1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
"""
Provides a menu that display the list of recent files and a RecentFilesManager
which use your application's QSettings to store the list of recent files.
"""
import sys
import os
from pyqode.core import icons
from pyqode.qt import QtCore, QtGui, QtWidgets
class RecentFilesManager(QtCore.QObject):
"""
Manages a list of recent files. The list of files is stored in your
application QSettings.
"""
#: Maximum number of files kept in the list.
max_recent_files = 15
updated = QtCore.Signal()
def __init__(self, organisation, application, qsettings=None):
super(RecentFilesManager, self).__init__()
if qsettings is None:
self._settings = QtCore.QSettings(organisation, application)
else:
self._settings = qsettings
def clear(self):
""" Clears recent files in QSettings """
self.set_value('list', [])
self.updated.emit()
def remove(self, filename):
"""
Remove a file path from the list of recent files.
:param filename: Path of the file to remove
"""
files = self.get_value('list', [])
files.remove(filename)
self.set_value('list', files)
self.updated.emit()
def get_value(self, key, default=None):
"""
Reads value from QSettings
:param key: value key
:param default: default value.
:return: value
"""
def unique(seq, idfun=None):
if idfun is None:
def idfun(x):
return x
# order preserving
seen = {}
result = []
for item in seq:
marker = idfun(item)
if marker in seen:
continue
seen[marker] = 1
result.append(item)
return result
lst = self._settings.value('recent_files/%s' % key, default)
# emtpy list
if lst is None:
lst = []
# single file
if isinstance(lst, str):
lst = [lst]
return unique([os.path.normpath(pth) for pth in lst])
def set_value(self, key, value):
"""
Set the recent files value in QSettings.
:param key: value key
:param value: new value
"""
if value is None:
value = []
value = [os.path.normpath(pth) for pth in value]
self._settings.setValue('recent_files/%s' % key, value)
def get_recent_files(self):
"""
Gets the list of recent files. (files that do not exists anymore
are automatically filtered)
"""
ret_val = []
files = self.get_value('list', [])
# filter files, remove files that do not exist anymore
for file in files:
if file is not None and os.path.exists(file):
if os.path.ismount(file) and \
sys.platform == 'win32' and not file.endswith('\\'):
file += '\\'
if file not in ret_val:
ret_val.append(file)
return ret_val
def open_file(self, file):
"""
Adds a file to the list (and move it to the top of the list if the
file already exists)
:param file: file path to add the list of recent files.
"""
files = self.get_recent_files()
try:
files.remove(file)
except ValueError:
pass
files.insert(0, file)
# discard old files
del files[self.max_recent_files:]
self.set_value('list', files)
self.updated.emit()
def last_file(self):
"""
Returns the path to the last opened file.
"""
files = self.get_recent_files()
try:
return files[0]
except IndexError:
return None
class MenuRecentFiles(QtWidgets.QMenu):
"""
Menu that manage the list of recent files.
To use the menu, simply connect to the open_requested signal.
"""
#: Signal emitted when the user clicked on a recent file action.
#: The parameter is the path of the file to open.
open_requested = QtCore.Signal(str)
clear_requested = QtCore.Signal()
def __init__(self, parent, recent_files_manager=None,
title='Recent files',
icon_provider=None,
clear_icon=None):
"""
:param parent: parent object
:param icon_provider: Object that provides icon based on the file path.
:type icon_provider: QtWidgets.QFileIconProvider
:param clear_icon: Clear action icon. This parameter is a tuple made up
of the icon theme name and the fallback icon path (from your
resources). Default is None, clear action has no icons.
"""
super(MenuRecentFiles, self).__init__(title, parent)
if icon_provider is None:
self.icon_provider = QtWidgets.QFileIconProvider()
else:
self.icon_provider = icon_provider
self.clear_icon = clear_icon
#: Recent files manager
self.manager = recent_files_manager
#: List of recent files actions
self.recent_files_actions = []
self.update_actions()
def update_actions(self):
"""
Updates the list of actions.
"""
self.clear()
self.recent_files_actions[:] = []
for file in self.manager.get_recent_files():
action = QtWidgets.QAction(self)
action.setText(os.path.split(file)[1])
action.setToolTip(file)
action.setStatusTip(file)
action.setData(file)
action.setIcon(self.icon_provider.icon(QtCore.QFileInfo(file)))
action.triggered.connect(self._on_action_triggered)
self.addAction(action)
self.recent_files_actions.append(action)
self.addSeparator()
action_clear = QtWidgets.QAction(_('Clear list'), self)
action_clear.triggered.connect(self.clear_recent_files)
if isinstance(self.clear_icon, QtGui.QIcon):
action_clear.setIcon(self.clear_icon)
elif self.clear_icon:
theme = ''
if len(self.clear_icon) == 2:
theme, path = self.clear_icon
else:
path = self.clear_icon
icons.icon(theme, path, 'fa.times-circle')
self.addAction(action_clear)
def clear_recent_files(self):
""" Clear recent files and menu. """
self.manager.clear()
self.update_actions()
self.clear_requested.emit()
def _on_action_triggered(self):
"""
Emits open_requested when a recent file action has been triggered.
"""
action = self.sender()
assert isinstance(action, QtWidgets.QAction)
path = action.data()
self.open_requested.emit(path)
self.update_actions()
|