5 |
6 | controlButton::controlButton(QWidget *parent)
7 | : QPushButton(parent)
8 | {
9 | setMouseTracking(true);
10 | }
11 |
12 | bool controlButton::eventFilter(QObject *obj, QEvent *event){
13 | Q_UNUSED(obj);
14 | if(event->type() == QEvent::ToolTip && this->isEnabled()){
15 | return true;
16 | }
17 | return controlButton::eventFilter(obj,event);
18 | }
19 |
20 | void controlButton::mouseMoveEvent(QMouseEvent *e){
21 | if(this->isEnabled()){
22 | QToolTip::showText(this->mapToGlobal(e->localPos().toPoint()),this->toolTip());
23 | }
24 | QPushButton::mouseMoveEvent(e);
25 | }
26 |
--------------------------------------------------------------------------------
/src/slides/1.html:
--------------------------------------------------------------------------------
1 |
2 |
5 | 
6 |
7 | Saves your recent translations history for future references
8 |
--------------------------------------------------------------------------------
/src/slides/4.html:
--------------------------------------------------------------------------------
1 |
2 |
5 | 
6 |
7 | Language switcher button, allows you switch between languages.
8 |
--------------------------------------------------------------------------------
/src/slides/2.html:
--------------------------------------------------------------------------------
1 |
2 |
5 | 
6 |
7 | Line By Line precise translation makes learning & understanding easy
8 |
--------------------------------------------------------------------------------
/src/slides/6.html:
--------------------------------------------------------------------------------
1 |
2 |
5 | 
6 |
7 | Share Translation on social media platforms or Export them to File or Audio.
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # C++ objects and libs
2 | *.slo
3 | *.lo
4 | *.o
5 | *.a
6 | *.la
7 | *.lai
8 | *.so
9 | *.so.*
10 | *.dll
11 | *.dylib
12 |
13 | # Qt-es
14 | object_script.*.Release
15 | object_script.*.Debug
16 | *_plugin_import.cpp
17 | /.qmake.cache
18 | /.qmake.stash
19 | *.pro.user
20 | *.pro.user.*
21 | *.qbs.user
22 | *.qbs.user.*
23 | *.moc
24 | moc_*.cpp
25 | moc_*.h
26 | qrc_*.cpp
27 | ui_*.h
28 | *.qmlc
29 | *.jsc
30 | Makefile*
31 | *build-*
32 | *.qm
33 | *.prl
34 |
35 | # Qt unit tests
36 | target_wrapper.*
37 |
38 | # QtCreator
39 | *.autosave
40 |
41 | # QtCreator Qml
42 | *.qmlproject.user
43 | *.qmlproject.user.*
44 |
45 | # QtCreator CMake
46 | CMakeLists.txt.user*
47 |
48 | # QtCreator 4.8< compilation database
49 | compile_commands.json
50 |
51 | # QtCreator local machine specific files for imported projects
52 | *creator.user*
53 |
--------------------------------------------------------------------------------
/src/translationdownloader.h:
--------------------------------------------------------------------------------
1 | #ifndef TRANSLATIONDOWNLOADER_H
2 | #define TRANSLATIONDOWNLOADER_H
3 |
4 | #include
5 | #include
6 |
7 | class TranslationDownloader : public QObject {
8 | Q_OBJECT
9 | public:
10 | explicit TranslationDownloader(QObject *parent = nullptr,
11 | QList urls = {},
12 | QString translationUUID = "");
13 | QString currentDownloadDir;
14 | signals:
15 | void downloadStarted(QString status);
16 | void downloadFinished(QString status);
17 | void downloadError(QString status);
18 | void downloadComplete();
19 |
20 | public slots:
21 | void start();
22 | private slots:
23 | void startDownload(QUrl url);
24 |
25 | private:
26 | QString _cache_path;
27 | int total = 0;
28 | int current = 0;
29 | QList urls;
30 | };
31 |
32 | #endif // TRANSLATIONDOWNLOADER_H
33 |
--------------------------------------------------------------------------------
/src/slides/7.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 
7 |
8 |
--------------------------------------------------------------------------------
/src/systemtraymanager.h:
--------------------------------------------------------------------------------
1 | #ifndef SYSTEMTRAYMANAGER_H
2 | #define SYSTEMTRAYMANAGER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | class SystemTrayManager : public QObject {
12 | Q_OBJECT
13 | public:
14 | explicit SystemTrayManager(QObject *parent = nullptr);
15 |
16 | ~SystemTrayManager();
17 |
18 | void updateMenu(bool windowVisible);
19 |
20 | signals:
21 | void showWindow();
22 | void hideWindow();
23 |
24 | private:
25 | QSystemTrayIcon *trayIcon = nullptr;
26 | QMenu *m_trayMenu = nullptr;
27 | QAction *m_showAction = nullptr;
28 | QAction *m_hideAction = nullptr;
29 | QAction *m_quitAction = nullptr;
30 |
31 | private slots:
32 | void showMainWindow();
33 |
34 | void hideMainWindow();
35 |
36 | void quitApplication();
37 | };
38 |
39 | #endif // SYSTEMTRAYMANAGER_H
40 |
--------------------------------------------------------------------------------
/src/linebyline.h:
--------------------------------------------------------------------------------
1 | #ifndef LINEBYLINE_H
2 | #define LINEBYLINE_H
3 |
4 | #include
5 | #include
6 |
7 | namespace Ui {
8 | class LineByLine;
9 | }
10 |
11 | class LineByLine : public QWidget {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit LineByLine(QWidget *parent = nullptr,
16 | QClipboard *clipborad = nullptr);
17 | ~LineByLine();
18 |
19 | public slots:
20 | void setData(QList data, QString sLang, QString tLang,
21 | QString tId);
22 | void clearData();
23 | QString getTId();
24 | private slots:
25 | void on_src1_currentRowChanged(int currentRow);
26 |
27 | void on_src2_currentRowChanged(int currentRow);
28 |
29 | void on_copySrc2_clicked();
30 |
31 | void on_copySrc1_clicked();
32 |
33 | private:
34 | Ui::LineByLine *ui;
35 | QString translationId;
36 | QClipboard *clipborad = nullptr;
37 | };
38 |
39 | #endif // LINEBYLINE_H
40 |
--------------------------------------------------------------------------------
/src/history.h:
--------------------------------------------------------------------------------
1 | #ifndef HISTORY_H
2 | #define HISTORY_H
3 |
4 | #include "ui_history_item.h"
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace Ui {
11 | class History;
12 | }
13 |
14 | class History : public QWidget {
15 | Q_OBJECT
16 |
17 | public:
18 | explicit History(QWidget *parent = nullptr);
19 | ~History();
20 |
21 | signals:
22 | void historyItemMeta(QStringList historyItemMeta);
23 | void setTranslationId(QString transId);
24 | public slots:
25 | void loadHistory();
26 | void save(QStringList meta, QString translationId);
27 | void insertItem(QStringList meta, bool fromHistory, QString translationId);
28 | void loadHistoryItem(QString itemPath);
29 |
30 | private slots:
31 | void on_clearall_clicked();
32 | QJsonDocument loadJson(QString fileName);
33 | void saveJson(QJsonDocument document, QString fileName);
34 |
35 | private:
36 | Ui::History *ui;
37 | Ui::history_item history_item_ui;
38 | };
39 |
40 | #endif // HISTORY_H
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Keshav Bhatt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/settings.h:
--------------------------------------------------------------------------------
1 | #ifndef SETTINGS_H
2 | #define SETTINGS_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace Ui {
11 | class Settings;
12 | }
13 |
14 | class Settings : public QWidget {
15 | Q_OBJECT
16 |
17 | public:
18 | explicit Settings(QWidget *parent = nullptr, QHotkey *hotKey = nullptr);
19 | ~Settings();
20 | signals:
21 | void translationRequest(QString selected);
22 | void themeToggled();
23 | public slots:
24 | QKeySequence keySequenceEditKeySequence();
25 | bool quickResultCheckBoxChecked();
26 | private slots:
27 | void get_selected_word_fromX11();
28 | void set_x11_selection();
29 | void show_requested_text();
30 | void setShortcut(const QKeySequence &sequence);
31 |
32 | void readSettings();
33 | void on_github_clicked();
34 |
35 | void on_rate_clicked();
36 |
37 | void on_donate_clicked();
38 |
39 | void on_dark_toggled(bool checked);
40 |
41 | void on_light_toggled(bool checked);
42 |
43 | private:
44 | Ui::Settings *ui;
45 | QSettings settings;
46 | QHotkey *nativeHotkey = nullptr;
47 | QString x11_selected;
48 | };
49 |
50 | #endif // SETTINGS_H
51 |
--------------------------------------------------------------------------------
/src/request.cpp:
--------------------------------------------------------------------------------
1 | #include "request.h"
2 |
3 | Request::Request(QObject *parent) : QObject(parent) {
4 | _cache_path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
5 | }
6 |
7 | Request::~Request() {}
8 |
9 | void Request::get(const QUrl &url) {
10 | QNetworkAccessManager *m_netwManager = new QNetworkAccessManager(this);
11 | QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
12 | diskCache->setCacheDirectory(_cache_path);
13 | m_netwManager->setCache(diskCache);
14 | connect(m_netwManager, &QNetworkAccessManager::finished, this,
15 | [=](QNetworkReply *rep) {
16 | if (rep->error() == QNetworkReply::NoError) {
17 | QString repStr = rep->readAll();
18 | emit requestFinished(repStr);
19 | } else {
20 | emit downloadError(rep->errorString());
21 | }
22 | rep->deleteLater();
23 | m_netwManager->deleteLater();
24 | });
25 |
26 | QNetworkRequest request(url);
27 | m_netwManager->get(request);
28 | emit requestStarted();
29 | }
30 |
31 | void Request::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
32 | double progress = (double)bytesReceived / bytesTotal * 100.0;
33 | int intProgress = static_cast(progress);
34 | emit _downloadProgress(intProgress);
35 | }
36 |
--------------------------------------------------------------------------------
/src/slider.h:
--------------------------------------------------------------------------------
1 | #ifndef SLIDER_H
2 | #define SLIDER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | namespace Ui {
14 | class Slider;
15 | }
16 |
17 | class Slider : public QWidget {
18 | Q_OBJECT
19 |
20 | public:
21 | explicit Slider(QWidget *parent = nullptr);
22 | ~Slider();
23 | public slots:
24 | void start();
25 | void stop();
26 | void reset();
27 | protected slots:
28 | void closeEvent(QCloseEvent *event);
29 | private slots:
30 | void createSlide(QString html, int index);
31 | void loadSlides();
32 | void next();
33 | void prev();
34 | void changeSlide(int index);
35 | void uncheckAllNavBtn();
36 | void on_stop_clicked();
37 | void progressBarUpdate();
38 | void updateStopButton();
39 |
40 | private:
41 | Ui::Slider *ui;
42 | QTimer *timer = nullptr;
43 | QStringList slideData;
44 | int currentIndex;
45 | int total;
46 | int duration;
47 | QPropertyAnimation *animation = nullptr;
48 | bool progressbar;
49 | };
50 |
51 | class Slide : public QLabel {
52 | Q_OBJECT
53 | public:
54 | Slide(QWidget *parent = nullptr) : QLabel(parent) {
55 | this->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
56 | this->setAlignment(Qt::AlignCenter);
57 | }
58 | };
59 |
60 | #endif // SLIDER_H
61 |
--------------------------------------------------------------------------------
/src/elidedlabel.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | // A label that elides its text when not enough geometry is available to show all of the text.
9 | // Currently only capable of one-line.
10 | class ElidedLabel : public QLabel {
11 | Q_OBJECT
12 |
13 | private:
14 | Qt::TextElideMode m_elide_mode;
15 | QString m_cached_elided_text;
16 |
17 |
18 | public:
19 | ElidedLabel(QWidget* parent = NULL, Qt::WindowFlags f = 0);
20 | ElidedLabel(const QString& txt, QWidget* parent = NULL, Qt::WindowFlags f = 0);
21 | ElidedLabel(const QString& txt, Qt::TextElideMode elideMode = Qt::ElideRight, QWidget* parent = NULL, Qt::WindowFlags f = 0);
22 |
23 | public:
24 | // Set the elide mode used for displaying text.
25 | inline void setElideMode(Qt::TextElideMode elideMode) {
26 | m_elide_mode = elideMode;
27 | updateGeometry();
28 | }
29 |
30 | // Get the elide mode currently used to display text.
31 | inline Qt::TextElideMode elideMode() const {
32 | return m_elide_mode;
33 | }
34 |
35 |
36 |
37 | public: // QLabel overrides
38 | void setText(const QString&); // note: not virtual so no polymorphism ...
39 |
40 |
41 | protected: // QLabel overrides
42 | virtual void paintEvent(QPaintEvent*) override;
43 | virtual void resizeEvent(QResizeEvent*) override;
44 |
45 | protected:
46 | // Cache the elided text so as to not recompute it every paint event
47 | void cacheElidedText(int w);
48 |
49 | };
50 |
--------------------------------------------------------------------------------
/src/share.h:
--------------------------------------------------------------------------------
1 | #ifndef SHARE_H
2 | #define SHARE_H
3 |
4 | #include "translationdownloader.h"
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | namespace Ui {
22 | class Share;
23 | }
24 |
25 | class Share : public QWidget {
26 | Q_OBJECT
27 |
28 | public:
29 | explicit Share(QWidget *parent = nullptr);
30 | ~Share();
31 |
32 | public slots:
33 | void setTranslation(QString translation, QString uuid);
34 | private slots:
35 | void on_twitter_clicked();
36 |
37 | void on_facebook_clicked();
38 | void on_text_clicked();
39 | void on_email_clicked();
40 |
41 | QString getFileNameFromString(QString string);
42 |
43 | void showStatus(QString message);
44 | void pastebin_it_finished(int k);
45 | void on_pastebin_clicked();
46 | bool saveFile(QString filename);
47 | void pastebin_it_facebook_finished(int k);
48 | void on_download_clicked();
49 |
50 | void ffmpeg_finished(int k);
51 | void concat(QString currentDownloadDir);
52 |
53 | private:
54 | Ui::Share *ui;
55 | QSettings settings;
56 | QProcess *ffmpeg = nullptr;
57 | QProcess *pastebin_it = nullptr;
58 | QProcess *pastebin_it_facebook = nullptr;
59 | QString translationUUID;
60 | TranslationDownloader *td = nullptr;
61 | QString cacheDirToDelete;
62 | };
63 |
64 | #endif // SHARE_H
65 |
--------------------------------------------------------------------------------
/src/elidedlabel.cpp:
--------------------------------------------------------------------------------
1 | #include "elidedlabel.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | ElidedLabel::ElidedLabel(QWidget* parent, Qt::WindowFlags f)
9 | : QLabel(parent, f), m_elide_mode(Qt::ElideRight) {
10 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
11 | }
12 |
13 | ElidedLabel::ElidedLabel(const QString& txt, QWidget* parent, Qt::WindowFlags f)
14 | : QLabel(txt, parent, f), m_elide_mode(Qt::ElideRight) {
15 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
16 | }
17 |
18 | ElidedLabel::ElidedLabel(const QString& txt, Qt::TextElideMode elideMode, QWidget* parent, Qt::WindowFlags f)
19 | : QLabel(txt, parent, f), m_elide_mode(elideMode) {
20 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
21 |
22 | }
23 |
24 | void ElidedLabel::setText(const QString& txt) {
25 | QLabel::setText(txt);
26 | cacheElidedText(geometry().width());
27 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
28 | }
29 |
30 |
31 | void ElidedLabel::cacheElidedText(int w) {
32 | m_cached_elided_text = fontMetrics().elidedText(text(), m_elide_mode, w, (buddy() == nullptr)? 0 : Qt::TextShowMnemonic);
33 | }
34 |
35 | void ElidedLabel::resizeEvent(QResizeEvent* e) {
36 | QLabel::resizeEvent(e);
37 | cacheElidedText(e->size().width());
38 | }
39 |
40 | void ElidedLabel::paintEvent(QPaintEvent* e) {
41 | if(m_elide_mode == Qt::ElideNone) {
42 | QLabel::paintEvent(e);
43 | } else {
44 | QPainter p(this);
45 | p.drawText(0, 0, geometry().width(), geometry().height(),
46 | QStyle::visualAlignment(text().isRightToLeft()? Qt::RightToLeft : Qt::LeftToRight, alignment()) | ((buddy() == nullptr)? 0 : Qt::TextShowMnemonic),
47 | m_cached_elided_text);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/icons.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | icons/arrow-left-circle-line.png
4 | icons/arrow-right-circle-line.png
5 | icons/disabled-arrow-left-circle-line.png
6 | icons/disabled-arrow-right-circle-line.png
7 | icons/download-line.png
8 | icons/folder-download-line.png
9 | icons/folder-open-line.png
10 | icons/image-2-line.png
11 | icons/links-line.png
12 | icons/map-pin-line.png
13 | icons/paypal-line.png
14 | icons/refresh-line.png
15 | icons/setting-line.png
16 | icons/star-line.png
17 | icons/texture.png
18 | icons/app/icon-64.png
19 | icons/app/icon-128.png
20 | icons/app/icon-256.png
21 | icons/app/icon-512.png
22 | icons/clipboard-line.png
23 | icons/close-fill.png
24 | icons/questionnaire-line.png
25 | icons/swap-box-line.png
26 | icons/volume-up-line.png
27 | icons/archive-drawer-line.png
28 | icons/file-copy-line.png
29 | icons/translate-2.png
30 | icons/magic-line.png
31 | icons/stop-line.png
32 | icons/loader-2-fill.png
33 | icons/facebook-box-line.png
34 | icons/file-text-line.png
35 | icons/mail-add-line.png
36 | icons/twitter-line.png
37 | icons/share-line.png
38 | icons/error-warning-line.png
39 | icons/play-line.png
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/systemtraymanager.cpp:
--------------------------------------------------------------------------------
1 | #include "systemtraymanager.h"
2 | #include
3 |
4 | SystemTrayManager::SystemTrayManager(QObject *parent) : QObject{parent} {
5 | if (QSystemTrayIcon::isSystemTrayAvailable()) {
6 | trayIcon =
7 | new QSystemTrayIcon(QIcon(":/icons/app/icon-64.png"), this->parent());
8 |
9 | m_trayMenu = new QMenu(0);
10 | m_showAction =
11 | new QAction(tr("Show %1").arg(qApp->applicationName()), this);
12 | m_hideAction =
13 | new QAction(tr("Hide %1").arg(qApp->applicationName()), this);
14 | m_quitAction = new QAction(tr("Quit"), this);
15 |
16 | m_trayMenu->addAction(m_showAction);
17 | m_trayMenu->addAction(m_hideAction);
18 | m_trayMenu->addSeparator();
19 | m_trayMenu->addAction(m_quitAction);
20 |
21 | trayIcon->setContextMenu(m_trayMenu);
22 |
23 | connect(m_showAction, &QAction::triggered, this,
24 | &SystemTrayManager::showMainWindow);
25 | connect(m_hideAction, &QAction::triggered, this,
26 | &SystemTrayManager::hideMainWindow);
27 | connect(m_quitAction, &QAction::triggered, this,
28 | &SystemTrayManager::quitApplication);
29 |
30 | trayIcon->show();
31 | } else {
32 | QMessageBox::information(nullptr, "Information",
33 | "Unable to find System tray.");
34 | }
35 | }
36 |
37 | SystemTrayManager::~SystemTrayManager() {
38 | if (trayIcon)
39 | delete trayIcon;
40 | }
41 |
42 | void SystemTrayManager::updateMenu(bool windowVisible) {
43 | if (QSystemTrayIcon::isSystemTrayAvailable()) {
44 | qWarning() << windowVisible;
45 | m_showAction->setEnabled(!windowVisible);
46 | m_hideAction->setEnabled(windowVisible);
47 | }
48 | }
49 |
50 | void SystemTrayManager::showMainWindow() { emit showWindow(); }
51 |
52 | void SystemTrayManager::hideMainWindow() { emit hideWindow(); }
53 |
54 | void SystemTrayManager::quitApplication() { qApp->quit(); }
55 |
--------------------------------------------------------------------------------
/src/QHotkey/qhotkey_p.h:
--------------------------------------------------------------------------------
1 | #ifndef QHOTKEY_P_H
2 | #define QHOTKEY_P_H
3 |
4 | #include "qhotkey.h"
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | class QHOTKEY_SHARED_EXPORT QHotkeyPrivate : public QObject, public QAbstractNativeEventFilter
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | QHotkeyPrivate();//singleton!!!
16 | ~QHotkeyPrivate();
17 |
18 | static QHotkeyPrivate *instance();
19 |
20 | QHotkey::NativeShortcut nativeShortcut(Qt::Key keycode, Qt::KeyboardModifiers modifiers);
21 |
22 | bool addShortcut(QHotkey *hotkey);
23 | bool removeShortcut(QHotkey *hotkey);
24 |
25 | protected:
26 | void activateShortcut(QHotkey::NativeShortcut shortcut);
27 |
28 | virtual quint32 nativeKeycode(Qt::Key keycode, bool &ok) = 0;//platform implement
29 | virtual quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) = 0;//platform implement
30 |
31 | virtual bool registerShortcut(QHotkey::NativeShortcut shortcut) = 0;//platform implement
32 | virtual bool unregisterShortcut(QHotkey::NativeShortcut shortcut) = 0;//platform implement
33 |
34 | private:
35 | QHash, QHotkey::NativeShortcut> mapping;
36 | QMultiHash shortcuts;
37 |
38 | Q_INVOKABLE void addMappingInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers, const QHotkey::NativeShortcut &nativeShortcut);
39 | Q_INVOKABLE bool addShortcutInvoked(QHotkey *hotkey);
40 | Q_INVOKABLE bool removeShortcutInvoked(QHotkey *hotkey);
41 | Q_INVOKABLE QHotkey::NativeShortcut nativeShortcutInvoked(Qt::Key keycode, Qt::KeyboardModifiers modifiers);
42 | };
43 |
44 | #define NATIVE_INSTANCE(ClassName) \
45 | Q_GLOBAL_STATIC(ClassName, hotkeyPrivate) \
46 | \
47 | QHotkeyPrivate *QHotkeyPrivate::instance()\
48 | {\
49 | return hotkeyPrivate;\
50 | }
51 |
52 | Q_DECLARE_METATYPE(Qt::Key)
53 | Q_DECLARE_METATYPE(Qt::KeyboardModifiers)
54 |
55 | #endif // QHOTKEY_P_H
56 |
--------------------------------------------------------------------------------
/src/resources/lang.glate:
--------------------------------------------------------------------------------
1 | Afrikaans<=>af
2 | Albanian<=>sq
3 | Amharic<=>am
4 | Arabic<=>ar
5 | Armenian<=>hy
6 | Azerbaijani<=>az
7 | Basque<=>eu
8 | Belarusian<=>be
9 | Bengali<=>bn
10 | Bosnian<=>bs
11 | Bulgarian<=>bg
12 | Catalan<=>ca
13 | Cebuano<=>ceb
14 | Chinese (Simplified)<=>zh-CN
15 | Chinese (Traditional)<=>zh-TW
16 | Corsican<=>co
17 | Croatian<=>hr
18 | Czech<=>cs
19 | Danish<=>da
20 | Dutch<=>nl
21 | English<=>en
22 | Esperanto<=>eo
23 | Estonian<=>et
24 | Finnish<=>fi
25 | French<=>fr
26 | Frisian<=>fy
27 | Galician<=>gl
28 | Georgian<=>ka
29 | German<=>de
30 | Greek<=>el
31 | Gujarati<=>gu
32 | Haitian Creole<=>ht
33 | Hausa<=>ha
34 | Hawaiian<=>haw
35 | Hebrew<=>he or iw
36 | Hindi<=>hi
37 | Hmong<=>hmn
38 | Hungarian<=>hu
39 | Icelandic<=>is
40 | Igbo<=>ig
41 | Indonesian<=>id
42 | Irish<=>ga
43 | Italian<=>it
44 | Japanese<=>ja
45 | Javanese<=>jv
46 | Kannada<=>kn
47 | Kazakh<=>kk
48 | Khmer<=>km
49 | Korean<=>ko
50 | Kurdish<=>ku
51 | Kyrgyz<=>ky
52 | Lao<=>lo
53 | Latin<=>la
54 | Latvian<=>lv
55 | Lithuanian<=>lt
56 | Luxembourgish<=>lb
57 | Macedonian<=>mk
58 | Malagasy<=>mg
59 | Malay<=>ms
60 | Malayalam<=>ml
61 | Maltese<=>mt
62 | Maori<=>mi
63 | Marathi<=>mr
64 | Mongolian<=>mn
65 | Myanmar (Burmese)<=>my
66 | Nepali<=>ne
67 | Norwegian<=>no
68 | Nyanja (Chichewa)<=>ny
69 | Pashto<=>ps
70 | Persian<=>fa
71 | Polish<=>pl
72 | Portuguese (Portugal, Brazil)<=>pt
73 | Punjabi<=>pa
74 | Romanian<=>ro
75 | Russian<=>ru
76 | Samoan<=>sm
77 | Scots Gaelic<=>gd
78 | Serbian<=>sr
79 | Sesotho<=>st
80 | Shona<=>sn
81 | Sindhi<=>sd
82 | Sinhala (Sinhalese)<=>si
83 | Slovak<=>sk
84 | Slovenian<=>sl
85 | Somali<=>so
86 | Spanish<=>es
87 | Sundanese<=>su
88 | Swahili<=>sw
89 | Swedish<=>sv
90 | Tagalog (Filipino)<=>tl
91 | Tajik<=>tg
92 | Tamil<=>ta
93 | Telugu<=>te
94 | Thai<=>th
95 | Turkish<=>tr
96 | Ukrainian<=>uk
97 | Urdu<=>ur
98 | Uzbek<=>uz
99 | Vietnamese<=>vi
100 | Welsh<=>cy
101 | Xhosa<=>xh
102 | Yiddish<=>yi
103 | Yoruba<=>yo
104 | Zulu<=>zu
105 |
--------------------------------------------------------------------------------
/src/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | class utils : public QObject {
12 | Q_OBJECT
13 |
14 | public:
15 | utils(QObject *parent = 0);
16 | virtual ~utils();
17 | public slots:
18 | static bool splitString(const QString &str, int m, QStringList &list);
19 | static QString refreshCacheSize(const QString cache_dir);
20 | bool delete_cache(const QString cache_dir);
21 | QString toCamelCase(const QString &s);
22 | static QString generateRandomId(int length);
23 | static QString convertSectoDay(qint64 secs);
24 | static QString returnPath(QString pathname);
25 |
26 | static QString EncodeXML(const QString &encodeMe) {
27 |
28 | QString temp;
29 | int length = encodeMe.size();
30 | for (int index = 0; index < length; index++) {
31 | QChar character(encodeMe.at(index));
32 |
33 | switch (character.unicode()) {
34 | case '&':
35 | temp += "&";
36 | break;
37 |
38 | case '\'':
39 | temp += "'";
40 | break;
41 |
42 | case '"':
43 | temp += """;
44 | break;
45 |
46 | case '<':
47 | temp += "<";
48 | break;
49 |
50 | case '>':
51 | temp += ">";
52 | break;
53 |
54 | default:
55 | temp += character;
56 | break;
57 | }
58 | }
59 |
60 | return temp;
61 | }
62 |
63 | static QString DecodeXML(const QString &decodeMe) {
64 |
65 | QString temp(decodeMe);
66 |
67 | temp.replace("&", "&");
68 | temp.replace("'", "'");
69 | temp.replace(""", "\"");
70 | temp.replace("<", "<");
71 | temp.replace(">", ">");
72 |
73 | return temp;
74 | }
75 |
76 | static QString htmlToPlainText(QString str);
77 |
78 | private slots:
79 | // use refreshCacheSize
80 | static quint64 dir_size(const QString &directory);
81 | };
82 |
83 | #endif // UTILS_H
84 |
--------------------------------------------------------------------------------
/src/error.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Error
4 |
5 |
6 |
7 | 0
8 | 0
9 | 526
10 | 312
11 |
12 |
13 |
14 | Form
15 |
16 |
17 | -
18 |
19 |
20 | 14
21 |
22 |
23 | 0
24 |
25 |
-
26 |
27 |
28 |
29 | 0
30 | 0
31 |
32 |
33 |
34 |
35 | 28
36 | 28
37 |
38 |
39 |
40 |
41 |
42 |
43 | :/icons/error-warning-line.png
44 |
45 |
46 | false
47 |
48 |
49 | 3
50 |
51 |
52 |
53 | -
54 |
55 |
56 | -
57 |
58 |
59 |
60 |
61 |
62 | -
63 |
64 |
65 | -
66 |
67 |
-
68 |
69 |
70 | Ok
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/src/slides/0.html:
--------------------------------------------------------------------------------
1 |
2 |
5 | 
6 | Welcome to Glate
7 | Designed and Developed by
8 | Keshav Bhatt
9 | keshavnrj@gmail.com
10 | Donate
11 | Rate in Store
12 | Other Applications
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/linebyline.cpp:
--------------------------------------------------------------------------------
1 | #include "linebyline.h"
2 | #include "ui_linebyline.h"
3 | #include
4 |
5 | LineByLine::LineByLine(QWidget *parent, QClipboard *clipborad)
6 | : QWidget(parent), ui(new Ui::LineByLine) {
7 | ui->setupUi(this);
8 | this->clipborad = clipborad;
9 | connect(ui->src1->verticalScrollBar(), &QScrollBar::valueChanged,
10 | [=](int val) { ui->src2->verticalScrollBar()->setValue(val); });
11 | connect(ui->src2->verticalScrollBar(), &QScrollBar::valueChanged,
12 | [=](int val) { ui->src1->verticalScrollBar()->setValue(val); });
13 | }
14 |
15 | LineByLine::~LineByLine() { delete ui; }
16 |
17 | void LineByLine::setData(QList currentTranslationData,
18 | QString sLang, QString tLang, QString tId) {
19 | translationId = tId;
20 | ui->sLang->setText(sLang);
21 | ui->tLang->setText(tLang);
22 | foreach (QStringList translationFregments, currentTranslationData) {
23 | ui->src2->addItem(translationFregments.at(0)); // translation
24 | ui->src1->addItem(translationFregments.at(1)); // source
25 | }
26 | if (ui->src1->count() > 0)
27 | ui->src1->setCurrentRow(0);
28 | if (ui->src2->count() > 0)
29 | ui->src2->setCurrentRow(0);
30 | }
31 |
32 | void LineByLine::clearData() {
33 | ui->src1->blockSignals(true);
34 | ui->src2->blockSignals(true);
35 |
36 | ui->src1->clear();
37 | ui->src2->clear();
38 |
39 | ui->src1->blockSignals(false);
40 | ui->src2->blockSignals(false);
41 | }
42 |
43 | void LineByLine::on_src1_currentRowChanged(int currentRow) {
44 | ui->src2->blockSignals(true);
45 | ui->src2->setCurrentRow(currentRow);
46 | ui->src2Browser->setText(ui->src2->item(currentRow)->text());
47 | ui->src1Browser->setText(ui->src1->item(currentRow)->text());
48 | ui->src2->blockSignals(false);
49 | }
50 |
51 | void LineByLine::on_src2_currentRowChanged(int currentRow) {
52 | ui->src1->blockSignals(true);
53 | ui->src1->setCurrentRow(currentRow);
54 | ui->src1Browser->setText(ui->src1->item(currentRow)->text());
55 | ui->src2Browser->setText(ui->src2->item(currentRow)->text());
56 | ui->src1->blockSignals(false);
57 | }
58 |
59 | QString LineByLine::getTId() { return translationId; }
60 |
61 | void LineByLine::on_copySrc2_clicked() {
62 | clipborad->setText(ui->src2Browser->toPlainText());
63 | }
64 |
65 | void LineByLine::on_copySrc1_clicked() {
66 | clipborad->setText(ui->src1Browser->toPlainText());
67 | }
68 |
--------------------------------------------------------------------------------
/src/translationdownloader.cpp:
--------------------------------------------------------------------------------
1 | #include "translationdownloader.h"
2 | #include "utils.h"
3 | #include
4 |
5 | /*
6 | Class used to download audio translation of given text
7 | */
8 |
9 | TranslationDownloader::TranslationDownloader(QObject *parent, QList urls,
10 | QString translationUUID)
11 | : QObject(parent) {
12 | // init download dir
13 | currentDownloadDir = utils::returnPath("audioCache/" + translationUUID);
14 | _cache_path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
15 | this->urls = urls;
16 | total = urls.count();
17 | current = -1;
18 | }
19 |
20 | // entry function after class init
21 | void TranslationDownloader::start() {
22 | if (current < total - 1) {
23 | current = current + 1;
24 | } else if (current == total - 1) {
25 | emit downloadComplete();
26 | return;
27 | }
28 | startDownload(urls.at(current));
29 | emit downloadStarted(
30 | "Share: downloading part: " +
31 | QString::number(current + 1) + " of " + QString::number(total));
32 | }
33 |
34 | void TranslationDownloader::startDownload(QUrl url) {
35 | QNetworkAccessManager *m_netwManager = new QNetworkAccessManager(this);
36 | QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
37 | diskCache->setCacheDirectory(_cache_path);
38 | m_netwManager->setCache(diskCache);
39 | connect(m_netwManager, &QNetworkAccessManager::finished,
40 | [=](QNetworkReply *rep) {
41 | if (rep->error() == QNetworkReply::NoError) {
42 | emit downloadFinished(
43 | "Downloaded part: " + QString::number(current + 1) + " of " +
44 | QString::number(total));
45 | // save to file
46 | QFile file(currentDownloadDir + "/" + QString::number(current));
47 | file.open(QIODevice::WriteOnly);
48 | file.write(rep->readAll());
49 | file.close();
50 | start();
51 | } else {
52 | emit downloadError("Share: "
53 | "downloaded error on part: " +
54 | QString::number(current + 1) + " " +
55 | rep->errorString() + " of " +
56 | QString::number(total));
57 | }
58 | rep->deleteLater();
59 | m_netwManager->deleteLater();
60 | });
61 | QNetworkRequest request(url);
62 | m_netwManager->get(request);
63 | }
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Glate - Google Translator and Text To Speech Service on Linux Desktop
4 | Website for "The Glate App" - The Google translator and TTS app for Desktop Linux.
5 |
6 |
7 |
8 |
9 | Galte is a neat, simple yet feature rich, Google Translator and Text to speech synthesizer for Linux Desktop Platform.
10 |
11 | ## Key Features of Glate :
12 |
13 | - Set the preferred source and target language
14 | - Translate between over 104 languages
15 | - Line by Line translation
16 | - Download synthesized speech in mp3 format
17 | - Read Selected text wit Text to speech Engine
18 | - History of text translation for reference
19 | - Export translated History in text(.txt) format
20 | - Translation share option with inbuilt pastebin generator
21 | - HOTKEY to translate text from any website or other Application
22 | - Listen to the pronunciation, Text to Speech
23 | - Dark and Light mode
24 | - Copy and paste the translated text
25 | - Glate will bring many more exciting features in near future, spread the name and the app with your friends, family and colleagues.
26 |
27 | ## Screenshot :
28 | 
29 |
30 | 
31 |
32 |
33 | 
34 |
35 | ## Preview
36 |
37 | [](https://www.youtube.com/watch?v=FxTDqcIgk7g
38 | "Glate - Google translator and text to speech Application for Linux Desktop")
39 |
40 |
41 | ## Install on Linux via snap-store here :
42 | Glate can be installed on all Linux Desktop supporting snapd
43 | Via command line app can be simply installed with following command:
44 |
45 | snap install glate
46 | ### Snapstore Store link:
47 | [](https://snapcraft.io/glate)
48 | [](https://snapcraft.io/glate)
49 |
50 | Version for Windows coming soon... Stay tuned for updates :)
51 |
52 |
53 | ## Credits :
54 | [Alan Pope](https://github.com/popey) of [Canonical](https://github.com/canonical) helped me deciding the name for this Application.
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/glate.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2020-03-26T13:53:21
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui network multimedia
8 |
9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
10 |
11 | include(qhotkey.pri)
12 |
13 | TARGET = glate
14 | TEMPLATE = app
15 |
16 | # The following define makes your compiler emit warnings if you use
17 | # any feature of Qt which has been marked as deprecated (the exact warnings
18 | # depend on your compiler). Please consult the documentation of the
19 | # deprecated API in order to know how to port your code away from it.
20 | DEFINES += QT_DEPRECATED_WARNINGS
21 |
22 | # No debug output in release mode
23 | CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
24 |
25 |
26 | # You can also make your code fail to compile if you use deprecated APIs.
27 | # In order to do so, uncomment the following line.
28 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
29 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
30 |
31 | CONFIG += c++11
32 |
33 | SOURCES += \
34 | controlbutton.cpp \
35 | error.cpp \
36 | history.cpp \
37 | linebyline.cpp \
38 | main.cpp \
39 | mainwindow.cpp \
40 | request.cpp \
41 | settings.cpp \
42 | share.cpp \
43 | slider.cpp \
44 | systemtraymanager.cpp \
45 | translationdownloader.cpp \
46 | utils.cpp \
47 | waitingspinnerwidget.cpp
48 |
49 | HEADERS += \
50 | controlbutton.h \
51 | error.h \
52 | history.h \
53 | linebyline.h \
54 | mainwindow.h \
55 | request.h \
56 | settings.h \
57 | share.h \
58 | slider.h \
59 | systemtraymanager.h \
60 | translationdownloader.h \
61 | utils.h \
62 | waitingspinnerwidget.h
63 |
64 | FORMS += \
65 | error.ui \
66 | history.ui \
67 | history_item.ui \
68 | linebyline.ui \
69 | mainwindow.ui \
70 | settings.ui \
71 | share.ui \
72 | slider.ui \
73 | textoptionform.ui
74 |
75 | # Default rules for deployment.
76 | isEmpty(PREFIX){
77 | PREFIX = /usr
78 | }
79 |
80 | BINDIR = $$PREFIX/bin
81 | DATADIR = $$PREFIX/share
82 |
83 | target.path = $$BINDIR
84 |
85 | icon.files = icons/linguist.png
86 | icon.path = $$DATADIR/icons/hicolor/512x512/apps/
87 |
88 | desktop.files = linguist.desktop
89 | desktop.path = $$DATADIR/applications/
90 |
91 | INSTALLS += target icon desktop
92 |
93 | RESOURCES += \
94 | icons.qrc \
95 | qbreeze.qrc \
96 | resources.qrc \
97 | slides.qrc
98 |
99 | DISTFILES +=
100 |
101 |
--------------------------------------------------------------------------------
/src/history.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | History
4 |
5 |
6 |
7 | 0
8 | 0
9 | 616
10 | 363
11 |
12 |
13 |
14 | Form
15 |
16 |
17 | -
18 |
19 |
20 | 0
21 |
22 |
-
23 |
24 |
25 |
26 | 16
27 |
28 |
29 |
30 | Translation history:
31 |
32 |
33 |
34 | -
35 |
36 |
37 |
38 | 10
39 | true
40 |
41 |
42 |
43 | History holds your 20 recent translations
44 |
45 |
46 |
47 |
48 |
49 | -
50 |
51 |
52 | true
53 |
54 |
55 | QAbstractItemView::ScrollPerPixel
56 |
57 |
58 | QAbstractItemView::ScrollPerPixel
59 |
60 |
61 | QListView::Free
62 |
63 |
64 | true
65 |
66 |
67 |
68 | -
69 |
70 |
71 | 0
72 |
73 |
-
74 |
75 |
76 | Clear All
77 |
78 |
79 |
80 | :/icons/close-fill.png:/icons/close-fill.png
81 |
82 |
83 |
84 | 22
85 | 22
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/src/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "controlbutton.h"
29 | #include "error.h"
30 | #include "history.h"
31 | #include "linebyline.h"
32 | #include "request.h"
33 | #include "settings.h"
34 | #include "share.h"
35 | #include "slider.h"
36 | #include "systemtraymanager.h"
37 | #include "ui_textoptionform.h"
38 | #include "utils.h"
39 | #include "waitingspinnerwidget.h"
40 |
41 | namespace Ui {
42 | class MainWindow;
43 | }
44 |
45 | class MainWindow : public QMainWindow {
46 | Q_OBJECT
47 |
48 | public:
49 | explicit MainWindow(QWidget *parent = nullptr);
50 | ~MainWindow();
51 |
52 | protected slots:
53 | void changeEvent(QEvent *e) override;
54 | void resizeEvent(QResizeEvent *event) override;
55 | void closeEvent(QCloseEvent *event) override;
56 | bool eventFilter(QObject *o, QEvent *e) override;
57 | private slots:
58 |
59 | void on_clear_clicked();
60 | void on_paste_clicked();
61 | void on_switch_lang_clicked();
62 | void on_lang1_currentIndexChanged(int index);
63 | void on_lang2_currentIndexChanged(int index);
64 | void on_play2_clicked();
65 | void on_play1_clicked();
66 | void on_src1_textChanged();
67 | void on_copy_clicked();
68 | void on_src2_textChanged();
69 | void on_share_clicked();
70 | void on_settings_clicked();
71 | void on_history_clicked();
72 | void on_lineByline_clicked();
73 | void on_help_clicked();
74 |
75 | void readLangCode();
76 | void resizeFix();
77 | void translate_clicked();
78 | void init_history();
79 | QString getTransLang();
80 | QString getSourceLang();
81 | void init_settings();
82 | void setStyle(const QString &fname);
83 | void showError(const QString &message);
84 | void textSelectionChanged(QTextEdit *editor);
85 | QString getLangName(const QString &langCode);
86 | QString getLangCode(const QString &langName);
87 | void saveByTransId(const QString &translationId, const QString &reply);
88 | void processTranslation(const QString &reply);
89 |
90 | private:
91 | Ui::MainWindow *ui;
92 | Ui::textOptionForm textOptionForm;
93 |
94 | controlButton *m_translate = nullptr;
95 | WaitingSpinnerWidget *m_loader = nullptr;
96 | Error *m_error = nullptr;
97 | LineByLine *m_lineByLine = nullptr;
98 | Share *m_share = nullptr;
99 | Request *m_request = nullptr;
100 | QMediaPlayer *m_player = nullptr;
101 | QClipboard *m_clipboard = nullptr;
102 | Settings *m_settingsWidget = nullptr;
103 | History *m_historyWidget = nullptr;
104 | QHotkey *m_nativeHotkey = nullptr;
105 | QWidget *m_textOptionWidget = nullptr;
106 | Slider *m_slider = nullptr;
107 | SystemTrayManager *m_trayManager = nullptr;
108 |
109 | QString m_selectedText;
110 | bool m_playSelected = false;
111 | QString m_translationId;
112 | QStringList m_langName, m_langCode, m_supportedTts;
113 | QSettings m_settings;
114 | QList m_currentTranslationData;
115 | };
116 |
117 | #endif // MAINWINDOW_H
118 |
--------------------------------------------------------------------------------
/src/qbreeze.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | dark/up_arrow_disabled.png
4 | dark/Hmovetoolbar.png
5 | dark/stylesheet-branch-end.png
6 | dark/branch_closed-on.png
7 | dark/stylesheet-vline.png
8 | dark/branch_closed.png
9 | dark/branch_open-on.png
10 | dark/transparent.png
11 | dark/right_arrow_disabled.png
12 | dark/sizegrip.png
13 | dark/close.png
14 | dark/close-hover.png
15 | dark/close-pressed.png
16 | dark/down_arrow.png
17 | dark/Vmovetoolbar.png
18 | dark/left_arrow.png
19 | dark/stylesheet-branch-more.png
20 | dark/up_arrow.png
21 | dark/right_arrow.png
22 | dark/left_arrow_disabled.png
23 | dark/Hsepartoolbar.png
24 | dark/branch_open.png
25 | dark/Vsepartoolbar.png
26 | dark/down_arrow_disabled.png
27 | dark/undock.png
28 | dark/checkbox_checked_disabled.png
29 | dark/checkbox_checked_focus.png
30 | dark/checkbox_checked.png
31 | dark/checkbox_indeterminate.png
32 | dark/checkbox_indeterminate_focus.png
33 | dark/checkbox_unchecked_disabled.png
34 | dark/checkbox_unchecked_focus.png
35 | dark/checkbox_unchecked.png
36 | dark/radio_checked_disabled.png
37 | dark/radio_checked_focus.png
38 | dark/radio_checked.png
39 | dark/radio_unchecked_disabled.png
40 | dark/radio_unchecked_focus.png
41 | dark/radio_unchecked.png
42 | light/up_arrow_disabled.png
43 | light/Hmovetoolbar.png
44 | light/stylesheet-branch-end.png
45 | light/branch_closed-on.png
46 | light/stylesheet-vline.png
47 | light/branch_closed.png
48 | light/branch_open-on.png
49 | light/transparent.png
50 | light/right_arrow_disabled.png
51 | light/sizegrip.png
52 | light/close.png
53 | light/close-hover.png
54 | light/close-pressed.png
55 | light/down_arrow.png
56 | light/Vmovetoolbar.png
57 | light/left_arrow.png
58 | light/stylesheet-branch-more.png
59 | light/up_arrow.png
60 | light/right_arrow.png
61 | light/left_arrow_disabled.png
62 | light/Hsepartoolbar.png
63 | light/branch_open.png
64 | light/Vsepartoolbar.png
65 | light/down_arrow_disabled.png
66 | light/undock.png
67 | light/checkbox_checked_disabled.png
68 | light/checkbox_checked_focus.png
69 | light/checkbox_checked.png
70 | light/checkbox_indeterminate.png
71 | light/checkbox_indeterminate_focus.png
72 | light/checkbox_unchecked_disabled.png
73 | light/checkbox_unchecked_focus.png
74 | light/checkbox_unchecked.png
75 | light/radio_checked_disabled.png
76 | light/radio_checked_focus.png
77 | light/radio_checked.png
78 | light/radio_unchecked_disabled.png
79 | light/radio_unchecked_focus.png
80 | light/radio_unchecked.png
81 |
82 |
83 | dark.qss
84 | light.qss
85 |
86 |
87 |
--------------------------------------------------------------------------------
/snap/snapcraft.yaml:
--------------------------------------------------------------------------------
1 | name: glate
2 | version: '3.1'
3 | summary: Google translator for Linux Desktop
4 | description: |
5 | Powerful google tranlator engine based native translation and TTS app for Linux Desktop.
6 |
7 | grade: stable
8 | confinement: strict
9 | icon: snap/gui/icon.png
10 | base: core20
11 | compression: lzo
12 |
13 | architectures:
14 | - build-on: amd64
15 | run-on: amd64
16 |
17 | environment:
18 | SNAP_DESKTOP_RUNTIME: $SNAP/qt515-core20
19 |
20 | package-repositories:
21 | - type: apt
22 | formats: [deb]
23 | components: [main]
24 | suites: [focal]
25 | key-id: C65D51784EDC19A871DBDBB710C56D0DE9977759
26 | url: https://ppa.launchpadcontent.net/beineri/opt-qt-5.15.2-focal/ubuntu
27 |
28 | apps:
29 | glate:
30 | command: bin/desktop-launch $SNAP/usr/bin/glate
31 | environment:
32 | IS_SNAP: 1
33 | QT_QPA_PLATFORMTHEME: gtk3
34 | LANG: en_US.UTF-8 # related whatsie issue 7,21
35 | desktop: usr/share/applications/glate.desktop
36 | plugs:
37 | - desktop
38 | - desktop-legacy
39 | - gsettings
40 | - home
41 | - opengl
42 | - audio-playback
43 | - removable-media
44 | - unity7
45 | - x11
46 | - mount-observe
47 | - network
48 | - network-control
49 | - network-observe
50 | - network-bind
51 | - wayland
52 | plugs:
53 | gtk-3-themes:
54 | interface: content
55 | target: $SNAP/data-dir/themes
56 | default-provider: gtk-common-themes
57 | icon-themes:
58 | interface: content
59 | target: $SNAP/data-dir/icons
60 | default-provider: gtk-common-themes
61 | sound-themes:
62 | interface: content
63 | target: $SNAP/data-dir/sounds
64 | default-provider: gtk-common-themes
65 | qt515-core20:
66 | interface: content
67 | target: $SNAP/qt515-core20
68 | default-provider: qt515-core20
69 |
70 | parts:
71 | build-src:
72 | plugin: nil
73 | source: https://github.com/keshavbhatt/glate.git
74 | source-subdir: src/
75 | override-build: |
76 | snapcraftctl build
77 |
78 | apt install -y build-essential qt515base qt515tools qt515multimedia qt515x11extras qt515xmlpatterns libgl1-mesa-dev
79 |
80 | QT_BASE_DIR=/opt/qt515
81 | export QTDIR=$QT_BASE_DIR
82 | export PATH=$QT_BASE_DIR/bin:$PATH
83 |
84 | if [[ $(uname -m) == "x86_64" ]]; then
85 | export LD_LIBRARY_PATH=$QT_BASE_DIR/lib/x86_64-linux-gnu:$QT_BASE_DIR/lib:${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
86 | else
87 | export LD_LIBRARY_PATH=$QT_BASE_DIR/lib/i386-linux-gnu:$QT_BASE_DIR/lib:${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
88 | fi
89 |
90 | export PKG_CONFIG_PATH=$QT_BASE_DIR/lib/pkgconfig:${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}
91 |
92 | which qmake
93 |
94 | mkdir -p ${SNAPCRAFT_PART_INSTALL}/usr/bin/
95 |
96 | /opt/qt515/bin/qmake src
97 |
98 | make -j4
99 |
100 | /opt/qt515/bin/qmake -install qinstall -exe glate ${SNAPCRAFT_PART_INSTALL}/usr/bin/glate
101 |
102 | strip ${SNAPCRAFT_PART_INSTALL}/usr/bin/glate
103 |
104 |
105 | sed -i 's|Icon=.*|Icon=${SNAP}/meta/gui/icon.png|g' ${SNAPCRAFT_PART_SRC}/src/glate.desktop
106 |
107 | mkdir -p ${SNAPCRAFT_PART_INSTALL}/usr/share/applications/
108 |
109 | cp -rf ${SNAPCRAFT_PART_SRC}/src/glate.desktop ${SNAPCRAFT_PART_INSTALL}/usr/share/applications/glate.desktop
110 |
111 | desktop-launch:
112 | plugin: nil
113 | source: https://github.com/keshavbhatt/qt515-core20.git
114 | after: [build-src]
115 | override-build: |
116 | snapcraftctl build
117 |
118 | mkdir -p ${SNAPCRAFT_PART_INSTALL}/bin/
119 |
120 | cp -rf ${SNAPCRAFT_PART_SRC}/snap_launcher/bin/desktop-launch ${SNAPCRAFT_PART_INSTALL}/bin/
121 |
--------------------------------------------------------------------------------
/src/waitingspinnerwidget.h:
--------------------------------------------------------------------------------
1 | /* Original Work Copyright (c) 2012-2014 Alexander Turkin
2 | Modified 2014 by William Hallatt
3 | Modified 2015 by Jacob Dawid
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of
5 | this software and associated documentation files (the "Software"), to deal in
6 | the Software without restriction, including without limitation the rights to
7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 | the Software, and to permit persons to whom the Software is furnished to do so,
9 | subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 |
22 | #pragma once
23 |
24 | // Qt includes
25 | #include
26 | #include
27 | #include
28 |
29 | class WaitingSpinnerWidget : public QWidget {
30 | Q_OBJECT
31 | public:
32 | /*! Constructor for "standard" widget behaviour - use this
33 | * constructor if you wish to, e.g. embed your widget in another. */
34 | WaitingSpinnerWidget(QWidget *parent = 0, bool centerOnParent = false,
35 | bool disableParentWhenSpinning = false);
36 |
37 | /*! Constructor - use this constructor to automatically create a modal
38 | * ("blocking") spinner on top of the calling widget/window. If a valid
39 | * parent widget is provided, "centreOnParent" will ensure that
40 | * QtWaitingSpinner automatically centres itself on it, if not,
41 | * "centreOnParent" is ignored. */
42 | WaitingSpinnerWidget(Qt::WindowModality modality, QWidget *parent = 0,
43 | bool centerOnParent = true,
44 | bool disableParentWhenSpinning = true);
45 |
46 | public slots:
47 | void start();
48 | void stop();
49 |
50 | public:
51 | void setColor(QColor color);
52 | void setRoundness(qreal roundness);
53 | void setMinimumTrailOpacity(qreal minimumTrailOpacity);
54 | void setTrailFadePercentage(qreal trail);
55 | void setRevolutionsPerSecond(qreal revolutionsPerSecond);
56 | void setNumberOfLines(int lines);
57 | void setLineLength(int length);
58 | void setLineWidth(int width);
59 | void setInnerRadius(int radius);
60 | void setText(QString text);
61 |
62 | QColor color();
63 | qreal roundness();
64 | qreal minimumTrailOpacity();
65 | qreal trailFadePercentage();
66 | qreal revolutionsPersSecond();
67 | int numberOfLines();
68 | int lineLength();
69 | int lineWidth();
70 | int innerRadius();
71 |
72 | bool isSpinning() const;
73 |
74 | private slots:
75 | void rotate();
76 |
77 | protected:
78 | void paintEvent(QPaintEvent *paintEvent);
79 |
80 | private:
81 | static int lineCountDistanceFromPrimary(int current, int primary,
82 | int totalNrOfLines);
83 | static QColor currentLineColor(int distance, int totalNrOfLines,
84 | qreal trailFadePerc, qreal minOpacity,
85 | QColor color);
86 |
87 | void initialize();
88 | void updateSize();
89 | void updateTimer();
90 | void updatePosition();
91 |
92 | private:
93 | QColor _color;
94 | qreal _roundness; // 0..100
95 | qreal _minimumTrailOpacity;
96 | qreal _trailFadePercentage;
97 | qreal _revolutionsPerSecond;
98 | int _numberOfLines;
99 | int _lineLength;
100 | int _lineWidth;
101 | int _innerRadius;
102 |
103 | private:
104 | WaitingSpinnerWidget(const WaitingSpinnerWidget &);
105 | WaitingSpinnerWidget &operator=(const WaitingSpinnerWidget &);
106 |
107 | QTimer *_timer;
108 | bool _centerOnParent;
109 | bool _disableParentWhenSpinning;
110 | int _currentCounter;
111 | bool _isSpinning;
112 | };
113 |
--------------------------------------------------------------------------------
/src/QHotkey/qhotkey.h:
--------------------------------------------------------------------------------
1 | #ifndef QHOTKEY_H
2 | #define QHOTKEY_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #ifdef QHOTKEY_LIB
10 | #ifdef QHOTKEY_LIB_BUILD
11 | #define QHOTKEY_SHARED_EXPORT Q_DECL_EXPORT
12 | #else
13 | #define QHOTKEY_SHARED_EXPORT Q_DECL_IMPORT
14 | #endif
15 | #else
16 | #define QHOTKEY_SHARED_EXPORT
17 | #endif
18 |
19 | //! A class to define global, systemwide Hotkeys
20 | class QHOTKEY_SHARED_EXPORT QHotkey : public QObject
21 | {
22 | Q_OBJECT
23 | friend class QHotkeyPrivate;
24 |
25 | //! Specifies whether this hotkey is currently registered or not
26 | Q_PROPERTY(bool registered READ isRegistered WRITE setRegistered NOTIFY registeredChanged)
27 | //! Holds the shortcut this hotkey will be triggered on
28 | Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut RESET resetShortcut)
29 |
30 | public:
31 | //! Defines shortcut with native keycodes
32 | class QHOTKEY_SHARED_EXPORT NativeShortcut {
33 | public:
34 | //! The native keycode
35 | quint32 key;
36 | //! The native modifiers
37 | quint32 modifier;
38 |
39 | //! Creates an invalid native shortcut
40 | NativeShortcut();
41 | //! Creates a valid native shortcut, with the given key and modifiers
42 | NativeShortcut(quint32 key, quint32 modifier = 0);
43 |
44 | //! Checks, whether this shortcut is valid or not
45 | bool isValid() const;
46 |
47 | //! Equality operator
48 | bool operator ==(const NativeShortcut &other) const;
49 | //! Inequality operator
50 | bool operator !=(const NativeShortcut &other) const;
51 |
52 | private:
53 | bool valid;
54 | };
55 |
56 | static void addGlobalMapping(const QKeySequence &shortcut, const NativeShortcut &nativeShortcut);
57 |
58 | //! Constructor
59 | explicit QHotkey(QObject *parent = Q_NULLPTR);
60 | //! Constructs a hotkey with a shortcut and optionally registers it
61 | explicit QHotkey(const QKeySequence &shortcut, bool autoRegister = false, QObject *parent = Q_NULLPTR);
62 | //! Constructs a hotkey with a key and modifiers and optionally registers it
63 | explicit QHotkey(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister = false, QObject *parent = Q_NULLPTR);
64 | //! Constructs a hotkey from a native shortcut and optionally registers it
65 | explicit QHotkey(const NativeShortcut &shortcut, bool autoRegister = false, QObject *parent = Q_NULLPTR);
66 | //! Destructor
67 | ~QHotkey();
68 |
69 | //! READ-Accessor for QHotkey::registered
70 | bool isRegistered() const;
71 | //! READ-Accessor for QHotkey::shortcut - the key and modifiers as a QKeySequence
72 | QKeySequence shortcut() const;
73 | //! READ-Accessor for QHotkey::shortcut - the key only
74 | Qt::Key keyCode() const;
75 | //! READ-Accessor for QHotkey::shortcut - the modifiers only
76 | Qt::KeyboardModifiers modifiers() const;
77 |
78 | //! Get the current native shortcut
79 | NativeShortcut currentNativeShortcut() const;
80 |
81 | public slots:
82 | //! WRITE-Accessor for QHotkey::registered
83 | bool setRegistered(bool registered);
84 |
85 | //! WRITE-Accessor for QHotkey::shortcut
86 | bool setShortcut(const QKeySequence &shortcut, bool autoRegister = false);
87 | //! WRITE-Accessor for QHotkey::shortcut
88 | bool setShortcut(Qt::Key keyCode, Qt::KeyboardModifiers modifiers, bool autoRegister = false);
89 | //! RESET-Accessor for QHotkey::shortcut
90 | bool resetShortcut();
91 |
92 | //! Set this hotkey to a native shortcut
93 | bool setNativeShortcut(NativeShortcut nativeShortcut, bool autoRegister = false);
94 |
95 | signals:
96 | //! Will be emitted if the shortcut is pressed
97 | void activated(QPrivateSignal);
98 |
99 | //! NOTIFY-Accessor for QHotkey::registered
100 | void registeredChanged(bool registered);
101 |
102 | private:
103 | Qt::Key _keyCode;
104 | Qt::KeyboardModifiers _modifiers;
105 |
106 | NativeShortcut _nativeShortcut;
107 | bool _registered;
108 | };
109 |
110 | uint QHOTKEY_SHARED_EXPORT qHash(const QHotkey::NativeShortcut &key);
111 | uint QHOTKEY_SHARED_EXPORT qHash(const QHotkey::NativeShortcut &key, uint seed);
112 |
113 | QHOTKEY_SHARED_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey)
114 |
115 | Q_DECLARE_METATYPE(QHotkey::NativeShortcut)
116 |
117 | #endif // QHOTKEY_H
118 |
--------------------------------------------------------------------------------
/src/settings.cpp:
--------------------------------------------------------------------------------
1 | #include "settings.h"
2 | #include "ui_settings.h"
3 |
4 | Settings::Settings(QWidget *parent, QHotkey *hotKey)
5 | : QWidget(parent), ui(new Ui::Settings) {
6 | ui->setupUi(this);
7 | this->nativeHotkey = hotKey;
8 | readSettings();
9 | connect(this->nativeHotkey, &QHotkey::activated, this,
10 | &Settings::get_selected_word_fromX11);
11 |
12 | connect(ui->quickResultCheckBox, &QCheckBox::toggled, this->nativeHotkey,
13 | &QHotkey::setRegistered);
14 |
15 | connect(ui->keySequenceEdit, &QKeySequenceEdit::keySequenceChanged, this,
16 | &Settings::setShortcut);
17 |
18 | ui->dark->setChecked(settings.value("theme", "dark").toString() == "dark");
19 | ui->light->setChecked(settings.value("theme").toString() == "light");
20 |
21 | QString aboutTxt =
22 | R"( Glate
23 | Designed and Developed
24 | by Keshav Bhatt
25 | <keshavnrj@gmail.com>
26 | Website: https://ktechpit.com
27 | Runtime: %1
28 | Version: %2
)";
29 |
30 | ui->aboutTextBrowser->setText(
31 | aboutTxt.arg(qVersion(), qApp->applicationVersion()));
32 | }
33 |
34 | Settings::~Settings() { delete ui; }
35 |
36 | void Settings::setShortcut(const QKeySequence &sequence) {
37 | this->nativeHotkey->setShortcut(sequence,
38 | ui->quickResultCheckBox->isChecked());
39 | // save quick trans shortcut instanty
40 | settings.setValue("quicktrans_shortcut", sequence);
41 | }
42 |
43 | void Settings::readSettings() {
44 |
45 | // quick trans settings
46 | if (settings.value("quicktrans").isValid()) {
47 | ui->quickResultCheckBox->setChecked(settings.value("quicktrans").toBool());
48 | } else if (settings.value("quicktrans").isValid()) {
49 | ui->quickResultCheckBox->setChecked(true);
50 | } else {
51 | ui->quickResultCheckBox->setChecked(false);
52 | }
53 | // quick trans key sequence
54 | if (settings.value("quicktrans_shortcut").isValid()) {
55 | QKeySequence k =
56 | QKeySequence(settings.value("quicktrans_shortcut").toString());
57 | ui->keySequenceEdit->setKeySequence(k);
58 | this->nativeHotkey->setShortcut(k.toString(),
59 | settings.value("quicktrans").toBool());
60 | } else {
61 | // default value if value not founds
62 | QKeySequence k = QKeySequence::fromString(tr("Ctrl+Shift+Space"));
63 | ui->keySequenceEdit->setKeySequence(k);
64 | this->nativeHotkey->setShortcut(k.toString(), true);
65 | ui->quickResultCheckBox->setChecked(true);
66 | }
67 | }
68 |
69 | void Settings::get_selected_word_fromX11() {
70 | QProcess *xsel = new QProcess(this);
71 | xsel->setObjectName("xclip");
72 | xsel->start("xclip", QStringList() << "-o"
73 | << "-sel");
74 | connect(xsel, SIGNAL(finished(int)), this, SLOT(set_x11_selection()));
75 | }
76 |
77 | void Settings::set_x11_selection() {
78 | QObject *xselection = this->findChild("xclip");
79 | if (xselection) {
80 | x11_selected = ((QProcess *)(xselection))->readAllStandardOutput();
81 | if (!x11_selected.trimmed().isEmpty())
82 | show_requested_text();
83 |
84 | xselection->deleteLater();
85 | }
86 | }
87 |
88 | void Settings::show_requested_text() { emit translationRequest(x11_selected); }
89 |
90 | bool Settings::quickResultCheckBoxChecked() {
91 | return ui->quickResultCheckBox->isChecked();
92 | }
93 |
94 | QKeySequence Settings::keySequenceEditKeySequence() {
95 | return ui->keySequenceEdit->keySequence();
96 | }
97 |
98 | void Settings::on_github_clicked() {
99 | QDesktopServices::openUrl(QUrl("https://github.com/keshavbhatt/glate"));
100 | }
101 |
102 | void Settings::on_rate_clicked() {
103 | QDesktopServices::openUrl(QUrl("snap://glate"));
104 | }
105 |
106 | void Settings::on_donate_clicked() {
107 | QDesktopServices::openUrl(QUrl("https://paypal.me/keshavnrj/5"));
108 | }
109 |
110 | void Settings::on_dark_toggled(bool checked) {
111 | settings.setValue("theme", checked ? "dark" : "light");
112 | emit themeToggled();
113 | }
114 |
115 | void Settings::on_light_toggled(bool checked) {
116 | settings.setValue("theme", checked ? "light" : "dark");
117 | emit themeToggled();
118 | }
119 |
--------------------------------------------------------------------------------
/src/utils.cpp:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 | #include
3 |
4 | utils::utils(QObject *parent) : QObject(parent) {}
5 |
6 | utils::~utils() {}
7 |
8 | // calculate dir size
9 | quint64 utils::dir_size(const QString &directory) {
10 | quint64 sizex = 0;
11 | QFileInfo str_info(directory);
12 | if (str_info.isDir()) {
13 | QDir dir(directory);
14 | QFileInfoList list =
15 | dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::Hidden |
16 | QDir::NoSymLinks | QDir::NoDotAndDotDot);
17 | for (int i = 0; i < list.size(); ++i) {
18 | QFileInfo fileInfo = list.at(i);
19 | if (fileInfo.isDir()) {
20 | sizex += dir_size(fileInfo.absoluteFilePath());
21 | } else {
22 | sizex += fileInfo.size();
23 | }
24 | }
25 | }
26 | return sizex;
27 | }
28 |
29 | // get the size of cache folder in human readble format
30 | QString utils::refreshCacheSize(const QString cache_dir) {
31 | qint64 cache_size = dir_size(cache_dir);
32 | QString cache_unit;
33 | if (cache_size > 1024 * 1024 * 1024) {
34 | cache_size = cache_size / (1024 * 1024 * 1024);
35 | cache_unit = " GB";
36 | }
37 | if (cache_size > 1024 * 1024) {
38 | cache_size = cache_size / (1024 * 1024);
39 | cache_unit = " MB";
40 | } else if (cache_size > 1024) {
41 | cache_size = cache_size / (1024);
42 | cache_unit = " kB";
43 | } else {
44 | cache_unit = " B";
45 | }
46 | return QString::number(cache_size) + cache_unit;
47 | }
48 |
49 | bool utils::delete_cache(const QString cache_dir) {
50 | bool deleted = QDir(cache_dir).removeRecursively();
51 | QDir(cache_dir).mkpath(cache_dir);
52 | return deleted;
53 | }
54 |
55 | // returns string with first letter capitalized
56 | QString utils::toCamelCase(const QString &s) {
57 | QStringList parts = s.split(' ', QString::SkipEmptyParts);
58 | for (int i = 0; i < parts.size(); ++i)
59 | parts[i].replace(0, 1, parts[i][0].toUpper());
60 | return parts.join(" ");
61 | }
62 |
63 | QString utils::generateRandomId(int length) {
64 |
65 | QDateTime cd = QDateTime::currentDateTime();
66 | const QString possibleCharacters(
67 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" +
68 | QString::number(cd.currentMSecsSinceEpoch())
69 | .remove(QRegExp("[^a-zA-Z\\d\\s]")));
70 | const int randomStringLength = length;
71 | QString randomString;
72 | qsrand(cd.toTime_t());
73 | for (int i = 0; i < randomStringLength; ++i) {
74 | int index = qrand() % possibleCharacters.length();
75 | QChar nextChar = possibleCharacters.at(index);
76 | randomString.append(nextChar);
77 | }
78 | return randomString.trimmed().simplified().remove(" ");
79 | }
80 |
81 | QString utils::convertSectoDay(qint64 secs) {
82 | int day = secs / (24 * 3600);
83 |
84 | secs = secs % (24 * 3600);
85 | int hour = secs / 3600;
86 |
87 | secs %= 3600;
88 | int minutes = secs / 60;
89 |
90 | secs %= 60;
91 | int seconds = secs;
92 |
93 | QString days = QString::number(day) + " " + "days " + QString::number(hour) +
94 | " " + "hours " + QString::number(minutes) + " " + "minutes " +
95 | QString::number(seconds) + " " + "seconds ";
96 | return days;
97 | }
98 |
99 | // static on demand path maker
100 | QString utils::returnPath(QString pathname) {
101 | QString _data_path =
102 | QStandardPaths::writableLocation(QStandardPaths::DataLocation);
103 | if (!QDir(_data_path + "/" + pathname).exists()) {
104 | QDir d(_data_path + "/" + pathname);
105 | d.mkpath(_data_path + "/" + pathname);
106 | }
107 | return _data_path + "/" + pathname + "/";
108 | }
109 |
110 | QString utils::htmlToPlainText(QString str) {
111 | QString out;
112 | QTextDocument text;
113 | text.setHtml(str);
114 | out = text.toPlainText();
115 | text.deleteLater();
116 | return out.replace("\\\"", "'")
117 | .replace("&", "&")
118 | .replace(">", ">")
119 | .replace("<", "<")
120 | .replace("'", "'");
121 | }
122 |
123 | bool utils::splitString(const QString &str, int m, QStringList &list) {
124 | if (m < 1)
125 | return false;
126 | QStringList words = str.split(" ");
127 | while (words.isEmpty() == false) {
128 | QString strPart;
129 | if (QString(words.join(" ")).length() > m) {
130 | for (int i = 0; i < words.count(); i++) {
131 | if (strPart.count() < m) {
132 | strPart.append(words.at(i) + " ");
133 | words.removeAt(i);
134 | --i;
135 | }
136 | }
137 | } else if (QString(words.join(" ")).length() < m) {
138 | strPart.append(words.join(" "));
139 | words.clear();
140 | }
141 | list.append(strPart);
142 | }
143 | return true;
144 | }
145 |
--------------------------------------------------------------------------------
/src/textoptionform.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | textOptionForm
4 |
5 |
6 |
7 | 0
8 | 0
9 | 193
10 | 40
11 |
12 |
13 |
14 | Form
15 |
16 |
17 |
18 | 6
19 |
20 |
21 | 0
22 |
23 |
24 | 0
25 |
26 |
27 | 0
28 |
29 |
30 | 0
31 |
32 | -
33 |
34 |
35 |
36 | 0
37 | 0
38 |
39 |
40 |
41 |
42 | 6
43 |
44 |
45 | 3
46 |
47 |
48 | 6
49 |
50 |
51 | 3
52 |
53 |
54 | 2
55 |
56 |
-
57 |
58 |
59 | 0
60 |
61 |
-
62 |
63 |
64 | border-radius:0px;
65 |
66 |
67 | Read
68 |
69 |
70 |
71 | :/icons/volume-up-line.png:/icons/volume-up-line.png
72 |
73 |
74 |
75 | 22
76 | 22
77 |
78 |
79 |
80 |
81 | -
82 |
83 |
84 | border-radius:0px;
85 | border-left: 0px;
86 |
87 |
88 | Copy
89 |
90 |
91 |
92 | :/icons/file-copy-line.png:/icons/file-copy-line.png
93 |
94 |
95 |
96 | 22
97 | 22
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | -
108 |
109 |
110 |
111 | 0
112 | 0
113 |
114 |
115 |
116 |
117 | 16777215
118 | 2
119 |
120 |
121 |
122 | background-color: rgb(45, 125, 179);
123 |
124 |
125 |
-
126 |
127 |
128 | Qt::Horizontal
129 |
130 |
131 |
132 | 0
133 | 0
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/src/linebyline.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | LineByLine
4 |
5 |
6 |
7 | 0
8 | 0
9 | 625
10 | 341
11 |
12 |
13 |
14 | Form
15 |
16 |
17 | -
18 |
19 |
20 | 0
21 |
22 |
-
23 |
24 |
25 |
26 | 16
27 |
28 |
29 |
30 | Line by Line Translation :
31 |
32 |
33 |
34 |
35 |
36 | -
37 |
38 |
39 | 0
40 |
41 |
-
42 |
43 |
44 | 0
45 |
46 |
-
47 |
48 |
49 | color: rgb(44, 162, 207);
50 |
51 |
52 |
53 |
54 |
55 |
56 | -
57 |
58 |
59 |
60 | 12
61 |
62 |
63 |
64 | Qt::ScrollBarAlwaysOff
65 |
66 |
67 | true
68 |
69 |
70 | Qt::ElideRight
71 |
72 |
73 | QAbstractItemView::ScrollPerPixel
74 |
75 |
76 |
77 | -
78 |
79 |
80 |
81 | 14
82 |
83 |
84 |
85 |
86 | -
87 |
88 |
89 | Copy
90 |
91 |
92 |
93 | :/icons/file-copy-line.png:/icons/file-copy-line.png
94 |
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | 0
103 |
104 |
-
105 |
106 |
107 | color: rgb(44, 162, 207);
108 |
109 |
110 |
111 |
112 |
113 |
114 | -
115 |
116 |
117 |
118 | 12
119 |
120 |
121 |
122 | Qt::ScrollBarAlwaysOff
123 |
124 |
125 | true
126 |
127 |
128 | Qt::ElideRight
129 |
130 |
131 | QAbstractItemView::ScrollPerPixel
132 |
133 |
134 |
135 | -
136 |
137 |
138 |
139 | 14
140 |
141 |
142 |
143 |
144 | -
145 |
146 |
147 | Copy
148 |
149 |
150 |
151 | :/icons/file-copy-line.png:/icons/file-copy-line.png
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/src/slider.cpp:
--------------------------------------------------------------------------------
1 | #include "slider.h"
2 | #include "ui_slider.h"
3 | #include
4 |
5 | Slider::Slider(QWidget *parent) : QWidget(parent), ui(new Ui::Slider) {
6 | ui->setupUi(this);
7 | /* Set Global variables here
8 | * total = total numbers of slides in resource.
9 | * currentIndex = index where the slider will start, this updates with time
10 | * set in timeout progeressbar = show slide timer based progressbar on top.
11 | * duration = duration of slide while auto playback
12 | */
13 | total = 8;
14 | currentIndex = 0;
15 | duration = 10000;
16 | progressbar = false;
17 |
18 | ui->progressBar->setMinimum(0);
19 | ui->progressBar->setMaximum(100);
20 |
21 | if (progressbar == false) {
22 | ui->progressBar->hide();
23 | }
24 |
25 | connect(ui->next, &QAbstractButton::clicked, this, &Slider::next);
26 | connect(ui->prev, &QAbstractButton::clicked, this, &Slider::prev);
27 | connect(ui->skip, &QAbstractButton::clicked, this, &QWidget::close);
28 |
29 | timer = new QTimer(this);
30 | timer->setInterval(duration);
31 | connect(timer, &QTimer::timeout, this, &Slider::next);
32 |
33 | loadSlides();
34 | }
35 |
36 | Slider::~Slider() { delete ui; }
37 |
38 | void Slider::closeEvent(QCloseEvent *event) {
39 | reset();
40 | QWidget::closeEvent(event);
41 | }
42 |
43 | void Slider::start() {
44 | changeSlide(0);
45 | timer->start();
46 | }
47 |
48 | void Slider::loadSlides() {
49 | for (int i = 0; i < total; i++) {
50 | QFile file(":/slides/" + QString::number(i) + ".html");
51 | file.open(QIODevice::ReadOnly);
52 | createSlide(file.readAll(), i);
53 | file.close();
54 | }
55 | }
56 |
57 | void Slider::progressBarUpdate() {
58 | if (progressbar) {
59 | animation = new QPropertyAnimation(ui->progressBar, "value");
60 | animation->setDuration(duration);
61 | animation->setStartValue(ui->progressBar->minimum());
62 | animation->setEndValue(ui->progressBar->maximum());
63 | animation->start(QPropertyAnimation::DeleteWhenStopped);
64 | }
65 | }
66 |
67 | void Slider::stop() {
68 | timer->stop();
69 | updateStopButton();
70 | progressBarUpdate();
71 | if (animation != nullptr) {
72 | animation->stop();
73 | }
74 | }
75 |
76 | void Slider::reset() {
77 | currentIndex = 0;
78 | changeSlide(currentIndex);
79 | stop();
80 | }
81 |
82 | void Slider::updateStopButton() {
83 | if (timer->isActive()) {
84 | ui->stop->setToolTip("Stop");
85 | ui->stop->setIcon(QIcon(":/icons/stop-line.png"));
86 | }
87 | if (timer->isActive() == false) {
88 | ui->stop->setToolTip("Play");
89 | ui->stop->setIcon(QIcon(":/icons/play-line.png"));
90 | }
91 | }
92 |
93 | void Slider::next() {
94 | timer->stop();
95 | if (currentIndex >= total - 1) {
96 | stop();
97 | } else {
98 | changeSlide(++currentIndex);
99 | timer->start();
100 | }
101 | updateStopButton();
102 | }
103 |
104 | void Slider::prev() {
105 | timer->stop();
106 | if (currentIndex == 0) {
107 | currentIndex = total - 1;
108 | changeSlide(currentIndex);
109 | } else {
110 | changeSlide(--currentIndex);
111 | timer->start();
112 | }
113 | updateStopButton();
114 | }
115 |
116 | void Slider::changeSlide(int index) {
117 |
118 | // hide all in view
119 | for (int i = 0; i < ui->view->count(); ++i) {
120 | QWidget *widget = ui->view->itemAt(i)->widget();
121 | if (widget != NULL) {
122 | widget->setVisible(false);
123 | }
124 | }
125 | // show requested slide
126 | Slide *slide = this->findChild("slide_" + QString::number(index));
127 | ui->view->addWidget(slide);
128 | slide->show();
129 | uncheckAllNavBtn();
130 | QPushButton *navBtn =
131 | this->findChild("navBtn_" + QString::number(index));
132 | navBtn->setChecked(true);
133 | progressBarUpdate();
134 | }
135 |
136 | void Slider::createSlide(QString html, int index) {
137 | Slide *slide = new Slide(this);
138 | slide->setObjectName("slide_" + QString::number(index));
139 | slide->hide();
140 | slide->setText(html);
141 | connect(slide, &Slide::linkActivated, this, [=](QString link) {
142 | if (link == "start") {
143 | this->close();
144 | } else {
145 | QDesktopServices::openUrl(QUrl(link));
146 | }
147 | });
148 | // make button without name
149 | QPushButton *navBtn = new QPushButton("", this);
150 | navBtn->setCheckable(true);
151 | navBtn->setFixedSize(12, 12);
152 | // uncomment to make buttons circular
153 | navBtn->setStyleSheet("border-radius:" +
154 | QString::number(navBtn->width() / 2));
155 | navBtn->setObjectName("navBtn_" + QString::number(index));
156 | connect(navBtn, &QPushButton::clicked, this, [=]() {
157 | uncheckAllNavBtn();
158 | navBtn->setChecked(true);
159 | changeSlide(index);
160 | currentIndex = index;
161 | stop(); // stop auto slider if user clicks button to navigate
162 | });
163 | ui->navDots->addWidget(navBtn);
164 | }
165 |
166 | void Slider::uncheckAllNavBtn() {
167 | foreach (QPushButton *btn, this->findChildren()) {
168 | btn->setChecked(false);
169 | }
170 | }
171 |
172 | void Slider::on_stop_clicked() {
173 | if (timer->isActive()) {
174 | if (animation != nullptr) {
175 | animation->stop();
176 | }
177 | timer->stop();
178 | } else if (timer->isActive() == false) {
179 | progressBarUpdate();
180 | timer->start();
181 | }
182 | updateStopButton();
183 | }
184 |
--------------------------------------------------------------------------------
/src/history.cpp:
--------------------------------------------------------------------------------
1 | #include "history.h"
2 | #include "ui_history.h"
3 | #include "utils.h"
4 | #include
5 | #include
6 |
7 | History::History(QWidget *parent) : QWidget(parent), ui(new Ui::History) {
8 | ui->setupUi(this);
9 | ui->historyList->setSelectionRectVisible(true);
10 | ui->historyList->setAlternatingRowColors(true);
11 | ui->historyList->setDragEnabled(false);
12 | ui->historyList->setDropIndicatorShown(false);
13 | ui->historyList->setDragDropMode(QAbstractItemView::NoDragDrop);
14 | }
15 |
16 | History::~History() { delete ui; }
17 |
18 | void History::on_clearall_clicked() {
19 | QDir dir(utils::returnPath("history"));
20 | if (dir.removeRecursively()) {
21 | ui->historyList->clear();
22 | ui->clearall->setEnabled(false);
23 | }
24 | }
25 |
26 | void History::insertItem(QStringList meta, bool fromHistory,
27 | QString translationId) {
28 | QWidget *histWid = new QWidget();
29 | if (meta.count() >= 5) {
30 | QString from, to, src1, src2, date;
31 | from = meta.at(0);
32 | to = meta.at(1);
33 | src1 = meta.at(2);
34 | src2 = meta.at(3);
35 | date = meta.at(4);
36 | history_item_ui.setupUi(histWid);
37 | histWid->setObjectName("widget_" + translationId);
38 | histWid->setStyleSheet("QWidget#widget_" + translationId +
39 | "{background: transparent;}");
40 | history_item_ui.remove->setObjectName("remove_" + translationId);
41 | history_item_ui.load->setObjectName("load_" + translationId);
42 | connect(history_item_ui.remove, &QPushButton::clicked, [=]() {
43 | QFile file(utils::returnPath("history") + "/" + translationId + ".json");
44 | if (file.remove()) {
45 | loadHistory();
46 | }
47 | });
48 |
49 | connect(history_item_ui.load, &QPushButton::clicked, [=]() {
50 | emit setTranslationId(translationId);
51 | loadHistoryItem(utils::returnPath("history") + "/" + translationId +
52 | ".json");
53 | });
54 | history_item_ui.time->setText(date);
55 | history_item_ui.from->setText(from);
56 | history_item_ui.to->setText(to);
57 | history_item_ui.src1->setText(src1.left(100) + "....");
58 | history_item_ui.src2->setText(src2.left(100) + "....");
59 | QListWidgetItem *item;
60 | item = new QListWidgetItem(ui->historyList);
61 | ui->historyList->setItemWidget(item, histWid);
62 | item->setSizeHint(histWid->minimumSizeHint());
63 | this->setMinimumWidth(histWid->width() + 60);
64 | ui->historyList->addItem(item);
65 | ui->clearall->setEnabled(true);
66 | if (!fromHistory) {
67 | save(meta, translationId);
68 | }
69 | }
70 | }
71 |
72 | void History::loadHistoryItem(QString itemPath) {
73 | QFile file(itemPath);
74 | if (file.exists()) {
75 | // open file , read it to stringlist pass it to insertItem
76 | QJsonDocument doc = loadJson(itemPath);
77 | QJsonObject jsonObject = doc.object();
78 | QString from, to, src1, src2, date;
79 | from = jsonObject.value("from").toString();
80 | to = jsonObject.value("to").toString();
81 | src1 = jsonObject.value("src1").toString();
82 | src2 = jsonObject.value("src2").toString();
83 | date = jsonObject.value("date").toString();
84 | emit historyItemMeta(QStringList() << from << to << src1 << src2);
85 | }
86 | file.deleteLater();
87 | }
88 |
89 | void History::save(QStringList meta, QString translationId) {
90 | if (meta.count() >= 5) {
91 | QString from, to, src1, src2, date;
92 | from = meta.at(0);
93 | to = meta.at(1);
94 | src1 = meta.at(2);
95 | src2 = meta.at(3);
96 | date = meta.at(4);
97 | QString history_file_path =
98 | utils::returnPath("history") + "/" + translationId + ".json";
99 | QVariantMap map;
100 | map.insert("date", date);
101 | map.insert("from", from);
102 | map.insert("to", to);
103 | map.insert("src1", src1);
104 | map.insert("src2", src2);
105 | QJsonObject object = QJsonObject::fromVariantMap(map);
106 | QJsonDocument document;
107 | document.setObject(object);
108 | saveJson(document, history_file_path);
109 | }
110 | }
111 |
112 | QJsonDocument History::loadJson(QString fileName) {
113 | QFile jsonFile(fileName);
114 | jsonFile.open(QFile::ReadOnly);
115 | QByteArray data = jsonFile.readAll();
116 | jsonFile.close();
117 | return QJsonDocument().fromJson(data);
118 | }
119 |
120 | void History::saveJson(QJsonDocument document, QString fileName) {
121 | QFile jsonFile(fileName);
122 | jsonFile.open(QFile::WriteOnly);
123 | jsonFile.write(document.toJson());
124 | jsonFile.close();
125 | }
126 |
127 | void History::loadHistory() {
128 | ui->historyList->clear();
129 | QString history_path = utils::returnPath("history");
130 | QDir dir(history_path);
131 | dir.setSorting(QDir::Time);
132 | QStringList filter;
133 | filter << +"*.json";
134 | QFileInfoList files = dir.entryInfoList(filter);
135 | ui->clearall->setEnabled(files.isEmpty() == false);
136 | foreach (QFileInfo fileInfo, files) {
137 | // open file , read it to stringlist pass it to insertItem
138 | QJsonDocument doc = loadJson(fileInfo.filePath());
139 | QJsonObject jsonObject = doc.object();
140 | QString from, to, src1, src2, date;
141 | from = jsonObject.value("from").toString();
142 | to = jsonObject.value("to").toString();
143 | src1 = jsonObject.value("src1").toString();
144 | src2 = jsonObject.value("src2").toString();
145 | date = jsonObject.value("date").toString();
146 | insertItem(QStringList()
147 | << from << to << src1.left(100) << src2.left(100) << date,
148 | true, fileInfo.baseName());
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/share.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Share
4 |
5 |
6 |
7 | 0
8 | 0
9 | 399
10 | 249
11 |
12 |
13 |
14 | Form
15 |
16 |
17 | -
18 |
19 |
20 | Text to be shared:
21 |
22 |
23 |
24 | -
25 |
26 |
27 | -
28 |
29 |
-
30 |
31 |
32 | Share on Twitter
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | :/icons/twitter-line.png:/icons/twitter-line.png
43 |
44 |
45 |
46 | 32
47 | 32
48 |
49 |
50 |
51 |
52 | -
53 |
54 |
55 | Share on Facebook
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | :/icons/facebook-box-line.png:/icons/facebook-box-line.png
66 |
67 |
68 |
69 | 32
70 | 32
71 |
72 |
73 |
74 |
75 | -
76 |
77 |
78 | Share via Email
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | :/icons/mail-add-line.png:/icons/mail-add-line.png
89 |
90 |
91 |
92 | 32
93 | 32
94 |
95 |
96 |
97 |
98 | -
99 |
100 |
101 | Get PasteBin Url
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | :/icons/clipboard-line.png:/icons/clipboard-line.png
112 |
113 |
114 |
115 | 32
116 | 32
117 |
118 |
119 |
120 |
121 | -
122 |
123 |
124 |
125 | 1
126 | 16777215
127 |
128 |
129 |
130 | background-color: rgb(45, 125, 179);
131 | border:none;
132 |
133 |
134 | Qt::Vertical
135 |
136 |
137 |
138 | -
139 |
140 |
141 | Download as audio
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | :/icons/download-line.png:/icons/download-line.png
152 |
153 |
154 |
155 | 32
156 | 32
157 |
158 |
159 |
160 |
161 | -
162 |
163 |
164 | Export to text file
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 | :/icons/file-text-line.png:/icons/file-text-line.png
175 |
176 |
177 |
178 | 32
179 | 32
180 |
181 |
182 |
183 |
184 |
185 |
186 | -
187 |
188 |
189 | Status:
190 |
191 |
192 |
193 | -
194 |
195 |
196 | true
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
--------------------------------------------------------------------------------
/src/QHotkey/qhotkey_x11.cpp:
--------------------------------------------------------------------------------
1 | #include "qhotkey.h"
2 | #include "qhotkey_p.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | //compability to pre Qt 5.8
10 | #ifndef Q_FALLTHROUGH
11 | #define Q_FALLTHROUGH() (void)0
12 | #endif
13 |
14 | class QHotkeyPrivateX11 : public QHotkeyPrivate
15 | {
16 | public:
17 | // QAbstractNativeEventFilter interface
18 | bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
19 |
20 | protected:
21 | // QHotkeyPrivate interface
22 | quint32 nativeKeycode(Qt::Key keycode, bool &ok) Q_DECL_OVERRIDE;
23 | quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) Q_DECL_OVERRIDE;
24 | QString getX11String(Qt::Key keycode);
25 | bool registerShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE;
26 | bool unregisterShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE;
27 |
28 | private:
29 | static const QVector specialModifiers;
30 | static const quint32 validModsMask;
31 |
32 | static QString formatX11Error(Display *display, int errorCode);
33 |
34 | class HotkeyErrorHandler {
35 | public:
36 | HotkeyErrorHandler();
37 | ~HotkeyErrorHandler();
38 |
39 | static bool hasError;
40 | static QString errorString;
41 |
42 | private:
43 | XErrorHandler prevHandler;
44 |
45 | static int handleError(Display *display, XErrorEvent *error);
46 | };
47 | };
48 | NATIVE_INSTANCE(QHotkeyPrivateX11)
49 |
50 | const QVector QHotkeyPrivateX11::specialModifiers = {0, Mod2Mask, LockMask, (Mod2Mask | LockMask)};
51 | const quint32 QHotkeyPrivateX11::validModsMask = ShiftMask | ControlMask | Mod1Mask | Mod4Mask;
52 |
53 | bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
54 | {
55 | Q_UNUSED(eventType);
56 | Q_UNUSED(result);
57 |
58 | xcb_generic_event_t *genericEvent = static_cast(message);
59 | if (genericEvent->response_type == XCB_KEY_PRESS) {
60 | xcb_key_press_event_t *keyEvent = static_cast(message);
61 | this->activateShortcut({keyEvent->detail, keyEvent->state & QHotkeyPrivateX11::validModsMask});
62 | }
63 |
64 | return false;
65 | }
66 |
67 | QString QHotkeyPrivateX11::getX11String(Qt::Key keycode)
68 | {
69 | switch(keycode){
70 |
71 | case Qt::Key_MediaLast :
72 | case Qt::Key_MediaPrevious :
73 | return "XF86AudioPrev";
74 | case Qt::Key_MediaNext :
75 | return "XF86AudioNext";
76 | case Qt::Key_MediaPause :
77 | case Qt::Key_MediaPlay :
78 | case Qt::Key_MediaTogglePlayPause :
79 | return "XF86AudioPlay";
80 | case Qt::Key_MediaRecord :
81 | return "XF86AudioRecord";
82 | case Qt::Key_MediaStop :
83 | return "XF86AudioStop";
84 | default :
85 | return QKeySequence(keycode).toString(QKeySequence::NativeText);
86 | }
87 | }
88 |
89 | quint32 QHotkeyPrivateX11::nativeKeycode(Qt::Key keycode, bool &ok)
90 | {
91 | QString keyString = getX11String(keycode);
92 |
93 | KeySym keysym = XStringToKeysym(keyString.toLatin1().constData());
94 | if (keysym == NoSymbol) {
95 | //not found -> just use the key
96 | if(keycode <= 0xFFFF)
97 | keysym = keycode;
98 | else
99 | return 0;
100 | }
101 |
102 | Display *display = QX11Info::display();
103 | if(display) {
104 | auto res = XKeysymToKeycode(QX11Info::display(), keysym);
105 | if(res != 0)
106 | ok = true;
107 | return res;
108 | } else
109 | return 0;
110 | }
111 |
112 | quint32 QHotkeyPrivateX11::nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok)
113 | {
114 | quint32 nMods = 0;
115 | if (modifiers & Qt::ShiftModifier)
116 | nMods |= ShiftMask;
117 | if (modifiers & Qt::ControlModifier)
118 | nMods |= ControlMask;
119 | if (modifiers & Qt::AltModifier)
120 | nMods |= Mod1Mask;
121 | if (modifiers & Qt::MetaModifier)
122 | nMods |= Mod4Mask;
123 | ok = true;
124 | return nMods;
125 | }
126 |
127 | bool QHotkeyPrivateX11::registerShortcut(QHotkey::NativeShortcut shortcut)
128 | {
129 | Display *display = QX11Info::display();
130 | if(!display)
131 | return false;
132 |
133 | HotkeyErrorHandler errorHandler;
134 | for(quint32 specialMod : QHotkeyPrivateX11::specialModifiers) {
135 | XGrabKey(display,
136 | shortcut.key,
137 | shortcut.modifier | specialMod,
138 | DefaultRootWindow(display),
139 | True,
140 | GrabModeAsync,
141 | GrabModeAsync);
142 | }
143 | XSync(display, False);
144 |
145 | if(errorHandler.hasError) {
146 | qCWarning(logQHotkey) << "Failed to register hotkey. Error:"
147 | << qPrintable(errorHandler.errorString);
148 | this->unregisterShortcut(shortcut);
149 | return false;
150 | } else
151 | return true;
152 | }
153 |
154 | bool QHotkeyPrivateX11::unregisterShortcut(QHotkey::NativeShortcut shortcut)
155 | {
156 | Display *display = QX11Info::display();
157 | if(!display)
158 | return false;
159 |
160 | HotkeyErrorHandler errorHandler;
161 | for(quint32 specialMod : QHotkeyPrivateX11::specialModifiers) {
162 | XUngrabKey(display,
163 | shortcut.key,
164 | shortcut.modifier | specialMod,
165 | DefaultRootWindow(display));
166 | }
167 | XSync(display, False);
168 |
169 | if(errorHandler.hasError) {
170 | qCWarning(logQHotkey) << "Failed to unregister hotkey. Error:"
171 | << qPrintable(errorHandler.errorString);
172 | return false;
173 | } else
174 | return true;
175 | }
176 |
177 | QString QHotkeyPrivateX11::formatX11Error(Display *display, int errorCode)
178 | {
179 | char errStr[256];
180 | XGetErrorText(display, errorCode, errStr, 256);
181 | return QString::fromLatin1(errStr);
182 | }
183 |
184 |
185 |
186 | // ---------- QHotkeyPrivateX11::HotkeyErrorHandler implementation ----------
187 |
188 | bool QHotkeyPrivateX11::HotkeyErrorHandler::hasError = false;
189 | QString QHotkeyPrivateX11::HotkeyErrorHandler::errorString;
190 |
191 | QHotkeyPrivateX11::HotkeyErrorHandler::HotkeyErrorHandler()
192 | {
193 | prevHandler = XSetErrorHandler(&HotkeyErrorHandler::handleError);
194 | }
195 |
196 | QHotkeyPrivateX11::HotkeyErrorHandler::~HotkeyErrorHandler()
197 | {
198 | XSetErrorHandler(prevHandler);
199 | hasError = false;
200 | errorString.clear();
201 | }
202 |
203 | int QHotkeyPrivateX11::HotkeyErrorHandler::handleError(Display *display, XErrorEvent *error)
204 | {
205 | switch (error->error_code) {
206 | case BadAccess:
207 | case BadValue:
208 | case BadWindow:
209 | if (error->request_code == 33 || //grab key
210 | error->request_code == 34) {// ungrab key
211 | hasError = true;
212 | errorString = QHotkeyPrivateX11::formatX11Error(display, error->error_code);
213 | return 1;
214 | }
215 | Q_FALLTHROUGH();
216 | // fall through
217 | default:
218 | return 0;
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/src/settings.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Settings
4 |
5 |
6 |
7 | 0
8 | 0
9 | 523
10 | 457
11 |
12 |
13 |
14 | Form
15 |
16 |
17 | -
18 |
19 |
20 | App Settings
21 |
22 |
23 |
-
24 |
25 |
26 | 7
27 |
28 |
29 | 7
30 |
31 |
-
32 |
33 |
34 | Open translator from anywhere on system
35 |
36 |
37 | Quick Translate
38 |
39 |
40 |
41 | -
42 |
43 |
44 | Theme
45 |
46 |
47 |
48 | -
49 |
50 |
51 | -
52 |
53 |
-
54 |
55 |
56 | Dark
57 |
58 |
59 |
60 | -
61 |
62 |
63 | Light
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | -
75 |
76 |
77 | About
78 |
79 |
80 |
-
81 |
82 |
-
83 |
84 |
85 |
86 | 0
87 | 215
88 |
89 |
90 |
91 | QAbstractScrollArea::AdjustToContents
92 |
93 |
94 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
95 | <html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
96 | p, li { white-space: pre-wrap; }
97 | hr { height: 1px; border-width: 0; }
98 | li.unchecked::marker { content: "\2610"; }
99 | li.checked::marker { content: "\2612"; }
100 | </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
101 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html>
102 |
103 |
104 |
105 | -
106 |
107 |
108 | 0
109 |
110 |
-
111 |
112 |
113 | Donate via Paypal
114 |
115 |
116 | Donate
117 |
118 |
119 |
120 | :/icons/paypal-line.png:/icons/paypal-line.png
121 |
122 |
123 |
124 | 22
125 | 22
126 |
127 |
128 |
129 |
130 | -
131 |
132 |
133 | Star repository on github
134 |
135 |
136 | Github
137 |
138 |
139 |
140 | :/icons/links-line.png:/icons/links-line.png
141 |
142 |
143 |
144 | 22
145 | 22
146 |
147 |
148 |
149 |
150 | -
151 |
152 |
153 | Rate this app in Software App
154 |
155 |
156 | Rate
157 |
158 |
159 |
160 | :/icons/star-line.png:/icons/star-line.png
161 |
162 |
163 |
164 | 22
165 | 22
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | controlButton
182 | QPushButton
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
--------------------------------------------------------------------------------
/src/history_item.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | history_item
4 |
5 |
6 |
7 | 0
8 | 0
9 | 519
10 | 150
11 |
12 |
13 |
14 | Form
15 |
16 |
17 | QWidget#history_item{
18 | background: transparent;
19 | }
20 |
21 |
22 |
23 | 0
24 |
25 |
26 | 5
27 |
28 |
29 | 0
30 |
31 |
32 | 5
33 |
34 | -
35 |
36 |
37 |
-
38 |
39 |
40 |
41 | 0
42 | 0
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 | -
51 |
52 |
53 | 10
54 |
55 |
56 | 2
57 |
58 |
-
59 |
60 |
61 |
62 | 0
63 | 0
64 |
65 |
66 |
67 |
68 | 180
69 | 80
70 |
71 |
72 |
73 | -
74 |
75 |
76 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
77 |
78 |
79 | true
80 |
81 |
82 |
83 | -
84 |
85 |
86 |
87 | 0
88 | 0
89 |
90 |
91 |
92 |
93 | 12
94 |
95 |
96 |
97 | color: rgb(44, 162, 207);
98 |
99 |
100 | from
101 |
102 |
103 |
104 | -
105 |
106 |
107 |
108 | 0
109 | 0
110 |
111 |
112 |
113 |
114 | 180
115 | 80
116 |
117 |
118 |
119 | -
120 |
121 |
122 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
123 |
124 |
125 | true
126 |
127 |
128 |
129 | -
130 |
131 |
132 |
133 | 0
134 | 0
135 |
136 |
137 |
138 |
139 | 12
140 |
141 |
142 |
143 | color: rgb(44, 162, 207);
144 |
145 |
146 | to
147 |
148 |
149 |
150 | -
151 |
152 |
153 |
154 | 0
155 | 0
156 |
157 |
158 |
159 | Load translation
160 |
161 |
162 |
163 | :/icons/translate-2.png:/icons/translate-2.png
164 |
165 |
166 |
167 | 16
168 | 16
169 |
170 |
171 |
172 |
173 | -
174 |
175 |
176 |
177 | 0
178 | 0
179 |
180 |
181 |
182 | Remove
183 |
184 |
185 |
186 | :/icons/close-fill.png:/icons/close-fill.png
187 |
188 |
189 |
190 | 16
191 | 16
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
--------------------------------------------------------------------------------
/src/QHotkey/qhotkey_win.cpp:
--------------------------------------------------------------------------------
1 | #include "qhotkey.h"
2 | #include "qhotkey_p.h"
3 | #include
4 | #include
5 |
6 | #define HKEY_ID(nativeShortcut) (((nativeShortcut.key ^ (nativeShortcut.modifier << 8)) & 0x0FFF) | 0x7000)
7 |
8 | class QHotkeyPrivateWin : public QHotkeyPrivate
9 | {
10 | public:
11 | // QAbstractNativeEventFilter interface
12 | bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
13 |
14 | protected:
15 | // QHotkeyPrivate interface
16 | quint32 nativeKeycode(Qt::Key keycode, bool &ok) Q_DECL_OVERRIDE;
17 | quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok) Q_DECL_OVERRIDE;
18 | bool registerShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE;
19 | bool unregisterShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE;
20 |
21 | private:
22 | static QString formatWinError(DWORD winError);
23 | };
24 | NATIVE_INSTANCE(QHotkeyPrivateWin)
25 |
26 | bool QHotkeyPrivateWin::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
27 | {
28 | Q_UNUSED(eventType);
29 | Q_UNUSED(result);
30 |
31 | MSG* msg = static_cast(message);
32 | if(msg->message == WM_HOTKEY)
33 | this->activateShortcut({HIWORD(msg->lParam), LOWORD(msg->lParam)});
34 |
35 | return false;
36 | }
37 |
38 | quint32 QHotkeyPrivateWin::nativeKeycode(Qt::Key keycode, bool &ok)
39 | {
40 | ok = true;
41 | if(keycode <= 0xFFFF) {//Try to obtain the key from it's "character"
42 | const SHORT vKey = VkKeyScanW(keycode);
43 | if(vKey > -1)
44 | return LOBYTE(vKey);
45 | }
46 |
47 | //find key from switch/case --> Only finds a very small subset of keys
48 | switch (keycode)
49 | {
50 | case Qt::Key_Escape:
51 | return VK_ESCAPE;
52 | case Qt::Key_Tab:
53 | case Qt::Key_Backtab:
54 | return VK_TAB;
55 | case Qt::Key_Backspace:
56 | return VK_BACK;
57 | case Qt::Key_Return:
58 | case Qt::Key_Enter:
59 | return VK_RETURN;
60 | case Qt::Key_Insert:
61 | return VK_INSERT;
62 | case Qt::Key_Delete:
63 | return VK_DELETE;
64 | case Qt::Key_Pause:
65 | return VK_PAUSE;
66 | case Qt::Key_Print:
67 | return VK_PRINT;
68 | case Qt::Key_Clear:
69 | return VK_CLEAR;
70 | case Qt::Key_Home:
71 | return VK_HOME;
72 | case Qt::Key_End:
73 | return VK_END;
74 | case Qt::Key_Left:
75 | return VK_LEFT;
76 | case Qt::Key_Up:
77 | return VK_UP;
78 | case Qt::Key_Right:
79 | return VK_RIGHT;
80 | case Qt::Key_Down:
81 | return VK_DOWN;
82 | case Qt::Key_PageUp:
83 | return VK_PRIOR;
84 | case Qt::Key_PageDown:
85 | return VK_NEXT;
86 | case Qt::Key_CapsLock:
87 | return VK_CAPITAL;
88 | case Qt::Key_NumLock:
89 | return VK_NUMLOCK;
90 | case Qt::Key_ScrollLock:
91 | return VK_SCROLL;
92 |
93 | case Qt::Key_F1:
94 | return VK_F1;
95 | case Qt::Key_F2:
96 | return VK_F2;
97 | case Qt::Key_F3:
98 | return VK_F3;
99 | case Qt::Key_F4:
100 | return VK_F4;
101 | case Qt::Key_F5:
102 | return VK_F5;
103 | case Qt::Key_F6:
104 | return VK_F6;
105 | case Qt::Key_F7:
106 | return VK_F7;
107 | case Qt::Key_F8:
108 | return VK_F8;
109 | case Qt::Key_F9:
110 | return VK_F9;
111 | case Qt::Key_F10:
112 | return VK_F10;
113 | case Qt::Key_F11:
114 | return VK_F11;
115 | case Qt::Key_F12:
116 | return VK_F12;
117 | case Qt::Key_F13:
118 | return VK_F13;
119 | case Qt::Key_F14:
120 | return VK_F14;
121 | case Qt::Key_F15:
122 | return VK_F15;
123 | case Qt::Key_F16:
124 | return VK_F16;
125 | case Qt::Key_F17:
126 | return VK_F17;
127 | case Qt::Key_F18:
128 | return VK_F18;
129 | case Qt::Key_F19:
130 | return VK_F19;
131 | case Qt::Key_F20:
132 | return VK_F20;
133 | case Qt::Key_F21:
134 | return VK_F21;
135 | case Qt::Key_F22:
136 | return VK_F22;
137 | case Qt::Key_F23:
138 | return VK_F23;
139 | case Qt::Key_F24:
140 | return VK_F24;
141 |
142 | case Qt::Key_Menu:
143 | return VK_APPS;
144 | case Qt::Key_Help:
145 | return VK_HELP;
146 | case Qt::Key_MediaNext:
147 | return VK_MEDIA_NEXT_TRACK;
148 | case Qt::Key_MediaPrevious:
149 | return VK_MEDIA_PREV_TRACK;
150 | case Qt::Key_MediaPlay:
151 | return VK_MEDIA_PLAY_PAUSE;
152 | case Qt::Key_MediaStop:
153 | return VK_MEDIA_STOP;
154 | case Qt::Key_VolumeDown:
155 | return VK_VOLUME_DOWN;
156 | case Qt::Key_VolumeUp:
157 | return VK_VOLUME_UP;
158 | case Qt::Key_VolumeMute:
159 | return VK_VOLUME_MUTE;
160 | case Qt::Key_Mode_switch:
161 | return VK_MODECHANGE;
162 | case Qt::Key_Select:
163 | return VK_SELECT;
164 | case Qt::Key_Printer:
165 | return VK_PRINT;
166 | case Qt::Key_Execute:
167 | return VK_EXECUTE;
168 | case Qt::Key_Sleep:
169 | return VK_SLEEP;
170 | case Qt::Key_Period:
171 | return VK_DECIMAL;
172 | case Qt::Key_Play:
173 | return VK_PLAY;
174 | case Qt::Key_Cancel:
175 | return VK_CANCEL;
176 |
177 | case Qt::Key_Forward:
178 | return VK_BROWSER_FORWARD;
179 | case Qt::Key_Refresh:
180 | return VK_BROWSER_REFRESH;
181 | case Qt::Key_Stop:
182 | return VK_BROWSER_STOP;
183 | case Qt::Key_Search:
184 | return VK_BROWSER_SEARCH;
185 | case Qt::Key_Favorites:
186 | return VK_BROWSER_FAVORITES;
187 | case Qt::Key_HomePage:
188 | return VK_BROWSER_HOME;
189 |
190 | case Qt::Key_LaunchMail:
191 | return VK_LAUNCH_MAIL;
192 | case Qt::Key_LaunchMedia:
193 | return VK_LAUNCH_MEDIA_SELECT;
194 | case Qt::Key_Launch0:
195 | return VK_LAUNCH_APP1;
196 | case Qt::Key_Launch1:
197 | return VK_LAUNCH_APP2;
198 |
199 | case Qt::Key_Massyo:
200 | return VK_OEM_FJ_MASSHOU;
201 | case Qt::Key_Touroku:
202 | return VK_OEM_FJ_TOUROKU;
203 |
204 | default:
205 | ok = false;
206 | return 0;
207 | }
208 | }
209 |
210 | quint32 QHotkeyPrivateWin::nativeModifiers(Qt::KeyboardModifiers modifiers, bool &ok)
211 | {
212 | quint32 nMods = 0;
213 | if (modifiers & Qt::ShiftModifier)
214 | nMods |= MOD_SHIFT;
215 | if (modifiers & Qt::ControlModifier)
216 | nMods |= MOD_CONTROL;
217 | if (modifiers & Qt::AltModifier)
218 | nMods |= MOD_ALT;
219 | if (modifiers & Qt::MetaModifier)
220 | nMods |= MOD_WIN;
221 | ok = true;
222 | return nMods;
223 | }
224 |
225 | bool QHotkeyPrivateWin::registerShortcut(QHotkey::NativeShortcut shortcut)
226 | {
227 | BOOL ok = RegisterHotKey(NULL,
228 | HKEY_ID(shortcut),
229 | shortcut.modifier,
230 | shortcut.key);
231 | if(ok)
232 | return true;
233 | else {
234 | qCWarning(logQHotkey) << "Failed to register hotkey. Error:"
235 | << qPrintable(QHotkeyPrivateWin::formatWinError(::GetLastError()));
236 | return false;
237 | }
238 | }
239 |
240 | bool QHotkeyPrivateWin::unregisterShortcut(QHotkey::NativeShortcut shortcut)
241 | {
242 | BOOL ok = UnregisterHotKey(NULL, HKEY_ID(shortcut));
243 | if(ok)
244 | return true;
245 | else {
246 | qCWarning(logQHotkey) << "Failed to unregister hotkey. Error:"
247 | << qPrintable(QHotkeyPrivateWin::formatWinError(::GetLastError()));
248 | return false;
249 | }
250 | }
251 |
252 | QString QHotkeyPrivateWin::formatWinError(DWORD winError)
253 | {
254 | wchar_t *buffer = NULL;
255 | DWORD num = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
256 | NULL,
257 | winError,
258 | 0,
259 | (LPWSTR)&buffer,
260 | 0,
261 | NULL);
262 | if(buffer) {
263 | QString res = QString::fromWCharArray(buffer, num);
264 | LocalFree(buffer);
265 | return res;
266 | } else
267 | return QString();
268 | }
269 |
--------------------------------------------------------------------------------