forked from qt-creator/qt-creator
ProjectExtensionsPage: Rework project combo box
Show a actual tree in the combobox. Task-number: QTCREATORBUG-12002 Change-Id: I22b62f444923193972109a096bc6eef26a31bf9f Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com> Reviewed-by: Daniel Teske <daniel.teske@digia.com>
This commit is contained in:
@@ -57,18 +57,41 @@ TreeViewComboBox::TreeViewComboBox(QWidget *parent)
|
|||||||
m_view->viewport()->installEventFilter(this);
|
m_view->viewport()->installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeViewComboBox::wheelEvent(QWheelEvent *e)
|
QModelIndex TreeViewComboBox::indexAbove(QModelIndex index)
|
||||||
{
|
{
|
||||||
QModelIndex index = m_view->currentIndex();
|
|
||||||
if (e->delta() > 0) {
|
|
||||||
do
|
do
|
||||||
index = m_view->indexAbove(index);
|
index = m_view->indexAbove(index);
|
||||||
while (index.isValid() && !(model()->flags(index) & Qt::ItemIsSelectable));
|
while (index.isValid() && !(model()->flags(index) & Qt::ItemIsSelectable));
|
||||||
} else if (e->delta() < 0) {
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex TreeViewComboBox::indexBelow(QModelIndex index)
|
||||||
|
{
|
||||||
do
|
do
|
||||||
index = m_view->indexBelow(index);
|
index = m_view->indexBelow(index);
|
||||||
while (index.isValid() && !(model()->flags(index) & Qt::ItemIsSelectable));
|
while (index.isValid() && !(model()->flags(index) & Qt::ItemIsSelectable));
|
||||||
}
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex TreeViewComboBox::lastIndex(const QModelIndex index)
|
||||||
|
{
|
||||||
|
if (index.isValid() && !m_view->isExpanded(index))
|
||||||
|
return index;
|
||||||
|
|
||||||
|
int rows = m_view->model()->rowCount(index);
|
||||||
|
if (rows == 0)
|
||||||
|
return index;
|
||||||
|
return lastIndex(m_view->model()->index(rows - 1, 0, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeViewComboBox::wheelEvent(QWheelEvent *e)
|
||||||
|
{
|
||||||
|
QModelIndex index = m_view->currentIndex();
|
||||||
|
if (e->delta() > 0)
|
||||||
|
index = indexAbove(index);
|
||||||
|
else if (e->delta() < 0)
|
||||||
|
index = indexBelow(index);
|
||||||
|
|
||||||
e->accept();
|
e->accept();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
@@ -79,8 +102,34 @@ void TreeViewComboBox::wheelEvent(QWheelEvent *e)
|
|||||||
emit activated(index.row());
|
emit activated(index.row());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TreeViewComboBox::keyPressEvent(QKeyEvent *e)
|
||||||
|
{
|
||||||
|
if (e->key() == Qt::Key_Up || e->key() == Qt::Key_PageUp) {
|
||||||
|
setCurrentIndex(indexAbove(m_view->currentIndex()));
|
||||||
|
} else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_PageDown) {
|
||||||
|
setCurrentIndex(indexBelow(m_view->currentIndex()));
|
||||||
|
} else if (e->key() == Qt::Key_Home) {
|
||||||
|
QModelIndex index = m_view->model()->index(0, 0);
|
||||||
|
if (index.isValid() && !model()->flags(index) & Qt::ItemIsSelectable)
|
||||||
|
index = indexBelow(index);
|
||||||
|
setCurrentIndex(index);
|
||||||
|
} else if (e->key() == Qt::Key_End) {
|
||||||
|
QModelIndex index = lastIndex(m_view->rootIndex());
|
||||||
|
if (index.isValid() && !model()->flags(index) & Qt::ItemIsSelectable)
|
||||||
|
index = indexAbove(index);
|
||||||
|
setCurrentIndex(index);
|
||||||
|
} else {
|
||||||
|
QComboBox::keyPressEvent(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e->accept();
|
||||||
|
}
|
||||||
|
|
||||||
void TreeViewComboBox::setCurrentIndex(const QModelIndex &index)
|
void TreeViewComboBox::setCurrentIndex(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return;
|
||||||
setRootModelIndex(model()->parent(index));
|
setRootModelIndex(model()->parent(index));
|
||||||
QComboBox::setCurrentIndex(index.row());
|
QComboBox::setCurrentIndex(index.row());
|
||||||
setRootModelIndex(QModelIndex());
|
setRootModelIndex(QModelIndex());
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public:
|
|||||||
TreeViewComboBox(QWidget *parent = 0);
|
TreeViewComboBox(QWidget *parent = 0);
|
||||||
|
|
||||||
void wheelEvent(QWheelEvent *e);
|
void wheelEvent(QWheelEvent *e);
|
||||||
|
void keyPressEvent(QKeyEvent *e);
|
||||||
void setCurrentIndex(const QModelIndex &index);
|
void setCurrentIndex(const QModelIndex &index);
|
||||||
bool eventFilter(QObject* object, QEvent* event);
|
bool eventFilter(QObject* object, QEvent* event);
|
||||||
void showPopup();
|
void showPopup();
|
||||||
@@ -60,6 +61,10 @@ public:
|
|||||||
TreeViewComboBoxView *view() const;
|
TreeViewComboBoxView *view() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QModelIndex indexBelow(QModelIndex index);
|
||||||
|
QModelIndex indexAbove(QModelIndex index);
|
||||||
|
QModelIndex lastIndex(const QModelIndex index);
|
||||||
|
|
||||||
TreeViewComboBoxView *m_view;
|
TreeViewComboBoxView *m_view;
|
||||||
bool m_skipNextHide;
|
bool m_skipNextHide;
|
||||||
};
|
};
|
||||||
|
|||||||
213
src/plugins/projectexplorer/addnewmodel.cpp
Normal file
213
src/plugins/projectexplorer/addnewmodel.cpp
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "addnewmodel.h"
|
||||||
|
|
||||||
|
#include "projectexplorer.h"
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
using namespace ProjectExplorer::Internal;
|
||||||
|
|
||||||
|
AddNewTree::AddNewTree(const QString &displayName)
|
||||||
|
: m_parent(0),
|
||||||
|
m_children(QList<AddNewTree *>()),
|
||||||
|
m_displayName(displayName),
|
||||||
|
m_node(0),
|
||||||
|
m_canAdd(true),
|
||||||
|
m_priority(-1)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AddNewTree::AddNewTree(FolderNode *node, QList<AddNewTree *> children, const QString &displayName)
|
||||||
|
: m_parent(0),
|
||||||
|
m_children(children),
|
||||||
|
m_displayName(displayName),
|
||||||
|
m_node(0),
|
||||||
|
m_canAdd(false),
|
||||||
|
m_priority(-1)
|
||||||
|
{
|
||||||
|
if (node)
|
||||||
|
m_toolTip = ProjectExplorerPlugin::directoryFor(node);
|
||||||
|
foreach (AddNewTree *child, m_children)
|
||||||
|
child->m_parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddNewTree::AddNewTree(FolderNode *node, QList<AddNewTree *> children, const FolderNode::AddNewInformation &info)
|
||||||
|
: m_parent(0),
|
||||||
|
m_children(children),
|
||||||
|
m_displayName(info.displayName),
|
||||||
|
m_node(node),
|
||||||
|
m_canAdd(true),
|
||||||
|
m_priority(info.priority)
|
||||||
|
{
|
||||||
|
if (node)
|
||||||
|
m_toolTip = ProjectExplorerPlugin::directoryFor(node);
|
||||||
|
foreach (AddNewTree *child, m_children)
|
||||||
|
child->m_parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddNewTree::~AddNewTree()
|
||||||
|
{
|
||||||
|
qDeleteAll(m_children);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddNewTree *AddNewTree::parent() const
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<AddNewTree *> AddNewTree::children() const
|
||||||
|
{
|
||||||
|
return m_children;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddNewTree::canAdd() const
|
||||||
|
{
|
||||||
|
return m_canAdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AddNewTree::displayName() const
|
||||||
|
{
|
||||||
|
return m_displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AddNewTree::toolTip() const
|
||||||
|
{
|
||||||
|
return m_toolTip;
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderNode *AddNewTree::node() const
|
||||||
|
{
|
||||||
|
return m_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AddNewTree::priority() const
|
||||||
|
{
|
||||||
|
return m_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddNewModel::AddNewModel(AddNewTree *root)
|
||||||
|
: m_root(root)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AddNewModel::~AddNewModel()
|
||||||
|
{
|
||||||
|
delete m_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AddNewModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (!parent.isValid())
|
||||||
|
return m_root->children().size();
|
||||||
|
AddNewTree *tree = static_cast<AddNewTree *>(parent.internalPointer());
|
||||||
|
return tree->children().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AddNewModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex AddNewModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (column != 0)
|
||||||
|
return QModelIndex();
|
||||||
|
if (!parent.isValid()) {
|
||||||
|
if (row >= 0 && row < m_root->children().size())
|
||||||
|
return createIndex(row, column, m_root->children().at(row));
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
AddNewTree *tree = static_cast<AddNewTree *>(parent.internalPointer());
|
||||||
|
if (row >= 0 && row < tree->children().size())
|
||||||
|
return createIndex(row, column, tree->children().at(row));
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex AddNewModel::parent(const QModelIndex &child) const
|
||||||
|
{
|
||||||
|
if (!child.isValid())
|
||||||
|
return QModelIndex();
|
||||||
|
AddNewTree *childTree = static_cast<AddNewTree *>(child.internalPointer());
|
||||||
|
if (childTree == m_root)
|
||||||
|
return QModelIndex();
|
||||||
|
AddNewTree *parent = childTree->parent();
|
||||||
|
if (parent == m_root)
|
||||||
|
return QModelIndex();
|
||||||
|
AddNewTree *grandparent = parent->parent();
|
||||||
|
for (int i = 0; i < grandparent->children().size(); ++i) {
|
||||||
|
if (grandparent->children().at(i) == parent)
|
||||||
|
return createIndex(i, 0, parent);
|
||||||
|
}
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant AddNewModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
AddNewTree *tree = static_cast<AddNewTree *>(index.internalPointer());
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return tree->displayName();
|
||||||
|
else if (role == Qt::ToolTipRole)
|
||||||
|
return tree->toolTip();
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags AddNewModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
AddNewTree *tree = static_cast<AddNewTree *>(index.internalPointer());
|
||||||
|
if (tree && tree->canAdd())
|
||||||
|
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||||
|
return Qt::NoItemFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderNode *AddNewModel::nodeForIndex(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return m_root->node();
|
||||||
|
AddNewTree *tree = static_cast<AddNewTree *>(index.internalPointer());
|
||||||
|
return tree->node();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex AddNewModel::indexForTree(AddNewTree *tree) const
|
||||||
|
{
|
||||||
|
if (!tree)
|
||||||
|
return index(0, 0, QModelIndex());
|
||||||
|
AddNewTree *parent = tree->parent();
|
||||||
|
if (!parent)
|
||||||
|
return QModelIndex();
|
||||||
|
for (int i = 0; i < parent->children().size(); ++i)
|
||||||
|
if (parent->children().at(i) == tree)
|
||||||
|
return createIndex(i, 0, tree);
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
88
src/plugins/projectexplorer/addnewmodel.h
Normal file
88
src/plugins/projectexplorer/addnewmodel.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ADDNEWMODEL_H
|
||||||
|
#define ADDNEWMODEL_H
|
||||||
|
|
||||||
|
#include "projectnodes.h"
|
||||||
|
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
class FolderNode;
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class AddNewTree
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AddNewTree(const QString &displayName);
|
||||||
|
AddNewTree(FolderNode *node, QList<AddNewTree *> children, const QString &displayName);
|
||||||
|
AddNewTree(FolderNode *node, QList<AddNewTree *> children, const FolderNode::AddNewInformation &info);
|
||||||
|
~AddNewTree();
|
||||||
|
|
||||||
|
AddNewTree *parent() const;
|
||||||
|
QList<AddNewTree *> children() const;
|
||||||
|
|
||||||
|
bool canAdd() const;
|
||||||
|
QString displayName() const;
|
||||||
|
QString toolTip() const;
|
||||||
|
FolderNode *node() const;
|
||||||
|
int priority() const;
|
||||||
|
private:
|
||||||
|
AddNewTree *m_parent;
|
||||||
|
QList<AddNewTree *> m_children;
|
||||||
|
QString m_displayName;
|
||||||
|
QString m_toolTip;
|
||||||
|
FolderNode *m_node;
|
||||||
|
bool m_canAdd;
|
||||||
|
int m_priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddNewModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AddNewModel(AddNewTree *root);
|
||||||
|
~AddNewModel();
|
||||||
|
int rowCount(const QModelIndex &parent) const;
|
||||||
|
int columnCount(const QModelIndex &parent) const;
|
||||||
|
QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
||||||
|
QModelIndex parent(const QModelIndex &child) const;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
FolderNode *nodeForIndex(const QModelIndex &index) const;
|
||||||
|
QModelIndex indexForTree(AddNewTree *tree) const;
|
||||||
|
private:
|
||||||
|
AddNewTree *m_root;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ADDNEWMODEL_H
|
||||||
@@ -145,7 +145,8 @@ HEADERS += projectexplorer.h \
|
|||||||
customparser.h \
|
customparser.h \
|
||||||
customparserconfigdialog.h \
|
customparserconfigdialog.h \
|
||||||
ipotentialkit.h \
|
ipotentialkit.h \
|
||||||
selectablefilesmodel.h
|
selectablefilesmodel.h \
|
||||||
|
addnewmodel.h
|
||||||
|
|
||||||
SOURCES += projectexplorer.cpp \
|
SOURCES += projectexplorer.cpp \
|
||||||
abi.cpp \
|
abi.cpp \
|
||||||
@@ -277,7 +278,8 @@ SOURCES += projectexplorer.cpp \
|
|||||||
customparser.cpp \
|
customparser.cpp \
|
||||||
customparserconfigdialog.cpp \
|
customparserconfigdialog.cpp \
|
||||||
ipotentialkit.cpp \
|
ipotentialkit.cpp \
|
||||||
selectablefilesmodel.cpp
|
selectablefilesmodel.cpp \
|
||||||
|
addnewmodel.cpp
|
||||||
|
|
||||||
FORMS += processstep.ui \
|
FORMS += processstep.ui \
|
||||||
editorsettingspropertiespage.ui \
|
editorsettingspropertiespage.ui \
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "projectnodes.h"
|
#include "projectnodes.h"
|
||||||
#include "nodesvisitor.h"
|
#include "nodesvisitor.h"
|
||||||
#include "projectwizardpage.h"
|
#include "projectwizardpage.h"
|
||||||
|
#include "addnewmodel.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
@@ -85,134 +86,168 @@ enum { debugExtension = 0 };
|
|||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
typedef QList<FolderNode *> FolderNodeList;
|
|
||||||
typedef QList<ProjectNode *> ProjectNodeList;
|
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
// AddNewFileNodesVisitor: Retrieve all folders which support AddNew
|
class BestNodeSelector
|
||||||
class AddNewFileNodesVisitor : public NodesVisitor
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AddNewFileNodesVisitor();
|
BestNodeSelector(const QString &commonDirectory, const QStringList &files, Node *contextNode);
|
||||||
|
void inspect(AddNewTree *tree);
|
||||||
static FolderNodeList allFolders();
|
AddNewTree *bestChoice() const;
|
||||||
|
QString deployingProjects() const;
|
||||||
virtual void visitProjectNode(ProjectNode *node);
|
|
||||||
virtual void visitFolderNode(FolderNode *node);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FolderNodeList m_folderNodes;
|
QString m_commonDirectory;
|
||||||
|
QStringList m_files;
|
||||||
|
Node *m_contextNode;
|
||||||
|
bool m_deploys;
|
||||||
|
QString m_deployText;
|
||||||
|
AddNewTree *m_bestChoice;
|
||||||
|
int m_bestMatchLength;
|
||||||
|
int m_bestMatchPriority;
|
||||||
};
|
};
|
||||||
|
|
||||||
AddNewFileNodesVisitor::AddNewFileNodesVisitor()
|
BestNodeSelector::BestNodeSelector(const QString &commonDirectory, const QStringList &files, Node *contextNode)
|
||||||
{}
|
: m_commonDirectory(commonDirectory),
|
||||||
|
m_files(files),
|
||||||
FolderNodeList AddNewFileNodesVisitor::allFolders()
|
m_contextNode(contextNode),
|
||||||
|
m_deploys(false),
|
||||||
|
m_deployText(QCoreApplication::translate("ProjectWizard", "The files are implicitly added to the projects:") + QLatin1Char('\n')),
|
||||||
|
m_bestChoice(0),
|
||||||
|
m_bestMatchLength(-1),
|
||||||
|
m_bestMatchPriority(-1)
|
||||||
{
|
{
|
||||||
AddNewFileNodesVisitor visitor;
|
|
||||||
SessionManager::sessionNode()->accept(&visitor);
|
|
||||||
return visitor.m_folderNodes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddNewFileNodesVisitor::visitProjectNode(ProjectNode *node)
|
// Find the project the new files should be added
|
||||||
|
// If any node deploys the files, then we don't want to add the files.
|
||||||
|
// Otherwise consider their common path. Either a direct match on the directory
|
||||||
|
// or the directory with the longest matching path (list containing"/project/subproject1"
|
||||||
|
// matching common path "/project/subproject1/newuserpath").
|
||||||
|
void BestNodeSelector::inspect(AddNewTree *tree)
|
||||||
{
|
{
|
||||||
visitFolderNode(node);
|
FolderNode *node = tree->node();
|
||||||
|
if (node->nodeType() == ProjectNodeType) {
|
||||||
|
if (static_cast<ProjectNode *>(node)->deploysFolder(m_commonDirectory)) {
|
||||||
|
m_deploys = true;
|
||||||
|
m_deployText += tree->displayName() + QLatin1Char('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_deploys)
|
||||||
|
return;
|
||||||
|
const QString projectDirectory = ProjectExplorerPlugin::directoryFor(node);
|
||||||
|
const int projectDirectorySize = projectDirectory.size();
|
||||||
|
if (!m_commonDirectory.startsWith(projectDirectory))
|
||||||
|
return;
|
||||||
|
bool betterMatch = projectDirectorySize > m_bestMatchLength
|
||||||
|
|| (projectDirectorySize == m_bestMatchLength && tree->priority() > m_bestMatchPriority);
|
||||||
|
if (betterMatch) {
|
||||||
|
m_bestMatchPriority = tree->priority();
|
||||||
|
m_bestMatchLength = projectDirectorySize;
|
||||||
|
m_bestChoice = tree;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddNewFileNodesVisitor::visitFolderNode(FolderNode *node)
|
AddNewTree *BestNodeSelector::bestChoice() const
|
||||||
{
|
{
|
||||||
const QList<ProjectExplorer::ProjectAction> &list = node->supportedActions(node);
|
if (m_deploys)
|
||||||
if (list.contains(ProjectExplorer::AddNewFile) && !list.contains(ProjectExplorer::InheritedFromParent))
|
|
||||||
m_folderNodes.push_back(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddNewProjectNodesVisitor: Retrieve all folders which support AddNewProject
|
|
||||||
// also checks the path of the added subproject
|
|
||||||
class AddNewProjectNodesVisitor : public NodesVisitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AddNewProjectNodesVisitor(const QString &subProjectPath);
|
|
||||||
|
|
||||||
static ProjectNodeList projectNodes(const QString &subProjectPath);
|
|
||||||
|
|
||||||
virtual void visitProjectNode(ProjectNode *node);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ProjectNodeList m_projectNodes;
|
|
||||||
QString m_subProjectPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
AddNewProjectNodesVisitor::AddNewProjectNodesVisitor(const QString &subProjectPath)
|
|
||||||
: m_subProjectPath(subProjectPath)
|
|
||||||
{}
|
|
||||||
|
|
||||||
ProjectNodeList AddNewProjectNodesVisitor::projectNodes(const QString &subProjectPath)
|
|
||||||
{
|
|
||||||
AddNewProjectNodesVisitor visitor(subProjectPath);
|
|
||||||
SessionManager::sessionNode()->accept(&visitor);
|
|
||||||
return visitor.m_projectNodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddNewProjectNodesVisitor::visitProjectNode(ProjectNode *node)
|
|
||||||
{
|
|
||||||
const QList<ProjectExplorer::ProjectAction> &list = node->supportedActions(node);
|
|
||||||
if (list.contains(ProjectExplorer::AddSubProject) && !list.contains(ProjectExplorer::InheritedFromParent))
|
|
||||||
if (m_subProjectPath.isEmpty() || node->canAddSubProject(m_subProjectPath))
|
|
||||||
m_projectNodes.push_back(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectEntry: Context entry for a *.pri/*.pro file. Stores name and path
|
|
||||||
// for quick sort and path search, provides operator<() for maps.
|
|
||||||
struct FolderEntry {
|
|
||||||
FolderEntry() : node(0), priority(-1) {}
|
|
||||||
explicit FolderEntry(FolderNode *node, const QStringList &generatedFiles, Node *contextNode);
|
|
||||||
|
|
||||||
int compare(const FolderEntry &rhs) const;
|
|
||||||
|
|
||||||
FolderNode *node;
|
|
||||||
QString directory; // For matching against wizards' files, which are native.
|
|
||||||
QString displayName;
|
|
||||||
QString baseName;
|
|
||||||
int priority;
|
|
||||||
};
|
|
||||||
|
|
||||||
FolderEntry::FolderEntry(FolderNode *n, const QStringList &generatedFiles, Node *contextNode) :
|
|
||||||
node(n)
|
|
||||||
{
|
|
||||||
FolderNode::AddNewInformation info = node->addNewInformation(generatedFiles, contextNode);
|
|
||||||
displayName = info.displayName;
|
|
||||||
const QFileInfo fi(ProjectExplorerPlugin::pathFor(node));
|
|
||||||
baseName = fi.baseName();
|
|
||||||
priority = info.priority;
|
|
||||||
directory = ProjectExplorerPlugin::directoryFor(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort helper that sorts by base name and puts '*.pro' before '*.pri'
|
|
||||||
int FolderEntry::compare(const FolderEntry &rhs) const
|
|
||||||
{
|
|
||||||
if (const int drc = displayName.compare(rhs.displayName))
|
|
||||||
return drc;
|
|
||||||
if (const int drc = directory.compare(rhs.directory))
|
|
||||||
return drc;
|
|
||||||
if (const int brc = baseName.compare(rhs.baseName))
|
|
||||||
return brc;
|
|
||||||
if (priority > rhs.priority)
|
|
||||||
return -1;
|
|
||||||
if (priority < rhs.priority)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
return m_bestChoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator<(const FolderEntry &pe1, const FolderEntry &pe2)
|
QString BestNodeSelector::deployingProjects() const
|
||||||
{
|
{
|
||||||
return pe1.compare(pe2) < 0;
|
if (m_deploys)
|
||||||
|
return m_deployText;
|
||||||
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug d, const FolderEntry &e)
|
static inline AddNewTree *createNoneNode(BestNodeSelector *selector)
|
||||||
{
|
{
|
||||||
d.nospace() << e.directory << ' ' << e.displayName << ' ' << e.priority;
|
QString displayName = QCoreApplication::translate("ProjectWizard", "<Implicitly Add>");
|
||||||
return d;
|
if (selector->bestChoice())
|
||||||
|
displayName = QCoreApplication::translate("ProjectWizard", "<None>");
|
||||||
|
return new AddNewTree(displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline AddNewTree *buildAddProjectTree(ProjectNode *root, const QString &projectPath, Node *contextNode, BestNodeSelector *selector)
|
||||||
|
{
|
||||||
|
QList<AddNewTree *> children;
|
||||||
|
foreach (ProjectNode *pn, root->subProjectNodes()) {
|
||||||
|
AddNewTree *child = buildAddProjectTree(pn, projectPath, contextNode, selector);
|
||||||
|
if (child)
|
||||||
|
children.append(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<ProjectExplorer::ProjectAction> &list = root->supportedActions(root);
|
||||||
|
if (list.contains(ProjectExplorer::AddSubProject) && !list.contains(ProjectExplorer::InheritedFromParent)) {
|
||||||
|
if (projectPath.isEmpty() || root->canAddSubProject(projectPath)) {
|
||||||
|
FolderNode::AddNewInformation info = root->addNewInformation(QStringList() << projectPath, contextNode);
|
||||||
|
AddNewTree *item = new AddNewTree(root, children, info);
|
||||||
|
selector->inspect(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children.isEmpty())
|
||||||
|
return 0;
|
||||||
|
return new AddNewTree(root, children, root->displayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline AddNewTree *buildAddProjectTree(SessionNode *root, const QString &projectPath, Node *contextNode, BestNodeSelector *selector)
|
||||||
|
{
|
||||||
|
QList<AddNewTree *> children;
|
||||||
|
foreach (ProjectNode *pn, root->projectNodes()) {
|
||||||
|
AddNewTree *child = buildAddProjectTree(pn, projectPath, contextNode, selector);
|
||||||
|
if (child)
|
||||||
|
children.append(child);
|
||||||
|
}
|
||||||
|
children.prepend(createNoneNode(selector));
|
||||||
|
return new AddNewTree(root, children, root->displayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline AddNewTree *buildAddFilesTree(FolderNode *root, const QStringList &files, Node *contextNode, BestNodeSelector *selector)
|
||||||
|
{
|
||||||
|
QList<AddNewTree *> children;
|
||||||
|
foreach (FolderNode *fn, root->subFolderNodes()) {
|
||||||
|
AddNewTree *child = buildAddFilesTree(fn, files, contextNode, selector);
|
||||||
|
if (child)
|
||||||
|
children.append(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<ProjectExplorer::ProjectAction> &list = root->supportedActions(root);
|
||||||
|
if (list.contains(ProjectExplorer::AddNewFile) && !list.contains(ProjectExplorer::InheritedFromParent)) {
|
||||||
|
FolderNode::AddNewInformation info = root->addNewInformation(files, contextNode);
|
||||||
|
AddNewTree *item = new AddNewTree(root, children, info);
|
||||||
|
selector->inspect(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
if (children.isEmpty())
|
||||||
|
return 0;
|
||||||
|
return new AddNewTree(root, children, root->displayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline AddNewTree *buildAddFilesTree(SessionNode *root, const QStringList &files, Node *contextNode, BestNodeSelector *selector)
|
||||||
|
{
|
||||||
|
QList<AddNewTree *> children;
|
||||||
|
foreach (ProjectNode *pn, root->projectNodes()) {
|
||||||
|
AddNewTree *child = buildAddFilesTree(pn, files, contextNode, selector);
|
||||||
|
if (child)
|
||||||
|
children.append(child);
|
||||||
|
}
|
||||||
|
children.prepend(createNoneNode(selector));
|
||||||
|
return new AddNewTree(root, children, root->displayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline AddNewTree *getChoices(const QStringList &generatedFiles,
|
||||||
|
IWizard::WizardKind wizardKind,
|
||||||
|
Node *contextNode,
|
||||||
|
BestNodeSelector *selector)
|
||||||
|
{
|
||||||
|
if (wizardKind == IWizard::ProjectWizard)
|
||||||
|
return buildAddProjectTree(SessionManager::sessionNode(), generatedFiles.first(), contextNode, selector);
|
||||||
|
else
|
||||||
|
return buildAddFilesTree(SessionManager::sessionNode(), generatedFiles, contextNode, selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------- ProjectWizardContext
|
// --------- ProjectWizardContext
|
||||||
@@ -223,7 +258,6 @@ struct ProjectWizardContext
|
|||||||
|
|
||||||
QList<IVersionControl*> versionControls;
|
QList<IVersionControl*> versionControls;
|
||||||
QList<IVersionControl*> activeVersionControls;
|
QList<IVersionControl*> activeVersionControls;
|
||||||
QList<FolderEntry> projects;
|
|
||||||
QPointer<ProjectWizardPage> page; // this is managed by the wizard!
|
QPointer<ProjectWizardPage> page; // this is managed by the wizard!
|
||||||
bool repositoryExists; // Is VCS 'add' sufficient, or should a repository be created?
|
bool repositoryExists; // Is VCS 'add' sufficient, or should a repository be created?
|
||||||
QString commonDirectory;
|
QString commonDirectory;
|
||||||
@@ -240,7 +274,6 @@ ProjectWizardContext::ProjectWizardContext() :
|
|||||||
void ProjectWizardContext::clear()
|
void ProjectWizardContext::clear()
|
||||||
{
|
{
|
||||||
activeVersionControls.clear();
|
activeVersionControls.clear();
|
||||||
projects.clear();
|
|
||||||
commonDirectory.clear();
|
commonDirectory.clear();
|
||||||
page = 0;
|
page = 0;
|
||||||
repositoryExists = false;
|
repositoryExists = false;
|
||||||
@@ -258,51 +291,6 @@ ProjectFileWizardExtension::~ProjectFileWizardExtension()
|
|||||||
delete m_context;
|
delete m_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QList<FolderEntry> findDeployProject(const QList<FolderEntry> &folders,
|
|
||||||
QString &commonPath)
|
|
||||||
{
|
|
||||||
QList<FolderEntry> filtered;
|
|
||||||
foreach (const FolderEntry &folder, folders)
|
|
||||||
if (folder.node->nodeType() == ProjectNodeType)
|
|
||||||
if (static_cast<ProjectNode *>(folder.node)->deploysFolder(commonPath))
|
|
||||||
filtered << folder;
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the project the new files should be added to given their common
|
|
||||||
// path. Either a direct match on the directory or the directory with
|
|
||||||
// the longest matching path (list containing"/project/subproject1" matching
|
|
||||||
// common path "/project/subproject1/newuserpath").
|
|
||||||
static int findMatchingProject(const QList<FolderEntry> &projects,
|
|
||||||
const QString &commonPath)
|
|
||||||
{
|
|
||||||
if (projects.isEmpty() || commonPath.isEmpty())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
const int count = projects.size();
|
|
||||||
int bestMatch = -1;
|
|
||||||
int bestMatchLength = 0;
|
|
||||||
int bestMatchPriority = -1;
|
|
||||||
for (int p = 0; p < count; p++) {
|
|
||||||
// Direct match or better match? (note that the wizards' files are native).
|
|
||||||
const FolderEntry &entry = projects.at(p);
|
|
||||||
const QString &projectDirectory = entry.directory;
|
|
||||||
const int projectDirectorySize = projectDirectory.size();
|
|
||||||
if (!commonPath.startsWith(projectDirectory))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bool betterMatch = projectDirectorySize > bestMatchLength
|
|
||||||
|| (projectDirectorySize == bestMatchLength && entry.priority > bestMatchPriority);
|
|
||||||
|
|
||||||
if (betterMatch) {
|
|
||||||
bestMatchPriority = entry.priority;
|
|
||||||
bestMatchLength = projectDirectory.size();
|
|
||||||
bestMatch = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bestMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString generatedProjectFilePath(const QList<GeneratedFile> &files)
|
static QString generatedProjectFilePath(const QList<GeneratedFile> &files)
|
||||||
{
|
{
|
||||||
foreach (const GeneratedFile &file, files)
|
foreach (const GeneratedFile &file, files)
|
||||||
@@ -315,48 +303,37 @@ void ProjectFileWizardExtension::firstExtensionPageShown(
|
|||||||
const QList<GeneratedFile> &files,
|
const QList<GeneratedFile> &files,
|
||||||
const QVariantMap &extraValues)
|
const QVariantMap &extraValues)
|
||||||
{
|
{
|
||||||
initProjectChoices(files, extraValues);
|
|
||||||
|
|
||||||
if (debugExtension)
|
if (debugExtension)
|
||||||
qDebug() << Q_FUNC_INFO << files.size();
|
qDebug() << Q_FUNC_INFO << files.size();
|
||||||
|
|
||||||
// Parametrize wizard page: find best project to add to, set up files display and
|
|
||||||
// version control depending on path
|
|
||||||
QStringList fileNames;
|
QStringList fileNames;
|
||||||
foreach (const GeneratedFile &f, files)
|
foreach (const GeneratedFile &f, files)
|
||||||
fileNames.push_back(f.path());
|
fileNames.push_back(f.path());
|
||||||
m_context->commonDirectory = Utils::commonPath(fileNames);
|
m_context->commonDirectory = Utils::commonPath(fileNames);
|
||||||
m_context->page->setFilesDisplay(m_context->commonDirectory, fileNames);
|
m_context->page->setFilesDisplay(m_context->commonDirectory, fileNames);
|
||||||
// Find best project (Entry at 0 is 'None').
|
|
||||||
|
|
||||||
int bestProjectIndex = -1;
|
QStringList filePaths;
|
||||||
|
ProjectExplorer::ProjectAction projectAction;
|
||||||
QList<FolderEntry> deployingProjects = findDeployProject(m_context->projects, m_context->commonDirectory);
|
if (m_context->wizard->kind()== IWizard::ProjectWizard) {
|
||||||
if (!deployingProjects.isEmpty()) {
|
projectAction = ProjectExplorer::AddSubProject;
|
||||||
// Oh we do have someone that deploys it
|
filePaths << generatedProjectFilePath(files);
|
||||||
// then the best match is NONE
|
|
||||||
// We display a label explaining that and rename <None> to
|
|
||||||
// <Implicitly Add>
|
|
||||||
m_context->page->setNoneLabel(tr("<Implicitly Add>"));
|
|
||||||
|
|
||||||
QString text = tr("The files are implicitly added to the projects:");
|
|
||||||
text += QLatin1Char('\n');
|
|
||||||
foreach (const FolderEntry &project, deployingProjects) {
|
|
||||||
text += project.displayName;
|
|
||||||
text += QLatin1Char('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
m_context->page->setAdditionalInfo(text);
|
|
||||||
bestProjectIndex = -1;
|
|
||||||
} else {
|
} else {
|
||||||
bestProjectIndex = findMatchingProject(m_context->projects, m_context->commonDirectory);
|
projectAction = ProjectExplorer::AddNewFile;
|
||||||
m_context->page->setNoneLabel(tr("<None>"));
|
foreach (const GeneratedFile &gf, files)
|
||||||
|
filePaths << gf.path();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestProjectIndex == -1)
|
|
||||||
m_context->page->setCurrentProjectIndex(0);
|
Node *contextNode = extraValues.value(QLatin1String(Constants::PREFERRED_PROJECT_NODE)).value<Node *>();
|
||||||
else
|
BestNodeSelector selector(m_context->commonDirectory, filePaths, contextNode);
|
||||||
m_context->page->setCurrentProjectIndex(bestProjectIndex + 1);
|
AddNewTree *tree = getChoices(filePaths, m_context->wizard->kind(), contextNode, &selector);
|
||||||
|
|
||||||
|
m_context->page->setAdditionalInfo(selector.deployingProjects());
|
||||||
|
|
||||||
|
AddNewModel *model = new AddNewModel(tree);
|
||||||
|
m_context->page->setModel(model);
|
||||||
|
m_context->page->setBestNode(selector.bestChoice());
|
||||||
|
m_context->page->setAddingSubProject(projectAction == ProjectExplorer::AddSubProject);
|
||||||
|
|
||||||
// Store all version controls for later use:
|
// Store all version controls for later use:
|
||||||
if (m_context->versionControls.isEmpty()) {
|
if (m_context->versionControls.isEmpty()) {
|
||||||
@@ -429,72 +406,6 @@ QList<QWizardPage *> ProjectFileWizardExtension::extensionPages(const IWizard *w
|
|||||||
return QList<QWizardPage *>() << m_context->page;
|
return QList<QWizardPage *>() << m_context->page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void getProjectChoicesAndToolTips(QStringList *projectChoicesParam,
|
|
||||||
QStringList *projectToolTipsParam,
|
|
||||||
ProjectExplorer::ProjectAction *projectActionParam,
|
|
||||||
const QList<GeneratedFile> &generatedFiles,
|
|
||||||
ProjectWizardContext *context,
|
|
||||||
Node *contextNode)
|
|
||||||
{
|
|
||||||
// Set up project list which remains the same over duration of wizard execution
|
|
||||||
// As tooltip, set the directory for disambiguation (should someone have
|
|
||||||
// duplicate base names in differing directories).
|
|
||||||
//: No project selected
|
|
||||||
QStringList projectChoices(ProjectFileWizardExtension::tr("<None>"));
|
|
||||||
QStringList projectToolTips((QString()));
|
|
||||||
|
|
||||||
typedef QMap<FolderEntry, bool> FolderEntryMap;
|
|
||||||
// Sort by base name and purge duplicated entries (resulting from dependencies)
|
|
||||||
// via Map.
|
|
||||||
FolderEntryMap entryMap;
|
|
||||||
ProjectExplorer::ProjectAction projectAction;
|
|
||||||
if (context->wizard->kind()== IWizard::ProjectWizard) {
|
|
||||||
const QString projectFilePath = generatedProjectFilePath(generatedFiles);
|
|
||||||
projectAction = ProjectExplorer::AddSubProject;
|
|
||||||
foreach (ProjectNode *pn, AddNewProjectNodesVisitor::projectNodes(projectFilePath))
|
|
||||||
entryMap.insert(FolderEntry(pn, QStringList() << projectFilePath, contextNode), true);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
QStringList filePaths;
|
|
||||||
foreach (const GeneratedFile &gf, generatedFiles)
|
|
||||||
filePaths << gf.path();
|
|
||||||
|
|
||||||
projectAction = ProjectExplorer::AddNewFile;
|
|
||||||
foreach (FolderNode *fn, AddNewFileNodesVisitor::allFolders())
|
|
||||||
entryMap.insert(FolderEntry(fn, filePaths, contextNode), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
context->projects.clear();
|
|
||||||
|
|
||||||
// Collect names
|
|
||||||
const FolderEntryMap::const_iterator cend = entryMap.constEnd();
|
|
||||||
for (FolderEntryMap::const_iterator it = entryMap.constBegin(); it != cend; ++it) {
|
|
||||||
context->projects.push_back(it.key());
|
|
||||||
projectChoices.push_back(it.key().displayName);
|
|
||||||
projectToolTips.push_back(QDir::toNativeSeparators(it.key().directory));
|
|
||||||
}
|
|
||||||
|
|
||||||
*projectChoicesParam = projectChoices;
|
|
||||||
*projectToolTipsParam = projectToolTips;
|
|
||||||
*projectActionParam = projectAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectFileWizardExtension::initProjectChoices(const QList<GeneratedFile> &generatedFiles, const QVariantMap &extraValues)
|
|
||||||
{
|
|
||||||
QStringList projectChoices;
|
|
||||||
QStringList projectToolTips;
|
|
||||||
ProjectExplorer::ProjectAction projectAction;
|
|
||||||
|
|
||||||
getProjectChoicesAndToolTips(&projectChoices, &projectToolTips, &projectAction,
|
|
||||||
generatedFiles, m_context,
|
|
||||||
extraValues.value(QLatin1String(Constants::PREFERRED_PROJECT_NODE)).value<Node *>());
|
|
||||||
|
|
||||||
m_context->page->setProjects(projectChoices);
|
|
||||||
m_context->page->setProjectToolTips(projectToolTips);
|
|
||||||
m_context->page->setAddingSubProject(projectAction == ProjectExplorer::AddSubProject);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ProjectFileWizardExtension::processFiles(
|
bool ProjectFileWizardExtension::processFiles(
|
||||||
const QList<GeneratedFile> &files,
|
const QList<GeneratedFile> &files,
|
||||||
bool *removeOpenProjectAttribute, QString *errorMessage)
|
bool *removeOpenProjectAttribute, QString *errorMessage)
|
||||||
@@ -525,11 +436,9 @@ bool ProjectFileWizardExtension::processProject(
|
|||||||
|
|
||||||
QString generatedProject = generatedProjectFilePath(files);
|
QString generatedProject = generatedProjectFilePath(files);
|
||||||
|
|
||||||
// Add files to folder (Entry at 0 is 'None').
|
FolderNode *folder = m_context->page->currentNode();
|
||||||
const int folderIndex = m_context->page->currentProjectIndex() - 1;
|
if (!folder)
|
||||||
if (folderIndex < 0 || folderIndex >= m_context->projects.size())
|
|
||||||
return true;
|
return true;
|
||||||
FolderNode *folder = m_context->projects.at(folderIndex).node;
|
|
||||||
if (m_context->wizard->kind() == IWizard::ProjectWizard) {
|
if (m_context->wizard->kind() == IWizard::ProjectWizard) {
|
||||||
if (!static_cast<ProjectNode *>(folder)->addSubProjects(QStringList(generatedProject))) {
|
if (!static_cast<ProjectNode *>(folder)->addSubProjects(QStringList(generatedProject))) {
|
||||||
*errorMessage = tr("Failed to add subproject \"%1\"\nto project \"%2\".")
|
*errorMessage = tr("Failed to add subproject \"%1\"\nto project \"%2\".")
|
||||||
@@ -600,11 +509,7 @@ void ProjectFileWizardExtension::applyCodeStyle(GeneratedFile *file) const
|
|||||||
if (!languageId.isValid())
|
if (!languageId.isValid())
|
||||||
return; // don't modify files like *.ui *.pro
|
return; // don't modify files like *.ui *.pro
|
||||||
|
|
||||||
FolderNode *folder = 0;
|
FolderNode *folder = m_context->page->currentNode();
|
||||||
const int projectIndex = m_context->page->currentProjectIndex() - 1;
|
|
||||||
if (projectIndex >= 0 && projectIndex < m_context->projects.size())
|
|
||||||
folder = m_context->projects.at(projectIndex).node;
|
|
||||||
|
|
||||||
Project *baseProject = SessionManager::projectForNode(folder);
|
Project *baseProject = SessionManager::projectForNode(folder);
|
||||||
|
|
||||||
ICodeStylePreferencesFactory *factory = TextEditorSettings::codeStyleFactory(languageId);
|
ICodeStylePreferencesFactory *factory = TextEditorSettings::codeStyleFactory(languageId);
|
||||||
@@ -632,10 +537,5 @@ void ProjectFileWizardExtension::applyCodeStyle(GeneratedFile *file) const
|
|||||||
file->setContents(doc.toPlainText());
|
file->setContents(doc.toPlainText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectFileWizardExtension::setProjectIndex(int i)
|
|
||||||
{
|
|
||||||
m_context->page->setCurrentProjectIndex(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <coreplugin/ifilewizardextension.h>
|
#include <coreplugin/ifilewizardextension.h>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
class FolderNode;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -52,14 +53,11 @@ public:
|
|||||||
bool *removeOpenProjectAttribute, QString *errorMessage);
|
bool *removeOpenProjectAttribute, QString *errorMessage);
|
||||||
void applyCodeStyle(Core::GeneratedFile *file) const;
|
void applyCodeStyle(Core::GeneratedFile *file) const;
|
||||||
|
|
||||||
void setProjectIndex(int i);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void firstExtensionPageShown(const QList<Core::GeneratedFile> &files, const QVariantMap &extraValues);
|
void firstExtensionPageShown(const QList<Core::GeneratedFile> &files, const QVariantMap &extraValues);
|
||||||
void initializeVersionControlChoices();
|
void initializeVersionControlChoices();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initProjectChoices(const QList<Core::GeneratedFile> &generatedFiles, const QVariantMap &extraValues);
|
|
||||||
bool processProject(const QList<Core::GeneratedFile> &files,
|
bool processProject(const QList<Core::GeneratedFile> &files,
|
||||||
bool *removeOpenProjectAttribute, QString *errorMessage);
|
bool *removeOpenProjectAttribute, QString *errorMessage);
|
||||||
bool processVersionControl(const QList<Core::GeneratedFile> &files, QString *errorMessage);
|
bool processVersionControl(const QList<Core::GeneratedFile> &files, QString *errorMessage);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "addnewmodel.h"
|
||||||
#include "projectwizardpage.h"
|
#include "projectwizardpage.h"
|
||||||
#include "ui_projectwizardpage.h"
|
#include "ui_projectwizardpage.h"
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class ProjectExplorer::Internal::ProjectWizardPage
|
\class ProjectExplorer::Internal::ProjectWizardPage
|
||||||
@@ -51,7 +53,8 @@ using namespace Internal;
|
|||||||
|
|
||||||
ProjectWizardPage::ProjectWizardPage(QWidget *parent) :
|
ProjectWizardPage::ProjectWizardPage(QWidget *parent) :
|
||||||
QWizardPage(parent),
|
QWizardPage(parent),
|
||||||
m_ui(new Ui::WizardPage)
|
m_ui(new Ui::WizardPage),
|
||||||
|
m_model(0)
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
m_ui->vcsManageButton->setText(Core::ICore::msgShowOptionsDialog());
|
m_ui->vcsManageButton->setText(Core::ICore::msgShowOptionsDialog());
|
||||||
@@ -64,19 +67,64 @@ ProjectWizardPage::ProjectWizardPage(QWidget *parent) :
|
|||||||
ProjectWizardPage::~ProjectWizardPage()
|
ProjectWizardPage::~ProjectWizardPage()
|
||||||
{
|
{
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
|
delete m_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectWizardPage::setProjects(const QStringList &p)
|
void ProjectWizardPage::setModel(AddNewModel *model)
|
||||||
{
|
{
|
||||||
m_ui->projectComboBox->clear();
|
delete m_model;
|
||||||
m_ui->projectComboBox->addItems(p);
|
m_model = model;
|
||||||
m_ui->projectComboBox->setEnabled(p.size() > 1);
|
|
||||||
m_ui->projectLabel->setEnabled(p.size() > 1);
|
// TODO see OverViewCombo and OverView for click event filter
|
||||||
|
m_ui->projectComboBox->setModel(model);
|
||||||
|
bool enabled = m_model->rowCount(QModelIndex()) > 1;
|
||||||
|
m_ui->projectComboBox->setEnabled(enabled);
|
||||||
|
|
||||||
|
expandTree(QModelIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectWizardPage::setProjectToolTips(const QStringList &t)
|
bool ProjectWizardPage::expandTree(const QModelIndex &root)
|
||||||
{
|
{
|
||||||
m_projectToolTips = t;
|
bool expand = false;
|
||||||
|
if (!root.isValid()) // always expand root
|
||||||
|
expand = true;
|
||||||
|
|
||||||
|
// Check children
|
||||||
|
int count = m_model->rowCount(root);
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
if (expandTree(m_model->index(i, 0, root)))
|
||||||
|
expand = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply to self
|
||||||
|
if (expand)
|
||||||
|
m_ui->projectComboBox->view()->expand(root);
|
||||||
|
else
|
||||||
|
m_ui->projectComboBox->view()->collapse(root);
|
||||||
|
|
||||||
|
// if we are a high priority node, our *parent* needs to be expanded
|
||||||
|
AddNewTree *tree = static_cast<AddNewTree *>(root.internalPointer());
|
||||||
|
if (tree && tree->priority() >= 100)
|
||||||
|
expand = true;
|
||||||
|
|
||||||
|
return expand;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectWizardPage::setBestNode(AddNewTree *tree)
|
||||||
|
{
|
||||||
|
QModelIndex index = m_model->indexForTree(tree);
|
||||||
|
m_ui->projectComboBox->setCurrentIndex(index);
|
||||||
|
|
||||||
|
while (index.isValid()) {
|
||||||
|
m_ui->projectComboBox->view()->expand(index);
|
||||||
|
index = index.parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderNode *ProjectWizardPage::currentNode() const
|
||||||
|
{
|
||||||
|
QModelIndex index = m_ui->projectComboBox->view()->currentIndex();
|
||||||
|
return m_model->nodeForIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectWizardPage::setAddingSubProject(bool addingSubProject)
|
void ProjectWizardPage::setAddingSubProject(bool addingSubProject)
|
||||||
@@ -86,16 +134,6 @@ void ProjectWizardPage::setAddingSubProject(bool addingSubProject)
|
|||||||
: tr("Add to &project:"));
|
: tr("Add to &project:"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ProjectWizardPage::currentProjectIndex() const
|
|
||||||
{
|
|
||||||
return m_ui->projectComboBox->currentIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectWizardPage::setCurrentProjectIndex(int idx)
|
|
||||||
{
|
|
||||||
m_ui->projectComboBox->setCurrentIndex(idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectWizardPage::setNoneLabel(const QString &label)
|
void ProjectWizardPage::setNoneLabel(const QString &label)
|
||||||
{
|
{
|
||||||
m_ui->projectComboBox->setItemText(0, label);
|
m_ui->projectComboBox->setItemText(0, label);
|
||||||
|
|||||||
@@ -32,8 +32,15 @@
|
|||||||
|
|
||||||
#include <QWizardPage>
|
#include <QWizardPage>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QTreeView;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
class FolderNode;
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
class AddNewModel;
|
||||||
|
class AddNewTree;
|
||||||
|
|
||||||
namespace Ui { class WizardPage; }
|
namespace Ui { class WizardPage; }
|
||||||
|
|
||||||
@@ -46,11 +53,9 @@ public:
|
|||||||
explicit ProjectWizardPage(QWidget *parent = 0);
|
explicit ProjectWizardPage(QWidget *parent = 0);
|
||||||
virtual ~ProjectWizardPage();
|
virtual ~ProjectWizardPage();
|
||||||
|
|
||||||
void setProjects(const QStringList &);
|
void setModel(AddNewModel *model);
|
||||||
void setProjectToolTips(const QStringList &);
|
void setBestNode(ProjectExplorer::Internal::AddNewTree *tree);
|
||||||
|
FolderNode *currentNode() const;
|
||||||
int currentProjectIndex() const;
|
|
||||||
void setCurrentProjectIndex(int);
|
|
||||||
|
|
||||||
void setNoneLabel(const QString &label);
|
void setNoneLabel(const QString &label);
|
||||||
void setAdditionalInfo(const QString &text);
|
void setAdditionalInfo(const QString &text);
|
||||||
@@ -71,9 +76,11 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void setProjectToolTip(const QString &);
|
void setProjectToolTip(const QString &);
|
||||||
|
bool expandTree(const QModelIndex &root);
|
||||||
|
|
||||||
Ui::WizardPage *m_ui;
|
Ui::WizardPage *m_ui;
|
||||||
QStringList m_projectToolTips;
|
QStringList m_projectToolTips;
|
||||||
|
AddNewModel *m_model;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1" colspan="2">
|
<item row="0" column="1" colspan="2">
|
||||||
<widget class="QComboBox" name="projectComboBox">
|
<widget class="Utils::TreeViewComboBox" name="projectComboBox">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
@@ -144,6 +144,13 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Utils::TreeViewComboBox</class>
|
||||||
|
<extends>QComboBox</extends>
|
||||||
|
<header location="global">utils/treeviewcombobox.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
Reference in New Issue
Block a user