diff --git a/ldoce5viewer/qtgui/__init__.py b/ldoce5viewer/qtgui/__init__.py
index 093ba01..56fa851 100644
--- a/ldoce5viewer/qtgui/__init__.py
+++ b/ldoce5viewer/qtgui/__init__.py
@@ -17,7 +17,7 @@
import codecs
import os.path
-from PyQt4.QtGui import QIcon
+from PyQt5.QtGui import QIcon
from .utils.singleapp import SingleApplication
from .utils.error import StdErrWrapper, MyStreamHandler
@@ -25,7 +25,7 @@
# set a dummy function if QLineEdit doesn't have setPlaceholderText
-from PyQt4.QtGui import QLineEdit
+from PyQt5.QtWidgets import QLineEdit
if not hasattr(QLineEdit, 'setPlaceholderText'):
def _dummySetPlaceholderText(self, *args, **kwargs):
pass
@@ -107,7 +107,7 @@ def messageHandler(msg):
# On Windows-ja
if app.font().family() == u'MS UI Gothic':
cand = (('Segoe UI', None), ('Meiryo UI', None), ('Tahoma', 8))
- from PyQt4.QtGui import QFont
+ from PyQt5.QtGui import QFont
for name, point in cand:
ps = app.font().pointSize()
if point is None:
diff --git a/ldoce5viewer/qtgui/access.py b/ldoce5viewer/qtgui/access.py
index b25aa86..c8752e0 100644
--- a/ldoce5viewer/qtgui/access.py
+++ b/ldoce5viewer/qtgui/access.py
@@ -8,9 +8,9 @@
import os.path
import traceback
-from PyQt4.QtCore import (
+from PyQt5.QtCore import (
Qt, Q_ARG, QMetaObject, QIODevice, QTimer,)
-from PyQt4.QtNetwork import (
+from PyQt5.QtNetwork import (
QNetworkAccessManager, QNetworkReply, QNetworkRequest,)
from .. import __version__
diff --git a/ldoce5viewer/qtgui/advanced.py b/ldoce5viewer/qtgui/advanced.py
index fa35480..36743a4 100644
--- a/ldoce5viewer/qtgui/advanced.py
+++ b/ldoce5viewer/qtgui/advanced.py
@@ -5,9 +5,11 @@
from operator import itemgetter
-from PyQt4.QtCore import Qt, QUrl
-from PyQt4.QtGui import (
- QAction, QDialog, QKeySequence, QIcon, QTreeWidgetItem,)
+from PyQt5.QtCore import Qt, QUrl, QUrlQuery
+from PyQt5.QtGui import (
+ QKeySequence, QIcon)
+from PyQt5.QtWidgets import (
+ QAction, QDialog, QTreeWidgetItem,)
from ..ldoce5 import advtree
from ..utils.compat import range
@@ -194,11 +196,13 @@ def _render_header(title, mode, phrase, filters):
for (name, spec) in modes:
href = QUrl('search:///')
+ urlquery = QUrlQuery()
if phrase:
- href.addQueryItem('phrase', phrase)
+ urlquery.addQueryItem('phrase', phrase)
if filters:
- href.addQueryItem('filters', filters)
- href.addQueryItem('mode', name)
+ urlquery.addQueryItem('filters', filters)
+ urlquery.addQueryItem('mode', name)
+ href.setQuery(urlquery)
if name != mode:
r.append(
'
{title}\n'.format(
@@ -276,10 +280,10 @@ def _render_hwdphr(items, mode):
def search_and_render(url, fulltext_hp, fulltext_de):
- query = dict((k, v) for (k, v) in url.queryItems())
- mode = query.get('mode', None)
- phrase = query.get('phrase', None)
- filters = query.get('filters', None)
+ query = QUrlQuery(url)
+ mode = query.queryItemValue('mode')
+ phrase = query.queryItemValue('phrase')
+ filters = query.queryItemValue('filters')
r = []
if mode in MODE_DICT:
diff --git a/ldoce5viewer/qtgui/async.py b/ldoce5viewer/qtgui/async_.py
similarity index 99%
rename from ldoce5viewer/qtgui/async.py
rename to ldoce5viewer/qtgui/async_.py
index 4b06af4..f578c5b 100644
--- a/ldoce5viewer/qtgui/async.py
+++ b/ldoce5viewer/qtgui/async_.py
@@ -5,7 +5,7 @@
import logging
-from PyQt4.QtCore import (
+from PyQt5.QtCore import (
QObject, QThread, QMutex, QWaitCondition, pyqtSignal)
_logger = logging.getLogger(__name__)
diff --git a/ldoce5viewer/qtgui/config.py b/ldoce5viewer/qtgui/config.py
index 84ea8b1..89e08e9 100644
--- a/ldoce5viewer/qtgui/config.py
+++ b/ldoce5viewer/qtgui/config.py
@@ -12,7 +12,7 @@
except ImportError:
import pickle
-from PyQt4.QtCore import QReadWriteLock
+from PyQt5.QtCore import QReadWriteLock
__config = None
diff --git a/ldoce5viewer/qtgui/indexer.py b/ldoce5viewer/qtgui/indexer.py
index 0fedba6..76baa0b 100644
--- a/ldoce5viewer/qtgui/indexer.py
+++ b/ldoce5viewer/qtgui/indexer.py
@@ -14,8 +14,9 @@
from struct import Struct
import traceback
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import *
import lxml.etree as et
from .. import __version__
diff --git a/ldoce5viewer/qtgui/main.py b/ldoce5viewer/qtgui/main.py
index 129133c..ef6f257 100644
--- a/ldoce5viewer/qtgui/main.py
+++ b/ldoce5viewer/qtgui/main.py
@@ -20,10 +20,13 @@
except ImportError:
objc = None
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-from PyQt4.QtNetwork import *
-from PyQt4.QtWebKit import *
+from PyQt5.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtNetwork import *
+from PyQt5.QtWebKit import *
+from PyQt5.QtWebKitWidgets import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtPrintSupport import *
from .. import fulltext
from .. import incremental
@@ -36,7 +39,7 @@
from .advanced import AdvancedSearchDialog
from .config import get_config
from .access import MyNetworkAccessManager, _load_static_data
-from .async import AsyncFTSearcher
+from .async_ import AsyncFTSearcher
from .utils.soundplayer import create_soundplayer
from .indexer import IndexerDialog
from .ui.custom import ToolButton, LineEdit
@@ -556,9 +559,13 @@ def finished():
def downloadSelectedAudio(self):
path = self._ui.webView.audioUrlToDownload.path()
def showSaveDialog(data):
- filename = QFileDialog.getSaveFileName(self, u'Save mp3', '', u'MP3 Files (*.mp3)')
+ filename = QFileDialog.getSaveFileName(self, u'Save mp3', \
+ '', u'MP3 Files (*.mp3)')
+ if type(filename) is tuple:
+ filename = filename[0]
+
if filename != '':
- file = open(filename, "w")
+ file = open(filename, "wb")
file.write(data)
file.close()
self._getAudioData(path, showSaveDialog)
@@ -568,7 +575,8 @@ def _onWebViewLinkClicked(self, url):
if scheme == 'audio':
self._playbackAudio(url.path())
elif scheme == 'lookup':
- query = dict((k, v) for (k, v) in url.queryItems())
+ urlQuery = QUrlQuery(url)
+ query = dict(urlQuery.queryItems())
if 'q' in query:
q = query['q'].replace('+', ' ')
self._ui.lineEditSearch.setText(q)
@@ -682,13 +690,15 @@ def fullSearch(self, phrase, filters, mode=None, only_web=False):
self._timerUpdateIndex.start(0)
if self._fts_hwdphr and self._fts_defexa:
- url = QUrl("search:///")
+ urlquery = QUrlQuery()
if phrase:
- url.addQueryItem("phrase", phrase)
+ urlquery.addQueryItem("phrase", phrase)
if filters:
- url.addQueryItem("filters", filters)
+ urlquery.addQueryItem("filters", filters)
if mode:
- url.addQueryItem("mode", mode)
+ urlquery.addQueryItem("mode", mode)
+ url = QUrl("search:///")
+ url.setQuery(urlquery)
self._ui.webView.load(url)
diff --git a/ldoce5viewer/qtgui/resources/Makefile b/ldoce5viewer/qtgui/resources/Makefile
index f7c9958..f6a80a0 100644
--- a/ldoce5viewer/qtgui/resources/Makefile
+++ b/ldoce5viewer/qtgui/resources/Makefile
@@ -3,7 +3,7 @@
FILES := $(wildcard *.png) $(wildcard *.svg) $(wildcard */*.png)
__init__.py: resource.qrc $(FILES)
- pyrcc4 -py3 $< -o $@
+ pyrcc5 $< -o $@
.PHONY: clean
clean:
diff --git a/ldoce5viewer/qtgui/ui/Makefile b/ldoce5viewer/qtgui/ui/Makefile
index 7f80401..ed1f405 100644
--- a/ldoce5viewer/qtgui/ui/Makefile
+++ b/ldoce5viewer/qtgui/ui/Makefile
@@ -6,7 +6,7 @@ __init__.py:
touch $@
%.py: %.ui
- pyuic4 $< -o $@
+ pyuic5 $< -o $@
.PYONY: clean
clean:
diff --git a/ldoce5viewer/qtgui/ui/custom.py b/ldoce5viewer/qtgui/ui/custom.py
index f475f42..ad455c4 100644
--- a/ldoce5viewer/qtgui/ui/custom.py
+++ b/ldoce5viewer/qtgui/ui/custom.py
@@ -2,9 +2,11 @@
import sys
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-from PyQt4.QtWebKit import *
+from PyQt5.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtWebKit import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtWebKitWidgets import *
from ...utils.text import ellipsis
@@ -285,7 +287,7 @@ def mouseReleaseEvent(self, event):
def wheelEvent(self, event):
if event.modifiers() & Qt.ControlModifier:
- self.wheelWithCtrl.emit(event.delta())
+ self.wheelWithCtrl.emit(event.pixelDelta())
return
super(WebView, self).wheelEvent(event)
diff --git a/ldoce5viewer/qtgui/ui/main.ui b/ldoce5viewer/qtgui/ui/main.ui
index 427ecf6..bd5d91b 100644
--- a/ldoce5viewer/qtgui/ui/main.ui
+++ b/ldoce5viewer/qtgui/ui/main.ui
@@ -758,7 +758,7 @@
QWebInspector
QWidget
-
+
HtmlListWidget
diff --git a/ldoce5viewer/qtgui/utils/error.py b/ldoce5viewer/qtgui/utils/error.py
index 59721a2..3a10bda 100644
--- a/ldoce5viewer/qtgui/utils/error.py
+++ b/ldoce5viewer/qtgui/utils/error.py
@@ -2,8 +2,8 @@
from logging import StreamHandler
-from PyQt4.QtCore import QMutex, QObject, pyqtSignal
-from PyQt4.QtGui import QPlainTextEdit
+from PyQt5.QtCore import QMutex, QObject, pyqtSignal
+from PyQt5.QtWidgets import QPlainTextEdit
class MyStreamHandler(StreamHandler):
diff --git a/ldoce5viewer/qtgui/utils/fontfallback.py b/ldoce5viewer/qtgui/utils/fontfallback.py
index 3cd769c..a43e19a 100644
--- a/ldoce5viewer/qtgui/utils/fontfallback.py
+++ b/ldoce5viewer/qtgui/utils/fontfallback.py
@@ -5,7 +5,7 @@
import re
-from PyQt4.QtGui import QFont
+from PyQt5.QtGui import QFont
_DEFAULT_FONT_NAMES = frozenset((b'sans-serif', b'serif', b'monospace'))
diff --git a/ldoce5viewer/qtgui/utils/singleapp.py b/ldoce5viewer/qtgui/utils/singleapp.py
index f6e40ff..7511f7d 100644
--- a/ldoce5viewer/qtgui/utils/singleapp.py
+++ b/ldoce5viewer/qtgui/utils/singleapp.py
@@ -1,9 +1,9 @@
'''This module prevent you from running two instances of the app'''
-from PyQt4.QtCore import pyqtSignal, QIODevice
-from PyQt4.QtGui import QApplication
-from PyQt4.QtNetwork import QLocalSocket, QLocalServer
+from PyQt5.QtCore import pyqtSignal, QIODevice
+from PyQt5.QtWidgets import QApplication
+from PyQt5.QtNetwork import QLocalSocket, QLocalServer
class SingleApplication(QApplication):
diff --git a/ldoce5viewer/qtgui/utils/soundplayer.py b/ldoce5viewer/qtgui/utils/soundplayer.py
index 0c8046d..8d93665 100644
--- a/ldoce5viewer/qtgui/utils/soundplayer.py
+++ b/ldoce5viewer/qtgui/utils/soundplayer.py
@@ -1,10 +1,10 @@
import sys
import os
import abc
-from tempfile import NamedTemporaryFile
+from tempfile import NamedTemporaryFile, mkdtemp
import logging
-from PyQt4.QtCore import *
+from PyQt5.QtCore import *
from ...utils.compat import range
_logger = logging.getLogger(__name__)
@@ -50,11 +50,18 @@
# Qt-Phonon
try:
- from PyQt4.phonon import Phonon
+ from PyQt5.phonon import Phonon
except ImportError:
Phonon = None
+# Qt-Multimedia
+try:
+ import PyQt5.QtMultimedia as QtMultimedia
+except ImportError:
+ QtMultimedia = None
+
+
class Backend(object):
__metaclass__ = abc.ABCMeta
def __init__(self, parent, temp_dir):
@@ -254,6 +261,29 @@ def close(self):
self._clean_tmp()
+class QtMultimediaBackend(Backend):
+ def __init__(self, parent, temp_dir):
+ self._player = QtMultimedia.QMediaPlayer()
+ self._tmpdir = mkdtemp()
+
+ def _play(self):
+ url = QUrl.fromLocalFile(self._path)
+ content = QtMultimedia.QMediaContent(url)
+ self._player.setMedia(content)
+ self._player.play()
+
+ def play(self, data):
+ self._player.stop()
+ with NamedTemporaryFile(mode='w+b', prefix='',
+ suffix='.tmp.mp3', dir=self._tmpdir, delete=False) as f:
+ f.write(data)
+ self._path = f.name
+ QTimer.singleShot(0, self._play)
+
+ def close(self):
+ self._player.stop()
+
+
class AppKitBackend(Backend):
def __init__(self, parent, temp_dir):
self._sound = None
@@ -281,6 +311,8 @@ def create_soundplayer(parent, temp_dir):
backends.append(WinMCIBackend)
if Phonon:
backends.append(PhononBackend)
+ if QtMultimedia:
+ backends.append(QtMultimediaBackend)
if Gst:
backends.append(GstreamerBackend)
if gst: