On windows when changing title or author via the main book list, handle the case of one of the books files being open in naother program more gracefully. Fixes #880585 (Changing the case of title generates "OSError:[Errno 13] Permission Denied...")

This commit is contained in:
Kovid Goyal 2011-11-10 12:35:24 +05:30
parent 794f010dc0
commit 36e40ee553
2 changed files with 75 additions and 56 deletions

View File

@ -5,13 +5,13 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import functools, re, os, traceback
import functools, re, os, traceback, errno
from collections import defaultdict
from PyQt4.Qt import (QAbstractTableModel, Qt, pyqtSignal, QIcon, QImage,
QModelIndex, QVariant, QDateTime, QColor)
from calibre.gui2 import NONE, UNDEFINED_QDATETIME
from calibre.gui2 import NONE, UNDEFINED_QDATETIME, error_dialog
from calibre.utils.pyparsing import ParseException
from calibre.ebooks.metadata import fmt_sidx, authors_to_string, string_to_authors
from calibre.ebooks.metadata.book.base import SafeFormat
@ -851,6 +851,25 @@ class BooksModel(QAbstractTableModel): # {{{
def setData(self, index, value, role):
if role == Qt.EditRole:
from calibre.gui2.ui import get_gui
try:
return self._set_data(index, value)
except (IOError, OSError) as err:
if getattr(err, 'errno', None) == errno.EACCES: # Permission denied
import traceback
error_dialog(get_gui(), _('Permission denied'),
_('Could not change the on disk location of this'
' book. Is it open in another program?'),
det_msg=traceback.format_exc(), show=True)
except:
import traceback
traceback.print_exc()
error_dialog(get_gui(), _('Failed to set data'),
_('Could not set data, click Show Details to see why.'),
det_msg=traceback.format_exc(), show=True)
return False
def _set_data(self, index, value):
row, col = index.row(), index.column()
column = self.column_map[col]
if self.is_custom_column(column):
@ -859,9 +878,9 @@ class BooksModel(QAbstractTableModel): # {{{
else:
if column not in self.editable_cols:
return False
val = int(value.toInt()[0]) if column == 'rating' else \
value.toDateTime() if column in ('timestamp', 'pubdate') else \
unicode(value.toString()).strip()
val = (int(value.toInt()[0]) if column == 'rating' else
value.toDateTime() if column in ('timestamp', 'pubdate')
else unicode(value.toString()).strip())
id = self.db.id(row)
books_to_refresh = set([id])
if column == 'rating':

View File

@ -440,8 +440,8 @@ class MetadataSingleDialogBase(ResizableDialog):
return False
self.books_to_refresh |= getattr(widget, 'books_to_refresh',
set([]))
except IOError as err:
if err.errno == errno.EACCES: # Permission denied
except (IOError, OSError) as err:
if getattr(err, 'errno', None) == errno.EACCES: # Permission denied
import traceback
fname = err.filename if err.filename else 'file'
error_dialog(self, _('Permission denied'),