Commit e58557d3 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD #227] added message popup windows. They can have a parent on whose...

[ADD #227] added message popup windows. They can have a parent on whose top,left corner they appear.
parent c55c51bb
......@@ -55,9 +55,25 @@ const std::vector< std::string >& WProjectFileIO::getErrors() const
return m_errors;
}
bool WProjectFileIO::hadWarnings() const
{
return m_warnings.size();
}
const std::vector< std::string >& WProjectFileIO::getWarnings() const
{
return m_warnings;
}
void WProjectFileIO::addError( std::string description )
{
wlog::error( "Project Loader" ) << description;
m_errors.push_back( description );
}
void WProjectFileIO::addWarning( std::string description )
{
wlog::warn( "Project Loader" ) << description;
m_warnings.push_back( description );
}
......@@ -86,6 +86,20 @@ public:
*/
const std::vector< std::string >& getErrors() const;
/**
* Checks whether there where warnings during load or save.
*
* \return true if there where.
*/
bool hadWarnings() const;
/**
* Get warnings list.
*
* \return the list
*/
const std::vector< std::string >& getWarnings() const;
protected:
/**
* Add an error. Use this when you encounter some difficulties during parsing or applying settings. Provide useful errors. They will be
......@@ -95,11 +109,24 @@ protected:
*/
void addError( std::string description );
/**
* Add an warning. Use this when you encounter some difficulties during parsing or applying settings. Provide useful warnings. They will be
* presented to the user.
*
* \param description the error description
*/
void addWarning( std::string description );
private:
/**
* List of errors if any.
*/
std::vector< std::string > m_errors;
/**
* List of warnings if any.
*/
std::vector< std::string > m_warnings;
};
#endif // WPROJECTFILEIO_H
......
......@@ -136,8 +136,9 @@ void WProjectFile::threadMain()
// Parse the file
wlog::info( "Project File" ) << "Loading project file \"" << m_project.string() << "\".";
// store some errors
// store some errors and warnings
std::vector< std::string > errors;
std::vector< std::string > warnings;
// read the file
std::ifstream input( m_project.string().c_str() );
......@@ -146,7 +147,7 @@ void WProjectFile::threadMain()
errors.push_back( std::string( "The project file \"" ) + m_project.string() + std::string( "\" does not exist." ) );
// give some feedback
m_signalLoadDone( m_project, errors );
m_signalLoadDone( m_project, errors, warnings );
m_signalLoadDoneConnection.disconnect();
// also throw an exception
......@@ -202,8 +203,9 @@ void WProjectFile::threadMain()
try
{
( *iter )->done();
// append errors
// append errors and warnings
std::copy( ( *iter )->getErrors().begin(), ( *iter )->getErrors().end(), std::back_inserter( errors ) );
std::copy( ( *iter )->getWarnings().begin(), ( *iter )->getWarnings().end(), std::back_inserter( warnings ) );
}
catch( const std::exception& e )
{
......@@ -213,7 +215,7 @@ void WProjectFile::threadMain()
}
// give some feedback
m_signalLoadDone( m_project, errors );
m_signalLoadDone( m_project, errors, warnings );
m_signalLoadDoneConnection.disconnect();
// remove from thread list
......
......@@ -57,12 +57,13 @@ public:
/**
* A callback function type reporting bach a finished load job. The given string vector contains a list of errors if any.
*/
typedef boost::function< void( boost::filesystem::path, std::vector< std::string > ) > ProjectLoadCallback;
typedef boost::function< void( boost::filesystem::path, std::vector< std::string >, std::vector< std::string > ) > ProjectLoadCallback;
/**
* A callback function signal type reporting bach a finished load job. The given string vector contains a list of errors if any.
*/
typedef boost::signals2::signal< void( boost::filesystem::path, std::vector< std::string > ) > ProjectLoadCallbackSignal;
typedef boost::signals2::signal< void( boost::filesystem::path, std::vector< std::string >, std::vector< std::string > ) >
ProjectLoadCallbackSignal;
/**
* Default constructor. It does NOT parse the file. Parsing is done by using load.
......
......@@ -210,8 +210,8 @@ void WModuleProjectFileCombiner::apply()
boost::shared_ptr< WPropertyBase > prop = m->getProperties()->findProperty( ( *iter ).first.second );
if( !prop )
{
// addError( "The module \"" + m->getName() + std::string( "\" has no property named \"" ) + ( *iter ).first.second +
// std::string( "\". Skipping." ) );
addWarning( "The module \"" + m->getName() + std::string( "\" has no property named \"" ) + ( *iter ).first.second +
std::string( "\". Skipping." ) );
continue;
}
else
......@@ -227,8 +227,8 @@ void WModuleProjectFileCombiner::apply()
}
else
{
addError( "The module \"" + m->getName() + "\" has a property named \"" +
( *iter ).first.second + "\" which is an INFORMATION property. Skipping." );
addWarning( "The module \"" + m->getName() + "\" has a property named \"" +
( *iter ).first.second + "\" which is an INFORMATION property. Skipping." );
}
}
}
......
......@@ -63,4 +63,7 @@
#include "ColorWheel.xpm"
#include "popup_more.xpm"
#include "popup_close.xpm"
#endif // WICONS_H
/* XPM */
const char * popup_close_xpm[] = {
"16 16 61 1",
" c None",
". c #AEB1A9",
"+ c #E0E1DF",
"@ c #8B8F88",
"# c #8B8E88",
"$ c #DFE0DF",
"% c #F0F1EC",
"& c #F0F0EC",
"* c #8F928D",
"= c #8D928A",
"- c #ECEDEA",
"; c #F2F5EF",
"> c #EEF0ED",
", c #EEF0EA",
"' c #F1F1F0",
") c #90918C",
"! c #90938C",
"~ c #EFF0EE",
"{ c #F1F4EE",
"] c #F0F2EE",
"^ c #8D908A",
"/ c #F0F0EF",
"( c #F2F4EE",
"_ c #F2F5F2",
": c #F2F4F0",
"< c #F6F7F2",
"[ c #EFF0EF",
"} c #91928B",
"| c #F5F7F1",
"1 c #F7F9F4",
"2 c #91938C",
"3 c #8F918B",
"4 c #F2F2EE",
"5 c #F2F4EF",
"6 c #F3F5F0",
"7 c #8F918C",
"8 c #8E928B",
"9 c #F1F2F0",
"0 c #ECEEEA",
"a c #EFF1EE",
"b c #F0F2EC",
"c c #8F928A",
"d c #8C8F88",
"e c #EDEFEB",
"f c #E7E9E3",
"g c #90928B",
"h c #EAEDE8",
"i c #EEF0EC",
"j c #8C8E88",
"k c #E1E2E0",
"l c #E9ECE7",
"m c #EEF0EB",
"n c #8B9089",
"o c #8B8D87",
"p c #EBECE9",
"q c #EEF1EB",
"r c #A8AAA2",
"s c #868983",
"t c #878983",
"u c #DEDFDE",
"v c #ACAFA9",
" ",
" ",
" ",
" .+@ #$. ",
" +%&* =-;+ ",
" #>,')!~{]@ ",
" ^/(_:<[= ",
" }]|1:2 ",
" 3456:7 ",
" 890]ab'c ",
" def93g[hij ",
" klmn opq+ ",
" r+s tuv ",
" ",
" ",
" "};
/* XPM */
const char * popup_more_xpm[] = {
"16 16 52 1",
" c None",
". c #BCBEB8",
"+ c #B6BAB4",
"@ c #A5A7A2",
"# c #A0A39D",
"$ c #BBBDB7",
"% c #FBFBFA",
"& c #F7F7F7",
"* c #AAAEA7",
"= c #CACBC9",
"- c #FDFDFC",
"; c #FBFAFA",
"> c #7F827B",
", c #B2B6AF",
"' c #EEEEED",
") c #F2F2F0",
"! c #FFFFFF",
"~ c #A6A7A3",
"{ c #B3B5B2",
"] c #FCFCFB",
"^ c #EFEFED",
"/ c #C8CAC7",
"( c #7E7F7A",
"_ c #A4A6A1",
": c #F8F8F8",
"< c #9C9F9B",
"[ c #C8CAC6",
"} c #FBFBFB",
"| c #F1F0EF",
"1 c #CCCECA",
"2 c #9DA19B",
"3 c #E9E9E7",
"4 c #EFEFEE",
"5 c #FFFFFE",
"6 c #AFB1AD",
"7 c #F9FAF9",
"8 c #E7E8E6",
"9 c #CACBC8",
"0 c #72746F",
"a c #949892",
"b c #E7E7E5",
"c c #E7E8E5",
"d c #F6F6F6",
"e c #EAEBE8",
"f c #C7C9C5",
"g c #8F918C",
"h c #DFDFDD",
"i c #E1E2DF",
"j c #C4C5C2",
"k c #6D6F6B",
"l c #878A84",
"m c #B5B7B3",
" ",
" ",
" ",
" ",
" .+ @# ",
" $%&* =-;> ",
" ,')!~ {]^/( ",
" _'):< [}|1 ",
" 234567890 ",
" abcdef ",
" ghijk ",
" lm ",
" 0 ",
" ",
" ",
" "};
......@@ -84,6 +84,7 @@
#include "events/WCloseCustomDockWidgetEvent.h"
#include "events/WLoadFinishedEvent.h"
#include "guiElements/WQtPropertyBoolAction.h"
#include "guiElements/WQtMessagePopup.h"
#include "WQt4Gui.h"
#include "WQtCombinerToolbar.h"
#include "WQtCustomDockWidget.h"
......@@ -194,6 +195,8 @@ void WMainWindow::setupGUI()
m_iconManager.addIcon( std::string( "axial icon" ), axial_xpm );
m_iconManager.addIcon( std::string( "coronal icon" ), cor_xpm );
m_iconManager.addIcon( std::string( "sagittal icon" ), sag_xpm );
m_iconManager.addIcon( std::string( "popup_more" ), popup_more_xpm );
m_iconManager.addIcon( std::string( "popup_close" ), popup_close_xpm );
try
{
......@@ -717,14 +720,14 @@ void WMainWindow::openLoadDialog()
void WMainWindow::asyncProjectLoad( std::string filename )
{
WProjectFile::SPtr proj( new WProjectFile( filename, boost::bind( &WMainWindow::slotLoadFinished, this, _1, _2 ) ) );
WProjectFile::SPtr proj( new WProjectFile( filename, boost::bind( &WMainWindow::slotLoadFinished, this, _1, _2, _3 ) ) );
proj->load();
}
void WMainWindow::slotLoadFinished( boost::filesystem::path file, std::vector< std::string > errors )
void WMainWindow::slotLoadFinished( boost::filesystem::path file, std::vector< std::string > errors, std::vector< std::string > warnings )
{
// as this function might be called from outside the gui thread, use an event:
QCoreApplication::postEvent( this, new WLoadFinishedEvent( file, errors ) );
QCoreApplication::postEvent( this, new WLoadFinishedEvent( file, errors, warnings ) );
if( errors.size() )
{
......@@ -897,6 +900,24 @@ void WMainWindow::customEvent( QEvent* event )
}
}
void WMainWindow::reportError( QWidget* parent, QString title, QString message )
{
WQtMessagePopup* m = new WQtMessagePopup( parent, title, message, WQtMessagePopup::ERROR );
m->show();
}
void WMainWindow::reportWarning( QWidget* parent, QString title, QString message )
{
WQtMessagePopup* m = new WQtMessagePopup( parent, title, message, WQtMessagePopup::WARNING );
m->show();
}
void WMainWindow::reportInfo( QWidget* parent, QString title, QString message )
{
WQtMessagePopup* m = new WQtMessagePopup( parent, title, message, WQtMessagePopup::INFO );
m->show();
}
bool WMainWindow::event( QEvent* event )
{
// a module got associated with the root container -> add it to the list
......@@ -916,15 +937,9 @@ bool WMainWindow::event( QEvent* event )
WModuleCrashEvent* e1 = dynamic_cast< WModuleCrashEvent* >( event ); // NOLINT
if( e1 )
{
QString title = "Problem in module: " + QString::fromStdString( e1->getModule()->getName() );
QString description = "<b>Module Problem</b><br/><br/><b>Module: </b>" + QString::fromStdString( e1->getModule()->getName() );
QString title = "Module \"" + QString::fromStdString( e1->getModule()->getName() ) + "\" caused a problem.";
QString message = QString::fromStdString( e1->getMessage() );
QMessageBox msgBox;
msgBox.setText( description );
msgBox.setInformativeText( message );
msgBox.setStandardButtons( QMessageBox::Ok );
msgBox.exec();
reportError( m_networkEditor->getView(), title, message );
}
}
......@@ -944,7 +959,7 @@ bool WMainWindow::event( QEvent* event )
WLoadFinishedEvent* e1 = dynamic_cast< WLoadFinishedEvent* >( event );
if( e1 )
{
if( e1->getErrors().size() )
if( e1->getErrors().size() || e1->getWarnings().size() )
{
size_t curErrCount = 0;
const size_t maxErrCount = 5;
......@@ -963,11 +978,48 @@ bool WMainWindow::event( QEvent* event )
}
errors += "</ul>";
QMessageBox::critical( this, "Error during load",
size_t curWarnCount = 0;
const size_t maxWarnCount = 5;
std::string warnings = "<ul>";
for( std::vector< std::string >::const_iterator iter = e1->getWarnings().begin(); iter != e1->getWarnings().end(); ++iter )
{
warnings += "<li> " + *iter;
curWarnCount++;
if( ( curWarnCount == maxWarnCount ) && ( e1->getWarnings().size() > maxWarnCount ) )
{
size_t warnDiff = e1->getWarnings().size() - curWarnCount;
warnings += "<li> ... and " + string_utils::toString( warnDiff ) + " more warnings.";
break;
}
}
warnings += "</ul>";
if( curWarnCount && curErrCount ) // Errors and warnings
{
reportError( m_networkEditor->getView(), "There where errors and warnings during load.",
"Errors occurred during load of \"" + QString::fromStdString( e1->getFilename() ) + "\". "
"The loader tried to apply as much as possible, ignoring the erroneous data. The first errors where:"
+ QString::fromStdString( errors ) +
"Warnings occurred during load of \"" + QString::fromStdString( e1->getFilename() ) + "\". "
+ QString::fromStdString( warnings )
);
}
else if ( curWarnCount && !curErrCount ) // only warnings
{
reportWarning( m_networkEditor->getView(), "There where warnings during load.",
"Warnings occurred during load of \"" + QString::fromStdString( e1->getFilename() ) + "\". "
+ QString::fromStdString( warnings )
);
}
else if ( !curWarnCount && curErrCount ) // only errors
{
reportError( m_networkEditor->getView(), "There where errors during load.",
"Errors occurred during load of \"" + QString::fromStdString( e1->getFilename() ) + "\". "
"The loader tried to apply as much as possible, ignoring the erroneous data. The first errors where:"
"<br><br>"
"<font color=\"#f00\">" + QString::fromStdString( errors )+ "</font>" );
+ QString::fromStdString( errors )
);
}
}
}
}
......
......@@ -195,6 +195,32 @@ public:
*/
void addGlobalMenu( QWidget* widget );
/**
* Allows comfortable error reporting using popups.
*
* \param parent the parent widget for this popup
* \param title the title
* \param message the message
*/
void reportError( QWidget* parent, QString title, QString message );
/**
* Allows comfortable warning reporting using popups.
*
* \param parent the parent widget for this popup
* \param title the title
* \param message the message
*/
void reportWarning( QWidget* parent, QString title, QString message );
/**
* Allows comfortable info reporting using popups.
*
* \param parent the parent widget for this popup
* \param title the title
* \param message the message
*/
void reportInfo( QWidget* parent, QString title, QString message );
protected:
/**
* Setup the GUI by handling special modules. NavSlices for example setup several toolbar buttons.
......@@ -426,9 +452,9 @@ private:
*
* \param file the filename
* \param errors the list of errors
* \param warnings the list of warnings
*/
void slotLoadFinished( boost::filesystem::path file, std::vector< std::string > errors );
void slotLoadFinished( boost::filesystem::path file, std::vector< std::string > errors, std::vector< std::string > warnings );
private slots:
/**
......
......@@ -29,10 +29,11 @@
#include "WLoadFinishedEvent.h"
WLoadFinishedEvent::WLoadFinishedEvent( boost::filesystem::path filename, std::vector< std::string > errors )
WLoadFinishedEvent::WLoadFinishedEvent( boost::filesystem::path filename, std::vector< std::string > errors, std::vector< std::string > warnings )
: QEvent( static_cast< QEvent::Type >( WQT_LOADFINISHED ) ),
m_filename( filename ),
m_errors( errors )
m_errors( errors ),
m_warnings( warnings )
{
// initialize members
}
......@@ -47,6 +48,11 @@ const std::vector< std::string >& WLoadFinishedEvent::getErrors() const
return m_errors;
}
const std::vector< std::string >& WLoadFinishedEvent::getWarnings() const
{
return m_warnings;
}
std::string WLoadFinishedEvent::getFilename() const
{
return m_filename.string();
......
......@@ -43,8 +43,9 @@ public:
*
* \param filename the filename of the file that was loaded
* \param errors the list of errors. Can be empty.
* \param warnings the list of warnings. Can be empty.
*/
WLoadFinishedEvent( boost::filesystem::path filename, std::vector< std::string > errors );
WLoadFinishedEvent( boost::filesystem::path filename, std::vector< std::string > errors, std::vector< std::string > warnings );
/**
* Destructor.
......@@ -58,6 +59,13 @@ public:
*/
const std::vector< std::string >& getErrors() const;
/**
* Returns the list of warnings
*
* \return the warnings.
*/
const std::vector< std::string >& getWarnings() const;
/**
* The filename of the file loaded.
*
......@@ -76,6 +84,11 @@ private:
* The error list.
*/
std::vector< std::string > m_errors;
/**
* The warnings list.
*/
std::vector< std::string > m_warnings;
};
#endif // WLOADFINISHEDEVENT_H
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <QtGui/QHBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QCloseEvent>
#include <QtGui/QHideEvent>
#include <QtGui/QShowEvent>
#include <QtGui/QMessageBox>
#include "core/common/WLogger.h"
#include "WScaleLabel.h"
#include "../WMainWindow.h"
#include "../WIconManager.h"
#include "WQtMessagePopup.h"
#include "WQtMessagePopup.moc"
#define OUTERMARGIN 10
#define BORDERWIDTH 2
#define CONTENTHEIGHT 16
WQtMessagePopup::WQtMessagePopup( QWidget* parent, const QString& title, const QString& message, MessageType type ):
QDialog( parent, Qt::Popup | Qt::FramelessWindowHint ),
m_title( title ),
m_message( message ),
m_type( type )
{
// these settings seem to be ignored somehow
setWindowModality( Qt::NonModal );
setModal( false );
// get top left corner