cabana: add online-help (#27349)

* add online helps

* typo

* remove duplicate 'too'

* show idle message:For Help, Press F1

* improve drawHelp

* fix color desc
old-commit-hash: 2510f78126
beeps
Dean Lee 2 years ago committed by GitHub
parent e06a040f5b
commit c043ea7fa2
  1. 15
      tools/cabana/binaryview.cc
  2. 5
      tools/cabana/chartswidget.cc
  3. 5
      tools/cabana/detailwidget.cc
  4. 66
      tools/cabana/mainwin.cc
  5. 14
      tools/cabana/mainwin.h
  6. 9
      tools/cabana/messageswidget.cc
  7. 5
      tools/cabana/signaledit.cc
  8. 7
      tools/cabana/videowidget.cc

@ -42,6 +42,21 @@ BinaryView::BinaryView(QWidget *parent) : QTableView(parent) {
QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &BinaryView::refresh); QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &BinaryView::refresh);
addShortcuts(); addShortcuts();
setWhatsThis(R"(
<b>Binary View</b><br/>
<!-- TODO: add descprition here -->
Shortcuts:<br />
Delete Signal:
<span style="background-color:lightGray;color:gray"> x </span>,
<span style="background-color:lightGray;color:gray"> Backspace </span>,
<span style="background-color:lightGray;color:gray"> Delete</span><br />
Change endianness: <span style="background-color:lightGray;color:gray"> e </span><br />
Change singedness: <span style="background-color:lightGray;color:gray"> s </span><br />
Open chart:
<span style="background-color:lightGray;color:gray"> c </span>,
<span style="background-color:lightGray;color:gray"> p </span>,
<span style="background-color:lightGray;color:gray"> g </span><br />
)");
} }
void BinaryView::addShortcuts() { void BinaryView::addShortcuts() {

@ -94,6 +94,11 @@ ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
docking = !docking; docking = !docking;
updateToolBar(); updateToolBar();
}); });
setWhatsThis(tr(R"(
<b>Chart view</b><br />
<!-- TODO: add descprition here -->
)"));
} }
void ChartsWidget::eventsMerged() { void ChartsWidget::eventsMerged() {

@ -264,11 +264,12 @@ WelcomeWidget::WelcomeWidget(QWidget *parent) : QWidget(parent) {
return hlayout; return hlayout;
}; };
auto lb = new QLabel(tr("<-Select a message to to view details")); auto lb = new QLabel(tr("<-Select a message to view details"));
lb->setAlignment(Qt::AlignHCenter); lb->setAlignment(Qt::AlignHCenter);
main_layout->addWidget(lb); main_layout->addWidget(lb);
main_layout->addLayout(newShortcutRow("Pause", "Space")); main_layout->addLayout(newShortcutRow("Pause", "Space"));
main_layout->addLayout(newShortcutRow("Help", "Alt + H")); main_layout->addLayout(newShortcutRow("Help", "F1"));
main_layout->addLayout(newShortcutRow("WhatsThis", "Shift+F1"));
main_layout->addStretch(0); main_layout->addStretch(0);
setStyleSheet("QLabel{color:darkGray;}"); setStyleSheet("QLabel{color:darkGray;}");

@ -9,7 +9,9 @@
#include <QMenu> #include <QMenu>
#include <QMenuBar> #include <QMenuBar>
#include <QMessageBox> #include <QMessageBox>
#include <QResizeEvent>
#include <QShortcut> #include <QShortcut>
#include <QTextDocument>
#include <QUndoView> #include <QUndoView>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWidgetAction> #include <QWidgetAction>
@ -20,7 +22,7 @@
static MainWindow *main_win = nullptr; static MainWindow *main_win = nullptr;
void qLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { void qLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
if (type == QtDebugMsg) std::cout << msg.toStdString() << std::endl; if (type == QtDebugMsg) std::cout << msg.toStdString() << std::endl;
if (main_win) emit main_win->showMessage(msg, 0); if (main_win) emit main_win->showMessage(msg, 2000);
} }
MainWindow::MainWindow() : QMainWindow() { MainWindow::MainWindow() : QMainWindow() {
@ -43,7 +45,7 @@ MainWindow::MainWindow() : QMainWindow() {
qRegisterMetaType<ReplyMsgType>("ReplyMsgType"); qRegisterMetaType<ReplyMsgType>("ReplyMsgType");
installMessageHandler([this](ReplyMsgType type, const std::string msg) { installMessageHandler([this](ReplyMsgType type, const std::string msg) {
// use queued connection to recv the log messages from replay. // use queued connection to recv the log messages from replay.
emit showMessage(QString::fromStdString(msg), 3000); emit showMessage(QString::fromStdString(msg), 2000);
}); });
installDownloadProgressHandler([this](uint64_t cur, uint64_t total, bool success) { installDownloadProgressHandler([this](uint64_t cur, uint64_t total, bool success) {
emit updateProgressBar(cur, total, success); emit updateProgressBar(cur, total, success);
@ -125,6 +127,7 @@ void MainWindow::createActions() {
tools_menu->addAction(tr("Find &Similar Bits"), this, &MainWindow::findSimilarBits); tools_menu->addAction(tr("Find &Similar Bits"), this, &MainWindow::findSimilarBits);
QMenu *help_menu = menuBar()->addMenu(tr("&Help")); QMenu *help_menu = menuBar()->addMenu(tr("&Help"));
help_menu->addAction(tr("Help"), this, &MainWindow::onlineHelp)->setShortcuts(QKeySequence::HelpContents);
help_menu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); help_menu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
} }
@ -173,6 +176,7 @@ void MainWindow::createStatusBar() {
progress_bar->setTextVisible(true); progress_bar->setTextVisible(true);
progress_bar->setFixedSize({230, 16}); progress_bar->setFixedSize({230, 16});
progress_bar->setVisible(false); progress_bar->setVisible(false);
statusBar()->addWidget(new QLabel(tr("For Help,Press F1")));
statusBar()->addPermanentWidget(progress_bar); statusBar()->addPermanentWidget(progress_bar);
} }
@ -422,3 +426,61 @@ void MainWindow::findSimilarBits() {
QObject::connect(dlg, &FindSimilarBitsDlg::openMessage, messages_widget, &MessagesWidget::selectMessage); QObject::connect(dlg, &FindSimilarBitsDlg::openMessage, messages_widget, &MessagesWidget::selectMessage);
dlg->show(); dlg->show();
} }
void MainWindow::onlineHelp() {
if (auto help = findChild<HelpOverlay*>()) {
help->close();
} else {
help = new HelpOverlay(this);
help->setGeometry(rect());
help->show();
help->raise();
}
}
// HelpOverlay
HelpOverlay::HelpOverlay(MainWindow *parent) : QWidget(parent) {
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_DeleteOnClose);
parent->installEventFilter(this);
}
void HelpOverlay::paintEvent(QPaintEvent *event) {
QPainter painter(this);
painter.fillRect(rect(), QColor(0, 0, 0, 50));
MainWindow *parent = (MainWindow *)parentWidget();
drawHelpForWidget(painter, parent->findChild<MessagesWidget *>());
drawHelpForWidget(painter, parent->findChild<BinaryView *>());
drawHelpForWidget(painter, parent->findChild<SignalView *>());
drawHelpForWidget(painter, parent->findChild<ChartsWidget *>());
drawHelpForWidget(painter, parent->findChild<VideoWidget *>());
}
void HelpOverlay::drawHelpForWidget(QPainter &painter, QWidget *w) {
if (w && w->isVisible() && !w->whatsThis().isEmpty()) {
QPoint pt = mapFromGlobal(w->mapToGlobal(w->rect().center()));
if (rect().contains(pt)) {
QTextDocument document;
document.setHtml(w->whatsThis());
QSize doc_size = document.size().toSize();
QPoint topleft = {pt.x() - doc_size.width() / 2, pt.y() - doc_size.height() / 2};
painter.translate(topleft);
painter.fillRect(QRect{{0, 0}, doc_size}, palette().toolTipBase());
document.drawContents(&painter);
painter.translate(-topleft);
}
}
}
bool HelpOverlay::eventFilter(QObject *obj, QEvent *event) {
if (obj == parentWidget() && event->type() == QEvent::Resize) {
QResizeEvent *resize_event = (QResizeEvent *)(event);
setGeometry(QRect{QPoint(0, 0), resize_event->size()});
}
return false;
}
void HelpOverlay::mouseReleaseEvent(QMouseEvent *event) {
close();
}

@ -54,6 +54,7 @@ protected:
void setOption(); void setOption();
void findSimilarBits(); void findSimilarBits();
void undoStackCleanChanged(bool clean); void undoStackCleanChanged(bool clean);
void onlineHelp();
VideoWidget *video_widget = nullptr; VideoWidget *video_widget = nullptr;
QDockWidget *video_dock; QDockWidget *video_dock;
@ -69,4 +70,17 @@ protected:
enum { MAX_RECENT_FILES = 15 }; enum { MAX_RECENT_FILES = 15 };
QAction *recent_files_acts[MAX_RECENT_FILES] = {}; QAction *recent_files_acts[MAX_RECENT_FILES] = {};
QMenu *open_recent_menu = nullptr; QMenu *open_recent_menu = nullptr;
friend class OnlineHelp;
};
class HelpOverlay : public QWidget {
Q_OBJECT
public:
HelpOverlay(MainWindow *parent);
protected:
void drawHelpForWidget(QPainter &painter, QWidget *w);
void paintEvent(QPaintEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
bool eventFilter(QObject *obj, QEvent *event) override;
}; };

@ -65,6 +65,15 @@ MessagesWidget::MessagesWidget(QWidget *parent) : QWidget(parent) {
}); });
updateSuppressedButtons(); updateSuppressedButtons();
setWhatsThis(tr(R"(
<b>Message View</b><br/>
<!-- TODO: add descprition here -->
Byte color: <br />
<span style="color:gray;"> </span> constant changing<br />
<span style="color:blue;"> </span> increasing<br />
<span style="color:red;"> </span> decreasing <br />
)"));
} }
void MessagesWidget::selectMessage(const MessageId &msg_id) { void MessagesWidget::selectMessage(const MessageId &msg_id) {

@ -365,6 +365,11 @@ SignalView::SignalView(ChartsWidget *charts, QWidget *parent) : charts(charts),
QObject::connect(model, &QAbstractItemModel::rowsInserted, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::rowsInserted, this, &SignalView::rowsChanged);
QObject::connect(model, &QAbstractItemModel::rowsRemoved, this, &SignalView::rowsChanged); QObject::connect(model, &QAbstractItemModel::rowsRemoved, this, &SignalView::rowsChanged);
QObject::connect(dbc(), &DBCManager::signalAdded, [this](uint32_t address, const Signal *sig) { expandSignal(sig); }); QObject::connect(dbc(), &DBCManager::signalAdded, [this](uint32_t address, const Signal *sig) { expandSignal(sig); });
setWhatsThis(tr(R"(
<b>Signal view</b><br />
<!-- TODO: add descprition here -->
)"));
} }
void SignalView::setMessage(const MessageId &id) { void SignalView::setMessage(const MessageId &id) {

@ -53,6 +53,13 @@ VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent) {
QObject::connect(can, &AbstractStream::paused, this, &VideoWidget::updatePlayBtnState); QObject::connect(can, &AbstractStream::paused, this, &VideoWidget::updatePlayBtnState);
QObject::connect(can, &AbstractStream::resume, this, &VideoWidget::updatePlayBtnState); QObject::connect(can, &AbstractStream::resume, this, &VideoWidget::updatePlayBtnState);
updatePlayBtnState(); updatePlayBtnState();
setWhatsThis(tr(R"(
<b>Video</b><br />
<!-- TODO: add descprition here -->
Shortcuts:<br />
Pause/Resume: <span style="background-color:lightGray;color:gray"> space </span></br>
)"));
} }
QWidget *VideoWidget::createCameraWidget() { QWidget *VideoWidget::createCameraWidget() {

Loading…
Cancel
Save