def about_to_show(self): cm = self.clone.menu() before = list(QMenu.actions(cm)) cm.aboutToShow.emit() after = list(QMenu.actions(cm)) if before != after: self.clone_menu()
def add_open_with_actions(self, menu, file_name): from calibre.gui2.open_with import populate_menu, edit_programs fmt = file_name.rpartition('.')[-1].lower() if not fmt: return m = QMenu(_('Open %s with...') % file_name) def connect_action(ac, entry): connect_lambda(ac.triggered, self, lambda self: self.open_with(file_name, fmt, entry)) populate_menu(m, connect_action, fmt) if len(m.actions()) == 0: menu.addAction( _('Open %s with...') % file_name, partial(self.choose_open_with, file_name, fmt)) else: m.addSeparator() m.addAction( _('Add other application for %s files...') % fmt.upper(), partial(self.choose_open_with, file_name, fmt)) m.addAction(_('Edit Open With applications...'), partial(edit_programs, fmt, file_name)) menu.addMenu(m) menu.ow = m
def _populate_action_children(self, children, parent, possible_menus, paths, plugin_name, is_location_mgr_child=False): for ac in children: if ac.isSeparator(): continue if not ac.isVisible() and not is_location_mgr_child: # That is special case of location mgr visibility, since it has child # actions that will not be visible if device not plugged in at the # moment but we want to always be able to configure them. continue text = get_safe_title(ac) it = Item(parent) it.setText(0, text) it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) it.setCheckState(0, Qt.Unchecked) it.setIcon(0, self._get_scaled_icon(ac.icon())) new_paths = list(paths) new_paths.append(text) if possible_menus: fav_menu = self._is_in_menu(possible_menus, new_paths) if fav_menu is not None: fav_menu['icon'] = it.icon(0) it.setCheckState(0, Qt.Checked) if ac.menu(): self._populate_action_children(QMenu.actions(ac.menu()), it, possible_menus, new_paths, plugin_name)
def clone_changed(self): otext = self.text() self.setText(self.clone.text()) if otext != self.text: self.text_changed.emit() ov = self.isVisible() self.setVisible(self.clone.isVisible()) if ov != self.isVisible(): self.visibility_changed.emit() self.setEnabled(self.clone.isEnabled()) self.setCheckable(self.clone.isCheckable()) self.setChecked(self.clone.isChecked()) self.setIcon(self.clone.icon()) if self.clone_shortcuts: self.setShortcuts(self.clone.shortcuts()) if self.clone.menu() is None: if not self.is_top_level: self.setMenu(None) else: m = QMenu(self.text(), self.parent()) for ac in QMenu.actions(self.clone.menu()): if ac.isSeparator(): m.addSeparator() else: m.addAction(CloneAction(ac, self.parent(), clone_shortcuts=self.clone_shortcuts)) self.setMenu(m)
def clone_changed(self): otext = self.text() self.setText(self.clone.text()) if otext != self.text: self.text_changed.emit() ov = self.isVisible() self.setVisible(self.clone.isVisible()) if ov != self.isVisible(): self.visibility_changed.emit() self.setEnabled(self.clone.isEnabled()) self.setCheckable(self.clone.isCheckable()) self.setChecked(self.clone.isChecked()) self.setIcon(self.clone.icon()) if self.clone_shortcuts: self.setShortcuts(self.clone.shortcuts()) if self.clone.menu() is None: if not self.is_top_level: self.setMenu(None) else: m = QMenu(self.text(), self.parent()) for ac in QMenu.actions(self.clone.menu()): if ac.isSeparator(): m.addSeparator() else: m.addAction( CloneAction(ac, self.parent(), clone_shortcuts=self.clone_shortcuts)) self.setMenu(m)
def menu_actions(menu): try: return menu.actions() except TypeError: if isinstance(menu, QMenu): return QMenu.actions(menu) raise
def contextMenuEvent(self, ev): from calibre.gui2.open_with import populate_menu, edit_programs cm = QMenu(self) paste = cm.addAction(_('Paste cover')) copy = cm.addAction(_('Copy cover')) remove = cm.addAction(_('Remove cover')) gc = cm.addAction(_('Generate cover from metadata')) cm.addSeparator() if not QApplication.instance().clipboard().mimeData().hasImage(): paste.setEnabled(False) copy.triggered.connect(self.copy_to_clipboard) paste.triggered.connect(self.paste_from_clipboard) remove.triggered.connect(self.remove_cover) gc.triggered.connect(self.generate_cover) m = QMenu(_('Open cover with...')) populate_menu(m, self.open_with, 'cover_image') if len(m.actions()) == 0: cm.addAction(_('Open cover with...'), self.choose_open_with) else: m.addSeparator() m.addAction(_('Add another application to open cover...'), self.choose_open_with) m.addAction(_('Edit Open with applications...'), partial(edit_programs, 'cover_image', self)) cm.ocw = m cm.addMenu(m) cm.si = m = create_search_internet_menu(self.search_internet.emit) cm.addMenu(m) cm.exec_(ev.globalPos())
def contextMenuEvent(self, ev): from calibre.gui2.open_with import populate_menu, edit_programs cm = QMenu(self) paste = cm.addAction(_("Paste Cover")) copy = cm.addAction(_("Copy Cover")) remove = cm.addAction(_("Remove Cover")) gc = cm.addAction(_("Generate Cover from metadata")) if not QApplication.instance().clipboard().mimeData().hasImage(): paste.setEnabled(False) copy.triggered.connect(self.copy_to_clipboard) paste.triggered.connect(self.paste_from_clipboard) remove.triggered.connect(self.remove_cover) gc.triggered.connect(self.generate_cover) m = QMenu(_("Open cover with...")) populate_menu(m, self.open_with, "cover_image") if len(m.actions()) == 0: cm.addAction(_("Open cover with..."), self.choose_open_with) else: m.addSeparator() m.addAction(_("Add another application to open cover..."), self.choose_open_with) m.addAction(_("Edit Open With applications..."), partial(edit_programs, "cover_image", self)) cm.addMenu(m) cm.exec_(ev.globalPos())
def clone_menu(self): m = self.menu() m.clear() for ac in QMenu.actions(self.clone.menu()): if ac.isSeparator(): m.addSeparator() else: m.addAction(CloneAction(ac, self.parent(), clone_shortcuts=self.clone_shortcuts))
def context_menu(self, pos): m = QMenu(self) if self.items.count() > 0: m.addAction(QIcon(I('edit-copy.png')), _('Copy list of errors to clipboard'), self.copy_to_clipboard) if list(m.actions()): m.exec_(self.mapToGlobal(pos))
def show_context_menu(self, point): item = self.itemAt(point) if item is None or item in set(self.categories.itervalues()): return m = QMenu(self) sel = self.selectedItems() num = len(sel) container = current_container() ci = self.currentItem() if ci is not None: cn = unicode(ci.data(0, NAME_ROLE) or '') mt = unicode(ci.data(0, MIME_ROLE) or '') cat = unicode(ci.data(0, CATEGORY_ROLE) or '') n = elided_text(cn.rpartition('/')[-1]) m.addAction(QIcon(I('save.png')), _('Export %s') % n, partial(self.export, cn)) if cn not in container.names_that_must_not_be_changed and cn not in container.names_that_must_not_be_removed and mt not in OEB_FONTS: m.addAction(_('Replace %s with file...') % n, partial(self.replace, cn)) if num > 1: m.addAction(QIcon(I('save.png')), _('Export all %d selected files') % num, self.export_selected) m.addSeparator() m.addAction(QIcon(I('modified.png')), _('&Rename %s') % n, self.edit_current_item) if is_raster_image(mt): m.addAction(QIcon(I('default_cover.png')), _('Mark %s as cover image') % n, partial(self.mark_as_cover, cn)) elif current_container().SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == 'text': m.addAction(QIcon(I('default_cover.png')), _('Mark %s as cover page') % n, partial(self.mark_as_titlepage, cn)) m.addSeparator() if num > 0: m.addSeparator() if num > 1: m.addAction(QIcon(I('modified.png')), _('&Bulk rename the selected files'), self.request_bulk_rename) m.addAction(QIcon(I('modified.png')), _('Change the file extension for the selected files'), self.request_change_ext) m.addAction(QIcon(I('trash.png')), ngettext( '&Delete the selected file', '&Delete the {} selected files', num).format(num), self.request_delete) m.addAction(QIcon(I('edit-copy.png')), ngettext( '&Copy the selected file to another editor instance', '&Copy the {} selected files to another editor instance', num).format(num), self.copy_selected_files) m.addSeparator() selected_map = defaultdict(list) for item in sel: selected_map[unicode(item.data(0, CATEGORY_ROLE) or '')].append(unicode(item.data(0, NAME_ROLE) or '')) for items in selected_map.itervalues(): items.sort(key=self.index_of_name) if selected_map['text']: m.addAction(QIcon(I('format-text-color.png')), _('Link &stylesheets...'), partial(self.link_stylesheets, selected_map['text'])) if len(selected_map['text']) > 1: m.addAction(QIcon(I('merge.png')), _('&Merge selected text files'), partial(self.start_merge, 'text', selected_map['text'])) if len(selected_map['styles']) > 1: m.addAction(QIcon(I('merge.png')), _('&Merge selected style files'), partial(self.start_merge, 'styles', selected_map['styles'])) if len(list(m.actions())) > 0: m.popup(self.mapToGlobal(point))
def show_context_menu(self, pos): pos = self.viewport().mapToGlobal(pos) locations = self.selected_locations m = QMenu(self) if locations: m.addAction(_('Delete selected files'), self.delete_selected) self.customize_context_menu(m, locations, self.current_location) if len(m.actions()) > 0: m.exec_(pos)
def details_context_menu_event(view, ev, book_info, add_popup_action=False): url = view.anchorAt(ev.pos()) menu = QMenu(view) menu.addAction(QIcon(I('edit-copy.png')), _('Copy all book details'), partial(copy_all, view)) cm = QMenu(_('Copy link to book'), menu) cm.setIcon(QIcon(I('edit-copy.png'))) copy_links_added = False search_internet_added = False if url and url.startswith('action:'): data = json_loads(from_hex_bytes(url.split(':', 1)[1])) create_copy_links(cm, data) copy_links_added = True search_internet_added = add_item_specific_entries( menu, data, book_info) elif url and not url.startswith('#'): ac = book_info.copy_link_action ac.current_url = url ac.setText(_('Copy link location')) menu.addAction(ac) if not copy_links_added: create_copy_links(cm) if list(cm.actions()): menu.addMenu(cm) if not search_internet_added and hasattr(book_info, 'search_internet'): menu.addSeparator() menu.si = create_search_internet_menu(book_info.search_internet) menu.addMenu(menu.si) for ac in tuple(menu.actions()): if not ac.isEnabled(): menu.removeAction(ac) menu.addSeparator() if add_popup_action: ac = menu.addAction(_('Open the Book details window')) ac.triggered.connect(book_info.show_book_info) else: from calibre.gui2.ui import get_gui ema = get_gui().iactions['Edit Metadata'].menuless_qaction menu.addAction( _('Open the Edit metadata window') + '\t' + ema.shortcut().toString(QKeySequence.NativeText), ema.trigger) if len(menu.actions()) > 0: menu.exec_(ev.globalPos())
def add_format_entries(menu, data, book_info): from calibre.ebooks.oeb.polish.main import SUPPORTED from calibre.gui2.ui import get_gui book_id = int(data['book_id']) fmt = data['fmt'] init_find_in_tag_browser(menu, book_info.find_in_tag_browser_action, 'formats', fmt) db = get_gui().current_db.new_api ofmt = fmt.upper() if fmt.startswith('ORIGINAL_') else 'ORIGINAL_' + fmt nfmt = ofmt[len('ORIGINAL_'):] fmts = {x.upper() for x in db.formats(book_id)} for a, t in [ ('remove', _('Delete the %s format')), ('save', _('Save the %s format to disk')), ('restore', _('Restore the %s format')), ('compare', ''), ('set_cover', _('Set the book cover from the %s file')), ]: if a == 'restore' and not fmt.startswith('ORIGINAL_'): continue if a == 'compare': if ofmt not in fmts or nfmt not in SUPPORTED: continue t = _('Compare to the %s format') % (fmt[9:] if fmt.startswith('ORIGINAL_') else ofmt) else: t = t % fmt ac = getattr(book_info, '%s_format_action'%a) ac.current_fmt = (book_id, fmt) ac.setText(t) menu.addAction(ac) if not fmt.upper().startswith('ORIGINAL_'): from calibre.gui2.open_with import populate_menu, edit_programs m = QMenu(_('Open %s with...') % fmt.upper()) def connect_action(ac, entry): connect_lambda(ac.triggered, book_info, lambda book_info: book_info.open_with(book_id, fmt, entry)) populate_menu(m, connect_action, fmt) if len(m.actions()) == 0: menu.addAction(_('Open %s with...') % fmt.upper(), partial(book_info.choose_open_with, book_id, fmt)) else: m.addSeparator() m.addAction(_('Add other application for %s files...') % fmt.upper(), partial(book_info.choose_open_with, book_id, fmt)) m.addAction(_('Edit Open with applications...'), partial(edit_programs, fmt, book_info)) menu.addMenu(m) menu.ow = m if fmt.upper() in SUPPORTED: menu.addSeparator() menu.addAction(_('Edit %s...') % fmt.upper(), partial(book_info.edit_fmt, book_id, fmt)) path = data['path'] if path: if data.get('fname'): path = os.path.join(path, data['fname'] + '.' + data['fmt'].lower()) ac = book_info.copy_link_action ac.current_url = path ac.setText(_('&Copy path to file')) menu.addAction(ac)
def publish_new_menu(self): menu = self.notifier.contextMenu() if menu is None: menu = QMenu() if len(menu.actions()) == 0: menu.addAction(self.notifier.icon(), _('Show/hide %s') % self.title, self.notifier.emit_activated) # The menu must have at least one entry, namely the show/hide entry. # This is necessary as Canonical in their infinite wisdom decided to # force all tray icons to show their popup menus when clicked. self.dbus_menu.publish_new_menu(menu)
def show_context_menu(self, point): item = self.itemAt(point) if item is None or item in set(self.categories.itervalues()): return m = QMenu(self) sel = self.selectedItems() num = len(sel) container = current_container() ci = self.currentItem() if ci is not None: cn = unicode(ci.data(0, NAME_ROLE) or '') mt = unicode(ci.data(0, MIME_ROLE) or '') cat = unicode(ci.data(0, CATEGORY_ROLE) or '') n = elided_text(cn.rpartition('/')[-1]) m.addAction(QIcon(I('save.png')), _('Export %s') % n, partial(self.export, cn)) if cn not in container.names_that_must_not_be_changed and cn not in container.names_that_must_not_be_removed and mt not in OEB_FONTS: m.addAction(_('Replace %s with file...') % n, partial(self.replace, cn)) if num > 1: m.addAction(QIcon(I('save.png')), _('Export all %d selected files') % num, self.export_selected) m.addSeparator() m.addAction(QIcon(I('modified.png')), _('&Rename %s') % n, self.edit_current_item) if is_raster_image(mt): m.addAction(QIcon(I('default_cover.png')), _('Mark %s as cover image') % n, partial(self.mark_as_cover, cn)) elif current_container().SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == 'text': m.addAction(QIcon(I('default_cover.png')), _('Mark %s as cover page') % n, partial(self.mark_as_titlepage, cn)) m.addSeparator() if num > 0: m.addSeparator() if num > 1: m.addAction(QIcon(I('modified.png')), _('&Bulk rename the selected files'), self.request_bulk_rename) m.addAction(QIcon(I('modified.png')), _('Change the file extension for the selected files'), self.request_change_ext) m.addAction(QIcon(I('trash.png')), ngettext( '&Delete the selected file', '&Delete the {} selected files', num).format(num), self.request_delete) m.addSeparator() selected_map = defaultdict(list) for item in sel: selected_map[unicode(item.data(0, CATEGORY_ROLE) or '')].append(unicode(item.data(0, NAME_ROLE) or '')) for items in selected_map.itervalues(): items.sort(key=self.index_of_name) if selected_map['text']: m.addAction(QIcon(I('format-text-color.png')), _('Link &stylesheets...'), partial(self.link_stylesheets, selected_map['text'])) if len(selected_map['text']) > 1: m.addAction(QIcon(I('merge.png')), _('&Merge selected text files'), partial(self.start_merge, 'text', selected_map['text'])) if len(selected_map['styles']) > 1: m.addAction(QIcon(I('merge.png')), _('&Merge selected style files'), partial(self.start_merge, 'styles', selected_map['styles'])) if len(list(m.actions())) > 0: m.popup(self.mapToGlobal(point))
def _populate_actions_tree(self, lookup_menu_map): # Lets re-sort the keys so that items will appear on screen sorted # by their display name (not by their key) skeys_map = {} for plugin_name, iaction in six.iteritems(self.gui.iactions): if plugin_name == self.plugin_action.name: continue if 'toolbar' in iaction.dont_add_to and 'toolbar-device' in iaction.dont_add_to: print(('Not adding:', plugin_name)) continue display_name = unicode(iaction.qaction.text()) if plugin_name == 'Choose Library': display_name = 'Library' skeys_map[display_name] = (plugin_name, iaction.qaction) # Add a special case item for the location manager skeys_map['Location Manager'] = ('Location Manager', None) self.top_level_items_map = {} for display_name in sorted(skeys_map.keys()): plugin_name, qaction = skeys_map[display_name] possible_menus = lookup_menu_map.get(plugin_name, []) # Create a node for our top level plugin name tl = Item() tl.setText(0, display_name) tl.setData(0, Qt.UserRole, plugin_name) if plugin_name == 'Location Manager': # Special case handling tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) tl.setCheckState(0, Qt.PartiallyChecked) tl.setIcon(0, self._get_scaled_icon(get_icon('reader.png'))) # Put all actions except library within this node. actions = self.gui.location_manager.all_actions[1:] self._populate_action_children(actions, tl, possible_menus, [], plugin_name, is_location_mgr_child=True) else: # Normal top-level checkable plugin iaction handling tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) tl.setCheckState(0, Qt.Unchecked) tl.setIcon(0, self._get_scaled_icon(qaction.icon())) # Lookup to see if we have a menu item for this top-level plugin if possible_menus: fav_menu = self._is_in_menu(possible_menus) if fav_menu is not None: fav_menu['icon'] = tl.icon(0) tl.setCheckState(0, Qt.Checked) m = qaction.menu() if m: # Iterate through all the children of this node self._populate_action_children(QMenu.actions(m), tl, possible_menus, [], plugin_name) self.tv.addTopLevelItem(tl) self.top_level_items_map[plugin_name] = tl
def showContextMenu(self, widget, pos): """ Show context menu. Arguments: widget (QWidget): Widget displaying popup menu. pos (QPoint): Mouse cursor position. """ menu = QMenu(self._astergui.mainWindow()) self._add_actions(menu, self._context) if len(menu.actions()) > 0: menu.exec_(widget.mapToGlobal(pos))
def _find_action_for_menu(self, parent, paths, plugin_name): if parent is not None: find_text = paths[0] for ac in QMenu.actions(parent): if ac.isSeparator(): continue #print('Looking at action:',unicode(ac.text())) safe_title = cfg.get_safe_title(ac) if safe_title == find_text: if len(paths) == 1: return ac return self._find_action_for_menu(ac.menu(), paths[1:], plugin_name)
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 create_open_cover_with_menu(self, parent_menu): from calibre.gui2.open_with import populate_menu, edit_programs m = QMenu(_('Open cover with...')) def connect_action(ac, entry): connect_lambda(ac.triggered, self, lambda self: self.open_with(entry)) populate_menu(m, connect_action, 'cover_image') if len(m.actions()) == 0: parent_menu.addAction(_('Open cover with...'), self.choose_open_with) else: m.addSeparator() m.addAction(_('Add another application to open cover...'), self.choose_open_with) m.addAction(_('Edit Open with applications...'), partial(edit_programs, 'cover_image', self)) parent_menu.ocw = m parent_menu.addMenu(m) return m
def show_context_menu(self, pos): m = QMenu(self) a = m.addAction i = unicode(self.textCursor().selectedText()).rstrip('\0') if i: a(QIcon(I('edit-copy.png')), _('Copy to clipboard'), self.copy).setShortcut(QKeySequence.Copy) if len(self.changes) > 0: a(QIcon(I('arrow-up.png')), _('Previous change'), partial(self.next_change.emit, -1)) a(QIcon(I('arrow-down.png')), _('Next change'), partial(self.next_change.emit, 1)) if self.show_open_in_editor: b = self.cursorForPosition(pos).block() if b.isValid(): a(QIcon(I('tweak.png')), _('Open file in the editor'), partial(self.generate_sync_request, b.blockNumber())) if len(m.actions()) > 0: m.exec_(self.mapToGlobal(pos))
def contextMenuEvent(self, ev): from calibre.gui2.open_with import populate_menu cm = QMenu(self) paste = cm.addAction(_('Paste Cover')) copy = cm.addAction(_('Copy Cover')) remove = cm.addAction(_('Remove Cover')) gc = cm.addAction(_('Generate Cover from metadata')) if not QApplication.instance().clipboard().mimeData().hasImage(): paste.setEnabled(False) copy.triggered.connect(self.copy_to_clipboard) paste.triggered.connect(self.paste_from_clipboard) remove.triggered.connect(self.remove_cover) gc.triggered.connect(self.generate_cover) m = QMenu(_('Open with...')) populate_menu(m, self.open_with, 'jpeg') if len(m.actions()) == 0: cm.addAction(_('Open with...'), self.choose_open_with) else: m.addSeparator() m.addAction(_('Choose other program...'), self.choose_open_with) cm.addMenu(m) cm.exec_(ev.globalPos())
def details_context_menu_event(view, ev, book_info): # {{{ p = view.page() mf = p.mainFrame() r = mf.hitTestContent(ev.pos()) url = unicode(r.linkUrl().toString(QUrl.None)).strip() menu = p.createStandardContextMenu() ca = view.pageAction(p.Copy) for action in list(menu.actions()): if action is not ca: menu.removeAction(action) if not r.isNull(): if url.startswith("format:"): parts = url.split(":") try: book_id, fmt = int(parts[1]), parts[2].upper() except: import traceback traceback.print_exc() else: from calibre.gui2.ui import get_gui from calibre.ebooks.oeb.polish.main import SUPPORTED db = get_gui().current_db.new_api ofmt = fmt.upper() if fmt.startswith("ORIGINAL_") else "ORIGINAL_" + fmt nfmt = ofmt[len("ORIGINAL_") :] fmts = {x.upper() for x in db.formats(book_id)} for a, t in [ ("remove", _("Delete the %s format")), ("save", _("Save the %s format to disk")), ("restore", _("Restore the %s format")), ("compare", ""), ("set_cover", _("Set the book cover from the %s file")), ]: if a == "restore" and not fmt.startswith("ORIGINAL_"): continue if a == "compare": if ofmt not in fmts or nfmt not in SUPPORTED: continue t = _("Compare to the %s format") % (fmt[9:] if fmt.startswith("ORIGINAL_") else ofmt) else: t = t % fmt ac = getattr(book_info, "%s_format_action" % a) ac.current_fmt = (book_id, fmt) ac.setText(t) menu.addAction(ac) if not fmt.upper().startswith("ORIGINAL_"): from calibre.gui2.open_with import populate_menu, edit_programs m = QMenu(_("Open %s with...") % fmt.upper()) populate_menu(m, partial(book_info.open_with, book_id, fmt), fmt) if len(m.actions()) == 0: menu.addAction( _("Open %s with...") % fmt.upper(), partial(book_info.choose_open_with, book_id, fmt) ) else: m.addSeparator() m.addAction( _("Add other application for %s files...") % fmt.upper(), partial(book_info.choose_open_with, book_id, fmt), ) m.addAction(_("Edit Open With applications..."), partial(edit_programs, fmt, book_info)) menu.addMenu(m) ac = book_info.copy_link_action ac.current_url = r.linkElement().attribute("data-full-path") if ac.current_url: ac.setText(_("&Copy path to file")) menu.addAction(ac) else: el = r.linkElement() data = el.attribute("data-item") author = el.toPlainText() if unicode(el.attribute("calibre-data")) == u"authors" else None if not url.startswith("search:"): for a, t in [("copy", _("&Copy Link"))]: ac = getattr(book_info, "%s_link_action" % a) ac.current_url = url if url.startswith("path:"): ac.current_url = el.attribute("title") ac.setText(t) menu.addAction(ac) if author is not None: ac = book_info.manage_author_action ac.current_fmt = author ac.setText(_("Manage %s") % author) menu.addAction(ac) if data: try: field, value, book_id = cPickle.loads(unhexlify(data)) except Exception: field = value = book_id = None if field: ac = book_info.remove_item_action ac.data = (field, value, book_id) ac.setText(_("Remove %s from this book") % value) menu.addAction(ac) if len(menu.actions()) > 0: menu.exec_(ev.globalPos())
def details_context_menu_event(view, ev, book_info): # {{{ p = view.page() mf = p.mainFrame() r = mf.hitTestContent(ev.pos()) url = unicode(r.linkUrl().toString(NO_URL_FORMATTING)).strip() menu = p.createStandardContextMenu() ca = view.pageAction(p.Copy) for action in list(menu.actions()): if action is not ca: menu.removeAction(action) menu.addAction(QIcon(I('edit-copy.png')), _('Copy &all'), partial(copy_all, book_info)) search_internet_added = False if not r.isNull(): if url.startswith('format:'): parts = url.split(':') try: book_id, fmt = int(parts[1]), parts[2].upper() except: import traceback traceback.print_exc() else: from calibre.gui2.ui import get_gui from calibre.ebooks.oeb.polish.main import SUPPORTED db = get_gui().current_db.new_api ofmt = fmt.upper() if fmt.startswith('ORIGINAL_') else 'ORIGINAL_' + fmt nfmt = ofmt[len('ORIGINAL_'):] fmts = {x.upper() for x in db.formats(book_id)} for a, t in [ ('remove', _('Delete the %s format')), ('save', _('Save the %s format to disk')), ('restore', _('Restore the %s format')), ('compare', ''), ('set_cover', _('Set the book cover from the %s file')), ]: if a == 'restore' and not fmt.startswith('ORIGINAL_'): continue if a == 'compare': if ofmt not in fmts or nfmt not in SUPPORTED: continue t = _('Compare to the %s format') % (fmt[9:] if fmt.startswith('ORIGINAL_') else ofmt) else: t = t % fmt ac = getattr(book_info, '%s_format_action'%a) ac.current_fmt = (book_id, fmt) ac.setText(t) menu.addAction(ac) if not fmt.upper().startswith('ORIGINAL_'): from calibre.gui2.open_with import populate_menu, edit_programs m = QMenu(_('Open %s with...') % fmt.upper()) populate_menu(m, partial(book_info.open_with, book_id, fmt), fmt) if len(m.actions()) == 0: menu.addAction(_('Open %s with...') % fmt.upper(), partial(book_info.choose_open_with, book_id, fmt)) else: m.addSeparator() m.addAction(_('Add other application for %s files...') % fmt.upper(), partial(book_info.choose_open_with, book_id, fmt)) m.addAction(_('Edit Open With applications...'), partial(edit_programs, fmt, book_info)) menu.addMenu(m) menu.ow = m ac = book_info.copy_link_action ac.current_url = r.linkElement().attribute('data-full-path') if ac.current_url: ac.setText(_('&Copy path to file')) menu.addAction(ac) else: el = r.linkElement() data = el.attribute('data-item') author = el.toPlainText() if unicode(el.attribute('calibre-data')) == u'authors' else None if url and not url.startswith('search:'): for a, t in [('copy', _('&Copy link')), ]: ac = getattr(book_info, '%s_link_action'%a) ac.current_url = url if url.startswith('path:'): ac.current_url = el.attribute('title') ac.setText(t) menu.addAction(ac) if author is not None: menu.addAction(init_manage_action(book_info.manage_action, 'authors', author)) if hasattr(book_info, 'search_internet'): menu.sia = sia = create_search_internet_menu(book_info.search_internet, author) menu.addMenu(sia) search_internet_added = True if hasattr(book_info, 'search_requested'): menu.addAction(_('Search calibre for %s') % author, lambda : book_info.search_requested('authors:"={}"'.format(author.replace('"', r'\"')))) if data: try: field, value, book_id = cPickle.loads(unhexlify(data)) except Exception: field = value = book_id = None if field: if author is None and ( field in ('tags', 'series', 'publisher') or is_category(field)): menu.addAction(init_manage_action(book_info.manage_action, field, value)) ac = book_info.remove_item_action ac.data = (field, value, book_id) ac.setText(_('Remove %s from this book') % value) menu.addAction(ac) if not search_internet_added and hasattr(book_info, 'search_internet'): menu.addSeparator() menu.si = create_search_internet_menu(book_info.search_internet) menu.addMenu(menu.si) if len(menu.actions()) > 0: menu.exec_(ev.globalPos())
def context_menu(self, pos): m = QMenu() if self.items.count() > 0: m.addAction(QIcon(I('edit-copy.png')), _('Copy list of errors to clipboard'), self.copy_to_clipboard) if list(m.actions()): m.exec_(self.mapToGlobal(pos))
def show_context_menu(self, point): item = self.itemAt(point) if item is None or item in set(self.categories.itervalues()): return m = QMenu(self) sel = self.selectedItems() num = len(sel) container = current_container() ci = self.currentItem() if ci is not None: cn = unicode(ci.data(0, NAME_ROLE) or "") mt = unicode(ci.data(0, MIME_ROLE) or "") cat = unicode(ci.data(0, CATEGORY_ROLE) or "") n = elided_text(cn.rpartition("/")[-1]) m.addAction(QIcon(I("save.png")), _("Export %s") % n, partial(self.export, cn)) if ( cn not in container.names_that_must_not_be_changed and cn not in container.names_that_must_not_be_removed and mt not in OEB_FONTS ): m.addAction(_("Replace %s with file...") % n, partial(self.replace, cn)) m.addSeparator() m.addAction(QIcon(I("modified.png")), _("&Rename %s") % n, self.edit_current_item) if is_raster_image(mt): m.addAction( QIcon(I("default_cover.png")), _("Mark %s as cover image") % n, partial(self.mark_as_cover, cn) ) elif current_container().SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == "text": m.addAction( QIcon(I("default_cover.png")), _("Mark %s as cover page") % n, partial(self.mark_as_titlepage, cn) ) m.addSeparator() if num > 0: m.addSeparator() if num > 1: m.addAction(QIcon(I("modified.png")), _("&Bulk rename selected files"), self.request_bulk_rename) m.addAction(QIcon(I("trash.png")), _("&Delete the %d selected file(s)") % num, self.request_delete) m.addSeparator() selected_map = defaultdict(list) for item in sel: selected_map[unicode(item.data(0, CATEGORY_ROLE) or "")].append(unicode(item.data(0, NAME_ROLE) or "")) for items in selected_map.itervalues(): items.sort(key=self.index_of_name) if selected_map["text"]: m.addAction( QIcon(I("format-text-color.png")), _("Link &stylesheets..."), partial(self.link_stylesheets, selected_map["text"]), ) if len(selected_map["text"]) > 1: m.addAction( QIcon(I("merge.png")), _("&Merge selected text files"), partial(self.start_merge, "text", selected_map["text"]), ) if len(selected_map["styles"]) > 1: m.addAction( QIcon(I("merge.png")), _("&Merge selected style files"), partial(self.start_merge, "styles", selected_map["styles"]), ) if len(list(m.actions())) > 0: m.popup(self.mapToGlobal(point))
def _clone_menu(self, orig_m, clone_m): for ac in QMenu.actions(orig_m): if ac.isSeparator(): clone_m.addSeparator() continue clone_m.addAction(ActionWrapper(ac, clone_m))
def details_context_menu_event(view, ev, book_info): # {{{ p = view.page() mf = p.mainFrame() r = mf.hitTestContent(ev.pos()) url = unicode(r.linkUrl().toString(QUrl.None)).strip() menu = p.createStandardContextMenu() ca = view.pageAction(p.Copy) for action in list(menu.actions()): if action is not ca: menu.removeAction(action) if not r.isNull(): if url.startswith('format:'): parts = url.split(':') try: book_id, fmt = int(parts[1]), parts[2].upper() except: import traceback traceback.print_exc() else: from calibre.gui2.ui import get_gui from calibre.ebooks.oeb.polish.main import SUPPORTED db = get_gui().current_db.new_api ofmt = fmt.upper() if fmt.startswith('ORIGINAL_') else 'ORIGINAL_' + fmt nfmt = ofmt[len('ORIGINAL_'):] fmts = {x.upper() for x in db.formats(book_id)} for a, t in [('remove', _('Delete the %s format')), ('save', _('Save the %s format to disk')), ('restore', _('Restore the %s format')), ('compare', ''), ]: if a == 'restore' and not fmt.startswith('ORIGINAL_'): continue if a == 'compare': if ofmt not in fmts or nfmt not in SUPPORTED: continue t = _('Compare to the %s format') % (fmt[9:] if fmt.startswith('ORIGINAL_') else ofmt) else: t = t % fmt ac = getattr(book_info, '%s_format_action'%a) ac.current_fmt = (book_id, fmt) ac.setText(t) menu.addAction(ac) if not fmt.upper().startswith('ORIGINAL_'): from calibre.gui2.open_with import populate_menu, edit_programs m = QMenu(_('Open %s with...') % fmt.upper()) populate_menu(m, partial(book_info.open_with, book_id, fmt), fmt) if len(m.actions()) == 0: menu.addAction(_('Open %s with...') % fmt.upper(), partial(book_info.choose_open_with, book_id, fmt)) else: m.addSeparator() m.addAction(_('Add other application for %s files...') % fmt.upper(), partial(book_info.choose_open_with, book_id, fmt)) m.addAction(_('Edit Open With applications...'), partial(edit_programs, fmt, book_info)) menu.addMenu(m) ac = book_info.copy_link_action ac.current_url = r.linkElement().attribute('data-full-path') if ac.current_url: ac.setText(_('&Copy path to file')) menu.addAction(ac) else: el = r.linkElement() author = el.toPlainText() if unicode(el.attribute('calibre-data')) == u'authors' else None if not url.startswith('search:'): for a, t in [('copy', _('&Copy Link')), ]: ac = getattr(book_info, '%s_link_action'%a) ac.current_url = url if url.startswith('path:'): ac.current_url = el.attribute('title') ac.setText(t) menu.addAction(ac) if author is not None: ac = book_info.manage_author_action ac.current_fmt = author ac.setText(_('Manage %s') % author) menu.addAction(ac) if len(menu.actions()) > 0: menu.exec_(ev.globalPos())
def contextMenuEvent(self, ev): p = self.page() mf = p.mainFrame() r = mf.hitTestContent(ev.pos()) url = unicode(r.linkUrl().toString(QUrl.None)).strip() menu = p.createStandardContextMenu() ca = self.pageAction(p.Copy) for action in list(menu.actions()): if action is not ca: menu.removeAction(action) if not r.isNull(): if url.startswith('format:'): parts = url.split(':') try: book_id, fmt = int(parts[1]), parts[2].upper() except: import traceback traceback.print_exc() else: from calibre.gui2.ui import get_gui from calibre.ebooks.oeb.polish.main import SUPPORTED db = get_gui().current_db.new_api ofmt = fmt.upper() if fmt.startswith( 'ORIGINAL_') else 'ORIGINAL_' + fmt nfmt = ofmt[len('ORIGINAL_'):] fmts = {x.upper() for x in db.formats(book_id)} for a, t in [ ('remove', _('Delete the %s format')), ('save', _('Save the %s format to disk')), ('restore', _('Restore the %s format')), ('compare', ''), ]: if a == 'restore' and not fmt.startswith('ORIGINAL_'): continue if a == 'compare': if ofmt not in fmts or nfmt not in SUPPORTED: continue t = _('Compare to the %s format') % ( fmt[9:] if fmt.startswith('ORIGINAL_') else ofmt) else: t = t % fmt ac = getattr(self, '%s_format_action' % a) ac.current_fmt = (book_id, fmt) ac.setText(t) menu.addAction(ac) if not fmt.upper().startswith('ORIGINAL_'): from calibre.gui2.open_with import populate_menu, edit_programs m = QMenu(_('Open %s with...') % fmt.upper()) populate_menu(m, partial(self.open_with, book_id, fmt), fmt) if len(m.actions()) == 0: menu.addAction( _('Open %s with...') % fmt.upper(), partial(self.choose_open_with, book_id, fmt)) else: m.addSeparator() m.addAction( _('Add other application for %s files...') % fmt.upper(), partial(self.choose_open_with, book_id, fmt)) m.addAction(_('Edit Open With applications...'), partial(edit_programs, fmt, self)) menu.addMenu(m) ac = self.copy_link_action ac.current_url = r.linkElement().attribute( 'data-full-path') if ac.current_url: ac.setText(_('&Copy path to file')) menu.addAction(ac) else: el = r.linkElement() author = el.toPlainText() if unicode( el.attribute('calibre-data')) == u'authors' else None if not url.startswith('search:'): for a, t in [ ('copy', _('&Copy Link')), ]: ac = getattr(self, '%s_link_action' % a) ac.current_url = url if url.startswith('path:'): ac.current_url = el.attribute('title') ac.setText(t) menu.addAction(ac) if author is not None: ac = self.manage_author_action ac.current_fmt = author ac.setText(_('Manage %s') % author) menu.addAction(ac) if len(menu.actions()) > 0: menu.exec_(ev.globalPos())