diff --git a/shell/openprojectdialog.cpp b/shell/openprojectdialog.cpp index ef3fde3267..d59a36e9f5 100644 --- a/shell/openprojectdialog.cpp +++ b/shell/openprojectdialog.cpp @@ -1,246 +1,261 @@ /*************************************************************************** * Copyright (C) 2008 by Andreas Pakulat #include #include #include #include #include #include "core.h" #include "uicontroller.h" +#include "plugincontroller.h" #include "mainwindow.h" #include "shellextension.h" #include "projectsourcepage.h" #include namespace KDevelop { OpenProjectDialog::OpenProjectDialog( bool fetch, const QUrl& startUrl, QWidget* parent ) : KAssistantDialog( parent ) , sourcePage(nullptr) , openPage(nullptr) , projectInfoPage(nullptr) { resize(QSize(700, 500)); + QStringList filters, allEntry; + allEntry << "*." + ShellExtension::getInstance()->projectFileExtension(); + filters << QStringLiteral("%1|%2 (%1)").arg("*." + ShellExtension::getInstance()->projectFileExtension(), ShellExtension::getInstance()->projectFileDescription()); + QVector plugins = ICore::self()->pluginController()->queryExtensionPlugins(QStringLiteral("org.kdevelop.IProjectFileManager")); + foreach(const KPluginMetaData& info, plugins) + { + QStringList filter = KPluginMetaData::readStringList(info.rawData(), QStringLiteral("X-KDevelop-ProjectFilesFilter")); + QString desc = info.value(QStringLiteral("X-KDevelop-ProjectFilesFilterDescription")); + + if (!filter.isEmpty() && !desc.isEmpty()) { + m_projectFilters.insert(info.name(), filter); + allEntry += filter; + filters << QStringLiteral("%1|%2 (%1)").arg(filter.join(QStringLiteral(" ")), desc); + } + } + + filters.prepend(i18n("%1|All Project Files (%1)", allEntry.join(QStringLiteral(" ")))); + QUrl start = startUrl.isValid() ? startUrl : Core::self()->projectController()->projectsBaseDirectory(); start = start.adjusted(QUrl::NormalizePathSegments); KPageWidgetItem* currentPage = 0; if( fetch ) { sourcePageWidget = new ProjectSourcePage( start, this ); connect( sourcePageWidget, &ProjectSourcePage::isCorrect, this, &OpenProjectDialog::validateSourcePage ); sourcePage = addPage( sourcePageWidget, i18n("Select Source") ); currentPage = sourcePage; } - openPageWidget = new OpenProjectPage( start, this ); + openPageWidget = new OpenProjectPage( start, filters, this ); connect( openPageWidget, &OpenProjectPage::urlSelected, this, &OpenProjectDialog::validateOpenUrl ); connect( openPageWidget, &OpenProjectPage::accepted, this, &OpenProjectDialog::openPageAccepted ); openPage = addPage( openPageWidget, i18n("Select a build system setup file, existing KDevelop project, " "or any folder to open as a project") ); if( !fetch ) { currentPage = openPage; } ProjectInfoPage* page = new ProjectInfoPage( this ); connect( page, &ProjectInfoPage::projectNameChanged, this, &OpenProjectDialog::validateProjectName ); connect( page, &ProjectInfoPage::projectManagerChanged, this, &OpenProjectDialog::validateProjectManager ); projectInfoPage = addPage( page, i18n("Project Information") ); setValid( sourcePage, false ); setValid( openPage, false ); setValid( projectInfoPage, false); setAppropriate( projectInfoPage, false ); setCurrentPage( currentPage ); setWindowTitle(i18n("Open Project")); } void OpenProjectDialog::validateSourcePage(bool valid) { setValid(sourcePage, valid); openPageWidget->setUrl(sourcePageWidget->workingDir()); } void OpenProjectDialog::validateOpenUrl( const QUrl& url_ ) { bool isDir = false; QString extension; bool isValid = false; const QUrl url = url_.adjusted(QUrl::StripTrailingSlash); if( url.isLocalFile() ) { QFileInfo info( url.toLocalFile() ); isValid = info.exists(); if ( isValid ) { isDir = info.isDir(); extension = info.suffix(); } } else if ( url.isValid() ) { KIO::StatJob* statJob = KIO::stat( url, KIO::HideProgressInfo ); KJobWidgets::setWindow(statJob, Core::self()->uiControllerInternal()->defaultMainWindow() ); isValid = statJob->exec(); // TODO: do this asynchronously so that the user isn't blocked while typing every letter of the hostname in sftp://hostname if ( isValid ) { KIO::UDSEntry entry = statJob->statResult(); isDir = entry.isDir(); extension = QFileInfo( entry.stringValue( KIO::UDSEntry::UDS_NAME ) ).suffix(); } } if ( isValid ) { // reset header openPage->setHeader(i18n("Open \"%1\" as project", url.fileName())); } else { // report error KColorScheme scheme(palette().currentColorGroup()); const QString errorMsg = i18n("Selected URL is invalid"); openPage->setHeader(QStringLiteral("%2") .arg(scheme.foreground(KColorScheme::NegativeText).color().name(), errorMsg) ); setAppropriate( projectInfoPage, false ); setAppropriate( openPage, true ); setValid( openPage, false ); return; } m_selected = url; if( isDir || extension != ShellExtension::getInstance()->projectFileExtension() ) { setAppropriate( projectInfoPage, true ); m_url = url; if( !isDir ) { m_url = m_url.adjusted(QUrl::StripTrailingSlash | QUrl::RemoveFilename); } ProjectInfoPage* page = qobject_cast( projectInfoPage->widget() ); if( page ) { page->setProjectName( m_url.fileName() ); - OpenProjectPage* page2 = qobject_cast( openPage->widget() ); - if( page2 ) + // Default manager + page->setProjectManager( QStringLiteral("Generic Project Manager") ); + // clear the filelist + m_fileList.clear(); + + if( isDir ) { + // If a dir was selected fetch all files in it + KIO::ListJob* job = KIO::listDir( m_url ); + connect( job, &KIO::ListJob::entries, + this, &OpenProjectDialog::storeFileList); + KJobWidgets::setWindow(job, Core::self()->uiController()->activeMainWindow()); + job->exec(); + } else { + // Else we'lll just take the given file + m_fileList << url.fileName(); + } + // Now find a manager for the file(s) in our filelist. + bool managerFound = false; + foreach( const QString& manager, m_projectFilters.keys() ) { - // Default manager - page->setProjectManager( QStringLiteral("Generic Project Manager") ); - // clear the filelist - m_fileList.clear(); - - if( isDir ) { - // If a dir was selected fetch all files in it - KIO::ListJob* job = KIO::listDir( m_url ); - connect( job, &KIO::ListJob::entries, - this, &OpenProjectDialog::storeFileList); - KJobWidgets::setWindow(job, Core::self()->uiController()->activeMainWindow()); - job->exec(); - } else { - // Else we'lll just take the given file - m_fileList << url.fileName(); - } - // Now find a manager for the file(s) in our filelist. - bool managerFound = false; - foreach( const QString& manager, page2->projectFilters().keys() ) + foreach( const QString& filterexp, m_projectFilters.value(manager) ) { - foreach( const QString& filterexp, page2->projectFilters().value(manager) ) - { - if( !m_fileList.filter( QRegExp( filterexp, Qt::CaseSensitive, QRegExp::Wildcard ) ).isEmpty() ) - { - managerFound = true; - break; - } - } - if( managerFound ) + if( !m_fileList.filter( QRegExp( filterexp, Qt::CaseSensitive, QRegExp::Wildcard ) ).isEmpty() ) { - page->setProjectManager( manager ); + managerFound = true; break; } } + if( managerFound ) + { + page->setProjectManager( manager ); + break; + } } } m_url.setPath( m_url.path() + '/' + m_url.fileName() + '.' + ShellExtension::getInstance()->projectFileExtension() ); } else { setAppropriate( projectInfoPage, false ); m_url = url; } validateProjectInfo(); setValid( openPage, true ); } void OpenProjectDialog::openPageAccepted() { if ( isValid( openPage ) ) { next(); } } void OpenProjectDialog::validateProjectName( const QString& name ) { m_projectName = name; validateProjectInfo(); } void OpenProjectDialog::validateProjectInfo() { setValid( projectInfoPage, (!projectName().isEmpty() && !projectManager().isEmpty()) ); } void OpenProjectDialog::validateProjectManager( const QString& manager ) { m_projectManager = manager; validateProjectInfo(); } QUrl OpenProjectDialog::projectFileUrl() const { return m_url; } QUrl OpenProjectDialog::selectedUrl() const { return m_selected; } QString OpenProjectDialog::projectName() const { return m_projectName; } QString OpenProjectDialog::projectManager() const { return m_projectManager; } void OpenProjectDialog::storeFileList(KIO::Job*, const KIO::UDSEntryList& list) { foreach( const KIO::UDSEntry& entry, list ) { QString name = entry.stringValue( KIO::UDSEntry::UDS_NAME ); if( name != QLatin1String(".") && name != QLatin1String("..") && !entry.isDir() ) { m_fileList << name; } } } } diff --git a/shell/openprojectdialog.h b/shell/openprojectdialog.h index 7aeae56030..87602fe409 100644 --- a/shell/openprojectdialog.h +++ b/shell/openprojectdialog.h @@ -1,75 +1,76 @@ /*************************************************************************** * Copyright (C) 2008 by Andreas Pakulat #include #include class KPageWidgetItem; namespace KIO { class Job; } namespace KDevelop { class ProjectSourcePage; class OpenProjectPage; class OpenProjectDialog : public KAssistantDialog { Q_OBJECT public: OpenProjectDialog( bool fetch, const QUrl& startUrl, QWidget* parent = nullptr ); /** * Return a QUrl pointing to the project's .kdev file. */ QUrl projectFileUrl() const; /** * Return a QUrl pointing to the file, that was selected by the user. * Unlike projectFileUrl(), this can be a .kdev file, as well * as build system file (e.g. CMakeLists.txt). */ QUrl selectedUrl() const; QString projectName() const; QString projectManager() const; private slots: void validateSourcePage( bool ); void validateOpenUrl( const QUrl& ); void validateProjectName( const QString& ); void validateProjectManager( const QString& ); void storeFileList(KIO::Job*, const KIO::UDSEntryList&); void openPageAccepted(); private: void validateProjectInfo(); QUrl m_url; QUrl m_selected; QString m_projectName; QString m_projectManager; KPageWidgetItem* sourcePage; KPageWidgetItem* openPage; KPageWidgetItem* projectInfoPage; QStringList m_fileList; + QMap m_projectFilters; KDevelop::OpenProjectPage* openPageWidget; KDevelop::ProjectSourcePage* sourcePageWidget; }; } #endif diff --git a/shell/openprojectpage.cpp b/shell/openprojectpage.cpp index dabde9727f..42d836fc92 100644 --- a/shell/openprojectpage.cpp +++ b/shell/openprojectpage.cpp @@ -1,129 +1,105 @@ /*************************************************************************** * Copyright (C) 2008 by Andreas Pakulat #include #include #include #include #include #include "shellextension.h" #include "core.h" -#include "plugincontroller.h" namespace KDevelop { -OpenProjectPage::OpenProjectPage( const QUrl& startUrl, QWidget* parent ) +OpenProjectPage::OpenProjectPage( const QUrl& startUrl, const QStringList& filters, + QWidget* parent ) : QWidget( parent ) { QHBoxLayout* layout = new QHBoxLayout( this ); fileWidget = new KFileWidget( startUrl, this); - QStringList filters; - QStringList allEntry; - allEntry << "*."+ShellExtension::getInstance()->projectFileExtension(); - filters << QStringLiteral( "%1|%2 (%1)").arg("*."+ShellExtension::getInstance()->projectFileExtension(), ShellExtension::getInstance()->projectFileDescription()); - QVector plugins = ICore::self()->pluginController()->queryExtensionPlugins( QStringLiteral( "org.kdevelop.IProjectFileManager" ) ); - foreach(const KPluginMetaData& info, plugins) - { - QStringList filter = KPluginMetaData::readStringList(info.rawData(), QStringLiteral("X-KDevelop-ProjectFilesFilter")); - QString desc = info.value(QStringLiteral("X-KDevelop-ProjectFilesFilterDescription")); - QString filterline; - if(!filter.isEmpty() && !desc.isEmpty()) { - m_projectFilters.insert(info.name(), filter); - allEntry += filter; - filters << QStringLiteral("%1|%2 (%1)").arg(filter.join(QStringLiteral(" ")), desc); - } - } - - filters.prepend( i18n( "%1|All Project Files (%1)", allEntry.join( QStringLiteral(" ") ) ) ); - fileWidget->setFilter( filters.join(QStringLiteral("\n")) ); fileWidget->setMode( KFile::Modes( KFile::File | KFile::Directory | KFile::ExistingOnly ) ); layout->addWidget( fileWidget ); KDirOperator* ops = fileWidget->dirOperator(); // Emitted for changes in the places view, the url navigator and when using the back/forward/up buttons connect(ops, &KDirOperator::urlEntered, this, &OpenProjectPage::opsEntered); // Emitted when selecting an entry from the "Name" box or editing in there connect( fileWidget->locationEdit(), &KUrlComboBox::editTextChanged, this, &OpenProjectPage::comboTextChanged); // Emitted when clicking on a file in the fileview area connect( fileWidget, &KFileWidget::fileHighlighted, this, &OpenProjectPage::highlightFile ); connect( fileWidget->dirOperator()->dirLister(), static_cast(&KDirLister::completed), this, &OpenProjectPage::dirChanged); connect( fileWidget, &KFileWidget::accepted, this, &OpenProjectPage::accepted); } QUrl OpenProjectPage::getAbsoluteUrl( const QString& file ) const { QUrl u(file); if( u.isRelative() ) { u = fileWidget->baseUrl().resolved( u ); } return u; } void OpenProjectPage::setUrl(const QUrl& url) { fileWidget->setUrl(url, false); } void OpenProjectPage::dirChanged(const QUrl& /*url*/) { if(fileWidget->selectedFiles().isEmpty()) { KFileItemList items=fileWidget->dirOperator()->dirLister()->items(); foreach(const KFileItem& item, items) { if(item.url().path().endsWith(ShellExtension::getInstance()->projectFileExtension()) && item.isFile()) fileWidget->setSelection(item.url().url()); } } } void OpenProjectPage::showEvent(QShowEvent* ev) { fileWidget->locationEdit()->setFocus(); QWidget::showEvent(ev); } void OpenProjectPage::highlightFile(const QUrl& file) { emit urlSelected(file); } void OpenProjectPage::opsEntered(const QUrl& url) { emit urlSelected(url); } void OpenProjectPage::comboTextChanged( const QString& file ) { emit urlSelected( getAbsoluteUrl( file ) ); } -QMap OpenProjectPage::projectFilters() const -{ - return m_projectFilters; -} - } diff --git a/shell/openprojectpage.h b/shell/openprojectpage.h index 93deb49634..1e0ff606eb 100644 --- a/shell/openprojectpage.h +++ b/shell/openprojectpage.h @@ -1,53 +1,52 @@ /*************************************************************************** * Copyright (C) 2008 by Andreas Pakulat #include class QUrl; class KFileWidget; namespace KDevelop { class OpenProjectPage : public QWidget { Q_OBJECT public: - explicit OpenProjectPage( const QUrl& startUrl, QWidget* parent = nullptr ); - QMap projectFilters() const; + explicit OpenProjectPage( const QUrl& startUrl, const QStringList& filters, + QWidget* parent = nullptr ); void setUrl(const QUrl& url); signals: void urlSelected(const QUrl&); void accepted(); protected: void showEvent(QShowEvent*) override; private slots: void highlightFile(const QUrl&); void opsEntered(const QUrl& item); void comboTextChanged(const QString&); void dirChanged(const QUrl& url); private: QUrl getAbsoluteUrl(const QString&) const; KFileWidget* fileWidget; - QMap m_projectFilters; }; } #endif