#include "logview.h" #include "ui_logview.h" #include "qad_types.h" #include "ecombobox.h" #include #include #include #include #include #include #include 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 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 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()); }