Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui: vastly improve online help #1621

Merged
merged 3 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 82 additions & 2 deletions src/lib/core/application/SafeQApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include "SafeQApplication.hpp"

#include <score/graphics/GraphicsItem.hpp>
#include <score/tools/Debug.hpp>
#include <score/tools/std/Invoke.hpp>

#include <QDebug>
#include <QDesktopServices>
#include <QFileInfo>
#include <QFileOpenEvent>
#include <QGraphicsView>
#include <QThread>

#include <wobjectimpl.h>
Expand Down Expand Up @@ -55,12 +58,87 @@ void SafeQApplication::DebugOutput(
fflush(out_file);
}

#if !defined(SCORE_DEBUG)
Q_GLOBAL_STATIC(QUrl, g_next_help_url_to_open);
Q_GLOBAL_STATIC(QTimer, g_next_help_url_to_open_timer);
static void open_help_url(const QUrl& u)
{
if(g_next_help_url_to_open.isDestroyed())
return;

*g_next_help_url_to_open = u;
g_next_help_url_to_open_timer->stop();
g_next_help_url_to_open_timer->setSingleShot(true);
QObject::disconnect(&*g_next_help_url_to_open_timer, &QTimer::timeout, qApp, nullptr);
QObject::connect(&*g_next_help_url_to_open_timer, &QTimer::timeout, qApp, [] {
QDesktopServices::openUrl(*g_next_help_url_to_open);
});

g_next_help_url_to_open_timer->start(15);
}

static void open_help_url(QGraphicsItem* item)
{
if(!item)
return;

if(auto url = getItemHelpUrl(item->type()); !url.isEmpty())
{
open_help_url(url);
}
else if(auto data = item->data(0xF1); data.isValid())
{
open_help_url(data.toUrl());
}
else
{
open_help_url(item->parentItem());
}
}

static void process_help_event(QObject* receiver, QEvent* event)
{
if(auto res = receiver->property("help_url"); res.isValid())
{
auto url = res.value<QUrl>();
open_help_url(url);
}
else if(auto gv = qobject_cast<QGraphicsView*>(receiver))
{
auto pos = QCursor::pos();
auto pt = gv->viewport()->mapFromGlobal(pos);
open_help_url(gv->itemAt(pt));
}
else if(auto gs = qobject_cast<QGraphicsScene*>(receiver))
{
auto pos = QCursor::pos();
auto gvs = gs->views();
if(!gvs.empty())
{
auto gv = gvs[0];
auto pt = gv->mapFromGlobal(pos);
open_help_url(gv->itemAt(pt));
}
}
else
{
open_help_url(QUrl("https://ossia.io/score-docs"));
}
}

bool SafeQApplication::notify(QObject* receiver, QEvent* event)
{
#if !defined(SCORE_DEBUG)
try
{
#endif
if(event->type() == QEvent::KeyPress)
{
auto ev = (QKeyEvent*)(event);
if(ev->key() == Qt::Key_F1)
process_help_event(receiver, event);
}
return QApplication::notify(receiver, event);
#if !defined(SCORE_DEBUG)
}
catch(std::exception& e)
{
Expand Down Expand Up @@ -92,8 +170,8 @@ bool SafeQApplication::notify(QObject* receiver, QEvent* event)
}

return false;
}
#endif
}

bool SafeQApplication::event(QEvent* ev)
{
Expand All @@ -110,6 +188,8 @@ bool SafeQApplication::event(QEvent* ev)
fileOpened(loadString);
return true;
}
case QEvent::HelpRequest:
return QApplication::event(ev);
default:
return QApplication::event(ev);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/core/application/SafeQApplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ class SCORE_LIB_BASE_EXPORT SafeQApplication final : public QApplication
score::information(QApplication::activeWindow(), "", str);
}

bool notify(QObject* receiver, QEvent* event) override;
#endif

bool notify(QObject* receiver, QEvent* event) override;
bool event(QEvent* ev) override;

void fileOpened(const QString& opened)
Expand Down
9 changes: 5 additions & 4 deletions src/lib/core/messages/MessagesPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "MessagesPanel.hpp"

#include <score/tools/Bind.hpp>
#include <score/widgets/HelpInteraction.hpp>

#include <core/application/SafeQApplication.hpp>

