This repository has been archived on 2020-09-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
libs/qad/application/logview.cpp

214 lines
5.8 KiB
C++

#include "logview.h"
#include "ui_logview.h"
#include "qad_types.h"
#include "ecombobox.h"
#include <QTextDocument>
#include <QAbstractTextDocumentLayout>
#include <QTextEdit>
#include <QTextBlock>
#include <QScrollBar>
#include <QPixmap>
#include <QEvent>
LogView::Category::Category() {
bold = false;
}
void LogView::Category::makeIcon(QSize size, QSize size_icon) {
icon_image = QImage();
if (!image.isNull())
icon_image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
QPixmap px = QPixmap::fromImage(image.scaled(size_icon, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
icon.addPixmap(px, QIcon::Active);
icon.addPixmap(px, QIcon::Disabled);
icon.addPixmap(px, QIcon::Normal);
icon.addPixmap(px, QIcon::Selected);
}
LogView::LogView(QWidget * parent): QWidget(parent) {
ui = new Ui::LogView();
ui->setupUi(this);
ui->textEdit->setContextMenuPolicy(Qt::ActionsContextMenu);
actionLogSelectAll = new QAction(QIcon(":/icons/select-all.png"), tr("Select All"));
actionLogCopy = new QAction(QIcon(":/icons/edit-copy.png"), tr("Copy"));
actionLogClear = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear"));
connect(actionLogSelectAll, SIGNAL(triggered(bool)), ui->textEdit, SLOT(selectAll()));
connect(actionLogCopy, SIGNAL(triggered(bool)), ui->textEdit, SLOT(copy()));
connect(actionLogClear, SIGNAL(triggered(bool)), ui->textEdit, SLOT(clear()));
ui->textEdit->addAction(actionLogSelectAll);
ui->textEdit->addAction(actionLogCopy);
ui->textEdit->addAction(actionLogClear);
ui->buttonClear->setDefaultAction(ui->actionClear);
ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this));
ui->comboCategory->addItem(tr("All"));
ui->textEdit->document()->setUndoRedoEnabled(false);
setLinesLimit(10000);
QTextCursor tc(ui->textEdit->document());
def_cf = tc.charFormat();
}
LogView::~LogView() {
delete ui;
}
const QTextEdit * LogView::textEdit() const {
return ui->textEdit;
}
void LogView::setLogFont(QFont f) {
ui->textEdit->document()->setDefaultFont(f);
QTextCursor tc(ui->textEdit->document());
def_cf = tc.charFormat();
}
QFont LogView::logFont() const {
return ui->textEdit->document()->defaultFont();
}
bool LogView::isFilterVisible() const {
return ui->widgetToolbar->isVisible();
}
int LogView::linesLimit() const {
return ui->textEdit->document()->maximumBlockCount();
}
void LogView::registerCategory(const QString & label, QString keyword, const QImage & icon, QColor color, bool bold) {
QRegularExpression regexp(keyword, QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption));
registerCategory(label, regexp, icon, color, bold);
}
void LogView::registerCategory(const QString & label, QRegularExpression regexp, const QImage & icon, QColor color, bool bold) {
if (!regexp.isValid()) return;
Category c;
c.regexp = regexp;
categories.removeAll(c);
c.label = label;
c.image = icon;
c.color = color;
c.bold = bold;
c.makeIcon(iconImageSize(), preferredIconSize(1., this));
categories.append(c);
ui->comboCategory->addItem(c.icon, label, regexp);
}
void LogView::addText(const QString & text, bool insert_newline) {
if (text.isEmpty()) return;
QTextCursor tc(ui->textEdit->document());
QStringList sl = text.split("\n");
tc.movePosition(QTextCursor::End);
QScrollBar * bar = ui->textEdit->verticalScrollBar();
bool at_end = (bar->value() == bar->maximum());
for (int i = 0; i < sl.size(); ++i) {
if (sl[i].isEmpty()) return;
tc.insertText(sl[i]);
if ((i < sl.size() - 1) || insert_newline)
newLine();
}
if (at_end)
bar->setValue(bar->maximum());
if (ui->widgetToolbar->isVisible())
filter();
}
void LogView::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
actionLogSelectAll->setText(tr("Select All"));
actionLogCopy->setText(tr("Copy"));
actionLogClear->setText(tr("Clear"));
break;
case QEvent::Polish: {
ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this));
QSize is = iconImageSize(), is_i = preferredIconSize(1., this);
QMutableListIterator<Category> it(categories);
while (it.hasNext())
it.next().makeIcon(is, is_i);
} break;
default:
break;
}
}
void LogView::newLine() {
QTextCursor tc(ui->textEdit->document());
tc.movePosition(QTextCursor::End);
tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
QString line = tc.selectedText();
QImage icon;
QListIterator<Category> it(categories);
while (it.hasNext()) {
const Category & c(it.next());
if (line.contains(c.regexp)) {
QTextCharFormat cf = def_cf;
cf.setForeground(c.color);
if (c.bold)
cf.setFontWeight(QFont::Bold);
tc.setCharFormat(cf);
icon = c.icon_image;
break;
}
}
if (!icon.isNull()) {
tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
tc.insertImage(icon);
}
tc.movePosition(QTextCursor::End);
tc.setCharFormat(def_cf);
tc.insertBlock();
}
QSize LogView::iconImageSize() {
int hei = QFontMetrics(ui->textEdit->document()->defaultFont()).height() / 1.25;
return QSize(hei, hei);
}
void LogView::setFilterVisible(bool yes) {
ui->widgetToolbar->setHidden(!yes);
}
void LogView::setLinesLimit(int l) {
ui->textEdit->document()->setMaximumBlockCount(l);
}
void LogView::clear() {
ui->textEdit->clear();
}
void LogView::filter() {
QTextDocument * doc = ui->textEdit->document();
int bc = doc->blockCount();
QRegularExpression regexp = ui->comboCategory->currentData().toRegularExpression();
QString fs = ui->lineEdit->text();
QTextBlock bl;
for (int i = 0; i < bc; ++i) {
bl = doc->findBlockByNumber(i);
bool vis = true;
if (regexp.isValid()) vis = vis && bl.text().contains(regexp);
if (!fs.isEmpty()) vis = vis && bl.text().contains(fs[1], Qt::CaseInsensitive);
bl.setVisible(vis);
}
doc->markContentsDirty(0, bl.position() + bl.length());
}