Commit 2c3b84e0 authored by Matthias Möller's avatar Matthias Möller
Browse files

add async loading of files

refs #2421

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@21052 383ad7c9-94d9-4d36-a494-682f7c89f535
parent f07975d1
......@@ -493,7 +493,7 @@ signals:
void slotLoad(QString _filename, DataType _type, int& _id);
/// the load widget wants to load a given file
void slotLoad(QString _filename, int _pluginID);
void slotLoad(QStringList _filenames, IdList _pluginIDs);
/// Called when a file has been opened
void slotFileOpened ( int _id );
......@@ -804,6 +804,8 @@ public slots:
int loadObject ( QString _filename );
private slots:
void loadObjectFinished(QString _filename);
/** Do a reset of the scenegraph (bounding box update,...)
*
* @param _resetTrackBall Should the rotation center of the trackball be reset to the scene center?
......
#include "OpenFunctionThread.hh"
#include <OpenFlipper/common/GlobalOptions.hh>
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
/////////////////////////////////////////////////
void LoadFromPluginThread::loadFromPlugin()
{
for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
PluginFunctions::viewerProperties(i).lockUpdate();
for (int i = 0; i < infos_.size(); ++i)
{
LoadInfos info = infos_[i];
if (info.type != DATA_UNKNOWN)
loadedIds_[i] = info.plugin->loadObject(info.filename,info.type );
else
loadedIds_[i] = info.plugin->loadObject(info.filename);
emit state(this->jobId(),i);
}
for ( int i = 0 ; i < PluginFunctions::viewers() ; ++i )
PluginFunctions::viewerProperties(i).unLockUpdate();
emit updateView();
}
/////////////////////////////////////////////////
LoadFromPluginThread::~LoadFromPluginThread()
{
}
/////////////////////////////////////////////////
LoadFromPluginThread::LoadFromPluginThread(QVector<LoadInfos> _loadInfos, const QString& _jobName)
: OpenFlipperThread(_jobName), infos_(_loadInfos), loadedIds_(_loadInfos.size(),-1)
{
connect( this ,SIGNAL(function()), this, SLOT(loadFromPlugin()), Qt::DirectConnection) ;
}
/////////////////////////////////////////////////
int LoadFromPluginThread::getObjId(int index)const
{
return loadedIds_[index];
}
/////////////////////////////////////////////////
const QString& LoadFromPluginThread::getFilename(int index) const
{
return infos_[index].filename;
}
#ifndef __OPENFUNCTIONSLOADFROMPLUGINTHREAD_HH__
#define __OPENFUNCTIONSLOADFROMPLUGINTHREAD_HH__
#include <OpenFlipper/threads/OpenFlipperThread.hh>
#include <OpenFlipper/common/DataTypes.hh>
#include <OpenFlipper/BasePlugin/FileInterface.hh>
#include <QString>
class LoadFromPluginThread : public OpenFlipperThread
{
Q_OBJECT
public:
struct LoadInfos
{
FileInterface* plugin;
DataType type;
QString filename;
LoadInfos():plugin(0),type(DATA_UNKNOWN),filename(){}//c'tor for QVector
LoadInfos(FileInterface* _plugin, const QString& _filename):plugin(_plugin),type(DATA_UNKNOWN),filename(_filename){}
LoadInfos(FileInterface* _plugin, DataType _type, const QString& _filename):plugin(_plugin),type(_type),filename(_filename){}
};
signals:
void updateView();
private:
const QVector<LoadInfos>& infos_;
QVector<int> loadedIds_;
public slots:
void loadFromPlugin();
public:
~LoadFromPluginThread();
LoadFromPluginThread(QVector<LoadInfos> _loadInfos, const QString& _jobName);
int getObjId(int index)const;
const QString& getFilename(int index) const;
};
#endif //__OPENFUNCTIONSLOADFROMPLUGINTHREAD_HH__
......@@ -69,6 +69,8 @@
#include <OpenFlipper/common/DataTypes.hh>
#include <time.h>
#include "OpenFunctionThread.hh"
void Core::resetScenegraph( bool _resetTrackBall ) {
if ( OpenFlipper::Options::gui() && !OpenFlipper::Options::sceneGraphUpdatesBlocked() ) {
......@@ -205,6 +207,42 @@ void Core::slotExecuteAfterStartup() {
exitApplication();
}
void Core::loadObjectFinished(QString _threadId)
{
if ( OpenFlipper::Options::gui() ) {
LoadFromPluginThread* thread = dynamic_cast<LoadFromPluginThread*>(sender());
if (!thread)
return;
int id = thread->getObjId(0);
QString filename = thread->getFilename(0);
if ( id != -1 ) {
coreWidget_->statusMessage( tr("Loading %1 ... done").arg(filename), 4000 );
// Get the object to figure out the data type
BaseObject* object;
PluginFunctions::getObject(id,object);
// Security check, if object really exists
if ( object != 0 ) {
// Add to recent files with the given datatype
if ( OpenFlipper::Options::gui() )
coreWidget_->addRecent(filename, object->dataType());
} else {
emit log(LOGERR, tr("Unable to add recent as object with id %1 could not be found!").arg(id) );
}
} else
coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(filename), 4000 );
if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
coreWidget_->setStatus(ApplicationStatus::READY );
}
}
int Core::loadObject ( QString _filename ) {
/** \todo Check if this function is ok. It should check all plugins for the given files and do not depend
......@@ -269,35 +307,36 @@ int Core::loadObject ( QString _filename ) {
coreWidget_->setStatus(ApplicationStatus::PROCESSING );
}
//load file
int id = supportedTypes()[i].plugin->loadObject(_filename);
QString jobId = QString("Loading_"+_filename);
QVector<LoadFromPluginThread::LoadInfos> infos;
infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _filename));
LoadFromPluginThread* thread = new LoadFromPluginThread(infos, jobId);
if ( OpenFlipper::Options::gui() ) {
if ( id != -1 ) {
coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
// Get the object to figure out the data type
BaseObject* object;
PluginFunctions::getObject(id,object);
// Security check, if object really exists
if ( object != 0 ) {
// Add to recent files with the given datatype
if ( OpenFlipper::Options::gui() )
coreWidget_->addRecent(_filename, object->dataType());
} else {
emit log(LOGERR, tr("Unable to add recent as object with id %1 could not be found!").arg(id) );
}
} else
coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );
connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
connect(thread, SIGNAL(finished(QString)), this, SLOT(loadObjectFinished(QString)));
if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
coreWidget_->setStatus(ApplicationStatus::READY );
if ( OpenFlipper::Options::gui() )
{
connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
slotStartJob(jobId , QString("Loading %1").arg(_filename) , 0, 0, true);
thread->start();
thread->startProcessing();
while(thread->isRunning())
QApplication::processEvents();
// process last events
QApplication::processEvents();
}
else
{
thread->loadFromPlugin();
}
int objId = thread->getObjId(0);
return id;
return objId;
}
}
......@@ -306,6 +345,7 @@ int Core::loadObject ( QString _filename ) {
return -1;
}
/// Function for loading a given file
int Core::loadObject( DataType _type, QString _filename) {
/** \todo this function has to be checked. test for the plugin which can handle
......@@ -387,34 +427,43 @@ int Core::loadObject( DataType _type, QString _filename) {
coreWidget_->setStatus(ApplicationStatus::PROCESSING );
}
int id = -1;
//load file
QString jobId = QString("Loading_"+_filename);
QVector<LoadFromPluginThread::LoadInfos> infos;
if ( checkSlot( supportedTypes()[i].object , "loadObject(QString,DataType)" ) )
id = supportedTypes()[i].plugin->loadObject(_filename, _type);
infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _type,_filename));
else
id = supportedTypes()[i].plugin->loadObject(_filename);
infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _filename));
if ( OpenFlipper::Options::gui() ) {
if ( id != -1 ) {
coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
LoadFromPluginThread* thread = new LoadFromPluginThread(infos, jobId);
// Get the object to figure out the data type
BaseObject* object;
PluginFunctions::getObject(id,object);
connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
connect(thread, SIGNAL(finished(QString)), this, SLOT(loadObjectFinished(QString)));
// Add to recent files with the given datatype
if ( OpenFlipper::Options::gui() )
coreWidget_->addRecent(_filename, object->dataType());
if ( OpenFlipper::Options::gui() )
{
connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
} else
coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );
slotStartJob(jobId , QString("Loading %1").arg(_filename) , 0, 0, true);
thread->start();
thread->startProcessing();
if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
coreWidget_->setStatus(ApplicationStatus::READY );
while(thread->isRunning())
QApplication::processEvents();
// process last events
QApplication::processEvents();
}
else
{
thread->loadFromPlugin();
}
return id;
int objId = thread->getObjId(0);
return objId;
} else {
emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
......@@ -513,70 +562,122 @@ void Core::slotCopyObject( int _oldId , int& _newId ) {
}
/// Function for loading a given file
void Core::slotLoad(QString _filename, int _pluginID) {
/// Function for loading multiple files
void Core::slotLoad(QStringList _filenames, IdList _pluginIDs) {
QString filemsg = "";
if (_filenames.size() > 1)
filemsg = QString( tr("Loading Files ...") );
else
filemsg = QString( tr("Loading %1 ...").arg(_filenames[0]) );
if ( OpenFlipper::Options::gui() ) {
coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
coreWidget_->statusMessage( filemsg );
if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
coreWidget_->setStatus(ApplicationStatus::PROCESSING );
}
//load file
time_t start = clock();
int id = supportedTypes()[_pluginID].plugin->loadObject(_filename);
time_t end = clock();
emit log(LOGINFO,tr("Loading %1 with Plugin %2 took %3 seconds.").arg(_filename).arg(supportedTypes()[_pluginID].name).arg((double)(end-start)/CLOCKS_PER_SEC) );
//setup thread
QString jobId = QString("Loading File");
if (_filenames.size() > 1)
jobId += "s";
if ( OpenFlipper::Options::gui() ) {
if ( id != -1 )
coreWidget_->statusMessage( tr("Loading %1 ... done").arg(_filename), 4000 );
QVector<LoadFromPluginThread::LoadInfos> loadInfos;
for (int i = 0; i < _filenames.size(); ++i)
loadInfos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[_pluginIDs[i]].plugin, _filenames[i]));
LoadFromPluginThread* thread = new LoadFromPluginThread(loadInfos, jobId);
connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
connect(thread, SIGNAL(state(QString , int )), this, SLOT(slotSetJobState(QString , int)));
if ( OpenFlipper::Options::gui() )
{
connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
//block log (decrease performance when loading multiple files)
coreWidget_->logWidget_->setUpdatesEnabled(false);
// start thread
if (_filenames.size() > 1)
slotStartJob(jobId , QString(filemsg), 0, _filenames.size(), true);
else
coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(_filename), 4000 );
slotStartJob(jobId , QString(filemsg), 0, 0, true);
if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
coreWidget_->setStatus(ApplicationStatus::READY );
thread->start();
thread->startProcessing();
//wait thread
while(thread->isRunning())
QApplication::processEvents();
//process last occuring events
QApplication::processEvents();
//unblock and update log
coreWidget_->logWidget_->setUpdatesEnabled(true);
}
else
{
thread->loadFromPlugin();
}
// Initialize as unknown type
DataType type = DATA_UNKNOWN;
QVector<DataType> type = QVector<DataType>(_filenames.size(), DATA_UNKNOWN);
// An object has been added. Get it and do some processing!
if ( id > 0 ) {
for (int i = 0; i < _filenames.size(); ++i)
{
int id = thread->getObjId(i);
BaseObjectData* object;
PluginFunctions::getObject(id,object);
if ( !object ) {
if ( OpenFlipper::Options::gui() ) {
BaseObject* baseObj = 0;
GroupObject* group = 0;
PluginFunctions::getObject(id,baseObj);
if (baseObj){
if ( id != -1 )
coreWidget_->statusMessage( tr("Loading %1 done").arg(_filenames[i]), 4000 );
else
coreWidget_->statusMessage( tr("Loading %1 failed").arg(_filenames[i]), 4000 );
group = dynamic_cast< GroupObject* > (baseObj);
if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
coreWidget_->setStatus(ApplicationStatus::READY );
}
if (group)
type = DATA_GROUP;
}
if ( group == 0 ){
emit log(LOGERR,tr("Object id returned but no object with this id has been found! Error in one of the file plugins!"));
return;
if ( id > 0 ) {
BaseObjectData* object;
PluginFunctions::getObject(id,object);
if ( !object ) {
BaseObject* baseObj = 0;
GroupObject* group = 0;
PluginFunctions::getObject(id,baseObj);
if (baseObj){
group = dynamic_cast< GroupObject* > (baseObj);
if (group)
type[i] = DATA_GROUP;
}
if ( group == 0 ){
emit log(LOGERR,tr("Object id returned but no object with this id has been found! Error in one of the file plugins!"));
return;
}
}
// Get the objects type
if (object)
type[i] = object->dataType();
}
// Get the objects type
if (object)
type = object->dataType();
}
// If the id was greater than zero, add the file to the recent files.
if ( id >= 0 )
if ( OpenFlipper::Options::gui() )
coreWidget_->addRecent(_filename, type);
if ( OpenFlipper::Options::gui() )
for (int i = 0; i < _filenames.size(); ++i)
if ( thread->getObjId(i) >= 0 )
coreWidget_->addRecent(_filenames[i], type[i]);
}
/// Slot for loading a given file
......@@ -784,7 +885,7 @@ void Core::loadObject() {
if (supportedTypes().size() != 0){
LoadWidget* widget = new LoadWidget(supportedTypes());
connect(widget,SIGNAL(load(QString, int)),this,SLOT(slotLoad(QString, int)));
connect(widget,SIGNAL(loadFiles(QStringList, IdList)),this,SLOT(slotLoad(QStringList, IdList)));
connect(widget,SIGNAL(save(int, QString, int)),this,SLOT(saveObject(int, QString, int)));
widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
......
......@@ -255,6 +255,8 @@ void LoadWidget::loadFile(){
//load the selected files
QStringList loadableFiles;
IdList pluginIds;
for (int i=0; i < files.size(); i++){
QFileInfo fi(files[i]);
......@@ -286,8 +288,11 @@ void LoadWidget::loadFile(){
//emit load signal
if ( pluginForExtension_.find( ext ) != pluginForExtension_.end() ){
emit load(filename, pluginForExtension_[ ext ]);
loadableFiles.push_back(filename);
pluginIds.push_back(pluginForExtension_[ext]);
}
}
emit loadFiles(loadableFiles, pluginIds);
}
/// find suitable plugin for saving current file
......
......@@ -69,6 +69,7 @@ class LoadWidget : public QFileDialog
signals:
void load(QString _filename, int _pluginID);
void loadFiles(QStringList _filenames, IdList _pluginIds);
void save(int _id, QString _filename, int _pluginID);
void save(IdList _ids, QString _filename, int _pluginID);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment