File indexing completed on 2024-05-12 04:39:40
0001 /* 0002 SPDX-FileCopyrightText: 2010 Andreas Pakulat <apaku@gmx.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-or-later 0005 */ 0006 0007 #include "includeswidget.h" 0008 0009 #include <QAction> 0010 #include <KLocalizedString> 0011 0012 #include <QFileInfo> 0013 0014 #include <interfaces/iproject.h> 0015 #include <util/path.h> 0016 0017 #include "../ui_includeswidget.h" 0018 #include "includesmodel.h" 0019 #include <debug.h> 0020 #include <QShortcut> 0021 0022 IncludesWidget::IncludesWidget( QWidget* parent ) 0023 : QWidget ( parent ), ui( new Ui::IncludesWidget ) 0024 , includesModel( new IncludesModel( this ) ) 0025 { 0026 ui->setupUi( this ); 0027 0028 // hack taken from kurlrequester, make the buttons a bit less in height so they better match the url-requester 0029 ui->addIncludePath->setFixedHeight( ui->includePathRequester->sizeHint().height() ); 0030 ui->removeIncludePath->setFixedHeight( ui->includePathRequester->sizeHint().height() ); 0031 0032 ui->errorWidget->setHidden(true); 0033 ui->errorWidget->setMessageType(KMessageWidget::Warning); 0034 0035 connect( ui->addIncludePath, &QPushButton::clicked, this, &IncludesWidget::addIncludePath ); 0036 connect( ui->removeIncludePath, &QPushButton::clicked, this, &IncludesWidget::deleteIncludePath ); 0037 0038 // also let user choose a file as include path. This file will be "automatically included" in all files. See also -include command line option of clang/gcc 0039 ui->includePathRequester->setMode( KFile::File | KFile::Directory | KFile::LocalOnly | KFile::ExistingOnly ); 0040 0041 ui->includePaths->setModel( includesModel ); 0042 connect( ui->includePaths->selectionModel(), &QItemSelectionModel::currentChanged, this, &IncludesWidget::includePathSelected ); 0043 connect( ui->includePathRequester, &KUrlRequester::textChanged, this, &IncludesWidget::includePathEdited ); 0044 connect( ui->includePathRequester, &KUrlRequester::urlSelected, this, &IncludesWidget::includePathUrlSelected ); 0045 connect(includesModel, &IncludesModel::dataChanged, this, QOverload<>::of(&IncludesWidget::includesChanged)); 0046 connect(includesModel, &IncludesModel::rowsInserted, this, QOverload<>::of(&IncludesWidget::includesChanged)); 0047 connect(includesModel, &IncludesModel::rowsRemoved, this, QOverload<>::of(&IncludesWidget::includesChanged)); 0048 0049 auto* delIncAction = new QAction(i18nc("@action", "Delete Include Path"), this); 0050 delIncAction->setShortcut( QKeySequence( Qt::Key_Delete ) ); 0051 delIncAction->setShortcutContext( Qt::WidgetWithChildrenShortcut ); 0052 ui->includePaths->addAction( delIncAction ); 0053 connect( delIncAction, &QAction::triggered, this, &IncludesWidget::deleteIncludePath ); 0054 } 0055 0056 void IncludesWidget::setIncludes( const QStringList& paths ) 0057 { 0058 bool b = blockSignals( true ); 0059 clear(); 0060 includesModel->setIncludes( paths ); 0061 blockSignals( b ); 0062 updateEnablements(); 0063 checkIfIncludePathExist(); 0064 } 0065 void IncludesWidget::includesChanged() 0066 { 0067 qCDebug(DEFINESANDINCLUDES) << "includes changed"; 0068 emit includesChanged( includesModel->includes() ); 0069 checkIfIncludePathExist(); 0070 } 0071 0072 void IncludesWidget::includePathSelected( const QModelIndex& /*selected*/ ) 0073 { 0074 updateEnablements(); 0075 } 0076 0077 void IncludesWidget::includePathEdited() 0078 { 0079 updateEnablements(); 0080 } 0081 0082 void IncludesWidget::clear() 0083 { 0084 includesModel->setIncludes( QStringList() ); 0085 updateEnablements(); 0086 } 0087 0088 void IncludesWidget::addIncludePath() 0089 { 0090 includesModel->addInclude( makeIncludeDirAbsolute(ui->includePathRequester->url()) ); 0091 ui->includePathRequester->clear(); 0092 updateEnablements(); 0093 } 0094 0095 void IncludesWidget::deleteIncludePath() 0096 { 0097 qCDebug(DEFINESANDINCLUDES) << "deleting include path" << ui->includePaths->currentIndex(); 0098 const QModelIndex curidx = ui->includePaths->currentIndex(); 0099 if (curidx.isValid()) { 0100 includesModel->removeRows(curidx.row(), 1); 0101 } 0102 updateEnablements(); 0103 } 0104 0105 void IncludesWidget::includePathUrlSelected(const QUrl &url) 0106 { 0107 Q_UNUSED(url); 0108 updateEnablements(); 0109 } 0110 0111 void IncludesWidget::setProject(KDevelop::IProject* w_project) 0112 { 0113 ui->includePathRequester->setStartDir( w_project->path().toUrl() ); 0114 } 0115 0116 void IncludesWidget::updateEnablements() { 0117 // Disable removal of the project root entry which is always first in the list 0118 ui->addIncludePath->setEnabled( QFileInfo::exists(makeIncludeDirAbsolute(ui->includePathRequester->url())) && !ui->includePathRequester->text().isEmpty() ); 0119 ui->removeIncludePath->setEnabled( ui->includePaths->currentIndex().isValid() ); 0120 } 0121 0122 QString IncludesWidget::makeIncludeDirAbsolute(const QUrl &url) const 0123 { 0124 QString localFile = url.toLocalFile(); 0125 if( url.isRelative() ) { 0126 // Relative, make absolute based on startDir of the requester 0127 localFile = ui->includePathRequester->startDir().toLocalFile() + QLatin1Char('/') + url.path(); 0128 } 0129 return localFile; 0130 } 0131 0132 void IncludesWidget::checkIfIncludePathExist() 0133 { 0134 QFileInfo info; 0135 for (auto& include : includesModel->includes()) { 0136 info.setFile(include); 0137 if (!info.exists()) { 0138 ui->errorWidget->setText(i18nc("%1 is an include path", "%1 does not exist", include)); 0139 ui->errorWidget->animatedShow(); 0140 return; 0141 } 0142 } 0143 ui->errorWidget->animatedHide(); 0144 } 0145 0146 #include "moc_includeswidget.cpp"