1+ #include < QMenu>
12#include < QEvent>
3+ #include < QStyle>
4+ #include < QClipboard>
5+ #include < QTextDocument>
6+ #include < QApplication>
7+ #include " fontutils.h"
28#include " htmldelegate.h"
39#include " modbuslogwidget.h"
410
@@ -45,9 +51,15 @@ QVariant ModbusLogModel::data(const QModelIndex& index, int role) const
4551 switch (role)
4652 {
4753 case Qt::DisplayRole:
48- return QString (" <b>%1</b> %2 %3" ).arg (item->timestamp ().toString (Qt::ISODateWithMs),
49- (item->isRequest ()? " ←" : " →" ),
50- item->toString (_parentWidget->dataDisplayMode ()));
54+ return QString (R"(
55+ <span style="color:#444444">%1</span>
56+ <b style="color:%2">%3</b>
57+ <span>%4</span>
58+ )" )
59+ .arg (item->timestamp ().toString (Qt::ISODateWithMs),
60+ item->isRequest () ? " #0066cc" : " #009933" ,
61+ item->isRequest () ? " [Tx] ←" : " [Rx] →" ,
62+ item->toString (_parentWidget->dataDisplayMode ()));
5163
5264 case Qt::UserRole:
5365 return QVariant::fromValue (item);
@@ -76,7 +88,9 @@ void ModbusLogModel::append(QSharedPointer<const ModbusMessage> data)
7688
7789 while (rowCount () >= _rowLimit)
7890 {
91+ beginRemoveRows (QModelIndex (), 0 , 0 );
7992 _items.removeFirst ();
93+ endRemoveRows ();
8094 }
8195
8296 beginInsertRows (QModelIndex (), rowCount (), rowCount ());
@@ -118,13 +132,51 @@ ModbusLogWidget::ModbusLogWidget(QWidget* parent)
118132 : QListView(parent)
119133 , _autoscroll(false )
120134{
135+ setFocusPolicy (Qt::StrongFocus);
136+ setFont (defaultMonospaceFont ());
137+ setContextMenuPolicy (Qt::CustomContextMenu);
121138 setItemDelegate (new HtmlDelegate (this ));
122139 setModel (new ModbusLogModel (this ));
123140
141+ QIcon copyIcon = QIcon::fromTheme (" edit-copy" );
142+ if (copyIcon.isNull ()) {
143+ copyIcon = style ()->standardIcon (QStyle::SP_FileIcon);
144+ }
145+
146+ _copyAct = new QAction (copyIcon, tr (" Copy Text" ), this );
147+ _copyAct->setShortcut (QKeySequence::Copy);
148+ _copyAct->setShortcutContext (Qt::WidgetShortcut);
149+ _copyAct->setShortcutVisibleInContextMenu (true );
150+ addAction (_copyAct);
151+
152+ connect (_copyAct, &QAction::triggered, this , [this ]() {
153+ QModelIndex index = currentIndex ();
154+ if (index.isValid ()) {
155+ QTextDocument doc;
156+ doc.setHtml (index.data (Qt::DisplayRole).toString ());
157+ QApplication::clipboard ()->setText (doc.toPlainText ());
158+ }
159+ });
160+
161+ _copyBytesAct = new QAction (tr (" Copy Bytes" ), this );
162+ _copyBytesAct->setShortcut (QKeySequence (Qt::CTRL | Qt::SHIFT | Qt::Key_C));
163+ _copyBytesAct->setShortcutContext (Qt::WidgetShortcut);
164+ _copyBytesAct->setShortcutVisibleInContextMenu (true );
165+ addAction (_copyBytesAct);
166+
167+ connect (_copyBytesAct, &QAction::triggered, this , [this ]() {
168+ QModelIndex index = currentIndex ();
169+ if (index.isValid ()) {
170+ auto msg = index.data (Qt::UserRole).value <QSharedPointer<const ModbusMessage>>();
171+ if (msg) QApplication::clipboard ()->setText (msg->toString (dataDisplayMode ()));
172+ }
173+ });
174+
175+ connect (this , &QWidget::customContextMenuRequested,
176+ this , &ModbusLogWidget::on_customContextMenuRequested);
124177 connect (model (), &ModbusLogModel::rowsInserted,
125178 this , [&]{
126179 if (_autoscroll) scrollToBottom ();
127- setCurrentIndex (QModelIndex ());
128180 });
129181}
130182
@@ -137,6 +189,8 @@ void ModbusLogWidget::changeEvent(QEvent* event)
137189 if (event->type () == QEvent::LanguageChange)
138190 {
139191 update ();
192+ _copyAct->setText (tr (" Copy Text" ));
193+ _copyBytesAct->setText (tr (" Copy Bytes" ));
140194 }
141195 QListView::changeEvent (event);
142196}
@@ -267,3 +321,36 @@ void ModbusLogWidget::setAutoscroll(bool on)
267321{
268322 _autoscroll = on;
269323}
324+
325+ // /
326+ // / \brief ModbusLogWidget::backgroundColor
327+ // / \return
328+ // /
329+ QColor ModbusLogWidget::backgroundColor () const
330+ {
331+ return palette ().color (QPalette::Base);
332+ }
333+
334+ // /
335+ // / \brief ModbusLogWidget::setBackGroundColor
336+ // / \param clr
337+ // /
338+ void ModbusLogWidget::setBackGroundColor (const QColor& clr)
339+ {
340+ auto pal = palette ();
341+ pal.setColor (QPalette::Base, clr);
342+ pal.setColor (QPalette::Window, clr);
343+ setPalette (pal);
344+ }
345+
346+ // /
347+ // / \brief ModbusLogWidget::on_customContextMenuRequested
348+ // / \param pos
349+ // /
350+ void ModbusLogWidget::on_customContextMenuRequested (const QPoint &pos)
351+ {
352+ QMenu menu (this );
353+ menu.addAction (_copyAct);
354+ menu.addAction (_copyBytesAct);
355+ menu.exec (viewport ()->mapToGlobal (pos));
356+ }
0 commit comments