global shortcuts with loading from .json map

This commit is contained in:
John Preston 2016-02-27 22:39:51 +03:00
parent 175968c3c0
commit a88b676588
19 changed files with 116 additions and 127 deletions

View file

@ -22,6 +22,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "application.h"
#include "style.h"
#include "shortcuts.h"
#include "pspecific.h"
#include "fileuploader.h"
#include "mainwidget.h"
@ -47,52 +49,6 @@ namespace {
}
}
class EventFilterForKeys : public QObject {
public:
EventFilterForKeys(QObject *parent) : QObject(parent) {
}
bool eventFilter(QObject *o, QEvent *e) {
if (e->type() == QEvent::KeyPress) {
QKeyEvent *ev = static_cast<QKeyEvent*>(e);
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
if (ev->key() == Qt::Key_W && (ev->modifiers() & Qt::ControlModifier)) {
Ui::hideWindowNoQuit();
return true;
} else if (ev->key() == Qt::Key_M && (ev->modifiers() & Qt::ControlModifier)) {
App::wnd()->setWindowState(Qt::WindowMinimized);
return true;
}
} else {
if ((ev->key() == Qt::Key_W || ev->key() == Qt::Key_F4) && (ev->modifiers() & Qt::ControlModifier)) {
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
App::wnd()->minimizeToTray();
return true;
} else {
App::wnd()->close();
return true;
}
}
}
if (ev->key() == Qt::Key_MediaPlay) {
if (App::main()) App::main()->player()->playPressed();
} else if (ev->key() == Qt::Key_MediaPause) {
if (App::main()) App::main()->player()->pausePressed();
} else if (ev->key() == Qt::Key_MediaTogglePlayPause) {
if (App::main()) App::main()->player()->playPausePressed();
} else if (ev->key() == Qt::Key_MediaStop) {
if (App::main()) App::main()->player()->stopPressed();
} else if (ev->key() == Qt::Key_MediaPrevious) {
if (App::main()) App::main()->player()->prevPressed();
} else if (ev->key() == Qt::Key_MediaNext) {
if (App::main()) App::main()->player()->nextPressed();
}
}
return QObject::eventFilter(o, e);
}
};
QChar _toHex(ushort v) {
v = v & 0x000F;
return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v));
@ -708,8 +664,6 @@ AppClass::AppClass() : QObject()
return;
}
application()->installEventFilter(new EventFilterForKeys(this));
if (cRetina()) {
cSetConfigScale(dbisOne);
cSetRealScale(dbisOne);
@ -767,6 +721,8 @@ AppClass::AppClass() : QObject()
DEBUG_LOG(("Application Info: window created.."));
Shortcuts::start();
initImageLinkManager();
App::initMedia();
@ -807,6 +763,13 @@ AppClass::AppClass() : QObject()
}
_window->updateIsActive(Global::OnlineFocusTimeout());
if (!Shortcuts::errors().isEmpty()) {
const QStringList &errors(Shortcuts::errors());
for (QStringList::const_iterator i = errors.cbegin(), e = errors.cend(); i != e; ++i) {
LOG(("Shortcuts Error: %1").arg(*i));
}
}
}
void AppClass::regPhotoUpdate(const PeerId &peer, const FullMsgId &msgId) {
@ -1070,6 +1033,8 @@ void AppClass::checkMapVersion() {
}
AppClass::~AppClass() {
Shortcuts::finish();
if (Window *w = _window) {
_window = 0;
delete w;

View file

@ -129,6 +129,8 @@ enum {
MaxZoomLevel = 7, // x8
ZoomToScreenLevel = 1024, // just constant
ShortcutsCountLimit = 256, // how many shortcuts can be in json file
PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request
EmojiPanPerRow = 7,
EmojiPanRowsPerPage = 6,

View file

@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "stdafx.h"
#include "application.h"
#include "window.h"
namespace Fonts {
@ -52,6 +53,10 @@ namespace {
}
}
bool TWidget::inFocusChain() const {
return !isHidden() && App::wnd() && (App::wnd()->focusWidget() == this || isAncestorOf(App::wnd()->focusWidget()));
}
void myEnsureResized(QWidget *target) {
if (target && (target->testAttribute(Qt::WA_PendingResizeEvent) || !target->testAttribute(Qt::WA_WState_Created))) {
_sendResizeEvents(target);

View file

@ -183,6 +183,8 @@ public:
virtual void grabFinish() {
}
bool inFocusChain() const;
private:
};

View file

@ -2612,7 +2612,7 @@ void SilentToggle::leaveEvent(QEvent *e) {
void SilentToggle::mouseReleaseEvent(QMouseEvent *e) {
FlatCheckbox::mouseReleaseEvent(e);
PopupTooltip::Show(0, this);
PeerData *p = App::main() ? App::main()->peer() : Nil;
PeerData *p = App::main() ? App::main()->peer() : nullptr;
if (p && p->isChannel() && p->notify != UnknownNotifySettings) {
App::main()->updateNotifySetting(p, NotifySettingDontChange, checked() ? SilentNotifiesSetSilent : SilentNotifiesSetNotify);
}
@ -2979,7 +2979,7 @@ void HistoryWidget::onDraftSave(bool delayed) {
return _saveDraftTimer.start(SaveDraftTimeout);
}
}
writeDrafts(Nil, Nil);
writeDrafts(nullptr, nullptr);
}
void HistoryWidget::writeDrafts(HistoryDraft **msgDraft, HistoryEditDraft **editDraft) {
@ -3228,6 +3228,26 @@ void HistoryWidget::notify_historyItemResized(const HistoryItem *row, bool scrol
updateListSize(0, false, false, row, scrollToIt);
}
void HistoryWidget::cmd_search() {
if (!inFocusChain() || !_peer) return;
App::main()->searchInPeer(_peer);
}
void HistoryWidget::cmd_next_chat() {
PeerData *p = 0;
MsgId m = 0;
App::main()->peerAfter(_peer, qMax(_showAtMsgId, 0), p, m);
if (p) Ui::showPeerHistory(p, m);
}
void HistoryWidget::cmd_previous_chat() {
PeerData *p = 0;
MsgId m = 0;
App::main()->peerBefore(_peer, qMax(_showAtMsgId, 0), p, m);
if (p) Ui::showPeerHistory(p, m);
}
void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
cSetLastStickersUpdate(getms(true));
_stickersUpdateRequest = 0;
@ -3546,13 +3566,13 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
if (_replyToId || !_field.getLastText().isEmpty()) {
_history->setMsgDraft(new HistoryDraft(_field, _replyToId, _previewCancelled));
} else {
_history->setMsgDraft(Nil);
_history->setMsgDraft(nullptr);
}
_history->setEditDraft(Nil);
_history->setEditDraft(nullptr);
}
if (_migrated) {
_migrated->setMsgDraft(Nil); // use migrated draft only once
_migrated->setEditDraft(Nil);
_migrated->setMsgDraft(nullptr); // use migrated draft only once
_migrated->setEditDraft(nullptr);
}
writeDrafts(&_history->msgDraft, &_history->editDraft);
@ -3666,14 +3686,14 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
Local::readDraftsWithCursors(_history);
if (_migrated) {
Local::readDraftsWithCursors(_migrated);
_migrated->setEditDraft(Nil);
_migrated->setEditDraft(nullptr);
if (_migrated->msgDraft && !_migrated->msgDraft->text.isEmpty()) {
_migrated->msgDraft->msgId = 0; // edit and reply to drafts can't migrate
if (!_history->msgDraft) {
_history->setMsgDraft(new HistoryDraft(*_migrated->msgDraft));
}
}
_migrated->setMsgDraft(Nil);
_migrated->setMsgDraft(nullptr);
}
applyDraft(false);
@ -4581,7 +4601,7 @@ void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates,
cancelEdit();
}
if (history->editDraft && history->editDraft->saveRequest == req) {
history->setEditDraft(Nil);
history->setEditDraft(nullptr);
writeDrafts(history);
}
}
@ -6520,59 +6540,23 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
void HistoryWidget::keyPressEvent(QKeyEvent *e) {
if (!_history) return;
MsgId msgid = qMax(_showAtMsgId, 0);
if (e->key() == Qt::Key_Escape) {
e->ignore();
} else if (e->key() == Qt::Key_Back) {
Ui::showChatsList();
emit cancelled();
} else if (e->key() == Qt::Key_PageDown) {
if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::MetaModifier)) {
PeerData *after = 0;
MsgId afterMsgId = 0;
App::main()->peerAfter(_peer, msgid, after, afterMsgId);
if (after) Ui::showPeerHistory(after, afterMsgId);
} else {
_scroll.keyPressEvent(e);
}
_scroll.keyPressEvent(e);
} else if (e->key() == Qt::Key_PageUp) {
if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::MetaModifier)) {
PeerData *before = 0;
MsgId beforeMsgId = 0;
App::main()->peerBefore(_peer, msgid, before, beforeMsgId);
if (before) Ui::showPeerHistory(before, beforeMsgId);
} else {
_scroll.keyPressEvent(e);
}
_scroll.keyPressEvent(e);
} else if (e->key() == Qt::Key_Down) {
if (e->modifiers() & Qt::AltModifier) {
PeerData *after = 0;
MsgId afterMsgId = 0;
App::main()->peerAfter(_peer, msgid, after, afterMsgId);
if (after) Ui::showPeerHistory(after, afterMsgId);
} else if (!(e->modifiers() & (Qt::ShiftModifier | Qt::MetaModifier | Qt::ControlModifier))) {
if (!(e->modifiers() & (Qt::ShiftModifier | Qt::MetaModifier | Qt::ControlModifier))) {
_scroll.keyPressEvent(e);
}
} else if (e->key() == Qt::Key_Up) {
if (e->modifiers() & Qt::AltModifier) {
PeerData *before = 0;
MsgId beforeMsgId = 0;
App::main()->peerBefore(_peer, msgid, before, beforeMsgId);
if (before) Ui::showPeerHistory(before, beforeMsgId);
} else if (!(e->modifiers() & (Qt::ShiftModifier | Qt::MetaModifier | Qt::ControlModifier))) {
if (!(e->modifiers() & (Qt::ShiftModifier | Qt::MetaModifier | Qt::ControlModifier))) {
_scroll.keyPressEvent(e);
}
} else if ((e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab) && ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::MetaModifier))) {
PeerData *p = 0;
MsgId m = 0;
if ((e->modifiers() & Qt::ShiftModifier) || e->key() == Qt::Key_Backtab) {
App::main()->peerBefore(_peer, msgid, p, m);
} else {
App::main()->peerAfter(_peer, msgid, p, m);
}
if (p) Ui::showPeerHistory(p, m);
} else if (_history && (e->key() == Qt::Key_Search || e == QKeySequence::Find)) {
App::main()->searchInPeer(_peer);
} else {
e->ignore();
}
@ -6902,7 +6886,7 @@ void HistoryWidget::onEditMessage() {
if (_replyToId || !_field.getLastText().isEmpty()) {
_history->setMsgDraft(new HistoryDraft(_field, _replyToId, _previewCancelled));
} else {
_history->setMsgDraft(Nil);
_history->setMsgDraft(nullptr);
}
QString text(textApplyEntities(to->originalText(), to->originalEntities()));
@ -6966,7 +6950,7 @@ void HistoryWidget::cancelReply(bool lastKeyboardUsed) {
update();
} else if (wasReply) {
if (_history->msgDraft->text.isEmpty()) {
_history->setMsgDraft(Nil);
_history->setMsgDraft(nullptr);
} else {
_history->msgDraft->msgId = 0;
}
@ -6988,7 +6972,7 @@ void HistoryWidget::cancelEdit() {
_editMsgId = 0;
_replyEditMsg = 0;
_history->setEditDraft(Nil);
_history->setEditDraft(nullptr);
applyDraft();
if (_saveEditMsgRequestId) {

View file

@ -596,6 +596,10 @@ public:
void notify_clipStopperHidden(ClipStopperType type);
void notify_historyItemResized(const HistoryItem *item, bool scrollToIt);
void cmd_search();
void cmd_next_chat();
void cmd_previous_chat();
~HistoryWidget();
signals:

View file

@ -2352,12 +2352,12 @@ namespace Local {
_readDraftCursors(peer, msgCursor, editCursor);
if (msgText.isEmpty() && !msgReplyTo) {
h->setMsgDraft(Nil);
h->setMsgDraft(nullptr);
} else {
h->setMsgDraft(new HistoryDraft(msgText, msgReplyTo, msgCursor, msgPreviewCancelled));
}
if (!editMsgId) {
h->setEditDraft(Nil);
h->setEditDraft(nullptr);
} else {
h->setEditDraft(new HistoryEditDraft(editText, editMsgId, editCursor, editPreviewCancelled));
}

View file

@ -517,7 +517,7 @@ bool MainWidget::onShareUrl(const PeerId &peer, const QString &url, const QStrin
}
History *h = App::history(peer);
h->setMsgDraft(new HistoryDraft(url + '\n' + text, 0, MessageCursor(url.size() + 1, url.size() + 1 + text.size(), QFIXED_MAX), false));
h->setEditDraft(Nil);
h->setEditDraft(nullptr);
bool opened = history.peer() && (history.peer()->id == peer);
if (opened) {
history.applyDraft();
@ -812,6 +812,18 @@ void MainWidget::notify_automaticLoadSettingsChangedGif() {
history.notify_automaticLoadSettingsChangedGif();
}
void MainWidget::cmd_search() {
history.cmd_search();
}
void MainWidget::cmd_next_chat() {
history.cmd_next_chat();
}
void MainWidget::cmd_previous_chat() {
history.cmd_previous_chat();
}
void MainWidget::notify_historyItemResized(const HistoryItem *item, bool scrollToIt) {
if (!item || ((history.peer() == item->history()->peer || (history.peer() && history.peer() == item->history()->peer->migrateTo())) && !item->detached())) {
history.notify_historyItemResized(item, scrollToIt);

View file

@ -435,6 +435,10 @@ public:
void notify_historyItemLayoutChanged(const HistoryItem *item);
void notify_automaticLoadSettingsChangedGif();
void cmd_search();
void cmd_next_chat();
void cmd_previous_chat();
~MainWidget();
signals:

View file

@ -620,6 +620,7 @@ namespace {
case WM_CLOSE:
App::wnd()->close();
break;
case WM_NCHITTEST: {
int32 xPos = GET_X_LPARAM(lParam), yPos = GET_Y_LPARAM(lParam);
switch (i) {

View file

@ -20,7 +20,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#define __HUGE
#define PSAPI_VERSION 1 // fix WinXP
//#define Q_NO_TEMPLATE_FRIENDS // fix some compiler difference issues
#define __STDC_FORMAT_MACROS // fix breakpad for mac
@ -38,15 +37,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <QtCore/QtCore>
#include <QtWidgets/QtWidgets>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkProxy>
#include <QtNetwork/QLocalSocket>
#include <QtNetwork/QLocalServer>
#include <QtNetwork/QHttpMultiPart>
#include <QtNetwork/QtNetwork>
#ifdef Q_OS_WIN // use Lzma SDK for win
#include <LzmaLib.h>

View file

@ -22,9 +22,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "style.h"
#include "lang.h"
#include "shortcuts.h"
#include "sysbuttons.h"
#include "passcodewidget.h"
#include "window.h"
#include "application.h"
#include "autoupdater.h"
@ -166,9 +166,5 @@ LockBtn::LockBtn(QWidget *parent, Window *window) : SysBtn(parent, st::sysLock),
}
void LockBtn::onClick() {
if (App::passcoded()) {
App::wnd()->passcodeWidget()->onSubmit();
} else {
App::wnd()->setupPasscode(true);
}
Shortcuts::launch(qsl("lock_telegram"));
}

View file

@ -20,7 +20,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <QtWidgets/QWidget>
#include "gui/animation.h"
#include "gui/button.h"

View file

@ -35,7 +35,9 @@ uint64 _SharedMemoryLocation[4] = { 0x00, 0x01, 0x02, 0x03 };
// Base types compile-time check
NilPointer Nil;
#ifdef TDESKTOP_CUSTOM_NULLPTR
NullPointerClass nullptr;
#endif
namespace {
template <typename T, int N>

View file

@ -36,7 +36,12 @@ T *exchange(T *&ptr) {
struct NullType {
};
class NilPointer {
#if __cplusplus < 199711L
#define TDESKTOP_CUSTOM_NULLPTR
#endif
#ifdef TDESKTOP_CUSTOM_NULLPTR
class NullPointerClass {
public:
template <typename T>
operator T*() const {
@ -50,7 +55,8 @@ public:
private:
void operator&() const;
};
extern NilPointer Nil;
extern NullPointerClass nullptr;
#endif
template <typename T>
class OrderedSet : public QMap<T, NullType> {

View file

@ -22,6 +22,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "style.h"
#include "lang.h"
#include "shortcuts.h"
#include "window.h"
#include "application.h"
@ -1008,8 +1010,8 @@ QRect Window::iconRect() const {
return QRect(st::titleIconPos + title->geometry().topLeft(), st::titleIconImg.pxSize());
}
bool Window::eventFilter(QObject *obj, QEvent *evt) {
QEvent::Type t = evt->type();
bool Window::eventFilter(QObject *obj, QEvent *e) {
QEvent::Type t = e->type();
if (t == QEvent::MouseButtonPress || t == QEvent::KeyPress || t == QEvent::TouchBegin || t == QEvent::Wheel) {
psUserActionDone();
} else if (t == QEvent::MouseMove) {
@ -1019,13 +1021,15 @@ bool Window::eventFilter(QObject *obj, QEvent *evt) {
}
} else if (t == QEvent::MouseButtonRelease) {
Ui::hideStickerPreview();
} else if (t == QEvent::Shortcut) {
Shortcuts::launch(static_cast<QShortcutEvent*>(e)->shortcutId());
}
if (obj == Application::instance()) {
if (t == QEvent::ApplicationActivate) {
psUserActionDone();
QTimer::singleShot(1, this, SLOT(checkHistoryActivation()));
} else if (t == QEvent::FileOpen) {
QString url = static_cast<QFileOpenEvent*>(evt)->url().toEncoded();
QString url = static_cast<QFileOpenEvent*>(e)->url().toEncoded();
if (!url.trimmed().midRef(0, 5).compare(qsl("tg://"), Qt::CaseInsensitive)) {
cSetStartUrl(url);
if (!cStartUrl().isEmpty() && App::main() && App::self()) {
@ -1043,7 +1047,7 @@ bool Window::eventFilter(QObject *obj, QEvent *evt) {
psUpdatedPosition();
}
}
return PsMainWindow::eventFilter(obj, evt);
return PsMainWindow::eventFilter(obj, e);
}
void Window::mouseMoveEvent(QMouseEvent *e) {

View file

@ -108,6 +108,7 @@ SOURCES += \
./SourceFiles/mainwidget.cpp \
./SourceFiles/settings.cpp \
./SourceFiles/settingswidget.cpp \
./SourceFiles/shortcuts.cpp \
./SourceFiles/structs.cpp \
./SourceFiles/sysbuttons.cpp \
./SourceFiles/title.cpp \
@ -197,6 +198,7 @@ HEADERS += \
./SourceFiles/mainwidget.h \
./SourceFiles/settings.h \
./SourceFiles/settingswidget.h \
./SourceFiles/shortcuts.h \
./SourceFiles/structs.h \
./SourceFiles/style.h \
./SourceFiles/sysbuttons.h \

View file

@ -1043,6 +1043,7 @@
<ClCompile Include="SourceFiles\pspecific_wnd.cpp" />
<ClCompile Include="SourceFiles\settings.cpp" />
<ClCompile Include="SourceFiles\settingswidget.cpp" />
<ClCompile Include="SourceFiles\shortcuts.cpp" />
<ClCompile Include="SourceFiles\stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
@ -1060,6 +1061,7 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SourceFiles\shortcuts.h" />
<ClInclude Include="ThirdParty\minizip\crypt.h" />
<ClInclude Include="ThirdParty\minizip\ioapi.h" />
<ClInclude Include="ThirdParty\minizip\zip.h" />

View file

@ -906,6 +906,9 @@
<ClCompile Include="ThirdParty\minizip\zip.c">
<Filter>ThirdParty\minizip</Filter>
</ClCompile>
<ClCompile Include="SourceFiles\shortcuts.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SourceFiles\stdafx.h">
@ -1004,6 +1007,9 @@
<ClInclude Include="ThirdParty\minizip\zip.h">
<Filter>ThirdParty\minizip</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\shortcuts.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="SourceFiles\mtproto\mtpConnection.h">