Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notification Area - Non-Intrusive notifications #8120

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Base/Builder3D.cpp
Expand Up @@ -987,7 +987,7 @@ void Builder3D::saveToLog()
{
ILogger* obs = Base::Console().Get("StatusBar");
if (obs){
obs->SendLog(result.str().c_str(), Base::LogStyle::Log);
obs->SendLog("Builder3D",result.str().c_str(), Base::LogStyle::Log);
}
}

Expand Down
105 changes: 82 additions & 23 deletions src/Base/Console.cpp
Expand Up @@ -49,10 +49,11 @@ namespace Base {
class ConsoleEvent : public QEvent {
public:
ConsoleSingleton::FreeCAD_ConsoleMsgType msgtype;
std::string notifier;
std::string msg;

ConsoleEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type, const std::string& msg)
: QEvent(QEvent::User), msgtype(type), msg(msg)
ConsoleEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type, const std::string& notifier, const std::string& msg)
: QEvent(QEvent::User), msgtype(type), notifier(notifier),msg(msg)
{
}
~ConsoleEvent() override = default;
Expand All @@ -76,16 +77,16 @@ class ConsoleOutput : public QObject // clazy:exclude=missing-qobject-macro
ConsoleEvent* ce = static_cast<ConsoleEvent*>(ev);
switch (ce->msgtype) {
case ConsoleSingleton::MsgType_Txt:
Console().NotifyMessage(ce->msg.c_str());
Console().NotifyMessage(ce->msg.c_str(), ce->notifier.c_str());
break;
case ConsoleSingleton::MsgType_Log:
Console().NotifyLog(ce->msg.c_str());
Console().NotifyLog(ce->msg.c_str(), ce->notifier.c_str());
break;
case ConsoleSingleton::MsgType_Wrn:
Console().NotifyWarning(ce->msg.c_str());
Console().NotifyWarning(ce->msg.c_str(), ce->notifier.c_str());
break;
case ConsoleSingleton::MsgType_Err:
Console().NotifyError(ce->msg.c_str());
Console().NotifyError(ce->msg.c_str(), ce->notifier.c_str());
break;
}
}
Expand Down Expand Up @@ -242,6 +243,22 @@ void ConsoleSingleton::SetConnectionMode(ConnectionMode mode)
* @see Log
*/
void ConsoleSingleton::Message( const char *pMsg, ... )
{
va_list namelessVars;
va_start(namelessVars, pMsg);
MessageV("", pMsg, namelessVars);
va_end(namelessVars);
}

void ConsoleSingleton::MessageS ( const std::string & notifier, const char * pMsg, ... )
{
va_list namelessVars;
va_start(namelessVars, pMsg);
MessageV(notifier, pMsg, namelessVars);
va_end(namelessVars);
}

void ConsoleSingleton::MessageV ( const std::string & notifier, const char * pMsg, va_list args )
{
#define FC_CONSOLE_FMT(_type,_type2) \
char format[BufferSize];\
Expand All @@ -250,17 +267,14 @@ void ConsoleSingleton::Message( const char *pMsg, ... )
format[sizeof(format)-2] = '\n';\
format[sizeof(format)-1] = 0;\
const unsigned int format_len = sizeof(format)-4;\
va_list namelessVars;\
va_start(namelessVars, pMsg);\
vsnprintf(format, format_len, pMsg, namelessVars);\
vsnprintf(format, format_len, pMsg, args);\
format[sizeof(format)-5] = '.';\
va_end(namelessVars);\
if (connectionMode == Direct)\
Notify##_type(format);\
Notify##_type(format, notifier);\
else\
QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_##_type2, format));
QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_##_type2, notifier, format));

FC_CONSOLE_FMT(Message,Txt);
FC_CONSOLE_FMT(Message,Txt);
}

/** Prints a Message
Expand All @@ -279,6 +293,22 @@ void ConsoleSingleton::Message( const char *pMsg, ... )
* @see Log
*/
void ConsoleSingleton::Warning( const char *pMsg, ... )
{
va_list namelessVars;
va_start(namelessVars, pMsg);
WarningV("", pMsg, namelessVars);
va_end(namelessVars);
}

void ConsoleSingleton::WarningS ( const std::string & notifier, const char * pMsg, ... )
{
va_list namelessVars;
va_start(namelessVars, pMsg);
WarningV(notifier, pMsg, namelessVars);
va_end(namelessVars);
}

