Commit fa9c0124 authored by Stéphane Albert's avatar Stéphane Albert

ENH: draft background Catalogue/File/Open; Background worker/thread pattern (WIP).

parent 94032551
......@@ -47,6 +47,7 @@
//
#include "Core/mvdDatabaseModel.h"
#include "Core/mvdDatasetModel.h"
#include "Core/mvdImageImporter.h"
#include "Core/mvdQuicklookModel.h"
#include "Core/mvdVectorImageModel.h"
//
......@@ -724,7 +725,9 @@ MainWindow
void
MainWindow
::on_action_OpenImage_triggered()
{
{
qDebug() << this << "::on_action_OpenImage_triggered()";
QString filename(
QFileDialog::getOpenFileName( this, tr( "Open file..." ) )
);
......@@ -732,27 +735,88 @@ MainWindow
if( filename.isNull() )
return;
// emit OpenImageRequest( filename );
QThread* thread = new QThread( this );
/*
try
{
DatasetModel* model = Application::LoadDatasetModel(
m_Filename, m_Width, m_Height );
thread->setObjectName( "ImageImporter" );
// We can only push to another thread,
// so thread affinity must be set here,
// and not in the slot that receives the object
model->moveToThread(Application::Instance()->thread());
emit ModelLoaded(model);
}
catch( std::exception& exc )
{
emit Error( exc.what() );
}
emit Finished();
*/
ImageImporter* importer =
new ImageImporter(
filename,
m_ImageView->width(), m_ImageView->height()
);
importer->moveToThread( thread );
// Start.
QObject::connect(
thread, SIGNAL( started() ),
// to:
importer, SLOT( Do() )
);
// Finish.
QObject::connect(
importer, SIGNAL( Finished() ),
// to:
thread, SLOT( quit() )
);
// Destroy thread.
QObject::connect(
thread, SIGNAL( finished() ),
// to:
thread, SLOT( deleteLater() )
);
// Destroy importer.
QObject::connect(
thread, SIGNAL( finished() ),
// to:
importer, SLOT( deleteLater() )
);
QProgressDialog progress(
this,
Qt::CustomizeWindowHint | Qt::WindowTitleHint
);
progress.setWindowModality( Qt::WindowModal );
progress.setAutoReset( false );
progress.setAutoClose( false );
progress.setCancelButton( NULL );
progress.setMinimumDuration( 0 );
QObject::connect(
importer, SIGNAL( ProgressTextChanged( const QString& ) ),
// to:
&progress, SLOT( setLabelText( const QString& ) )
);
QObject::connect(
importer, SIGNAL( ProgressValueChanged( int ) ),
// to:
&progress, SLOT( setValue( int ) )
);
QObject::connect(
importer,
SIGNAL( Done( QObject* ) ),
// to:
&progress,
SLOT( accept() )
);
QObject::connect(
importer,
SIGNAL( ExceptionRaised( std::exception ) ),
// to:
&progress,
SLOT( reject() )
);
thread->start();
progress.exec();
}
/*****************************************************************************/
......
......@@ -1014,7 +1014,6 @@ MainWindow
m_DatasetCreationProgressDialog->show();
}
/*****************************************************************************/
void
MainWindow
......
......@@ -12,6 +12,7 @@ set( Common_Core_SOURCES
mvdDatasetModel.cxx
mvdHistogramModel.cxx
mvdI18nApplication.cxx
mvdImageImporter.cxx
mvdMath.cxx
mvdModifiableInterface.cxx
mvdMyClass.cxx
......@@ -37,6 +38,7 @@ set( Common_Core_HEADERS_MOC
mvdDatasetModel.h
mvdHistogramModel.h
mvdI18nApplication.h
mvdImageImporter.h
# mvdMath.h
mvdMyClass.h
mvdQuicklookModel.h
......
......@@ -37,6 +37,7 @@
//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdI18nApplication.h"
namespace mvd
{
......@@ -76,6 +77,50 @@ AbstractWorker
{
}
/*****************************************************************************/
void
AbstractWorker
::Do()
{
qDebug() << this << "::Do()";
qDebug() << this->thread();
QObject* result = NULL;
try
{
// Just do it and get resulting QObject.
result = virtual_Do();
// Access application.
const I18nApplication* app = I18nApplication::ConstInstance();
assert( app!=NULL );
// Move object into application's main thread.
//
// We can only push to another thread,
// so thread affinity must be set here,
// and not in the slot that receives the object.
if( result->thread()!=app->thread() )
result->moveToThread( app->thread() );
// Emit task/job has been correctly done.
emit Done( result );
}
catch( std::exception& exc )
{
// Delete allocated object.
delete result;
result = NULL;
// Emit clone of caught exception.
emit ExceptionRaised( exc );
}
// Emit task/job has finished.
emit Finished();
}
/*******************************************************************************/
/* SLOTS */
/*******************************************************************************/
......
......@@ -92,11 +92,56 @@ public:
// Public SLOTS.
public slots:
/**
* \brief Call the implemented do job/task routine.
*/
void Do();
/*-[ SIGNALS SECTION ]-----------------------------------------------------*/
//
// Signals.
signals:
/**
* \brief Signal emitted when progress text has changed.
*
* \param text New progress text to display;
*/
void ProgressTextChanged( const QString& text );
/**
* \brief Signal emitted when progress value has changed.
*
* \param value New progress value to display.
*/
void ProgressValueChanged( int value );
/**
* \brief Signal emitted when progress range has changed.
*
* \param min Minimum progress value.
* \param max Maximum progress value.
*/
void ProgressRangeChanged( int min, int max );
/**
* \brief Signal emitted when job/task has correctly been done.
*
* \param result Resulting QObject instance of NULL if none.
*/
void Done( QObject* result =NULL );
/**
* \brief Signal emitted when job/task has finished correctly or not.
*/
void Finished();
/**
* \brief Signal emitted when an exception has been caught by this worker.
*
* \param exc The copy (thread safety) exception which has been caught.
*/
void ExceptionRaised( std::exception exc );
/*-[ PROTECTED SECTION ]---------------------------------------------------*/
......@@ -116,6 +161,10 @@ protected:
//
// Private methods.
private:
/**
* \brief Do job/task abstract method to implement.
*/
virtual QObject* virtual_Do() =0;
//
......@@ -152,6 +201,7 @@ private slots:
namespace mvd
{
} // end namespace 'mvd'
#endif // __mvdAbstractWorker_h
/*=========================================================================
Program: Monteverdi2
Language: C++
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See Copyright.txt for details.
Monteverdi2 is distributed under the CeCILL licence version 2. See
Licence_CeCILL_V2-en.txt or
http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "mvdWorkerThread.h"
/*****************************************************************************/
/* INCLUDE SECTION */
//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.
//
// System includes (sorted by alphabetic order)
//
// ITK includes (sorted by alphabetic order)
//
// OTB includes (sorted by alphabetic order)
//
// Monteverdi includes (sorted by alphabetic order)
namespace mvd
{
/*
TRANSLATOR mvd::WorkerThread
Necessary for lupdate to be aware of C++ namespaces.
Context comment for translator.
*/
/*****************************************************************************/
/* CONSTANTS */
namespace
{
} // end of anonymous namespace.
/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION */
/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION */
/*******************************************************************************/
WorkerThread
::WorkerThread( AbstractWorker* worker, QObject* parent ) :
QObject( parent ),
m_Worker( worker )
{
QObject::connect(
this,
SIGNAL( started() ),
// to:
worker,
SLOT( Do() )
);
QObject::connect(
this,
SIGNAL( finished() ),
// to:
worker,
SLOT( deleteLater() )
);
m_Worker->moveToThread( this );
}
/*******************************************************************************/
WorkerThread
::~WorkerThread()
{
}
/*******************************************************************************/
/* SLOTS */
/*******************************************************************************/
} // end namespace 'mvd'
/*=========================================================================
Program: Monteverdi2
Language: C++
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See Copyright.txt for details.
Monteverdi2 is distributed under the CeCILL licence version 2. See
Licence_CeCILL_V2-en.txt or
http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef __mvdWorkerThread_h
#define __mvdWorkerThread_h
//
// Configuration include.
//// Included at first position before any other ones.
#include "ConfigureMonteverdi2.h"
/*****************************************************************************/
/* INCLUDE SECTION */
//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.
#include <QtCore>
//
// System includes (sorted by alphabetic order)
//
// ITK includes (sorted by alphabetic order)
//
// OTB includes (sorted by alphabetic order)
//
// Monteverdi includes (sorted by alphabetic order)
/*****************************************************************************/
/* PRE-DECLARATION SECTION */
//
// External classes pre-declaration.
namespace
{
}
namespace mvd
{
//
// Internal classes pre-declaration.
class AbstractWorker;
/*****************************************************************************/
/* CLASS DEFINITION SECTION */
/**
* \class WorkerThread
*
* \brief WIP.
*/
class Monteverdi2_EXPORT WorkerThread :
public QThread
{
/*-[ QOBJECT SECTION ]-----------------------------------------------------*/
Q_OBJECT;
/*-[ PUBLIC SECTION ]------------------------------------------------------*/
//
// Public methods.
public:
/**
* \brief Constructor.
*/
WorkerThread( AbstractWorker* worker, QObject* parent =NULL );
/**
* \brief Destructor.
*/
virtual ~WorkerThread();
/*-[ PUBLIC SLOTS SECTION ]------------------------------------------------*/
//
// Public SLOTS.
public slots:
/*-[ SIGNALS SECTION ]-----------------------------------------------------*/
//
// Signals.
signals:
/*-[ PROTECTED SECTION ]---------------------------------------------------*/
//
// Protected methods.
protected:
//
// Protected attributes.
protected:
/*-[ PRIVATE SECTION ]-----------------------------------------------------*/
//
// Private methods.
private:
//
// Private attributes.
private:
/**
*/
AbstractWorker* m_Worker;
/*-[ PRIVATE SLOTS SECTION ]-----------------------------------------------*/
//
// Slots.
private slots:
};
} // end namespace 'mvd'.
/*****************************************************************************/
/* INLINE SECTION */
//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.
//
// System includes (sorted by alphabetic order)
//
// ITK includes (sorted by alphabetic order)
//
// OTB includes (sorted by alphabetic order)
//
// Monteverdi includes (sorted by alphabetic order)
namespace mvd
{
} // end namespace 'mvd'
#endif // __mvdWorkerThread_h
......@@ -128,6 +128,20 @@ DatabaseModel
return datasetModel;
}
/*******************************************************************************/
void
DatabaseModel
::RegisterDatasetModel( DatasetModel* model )
{
qDebug() << this << "::RegisterDatasetModel(" << model << ")";
assert( model!=NULL );
// TODO: Implement slot.
delete model;
model = NULL;
}
/*******************************************************************************/
void
DatabaseModel
......
......@@ -162,6 +162,15 @@ signals:
/** */
void CurrentSelectedItemDeleted();
/*-[ PUBLIC SLOTS SECTION ]-----------------------------------------------*/
//
// Slots.
public slots:
/**
*/
void RegisterDatasetModel( DatasetModel* );
/*-[ PROTECTED SECTION ]---------------------------------------------------*/
//
......
......@@ -160,6 +160,7 @@ I18nApplication
{
// try if the filename is valid
VectorImageModel::EnsureValidImage(imageFilename);
// Build model (relink to cached data).
DatasetModel::BuildContext context( path, name, width, height );
model->BuildModel( &context );
......
/*=========================================================================
Program: Monteverdi2
Language: C++
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See Copyright.txt for details.
Monteverdi2 is distributed under the CeCILL licence version 2. See
Licence_CeCILL_V2-en.txt or
http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "mvdImageImporter.h"
/*****************************************************************************/
/* INCLUDE SECTION */
//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.
//
// System includes (sorted by alphabetic order)
#include <cassert>
//
// ITK includes (sorted by alphabetic order)
//
// OTB includes (sorted by alphabetic order)
//
// Monteverdi includes (sorted by alphabetic order)
#include "mvdDatasetModel.h"
#include "mvdI18nApplication.h"
namespace mvd
{
/*
TRANSLATOR mvd::ImageImporter
Necessary for lupdate to be aware of C++ namespaces.
Context comment for translator.
*/
/*****************************************************************************/
/* CONSTANTS */
namespace