When using the View specific format action add an "Open With" button to choose a specific program to view the specified format

This commit is contained in:
Kovid Goyal 2015-04-10 21:44:53 +05:30
parent 4c4f74fb5d
commit cbfd5f6e38
3 changed files with 73 additions and 95 deletions

View File

@ -170,7 +170,7 @@ class ViewAction(InterfaceAction):
_('Selected books have no formats'), show=True) _('Selected books have no formats'), show=True)
return return
d = ChooseFormatDialog(self.gui, _('Choose the format to view'), d = ChooseFormatDialog(self.gui, _('Choose the format to view'),
list(sorted(all_fmts))) list(sorted(all_fmts)), show_open_with=True)
self.gui.book_converted.connect(d.book_converted) self.gui.book_converted.connect(d.book_converted)
if d.exec_() == d.Accepted: if d.exec_() == d.Accepted:
formats = [[x.upper() for x in db.new_api.formats(book_id)] for book_id in book_ids] formats = [[x.upper() for x in db.new_api.formats(book_id)] for book_id in book_ids]
@ -180,7 +180,10 @@ class ViewAction(InterfaceAction):
formats[i]] formats[i]]
if self._view_check(len(rows)): if self._view_check(len(rows)):
for row in rows: for row in rows:
self.view_format(row, fmt) if d.open_with_format is None:
self.view_format(row, fmt)
else:
self.open_fmt_with(row, *d.open_with_format)
if len(rows) < orig_num: if len(rows) < orig_num:
info_dialog(self.gui, _('Format unavailable'), info_dialog(self.gui, _('Format unavailable'),
_('Not all the selected books were available in' _('Not all the selected books were available in'
@ -188,6 +191,10 @@ class ViewAction(InterfaceAction):
' them first.')%fmt, show=True) ' them first.')%fmt, show=True)
self.gui.book_converted.disconnect(d.book_converted) self.gui.book_converted.disconnect(d.book_converted)
def open_fmt_with(self, row, fmt, entry):
book_id = self.gui.library_view.model().id(row)
self.gui.book_details.open_fmt_with.emit(book_id, fmt, entry)
def _view_check(self, num, max_=3): def _view_check(self, num, max_=3):
if num <= max_: if num <= max_:
return True return True

View File

@ -1,26 +1,75 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
from PyQt5.Qt import QDialog, QListWidgetItem, QModelIndex from functools import partial
from PyQt5.Qt import (
QDialog, QListWidgetItem, QModelIndex, QIcon, QLabel, QVBoxLayout, QSize,
QDialogButtonBox, QListWidget, QHBoxLayout, QPushButton, QMenu)
from calibre.gui2 import file_icon_provider from calibre.gui2 import file_icon_provider
from calibre.gui2.dialogs.choose_format_ui import Ui_ChooseFormatDialog
class ChooseFormatDialog(QDialog, Ui_ChooseFormatDialog): class ChooseFormatDialog(QDialog):
def __init__(self, window, msg, formats): def __init__(self, window, msg, formats, show_open_with=False):
QDialog.__init__(self, window) QDialog.__init__(self, window)
Ui_ChooseFormatDialog.__init__(self) self.resize(507, 377)
self.setupUi(self) self.setWindowIcon(QIcon(I("mimetypes/unknown.png")))
self.setWindowTitle(_('Choose Format'))
self.l = l = QVBoxLayout(self)
self.msg = QLabel(msg)
l.addWidget(self.msg)
self.formats = QListWidget(self)
self.formats.setIconSize(QSize(64, 64))
self.formats.activated[QModelIndex].connect(self.activated_slot) self.formats.activated[QModelIndex].connect(self.activated_slot)
l.addWidget(self.formats)
self.h = h = QHBoxLayout()
h.setContentsMargins(0, 0, 0, 0)
l.addLayout(h)
if show_open_with:
self.owb = QPushButton(_('&Open With...'), self)
h.addWidget(self.owb)
self.own = QMenu(self.owb.text())
self.owb.setMenu(self.own)
self.own.aboutToShow.connect(self.populate_open_with)
self.buttonBox = bb = QDialogButtonBox(self)
bb.setStandardButtons(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
bb.accepted.connect(self.accept), bb.rejected.connect(self.reject)
h.addStretch(10), h.addWidget(self.buttonBox)
self.msg.setText(msg)
for format in formats: for format in formats:
self.formats.addItem(QListWidgetItem(file_icon_provider().icon_from_ext(format.lower()), self.formats.addItem(QListWidgetItem(file_icon_provider().icon_from_ext(format.lower()),
format.upper())) format.upper()))
self._formats = formats self._formats = formats
self.formats.setCurrentRow(0) self.formats.setCurrentRow(0)
self._format = None self._format = self.open_with_format = None
self.populate_open_with()
def populate_open_with(self):
from calibre.gui2.open_with import populate_menu, edit_programs
menu = self.own
menu.clear()
fmt = self._formats[self.formats.currentRow()]
m = QMenu(_('Open %s with...') % fmt.upper(), menu)
populate_menu(m, self.open_with, fmt)
if len(m.actions()) == 0:
menu.addAction(_('Open %s with...') % fmt.upper(), self.choose_open_with)
else:
m.addSeparator()
m.addAction(_('Add other application for %s files...') % fmt.upper(), self.choose_open_with)
m.addAction(_('Edit Open With applications...'), partial(edit_programs, fmt, self))
menu.addMenu(m)
def open_with(self, entry):
self.open_with_format = (self._formats[self.formats.currentRow()], entry)
self.accept()
def choose_open_with(self):
from calibre.gui2.open_with import choose_program
fmt = self._formats[self.formats.currentRow()]
entry = choose_program(fmt, self)
if entry is not None:
self.open_with(entry)
def book_converted(self, book_id, fmt): def book_converted(self, book_id, fmt):
fmt = fmt.upper() fmt = fmt.upper()
@ -39,3 +88,10 @@ class ChooseFormatDialog(QDialog, Ui_ChooseFormatDialog):
self._format = self._formats[self.formats.currentRow()] self._format = self._formats[self.formats.currentRow()]
return QDialog.accept(self) return QDialog.accept(self)
if __name__ == '__main__':
from calibre.gui2 import Application
app = Application([])
d = ChooseFormatDialog(None, 'Testing choose format', ['epub', 'mobi', 'docx'], show_open_with=True)
d.exec_()
print (d._format)
del app

View File

@ -1,85 +0,0 @@
<ui version="4.0" >
<class>ChooseFormatDialog</class>
<widget class="QDialog" name="ChooseFormatDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>507</width>
<height>377</height>
</rect>
</property>
<property name="windowTitle" >
<string>Choose Format</string>
</property>
<property name="windowIcon" >
<iconset resource="../../../../resources/images.qrc" >:/images/mimetypes/unknown.png</iconset>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="msg" >
<property name="text" >
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="formats" >
<property name="iconSize" >
<size>
<width>64</width>
<height>64</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Ok|QDialogButtonBox::Cancel</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../../../resources/images.qrc" />
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ChooseFormatDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ChooseFormatDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>