mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Dialog to select open with program
This commit is contained in:
parent
ee6f9b86c3
commit
d30f65b88a
@ -11,6 +11,7 @@ from collections import defaultdict
|
|||||||
|
|
||||||
from calibre import force_unicode, walk, guess_type, prints
|
from calibre import force_unicode, walk, guess_type, prints
|
||||||
from calibre.constants import iswindows, isosx, filesystem_encoding, cache_dir
|
from calibre.constants import iswindows, isosx, filesystem_encoding, cache_dir
|
||||||
|
from calibre.utils.icu import numeric_sort_key as sort_key
|
||||||
from calibre.utils.localization import canonicalize_lang, get_lang
|
from calibre.utils.localization import canonicalize_lang, get_lang
|
||||||
|
|
||||||
if iswindows:
|
if iswindows:
|
||||||
@ -18,6 +19,7 @@ if iswindows:
|
|||||||
elif isosx:
|
elif isosx:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
# Linux find_programs {{{
|
||||||
def parse_localized_key(key):
|
def parse_localized_key(key):
|
||||||
name, rest = key.partition('[')[0::2]
|
name, rest = key.partition('[')[0::2]
|
||||||
if not rest:
|
if not rest:
|
||||||
@ -68,7 +70,7 @@ else:
|
|||||||
ans[name][lang] = v
|
ans[name][lang] = v
|
||||||
else:
|
else:
|
||||||
ans[k] = v
|
ans[k] = v
|
||||||
if 'Exec' in ans and 'MimeType' in ans:
|
if 'Exec' in ans and 'MimeType' in ans and 'Name' in ans:
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
icon_data = None
|
icon_data = None
|
||||||
@ -168,6 +170,7 @@ else:
|
|||||||
data_dirs = [x for x in data_dirs if x and os.path.isdir(x)]
|
data_dirs = [x for x in data_dirs if x and os.path.isdir(x)]
|
||||||
desktop_files = {}
|
desktop_files = {}
|
||||||
mime_types = {guess_type('file.' + ext)[0] for ext in extensions}
|
mime_types = {guess_type('file.' + ext)[0] for ext in extensions}
|
||||||
|
ans = []
|
||||||
for base in data_dirs:
|
for base in data_dirs:
|
||||||
for f in walk(os.path.join(base, 'applications')):
|
for f in walk(os.path.join(base, 'applications')):
|
||||||
if f.endswith('.desktop'):
|
if f.endswith('.desktop'):
|
||||||
@ -191,7 +194,107 @@ else:
|
|||||||
val = data.get(k)
|
val = data.get(k)
|
||||||
if val:
|
if val:
|
||||||
data[k] = localize_string(val)
|
data[k] = localize_string(val)
|
||||||
yield data
|
ans.append(data)
|
||||||
|
ans.sort(key=lambda d:sort_key(d.get('Name')))
|
||||||
|
return ans
|
||||||
|
|
||||||
|
def entry_to_item(entry, parent):
|
||||||
|
icon_path = entry.get('Icon') or I('blank.png')
|
||||||
|
ans = QListWidgetItem(QIcon(icon_path), entry.get('Name') or _('Unknown'), parent)
|
||||||
|
ans.setData(DESC_ROLE, entry.get('Comment') or '')
|
||||||
|
ans.setData(ENTRY_ROLE, entry)
|
||||||
|
comment = (entry.get('Comment') or '')
|
||||||
|
if comment:
|
||||||
|
comment += '\n'
|
||||||
|
ans.setToolTip(comment + _('Command line:') + '\n' + (' '.join(entry['Exec'])))
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
from PyQt5.Qt import (
|
||||||
|
QApplication, QStackedLayout, QVBoxLayout, QWidget, QLabel, Qt,
|
||||||
|
QListWidget, QSize, pyqtSignal, QListWidgetItem, QIcon)
|
||||||
|
from calibre.gui2 import gprefs, error_dialog
|
||||||
|
from calibre.gui2.widgets2 import Dialog
|
||||||
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
|
|
||||||
|
DESC_ROLE = Qt.UserRole
|
||||||
|
ENTRY_ROLE = DESC_ROLE + 1
|
||||||
|
|
||||||
|
class ChooseProgram(Dialog):
|
||||||
|
|
||||||
|
found = pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self, file_type='jpeg', parent=None, prefs=gprefs):
|
||||||
|
self.file_type = file_type
|
||||||
|
self.programs = self.find_error = self.selected_entry = None
|
||||||
|
self.select_manually = False
|
||||||
|
Dialog.__init__(self, _('Choose a program'), 'choose-open-with-program-dialog', parent=parent, prefs=prefs)
|
||||||
|
self.found.connect(self.programs_found, type=Qt.QueuedConnection)
|
||||||
|
self.pi.startAnimation()
|
||||||
|
t = Thread(target=self.find_programs)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
def setup_ui(self):
|
||||||
|
self.stacks = s = QStackedLayout(self)
|
||||||
|
self.w = w = QWidget(self)
|
||||||
|
self.w.l = l = QVBoxLayout(w)
|
||||||
|
self.pi = pi = ProgressIndicator(self, 256)
|
||||||
|
l.addStretch(1), l.addWidget(pi, alignment=Qt.AlignHCenter), l.addSpacing(10)
|
||||||
|
w.la = la = QLabel(_('Gathering data, please wait...'))
|
||||||
|
la.setStyleSheet('QLabel { font-size: 30pt; font-weight: bold }')
|
||||||
|
l.addWidget(la, alignment=Qt.AlignHCenter), l.addStretch(1)
|
||||||
|
s.addWidget(w)
|
||||||
|
|
||||||
|
self.w2 = w = QWidget(self)
|
||||||
|
self.l = l = QVBoxLayout(w)
|
||||||
|
s.addWidget(w)
|
||||||
|
|
||||||
|
self.la = la = QLabel(_('Choose a program to open %s files') % self.file_type.upper())
|
||||||
|
self.plist = pl = QListWidget(self)
|
||||||
|
pl.setIconSize(QSize(48, 48)), pl.setSpacing(5)
|
||||||
|
pl.doubleClicked.connect(self.accept)
|
||||||
|
l.addWidget(la), l.addWidget(pl)
|
||||||
|
la.setBuddy(pl)
|
||||||
|
|
||||||
|
l.addWidget(self.bb)
|
||||||
|
|
||||||
|
def sizeHint(self):
|
||||||
|
return QSize(600, 500)
|
||||||
|
|
||||||
|
def find_programs(self):
|
||||||
|
try:
|
||||||
|
self.programs = find_programs(self.file_type.split())
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
self.find_error = traceback.print_exc()
|
||||||
|
self.found.emit()
|
||||||
|
|
||||||
|
def programs_found(self):
|
||||||
|
if self.find_error is not None:
|
||||||
|
error_dialog(self, _('Error finding programs'), _(
|
||||||
|
'Failed to find programs on your computer, click "Show details" for'
|
||||||
|
' more information'), det_msg=self.find_error, show=True)
|
||||||
|
self.select_manually = True
|
||||||
|
return self.reject()
|
||||||
|
if not self.programs:
|
||||||
|
self.select_manually = True
|
||||||
|
return self.reject()
|
||||||
|
for entry in self.programs:
|
||||||
|
entry_to_item(entry, self.plist)
|
||||||
|
self.stacks.setCurrentIndex(1)
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
ci = self.plist.currentItem()
|
||||||
|
if ci is not None:
|
||||||
|
self.selected_entry = ci.data(ENTRY_ROLE)
|
||||||
|
return Dialog.accept(self)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print (find_programs('jpg jpeg'.split()))
|
from pprint import pprint
|
||||||
|
app = QApplication([])
|
||||||
|
d = ChooseProgram()
|
||||||
|
d.exec_()
|
||||||
|
pprint(d.selected_entry)
|
||||||
|
del app
|
||||||
|
Loading…
x
Reference in New Issue
Block a user