KDE/kdevelop/lib
Dukju Ahn
dukjuahn at gmail.com
Mon May 28 08:04:41 UTC 2007
SVN commit 668957 by dukjuahn:
Make project loading totally asynchronous.
1. Used threadweaver for ImportJob
2. Doesn't invoke setIcon() for the whole tree. Rather, setIcon()
is called whenever the item is expanded via QStandardItemModel::fetchMore()
This was necessary because items are created at separated thread, and KIO:: fails at multithreaded environment.
CCMAIL: kdevelop-devel at kdevelop.org
M +1 -0 project/CMakeLists.txt
M +25 -21 project/importprojectjob.cpp
M +13 -2 project/importprojectjob.h
A project/importprojectthread.cpp [License: LGPL (v2+)]
A project/importprojectthread.h [License: LGPL (v2+)]
M +41 -3 project/projectmodel.cpp
M +12 -0 project/projectmodel.h
M +16 -4 shell/project.cpp
M +4 -0 shell/project.h
M +12 -5 shell/projectcontroller.cpp
M +1 -0 shell/projectcontroller.h
--- trunk/KDE/kdevelop/lib/project/CMakeLists.txt #668956:668957
@@ -7,6 +7,7 @@
projectmodel.cpp
projectconfigskeleton.cpp
importprojectjob.cpp
+ importprojectthread.cpp
interfaces/iprojectbuilder.cpp
interfaces/iprojectfilemanager.cpp
interfaces/ibuildsystemmanager.cpp
--- trunk/KDE/kdevelop/lib/project/importprojectjob.cpp #668956:668957
@@ -19,34 +19,40 @@
*/
#include "importprojectjob.h"
+#include "importprojectthread.h"
#include "interfaces/iprojectfilemanager.h"
+#include "projectmodel.h"
#include <kglobal.h>
#include <kdebug.h>
+#include <threadweaver/ThreadWeaver.h>
namespace KDevelop
{
struct ImportProjectJobPrivate
{
- ProjectFolderItem *m_folder;
- IProjectFileManager *m_importer;
- QList<ProjectFolderItem*> m_workingList;
+ ThreadWeaver::Weaver *m_weaver;
+ ImportProjectThread *m_weaverJob;
};
ImportProjectJob::ImportProjectJob(QStandardItem *folder, IProjectFileManager *importer)
: KJob(0), d(new ImportProjectJobPrivate)
{
- d->m_importer = importer;
- d->m_folder = 0;
+ d->m_weaver = new ThreadWeaver::Weaver( this );
+ d->m_weaverJob = new ImportProjectThread( this );
+
+ d->m_weaverJob->setProjectFileManager( importer );
+ ProjectFolderItem *folderItem = 0;
if ( folder->type() == ProjectBaseItem::Folder ||
folder->type() == ProjectBaseItem::BuildFolder ||
folder->type() == ProjectBaseItem::Project )
{
- d->m_folder = dynamic_cast<ProjectFolderItem*>( folder );
+ folderItem = dynamic_cast<ProjectFolderItem*>( folder );
}
+ d->m_weaverJob->setProjectFolderItem( folderItem );
}
ImportProjectJob::~ImportProjectJob()
@@ -56,28 +62,26 @@
void ImportProjectJob::start()
{
- if ( d->m_folder )
- startNextJob( d->m_folder );
+ if( !(d->m_weaverJob) )
+ return;
- emitResult();
-}
+ d->m_weaver->enqueue( d->m_weaverJob );
+ connect( d->m_weaverJob, SIGNAL(done(ThreadWeaver::Job*)), this, SLOT(slotDone(ThreadWeaver::Job*)) );
-void ImportProjectJob::startNextJob(ProjectFolderItem *dom)
-{
- d->m_workingList += d->m_importer->parse(dom);
- while ( !d->m_workingList.isEmpty() )
- {
- ProjectFolderItem *folder = d->m_workingList.first();
- d->m_workingList.pop_front();
-
- startNextJob(folder);
- }
+// d->m_weaverJob->start();
+// connect( d->m_weaverJob, SIGNAL(finished()), this, SLOT(slotFinished()) );
}
-void ImportProjectJob::processList()
+void ImportProjectJob::slotDone(ThreadWeaver::Job*)
{
+ emitResult();
}
+// void ImportProjectJob::slotFinished()
+// {
+// emitResult();
+// }
+
}
#include "importprojectjob.moc"
--- trunk/KDE/kdevelop/lib/project/importprojectjob.h #668956:668957
@@ -21,13 +21,21 @@
#define KDEVIMPORTPROJECTJOB_H
#include <kjob.h>
-#include "projectmodel.h"
+// #include "projectmodel.h"
#include "kdevexport.h"
+class QStandardItem;
+
+namespace ThreadWeaver
+{
+class Job;
+}
+
namespace KDevelop
{
class IProjectFileManager;
+class ProjectFolderItem;
class KDEVPLATFORMPROJECT_EXPORT ImportProjectJob: public KJob
{
@@ -42,8 +50,11 @@
protected:
void startNextJob(ProjectFolderItem *folder);
void slotResult(KJob *job);
- void processList();
+protected Q_SLOTS:
+ void slotDone(ThreadWeaver::Job*);
+// void slotFinished();
+
private:
struct ImportProjectJobPrivate* const d;
};
--- trunk/KDE/kdevelop/lib/project/projectmodel.cpp #668956:668957
@@ -95,6 +95,10 @@
parent->setChild( parent->rowCount(), this );
}
+void ProjectBaseItem::setIcon()
+{
+}
+
void ProjectBaseItem::add( ProjectBaseItem* item )
{
setChild( rowCount(), item );
@@ -218,7 +222,29 @@
reset();
}
+void ProjectModel::fetchMore( const QModelIndex &parent )
+{
+ QStandardItem *parentItem = itemFromIndex( parent );
+ if( !parentItem )
+ return;
+ int rowcount = parentItem->rowCount();
+ for( int i=0; i<rowcount; i++ )
+ {
+ ProjectBaseItem *childItem = dynamic_cast<ProjectBaseItem*>(parentItem->child(i));
+ if( childItem && childItem->icon().isNull() )
+ childItem->setIcon();
+ }
+}
+bool ProjectModel::canFetchMore( const QModelIndex & parent ) const
+{
+ QStandardItem *parentItem = itemFromIndex( parent );
+ if( !parentItem )
+ return false;
+ return true;
+}
+
+
ProjectFolderItem::ProjectFolderItem( IProject* project, const KUrl & dir, QStandardItem * parent )
: ProjectBaseItem( *new ProjectFolderItemPrivate )
{
@@ -227,7 +253,6 @@
d->m_url = dir;
setParent(parent);
setText( dir.fileName() );
- setIcon( KIO::pixmapForUrl( url(), 0, K3Icon::Small ) );
}
ProjectFolderItem::ProjectFolderItem( ProjectFolderItemPrivate& dd)
@@ -262,6 +287,11 @@
setText( url.fileName() );
}
+void ProjectFolderItem::setIcon()
+{
+ QStandardItem::setIcon( KIO::pixmapForUrl( url(), 0, K3Icon::Small ) );
+}
+
ProjectBuildFolderItem::ProjectBuildFolderItem( ProjectBuildFolderItemPrivate& dd )
: ProjectFolderItem( dd )
{
@@ -274,7 +304,6 @@
d->project = project;
setUrl( dir );
setParent( parent );
- setIcon( KIcon("folder-development") );
}
int ProjectBuildFolderItem::type() const
@@ -300,6 +329,11 @@
return d->m_env;
}
+void ProjectBuildFolderItem::setIcon()
+{
+ QStandardItem::setIcon( KIcon("folder-development") );
+}
+
ProjectFileItem::ProjectFileItem( ProjectFileItemPrivate& dd)
: ProjectBaseItem(dd)
{
@@ -313,7 +347,6 @@
d->m_url = file;
setText( file.fileName() );
setParent( parent );
- setIcon( KIO::pixmapForUrl( url(), 0, K3Icon::Small ) );
}
const KUrl & ProjectFileItem::url( ) const
@@ -338,6 +371,11 @@
return const_cast<ProjectFileItem*>( this );
}
+void ProjectFileItem::setIcon()
+{
+ QStandardItem::setIcon( KIO::pixmapForUrl( url(), 0, K3Icon::Small ) );
+}
+
ProjectTargetItem::ProjectTargetItem( ProjectTargetItemPrivate& dd)
: ProjectBaseItem( dd )
{
--- trunk/KDE/kdevelop/lib/project/projectmodel.h #668956:668957
@@ -81,6 +81,7 @@
virtual ProjectItem* projectItem() const;
void setParent( QStandardItem* );
+ virtual void setIcon();
QList<ProjectFolderItem*> folderList() const;
QList<ProjectTargetItem*> targetList() const;
@@ -114,6 +115,9 @@
/** Set the url of this folder */
void setUrl( const KUrl& );
+
+ virtual void setIcon();
+
protected:
ProjectFolderItem( ProjectFolderItemPrivate& );
private:
@@ -146,6 +150,9 @@
* for all targets in this directory.
*/
const QHash<QString, QString>& environment() const;
+
+ virtual void setIcon();
+
protected:
ProjectBuildFolderItem( ProjectBuildFolderItemPrivate& );
private:
@@ -229,6 +236,8 @@
const KUrl& url() const;
void setUrl( const KUrl& );
+ virtual void setIcon();
+
protected:
ProjectFileItem( ProjectFileItemPrivate& );
private:
@@ -247,6 +256,9 @@
void resetModel();
+ virtual void fetchMore( const QModelIndex &parent );
+ virtual bool canFetchMore( const QModelIndex & parent ) const;
+
private:
class ProjectModelPrivate* const d;
--- trunk/KDE/kdevelop/lib/shell/project.cpp #668956:668957
@@ -73,6 +73,8 @@
ProjectItem* topItem;
QString name;
KSharedConfig::Ptr m_cfg;
+ Project *project;
+
QList<ProjectFileItem*> recurseFiles( ProjectBaseItem * projectItem )
{
QList<ProjectFileItem*> files;
@@ -103,9 +105,18 @@
return files;
}
- void importDone( KJob* job )
+ void importDone( KJob* /*job*/ )
{
- job->deleteLater();
+ // set icon for toplevel file/dirs only. Subsequent children's icon will be set
+ // when the treeview is expanded
+ int rowcount = topItem->rowCount();
+ for( int i=0; i<rowcount; i++ )
+ {
+ ProjectBaseItem *childItem = dynamic_cast<ProjectBaseItem*>(topItem->child(i));
+ if( childItem )
+ childItem->setIcon();
+ }
+ emit project->importingFinished(project);
}
};
@@ -116,6 +127,7 @@
{
QDBusConnection::sessionBus().registerObject( "/org/kdevelop/Project", this, QDBusConnection::ExportScriptableSlots );
+ d->project = this;
d->manager = 0;
d->topItem = 0;
d->tmp = 0;
@@ -244,9 +256,9 @@
}
if ( d->manager && iface )
{
- ProjectModel* model = Core::self()->projectController()->projectModel();
+// ProjectModel* model = Core::self()->projectController()->projectModel();
d->topItem = iface->import( this );
- model->insertRow( model->rowCount(), d->topItem );
+// model->insertRow( model->rowCount(), d->topItem );
ImportProjectJob* importJob = new ImportProjectJob( d->topItem, iface );
connect( importJob, SIGNAL( result( KJob* ) ), this, SLOT( importDone( KJob* ) ) );
--- trunk/KDE/kdevelop/lib/shell/project.h #668956:668957
@@ -81,6 +81,9 @@
virtual KUrl projectFileUrl() const;
virtual KSharedConfig::Ptr projectConfiguration() const;
+Q_SIGNALS:
+ void importingFinished(IProject*);
+
public Q_SLOTS:
/**
* @brief Open a project
@@ -170,6 +173,7 @@
Q_PRIVATE_SLOT(d, void importDone(KJob*) )
class ProjectPrivate* const d;
+ friend class ProjectPrivate;
};
}
--- trunk/KDE/kdevelop/lib/shell/projectcontroller.cpp #668956:668957
@@ -220,7 +220,6 @@
}
//FIXME Create the hidden directory if it doesn't exist
-
if ( loadProjectPart() )
{
//The project file has been opened.
@@ -231,23 +230,31 @@
else
return false;
-
- IProject* project = new Project();
+ Project* project = new Project();
if ( !project->open( url ) )
{
delete project;
return false;
}
+ connect( project, SIGNAL(importingFinished(IProject*)), this, SLOT(projectImportingFinished(IProject*)) );
+ return true;
+}
+
+bool ProjectController::projectImportingFinished( IProject* project )
+{
+ ProjectItem *topItem = project->projectItem();
+ ProjectModel *model = projectModel();
+ model->insertRow( model->rowCount(), topItem );
+
d->m_projects.append( project );
-
// KActionCollection * ac = d->m_core->uiControllerInternal()->defaultMainWindow()->actionCollection();
// QAction * action;
//action = ac->action( "project_close" );
//action->setEnabled( true );
- d->m_recentAction->addUrl( url );
+ d->m_recentAction->addUrl( project->projectFileUrl() );
KSharedConfig * config = KGlobal::config().data();
KConfigGroup recentGroup = config->group("RecentProjects");
d->m_recentAction->saveEntries( recentGroup );
--- trunk/KDE/kdevelop/lib/shell/projectcontroller.h #668956:668957
@@ -53,6 +53,7 @@
public Q_SLOTS:
bool openProject( const KUrl &KDev4ProjectFile = KUrl() );
+ bool projectImportingFinished( IProject* );
bool closeProject( IProject* );
// void changeCurrentProject( ProjectBaseItem* );
More information about the KDevelop-devel
mailing list