diff --git a/shell/partcontroller.cpp b/shell/partcontroller.cpp index e329f914cd..f004afde80 100644 --- a/shell/partcontroller.cpp +++ b/shell/partcontroller.cpp @@ -1,292 +1,292 @@ /*************************************************************************** * Copyright 2006 Adam Treat * * Copyright 2007 Alexander Dymo * * * * This program 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 program 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 General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "partcontroller.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "core.h" // #include "kdevmainwindow.h" // #include "kdevconfig.h" #include "editorintegrator.h" namespace KDevelop { class PartControllerPrivate { public: QString m_editor; QStringList m_textTypes; Core *m_core; KParts::Factory *findPartFactory( const QString &mimeType, const QString &partType, const QString &preferredName = QString() ) { KService::List offers = KMimeTypeTrader::self() ->query( mimeType, "KParts/ReadOnlyPart", QString( "'%1' in ServiceTypes" ).arg( partType ) ); if ( offers.count() > 0 ) { KService::Ptr ptr; // if there is a preferred plugin we'll take it if ( !preferredName.isEmpty() ) { KService::List::ConstIterator it; for ( it = offers.begin(); it != offers.end(); ++it ) { if ( ( *it ) ->desktopEntryName() == preferredName ) { ptr = ( *it ); } } } // else we just take the first in the list if ( !ptr ) { ptr = offers.first(); } KParts::Factory *factory = static_cast( KLibLoader::self() ->factory( QFile::encodeName( ptr->library() ) ) ); return factory; } return 0; } }; PartController::PartController(Core *core, QWidget *toplevel) : KParts::PartManager( toplevel, 0 ), d(new PartControllerPrivate) { d->m_core = core; //Cache this as it is too expensive when creating parts // KConfig * config = Config::standard(); // config->setGroup( "General" ); // // d->m_textTypes = config->readEntry( "TextTypes", QStringList() ); // // config ->setGroup( "Editor" ); - // d->m_editor = config->readPathEntry( "EmbeddedKTextEditor" ); + // d->m_editor = config->readPathEntry( "EmbeddedKTextEditor", QString() ); } PartController::~PartController() {} //MOVE BACK TO DOCUMENTCONTROLLER OR MULTIBUFFER EVENTUALLY bool PartController::isTextType( KMimeType::Ptr mimeType ) { bool isTextType = false; if ( d->m_textTypes.contains( mimeType->name() ) ) { isTextType = true; } bool isKDEText = false; QVariant v = mimeType->property( "X-KDE-text" ); if ( v.isValid() ) isKDEText = v.toBool(); // is this regular text - open in editor return ( isTextType || isKDEText || mimeType->is( "text/plain" ) || mimeType->is( "text/html" ) || mimeType->is( "application/x-zerosize" ) ); } KTextEditor::Document* PartController::createTextPart( const KUrl &url, const QString &encoding, bool activate ) { KTextEditor::Document* doc = qobject_cast( createPart( "text/plain", "KTextEditor/Document", "KTextEditor::Editor", d->m_editor ) ); EditorIntegrator::addDocument( doc ); if ( !encoding.isNull() ) { KParts::OpenUrlArguments args = doc->arguments(); args.setMimeType( QString( "text/plain;" ) + encoding ); doc->setArguments( args ); } if ( activate ) { doc->openUrl( url ); } return doc; } void PartController::removePart( KParts::Part *part ) { if ( KTextEditor::Document * doc = qobject_cast( part ) ) { if ( KTextEditor::SmartInterface * smart = dynamic_cast( doc ) ) { // FIXME not supposed to delete locked mutexes... QMutexLocker lock ( smart->smartMutex() ); KParts::PartManager::removePart( part ); return ; } kWarning() << "Deleting text editor" << doc << "which does not have a smart interface." ; } KParts::PartManager::removePart( part ); } KParts::Part* PartController::createPart( const QString & mimeType, const QString & partType, const QString & className, const QString & preferredName ) { KParts::Factory * editorFactory = d->findPartFactory( mimeType, partType, preferredName ); if ( !className.isEmpty() && editorFactory ) { return editorFactory->createPart( 0, this, className.toLatin1() ); } return 0; } KParts::Part* PartController::createPart( const KUrl & url ) { KMimeType::Ptr mimeType; if ( url.isEmpty() ) //create a part for empty text file mimeType = KMimeType::mimeType("text/plain"); else if ( !url.isValid() ) return 0; else mimeType = KMimeType::findByUrl( url ); QString className; QString services[] = { "KParts/ReadWritePart", "KParts/ReadOnlyPart" }; QString classNames[] = { "KParts::ReadWritePart", "KParts::ReadOnlyPart" }; KParts::Factory *editorFactory = 0; for ( uint i = 0; i < 2; ++i ) { editorFactory = d->findPartFactory( mimeType->name(), services[ i ] ); if ( editorFactory ) { className = classNames[ i ]; break; } } if ( !className.isEmpty() && editorFactory ) { KParts::Part * part = editorFactory->createPart( 0, this, className.toLatin1() ); readOnly( part ) ->openUrl( url ); return part; } return 0; } KParts::ReadOnlyPart* PartController::activeReadOnly() const { return readOnly( activePart() ); } KParts::ReadWritePart* PartController::activeReadWrite() const { return readWrite( activePart() ); } KParts::ReadOnlyPart* PartController::readOnly( KParts::Part * part ) const { return qobject_cast( part ); } KParts::ReadWritePart* PartController::readWrite( KParts::Part * part ) const { return qobject_cast( part ); } void PartController::loadSettings( bool projectIsLoaded ) { Q_UNUSED( projectIsLoaded ); } void PartController::saveSettings( bool projectIsLoaded ) { Q_UNUSED( projectIsLoaded ); } void PartController::initialize() {} void PartController::cleanup() {} } #include "partcontroller.moc" diff --git a/shell/project.cpp b/shell/project.cpp index da06901fd0..e7443cabb7 100644 --- a/shell/project.cpp +++ b/shell/project.cpp @@ -1,464 +1,464 @@ /* This file is part of the KDE project Copyright 2001 Matthias Hoelzer-Kluepfel Copyright 2002-2003 Roberto Raggi Copyright 2002 Simon Hausmann Copyright 2003 Jens Dagerbo Copyright 2003 Mario Scalas Copyright 2003-2004 Alexander Dymo Copyright 2006 Matt Rogers 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 "project.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "iprojectfilemanager.h" #include "ibuildsystemmanager.h" #include "core.h" #include "iplugin.h" #include "mainwindow.h" #include "projectcontroller.h" #include "importprojectjob.h" #include "projectmodel.h" #include "iplugincontroller.h" #include "uicontroller.h" #include "ilanguagecontroller.h" #include "backgroundparser.h" namespace KDevelop { class ProjectPrivate { public: KUrl folder; KUrl projectFileUrl; KUrl developerFileUrl; QString developerTempFile; QString projectTempFile; KTemporaryFile* tmp; IPlugin* manager; // IPersistentHash persistentHash; ProjectFolderItem* topItem; QString name; KSharedConfig::Ptr m_cfg; IProject *project; QList recurseFiles( ProjectBaseItem * projectItem ) { QList files; if ( ProjectFolderItem * folder = projectItem->folder() ) { QList folder_list = folder->folderList(); for ( QList::Iterator it = folder_list.begin(); it != folder_list.end(); ++it ) files += recurseFiles( ( *it ) ); QList target_list = folder->targetList(); for ( QList::Iterator it = target_list.begin(); it != target_list.end(); ++it ) files += recurseFiles( ( *it ) ); QList file_list = folder->fileList(); for ( QList::Iterator it = file_list.begin(); it != file_list.end(); ++it ) files += recurseFiles( ( *it ) ); } else if ( ProjectTargetItem * target = projectItem->target() ) { QList file_list = target->fileList(); for ( QList::Iterator it = file_list.begin(); it != file_list.end(); ++it ) files += recurseFiles( ( *it ) ); } else if ( ProjectFileItem * file = projectItem->file() ) { files.append( file ); } return files; } void importDone( KJob* ) { Core::self()->projectControllerInternal()->projectImportingFinished( project ); // Add the project files to the baackground parse to be parsed. /* if ( topItem ) { KUrl::List urlList; QList files = recurseFiles( topItem ); foreach ( ProjectFileItem* file, files ) { urlList.append( file->url() ); } Core::self()->languageController()->backgroundParser()->addDocumentList( urlList ); }*/ } }; Project::Project( QObject *parent ) : IProject( parent ) , d( new ProjectPrivate ) { QDBusConnection::sessionBus().registerObject( "/org/kdevelop/Project", this, QDBusConnection::ExportScriptableSlots ); d->project = this; d->manager = 0; d->topItem = 0; d->tmp = 0; } Project::~Project() { delete d; } QString Project::name() const { return d->name; } QString Project::developerTempFile() const { return d->developerTempFile; } QString Project::projectTempFile() const { return d->projectTempFile; } KSharedConfig::Ptr Project::projectConfiguration() const { d->m_cfg->reparseConfiguration(); return d->m_cfg; } // void Project::setLocalFile( const KUrl& u ) // { // d->localFile = u; // } // void Project::setGlobalFile( const KUrl& u ) // { // d->globalFile = u; // } const KUrl& Project::folder() const { return d->folder; } bool Project::open( const KUrl& projectFileUrl ) { KIO::StatJob* statJob = KIO::stat( projectFileUrl ); if ( !statJob->exec() ) //be sync for right now { KMessageBox::sorry( Core::self()->uiControllerInternal()->defaultMainWindow(), i18n( "Unable to load the project file %1", projectFileUrl.pathOrUrl() ) ); return false; } d->projectFileUrl = projectFileUrl; d->developerFileUrl = KUrl( projectFileUrl.directory( KUrl::AppendTrailingSlash ) + ".kdev4/" + projectFileUrl.fileName() ); statJob = KIO::stat( d->developerFileUrl ); if( !statJob->exec() ) { KUrl dir = KUrl( projectFileUrl.directory( KUrl::AppendTrailingSlash ) + ".kdev4"); statJob = KIO::stat( dir ); if( !statJob->exec() ) { KIO::SimpleJob* mkdirJob = KIO::mkdir( dir ); if( !mkdirJob->exec() ) { KMessageBox::sorry( Core::self()->uiController()->activeMainWindow(), i18n("Unable to create hidden dir (%1) for developer file", dir.pathOrUrl() ) ); return false; } } } if( !KIO::NetAccess::download( d->projectFileUrl, d->projectTempFile, Core::self()->uiController()->activeMainWindow() ) ) { KMessageBox::sorry( Core::self()->uiController()->activeMainWindow(), i18n("Unable to get project file: %1", d->projectFileUrl.pathOrUrl() ) ); return false; } statJob = KIO::stat( d->developerFileUrl ); if( !statJob->exec() || !KIO::NetAccess::download( d->developerFileUrl, d->developerTempFile, Core::self()->uiController()->activeMainWindow() ) ) { d->tmp = new KTemporaryFile(); d->tmp->open(); d->developerTempFile = d->tmp->fileName(); d->tmp->close(); } d->m_cfg = KSharedConfig::openConfig( d->projectTempFile ); - d->m_cfg->setExtraConfigFiles( QStringList() << d->developerTempFile ); + d->m_cfg->addConfigSources( QStringList() << d->developerTempFile ); KConfigGroup projectGroup( d->m_cfg, "Project" ); d->name = projectGroup.readEntry( "Name", projectFileUrl.fileName() ); d->folder = projectFileUrl.directory(); QString managerSetting = projectGroup.readEntry( "Manager", "KDevGenericManager" ); //Get our importer IPluginController* pluginManager = Core::self()->pluginController(); d->manager = pluginManager->pluginForExtension( "org.kdevelop.IProjectFileManager", managerSetting ); IProjectFileManager* iface = 0; if ( d->manager ) iface = d->manager->extension(); else { KMessageBox::sorry( Core::self()->uiControllerInternal()->defaultMainWindow(), i18n( "Could not load project management plugin %1.", managerSetting ) ); d->manager = 0; return false; } if ( d->manager && iface ) { // ProjectModel* model = Core::self()->projectController()->projectModel(); d->topItem = iface->import( this ); if( !d->topItem ) { return false; } // model->insertRow( model->rowCount(), d->topItem ); ImportProjectJob* importJob = new ImportProjectJob( d->topItem, iface ); connect( importJob, SIGNAL( result( KJob* ) ), this, SLOT( importDone( KJob* ) ) ); importJob->start(); //be asynchronous } else { KMessageBox::sorry( Core::self()->uiControllerInternal()->defaultMainWindow(), i18n( "project importing plugin (%1) does not support the IProjectFileManager interface.", managerSetting ) ); delete d->manager; d->manager = 0; return false; } return true; } void Project::close() { // unloaded by project controller, depending on shared count // KPluginInfo* pluginInfo = Core::self()->pluginController()->pluginInfo( d->manager ); // if ( pluginInfo ) // { // Core::self()->pluginController()->unloadPlugin( pluginInfo->pluginName() ); // } //the manager plugin will be deleted in the plugin controller, so just set //the manager to zero. // d->manager = 0; QList itemList = Core::self()->projectController()->projectModel()->takeRow( d->topItem->row() ); qDeleteAll( itemList ); if( d->tmp ) { d->tmp->close(); } if( !KIO::NetAccess::upload( d->developerTempFile, d->developerFileUrl, Core::self()->uiController()->activeMainWindow() ) ) { KMessageBox::sorry( Core::self()->uiController()->activeMainWindow(), i18n("Could not store developer specific project configuration.\n" "Attention: The project settings you changed will be lost." ) ); } delete d->tmp; } bool Project::inProject( const KUrl& url ) const { return fileForUrl( url ) != 0; } ProjectFileItem* Project::fileAt( int num ) const { QList files; if ( d->topItem ) files = d->recurseFiles( d->topItem ); if( !files.isEmpty() && num >= 0 && num < files.count() ) return files.at( num ); return 0; } QList KDevelop::Project::files() const { QList files; if ( d->topItem ) files = d->recurseFiles( d->topItem ); return files; } ProjectFileItem *Project::fileForUrl(const KUrl& url) const { // TODO: This is moderately efficient, but could be much faster with a // QHash member. Would it be worth it? KUrl u = d->topItem->url(); if ( u.protocol() != url.protocol() || u.host() != url.host() ) return 0; foreach( ProjectFolderItem* top, d->topItem->folderList() ) { while ( top ) { u = top->url(); if ( u.isParentOf( url ) ) { ProjectFolderItem *parent = 0; QList folder_list = top->folderList(); foreach( ProjectFolderItem *folder, folder_list ) { if ( folder->url().isParentOf( url ) ) { parent = folder; break; } } if ( !parent ) //the subfolders are not parent of url { QList file_list = top->fileList(); foreach( ProjectFileItem *file, file_list ) { if ( file->url() == url ) { return file; //we found it break; } } QList target_list = top->targetList(); foreach( ProjectTargetItem *target, target_list ) { QList targetfile_list = target->fileList(); foreach( ProjectFileItem *file, targetfile_list ) { if ( file->url() == url ) { return file; //we found it break; } } } return 0; //not in the project } top = parent; } else top = 0; } } return 0; } int Project::fileCount() const { QList files; if ( d->topItem ) files = d->recurseFiles( d->topItem ); return files.count(); } KUrl Project::relativeUrl( const KUrl& absolute ) const { return KUrl::relativeUrl( folder(), absolute ); } KUrl Project::urlRelativeToProject( const KUrl & relativeUrl ) const { if ( KUrl::isRelativeUrl( relativeUrl.toLocalFile() ) ) return KUrl( folder(), relativeUrl.toLocalFile() ); return relativeUrl; } IProjectFileManager* Project::projectFileManager() const { return d->manager->extension(); } IBuildSystemManager* Project::buildSystemManager() const { return d->manager->extension(); } IPlugin* Project::managerPlugin() const { return d->manager; } void Project::setManagerPlugin( IPlugin* manager ) { d->manager = manager; } // PersistentHash * Project::persistentHash() const // { // return &d->persistentHash; // } KUrl Project::projectFileUrl() const { return d->projectFileUrl; } KUrl Project::developerFileUrl() const { return d->developerFileUrl; } ProjectFolderItem* Project::projectItem() const { return d->topItem; } } #include "project.moc"