keyboard shortcuts widget now checks for duplicate shortcuts everytime shortcut is changed and offers solutions, fixes #1605
This commit is contained in:
parent
08388cb9b9
commit
68060c7dcd
46
resources/scripts/scrapers/youtube-limit-length.py
Normal file
46
resources/scripts/scrapers/youtube-limit-length.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Use this as RSS Guard post-processing script.
|
||||
#
|
||||
# Example command line usage:
|
||||
# curl 'PATH_TO_SOME_YOUTUBE_CHANNEL_RSS_FEED' | python 'youtube-limit-length.py'
|
||||
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
import requests
|
||||
import json
|
||||
import isodate
|
||||
|
||||
sys.stdin.reconfigure(encoding="utf-8")
|
||||
input_data = sys.stdin.read()
|
||||
|
||||
api_key = "YOUR_API_KEY_HERE"
|
||||
min_required_length = 90 # In seconds.
|
||||
|
||||
youtube_query = (
|
||||
"https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=VIDEO-ID&key="
|
||||
+ api_key
|
||||
)
|
||||
ns = {
|
||||
"atom": "http://www.w3.org/2005/Atom",
|
||||
"yt": "http://www.youtube.com/xml/schemas/2015",
|
||||
}
|
||||
|
||||
tree = ET.fromstring(input_data)
|
||||
entries = tree.findall("atom:entry", ns)
|
||||
|
||||
for entry in entries:
|
||||
video_id = entry.find("yt:videoId", ns).text
|
||||
youtube_query_specific = youtube_query.replace("VIDEO-ID", video_id)
|
||||
api_response = requests.get(youtube_query_specific).text
|
||||
response_json = json.loads(api_response)
|
||||
|
||||
try:
|
||||
length_encoded = str(response_json["items"][0]["contentDetails"]["duration"])
|
||||
except:
|
||||
continue
|
||||
|
||||
length = isodate.parse_duration(length_encoded)
|
||||
|
||||
if length.seconds < min_required_length:
|
||||
tree.remove(entry)
|
||||
|
||||
sys.stdout.buffer.write(ET.tostring(tree, encoding='utf-8', method='xml'))
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "definitions/definitions.h"
|
||||
#include "dynamic-shortcuts/shortcutcatcher.h"
|
||||
#include "gui/messagebox.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QGridLayout>
|
||||
@ -25,15 +26,15 @@ bool DynamicShortcutsWidget::areShortcutsUnique() const {
|
||||
QList<QKeySequence> all_shortcuts;
|
||||
|
||||
// Obtain all shortcuts.
|
||||
for (const ActionBinding& binding : m_actionBindings) {
|
||||
const QKeySequence new_shortcut = binding.second->shortcut();
|
||||
for (ShortcutCatcher* catcher : m_actionBindings) {
|
||||
const QKeySequence new_shortcut = catcher->shortcut();
|
||||
|
||||
if (!new_shortcut.isEmpty() && all_shortcuts.contains(new_shortcut)) {
|
||||
// Problem, two identical non-empty shortcuts found.
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
all_shortcuts.append(binding.second->shortcut());
|
||||
all_shortcuts.append(catcher->shortcut());
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,8 +42,8 @@ bool DynamicShortcutsWidget::areShortcutsUnique() const {
|
||||
}
|
||||
|
||||
void DynamicShortcutsWidget::updateShortcuts() {
|
||||
for (const ActionBinding& binding : std::as_const(m_actionBindings)) {
|
||||
binding.first->setShortcut(binding.second->shortcut());
|
||||
for (ShortcutCatcher* catcher : std::as_const(m_actionBindings)) {
|
||||
catcher->action()->setShortcut(catcher->shortcut());
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,15 +59,14 @@ void DynamicShortcutsWidget::populate(QList<QAction*> actions) {
|
||||
// Create shortcut catcher for this action and set default shortcut.
|
||||
auto* catcher = new ShortcutCatcher(this);
|
||||
|
||||
catcher->setAction(action);
|
||||
catcher->setDefaultShortcut(action->shortcut());
|
||||
|
||||
// Store information for re-initialization of shortcuts
|
||||
// of actions when widget gets "confirmed".
|
||||
QPair<QAction*, ShortcutCatcher*> new_binding;
|
||||
if (!action->shortcut().isEmpty()) {
|
||||
m_assignedShortcuts.insert(action->shortcut(), catcher);
|
||||
}
|
||||
|
||||
new_binding.first = action;
|
||||
new_binding.second = catcher;
|
||||
m_actionBindings << new_binding;
|
||||
m_actionBindings.append(catcher);
|
||||
|
||||
// Add new catcher to our control.
|
||||
auto* action_label = new QLabel(this);
|
||||
@ -89,15 +89,63 @@ void DynamicShortcutsWidget::populate(QList<QAction*> actions) {
|
||||
|
||||
action_icon->setPixmap(action->icon().pixmap(ICON_SIZE_SETTINGS, ICON_SIZE_SETTINGS));
|
||||
action_icon->setToolTip(action->toolTip());
|
||||
|
||||
m_layout->addWidget(action_icon, row_id, 0);
|
||||
m_layout->addWidget(action_label, row_id, 1);
|
||||
m_layout->addWidget(catcher, row_id, 2);
|
||||
|
||||
row_id++;
|
||||
connect(catcher, &ShortcutCatcher::shortcutChanged, this, &DynamicShortcutsWidget::setupChanged);
|
||||
connect(catcher, &ShortcutCatcher::shortcutChanged, this, &DynamicShortcutsWidget::onShortcutChanged);
|
||||
}
|
||||
|
||||
// Make sure that "spacer" is added.
|
||||
m_layout->setRowStretch(row_id, 1);
|
||||
m_layout->setColumnStretch(1, 1);
|
||||
}
|
||||
|
||||
void DynamicShortcutsWidget::onShortcutChanged(const QKeySequence& sequence) {
|
||||
ShortcutCatcher* catcher = qobject_cast<ShortcutCatcher*>(sender());
|
||||
QKeySequence assigned_sequence = m_assignedShortcuts.key(catcher);
|
||||
|
||||
qDebugNN << catcher->action()->text();
|
||||
|
||||
// We remove currently assigned sequence to this catcher.
|
||||
m_assignedShortcuts.remove(assigned_sequence);
|
||||
|
||||
if (!sequence.isEmpty()) {
|
||||
// Now we check if any other catcher has assigned the same sequence.
|
||||
ShortcutCatcher* conflicting_catcher = m_assignedShortcuts.value(sequence);
|
||||
|
||||
if (conflicting_catcher != nullptr) {
|
||||
// We found conflicting catcher.
|
||||
catcher->blockSignals(true);
|
||||
|
||||
QMessageBox::StandardButton decision =
|
||||
MsgBox::show(this,
|
||||
QMessageBox::Icon::Critical,
|
||||
tr("Duplicate shortcut"),
|
||||
tr("There is another action which has the same shortcut assigned."),
|
||||
tr("Do you want to keep the new shortcut assignment and clear the previous shortcut?"),
|
||||
conflicting_catcher->action()->text().remove(QSL("&")),
|
||||
QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No,
|
||||
QMessageBox::StandardButton::Yes);
|
||||
|
||||
catcher->blockSignals(false);
|
||||
|
||||
if (decision == QMessageBox::StandardButton::Yes) {
|
||||
// We keep the new shortcut and reset old conflicting action.
|
||||
m_assignedShortcuts.insert(sequence, catcher);
|
||||
conflicting_catcher->clearShortcut();
|
||||
}
|
||||
else {
|
||||
// We discard new shortcut.
|
||||
catcher->clearShortcut();
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_assignedShortcuts.insert(sequence, catcher);
|
||||
}
|
||||
}
|
||||
|
||||
emit setupChanged();
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
class QGridLayout;
|
||||
class ShortcutCatcher;
|
||||
|
||||
typedef QPair<QAction*, ShortcutCatcher*> ActionBinding;
|
||||
|
||||
class DynamicShortcutsWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
@ -33,12 +31,16 @@ class DynamicShortcutsWidget : public QWidget {
|
||||
// assigned to actions before calling this method.
|
||||
void populate(QList<QAction*> actions);
|
||||
|
||||
private slots:
|
||||
void onShortcutChanged(const QKeySequence& sequence);
|
||||
|
||||
signals:
|
||||
void setupChanged();
|
||||
|
||||
private:
|
||||
QGridLayout* m_layout;
|
||||
QList<ActionBinding> m_actionBindings;
|
||||
QList<ShortcutCatcher*> m_actionBindings;
|
||||
QHash<QKeySequence, ShortcutCatcher*> m_assignedShortcuts;
|
||||
};
|
||||
|
||||
#endif // DYNAMICSHORTCUTSOVERVIEW_H
|
||||
|
@ -65,3 +65,11 @@ void ShortcutCatcher::resetShortcut() {
|
||||
void ShortcutCatcher::clearShortcut() {
|
||||
setShortcut(QKeySequence());
|
||||
}
|
||||
|
||||
QAction* ShortcutCatcher::action() const {
|
||||
return m_action;
|
||||
}
|
||||
|
||||
void ShortcutCatcher::setAction(QAction* act) {
|
||||
m_action = act;
|
||||
}
|
||||
|
@ -19,6 +19,9 @@ class ShortcutCatcher : public QWidget {
|
||||
void setDefaultShortcut(const QKeySequence& key);
|
||||
void setShortcut(const QKeySequence& key);
|
||||
|
||||
QAction* action() const;
|
||||
void setAction(QAction* act);
|
||||
|
||||
public slots:
|
||||
void resetShortcut();
|
||||
void clearShortcut();
|
||||
@ -27,6 +30,7 @@ class ShortcutCatcher : public QWidget {
|
||||
void shortcutChanged(const QKeySequence& seguence);
|
||||
|
||||
private:
|
||||
QAction* m_action;
|
||||
PlainToolButton* m_btnReset;
|
||||
PlainToolButton* m_btnClear;
|
||||
QKeySequenceEdit* m_shortcutBox;
|
||||
|
Loading…
x
Reference in New Issue
Block a user