diff --git a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetView.h b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetView.h index e0f204496208daa00a323d6707ebfbd997d822f3..09f905c46b240faada2afd7af530c7f6242c7f6d 100644 --- a/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetView.h +++ b/Modules/Wrappers/QtWidget/include/otbWrapperQtWidgetView.h @@ -22,52 +22,128 @@ #define otbWrapperQtWidgetView_h #include <QtGui> -#include <QObject> #include <QShortcut> + +// +// OTB includes (sorted by alphabetic order) #ifndef Q_MOC_RUN // See: https://bugreports.qt-project.org/browse/QTBUG-22829 //tag=QT4-boost-compatibility +#include "otbWrapperApplication.h" #include "otbWrapperQtWidgetModel.h" #endif //tag=QT4-boost-compatibility +#include "OTBQtWidgetExport.h" namespace otb { namespace Wrapper { -/** \class QtWidgetView - * \brief +/*****************************************************************************/ +/* CLASS DEFINITION SECTION */ + +/** + * \class QtWidgetView * * \ingroup OTBQtWidget + * + * \brief WIP. */ -class OTBQtWidget_EXPORT QtWidgetView : public QWidget + +class OTBQtWidget_EXPORT QtWidgetView : + public QWidget { + /*-[ QOBJECT SECTION ]-----------------------------------------------------*/ + Q_OBJECT + + Q_PROPERTY( bool isClosable + READ IsClosable + WRITE SetClosable ); + + /*-[ PUBLIC SECTION ]------------------------------------------------------*/ + +// +// Public methods. public: - QtWidgetView(Application* app); + + /** + */ + static char const * const OBJECT_NAME; + + /** \brief Constructor. */ + QtWidgetView( const otb::Wrapper::Application::Pointer & otbApp, + QWidget* p =0, + Qt::WindowFlags flags =0 ); + + /** \brief Destructor. */ ~QtWidgetView() override; + /** \brief Gui Creation. */ void CreateGui(); - QtWidgetModel* GetModel() + /** \brief Model Accessor */ + inline otb::Wrapper::QtWidgetModel* GetModel() { return m_Model; } + /** + * \return The OTB-application pointer of this view. + */ + //~ otb::Wrapper::Application::ConstPointer GetApplication() const + //~ { + //~ return otb::ConstCast< otb::Wrapper::Application >( + //~ m_Application + //~ ); + //~ } + + /** + */ + inline bool IsClosable() const; + + /*-[ PUBLIC SLOTS SECTION ]------------------------------------------------*/ + +// +// Public SLOTS. public slots: - void CloseSlot(); void UnhandledException(QString message); - void OnExceptionRaised(QString message); - -private slots: - void UpdateMessageAfterExecuteClicked(); - void UpdateMessageAfterCancelClicked(); - void UpdateMessageAfterExecution(int status); - void UpdateMessageAfterApplicationReady(bool val); + void OnExceptionRaised( QString what ); + /*-[ SIGNALS SECTION ]-----------------------------------------------------*/ +// +// Signals. signals: void QuitSignal(); + void ExecuteAndWriteOutput(); + void Stop(); + + + /*-[ PROTECTED SECTION ]---------------------------------------------------*/ + +// +// Protected methods. +protected: + + // + // QWidget overloads. + + void closeEvent( QCloseEvent * event ) override; + +// +// Protected attributes. +protected: + + /** Html section for 'Done' icon */ + std::string m_IconPathDone; + /** Html section for 'Failed' icon */ + std::string m_IconPathFailed; + + /*-[ PRIVATE SECTION ]-----------------------------------------------------*/ +// +// Private methods. private: + QtWidgetView(const QtWidgetView&); //purposely not implemented void operator=(const QtWidgetView&); //purposely not implemented @@ -77,21 +153,107 @@ private: QWidget* CreateDoc(); - Application::Pointer m_Application; - QtWidgetModel* m_Model; +// +// Private attributes. - QTextEdit *m_LogText; - QTabWidget *m_TabWidget; +private: + + otb::Wrapper::QtWidgetModel* m_Model; QPushButton* m_ExecButton; QPushButton* m_QuitButton; QShortcut* m_QuitShortcut; QLabel* m_Message; + QTextEdit *m_LogText; + QTabWidget *m_TabWidget; + + bool m_IsClosable : 1; + + bool m_IsRunning; + + /*-[ PRIVATE SLOTS SECTION ]-----------------------------------------------*/ + +// +// Slots. +private slots: + void UpdateMessageAfterExecution(int status); + void UpdateMessageAfterApplicationReady(bool val); + + /** + */ + void OnExecButtonClicked(); + + /** + */ + inline void OnProgressReportBegin(); + + /** + */ + inline void OnProgressReportEnd( int status ); + + /** + */ + inline void SetClosable( bool ); + }; +} // end namespace 'Wrapper' + +} // end namespace 'otb' + +/*****************************************************************************/ +/* INLINE SECTION */ + +namespace otb +{ + +namespace Wrapper +{ + +/*****************************************************************************/ +inline +bool +QtWidgetView +::IsClosable() const +{ + return m_IsClosable; +} + +/*****************************************************************************/ +inline +void +QtWidgetView +::SetClosable( bool enabled ) +{ + m_IsClosable = enabled; + + setEnabled( true ); + + if( m_QuitButton!=NULL ) + m_QuitButton->setEnabled( m_IsClosable ); +} +/*******************************************************************************/ +inline +void +QtWidgetView +::OnProgressReportBegin() +{ + SetClosable( false ); } + +/*******************************************************************************/ +inline +void +QtWidgetView +::OnProgressReportEnd( int ) +{ + SetClosable( true ); } +} // end namespace 'Wrapper' + +} // end namespace 'otb' + #endif diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetView.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetView.cxx index b265b5e88627a8dad342fe8c426bd0b91dce33c0..2daeb8d697cb3af39e49c65401e3e97a0bda626d 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetView.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetView.cxx @@ -20,31 +20,77 @@ #include "otbWrapperQtWidgetView.h" +#include <functional> + #include "otbWrapperQtWidgetParameterGroup.h" #include "otbWrapperQtWidgetParameterFactory.h" -#include "otbWrapperQtWidgetProgressReport.h" -#include "otbWrapperOutputImageParameter.h" -#include "otbWrapperChoiceParameter.h" -#include "otbWrapperQtWidgetSimpleProgressReport.h" #include "otbWrapperApplicationHtmlDocGenerator.h" - -#include "itksys/SystemTools.hxx" - +#include "otbWrapperOutputFilenameParameter.h" +#include "otbWrapperOutputVectorDataParameter.h" +#include "otbWrapperQtWidgetSimpleProgressReport.h" namespace otb { namespace Wrapper { - -QtWidgetView::QtWidgetView(Application* app) +/* + TRANSLATOR mvd::Wrapper::QtWidgetView + + Necessary for lupdate to be aware of C++ namespaces. + + Context comment for translator. +*/ + +/*****************************************************************************/ +/* CONSTANTS */ + +char const * const +QtWidgetView +::OBJECT_NAME = "otb::Wrapper::QtWidgetView"; + +/*****************************************************************************/ +/* CLASS IMPLEMENTATION SECTION */ +/*****************************************************************************/ +QtWidgetView::QtWidgetView( const otb::Wrapper::Application::Pointer & otbApp, + QWidget* p, + Qt::WindowFlags flags ) : + QWidget( p, flags ), + m_IconPathDone(""), + m_IconPathFailed(""), + m_Model( NULL ), + m_ExecButton( NULL ), + m_QuitButton( NULL ), + m_Message( NULL ), + m_LogText( NULL ), + m_TabWidget( NULL ), + m_IsClosable( true ), + m_IsRunning(false) { - m_Model = new QtWidgetModel(app); - m_Application = app; + setObjectName( QtWidgetView::OBJECT_NAME ); + + m_Model = new otb::Wrapper::QtWidgetModel( otbApp ); + m_QuitShortcut = new QShortcut(QKeySequence("Ctrl+Q"), this); + + QObject::connect( + m_Model, SIGNAL( SetProgressReportBegin() ), + this, SLOT( OnProgressReportBegin() ) + ); + + QObject::connect( + m_Model, SIGNAL( SetProgressReportDone( int ) ), + this, SLOT( OnProgressReportEnd( int ) ) + ); + + QObject::connect( + m_Model, SIGNAL( ExceptionRaised( QString ) ), + this, SLOT( OnExceptionRaised( QString ) ) + ); } QtWidgetView::~QtWidgetView() { delete m_Model; + m_Model = NULL; } void QtWidgetView::CreateGui() @@ -53,88 +99,74 @@ void QtWidgetView::CreateGui() QVBoxLayout *mainLayout = new QVBoxLayout(); m_TabWidget = new QTabWidget(); - m_TabWidget->addTab(CreateInputWidgets(), "Parameters"); + m_TabWidget->addTab(CreateInputWidgets(), tr("Parameters")); m_LogText = new QTextEdit(); connect( m_Model->GetLogOutput(), SIGNAL(NewContentLog(QString)), m_LogText, SLOT(append(QString) ) ); - m_TabWidget->addTab(m_LogText, "Logs"); - QtWidgetProgressReport* prog = new QtWidgetProgressReport(m_Model); - prog->SetApplication(m_Application); - m_TabWidget->addTab(prog, "Progress"); - m_TabWidget->addTab(CreateDoc(), "Documentation"); + m_TabWidget->addTab(m_LogText, tr("Logs")); + m_TabWidget->addTab(CreateDoc(), tr("Documentation")); mainLayout->addWidget(m_TabWidget); - m_Message = new QLabel("<center><font color=\"#FF0000\">Select parameters</font></center>"); - connect( m_Model, SIGNAL(SetApplicationReady(bool)), this, SLOT(UpdateMessageAfterApplicationReady(bool)) ); + m_Message = new QLabel("<center><font color=\"#FF0000\">"+tr("Select parameters")+"</font></center>"); + connect( m_Model, SIGNAL(SetApplicationReady(bool)), this, SLOT( UpdateMessageAfterApplicationReady(bool)) ); connect( m_Model, SIGNAL(SetProgressReportDone(int)), this, SLOT(UpdateMessageAfterExecution(int)) ); mainLayout->addWidget(m_Message); - QtWidgetSimpleProgressReport * progressReport = new QtWidgetSimpleProgressReport(m_Model); - progressReport->SetApplication(m_Application); + otb::Wrapper::QtWidgetSimpleProgressReport * progressReport = new otb::Wrapper::QtWidgetSimpleProgressReport(m_Model); + progressReport->SetApplication(m_Model->GetApplication()); + QWidget* footer = CreateFooter(); + QHBoxLayout *footLayout = new QHBoxLayout; footLayout->addWidget(progressReport); - footLayout->addWidget(CreateFooter()); + footLayout->addWidget(footer); mainLayout->addLayout(footLayout); + footLayout->setAlignment(footer, Qt::AlignBottom); + QGroupBox *mainGroup = new QGroupBox(); mainGroup->setLayout(mainLayout); QVBoxLayout *finalLayout = new QVBoxLayout(); finalLayout->addWidget(mainGroup); - connect( m_Model, SIGNAL(ExceptionRaised(QString)), this, SLOT(OnExceptionRaised(QString)) ); - // Make the final layout to the widget this->setLayout(finalLayout); } -void QtWidgetView::UpdateMessageAfterExecuteClicked() -{ - m_Message->setText("<center><font color=\"#FF0000\">Running</font></center>"); - m_ExecButton->setText(QObject::tr("Cancel")); - - disconnect( m_ExecButton, SIGNAL(clicked()), m_Model, SLOT(ExecuteAndWriteOutputSlot() ) ); - disconnect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterExecuteClicked() ) ); - connect( m_ExecButton, SIGNAL(clicked()), m_Model, SIGNAL(Stop())); - connect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterCancelClicked())); -} - -void QtWidgetView::UpdateMessageAfterCancelClicked() -{ - m_Message->setText("<center><font color=\"#FF0000\">Cancelling...</font></center>"); -} - void QtWidgetView::UpdateMessageAfterExecution(int status) { if (status >= 0) { - m_Message->setText("<center><font color=\"#00A000\">Done</font></center>"); + m_Message->setText("<center>"+QString(m_IconPathDone.c_str())+ + "<font color=\"#00A000\">"+tr("Done")+"</font></center>"); } else { - m_Message->setText("<center><font color=\"#FF0000\">Failed</font></center>"); + m_Message->setText("<center>"+QString(m_IconPathFailed.c_str())+ + "<font color=\"#FF0000\">"+tr("Failed")+"</font></center>"); } m_ExecButton->setText(QObject::tr("Execute")); - - disconnect( m_ExecButton, SIGNAL(clicked()), m_Model, SIGNAL(Stop())); - disconnect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterCancelClicked())); - connect( m_ExecButton, SIGNAL(clicked()), m_Model, SLOT(ExecuteAndWriteOutputSlot() ) ); - connect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterExecuteClicked() ) ); + m_IsRunning = false; } void QtWidgetView::UpdateMessageAfterApplicationReady( bool val ) { - if(val == true) - m_Message->setText("<center><font color=\"#00A000\">Ready to run</font></center>"); - else - m_Message->setText("<center><font color=\"#FF0000\">Select parameters</font></center>"); + if(!m_IsRunning) + { + if(val == true) + m_Message->setText("<center><font color=\"#00A000\">"+tr("Ready to run")+"</font></center>"); + else + m_Message->setText("<center><font color=\"#FF0000\">"+tr("Select parameters")+"</font></center>"); + } } QWidget* QtWidgetView::CreateInputWidgets() { QScrollArea *scrollArea = new QScrollArea; - // Put the main group inside a scroll area - scrollArea->setWidget(QtWidgetParameterFactory::CreateQtWidget(m_Model->GetApplication()->GetParameterList(), m_Model)); + + scrollArea->setWidget( otb::Wrapper::QtWidgetParameterFactory::CreateQtWidget( + m_Model->GetApplication()->GetParameterList(), + m_Model)); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); scrollArea->setWidgetResizable(true); @@ -148,7 +180,7 @@ QWidget* QtWidgetView::CreateFooter() // an HLayout with two buttons : Execute and Quit QGroupBox *footerGroup = new QGroupBox; QHBoxLayout *footerLayout = new QHBoxLayout; - + footerGroup->setFixedHeight(40); footerGroup->setContentsMargins(0, 0, 0, 0); footerLayout->setContentsMargins(5, 5, 5, 5); @@ -157,17 +189,17 @@ QWidget* QtWidgetView::CreateFooter() m_ExecButton->setDefault(true); m_ExecButton->setEnabled(false); m_ExecButton->setText(QObject::tr("Execute")); - connect( m_ExecButton, SIGNAL(clicked()), m_Model, SLOT(ExecuteAndWriteOutputSlot() ) ); - connect( m_Model, SIGNAL(SetApplicationReady(bool)), m_ExecButton, SLOT(setEnabled(bool)) ); - connect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterExecuteClicked() ) ); + connect( m_Model, SIGNAL( SetApplicationReady( bool ) ), m_ExecButton, SLOT( setEnabled( bool ) )); + QObject::connect( m_ExecButton, SIGNAL( clicked() ), this, SLOT( OnExecButtonClicked() )); + QObject::connect( this, SIGNAL( ExecuteAndWriteOutput() ), m_Model, SLOT( ExecuteAndWriteOutputSlot() )); + QObject::connect( this, SIGNAL( Stop() ), m_Model, SIGNAL( Stop() )); m_QuitButton = new QPushButton(footerGroup); m_QuitButton->setText(QObject::tr("Quit")); - connect( m_QuitButton, SIGNAL(clicked()), this, SLOT(CloseSlot()) ); + connect(m_QuitButton, SIGNAL( clicked() ), this, SLOT( close() )); // Add Ctrl-Q shortcut to quit - m_QuitShortcut = new QShortcut(QKeySequence("Ctrl+Q"), this); - connect( m_QuitShortcut, SIGNAL(activated()), this, SLOT(CloseSlot()) ); + connect( m_QuitShortcut, SIGNAL(activated()), this, SLOT(close()) ); // Put the buttons on the right footerLayout->addStretch(); @@ -187,7 +219,7 @@ QWidget* QtWidgetView::CreateDoc() QTextDocument * doc = new QTextDocument(); std::string docContain; - ApplicationHtmlDocGenerator::GenerateDoc( m_Application, docContain, true); + otb::Wrapper::ApplicationHtmlDocGenerator::GenerateDoc( GetModel()->GetApplication(), docContain); doc->setHtml(docContain.c_str()); @@ -196,13 +228,49 @@ QWidget* QtWidgetView::CreateDoc() return text; } -void QtWidgetView::CloseSlot() +void QtWidgetView::closeEvent( QCloseEvent * e ) { - // Close the widget - this->close(); + assert( e!=NULL ); + + if( !IsClosable() ) + { + assert( GetModel()->GetApplication() ); + + QMessageBox::warning( + this, + tr( "Warning!" ), + tr( "OTB-Application '%1' cannot be closed while running!") + .arg( GetModel()->GetApplication()->GetDocName() ) + ); + + e->ignore(); + + return; + } + + QWidget::closeEvent( e ); - // Emit a signal to close any widget that this gui belonging to emit QuitSignal(); + + deleteLater(); +} + +void +QtWidgetView +::OnExecButtonClicked() +{ + if (m_IsRunning) + { + m_Message->setText("<center><font color=\"#FF0000\">"+tr("Cancelling")+"...</font></center>"); + emit Stop(); + } + else + { + m_IsRunning = true; + m_Message->setText("<center><font color=\"#FF0000\">"+tr("Running")+"</font></center>"); + m_ExecButton->setText(QObject::tr("Cancel")); + emit ExecuteAndWriteOutput(); + } } void QtWidgetView::UnhandledException(QString message) @@ -211,10 +279,11 @@ void QtWidgetView::UnhandledException(QString message) m_LogText->append(message); } -void QtWidgetView::OnExceptionRaised(QString /*message*/) +void QtWidgetView::OnExceptionRaised( QString /*message*/) { m_TabWidget->setCurrentIndex(1); } } } +