void ConsoleSingleton::WarningV( const std::string & notifier, const char *pMsg, va_list args )
{
FC_CONSOLE_FMT(Warning,Wrn);
}
Expand All @@ -300,9 +330,24 @@ void ConsoleSingleton::Warning( const char *pMsg, ... )
*/
void ConsoleSingleton::Error( const char *pMsg, ... )
{
FC_CONSOLE_FMT(Error,Err);
va_list namelessVars;
va_start(namelessVars, pMsg);
ErrorV("", pMsg, namelessVars);
va_end(namelessVars);
}

void ConsoleSingleton::ErrorS ( const std::string & notifier, const char * pMsg, ... )
{
va_list namelessVars;
va_start(namelessVars, pMsg);
ErrorV(notifier, pMsg, namelessVars);
va_end(namelessVars);
}

void ConsoleSingleton::ErrorV( const std::string & notifier, const char *pMsg, va_list args )
{
FC_CONSOLE_FMT(Error,Err);
}

/** Prints a Message
* This method is appropriate for development and tracking purposes.
Expand All @@ -318,9 +363,23 @@ void ConsoleSingleton::Error( const char *pMsg, ... )
* @see Warning
* @see Error
*/
void ConsoleSingleton::Log( const char *pMsg, ... )
{
va_list namelessVars;
va_start(namelessVars, pMsg);
LogV("", pMsg, namelessVars);
va_end(namelessVars);
}

void ConsoleSingleton::LogS ( const std::string & notifier, const char * pMsg, ... )
{
va_list namelessVars;
va_start(namelessVars, pMsg);
LogV(notifier, pMsg, namelessVars);
va_end(namelessVars);
}

