diff --git a/qad/application/lang/qad_application_en.ts b/qad/application/lang/qad_application_en.ts index 824e696..cc85e91 100644 --- a/qad/application/lang/qad_application_en.ts +++ b/qad/application/lang/qad_application_en.ts @@ -118,11 +118,25 @@ + + Clear - + + + Select All + + + + + + Copy + + + + All diff --git a/qad/application/lang/qad_application_ru.ts b/qad/application/lang/qad_application_ru.ts index c4d9101..bb4ba21 100644 --- a/qad/application/lang/qad_application_ru.ts +++ b/qad/application/lang/qad_application_ru.ts @@ -118,11 +118,25 @@ + + Clear Очистить - + + + Select All + Выделить всё + + + + + Copy + Копировать + + + All Все diff --git a/qad/application/logview.cpp b/qad/application/logview.cpp index eb39473..6d2cb02 100644 --- a/qad/application/logview.cpp +++ b/qad/application/logview.cpp @@ -28,11 +28,19 @@ void LogView::Category::makeIcon(QSize size, QSize size_icon) { } - - 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")); @@ -66,7 +74,7 @@ QFont LogView::logFont() const { bool LogView::isFilterVisible() const { - return !ui->widgetToolbar->isHidden(); + return ui->widgetToolbar->isVisible(); } @@ -76,43 +84,64 @@ int LogView::linesLimit() const { void LogView::registerCategory(const QString & label, QString keyword, const QImage & icon, QColor color, bool bold) { - if (keyword.isEmpty()) keyword = label; - if (keyword.isEmpty()) return; - Category & c(categories[keyword]); + 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.keyword = keyword; c.image = icon; c.color = color; c.bold = bold; c.makeIcon(iconImageSize(), preferredIconSize(1., this)); - ui->comboCategory->addItem(c.icon, label, keyword); + 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()); - filter(); + if (ui->widgetToolbar->isVisible()) + filter(); } void LogView::changeEvent(QEvent * e) { - if (e->type() == QEvent::Polish) { - ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this)); - QSize is = iconImageSize(), is_i = preferredIconSize(1., this); - QMutableMapIterator it(categories); - while (it.hasNext()) - it.next().value().makeIcon(is, is_i); + 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; } } @@ -123,16 +152,16 @@ void LogView::newLine() { tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); QString line = tc.selectedText(); QImage icon; - QMapIterator it(categories); + QListIterator it(categories); while (it.hasNext()) { - it.next(); - if (line.contains(it.key(), Qt::CaseInsensitive)) { + const Category & c(it.next()); + if (line.contains(c.regexp)) { QTextCharFormat cf = def_cf; - cf.setForeground(it.value().color); - if (it.value().bold) + cf.setForeground(c.color); + if (c.bold) cf.setFontWeight(QFont::Bold); tc.setCharFormat(cf); - icon = it.value().icon_image; + icon = c.icon_image; break; } } @@ -170,13 +199,14 @@ void LogView::clear() { void LogView::filter() { QTextDocument * doc = ui->textEdit->document(); int bc = doc->blockCount(); - QString fs[2] = {ui->comboCategory->currentData().toString(), ui->lineEdit->text()}; + 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 (!fs[0].isEmpty()) vis = vis && bl.text().contains(fs[0], Qt::CaseInsensitive); - if (!fs[1].isEmpty()) vis = vis && bl.text().contains(fs[1], Qt::CaseInsensitive); + 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()); diff --git a/qad/application/logview.h b/qad/application/logview.h index 8212056..f3df199 100644 --- a/qad/application/logview.h +++ b/qad/application/logview.h @@ -23,11 +23,12 @@ #include #include #include -#include #include +#include #include "qad_export.h" class QTextEdit; +class QAction; namespace Ui { class LogView; @@ -56,6 +57,12 @@ public: QColor color = QColor(), bool bold = false); + void registerCategory(const QString & label, + QRegularExpression regexp = QRegularExpression(), + const QImage & icon = QImage(), + QColor color = QColor(), + bool bold = false); + void addText(const QString & text, bool insert_newline = true); private: @@ -63,11 +70,12 @@ private: Category(); void makeIcon(QSize size, QSize size_icon); QString label; - QString keyword; + QRegularExpression regexp; QImage image, icon_image; QIcon icon; QColor color; bool bold; + inline bool operator ==(const Category & it) const {return (regexp.pattern() == it.regexp.pattern());} }; void changeEvent(QEvent * e); @@ -75,8 +83,9 @@ private: QSize iconImageSize(); Ui::LogView * ui; - QMap categories; // by keyword + QList categories; QTextCharFormat def_cf; + QAction * actionLogSelectAll, * actionLogCopy, * actionLogClear; public slots: void setFilterVisible(bool yes); diff --git a/qad/application/qad_application.qrc b/qad/application/qad_application.qrc index 794f52d..aed461c 100644 --- a/qad/application/qad_application.qrc +++ b/qad/application/qad_application.qrc @@ -29,5 +29,7 @@ ../icons/layer-visible-on.png ../icons/logview.png ../icons/qt.png + ../icons/select-all.png + ../icons/select-none.png diff --git a/qad/icons/select-all.png b/qad/icons/select-all.png new file mode 100644 index 0000000..c045ff1 Binary files /dev/null and b/qad/icons/select-all.png differ diff --git a/qad/icons/select-none.png b/qad/icons/select-none.png new file mode 100644 index 0000000..cf65075 Binary files /dev/null and b/qad/icons/select-none.png differ