mirror of https://github.com/procxx/kepka.git
Media shortcuts now are enabled only when in-app player is opened.
This commit is contained in:
parent
acc7e08a54
commit
fdead263d6
|
@ -100,7 +100,7 @@ MainWidget::MainWidget(MainWindow *window) : TWidget(window)
|
||||||
App::wnd()->getTitle()->updateBackButton();
|
App::wnd()->getTitle()->updateBackButton();
|
||||||
_topBar->hide();
|
_topBar->hide();
|
||||||
|
|
||||||
_player->hide();
|
_player->hidePlayer();
|
||||||
|
|
||||||
orderWidgets();
|
orderWidgets();
|
||||||
|
|
||||||
|
@ -1558,15 +1558,17 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) {
|
||||||
if (playing == songId) {
|
if (playing == songId) {
|
||||||
_player->updateState(playing, playingState, playingPosition, playingDuration, playingFrequency);
|
_player->updateState(playing, playingState, playingPosition, playingDuration, playingFrequency);
|
||||||
|
|
||||||
if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing && !_a_show.animating()) {
|
if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||||
if (_player->isHidden()) {
|
if (!_player->isOpened()) {
|
||||||
_player->clearSelection();
|
_player->openPlayer();
|
||||||
_player->show();
|
if (_player->isHidden() && !_a_show.animating()) {
|
||||||
|
_player->showPlayer();
|
||||||
_playerHeight = _contentScrollAddToY = _player->height();
|
_playerHeight = _contentScrollAddToY = _player->height();
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (HistoryItem *item = App::histItemById(songId.contextId)) {
|
if (HistoryItem *item = App::histItemById(songId.contextId)) {
|
||||||
Ui::repaintHistoryItem(item);
|
Ui::repaintHistoryItem(item);
|
||||||
|
@ -1578,13 +1580,16 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::hidePlayer() {
|
void MainWidget::closePlayer() {
|
||||||
if (!_player->isHidden()) {
|
if (_player->isOpened()) {
|
||||||
_player->hide();
|
_player->closePlayer();
|
||||||
|
if (!_player->isHidden() && !_a_show.animating()) {
|
||||||
|
_player->hidePlayer();
|
||||||
_contentScrollAddToY = -_player->height();
|
_contentScrollAddToY = -_player->height();
|
||||||
_playerHeight = 0;
|
_playerHeight = 0;
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::documentLoadProgress(FileLoader *loader) {
|
void MainWidget::documentLoadProgress(FileLoader *loader) {
|
||||||
|
@ -2477,8 +2482,10 @@ void MainWidget::hideAll() {
|
||||||
}
|
}
|
||||||
_topBar->hide();
|
_topBar->hide();
|
||||||
_mediaType->hide();
|
_mediaType->hide();
|
||||||
_player->hide();
|
if (_player->isOpened() && !_player->isHidden()) {
|
||||||
|
_player->hidePlayer();
|
||||||
_playerHeight = 0;
|
_playerHeight = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::showAll() {
|
void MainWidget::showAll() {
|
||||||
|
@ -2538,21 +2545,10 @@ void MainWidget::showAll() {
|
||||||
_topBar->show();
|
_topBar->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (audioPlayer()) {
|
if (_player->isOpened() && _player->isHidden()) {
|
||||||
SongMsgId playing;
|
_player->showPlayer();
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
|
||||||
int64 playingPosition = 0, playingDuration = 0;
|
|
||||||
int32 playingFrequency = 0;
|
|
||||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
|
||||||
if (playing) {
|
|
||||||
_player->updateState(playing, playingState, playingPosition, playingDuration, playingFrequency);
|
|
||||||
if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
|
||||||
_player->clearSelection();
|
|
||||||
_player->show();
|
|
||||||
_playerHeight = _player->height();
|
_playerHeight = _player->height();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
|
|
||||||
App::wnd()->checkHistoryActivation();
|
App::wnd()->checkHistoryActivation();
|
||||||
|
|
|
@ -372,6 +372,8 @@ public:
|
||||||
|
|
||||||
bool isItemVisible(HistoryItem *item);
|
bool isItemVisible(HistoryItem *item);
|
||||||
|
|
||||||
|
void closePlayer();
|
||||||
|
|
||||||
void app_sendBotCallback(const HistoryMessageReplyMarkup::Button *button, const HistoryItem *msg, int row, int col);
|
void app_sendBotCallback(const HistoryMessageReplyMarkup::Button *button, const HistoryItem *msg, int row, int col);
|
||||||
|
|
||||||
void ui_repaintHistoryItem(const HistoryItem *item);
|
void ui_repaintHistoryItem(const HistoryItem *item);
|
||||||
|
@ -422,7 +424,6 @@ public slots:
|
||||||
void documentPlayProgress(const SongMsgId &songId);
|
void documentPlayProgress(const SongMsgId &songId);
|
||||||
void inlineResultLoadProgress(FileLoader *loader);
|
void inlineResultLoadProgress(FileLoader *loader);
|
||||||
void inlineResultLoadFailed(FileLoader *loader, bool started);
|
void inlineResultLoadFailed(FileLoader *loader, bool started);
|
||||||
void hidePlayer();
|
|
||||||
|
|
||||||
void dialogsCancelled();
|
void dialogsCancelled();
|
||||||
|
|
||||||
|
|
|
@ -19,41 +19,21 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "playerwidget.h"
|
||||||
|
|
||||||
|
#include "shortcuts.h"
|
||||||
#include "ui/style.h"
|
#include "ui/style.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
||||||
#include "boxes/addcontactbox.h"
|
#include "boxes/addcontactbox.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "playerwidget.h"
|
#include "playerwidget.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
|
||||||
PlayerWidget::PlayerWidget(QWidget *parent) : TWidget(parent)
|
PlayerWidget::PlayerWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _prevAvailable(false)
|
|
||||||
, _nextAvailable(false)
|
|
||||||
, _fullAvailable(false)
|
|
||||||
, _over(OverNone)
|
|
||||||
, _down(OverNone)
|
|
||||||
, _downCoord(0)
|
|
||||||
, _downFrequency(AudioVoiceMsgFrequency)
|
|
||||||
, _downProgress(0.)
|
|
||||||
, _a_state(animation(this, &PlayerWidget::step_state))
|
, _a_state(animation(this, &PlayerWidget::step_state))
|
||||||
, _msgmigrated(false)
|
|
||||||
, _index(-1)
|
|
||||||
, _migrated(0)
|
|
||||||
, _history(0)
|
|
||||||
, _timeWidth(0)
|
|
||||||
, _repeat(false)
|
|
||||||
, _showPause(false)
|
|
||||||
, _position(0)
|
|
||||||
, _duration(0)
|
|
||||||
, _loaded(0)
|
|
||||||
, a_progress(0., 0.)
|
|
||||||
, a_loadProgress(0., 0.)
|
|
||||||
, _a_progress(animation(this, &PlayerWidget::step_progress))
|
, _a_progress(animation(this, &PlayerWidget::step_progress))
|
||||||
, _sideShadow(this, st::shadowColor) {
|
, _sideShadow(this, st::shadowColor) {
|
||||||
resize(st::wndMinWidth, st::playerHeight);
|
resize(st::wndMinWidth, st::playerHeight);
|
||||||
|
@ -372,6 +352,29 @@ bool PlayerWidget::seekingSong(const SongMsgId &song) const {
|
||||||
return (_down == OverPlayback) && (song == _song);
|
return (_down == OverPlayback) && (song == _song);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerWidget::openPlayer() {
|
||||||
|
_playerOpened = true;
|
||||||
|
Shortcuts::enableMediaShortcuts();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerWidget::isOpened() const {
|
||||||
|
return _playerOpened;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerWidget::closePlayer() {
|
||||||
|
_playerOpened = false;
|
||||||
|
Shortcuts::disableMediaShortcuts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerWidget::showPlayer() {
|
||||||
|
TWidget::show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerWidget::hidePlayer() {
|
||||||
|
clearSelection();
|
||||||
|
TWidget::hide();
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerWidget::step_state(uint64 ms, bool timer) {
|
void PlayerWidget::step_state(uint64 ms, bool timer) {
|
||||||
for (StateAnimations::iterator i = _stateAnimations.begin(); i != _stateAnimations.cend();) {
|
for (StateAnimations::iterator i = _stateAnimations.begin(); i != _stateAnimations.cend();) {
|
||||||
int32 over = qAbs(i.key());
|
int32 over = qAbs(i.key());
|
||||||
|
@ -463,7 +466,7 @@ void PlayerWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
} else if (_down == OverClose && _over == OverClose) {
|
} else if (_down == OverClose && _over == OverClose) {
|
||||||
stopPressed();
|
closePressed();
|
||||||
}
|
}
|
||||||
_down = OverNone;
|
_down = OverNone;
|
||||||
}
|
}
|
||||||
|
@ -545,7 +548,11 @@ void PlayerWidget::stopPressed() {
|
||||||
if (!_song || isHidden()) return;
|
if (!_song || isHidden()) return;
|
||||||
|
|
||||||
audioPlayer()->stop(OverviewFiles);
|
audioPlayer()->stop(OverviewFiles);
|
||||||
if (App::main()) App::main()->hidePlayer();
|
}
|
||||||
|
|
||||||
|
void PlayerWidget::closePressed() {
|
||||||
|
stopPressed();
|
||||||
|
if (App::main()) App::main()->closePlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerWidget::resizeEvent(QResizeEvent *e) {
|
void PlayerWidget::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
void prevPressed();
|
void prevPressed();
|
||||||
void nextPressed();
|
void nextPressed();
|
||||||
void stopPressed();
|
void stopPressed();
|
||||||
|
void closePressed();
|
||||||
|
|
||||||
void step_progress(float64 ms, bool timer);
|
void step_progress(float64 ms, bool timer);
|
||||||
void step_state(uint64 ms, bool timer);
|
void step_state(uint64 ms, bool timer);
|
||||||
|
@ -55,12 +56,23 @@ public:
|
||||||
|
|
||||||
bool seekingSong(const SongMsgId &song) const;
|
bool seekingSong(const SongMsgId &song) const;
|
||||||
|
|
||||||
|
void openPlayer();
|
||||||
|
bool isOpened() const;
|
||||||
|
void closePlayer();
|
||||||
|
|
||||||
|
void showPlayer();
|
||||||
|
void hidePlayer();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void playerSongChanged(const FullMsgId &msgId);
|
void playerSongChanged(const FullMsgId &msgId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// Use startPlayer()/stopPlayer() or showPlayer()/hidePlayer() instead.
|
||||||
|
void show();
|
||||||
|
void hide();
|
||||||
|
|
||||||
enum OverState {
|
enum OverState {
|
||||||
OverNone = 0,
|
OverNone = 0,
|
||||||
OverPrev,
|
OverPrev,
|
||||||
|
@ -87,12 +99,17 @@ private:
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
void updateSelected();
|
void updateSelected();
|
||||||
|
|
||||||
bool _prevAvailable, _nextAvailable, _fullAvailable;
|
bool _playerOpened = false;
|
||||||
OverState _over, _down;
|
|
||||||
int32 _downCoord;
|
bool _prevAvailable = false;
|
||||||
|
bool _nextAvailable = false;
|
||||||
|
bool _fullAvailable = false;
|
||||||
|
OverState _over = OverNone;
|
||||||
|
OverState _down = OverNone;
|
||||||
|
int32 _downCoord = 0;
|
||||||
int64 _downDuration;
|
int64 _downDuration;
|
||||||
int32 _downFrequency;
|
int32 _downFrequency = AudioVoiceMsgFrequency;
|
||||||
float64 _downProgress;
|
float64 _downProgress = 0.;
|
||||||
|
|
||||||
float64 _stateHovers[OverStateCount];
|
float64 _stateHovers[OverStateCount];
|
||||||
typedef QMap<int32, uint64> StateAnimations;
|
typedef QMap<int32, uint64> StateAnimations;
|
||||||
|
@ -100,20 +117,23 @@ private:
|
||||||
Animation _a_state;
|
Animation _a_state;
|
||||||
|
|
||||||
SongMsgId _song;
|
SongMsgId _song;
|
||||||
bool _msgmigrated;
|
bool _msgmigrated = false;
|
||||||
int32 _index;
|
int32 _index = -1;
|
||||||
History *_migrated, *_history;
|
History *_migrated = nullptr;
|
||||||
|
History *_history = nullptr;
|
||||||
QRect _playRect, _prevRect, _nextRect, _playbackRect;
|
QRect _playRect, _prevRect, _nextRect, _playbackRect;
|
||||||
QRect _closeRect, _volumeRect, _fullRect, _repeatRect, _infoRect;
|
QRect _closeRect, _volumeRect, _fullRect, _repeatRect, _infoRect;
|
||||||
int32 _timeWidth;
|
int32 _timeWidth = 0;
|
||||||
bool _repeat;
|
bool _repeat = false;
|
||||||
QString _time;
|
QString _time;
|
||||||
Text _name;
|
Text _name;
|
||||||
bool _showPause;
|
bool _showPause = false;
|
||||||
int64 _position, _duration;
|
int64 _position = 0;
|
||||||
int32 _loaded;
|
int64 _duration = 0;
|
||||||
|
int32 _loaded = 0;
|
||||||
|
|
||||||
anim::fvalue a_progress, a_loadProgress;
|
anim::fvalue a_progress = { 0., 0. };
|
||||||
|
anim::fvalue a_loadProgress = { 0., 0. };
|
||||||
Animation _a_progress;
|
Animation _a_progress;
|
||||||
|
|
||||||
PlainShadow _sideShadow;
|
PlainShadow _sideShadow;
|
||||||
|
|
|
@ -27,9 +27,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "playerwidget.h"
|
#include "playerwidget.h"
|
||||||
|
|
||||||
namespace ShortcutCommands {
|
namespace ShortcutCommands {
|
||||||
typedef void(*Handler)();
|
|
||||||
|
|
||||||
void lock_telegram() {
|
typedef void(*Handler)();
|
||||||
|
|
||||||
|
void lock_telegram() {
|
||||||
if (auto w = App::wnd()) {
|
if (auto w = App::wnd()) {
|
||||||
if (App::passcoded()) {
|
if (App::passcoded()) {
|
||||||
w->passcodeWidget()->onSubmit();
|
w->passcodeWidget()->onSubmit();
|
||||||
|
@ -37,9 +38,9 @@ namespace ShortcutCommands {
|
||||||
w->setupPasscode(true);
|
w->setupPasscode(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void minimize_telegram() {
|
void minimize_telegram() {
|
||||||
if (auto w = App::wnd()) {
|
if (auto w = App::wnd()) {
|
||||||
if (cWorkMode() == dbiwmTrayOnly) {
|
if (cWorkMode() == dbiwmTrayOnly) {
|
||||||
w->minimizeToTray();
|
w->minimizeToTray();
|
||||||
|
@ -47,94 +48,94 @@ namespace ShortcutCommands {
|
||||||
w->setWindowState(Qt::WindowMinimized);
|
w->setWindowState(Qt::WindowMinimized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_telegram() {
|
void close_telegram() {
|
||||||
if (!Ui::hideWindowNoQuit()) {
|
if (!Ui::hideWindowNoQuit()) {
|
||||||
if (auto w = App::wnd()) {
|
if (auto w = App::wnd()) {
|
||||||
w->close();
|
w->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void quit_telegram() {
|
void quit_telegram() {
|
||||||
App::quit();
|
App::quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
//void start_stop_recording() {
|
//void start_stop_recording() {
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//void cancel_recording() {
|
//void cancel_recording() {
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void media_play() {
|
void media_play() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->player()->playPressed();
|
m->player()->playPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void media_pause() {
|
void media_pause() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->player()->pausePressed();
|
m->player()->pausePressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void media_playpause() {
|
void media_playpause() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->player()->playPausePressed();
|
m->player()->playPausePressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void media_stop() {
|
void media_stop() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->player()->stopPressed();
|
m->player()->stopPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void media_previous() {
|
void media_previous() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->player()->prevPressed();
|
m->player()->prevPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void media_next() {
|
void media_next() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->player()->nextPressed();
|
m->player()->nextPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void search() {
|
void search() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->cmd_search();
|
m->cmd_search();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void previous_chat() {
|
void previous_chat() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->cmd_previous_chat();
|
m->cmd_previous_chat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void next_chat() {
|
void next_chat() {
|
||||||
if (MainWidget *m = App::main()) {
|
if (MainWidget *m = App::main()) {
|
||||||
m->cmd_next_chat();
|
m->cmd_next_chat();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// other commands here
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// other commands here
|
||||||
|
|
||||||
|
} // namespace ShortcutCommands
|
||||||
|
|
||||||
inline bool qMapLessThanKey(const ShortcutCommands::Handler &a, const ShortcutCommands::Handler &b) {
|
inline bool qMapLessThanKey(const ShortcutCommands::Handler &a, const ShortcutCommands::Handler &b) {
|
||||||
return a < b;
|
return a < b;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Shortcuts {
|
namespace Shortcuts {
|
||||||
|
|
||||||
// inspired by https://github.com/sindresorhus/strip-json-comments
|
// inspired by https://github.com/sindresorhus/strip-json-comments
|
||||||
QByteArray _stripJsonComments(const QByteArray &json) {
|
QByteArray _stripJsonComments(const QByteArray &json) {
|
||||||
enum InsideComment {
|
enum InsideComment {
|
||||||
InsideCommentNone,
|
InsideCommentNone,
|
||||||
InsideCommentSingleLine,
|
InsideCommentSingleLine,
|
||||||
|
@ -201,20 +202,26 @@ namespace Shortcuts {
|
||||||
result.append(offset, e - offset);
|
result.append(offset, e - offset);
|
||||||
}
|
}
|
||||||
return result.isEmpty() ? json : result;
|
return result.isEmpty() ? json : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DataStruct;
|
struct DataStruct;
|
||||||
DataStruct *DataPtr = nullptr;
|
DataStruct *DataPtr = nullptr;
|
||||||
|
|
||||||
void _createCommand(const QString &command, ShortcutCommands::Handler handler);
|
namespace {
|
||||||
QKeySequence _setShortcut(const QString &keys, const QString &command);
|
|
||||||
struct DataStruct {
|
void createCommand(const QString &command, ShortcutCommands::Handler handler);
|
||||||
|
QKeySequence setShortcut(const QString &keys, const QString &command);
|
||||||
|
void destroyShortcut(QShortcut *shortcut);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
struct DataStruct {
|
||||||
DataStruct() {
|
DataStruct() {
|
||||||
t_assert(DataPtr == nullptr);
|
t_assert(DataPtr == nullptr);
|
||||||
DataPtr = this;
|
DataPtr = this;
|
||||||
|
|
||||||
#define DeclareAlias(keys, command) _setShortcut(qsl(keys), qsl(#command))
|
#define DeclareAlias(keys, command) setShortcut(qsl(keys), qsl(#command))
|
||||||
#define DeclareCommand(keys, command) _createCommand(qsl(#command), ShortcutCommands::command); DeclareAlias(keys, command)
|
#define DeclareCommand(keys, command) createCommand(qsl(#command), ShortcutCommands::command); DeclareAlias(keys, command)
|
||||||
|
|
||||||
DeclareCommand("ctrl+w", close_telegram);
|
DeclareCommand("ctrl+w", close_telegram);
|
||||||
DeclareAlias("ctrl+f4", close_telegram);
|
DeclareAlias("ctrl+f4", close_telegram);
|
||||||
|
@ -264,23 +271,36 @@ namespace Shortcuts {
|
||||||
QMap<QKeySequence, QShortcut*> sequences;
|
QMap<QKeySequence, QShortcut*> sequences;
|
||||||
QMap<int, ShortcutCommands::Handler> handlers;
|
QMap<int, ShortcutCommands::Handler> handlers;
|
||||||
|
|
||||||
|
QSet<QShortcut*> mediaShortcuts;
|
||||||
|
|
||||||
QSet<QString> autoRepeatCommands = {
|
QSet<QString> autoRepeatCommands = {
|
||||||
qsl("media_previous"),
|
qsl("media_previous"),
|
||||||
qsl("media_next"),
|
qsl("media_next"),
|
||||||
qsl("next_chat"),
|
qsl("next_chat"),
|
||||||
qsl("previous_chat"),
|
qsl("previous_chat"),
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
void _createCommand(const QString &command, ShortcutCommands::Handler handler) {
|
QSet<QString> mediaCommands = {
|
||||||
|
qsl("media_play"),
|
||||||
|
qsl("media_pause"),
|
||||||
|
qsl("media_playpause"),
|
||||||
|
qsl("media_stop"),
|
||||||
|
qsl("media_previous"),
|
||||||
|
qsl("media_next")
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void createCommand(const QString &command, ShortcutCommands::Handler handler) {
|
||||||
t_assert(DataPtr != nullptr);
|
t_assert(DataPtr != nullptr);
|
||||||
t_assert(!command.isEmpty());
|
t_assert(!command.isEmpty());
|
||||||
|
|
||||||
DataPtr->commands.insert(command, handler);
|
DataPtr->commands.insert(command, handler);
|
||||||
DataPtr->commandnames.insert(handler, command);
|
DataPtr->commandnames.insert(handler, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
QKeySequence _setShortcut(const QString &keys, const QString &command) {
|
QKeySequence setShortcut(const QString &keys, const QString &command) {
|
||||||
t_assert(DataPtr != nullptr);
|
t_assert(DataPtr != nullptr);
|
||||||
t_assert(!command.isEmpty());
|
t_assert(!command.isEmpty());
|
||||||
if (keys.isEmpty()) return QKeySequence();
|
if (keys.isEmpty()) return QKeySequence();
|
||||||
|
@ -293,30 +313,37 @@ namespace Shortcuts {
|
||||||
if (it == DataPtr->commands.cend()) {
|
if (it == DataPtr->commands.cend()) {
|
||||||
LOG(("Warning: could not find shortcut command handler '%1'").arg(command));
|
LOG(("Warning: could not find shortcut command handler '%1'").arg(command));
|
||||||
} else {
|
} else {
|
||||||
QShortcut *shortcut(new QShortcut(seq, App::wnd(), nullptr, nullptr, Qt::ApplicationShortcut));
|
auto shortcut = std_::make_unique<QShortcut>(seq, App::wnd(), nullptr, nullptr, Qt::ApplicationShortcut);
|
||||||
if (!DataPtr->autoRepeatCommands.contains(command)) {
|
if (!DataPtr->autoRepeatCommands.contains(command)) {
|
||||||
shortcut->setAutoRepeat(false);
|
shortcut->setAutoRepeat(false);
|
||||||
}
|
}
|
||||||
|
auto isMediaShortcut = DataPtr->mediaCommands.contains(command);
|
||||||
|
if (isMediaShortcut) {
|
||||||
|
shortcut->setEnabled(false);
|
||||||
|
}
|
||||||
int shortcutId = shortcut->id();
|
int shortcutId = shortcut->id();
|
||||||
if (!shortcutId) {
|
if (!shortcutId) {
|
||||||
DataPtr->errors.push_back(qsl("Could not create shortcut '%1'!").arg(keys));
|
DataPtr->errors.push_back(qsl("Could not create shortcut '%1'!").arg(keys));
|
||||||
} else {
|
} else {
|
||||||
QMap<QKeySequence, QShortcut*>::iterator seqIt = DataPtr->sequences.find(seq);
|
auto seqIt = DataPtr->sequences.find(seq);
|
||||||
if (seqIt == DataPtr->sequences.cend()) {
|
if (seqIt == DataPtr->sequences.cend()) {
|
||||||
seqIt = DataPtr->sequences.insert(seq, shortcut);
|
seqIt = DataPtr->sequences.insert(seq, shortcut.release());
|
||||||
} else {
|
} else {
|
||||||
DataPtr->handlers.remove(seqIt.value()->id());
|
auto oldShortcut = seqIt.value();
|
||||||
delete seqIt.value();
|
seqIt.value() = shortcut.release();
|
||||||
seqIt.value() = shortcut;
|
destroyShortcut(oldShortcut);
|
||||||
}
|
}
|
||||||
DataPtr->handlers.insert(shortcutId, it.value());
|
DataPtr->handlers.insert(shortcutId, it.value());
|
||||||
|
if (isMediaShortcut) {
|
||||||
|
DataPtr->mediaShortcuts.insert(seqIt.value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
QKeySequence _removeShortcut(const QString &keys) {
|
QKeySequence removeShortcut(const QString &keys) {
|
||||||
t_assert(DataPtr != nullptr);
|
t_assert(DataPtr != nullptr);
|
||||||
if (keys.isEmpty()) return QKeySequence();
|
if (keys.isEmpty()) return QKeySequence();
|
||||||
|
|
||||||
|
@ -324,17 +351,27 @@ namespace Shortcuts {
|
||||||
if (seq.isEmpty()) {
|
if (seq.isEmpty()) {
|
||||||
DataPtr->errors.push_back(qsl("Could not derive key sequence '%1'!").arg(keys));
|
DataPtr->errors.push_back(qsl("Could not derive key sequence '%1'!").arg(keys));
|
||||||
} else {
|
} else {
|
||||||
QMap<QKeySequence, QShortcut*>::iterator seqIt = DataPtr->sequences.find(seq);
|
auto seqIt = DataPtr->sequences.find(seq);
|
||||||
if (seqIt != DataPtr->sequences.cend()) {
|
if (seqIt != DataPtr->sequences.cend()) {
|
||||||
DataPtr->handlers.remove(seqIt.value()->id());
|
auto shortcut = seqIt.value();
|
||||||
delete seqIt.value();
|
|
||||||
DataPtr->sequences.erase(seqIt);
|
DataPtr->sequences.erase(seqIt);
|
||||||
|
destroyShortcut(shortcut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void destroyShortcut(QShortcut *shortcut) {
|
||||||
|
t_assert(DataPtr != nullptr);
|
||||||
|
|
||||||
|
DataPtr->handlers.remove(shortcut->id());
|
||||||
|
DataPtr->mediaShortcuts.remove(shortcut);
|
||||||
|
delete shortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void start() {
|
||||||
t_assert(Global::started());
|
t_assert(Global::started());
|
||||||
|
|
||||||
new DataStruct();
|
new DataStruct();
|
||||||
|
@ -371,10 +408,10 @@ namespace Shortcuts {
|
||||||
version.insert(qsl("version"), QString::number(AppVersion));
|
version.insert(qsl("version"), QString::number(AppVersion));
|
||||||
shortcuts.push_back(version);
|
shortcuts.push_back(version);
|
||||||
|
|
||||||
for (QMap<QKeySequence, QShortcut*>::const_iterator i = DataPtr->sequences.cbegin(), e = DataPtr->sequences.cend(); i != e; ++i) {
|
for (auto i = DataPtr->sequences.cbegin(), e = DataPtr->sequences.cend(); i != e; ++i) {
|
||||||
QMap<int, ShortcutCommands::Handler>::const_iterator h = DataPtr->handlers.constFind(i.value()->id());
|
auto h = DataPtr->handlers.constFind(i.value()->id());
|
||||||
if (h != DataPtr->handlers.cend()) {
|
if (h != DataPtr->handlers.cend()) {
|
||||||
QMap<ShortcutCommands::Handler, QString>::const_iterator n = DataPtr->commandnames.constFind(h.value());
|
auto n = DataPtr->commandnames.constFind(h.value());
|
||||||
if (n != DataPtr->commandnames.cend()) {
|
if (n != DataPtr->commandnames.cend()) {
|
||||||
QJsonObject entry;
|
QJsonObject entry;
|
||||||
entry.insert(qsl("keys"), i.key().toString().toLower());
|
entry.insert(qsl("keys"), i.key().toString().toLower());
|
||||||
|
@ -415,9 +452,9 @@ namespace Shortcuts {
|
||||||
if (keys == entry.constEnd() || command == entry.constEnd() || !(*keys).isString() || (!(*command).isString() && !(*command).isNull())) {
|
if (keys == entry.constEnd() || command == entry.constEnd() || !(*keys).isString() || (!(*command).isString() && !(*command).isNull())) {
|
||||||
DataPtr->errors.push_back(qsl("Bad entry! {\"keys\": \"...\", \"command\": [ \"...\" | null ]} expected"));
|
DataPtr->errors.push_back(qsl("Bad entry! {\"keys\": \"...\", \"command\": [ \"...\" | null ]} expected"));
|
||||||
} else if ((*command).isNull()) {
|
} else if ((*command).isNull()) {
|
||||||
seq = _removeShortcut((*keys).toString());
|
seq = removeShortcut((*keys).toString());
|
||||||
} else {
|
} else {
|
||||||
seq = _setShortcut((*keys).toString(), (*command).toString());
|
seq = setShortcut((*keys).toString(), (*command).toString());
|
||||||
}
|
}
|
||||||
if (!--limit) {
|
if (!--limit) {
|
||||||
DataPtr->errors.push_back(qsl("Too many entries! Limit is %1").arg(ShortcutsCountLimit));
|
DataPtr->errors.push_back(qsl("Too many entries! Limit is %1").arg(ShortcutsCountLimit));
|
||||||
|
@ -450,38 +487,52 @@ namespace Shortcuts {
|
||||||
customFile.write(customContent);
|
customFile.write(customContent);
|
||||||
customFile.close();
|
customFile.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringList &errors() {
|
const QStringList &errors() {
|
||||||
t_assert(DataPtr != nullptr);
|
t_assert(DataPtr != nullptr);
|
||||||
return DataPtr->errors;
|
return DataPtr->errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool launch(int shortcutId) {
|
bool launch(int shortcutId) {
|
||||||
t_assert(DataPtr != nullptr);
|
t_assert(DataPtr != nullptr);
|
||||||
|
|
||||||
QMap<int, ShortcutCommands::Handler>::const_iterator it = DataPtr->handlers.constFind(shortcutId);
|
auto it = DataPtr->handlers.constFind(shortcutId);
|
||||||
if (it == DataPtr->handlers.cend()) {
|
if (it == DataPtr->handlers.cend()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
(*it.value())();
|
(*it.value())();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool launch(const QString &command) {
|
bool launch(const QString &command) {
|
||||||
t_assert(DataPtr != nullptr);
|
t_assert(DataPtr != nullptr);
|
||||||
|
|
||||||
QMap<QString, ShortcutCommands::Handler>::const_iterator it = DataPtr->commands.constFind(command);
|
auto it = DataPtr->commands.constFind(command);
|
||||||
if (it == DataPtr->commands.cend()) {
|
if (it == DataPtr->commands.cend()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
(*it.value())();
|
(*it.value())();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void finish() {
|
void enableMediaShortcuts() {
|
||||||
|
if (!DataPtr) return;
|
||||||
|
for_const (auto shortcut, DataPtr->mediaShortcuts) {
|
||||||
|
shortcut->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableMediaShortcuts() {
|
||||||
|
if (!DataPtr) return;
|
||||||
|
for_const (auto shortcut, DataPtr->mediaShortcuts) {
|
||||||
|
shortcut->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish() {
|
||||||
delete DataPtr;
|
delete DataPtr;
|
||||||
DataPtr = nullptr;
|
DataPtr = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Shortcuts
|
||||||
|
|
|
@ -28,6 +28,12 @@ namespace Shortcuts {
|
||||||
bool launch(int shortcutId);
|
bool launch(int shortcutId);
|
||||||
bool launch(const QString &command);
|
bool launch(const QString &command);
|
||||||
|
|
||||||
|
// Media shortcuts are not enabled by default, because other
|
||||||
|
// applications also use them. They are enabled only when
|
||||||
|
// the in-app player is active and disabled back after.
|
||||||
|
void enableMediaShortcuts();
|
||||||
|
void disableMediaShortcuts();
|
||||||
|
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue