Skip to content

Commit

Permalink
Log|libappfw|Client: Added PrivilegedLogWidget (developer utility)
Browse files Browse the repository at this point in the history
Often when working on a specific piece of code, it is easiest to just
use qDebug to print debug messages because they can be easily seen
among the other messages.

Doomsday's Log should provide a better way to handle this use case, so
now there are Privileged entries. Instead of qDebug, you can now use
LOG_WIP() in a similar fashion, and the entries will show up in the
special overlaid log in the top left side of the screen.

LOG_WIP() entries will appear normally in doomsday.out and the standard
output, however they are omitted from the runtime console log widget.
  • Loading branch information
skyjake committed Jul 31, 2015
1 parent 1657eae commit bed4aa0
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 4 deletions.
45 changes: 45 additions & 0 deletions doomsday/apps/client/include/ui/widgets/privilegedlogwidget.h
@@ -0,0 +1,45 @@
/** @file privilegedlogwidget.h
*
* @authors Copyright (c) 2015 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program 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 2 of the License, or (at your
* option) any later version. This program 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</small>
*/

#ifndef CLIENT_UI_WIDGETS_PRIVILEGEDLOGWIDGET_H
#define CLIENT_UI_WIDGETS_PRIVILEGEDLOGWIDGET_H

#include <de/GuiWidget>

/**
* Special heads-up log for viewing information about the current task (for
* developers).
*/
class PrivilegedLogWidget : public de::GuiWidget
{
Q_OBJECT

public:
PrivilegedLogWidget();

public slots:
void showLog();
void hideLog();

private:
DENG2_PRIVATE(d)
};


#endif // CLIENT_UI_WIDGETS_PRIVILEGEDLOGWIDGET_H

77 changes: 77 additions & 0 deletions doomsday/apps/client/src/ui/widgets/privilegedlogwidget.cpp
@@ -0,0 +1,77 @@
/** @file privilegedlogwidget.cpp
*
* @authors Copyright (c) 2015 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program 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 2 of the License, or (at your
* option) any later version. This program 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</small>
*/

#include "ui/widgets/privilegedlogwidget.h"
#include "ui/styledlogsinkformatter.h"
#include <de/LogWidget>
#include <de/ButtonWidget>

using namespace de;

DENG_GUI_PIMPL(PrivilegedLogWidget)
{
StyledLogSinkFormatter formatter;
LogWidget *log = nullptr;
ButtonWidget *closeButton = nullptr;

Instance(Public *i) : Base(i)
{
log = new LogWidget("privlog");
log->setLogFormatter(formatter);
log->setPrivilegedEntries(true);
self.add(log);

closeButton = new ButtonWidget;
closeButton->setSizePolicy(ui::Expand, ui::Expand);
closeButton->setImage(style().images().image("close.ringless"));
closeButton->setImageScale(toDevicePixels(.25f));
closeButton->setImageColor(style().colors().colorf("altaccent"));
self.add(closeButton);
}
};

PrivilegedLogWidget::PrivilegedLogWidget()
: d(new Instance(this))
{
auto const &gap = style().rules().rule("gap");

hide();
connect(d->log, SIGNAL(contentHeightIncreased(int)), this, SLOT(showLog()));
connect(d->closeButton, SIGNAL(pressed()), this, SLOT(hideLog()));

d->log->rule()
.setInput(Rule::Left, rule().left() + gap)
.setInput(Rule::Top, rule().top() + gap)
.setInput(Rule::Right, (rule().left() + rule().midX()) / 2)
.setInput(Rule::Bottom, rule().midY() - gap);

d->closeButton->rule()
.setInput(Rule::Top, d->log->rule().top())
.setInput(Rule::Right, d->log->rule().right());
}

void PrivilegedLogWidget::showLog()
{
show();
}

void PrivilegedLogWidget::hideLog()
{
hide();
d->log->clear();
}
7 changes: 7 additions & 0 deletions doomsday/sdk/libappfw/include/de/widgets/logwidget.h
Expand Up @@ -49,6 +49,13 @@ class LIBAPPFW_PUBLIC LogWidget : public ScrollAreaWidget
*/
void setLogFormatter(LogSink::IFormatter &formatter);

/**
* Enables the showing of privileged messages.
*
* @param onlyPrivileged Only show privileged entries.
*/
void setPrivilegedEntries(bool onlyPrivileged);

