• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdevelop API Reference
  • KDE Home
  • Contact Us
 

kdevplatform/project

  • sources
  • kfour-appscomplete
  • kdevelop
  • kdevplatform
  • project
projectitemlineedit.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright 2008 Aleix Pol <[email protected]> *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU Library General Public License as *
6  * published by the Free Software Foundation; either version 2 of the *
7  * License, or (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  * *
14  * You should have received a copy of the GNU Library General Public *
15  * License along with this program; if not, write to the *
16  * Free Software Foundation, Inc., *
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18  ***************************************************************************/
19 
20 #include "projectitemlineedit.h"
21 
22 #include <QAction>
23 #include <QCompleter>
24 #include <QDialog>
25 #include <QDialogButtonBox>
26 #include <QHeaderView>
27 #include <QLabel>
28 #include <QMenu>
29 #include <QPushButton>
30 #include <QTreeView>
31 #include <QValidator>
32 #include <QVBoxLayout>
33 
34 #include <KLocalizedString>
35 
36 #include <interfaces/icore.h>
37 #include <interfaces/iprojectcontroller.h>
38 #include <project/projectmodel.h>
39 #include <util/kdevstringhandler.h>
40 #include <interfaces/iproject.h>
41 #include "projectproxymodel.h"
42 
43 constexpr QChar sep = QLatin1Char('/');
44 constexpr QChar escape = QLatin1Char('\\');
45 
46 
47 class ProjectItemCompleter : public QCompleter
48 {
49  Q_OBJECT
50 public:
51  explicit ProjectItemCompleter(QObject* parent=nullptr);
52 
53  QString separator() const { return sep; }
54  QStringList splitPath(const QString &path) const override;
55  QString pathFromIndex(const QModelIndex& index) const override;
56 
57  void setBaseItem( KDevelop::ProjectBaseItem* item ) { mBase = item; }
58 
59 private:
60  KDevelop::ProjectModel* mModel;
61  KDevelop::ProjectBaseItem* mBase = nullptr;
62 };
63 
64 class ProjectItemValidator : public QValidator
65 {
66  Q_OBJECT
67 public:
68  explicit ProjectItemValidator(QObject* parent = nullptr );
69  QValidator::State validate( QString& input, int& pos ) const override;
70 
71  void setBaseItem( KDevelop::ProjectBaseItem* item ) { mBase = item; }
72 
73 private:
74  KDevelop::ProjectBaseItem* mBase = nullptr;
75 };
76 
77 ProjectItemCompleter::ProjectItemCompleter(QObject* parent)
78  : QCompleter(parent)
79  , mModel(KDevelop::ICore::self()->projectController()->projectModel())
80 
81 {
82  setModel(mModel);
83  setCaseSensitivity( Qt::CaseInsensitive );
84 }
85 
86 
87 QStringList ProjectItemCompleter::splitPath(const QString& path) const
88 {
89  return joinProjectBasePath( KDevelop::splitWithEscaping( path, sep, escape ), mBase );
90 }
91 
92 QString ProjectItemCompleter::pathFromIndex(const QModelIndex& index) const
93 {
94  QString postfix;
95  if(mModel->itemFromIndex(index)->folder())
96  postfix=sep;
97  return KDevelop::joinWithEscaping(removeProjectBasePath( mModel->pathFromIndex(index), mBase ), sep, escape)+postfix;
98 }
99 
100 
101 ProjectItemValidator::ProjectItemValidator(QObject* parent): QValidator(parent)
102 {
103 }
104 
105 
106 QValidator::State ProjectItemValidator::validate(QString& input, int& pos) const
107 {
108  Q_UNUSED( pos );
109  KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel();
110  QStringList path = joinProjectBasePath( KDevelop::splitWithEscaping( input, sep, escape ), mBase );
111  QModelIndex idx = model->pathToIndex( path );
112  QValidator::State state = input.isEmpty() ? QValidator::Intermediate : QValidator::Invalid;
113  if( idx.isValid() )
114  {
115  state = QValidator::Acceptable;
116  } else if( path.count() > 1 )
117  {
118  // Check beginning of path and if that is ok, then try to find a child
119  QString end = path.takeLast();
120  idx = model->pathToIndex( path );
121  if( idx.isValid() )
122  {
123  for( int i = 0; i < model->rowCount( idx ); i++ )
124  {
125  if( model->data( model->index( i, 0, idx ) ).toString().startsWith( end, Qt::CaseInsensitive ) )
126  {
127  state = QValidator::Intermediate;
128  break;
129  }
130  }
131  }
132  } else if( path.count() == 1 )
133  {
134  // Check for a project whose name beings with the input
135  QString first = path.first();
136  const auto projects = KDevelop::ICore::self()->projectController()->projects();
137  bool matchesAnyName = std::any_of(projects.begin(), projects.end(), [&](KDevelop::IProject* project) {
138  return (project->name().startsWith(first, Qt::CaseInsensitive));
139  });
140  if (matchesAnyName) {
141  state = QValidator::Intermediate;
142  }
143  }
144  return state;
145 }
146 
147 class ProjectItemLineEditPrivate
148 {
149 public:
150  explicit ProjectItemLineEditPrivate(ProjectItemLineEdit* q)
151  : completer(new ProjectItemCompleter(q))
152  , validator(new ProjectItemValidator(q))
153  {
154  }
155  KDevelop::ProjectBaseItem* base = nullptr;
156  ProjectItemCompleter* completer;
157  ProjectItemValidator* validator;
158  KDevelop::IProject* suggestion = nullptr;
159 };
160 
161 ProjectItemLineEdit::ProjectItemLineEdit(QWidget* parent)
162  : QLineEdit(parent),
163  d_ptr(new ProjectItemLineEditPrivate(this))
164 {
165  Q_D(ProjectItemLineEdit);
166 
167  setCompleter(d->completer);
168  setValidator(d->validator);
169  setPlaceholderText( i18nc("@info:placeholder", "Enter the path to an item from the projects tree..." ) );
170 
171  auto* selectItemAction = new QAction(QIcon::fromTheme(QStringLiteral("folder-document")), i18nc("@action", "Select..."), this);
172  connect(selectItemAction, &QAction::triggered, this, &ProjectItemLineEdit::selectItemDialog);
173  addAction(selectItemAction);
174 
175  setContextMenuPolicy(Qt::CustomContextMenu);
176  connect(this, &ProjectItemLineEdit::customContextMenuRequested, this, &ProjectItemLineEdit::showCtxMenu);
177 }
178 
179 ProjectItemLineEdit::~ProjectItemLineEdit() = default;
180 
181 void ProjectItemLineEdit::showCtxMenu(const QPoint& p)
182 {
183  QScopedPointer<QMenu> menu(createStandardContextMenu());
184  menu->addActions(actions());
185  menu->exec(mapToGlobal(p));
186 }
187 
188 bool ProjectItemLineEdit::selectItemDialog()
189 {
190  Q_D(ProjectItemLineEdit);
191 
192  KDevelop::ProjectModel* model=KDevelop::ICore::self()->projectController()->projectModel();
193 
194  QDialog dialog;
195  dialog.setWindowTitle(i18nc("@title:window", "Select an Item"));
196 
197  auto mainLayout = new QVBoxLayout(&dialog);
198 
199  auto* view = new QTreeView(&dialog);
200  auto* proxymodel = new ProjectProxyModel(view);
201  proxymodel->setSourceModel(model);
202  view->header()->hide();
203  view->setModel(proxymodel);
204  view->setSelectionMode(QAbstractItemView::SingleSelection);
205  mainLayout->addWidget(new QLabel(i18n("Select the item you want to get the path from.")));
206  mainLayout->addWidget(view);
207 
208  auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
209  QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
210  okButton->setDefault(true);
211  okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
212  connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
213  connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
214  mainLayout->addWidget(buttonBox);
215 
216  if (d->suggestion) {
217  const QModelIndex idx = proxymodel->proxyIndexFromItem(d->suggestion->projectItem());
218  view->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
219  }
220 
221  int res = dialog.exec();
222 
223  if(res==QDialog::Accepted && view->selectionModel()->hasSelection()) {
224  QModelIndex idx=proxymodel->mapToSource(view->selectionModel()->selectedIndexes().first());
225 
226  setText(KDevelop::joinWithEscaping(model->pathFromIndex(idx), sep, escape));
227  selectAll();
228  return true;
229  }
230  return false;
231 }
232 
233 void ProjectItemLineEdit::setItemPath(const QStringList& list)
234 {
235  Q_D(ProjectItemLineEdit);
236 
237  setText(KDevelop::joinWithEscaping(removeProjectBasePath(list, d->base), sep, escape));
238 }
239 
240 QStringList ProjectItemLineEdit::itemPath() const
241 {
242  Q_D(const ProjectItemLineEdit);
243 
244  return joinProjectBasePath(KDevelop::splitWithEscaping(text(), sep, escape), d->base);
245 }
246 
247 void ProjectItemLineEdit::setBaseItem(KDevelop::ProjectBaseItem* item)
248 {
249  Q_D(ProjectItemLineEdit);
250 
251  d->base = item;
252  d->validator->setBaseItem(d->base);
253  d->completer->setBaseItem(d->base);
254 }
255 
256 KDevelop::ProjectBaseItem* ProjectItemLineEdit::baseItem() const
257 {
258  Q_D(const ProjectItemLineEdit);
259 
260  return d->base;
261 }
262 
263 KDevelop::ProjectBaseItem* ProjectItemLineEdit::currentItem() const
264 {
265  KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel();
266  return model->itemFromIndex(model->pathToIndex(KDevelop::splitWithEscaping(text(), QLatin1Char('/'), QLatin1Char('\\'))));
267 }
268 
269 void ProjectItemLineEdit::setSuggestion(KDevelop::IProject* project)
270 {
271  Q_D(ProjectItemLineEdit);
272 
273  d->suggestion = project;
274 }
275 
276 #include "projectitemlineedit.moc"
277 #include "moc_projectitemlineedit.cpp"
QList::first
T & first()
QLineEdit::setPlaceholderText
void setPlaceholderText(const QString &)
ProjectProxyModel
Definition: projectproxymodel.h:31
QVBoxLayout
QLineEdit::setValidator
void setValidator(const QValidator *v)
QWidget::actions
QList< QAction * > actions() const
QLineEdit::createStandardContextMenu
QMenu * createStandardContextMenu()
ProjectItemLineEdit::selectItemDialog
bool selectItemDialog()
Definition: projectitemlineedit.cpp:188
QDialog::reject
virtual void reject()
QAbstractButton::setShortcut
void setShortcut(const QKeySequence &key)
QLineEdit
ProjectItemLineEdit::setBaseItem
void setBaseItem(KDevelop::ProjectBaseItem *item)
Sets item as the base item for this lineedit, the user then doesn't need to specify the path leading ...
Definition: projectitemlineedit.cpp:247
KDevelop::ProjectModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: projectmodel.cpp:1033
QWidget::customContextMenuRequested
void customContextMenuRequested(const QPoint &pos)
KDevelop::ProjectBaseItem
Interface that allows a developer to implement the three basic types of items you would see in a mult...
Definition: projectmodel.h:101
QList::count
int count(const T &value) const
QWidget
QIcon::fromTheme
QIcon fromTheme(const QString &name, const QIcon &fallback)
KDevelop::ProjectModel
Class providing some convenience methods for accessing the project model.
Definition: projectmodel.h:420
QLineEdit::selectAll
void selectAll()
QCompleter::splitPath
virtual QStringList splitPath(const QString &path) const
ProjectItemLineEdit::ProjectItemLineEdit
ProjectItemLineEdit(QWidget *parent=nullptr)
Definition: projectitemlineedit.cpp:161
ProjectItemLineEdit::baseItem
KDevelop::ProjectBaseItem * baseItem() const
Definition: projectitemlineedit.cpp:256
KDevelop::ProjectModel::itemFromIndex
ProjectBaseItem * itemFromIndex(const QModelIndex &) const
Definition: projectmodel.cpp:967
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QValidator::validate
virtual State validate(QString &input, int &pos) const=0
KDevelop::ProjectModel::data
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Definition: projectmodel.cpp:978
QLabel
QCompleter::pathFromIndex
virtual QString pathFromIndex(const QModelIndex &index) const
QPushButton
projectmodel.h
QObject
QTest::toString
char * toString(const T &value)
QString
QLineEdit::setText
void setText(const QString &)
QChar
QString::isEmpty
bool isEmpty() const
QWidget::setWindowTitle
void setWindowTitle(const QString &)
ProjectItemLineEdit::~ProjectItemLineEdit
~ProjectItemLineEdit() override
QDialogButtonBox::accepted
void accepted()
QDialog::accept
virtual void accept()
KDevelop::joinProjectBasePath
QStringList joinProjectBasePath(const QStringList &partialpath, KDevelop::ProjectBaseItem *item)
Definition: projectmodel.cpp:62
projectitemlineedit.h
QLineEdit::setCompleter
void setCompleter(QCompleter *c)
QWidget::mapToGlobal
QPoint mapToGlobal(const QPoint &pos) const
ProjectItemLineEdit::currentItem
KDevelop::ProjectBaseItem * currentItem() const
Definition: projectitemlineedit.cpp:263
QDialog::exec
int exec()
QValidator
QModelIndex::isValid
bool isValid() const
QScopedPointer
QWidget::setContextMenuPolicy
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
sep
constexpr QChar sep
Definition: projectitemlineedit.cpp:43
QAction::triggered
void triggered(bool checked)
QDialogButtonBox::rejected
void rejected()
QLatin1Char
QAction
KDevelop
Definition: abstractfilemanagerplugin.h:33
ProjectItemLineEdit::setSuggestion
void setSuggestion(KDevelop::IProject *project)
Definition: projectitemlineedit.cpp:269
ProjectItemLineEdit::itemPath
QStringList itemPath() const
Generates a path from the content of the lineedit, including the base item if present.
Definition: projectitemlineedit.cpp:240
QPushButton::setDefault
void setDefault(bool)
QModelIndex
KDevelop::ProjectModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: projectmodel.cpp:942
KDevelop::removeProjectBasePath
QStringList removeProjectBasePath(const QStringList &fullpath, KDevelop::ProjectBaseItem *item)
Definition: projectmodel.cpp:46
QDialog
QWidget::addAction
void addAction(QAction *action)
escape
constexpr QChar escape
Definition: projectitemlineedit.cpp:44
QTreeView
ProjectItemLineEdit::setItemPath
void setItemPath(const QStringList &path)
Sets this lineedit to show the given path, eventually removing parts from the beginning if a base ite...
Definition: projectitemlineedit.cpp:233
QCompleter
QList::takeLast
T takeLast()
KDevelop::ProjectModel::pathToIndex
QModelIndex pathToIndex(const QStringList &tofetch) const
Definition: projectmodel.cpp:885
QDialogButtonBox
KDevelop::ProjectModel::pathFromIndex
QStringList pathFromIndex(const QModelIndex &index) const
Definition: projectmodel.cpp:920
QPoint
ProjectItemLineEdit
Definition: projectitemlineedit.h:31
QStringList
projectproxymodel.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Mar 8 2021 23:30:20 by doxygen 1.8.16 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kdevplatform/project

Skip menu "kdevplatform/project"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdevelop API Reference

Skip menu "kdevelop API Reference"
  • kdevplatform
  •   debugger
  •   documentation
  •   interfaces
  •   language
  •     assistant
  •     backgroundparser
  •     checks
  •     classmodel
  •     codecompletion
  •     codegen
  •     duchain
  •     editor
  •     highlighting
  •     interfaces
  •     util
  •   outputview
  •   project
  •   serialization
  •   shell
  •   sublime
  •   tests
  •   util
  •   vcs

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal