Skip to content

Commit

Permalink
Add MessageDisplay & QtSignalChannel classes. Refs #6202
Browse files Browse the repository at this point in the history
  • Loading branch information
martyngigg committed Apr 15, 2013
1 parent 31764e3 commit 5a26f0a
Show file tree
Hide file tree
Showing 5 changed files with 390 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Code/Mantid/MantidQt/API/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ set ( SRC_FILES
src/MantidQwtIMDWorkspaceData.cpp
src/MantidQwtMatrixWorkspaceData.cpp
src/MantidWidget.cpp
src/MessageDisplay.cpp
src/OptionsPropertyWidget.cpp
src/PropertyWidget.cpp
src/PropertyWidgetFactory.cpp
src/PythonRunner.cpp
src/QtSignalChannel.cpp
src/ScriptRepositoryView.cpp
src/RepoModel.cpp
src/SyncedCheckboxes.cpp
Expand All @@ -38,9 +40,11 @@ set ( MOC_FILES
inc/MantidQtAPI/ManageUserDirectories.h
inc/MantidQtAPI/MantidDialog.h
inc/MantidQtAPI/MantidWidget.h
inc/MantidQtAPI/MessageDisplay.h
inc/MantidQtAPI/OptionsPropertyWidget.h
inc/MantidQtAPI/PropertyWidget.h
inc/MantidQtAPI/PythonRunner.h
inc/MantidQtAPI/QtSignalChannel.h
inc/MantidQtAPI/ScriptRepositoryView.h
inc/MantidQtAPI/RepoModel.h
inc/MantidQtAPI/SyncedCheckboxes.h
Expand Down
74 changes: 74 additions & 0 deletions Code/Mantid/MantidQt/API/inc/MantidQtAPI/MessageDisplay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#ifndef MESSAGEDISPLAY_H_
#define MESSAGEDISPLAY_H_

//----------------------------------
// Includes
//----------------------------------
#include "MantidQtAPI/QtSignalChannel.h"

#include <QWidget>

//----------------------------------------------------------
// Forward declarations
//----------------------------------------------------------
class QAction;
class QActionGroup;
class QPoint;
class QSignalMapper;
class QTextEdit;

namespace MantidQt
{
namespace API
{
/** @class MessageDisplay
* Provides a widget for display messages in a text box
* It deals with Message objects which in turn hide whether
* a message is a framework Poco message or a simple string
*/
class MessageDisplay : public QWidget
{
Q_OBJECT

public:
/// Constructor
MessageDisplay(QWidget *parent=NULL);
///Destructor
~MessageDisplay();

// Setup logging framework connections
void attachLoggingChannel();

public slots:
/// Write a message
void displayMessage(const QString & msg);

private slots:
/// Provide a custom context menu
void showContextMenu(const QPoint & event);
/// Set the global logging level
void setGlobalLogLevel(int priority);

private:
Q_DISABLE_COPY(MessageDisplay);
/// Setup the actions
void initActions();
/// Set the properties of the text display
void setupTextArea();

/// A reference to the
QtSignalChannel *m_logChannel;
/// The actual widget holding the text
QTextEdit * m_textDisplay;
/// Mutually exclusive log actions
QActionGroup *m_loglevels;
/// Map action signal to log level parameter
QSignalMapper *m_logLevelMapping;
/// Log level actions
QAction *m_error,*m_warning,*m_notice, *m_information, *m_debug;
};

}
}

#endif //MESSAGEDISPLAY_H_
59 changes: 59 additions & 0 deletions Code/Mantid/MantidQt/API/inc/MantidQtAPI/QtSignalChannel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef MANTIDQTAPI_QTSIGNALCHANNEL_H_
#define MANTIDQTAPI_QTSIGNALCHANNEL_H_

#include "DllOption.h"

#include <QObject>
#include <Poco/Channel.h>

namespace MantidQt
{
namespace API
{
/**
Provides a translation layer that takes a Poco::Message and converts it
to a Qt signal.
Copyright &copy; 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class EXPORT_OPT_MANTIDQT_API QtSignalChannel : public QObject, public Poco::Channel
{
Q_OBJECT

public:

/// Constructor
QtSignalChannel();
/// Destructor
~QtSignalChannel();

/// Converts the Poco::Message to a Qt signal
void log(const Poco::Message& msg);

signals:

// Emitted when a Poco log message is received in this channel
void messageReceived(const QString & msg);
};
}
}

#endif //MANTIDQTAPI_MANTIDWIDGET_H_
219 changes: 219 additions & 0 deletions Code/Mantid/MantidQt/API/src/MessageDisplay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
//-------------------------------------------
// Includes
//-------------------------------------------
#include "MantidQtAPI/MessageDisplay.h"

#include "MantidKernel/Logger.h"

#include <QAction>
#include <QActionGroup>
#include <QHBoxLayout>
#include <QMenu>
#include <QPoint>
#include <QSignalMapper>
#include <QTextEdit>

#include <Poco/Logger.h>
#include <Poco/Message.h>
#include <Poco/SplitterChannel.h>


namespace MantidQt
{
namespace API
{

//-------------------------------------------
// Public member functions
//-------------------------------------------
/**
* @param parent An optional parent widget
*/
MessageDisplay::MessageDisplay(QWidget *parent)
: QWidget(parent), m_logChannel(NULL), m_textDisplay(new QTextEdit(this)),
m_loglevels(new QActionGroup(this)), m_logLevelMapping(new QSignalMapper(this)),
m_error(new QAction(tr("&Error"), this)), m_warning(new QAction(tr("&Warning"), this)),
m_notice(new QAction(tr("&Notice"), this)), m_information(new QAction(tr("&Information"), this)),
m_debug(new QAction(tr("&Debug"), this))
{
initActions();
setupTextArea();
}

/**
* Attaches the Mantid logging framework
* (Note the ConfigService must have already been started)
*/
void MessageDisplay::attachLoggingChannel()
{
// Setup logging
m_logChannel = new QtSignalChannel;
auto & rootLogger = Poco::Logger::root();
auto * rootChannel = Poco::Logger::root().getChannel();
// The root channel might be a SplitterChannel
if(auto *splitChannel = dynamic_cast<Poco::SplitterChannel*>(rootChannel))
{
splitChannel->addChannel(m_logChannel);
}
else
{
Poco::Logger::setChannel(rootLogger.name(), m_logChannel);
}

connect(m_logChannel, SIGNAL(messageReceived(const QString&)),
this, SLOT(displayMessage(const QString &)));

}


/**
* @param A message that is echoed to the display
*/
void MessageDisplay::displayMessage(const QString & msg)
{
m_textDisplay->append(msg);
}

/**
*/
MessageDisplay::~MessageDisplay()
{
// The Channel class is ref counted and will
// delete itself when required
m_logChannel->release();
delete m_textDisplay;
}

//-----------------------------------------------------------------------------
// Private slot member functions
//-----------------------------------------------------------------------------

void MessageDisplay::showContextMenu(const QPoint & mousePos)
{
QMenu * menu = m_textDisplay->createStandardContextMenu();
if(!m_textDisplay->text().isEmpty()) menu->addAction("Clear",m_textDisplay, SLOT(clear()));

// Change the log level
QMenu *logLevelMenu = menu->addMenu("&Log Level");
logLevelMenu->addAction(m_error);
logLevelMenu->addAction(m_warning);
logLevelMenu->addAction(m_notice);
logLevelMenu->addAction(m_information);
logLevelMenu->addAction(m_debug);

//check the right level
int level = Mantid::Kernel::Logger::get("").getLevel(); //get the root logger logging level
if (level == Poco::Message::PRIO_ERROR)
m_error->setChecked(true);
if (level == Poco::Message::PRIO_WARNING)
m_warning->setChecked(true);
if (level == Poco::Message::PRIO_NOTICE)
m_notice->setChecked(true);
if (level == Poco::Message::PRIO_INFORMATION)
m_information->setChecked(true);
if (level == Poco::Message::PRIO_DEBUG)
m_debug->setChecked(true);

menu->exec(this->mapToGlobal(mousePos));
delete menu;

// QMenu *menu = results->createStandardContextMenu();
// if(!menu) return;
// if(results->text().isEmpty())
// {
// actionClearLogInfo->setEnabled(false);
// }
// else
// {
// actionClearLogInfo->setEnabled(true);
// }
//
// menu->addAction(actionClearLogInfo);
// //Mantid log level changes
// QMenu *logLevelMenu = menu->addMenu("&Log Level");
// logLevelMenu->addAction(actionLogLevelError);
// logLevelMenu->addAction(actionLogLevelWarning);
// logLevelMenu->addAction(actionLogLevelNotice);
// logLevelMenu->addAction(actionLogLevelInformation);
// logLevelMenu->addAction(actionLogLevelDebug);
//
// //check the right level
// int level = Mantid::Kernel::Logger::get("").getLevel(); //get the root logger logging level
// if (level == Poco::Message::PRIO_ERROR)
// actionLogLevelError->setChecked(true);
// if (level == Poco::Message::PRIO_WARNING)
// actionLogLevelWarning->setChecked(true);
// if (level == Poco::Message::PRIO_NOTICE)
// actionLogLevelNotice->setChecked(true);
// if (level == Poco::Message::PRIO_INFORMATION)
// actionLogLevelInformation->setChecked(true);
// if (level == Poco::Message::PRIO_DEBUG)
// actionLogLevelDebug->setChecked(true);

}

/*
* @param priority An integer that must match the Poco::Message priority
* enumeration
*/
void MessageDisplay::setGlobalLogLevel(int priority)
{
Mantid::Kernel::Logger::setLevelForAll(priority);
}

//-----------------------------------------------------------------------------
// Private non-slot member functions
//-----------------------------------------------------------------------------
/*
*/
void MessageDisplay::initActions()
{
m_error->setCheckable(true);
m_warning->setCheckable(true);
m_notice->setCheckable(true);
m_information->setCheckable(true);
m_debug->setCheckable(true);

m_loglevels->addAction(m_error);
m_loglevels->addAction(m_warning);
m_loglevels->addAction(m_notice);
m_loglevels->addAction(m_information);
m_loglevels->addAction(m_debug);

m_logLevelMapping->setMapping(m_error, Poco::Message::PRIO_ERROR);
m_logLevelMapping->setMapping(m_warning, Poco::Message::PRIO_WARNING);
m_logLevelMapping->setMapping(m_notice, Poco::Message::PRIO_NOTICE);
m_logLevelMapping->setMapping(m_information, Poco::Message::PRIO_INFORMATION);
m_logLevelMapping->setMapping(m_debug, Poco::Message::PRIO_DEBUG);

connect(m_error, SIGNAL(activated()), m_logLevelMapping, SLOT (map()));
connect(m_warning, SIGNAL(activated()), m_logLevelMapping, SLOT (map()));
connect(m_notice, SIGNAL(activated()), m_logLevelMapping, SLOT (map()));
connect(m_information, SIGNAL(activated()), m_logLevelMapping, SLOT (map()));
connect(m_debug, SIGNAL(activated()), m_logLevelMapping, SLOT (map()));

connect(m_logLevelMapping, SIGNAL(mapped(int)), this, SLOT(setGlobalLogLevel(int)));
}

/**
* Set the properties of the text display, i.e read-only
* and make it occupy the whole widget
*/
void MessageDisplay::setupTextArea()
{
m_textDisplay->setReadOnly(true);

this->setLayout(new QHBoxLayout(this));
QLayout *layout = this->layout();
layout->setContentsMargins(0,0,0,0);
layout->addWidget(m_textDisplay);

this->setFocusProxy(m_textDisplay);
m_textDisplay->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_textDisplay, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(showContextMenu(const QPoint&)));
}


}
}

0 comments on commit 5a26f0a

Please sign in to comment.