Commit c9a307a3 authored by Victor Poughon's avatar Victor Poughon

Merge branch 'redesign-gui' into 'develop'

Design improvements of applications Qt Wrapper

See merge request orfeotoolbox/otb!468
parents 98a40235 41a7950b
Pipeline #1275 passed with stages
in 7 minutes and 4 seconds
......@@ -194,7 +194,7 @@ protected:
*/
double Value(BandNameType band, const itk::VariableLengthVector<TInput>& input) const
{
assert(m_RequiredBands[band] && "Retrieving value for a band that is not in the required bands list");
assert(m_RequiredBands[static_cast<size_t>(band)] && "Retrieving value for a band that is not in the required bands list");
return static_cast<double>(input[UncheckedBandIndex(band) - 1]);
}
......
......@@ -1372,56 +1372,6 @@ MainWindow
{
assert( e!=NULL );
{
//
// List OTB-application widgets.
typedef QList< mvd::Wrapper::QtWidgetView * > QtWidgetViewList;
QtWidgetViewList c( findChildren< mvd::Wrapper::QtWidgetView * >() );
QStringList names;
//
// Find out which OTB-applications are running.
for( QtWidgetViewList::iterator it( c.begin() );
it!=c.end();
++ it )
{
assert( *it );
if( !( *it )->IsClosable() )
{
assert( ( *it )->GetModel()->GetApplication() );
// qDebug() << "OTB-application:" << ( *it )->GetApplication()->GetDocName();
names.push_back( ( *it )->GetModel()->GetApplication()->GetDocName() );
}
}
//
// If some OTB-application is running, display warning, names and
// prevent to close.
if( !names.isEmpty() )
{
QMessageBox::warning(
this,
tr( "Warning!" ),
tr(
PROJECT_NAME
" cannot exit while some OTB-application is running!\n\n"
"Please wait for following OTB-applicatio(s) to exit:\n- %1"
)
.arg( names.join( "\n- " ) )
);
e->ignore();
return;
}
}
{
assert( I18nCoreApplication::Instance()!=NULL );
assert( I18nCoreApplication::Instance()->GetModel()==
......
......@@ -62,7 +62,7 @@ public:
otb::Wrapper::Application::Pointer PrepareApplication(const QString& appName, bool isStandalone = false) const;
otb::Wrapper::QtMainWindow* NewOtbApplicationWindow(const QString& appName, bool isStandalone = false, QWidget* p = nullptr, Qt::WindowFlags = 0) const;
otb::Wrapper::QtMainWindow* NewOtbApplicationWindow(const QString& appName, bool isStandalone = false, QWidget* p = nullptr) const;
};
} // namespace mvd
......
......@@ -90,7 +90,7 @@ namespace Wrapper
*/
template< typename W >
void
SetupForFilenameDrop( W* widget, const char* text =NULL );
SetupForFilenameDrop( W* widget );
/**
*/
......@@ -376,7 +376,7 @@ FileSelectionInitializer
{
assert( widget!=NULL );
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
}
/*****************************************************************************/
......@@ -387,7 +387,7 @@ InputImageInitializer
{
assert( widget!=NULL );
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
}
/*****************************************************************************/
......@@ -409,7 +409,7 @@ InputFilenameInitializer
{
assert( widget!=NULL );
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
}
/*****************************************************************************/
......@@ -431,7 +431,7 @@ InputVectorDataInitializer
{
assert( widget!=NULL );
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
}
/*****************************************************************************/
......@@ -453,7 +453,7 @@ InputProcessXMLInitializer
{
assert( widget!=NULL );
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
}
/*****************************************************************************/
......@@ -494,7 +494,7 @@ OutputImageInitializer
if( m_Prefix.isEmpty() )
{
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
assert( qApp!=NULL );
assert( !qApp->arguments().empty() );
......@@ -518,7 +518,7 @@ OutputVectorDataInitializer
{
assert( widget!=NULL );
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
assert( qApp!=NULL );
assert( !qApp->arguments().empty() );
......@@ -534,7 +534,7 @@ OutputFilenameInitializer
{
assert( widget!=NULL );
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
assert( qApp!=NULL );
assert( !qApp->arguments().empty() );
......@@ -550,7 +550,7 @@ OutputProcessXMLInitializer
{
assert( widget!=NULL );
SetupForFilenameDrop( widget, "You can drop filename here." );
SetupForFilenameDrop( widget );
assert( qApp!=NULL );
assert( !qApp->arguments().empty() );
......@@ -592,7 +592,7 @@ ParameterListInitializer
/*****************************************************************************/
template< typename W >
void
SetupForFilenameDrop( W* widget, const char* text )
SetupForFilenameDrop( W* widget )
{
assert( widget!=NULL );
......@@ -602,15 +602,12 @@ SetupForFilenameDrop( W* widget, const char* text )
// Setup widget.
bool signalsBlocked = lineEdit->blockSignals( true );
{
if( text!=NULL )
{
lineEdit->setPlaceholderText(
QCoreApplication::translate(
"mvd::Wrapper::QtWidgetView",
text
"You can drop a file here"
)
);
}
// lineEdit->setReadOnly( true );
......
......@@ -64,18 +64,10 @@ namespace Wrapper
class OTBMonteverdiGUI_EXPORT QtWidgetView :
public otb::Wrapper::QtWidgetView
{
/*-[ QOBJECT SECTION ]-----------------------------------------------------*/
Q_OBJECT
/*-[ PUBLIC SECTION ]------------------------------------------------------*/
//
// Public methods.
public:
/**
*/
static char const * const OBJECT_NAME;
/** \brief Constructor. */
......@@ -86,30 +78,18 @@ public:
/** \brief Destructor. */
~QtWidgetView() override;
protected:
bool BeforeExecuteButtonClicked() override;
protected:
QWidget* CreateInputWidgets() override;
protected slots:
/** extend the behaviour of base class OnExecButtonClicked */
void OnExecButtonClicked() override;
/** modify the behaviour of base class OnExceptionRaised
*/
void OnExceptionRaised( QString what ) override;
private:
QtWidgetView(const QtWidgetView&) = delete;
void operator=(const QtWidgetView&) = delete;
/**
*/
void SetupParameterWidgets( QWidget* widget );
/**
*/
void SetupFileSelectionWidget( QWidget * );
private slots:
......@@ -119,12 +99,8 @@ private slots:
// image filename{s} set by the user in this OTB application (if any).
void OnApplicationExecutionDone( int );
/**
*/
inline void OnFileSelectionWidgetAdded0( QWidget * );
/**
*/
inline void OnFileSelectionWidgetAdded1( QWidget * );
};
......@@ -132,16 +108,12 @@ private slots:
} // end namespace 'mvd'
/*****************************************************************************/
/* INLINE SECTION */
namespace mvd
{
namespace Wrapper
{
/*******************************************************************************/
inline
void
QtWidgetView
......@@ -150,7 +122,6 @@ QtWidgetView
SetupFileSelectionWidget( widget );
}
/*******************************************************************************/
inline
void
QtWidgetView
......
......@@ -179,12 +179,7 @@ ApplicationLauncher
}
otb::Wrapper::QtMainWindow*
ApplicationLauncher
::NewOtbApplicationWindow( const QString & appName,
bool isStandalone,
QWidget* parent,
Qt::WindowFlags flags ) const
otb::Wrapper::QtMainWindow* ApplicationLauncher ::NewOtbApplicationWindow(const QString& appName, bool isStandalone, QWidget* parent) const
{
// Setup the otb application
auto otbApp = PrepareApplication(appName, isStandalone);
......@@ -194,7 +189,7 @@ ApplicationLauncher
gui->CreateGui();
// Make the application window
auto window = new ::otb::Wrapper::QtMainWindow(otbApp, gui, parent, flags | Qt::Window);
auto window = new ::otb::Wrapper::QtMainWindow(otbApp, gui, parent);
return window;
}
......
......@@ -116,13 +116,6 @@ char const * const
QtWidgetView
::OBJECT_NAME = "mvd::Wrapper::QtWidgetView";
/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION */
/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION */
/*****************************************************************************/
QtWidgetView
::QtWidgetView( const otb::Wrapper::Application::Pointer & otbApp,
QWidget* p,
......@@ -131,10 +124,6 @@ QtWidgetView
{
setObjectName( QtWidgetView::OBJECT_NAME );
m_IconPathDone = std::string("<img src=\":/icons/done\" width=\"16\" height=\"16\" />");
m_IconPathFailed = std::string("<img src=\":/icons/failed\" width=\"16\" height=\"16\" />");
//
// need to be connected to the end of a process
QObject::connect(
GetModel(),
......@@ -158,10 +147,7 @@ QtWidgetView
{
QWidget * widget = otb::Wrapper::QtWidgetView::CreateInputWidgets();
otb::Wrapper::QtWidgetParameterBase *paramWidget =
widget->findChild<otb::Wrapper::QtWidgetParameterBase*>();
SetupParameterWidgets(paramWidget);
SetupParameterWidgets(widget);
return widget;
}
......@@ -211,197 +197,90 @@ QtWidgetView
initialize( qobject_cast< FileSelectionInitializer::argument_type >( widget ) );
}
/*******************************************************************************/
/* SLOTS */
/*******************************************************************************/
void
QtWidgetView
::OnExecButtonClicked()
bool QtWidgetView::BeforeExecuteButtonClicked()
{
if ( !IsRunning() )
assert(GetModel() != NULL);
assert(GetModel()->GetApplication() != NULL);
assert(I18nCoreApplication::Instance() != NULL);
// Get layer-stack, if any
StackedLayerModel* layerStack = I18nCoreApplication::Instance()->GetModel<StackedLayerModel>();
otb::Wrapper::Application::Pointer otbApp(GetModel()->GetApplication());
// Check output parameters of OTB-application
StringVector paramKeys(otbApp->GetParametersKeys());
QStringList filenames1;
KeyLayerAccumulator::KeyLayerPairList layers;
for (StringVector::const_iterator it(paramKeys.begin()); it != paramKeys.end(); ++it)
{
if (otbApp->IsParameterEnabled(*it, true) && otbApp->HasValue(*it))
{
assert( GetModel()!=NULL );
assert( GetModel()->GetApplication()!=NULL );
assert( I18nCoreApplication::Instance()!=NULL );
//
// Get layer-stack, if any.
StackedLayerModel * layerStack =
I18nCoreApplication::Instance()->GetModel< StackedLayerModel >();
otb::Wrapper::Application::Pointer otbApp( GetModel()->GetApplication() );
//
// Check output parameters of OTB-application.
StringVector paramKeys( otbApp->GetParametersKeys() );
QStringList filenames1;
KeyLayerAccumulator::KeyLayerPairList layers;
QStringList filenames2;
for( StringVector::const_iterator it( paramKeys.begin() );
it!=paramKeys.end();
++it )
otb::Wrapper::Parameter::Pointer param(otbApp->GetParameterByKey(*it));
assert(!param.IsNull());
std::string filename;
switch (otbApp->GetParameterType(*it))
{
if( otbApp->IsParameterEnabled( *it, true ) &&
otbApp->HasValue( *it ) )
{
otb::Wrapper::Parameter::Pointer param( otbApp->GetParameterByKey( *it ) );
assert( !param.IsNull() );
// qDebug()
// << it->c_str() << ": type" << otbApp->GetParameterType( *it );
// const char* filename = NULL;
std::string filename;
switch( otbApp->GetParameterType( *it ) )
{
case otb::Wrapper::ParameterType_OutputFilename:
filename =
otb::DynamicCast< otb::Wrapper::OutputFilenameParameter >( param )
->GetValue();
break;
//
// FILENAME.
//
// IMAGE.
case otb::Wrapper::ParameterType_OutputImage:
filename =
otb::DynamicCast< otb::Wrapper::OutputImageParameter >( param )
->GetFileName();
break;
//
// VECTOR-DATA.
case otb::Wrapper::ParameterType_OutputVectorData:
filename =
otb::DynamicCast< otb::Wrapper::OutputVectorDataParameter >( param )
->GetFileName();
break;
//
// NONE.
default:
break;
case otb::Wrapper::ParameterType_OutputFilename:
filename = otb::DynamicCast<otb::Wrapper::OutputFilenameParameter>(param)->GetValue();
break;
case otb::Wrapper::ParameterType_OutputImage:
filename = otb::DynamicCast<otb::Wrapper::OutputImageParameter>(param)->GetFileName();
break;
case otb::Wrapper::ParameterType_OutputVectorData:
filename = otb::DynamicCast<otb::Wrapper::OutputVectorDataParameter>(param)->GetFileName();
break;
default:
break;
}
if (QFileInfo(filename.c_str()).exists())
filenames1.push_back(filename.c_str());
if (layerStack != NULL)
{
KeyLayerAccumulator accumulator(std::for_each(layerStack->Begin(), layerStack->End(), KeyLayerAccumulator(filename, layers)));
}
}
if( QFileInfo( filename.c_str() ).exists() )
filenames1.push_back( filename.c_str() );
if( layerStack!=NULL )
}
{
QString message;
if (filenames1.size() == 1)
{
KeyLayerAccumulator accumulator(
std::for_each(
layerStack->Begin(),
layerStack->End(), KeyLayerAccumulator( filename, layers )
)
);
if( accumulator.GetCount()>0 )
filenames2.push_back( filename.c_str() );
message = tr("Are you sure you want to overwrite file '%1'?").arg(filenames1.front());
}
}
}
else if (filenames1.size() > 1)
{
QString message;
if( filenames1.size()==1 )
{
// qDebug()
// << it->c_str() << ":" << QString( filename.c_str() );
message =
tr( "Are you sure you want to overwrite file '%1'?" )
.arg( filenames1.front() );
}
else if( filenames1.size()>1 )
{
message =
tr( "Following files will be overwritten. Are you sure you want to continue?\n- %1" )
.arg( filenames1.join( "\n- " ) );
}
if( !message.isEmpty() )
{
QMessageBox::StandardButton button =
QMessageBox::question(
this,
PROJECT_NAME,
message,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No
);
if( button==QMessageBox::No )
return;
}
message = tr("Following files will be overwritten. Are you sure you want to continue?\n- %1").arg(filenames1.join("\n- "));
}
if (!message.isEmpty())
{
QString message;
if( filenames2.size()==1 )
{
// qDebug()
// << it->c_str() << ":" << QString( filename.c_str() );
message =
tr( "File '%1' is being viewed in " PROJECT_NAME " and will be concurrently overwritten by running this %2. File will be removed from layer-stack before running %2 and reloaded after.\n\nDo you want to continue?" )
.arg( filenames2.front() )
.arg( otbApp->GetDocName() );
}
else if( filenames2.size()>1 )
{
message =
tr( "Following files are being viewed in " PROJECT_NAME " and will be concurrently overwritter by running %2. Files will be removed from layer-stack before running %2. Do you want to continue?\n- %1" )
.arg( filenames2.join( "\n- " ) )
.arg( otbApp->GetDocName() );
}
if( !message.isEmpty() )
{
QMessageBox::StandardButton button =
QMessageBox::question(
this,
PROJECT_NAME,
message,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No
);
if( button==QMessageBox::No )
return;
while( !layers.empty() )
{
layerStack->Delete( layers.front().first );
layers.pop_front();
}
}
QMessageBox::StandardButton button = QMessageBox::question(this, PROJECT_NAME, message, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
if (button == QMessageBox::No)
return false;
}
}
otb::Wrapper::QtWidgetView::OnExecButtonClicked();
}
// Delete from layer stack the images that will be overwritten and reloaded
while (!layers.empty())
{
layerStack->Delete(layers.front().first);
/*******************************************************************************/
void
QtWidgetView
::OnExceptionRaised( QString what )
{
qWarning() << what;
layers.pop_front();
}
#if defined( OTB_DEBUG )
QMessageBox::warning(
this,
PROJECT_NAME,
what,
QMessageBox::Ok
);
#endif
return true;
}
/*******************************************************************************/
......@@ -429,18 +308,6 @@ QtWidgetView
return;
}
/*
// Removed as per MVDX-259.
QMessageBox::information(
this,
PROJECT_NAME,
tr( "'%1' has succeeded.\n"
"Result(s) will be imported as dataset(s).\n")
.arg( otbApp->GetName() ),
QMessageBox::Ok
);
*/
CountType count = 0;
//
......
......@@ -105,6 +105,8 @@ public:
TiXmlElement* ParseApplication(Application::Pointer app);
static std::string MakeCommandLine(otb::Wrapper::Application::Pointer application);
protected:
OutputProcessXMLParameter();
......
......@@ -366,6 +366,77 @@ OutputProcessXMLParameter::ParseGroup(const std::string& group)
}
}
std::string OutputProcessXMLParameter::MakeCommandLine(Application::Pointer application)
{
OutputProcessXMLParameter::Pointer outXMLParam = OutputProcessXMLParameter::New();
TiXmlElement* XMLAppElement = outXMLParam->ParseApplication(application);
// Create command line from the XML document
TiXmlElement * pName, *pParam;
std::ostringstream cmdLine;
cmdLine << "";
if (XMLAppElement)
{
pName = XMLAppElement->FirstChildElement("name");
cmdLine << "otbcli_" << pName->GetText();
#ifdef _WIN32
cmdLine << ".bat";
#endif
cmdLine << " ";
// Parse application parameters
pParam = XMLAppElement->FirstChildElement("parameter");
while (pParam)
{
// Get parameter key
cmdLine << "-";
cmdLine << pParam->FirstChildElement("key")->GetText();
cmdLine << " ";
// Some parameters can have multiple values. Test it and handle this
// specific case
TiXmlElement* values = pParam->FirstChildElement("values");
if (values)
{
// Loop over value
TiXmlElement* pValue = values->FirstChildElement("value");
while (pValue)
{
cmdLine << pValue->GetText();
cmdLine << " ";
pValue = pValue->NextSiblingElement(); // iteration over multiple values
}
}
else
{
// Get parameter value
cmdLine << pParam->FirstChildElement("value")->GetText();
cmdLine << " ";
// In case of OutputImageparameter we need to report output pixel type
TiXmlElement* pPixType = pParam->FirstChildElement("pixtype");
if (pPixType)
{