Expand Down Expand Up @@ -145,10 +146,10 @@ MessagesPanelDelegate::MessagesPanelDelegate(const score::GUIApplicationContext&
{
qInstallMessageHandler(LogToMessagePanel);
m_widget->setModel(m_itemModel);
m_widget->setStatusTip(
QObject::tr("This panel displays all warnings, errors and logs. \n"
"It is generally a good place to look first if something \n"
"is not behaving as it should"));
score::setHelp(
m_widget, QObject::tr("This panel displays all warnings, errors and logs. \n"
"It is generally a good place to look first if something \n"
"is not behaving as it should"));
m_widget->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
connect(
m_widget, &QListView::customContextMenuRequested, this, [this](const QPoint& pos) {
Expand Down
14 changes: 8 additions & 6 deletions src/lib/core/presenter/CoreApplicationPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <score/actions/Menu.hpp>
#include <score/plugins/documentdelegate/DocumentDelegateFactory.hpp>
#include <score/widgets/HelpInteraction.hpp>

#include <core/presenter/CoreActions.hpp>
#include <core/settings/Settings.hpp>
Expand Down Expand Up @@ -280,15 +281,15 @@ GUIElements CoreApplicationPlugin::makeGUIElements()
////// About /////
{
auto about_act = new QAction(m_presenter.view());
about_act->setStatusTip(tr("About ossia score"));
score::setHelp(about_act, tr("About ossia score"));
connect(about_act, &QAction::triggered, this, &CoreApplicationPlugin::about);
e.actions.add<Actions::About>(about_act);
about->addAction(about_act);
}

{
auto website_act = new QAction(m_presenter.view());
website_act->setStatusTip(tr("Open link to ossia website https://ossia.io/"));
score::setHelp(website_act, tr("Open link to ossia website https://ossia.io/"));
connect(website_act, &QAction::triggered, this, [] {
QDesktopServices::openUrl(QUrl("https://ossia.io/"));
});
Expand All @@ -298,16 +299,17 @@ GUIElements CoreApplicationPlugin::makeGUIElements()

{
auto doc_act = new QAction(m_presenter.view());
doc_act->setStatusTip(
tr("Open link to documentation https://ossia.io/score-docs"));
score::setHelp(
doc_act, tr("Open link to documentation https://ossia.io/score-docs"));
connect(doc_act, &QAction::triggered, this, &CoreApplicationPlugin::help);
e.actions.add<Actions::Documentation>(doc_act);
about->addAction(doc_act);
}

{
auto issues_act = new QAction(m_presenter.view());
issues_act->setStatusTip(tr("Report issues on the Github ossia score repository"));
score::setHelp(
issues_act, tr("Report issues on the Github ossia score repository"));
connect(issues_act, &QAction::triggered, this, [] {
QDesktopServices::openUrl(QUrl("https://github.com/ossia/score/issues"));
});
Expand All @@ -317,7 +319,7 @@ GUIElements CoreApplicationPlugin::makeGUIElements()

{
auto forum_act = new QAction(m_presenter.view());
forum_act->setStatusTip(tr("Open link to ossia forum https://forum.ossia.io"));
score::setHelp(forum_act, tr("Open link to ossia forum https://forum.ossia.io"));
connect(forum_act, &QAction::triggered, this, [] {
QDesktopServices::openUrl(QUrl("https://forum.ossia.io"));
});
Expand Down
9 changes: 5 additions & 4 deletions src/lib/core/undo/Panel/UndoPanelDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include "UndoPanelDelegate.hpp"

#include <score/widgets/HelpInteraction.hpp>
#include <score/widgets/MarginLess.hpp>

#include <core/document/Document.hpp>
Expand All @@ -17,10 +18,10 @@ UndoPanelDelegate::UndoPanelDelegate(const GUIApplicationContext& ctx)
{
m_widget->setLayout(new score::MarginLess<QVBoxLayout>);
m_widget->setObjectName("HistoryExplorer");
m_widget->setStatusTip(
QObject::tr("This panel shows the history of edits to your scenario. \n"
"This list of possible \"Undo\" and \"Redo\" \n"
"allows you to navigate through your past actions"));
score::setHelp(
m_widget, QObject::tr("This panel shows the history of edits to your scenario. \n"
"This list of possible \"Undo\" and \"Redo\" \n"
"allows you to navigate through your past actions"));
}

UndoPanelDelegate::~UndoPanelDelegate() { }
Expand Down
5 changes: 3 additions & 2 deletions src/lib/core/undo/UndoApplicationPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <score/plugins/application/GUIApplicationPlugin.hpp>
#include <score/tools/Bind.hpp>
#include <score/tools/ForEach.hpp>
#include <score/widgets/HelpInteraction.hpp>
#include <score/widgets/SetIcons.hpp>

#include <core/command/CommandStack.hpp>
Expand All @@ -26,7 +27,7 @@ score::UndoApplicationPlugin::UndoApplicationPlugin(
m_undoAction->setShortcut(QKeySequence::Undo);
m_undoAction->setEnabled(false);
m_undoAction->setText(QObject::tr("Nothing to undo"));
m_undoAction->setToolTip(QObject::tr("Undo (Ctrl+Z)"));
score::setHelp(m_undoAction, QObject::tr("Undo (Ctrl+Z)"));

setIcons(
m_undoAction, QStringLiteral(":/icons/prev_on.png"),
Expand All @@ -41,7 +42,7 @@ score::UndoApplicationPlugin::UndoApplicationPlugin(
m_redoAction->setShortcut(QKeySequence::Redo);
m_redoAction->setEnabled(false);
m_redoAction->setText(QObject::tr("Nothing to redo"));
m_redoAction->setToolTip(QObject::tr("Redo (Ctrl+Shift+Z)"));
score::setHelp(m_redoAction, QObject::tr("Redo (Ctrl+Shift+Z)"));

setIcons(
m_redoAction, QStringLiteral(":/icons/next_on.png"),
Expand Down
4 changes: 3 additions & 1 deletion src/lib/core/view/FixedTabWidget.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "FixedTabWidget.hpp"

#include <score/widgets/HelpInteraction.hpp>

#include <QActionGroup>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
Expand Down Expand Up @@ -135,7 +137,7 @@ QAction* FixedTabWidget::addAction(QWidget* widg, const PanelStatus& v)
btn->setShortcut(v.shortcut);
btn->setIcon(v.icon);

btn->setToolTip(v.prettyName);
score::setHelp(btn, v.prettyName);
btn->setWhatsThis(widg->whatsThis());
btn->setStatusTip(widg->statusTip());

Expand Down
29 changes: 12 additions & 17 deletions src/lib/core/view/HelperPanelDelegate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,26 @@ namespace score
class HelperPanelDelegate : public PanelDelegate
{
public:
struct FasterLabel : QLabel
{
QSize sizeHint() const override { return {180, 200}; }
QSize minimumSizeHint() const override { return {180, 100}; }
int heightForWidth(int) const override { return 200; }
};

HelperPanelDelegate(const score::GUIApplicationContext& ctx)
: PanelDelegate{ctx}
{
widg = new QWidget;
widg->setContentsMargins(3, 2, 3, 2);
widg = status = new FasterLabel;
widg->setContentsMargins(3, 5, 3, 2);
widg->setMinimumHeight(100);
widg->setMaximumHeight(100);
widg->setMaximumHeight(200);
widg->setMinimumWidth(180);

auto l = new QVBoxLayout{widg};

struct FasterLabel : QLabel
{
QSize sizeHint() const override { return {180, 100}; }
QSize minimumSizeHint() const override { return {180, 100}; }
int heightForWidth(int) const override { return 100; }
};

status = new FasterLabel;
status->setAlignment(Qt::AlignTop);
status->setTextFormat(Qt::RichText);
status->setText("<i>Remember those quiet evenings</i>");
status->setText("<i>Do the words need changing?</i>");
status->setWordWrap(true);

l->addWidget(status);
l->addStretch(12);
}

QWidget* widget() override { return widg; }
Expand Down
9 changes: 6 additions & 3 deletions src/lib/core/view/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,7 @@ void View::resizeEvent(QResizeEvent* e)

bool score::View::event(QEvent* event)
{
if(event->type() == QEvent::StatusTip)
{
auto tip = ((QStatusTipEvent*)event)->tip();
auto display = [this](QString tip) {
auto idx = tip.indexOf(QChar('\n'));
if(idx != -1)
{
Expand All @@ -464,6 +462,11 @@ bool score::View::event(QEvent* event)
}
tip.replace(QChar('\n'), "<br/>");
m_status->setText(tip);
};

if(event->type() == QEvent::StatusTip)
{
display(((QStatusTipEvent*)event)->tip());
}

return QMainWindow::event(event);
Expand Down
1 change: 1 addition & 0 deletions src/lib/score/actions/Action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <score/actions/ActionManager.hpp>
#include <score/selection/SelectionStack.hpp>
#include <score/widgets/HelpInteraction.hpp>

#include <core/presenter/DocumentManager.hpp>

Expand Down
20 changes: 20 additions & 0 deletions src/lib/score/graphics/GraphicsItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@
#include <QGraphicsView>
#include <QGuiApplication>

using item_help = ossia::hash_map<int, std::pair<QString, QUrl>>;
#if __has_include(<QApplicationStatic>)
#include <QApplicationStatic>
Q_APPLICATION_STATIC(item_help, g_itemHelpRegistry);
#else
Q_GLOBAL_STATIC(item_help, g_itemHelpRegistry);
#endif

void registerItemHelp(int itemType, QString tooltip, QUrl url) noexcept
{
auto& val = *g_itemHelpRegistry;
val[itemType] = std::pair<QString, QUrl>{tooltip, url};
}

QUrl getItemHelpUrl(int itemType) noexcept
{
auto& val = *g_itemHelpRegistry;
return val[itemType].second;
}

void deleteGraphicsObject(QGraphicsObject* item)
{
if(item)
Expand Down
Loading
Loading