diff --git a/modules/base/src/CMakeLists.txt b/modules/base/src/CMakeLists.txt index 3ca08186ac38dd5b8a6a563338ba7278d4610d1d..4836b0896db66c48a37069196cd3fab6a8ff0393 100644 --- a/modules/base/src/CMakeLists.txt +++ b/modules/base/src/CMakeLists.txt @@ -1,6 +1,7 @@ set(OST_BASE_SOURCES generic_property.cc log.cc +log_sink.cc profile.cc units.cc string_ref.cc @@ -15,6 +16,7 @@ integrity_error.hh invalid_handle.hh ptr_observer.hh log.hh +log_sink.hh profile.hh dyn_cast.hh stdint.hh diff --git a/modules/base/src/log.cc b/modules/base/src/log.cc index 1a153426058779a1757b91fe59a070fcd116f58c..14bc027ae2cf77dd0bae6fe5d709980ec319e90e 100644 --- a/modules/base/src/log.cc +++ b/modules/base/src/log.cc @@ -16,27 +16,13 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ -#include <iostream> -#include <fstream> - - +#include <ost/log_sink.hh> #include <ost/log.hh> namespace ost { Logger& Log = Logger::Instance(); -namespace { - - class DevNull: public std::streambuf { - protected: - virtual int_type overflow(int_type c) {return c;} - virtual std::streamsize xsputn(const char* s, std::streamsize num) {return num;} - }; - -} // anon ns - - Logger& Logger::Instance() { static Logger inst; @@ -46,23 +32,23 @@ Logger& Logger::Instance() Logger::Logger(): level_(0), level_stack_(), - null_(new DevNull()), - stream_(0), - ostream_stack_() + sink_stack_(), + null_sink_(new NullLogSink()), + sink_() { - ostream_stack_.push(new std::ostream(std::cerr.rdbuf())); - stream_.rdbuf(ostream_stack_.top()->rdbuf()); + sink_stack_.push(LogSinkPtr(new StdLogSink(std::cerr))); + sink_= sink_stack_.top(); } Logger::Logger(const Logger&): level_(0), level_stack_(), - null_(0), - stream_(0), - ostream_stack_() + sink_stack_(), + null_sink_(new NullLogSink()), + sink_() { - ostream_stack_.push(new std::ostream(std::cerr.rdbuf())); - stream_.rdbuf(ostream_stack_.top()->rdbuf()); + sink_stack_.push(LogSinkPtr(new StdLogSink(std::cerr))); + sink_= sink_stack_.top(); } Logger& Logger::operator=(const Logger&) @@ -88,29 +74,41 @@ void Logger::PopVerbosityLevel() } } -std::ostream& Logger::operator()(enum LogLevel l) +LogSinkPtr& Logger::operator()(enum LogLevel l) { if(l<=level_) { - return stream_; + return sink_; } - return null_; + return null_sink_; } void Logger::PushFile(const String& fn) { - ostream_stack_.push(new std::ofstream(fn.c_str())); - stream_.rdbuf(ostream_stack_.top()->rdbuf()); + sink_stack_.push(LogSinkPtr(new FileLogSink(fn))); + sink_ = sink_stack_.top(); } void Logger::PopFile() { - if(ostream_stack_.size()>1) { - delete ostream_stack_.top(); - ostream_stack_.pop(); - stream_.rdbuf(ostream_stack_.top()->rdbuf()); + if(sink_stack_.size()>1) { + sink_stack_.pop(); + sink_ = sink_stack_.top(); } } +void Logger::PushSink(LogSinkPtr& sink) +{ + sink_stack_.push(sink); + sink_ = sink_stack_.top(); +} + +void Logger::PopSink() +{ + if(sink_stack_.size()>1) { + sink_stack_.pop(); + sink_ = sink_stack_.top(); + } +} } // ns diff --git a/modules/base/src/log.hh b/modules/base/src/log.hh index a6b3912a78ffc512929f1099ec1bdcbd3aea1aef..b3326d411278ac8cf2ccca21d17dc5abf12ed94d 100644 --- a/modules/base/src/log.hh +++ b/modules/base/src/log.hh @@ -22,11 +22,12 @@ #include <ostream> #include <stack> +#include <ost/log_sink.hh> #include <ost/module_config.hh> namespace ost { -typedef std::stack<std::ostream*> OStreamStack; +typedef std::stack<LogSinkPtr> LogSinkStack; // singleton class DLLEXPORT_OST_BASE Logger { @@ -39,18 +40,20 @@ public: DUMP, TRACE }; - + void PushVerbosityLevel(int level); void PopVerbosityLevel(); + void PushSink(LogSinkPtr& sink); void PushFile(const String& filename); + //! DEPRECATED use PopSink() instead void PopFile(); - - std::ostream& operator()(enum LogLevel); + void PopSink(); + LogSinkPtr& operator()(enum LogLevel); static Logger& Instance(); int GetLogLevel() const {return level_;} - + protected: Logger(); Logger(const Logger&); @@ -59,9 +62,9 @@ protected: private: int level_; std::stack<int> level_stack_; - std::ostream null_; - std::ostream stream_; - OStreamStack ostream_stack_; + LogSinkStack sink_stack_; + LogSinkPtr null_sink_; + LogSinkPtr sink_; }; #define PUSH_VERBOSITY(n) ::ost::Logger::Instance().PushVerbosityLevel(n) diff --git a/modules/base/src/log_sink.cc b/modules/base/src/log_sink.cc new file mode 100644 index 0000000000000000000000000000000000000000..c798ed018fb0108382f52d6ad0370aedb3262179 --- /dev/null +++ b/modules/base/src/log_sink.cc @@ -0,0 +1,52 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library 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.0 of the License, or (at your option) +// any later version. +// This library 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 this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#include <ost/log_sink.hh> +#include <iostream> +namespace ost { + +ObservableLogSink::ObservableLogSink(){} + +bool ObservableLogSink::AddObserver(LogObserverPtr& observer){ + if((std::find( this->observers_.begin(), this->observers_.end(), observer )) == this->observers_.end()) + { + this->observers_.push_back( observer ); + return true; + } + return false; +} +bool ObservableLogSink::RemoveObserver(LogObserverPtr& observer){ + std::vector<LogObserverPtr>::iterator found = std::find( this->observers_.begin(), this->observers_.end(), observer); + if( found != this->observers_.end() ){ + this->observers_.erase(found); + return true; + } + return false; +} + +void ObservableLogSink::LogMessage(const String& message){ + std::vector<LogObserverPtr>::const_iterator observers_it = this->observers_.begin() ; + while( observers_it != this->observers_.end() ) + { + ( *observers_it )->LogMessage(message) ; + observers_it++; + } +} + +} // ns + diff --git a/modules/base/src/log_sink.hh b/modules/base/src/log_sink.hh new file mode 100644 index 0000000000000000000000000000000000000000..8712e0f41fbef4cf4b61ee8d9d121265e4667363 --- /dev/null +++ b/modules/base/src/log_sink.hh @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library 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.0 of the License, or (at your option) +// any later version. +// This library 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 this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_LOG_SINK_HH +#define OST_LOG_SINK_HH + +#include <ostream> +#include <iostream> +#include <stack> +#include <vector> + +#include <boost/shared_ptr.hpp> + +#include <ost/module_config.hh> + +namespace ost { + +namespace { + + class DevNull: public std::streambuf { + protected: + virtual int_type overflow(int_type c) {return c;} + virtual std::streamsize xsputn(const char* s, std::streamsize num) {return num;} + }; + +} // anon ns + +class DLLEXPORT_OST_BASE LogSink { +public: + virtual void LogMessage(const String& message)=0; +}; + +typedef boost::shared_ptr<LogSink> LogSinkPtr; + +class DLLEXPORT_OST_BASE NullLogSink : public LogSink { +public: + NullLogSink():null_(new DevNull()){} + virtual void LogMessage(const String& message){null_ << message;} + +private: + std::ostream null_; +}; + + +class DLLEXPORT_OST_BASE StdLogSink : public LogSink { +public: + StdLogSink(std::ostream& stream):stream_(stream){} + virtual void LogMessage(const String& message){ + stream_ << message; + } + +private: + std::ostream& stream_; +}; + +class DLLEXPORT_OST_BASE LogObserver { +public: + virtual void LogMessage(const String& message)=0; +}; +typedef boost::shared_ptr<LogObserver> LogObserverPtr; + +class DLLEXPORT_OST_BASE ObservableLogSink : public LogSink { +public: + ObservableLogSink(); + bool AddObserver(LogObserverPtr& observer); + bool RemoveObserver(LogObserverPtr& observer); + void LogMessage(const String& message); +private: + std::vector<LogObserverPtr> observers_; +}; + +typedef boost::shared_ptr<ObservableLogSink> ObservableLogSinkPtr; + +} +#endif diff --git a/modules/gui/src/CMakeLists.txt b/modules/gui/src/CMakeLists.txt index 6a5f6f58dba1f5ea66e46dd061ea71fee89adcff..9d2cae37e2d50a1fd38f74531c8772a0369bf4b9 100644 --- a/modules/gui/src/CMakeLists.txt +++ b/modules/gui/src/CMakeLists.txt @@ -93,6 +93,7 @@ scene_win_model.hh set(OST_GUI_INFO_WIDGET_HEADERS info_widget.hh +log_reader.hh ) if (ENABLE_SPNAV) @@ -212,6 +213,7 @@ admin.cc widget_pool.cc remote_site_loader.cc info_widget/info_widget.cc +info_widget/log_reader.cc sequence_viewer/align_properties_painter.cc sequence_viewer/base_row.cc sequence_viewer/background_painter.cc @@ -346,6 +348,7 @@ widget.hh widget_geom_handler.hh widget_pool.hh info_widget/info_widget.hh +info_widget/log_reader.hh sequence_viewer/align_properties_painter.hh sequence_viewer/background_painter.hh sequence_viewer/base_row.hh diff --git a/modules/gui/src/info_widget/info_widget.cc b/modules/gui/src/info_widget/info_widget.cc index 4eeaa552a049cce655331d1c40bad27cd6d6b65e..4451cc977bca780a15449102ab025602ca3d9b17 100644 --- a/modules/gui/src/info_widget/info_widget.cc +++ b/modules/gui/src/info_widget/info_widget.cc @@ -29,10 +29,10 @@ #include <ost/gui/widget_registry.hh> #include <ost/gui/gosty_app.hh> +#include "log_reader.hh" #include "info_widget.hh" -namespace ost { -namespace gui { +namespace ost {namespace gui { class InfoWidgetFactory: public WidgetFactory { public: @@ -75,6 +75,8 @@ InfoWidget::InfoWidget(QWidget* parent) : + QString("delete_icon.png"))); connect(clear_action, SIGNAL(triggered(bool)), this, SLOT(Clear())); this->actions_.append(clear_action); + + new LogReader(this); } void InfoWidget::Update() { @@ -86,6 +88,7 @@ void InfoWidget::LogMessage(const QString& message, QMessageBox::Icon icon) { QStandardItem* item = new QStandardItem(); item->setText(message); item->setIcon(QIcon(pix_icon)); + item->setEditable(false); this->model_->appendRow(item); } @@ -97,6 +100,7 @@ void InfoWidget::LogMessage(const QString& message, QIcon icon) { QStandardItem* item = new QStandardItem(); item->setText(message); item->setIcon(icon); + item->setEditable(false); this->model_->appendRow(item); } diff --git a/modules/gui/src/info_widget/log_reader.cc b/modules/gui/src/info_widget/log_reader.cc new file mode 100644 index 0000000000000000000000000000000000000000..f98411f3ec90dd4a5ca2baae389bd9285cd07fbe --- /dev/null +++ b/modules/gui/src/info_widget/log_reader.cc @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library 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.0 of the License, or (at your option) +// any later version. +// This library 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 this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +/* + Author: Stefan Scheuber + */ +#include <ost/log.hh> + +#include "info_widget.hh" +#include "log_reader.hh" + +namespace ost { namespace gui { + +LogReader::LogReader(QObject* parent) : + QObject(parent) { + ost::Logger& logger = ost::Logger::Instance(); + ObservableLogSinkPtr olsp = ObservableLogSinkPtr(new ObservableLogSink()); + LogSinkPtr lsp = LogSinkPtr(olsp); + logger.SetSink(lsp); + LogObserverPtr losp = LogObserverPtr(this); + olsp->AddObserver(losp); +} + +void LogReader::LogMessage(const String& message){ + if(this->parent()){ + if(InfoWidget* info_widget = qobject_cast<InfoWidget*>(this->parent())){ + info_widget->LogMessage(message.c_str()); + } + } +} + +LogReader::~LogReader() {} + +} +} // ns diff --git a/modules/gui/src/info_widget/log_reader.hh b/modules/gui/src/info_widget/log_reader.hh new file mode 100644 index 0000000000000000000000000000000000000000..87a85b49b66642f452f2bcb2f2ecaa8b0cd6e873 --- /dev/null +++ b/modules/gui/src/info_widget/log_reader.hh @@ -0,0 +1,48 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library 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.0 of the License, or (at your option) +// any later version. +// This library 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 this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_GUI_INFO_WIDGET_LOG_READER_HH +#define OST_GUI_INFO_WIDGET_LOG_READER_HH + +#include <QObject> + +#include <ost/log_sink.hh> + +#include <ost/gui/module_config.hh> + +/* + Author: Stefan Scheuber +*/ + +namespace ost { namespace gui { + +class DLLEXPORT_OST_GUI LogReader: public QObject, public LogObserver +{ + Q_OBJECT; +public: + LogReader(QObject* parent=NULL); + ~LogReader(); + +public: + void LogMessage(const String& message); + +}; + +}} // ns + +#endif