diff --git a/shell/projectcontroller.cpp b/shell/projectcontroller.cpp index 04ec06dc7c..0f467df9cc 100644 --- a/shell/projectcontroller.cpp +++ b/shell/projectcontroller.cpp @@ -1,819 +1,802 @@ /* This file is part of KDevelop Copyright 2006 Adam Treat Copyright 2007 Andreas Pakulat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "projectcontroller.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "core.h" #include "project.h" #include "mainwindow.h" #include "shellextension.h" #include "plugincontroller.h" #include "uicontroller.h" #include "documentcontroller.h" #include "openprojectdialog.h" #include #include #include namespace KDevelop { bool reopenProjectsOnStartup() { KConfigGroup group = Core::self()->activeSession()->config()->group( "Project Manager" ); return group.readEntry( "Reopen Projects On Startup", false ); } bool parseAllProjectSources() { KConfigGroup group = Core::self()->activeSession()->config()->group( "Project Manager" ); return group.readEntry( "Parse All Project Sources", true ); } class ProjectControllerPrivate { public: QList m_projects; QMap< IProject*, QList > m_projectPlugins; QPointer m_recentAction; Core* m_core; // IProject* m_currentProject; ProjectModel* model; QItemSelectionModel* selectionModel; QMap > m_cfgDlgs; QPointer m_closeAllProjects; QPointer m_closeProject; QPointer m_openConfig; IProjectDialogProvider* dialog; QList m_currentlyOpening; // project-file urls that are being opened IProject* m_configuringProject; ProjectController* q; bool m_foundProjectFile; //Temporary flag used while searching the hierarchy for a project file ProjectControllerPrivate( ProjectController* p ) : m_core(0), model(0), selectionModel(0), dialog(0), m_configuringProject(0), q(p), m_foundProjectFile(false) { } void unloadAllProjectPlugins() { if( m_projects.isEmpty() ) m_core->pluginControllerInternal()->unloadProjectPlugins(); } void projectConfig( QObject * obj ) { if( !obj ) return; Project* proj = qobject_cast(obj); if( !proj ) return; if( !m_cfgDlgs.contains( proj ) ) { //@FIXME: compute a blacklist, based on a query for all KDevelop //plugins implementing IProjectManager, removing from that the //plugin that manages this project. Set this as blacklist on the //dialog //@FIXME: Currently it is important to set a parentApp on the kcms //that's different from the component name of the application, else //the plugin will show up on all projects settings dialogs. QStringList pluginsForPrj = findPluginsForProject( proj ); kDebug() << "Using pluginlist:" << pluginsForPrj; pluginsForPrj << "kdevplatformproject"; // for project-wide env settings. m_cfgDlgs[proj] = new KSettings::Dialog( pluginsForPrj, m_core->uiController()->activeMainWindow() ); m_cfgDlgs[proj]->setKCMArguments( QStringList() << proj->developerTempFile() << proj->projectTempFile() << proj->projectFileUrl().url() << proj->developerFileUrl().url() ); } m_configuringProject = proj; m_cfgDlgs[proj]->exec(); proj->projectConfiguration()->sync(); m_configuringProject = 0; } void saveListOfOpenedProjects() { KSharedConfig::Ptr config = Core::self()->activeSession()->config(); KConfigGroup group = config->group( "General Options" ); KUrl::List openProjects; foreach( IProject* project, m_projects ) { openProjects.append(project->projectFileUrl()); } group.writeEntry( "Open Projects", openProjects.toStringList() ); group.sync(); } QStringList findPluginsForProject( IProject* project ) { QList plugins = m_core->pluginController()->loadedPlugins(); QStringList pluginnames; for( QList::iterator it = plugins.begin(); it != plugins.end(); ++it ) { IPlugin* plugin = *it; IProjectFileManager* iface = plugin->extension(); if( !iface || plugin == project->managerPlugin() ) pluginnames << m_core->pluginController()->pluginInfo( plugin ).pluginName(); } return pluginnames; } void notifyProjectConfigurationChanged() { if( m_configuringProject ) { emit q->projectConfigurationChanged( m_configuringProject ); } } void updateActionStates( Context* ctx ) { ProjectItemContext* itemctx = dynamic_cast(ctx); m_openConfig->setEnabled( itemctx && itemctx->items().count() == 1 ); m_closeProject->setEnabled( itemctx && itemctx->items().count() > 0 ); } void openProjectConfig() { ProjectItemContext* ctx = dynamic_cast( Core::self()->selectionController()->currentSelection() ); if( ctx && ctx->items().count() == 1 ) { q->configureProject( ctx->items().at(0)->project() ); } } void closeSelectedProjects() { ProjectItemContext* ctx = dynamic_cast( Core::self()->selectionController()->currentSelection() ); if( ctx && ctx->items().count() > 0 ) { QSet projects; foreach( ProjectBaseItem* item, ctx->items() ) { projects.insert( item->project() ); } foreach( IProject* project, projects ) { q->closeProject( project ); } } } }; IProjectDialogProvider::IProjectDialogProvider() {} IProjectDialogProvider::~IProjectDialogProvider() {} ProjectDialogProvider::ProjectDialogProvider(ProjectControllerPrivate* const p) : d(p) {} ProjectDialogProvider::~ProjectDialogProvider() {} bool writeNewProjectFile( KSharedConfig::Ptr cfg, const QString& name, const QString& manager ) { if (!cfg->isConfigWritable(true)) { kDebug() << "can't write to configfile"; return false; } KConfigGroup grp = cfg->group( "Project" ); grp.writeEntry( "Name", name ); grp.writeEntry( "Manager", manager ); cfg->sync(); return true; } bool projectFileExists( const KUrl& u ) { if( u.isLocalFile() ) { return QFileInfo( u.toLocalFile() ).exists(); } else { return KIO::NetAccess::exists( u, KIO::NetAccess::DestinationSide, Core::self()->uiControllerInternal()->activeMainWindow() ); } } KUrl ProjectDialogProvider::askProjectConfigLocation(const KUrl& startUrl) { Q_ASSERT(d); OpenProjectDialog dlg( startUrl, Core::self()->uiController()->activeMainWindow() ); if(dlg.exec() == QDialog::Rejected) return KUrl(); KUrl projectFileUrl = dlg.projectFileUrl(); kDebug() << "selected project:" << projectFileUrl << dlg.projectName() << dlg.projectManager(); if( !projectFileExists( projectFileUrl ) ) { if( projectFileUrl.isLocalFile() ) { bool ok = writeNewProjectFile( KSharedConfig::openConfig( projectFileUrl.toLocalFile(), KConfig::SimpleConfig ), dlg.projectName(), dlg.projectManager() ); if (!ok) return KUrl(); } else { KTemporaryFile tmp; ///TODO: do we really want to set setAutoRemove to false?? tmp.setAutoRemove( false ); tmp.open(); bool ok = writeNewProjectFile( KSharedConfig::openConfig( tmp.fileName(), KConfig::SimpleConfig ), dlg.projectName(), dlg.projectManager() ); if (!ok) return KUrl(); ok = KIO::NetAccess::upload( tmp.fileName(), projectFileUrl, Core::self()->uiControllerInternal()->defaultMainWindow() ); if (!ok) { KMessageBox::error(d->m_core->uiControllerInternal()->defaultMainWindow(), i18n("Unable to create configuration file %1", projectFileUrl.url())); return KUrl(); } } } return projectFileUrl; } bool ProjectDialogProvider::userWantsReopen() { Q_ASSERT(d); return (KMessageBox::questionYesNo( d->m_core->uiControllerInternal()->defaultMainWindow(), i18n( "Reopen the current project?" ) ) == KMessageBox::No) ? false : true; } void ProjectController::setDialogProvider(IProjectDialogProvider* dialog) { Q_ASSERT(d->dialog); delete d->dialog; d->dialog = dialog; } ProjectController::ProjectController( Core* core ) : IProjectController( core ), d( new ProjectControllerPrivate( this ) ) { setObjectName("ProjectController"); d->m_core = core; d->model = new ProjectModel(); d->selectionModel = new QItemSelectionModel(d->model); if(!(Core::self()->setupFlags() & Core::NoUi)) setupActions(); loadSettings(false); d->dialog = new ProjectDialogProvider(d); KSettings::Dispatcher::registerComponent( KComponentData("kdevplatformproject"), this, "notifyProjectConfigurationChanged" ); } void ProjectController::setupActions() { KActionCollection * ac = d->m_core->uiControllerInternal()->defaultMainWindow()->actionCollection(); KAction *action; action = ac->addAction( "project_open" ); action->setText(i18n( "Open / Import Project..." ) ); connect( action, SIGNAL( triggered( bool ) ), SLOT( openProject() ) ); action->setToolTip( i18n( "Open / Import Project" ) ); action->setWhatsThis( i18n( "Open / Import project

Open an existing KDevelop 4 project or import an existing Project into KDevelop 4. This entry allows to select a KDevelop4 project file or an existing directory to open it in KDevelop. When opening an existing directory that does not yet have a KDevelop4 project file, the file will be created.

" ) ); action->setIcon(KIcon("project-open")); // action = ac->addAction( "project_close" ); // action->setText( i18n( "C&lose Project" ) ); // connect( action, SIGNAL( triggered( bool ) ), SLOT( closeProject() ) ); // action->setToolTip( i18n( "Close project" ) ); // action->setWhatsThis( i18n( "Close project

Closes the current project." ) ); // action->setEnabled( false ); d->m_closeAllProjects = action = ac->addAction( "project_close_all" ); action->setText( i18n( "Close All Projects" ) ); connect( action, SIGNAL( triggered( bool ) ), SLOT( closeAllProjects() ) ); action->setToolTip( i18n( "Close all currently open projects" ) ); action->setWhatsThis( i18n( "Close all projects

Closes all of the currently open projects.

" ) ); action->setEnabled( false ); action->setIcon(KIcon("project-development-close-all")); d->m_closeProject = action = ac->addAction( "project_close" ); connect( action, SIGNAL( triggered( bool ) ), SLOT( closeSelectedProjects() ) ); action->setText( i18n( "Close Project(s)" ) ); action->setIcon( KIcon( "project-development-close" ) ); action->setToolTip( i18n( "Closes all currently selected projects" ) ); action->setEnabled( false ); d->m_openConfig = action = ac->addAction( "project_open_config" ); connect( action, SIGNAL( triggered( bool ) ), SLOT( openProjectConfig() ) ); action->setText( i18n( "Open Configuration..." ) ); action->setIcon( KIcon("configure") ); action->setEnabled( false ); KSharedConfig * config = KGlobal::config().data(); // KConfigGroup group = config->group( "General Options" ); d->m_recentAction = new KRecentFilesAction( this ); connect( d->m_recentAction, SIGNAL(urlSelected(const KUrl&)), SLOT( openProject( const KUrl& ) )); ac->addAction( "project_open_recent", d->m_recentAction ); d->m_recentAction->setText( i18n( "Open Recent" ) ); d->m_recentAction->setToolTip( i18n( "Open recent project" ) ); d->m_recentAction->setWhatsThis( i18n( "Open recent project

Opens recently opened project.

" ) ); d->m_recentAction->loadEntries( KConfigGroup(config, "RecentProjects") ); KAction* openProjectForFileAction = new KAction( this ); ac->addAction("project_open_for_file", openProjectForFileAction); openProjectForFileAction->setText(i18n("Open Project for Current File")); connect( openProjectForFileAction, SIGNAL(triggered(bool)), SLOT(openProjectForUrlSlot(bool))); } ProjectController::~ProjectController() { delete d->model; delete d->dialog; delete d; } void ProjectController::cleanup() { KSharedConfig::Ptr config = Core::self()->activeSession()->config(); KConfigGroup group = config->group( "General Options" ); KUrl::List openProjects; foreach( IProject* project, d->m_projects ) { openProjects.append(project->projectFileUrl()); closeProject( project ); } group.writeEntry( "Open Projects", openProjects.toStringList() ); } void ProjectController::initialize() { if (reopenProjectsOnStartup()) { KSharedConfig::Ptr config = Core::self()->activeSession()->config(); KConfigGroup group = config->group( "General Options" ); KUrl::List openProjects = group.readEntry( "Open Projects", QStringList() ); foreach (const KUrl& url, openProjects) openProject(url); } connect( Core::self()->selectionController(), SIGNAL(selectionChanged(KDevelop::Context*)), SLOT(updateActionStates(KDevelop::Context*)) ); } void ProjectController::loadSettings( bool projectIsLoaded ) { Q_UNUSED(projectIsLoaded) } void ProjectController::saveSettings( bool projectIsLoaded ) { Q_UNUSED( projectIsLoaded ); } int ProjectController::projectCount() const { return d->m_projects.count(); } IProject* ProjectController::projectAt( int num ) const { if( !d->m_projects.isEmpty() && num >= 0 && num < d->m_projects.count() ) return d->m_projects.at( num ); return 0; } QList ProjectController::projects() const { return d->m_projects; } void ProjectController::eventuallyOpenProjectFile(KIO::Job* _job, KIO::UDSEntryList entries ) { KIO::SimpleJob* job(dynamic_cast(_job)); Q_ASSERT(job); foreach(KIO::UDSEntry entry, entries) { if(d->m_foundProjectFile) break; if(!entry.isDir()) { QString name = entry.stringValue( KIO::UDSEntry::UDS_NAME ); if(name.endsWith(".kdev4")) { //We have found a project-file, open it KUrl u(job->url()); u.addPath(name); openProject(u); d->m_foundProjectFile = true; } } } } void ProjectController::openProjectForUrlSlot(bool) { if(ICore::self()->documentController()->activeDocument()) { KUrl url = ICore::self()->documentController()->activeDocument()->url(); IProject* project = ICore::self()->projectController()->findProjectForUrl(url); if(!project) { openProjectForUrl(url); }else{ KMessageBox::error(Core::self()->uiController()->activeMainWindow(), i18n("Project already open: %1", project->name())); } }else{ KMessageBox::error(Core::self()->uiController()->activeMainWindow(), i18n("No active document")); } } void ProjectController::openProjectForUrl(const KUrl& sourceUrl) { KUrl dirUrl = sourceUrl.upUrl(); KUrl testAt = dirUrl; d->m_foundProjectFile = false; while(!testAt.path().isEmpty()) { KUrl testProjectFile(testAt); KIO::ListJob* job = KIO::listDir(testAt); connect(job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), SLOT(eventuallyOpenProjectFile(KIO::Job*,KIO::UDSEntryList))); KIO::NetAccess::synchronousRun(job, ICore::self()->uiController()->activeMainWindow()); if(d->m_foundProjectFile) { //Fine! We have directly opened the project d->m_foundProjectFile = false; return; } KUrl oldTest = testAt; testAt = testAt.upUrl(); if(oldTest == testAt) break; } KUrl askForOpen = d->dialog->askProjectConfigLocation(dirUrl); if(askForOpen.isValid()) openProject(askForOpen); } void ProjectController::openProject( const KUrl &projectFile ) { KUrl url = projectFile; if ( url.isEmpty() ) { url = d->dialog->askProjectConfigLocation(); if ( url.isEmpty() ) return; } if ( !url.isValid() ) { KMessageBox::error(Core::self()->uiControllerInternal()->activeMainWindow(), i18n("Invalid Location: %1", url.prettyUrl())); return; } if ( d->m_currentlyOpening.contains(url)) { kDebug() << "Already opening " << url << ". Aborting."; KPassivePopup::message( i18n( "Project already being opened"), i18n( "Already opening %1, not opening again", url.prettyUrl() ), Core::self()->uiController()->activeMainWindow() ); return; } foreach( IProject* project, d->m_projects ) { if ( url == project->projectFileUrl() ) { if ( d->dialog->userWantsReopen() ) { // close first, then open again by falling through closeProject(project); } else { // abort return; } } } - //FIXME Create the hidden directory if it doesn't exist - if ( loadProjectPart() ) - { - //The project file has been opened. - //Now we can load settings for all of the Core objects including this one!! -// Core::loadSettings(); - d->m_core->pluginControllerInternal()->loadProjectPlugins(); - } else { - KMessageBox::error(Core::self()->uiControllerInternal()->activeMainWindow(), - i18n("Cannot Load Projects View plugin, aborting.")); - return; - } + d->m_core->pluginControllerInternal()->loadProjectPlugins(); Project* project = new Project(); emit projectAboutToBeOpened( project ); if ( !project->open( url ) ) { KMessageBox::error(Core::self()->uiControllerInternal()->activeMainWindow(), i18n( "Project could not be opened: %1", url.prettyUrl() )); delete project; return; } d->m_currentlyOpening << url; d->m_closeAllProjects->setEnabled(true); return; } void ProjectController::projectImportingFinished( IProject* project ) { if( !project ) { kWarning() << "OOOPS: 0-pointer project"; return; } IPlugin *managerPlugin = project->managerPlugin(); QList pluglist; pluglist.append( managerPlugin ); d->m_projectPlugins.insert( project, pluglist ); d->m_projects.append( project ); d->saveListOfOpenedProjects(); // KActionCollection * ac = d->m_core->uiController()->defaultMainWindow()->actionCollection(); // QAction * action; //action = ac->action( "project_close" ); //action->setEnabled( true ); d->m_recentAction->addUrl( project->projectFileUrl() ); KSharedConfig * config = KGlobal::config().data(); KConfigGroup recentGroup = config->group("RecentProjects"); d->m_recentAction->saveEntries( recentGroup ); config->sync(); d->m_currentlyOpening.removeAll(project->projectFileUrl()); emit projectOpened( project ); if (parseAllProjectSources()) { KJob* parseProjectJob = new KDevelop::ParseProjectJob(project); ICore::self()->runController()->registerJob(parseProjectJob); } KUrl::List parseList; // Add all currently open files that belong to the project to the background-parser, // since more information may be available for parsing them now(Like include-paths). foreach(IDocument* document, Core::self()->documentController()->openDocuments()) { if(!project->filesForUrl(document->url()).isEmpty()) { parseList.append(document->url()); } } Core::self()->languageController()->backgroundParser()->addDocumentList( parseList, KDevelop::TopDUContext::AllDeclarationsContextsAndUses, 10 ); } // helper method for closeProject() void ProjectController::unloadUnusedProjectPlugins(IProject* proj) { QList pluginsForProj = d->m_projectPlugins.value( proj ); d->m_projectPlugins.remove( proj ); QList otherProjectPlugins; Q_FOREACH( QList _list, d->m_projectPlugins ) { otherProjectPlugins << _list; } QSet pluginsForProjSet = QSet::fromList( pluginsForProj ); QSet otherPrjPluginsSet = QSet::fromList( otherProjectPlugins ); // loaded - target = tobe unloaded. QSet tobeRemoved = pluginsForProjSet.subtract( otherPrjPluginsSet ); Q_FOREACH( IPlugin* _plugin, tobeRemoved ) { KPluginInfo _plugInfo = Core::self()->pluginController()->pluginInfo( _plugin ); if( _plugInfo.isValid() ) { QString _plugName = _plugInfo.pluginName(); kDebug() << "about to unloading :" << _plugName; Core::self()->pluginController()->unloadPlugin( _plugName ); } } } // helper method for closeProject() void ProjectController::closeAllOpenedFiles(IProject* proj) { Q_FOREACH( ProjectFileItem *fileItem, proj->files() ) { Core::self()->documentControllerInternal()->closeDocument( fileItem->url() ); } } // helper method for closeProject() void ProjectController::initializePluginCleanup(IProject* proj) { // Unloading (and thus deleting) these plugins is not a good idea just yet // as we're being called by the view part and it gets deleted when we unload the plugin(s) // TODO: find a better place to unload connect(proj, SIGNAL(destroyed(QObject*)), this, SLOT(unloadAllProjectPlugins())); if (d->m_closeAllProjects) { d->m_closeAllProjects->setEnabled(false); } } void ProjectController::closeProject(IProject* proj) { if(!proj || d->m_projects.indexOf(proj) == -1) { return; } d->m_projects.removeAll(proj); emit projectClosing(proj); //Core::self()->saveSettings(); // The project file is being closed. // Now we can save settings for all of the Core // objects including this one!! unloadUnusedProjectPlugins(proj); closeAllOpenedFiles(proj); proj->close(); proj->deleteLater(); //be safe when deleting if (d->m_projects.isEmpty()) { initializePluginCleanup(proj); } d->saveListOfOpenedProjects(); emit projectClosed(proj); return; } -bool ProjectController::loadProjectPart() -{ - - return true; -} - ProjectModel* ProjectController::projectModel() { return d->model; } IProject* ProjectController::findProjectForUrl( const KUrl& url ) const { Q_FOREACH( IProject* proj, d->m_projects ) { if( proj->inProject( url ) ) return proj; } return 0; } IProject* ProjectController::findProjectByName( const QString& name ) { Q_FOREACH( IProject* proj, d->m_projects ) { if( proj->name() == name ) { return proj; } } return 0; } void ProjectController::configureProject( IProject* project ) { d->projectConfig( project ); } void ProjectController::addProject(IProject* project) { d->m_projects.append( project ); } void ProjectController::closeAllProjects() { foreach (IProject* project, projects()) { closeProject(project); } } QItemSelectionModel* ProjectController::projectSelectionModel() { return d->selectionModel; } bool ProjectController::isProjectNameUsed( const QString& name ) const { foreach( IProject* p, projects() ) { if( p->name() == name ) { return true; } } return false; } KUrl ProjectController::projectsBaseDirectory() const { KConfigGroup group = Core::self()->activeSession()->config()->group( "Project Manager" ); return group.readEntry( "Projects Base Directory", KUrl( QDir::homePath()+"/projects" ) ); } QString ProjectController::prettyFileName(KUrl url, FormattingOptions format) const { IProject* project = Core::self()->projectController()->findProjectForUrl(url); QString prefixText = url.upUrl().pathOrUrl(KUrl::AddTrailingSlash); if (project) { if (format == FormatHtml) { prefixText = "" + project->name() + "/"; } else { prefixText = project->name() + '/'; } prefixText += project->relativeUrl(url.upUrl()).path(KUrl::AddTrailingSlash); } if (format == FormatHtml) { return prefixText + "" + url.fileName() + ""; } else { return prefixText + url.fileName(); } } } #include "projectcontroller.moc" diff --git a/shell/projectcontroller.h b/shell/projectcontroller.h index 97e0b8744a..5f60696d61 100644 --- a/shell/projectcontroller.h +++ b/shell/projectcontroller.h @@ -1,138 +1,137 @@ /* This file is part of KDevelop Copyright 2006 Adam Treat Copyright 2007 Andreas Pakulat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEVPROJECTCONTROLLER_H #define KDEVPROJECTCONTROLLER_H #include #include #include "shellexport.h" class QModelIndex; namespace KIO { class Job; } namespace KDevelop { class IProject; class Core; class UiController; class KDEVPLATFORMSHELL_EXPORT IProjectDialogProvider : public QObject { Q_OBJECT public: IProjectDialogProvider(); virtual ~IProjectDialogProvider(); public Q_SLOTS: virtual KUrl askProjectConfigLocation(const KUrl& startUrl = KUrl()) = 0; virtual bool userWantsReopen() = 0; }; class KDEVPLATFORMSHELL_EXPORT ProjectController : public IProjectController { Q_OBJECT friend class Core; friend class CorePrivate; friend class ProjectPreferences; public: ProjectController( Core* core ); virtual ~ProjectController(); virtual IProject* projectAt( int ) const; virtual int projectCount() const; virtual QList projects() const; virtual ProjectModel* projectModel(); virtual QItemSelectionModel* projectSelectionModel(); virtual IProject* findProjectByName( const QString& name ); IProject* findProjectForUrl( const KUrl& ) const; void addProject(IProject*); // IProject* currentProject() const; virtual bool isProjectNameUsed( const QString& name ) const; void setDialogProvider(IProjectDialogProvider*); KUrl projectsBaseDirectory() const; QString prettyFileName(KUrl url, FormattingOptions format = FormatHtml) const; public Q_SLOTS: virtual void openProjectForUrl( const KUrl &sourceUrl ); virtual void openProject( const KUrl &KDev4ProjectFile = KUrl() ); void projectImportingFinished( IProject* ); virtual void closeProject( IProject* ); virtual void closeAllProjects(); virtual void configureProject( IProject* ); void eventuallyOpenProjectFile(KIO::Job*,KIO::UDSEntryList); void openProjectForUrlSlot(bool); // void changeCurrentProject( ProjectBaseItem* ); protected: virtual void loadSettings( bool projectIsLoaded ); virtual void saveSettings( bool projectIsLoaded ); private: //FIXME Do not load all of this just for the project being opened... //void legacyLoading(); void setupActions(); void cleanup(); - bool loadProjectPart(); void initialize(); // helper methods for closeProject() void unloadUnusedProjectPlugins(IProject* proj); void disableProjectCloseAction(); void closeAllOpenedFiles(IProject* proj); void initializePluginCleanup(IProject* proj); private: Q_PRIVATE_SLOT(d, void projectConfig( QObject* ) ) Q_PRIVATE_SLOT(d, void unloadAllProjectPlugins() ) Q_PRIVATE_SLOT(d, void notifyProjectConfigurationChanged() ) Q_PRIVATE_SLOT(d, void updateActionStates( KDevelop::Context* ) ) Q_PRIVATE_SLOT(d, void closeSelectedProjects() ) Q_PRIVATE_SLOT(d, void openProjectConfig() ) class ProjectControllerPrivate* const d; friend class ProjectControllerPrivate; }; class ProjectDialogProvider : public IProjectDialogProvider { Q_OBJECT public: ProjectDialogProvider(ProjectControllerPrivate* const p); virtual ~ProjectDialogProvider(); ProjectControllerPrivate* const d; public Q_SLOTS: virtual KUrl askProjectConfigLocation(const KUrl& sta); virtual bool userWantsReopen(); }; } #endif