/**
* Returns the log sink that can be connected to a log buffer for receiving
* log entries into the widget's buffer.
Expand Down
5 changes: 5 additions & 0 deletions doomsday/sdk/libappfw/src/widgets/logwidget.cpp
Expand Up @@ -804,6 +804,11 @@ void LogWidget::setLogFormatter(LogSink::IFormatter &formatter)
d->formatter = &formatter;
}

void LogWidget::setPrivilegedEntries(bool onlyPrivileged)
{
d->sink.setPrivileged(onlyPrivileged);
}

LogSink &LogWidget::logSink()
{
return d->sink;
Expand Down
12 changes: 9 additions & 3 deletions doomsday/sdk/libcore/include/de/core/log.h
Expand Up @@ -80,6 +80,8 @@
#define LOGDEV_WARNING(str) LOGDEV_AT_LEVEL(de::LogEntry::Warning, str)
#define LOGDEV_ERROR(str) LOGDEV_AT_LEVEL(de::LogEntry::Error, str)

#define LOG_WIP(str) LOG_AT_LEVEL(de::LogEntry::Privileged | de::LogEntry::Note, str)

// Custom combination of audiences
#define LOG_XVERBOSE_TO(audflags, str) LOG_AT_LEVEL((audflags) | de::LogEntry::XVerbose, str)
#define LOG_VERBOSE_TO(audflags, str) LOG_AT_LEVEL((audflags) | de::LogEntry::Verbose, str)
Expand Down Expand Up @@ -288,13 +290,17 @@ class DENG2_PUBLIC LogEntry : public Lockable, public ISerializable
Network = (1 << NetworkBit), ///< Network domain: connections, packets, etc.

// User groups
Dev = 0x8000000, /**< Native code developer (i.e., the programmer); can be
Dev = 0x08000000, /**< Native code developer (i.e., the programmer); can be
combined with other flags to mark the entry for devs.
If bit is not set, the entry is for the end-user. */
Privileged = 0x04000000, /**< Work in progress. Entries with this flag are shown
regardless of log filtering, in a separate overlay.
Use this for whatever you are currently working on
(so there is no need to rely on qDebug). */

AllDomains = 0xff0000,
AllDomains = 0x00ff0000,
DomainMask = AllDomains,
ContextMask = 0xfff0000
ContextMask = 0x0fff0000
};

static String contextToText(duint32 context)
Expand Down
3 changes: 3 additions & 0 deletions doomsday/sdk/libcore/include/de/core/memorylogsink.h
Expand Up @@ -36,6 +36,8 @@ class DENG2_PUBLIC MemoryLogSink : public LogSink, public Lockable
MemoryLogSink(LogEntry::Level minimumLevel = LogEntry::XVerbose);
~MemoryLogSink();

void setPrivileged(bool onlyPrivileged);

LogSink &operator << (LogEntry const &entry);
LogSink &operator << (String const &plainText);

Expand All @@ -57,6 +59,7 @@ class DENG2_PUBLIC MemoryLogSink : public LogSink, public Lockable
private:
QList<LogEntry *> _entries;
LogEntry::Level _minLevel;
bool _privileged;
};

} // namespace de
Expand Down
1 change: 1 addition & 0 deletions doomsday/sdk/libcore/src/core/logbuffer.cpp
Expand Up @@ -194,6 +194,7 @@ bool LogBuffer::isEnabled(duint32 entryMetadata) const
{
DENG2_ASSERT(d->entryFilter != 0);
DENG2_ASSERT(entryMetadata & LogEntry::DomainMask); // must have a domain
if(entryMetadata & LogEntry::Privileged) return true; // always passes
return d->entryFilter->isLogEntryAllowed(entryMetadata);
}

Expand Down
16 changes: 15 additions & 1 deletion doomsday/sdk/libcore/src/core/memorylogsink.cpp
Expand Up @@ -20,7 +20,9 @@

namespace de {

MemoryLogSink::MemoryLogSink(LogEntry::Level minimumLevel) : _minLevel(minimumLevel)
MemoryLogSink::MemoryLogSink(LogEntry::Level minimumLevel)
: _minLevel(minimumLevel)
, _privileged(false)
{}

MemoryLogSink::~MemoryLogSink()
Expand All @@ -30,6 +32,11 @@ MemoryLogSink::~MemoryLogSink()
qDeleteAll(_entries);
}

void MemoryLogSink::setPrivileged(bool onlyPrivileged)
{
_privileged = onlyPrivileged;
}

void MemoryLogSink::clear()
{
DENG2_GUARD(this);
Expand All @@ -40,6 +47,13 @@ void MemoryLogSink::clear()

LogSink &MemoryLogSink::operator << (LogEntry const &entry)
{
if((!_privileged && (entry.context() & LogEntry::Privileged)) ||
(_privileged && !(entry.context() & LogEntry::Privileged)))
{
// Skip (non-)privileged entry.
return *this;
}

if(entry.level() >= _minLevel)
{
DENG2_GUARD(this);
Expand Down

0 comments on commit bed4aa0

Please sign in to comment.