void ConsoleSingleton::Log( const char *pMsg, ... )
void ConsoleSingleton::LogV( const std::string & notifier, const char *pMsg, va_list args )
{
if (_bVerbose)
{
Expand Down Expand Up @@ -357,35 +416,35 @@ void ConsoleSingleton::DetachObserver(ILogger *pcObserver)
_aclObservers.erase(pcObserver);
}

void ConsoleSingleton::NotifyMessage(const char *sMsg)
void ConsoleSingleton::NotifyMessage(const char *sMsg, const std::string & notifiername)
{
for (std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
if ((*Iter)->bMsg)
(*Iter)->SendLog(sMsg, LogStyle::Message); // send string to the listener
(*Iter)->SendLog(notifiername, sMsg, LogStyle::Message); // send string to the listener
}
}

void ConsoleSingleton::NotifyWarning(const char *sMsg)
void ConsoleSingleton::NotifyWarning(const char *sMsg, const std::string & notifiername)
{
for (std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
if ((*Iter)->bWrn)
(*Iter)->SendLog(sMsg, LogStyle::Warning); // send string to the listener
(*Iter)->SendLog(notifiername, sMsg, LogStyle::Warning); // send string to the listener
}
}

void ConsoleSingleton::NotifyError(const char *sMsg)
void ConsoleSingleton::NotifyError(const char *sMsg, const std::string & notifiername)
{
for (std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
if ((*Iter)->bErr)
(*Iter)->SendLog(sMsg, LogStyle::Error); // send string to the listener
(*Iter)->SendLog(notifiername, sMsg, LogStyle::Error); // send string to the listener
}
}

void ConsoleSingleton::NotifyLog(const char *sMsg)
void ConsoleSingleton::NotifyLog(const char *sMsg, const std::string & notifiername)
{
for (std::set<ILogger * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) {
if ((*Iter)->bLog)
(*Iter)->SendLog(sMsg, LogStyle::Log); // send string to the listener
(*Iter)->SendLog(notifiername, sMsg, LogStyle::Log); // send string to the listener
}
}

Expand Down
37 changes: 27 additions & 10 deletions src/Base/Console.h
Expand Up @@ -489,7 +489,7 @@ class BaseExport ILogger

/** Used to send a Log message at the given level.
*/
virtual void SendLog(const std::string& msg, LogStyle level) = 0;
virtual void SendLog(const std::string& notifiername, const std::string& msg, LogStyle level) = 0;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notes:
ILogger interface is extended to include a new string "notifiername". This would ultimately enable Console messaging to offer notifier identification, which is specially useful to discern between Documents and Document Objects where an notification may originate, while still allowing other, client defined, identification where the object is neither a Document or a DocumentObject (such as sketch.cpp). In part, this is done to separate the actual error messages and notifier (which could be treated differently by different observers, and may lead to reusing the same message for different observers despite how the handle notifier information) and, in part, to support multi-document projects.

This implies a change in the API. The majority of the rest of the changes in this commit are to deal with this change of API. If there is client code that links against FreeCAD and uses this interface, that client code would need to be adapted too. In those changes, I have not made a decision yet on how to best convey the notifier information.


virtual const char *Name(){return nullptr;}
bool bErr,bMsg,bLog,bWrn;
Expand All @@ -515,24 +515,32 @@ class BaseExport ILogger
*/
class BaseExport ConsoleSingleton
{

public:
static const unsigned int BufferSize = 4024;
// exported functions goes here +++++++++++++++++++++++++++++++++++++++
/// Prints a Message
virtual void Message ( const char * pMsg, ... );
void Message ( const char * pMsg, ... );
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note:

Legacy Message/Warning/Error/Log functions stop being virtual. New MessageS/WarningS/ErrorS/LogS counterparts are created, which take an additional notifier parameter (also non-virtual). Both this are then handled via a virtual private interface (NVI pattern) for extension (see MessageV/WarningV/ErrorV/LogV).

The Console client user has then the option to emit regular legacy message (not identifying the notifier), or use the new versions identifying the notifier.

/// Prints a warning Message
virtual void Warning ( const char * pMsg, ... );
void Warning ( const char * pMsg, ... );
/// Prints a error Message
virtual void Error ( const char * pMsg, ... );
void Error ( const char * pMsg, ... );
/// Prints a log Message
virtual void Log ( const char * pMsg, ... );
void Log ( const char * pMsg, ... );

/// Prints a Message with source indication
void MessageS ( const std::string &, const char * pMsg, ... );
/// Prints a warning Message with source indication
void WarningS ( const std::string &, const char * pMsg, ... );
/// Prints a error Message with source indication
void ErrorS ( const std::string &, const char * pMsg, ... );
/// Prints a log Message with source indication
void LogS ( const std::string &, const char * pMsg, ... );

// observer processing
void NotifyMessage(const char *sMsg);
void NotifyWarning(const char *sMsg);
void NotifyError (const char *sMsg);
void NotifyLog (const char *sMsg);
void NotifyMessage(const char *sMsg, const std::string & notifiername = "");
void NotifyWarning(const char *sMsg, const std::string & notifiername = "");
void NotifyError (const char *sMsg, const std::string & notifiername = "");
void NotifyLog (const char *sMsg, const std::string & notifiername = "");

/// Attaches an Observer to FCConsole
void AttachObserver(ILogger *pcObserver);
Expand Down Expand Up @@ -603,6 +611,15 @@ class BaseExport ConsoleSingleton
// Singleton!
ConsoleSingleton();
virtual ~ConsoleSingleton();

/// Prints a Message with source indication
virtual void MessageV ( const std::string &, const char * pMsg, va_list args );
/// Prints a warning Message with source indication
virtual void WarningV ( const std::string &, const char * pMsg, va_list args );
/// Prints a error Message with source indication
virtual void ErrorV ( const std::string &, const char * pMsg, va_list args );
/// Prints a log Message with source indication
virtual void LogV ( const std::string &, const char * pMsg, va_list args );

private:
// singleton
Expand Down
8 changes: 6 additions & 2 deletions src/Base/ConsoleObserver.cpp
Expand Up @@ -58,8 +58,10 @@ ConsoleObserverFile::~ConsoleObserverFile()
cFileStream.close();
}

void ConsoleObserverFile::SendLog(const std::string& msg, LogStyle level)
void ConsoleObserverFile::SendLog(const std::string& notifiername, const std::string& msg, LogStyle level)
{
(void) notifiername;

std::string prefix;
switch(level){
case LogStyle::Warning:
Expand Down Expand Up @@ -94,8 +96,10 @@ ConsoleObserverStd::ConsoleObserverStd() :

ConsoleObserverStd::~ConsoleObserverStd() = default;

void ConsoleObserverStd::SendLog(const std::string& msg, LogStyle level)
void ConsoleObserverStd::SendLog(const std::string& notifiername, const std::string& msg, LogStyle level)
{
(void) notifiername;

switch(level){
case LogStyle::Warning:
this->Warning(msg.c_str());
Expand Down
4 changes: 2 additions & 2 deletions src/Base/ConsoleObserver.h
Expand Up @@ -42,7 +42,7 @@ class BaseExport ConsoleObserverFile : public ILogger
ConsoleObserverFile(const char *sFileName);
~ConsoleObserverFile() override;

void SendLog(const std::string& message, LogStyle level) override;
void SendLog(const std::string& notifiername, const std::string& message, LogStyle level) override;
const char* Name() override {return "File";}

protected:
Expand All @@ -57,7 +57,7 @@ class BaseExport ConsoleObserverStd: public ILogger
public:
ConsoleObserverStd();
~ConsoleObserverStd() override;
void SendLog(const std::string& message, LogStyle level) override;
void SendLog(const std::string& notifiername, const std::string& message, LogStyle level) override;
const char* Name() override {return "Console";}
protected:
bool useColorStderr;
Expand Down
4 changes: 3 additions & 1 deletion src/Gui/CommandTest.cpp
Expand Up @@ -728,8 +728,10 @@ class TestConsoleObserver : public Base::ILogger
TestConsoleObserver() : matchMsg(0), matchWrn(0), matchErr(0), matchLog(0)
{
}
void SendLog(const std::string& msg, Base::LogStyle level) override{
void SendLog(const std::string& notifiername, const std::string& msg, Base::LogStyle level) override{

(void) notifiername;

QMutexLocker ml(&mutex);

switch(level){
Expand Down
4 changes: 3 additions & 1 deletion src/Gui/GuiConsole.cpp
Expand Up @@ -109,8 +109,10 @@ void GUIConsole::SendLog(const std::string& msg, Base::LogStyle level)
// safely ignore GUIConsole::s_nMaxLines and GUIConsole::s_nRefCount
GUIConsole::GUIConsole () {}
GUIConsole::~GUIConsole () {}
void GUIConsole::SendLog(const std::string& msg, Base::LogStyle level)
void GUIConsole::SendLog(const std::string& notifiername, const std::string& msg, Base::LogStyle level)
{
(void) notifiername;

switch(level){
case Base::LogStyle::Warning:
std::cerr << "Warning: " << msg;
Expand Down
2 changes: 1 addition & 1 deletion src/Gui/GuiConsole.h
Expand Up @@ -47,7 +47,7 @@ class GuiExport GUIConsole :public Base::ILogger
GUIConsole();
/// Destructor
~GUIConsole() override;
void SendLog(const std::string& msg, Base::LogStyle level) override;
void SendLog(const std::string& notifiername, const std::string& msg, Base::LogStyle level) override;
const char* Name() override {return "GUIConsole";}

protected:
Expand Down
4 changes: 3 additions & 1 deletion src/Gui/MainWindow.cpp
Expand Up @@ -2123,8 +2123,10 @@ void StatusBarObserver::OnChange(Base::Subject<const char*> &rCaller, const char
}
}

void StatusBarObserver::SendLog(const std::string& msg, Base::LogStyle level)
void StatusBarObserver::SendLog(const std::string& notifiername, const std::string& msg, Base::LogStyle level)
{
(void) notifiername;

int messageType = -1;
switch(level){
case Base::LogStyle::Warning:
Expand Down
2 changes: 1 addition & 1 deletion src/Gui/MainWindow.h
Expand Up @@ -375,7 +375,7 @@ class StatusBarObserver: public WindowParameter, public Base::ILogger
/** Observes its parameter group. */
void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;

void SendLog(const std::string& msg, Base::LogStyle level) override;
void SendLog(const std::string& notifiername, const std::string& msg, Base::LogStyle level) override;

/// name of the observer
const char *Name() override {return "StatusBar";}
Expand Down
4 changes: 3 additions & 1 deletion src/Gui/ReportView.cpp
Expand Up @@ -449,8 +449,10 @@ void ReportOutput::restoreFont()
setFont(serifFont);
}

void ReportOutput::SendLog(const std::string& msg, Base::LogStyle level)
void ReportOutput::SendLog(const std::string& notifiername, const std::string& msg, Base::LogStyle level)
{
(void) notifiername;

ReportHighlighter::Paragraph style = ReportHighlighter::LogText;
switch (level) {
case Base::LogStyle::Warning:
Expand Down
2 changes: 1 addition & 1 deletion src/Gui/ReportView.h
Expand Up @@ -134,7 +134,7 @@ class GuiExport ReportOutput : public QTextEdit, public WindowParameter, public
/** Observes its parameter group. */
void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;

void SendLog(const std::string& msg, Base::LogStyle level) override;
void SendLog(const std::string& notifiername, const std::string& msg, Base::LogStyle level) override;

/// returns the name for observer handling
const char* Name() override {return "ReportOutput";}
Expand Down