mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Pull from trunk
This commit is contained in:
commit
3b9a290ec0
@ -4,6 +4,53 @@
|
||||
# for important features/bug fixes.
|
||||
# Also, each release can have new and improved recipes.
|
||||
|
||||
- version: 0.7.6
|
||||
date: 2010-06-28
|
||||
|
||||
new features:
|
||||
- title: "Add support for the new firmware of the Azbooka"
|
||||
tickets: [5994]
|
||||
|
||||
- title: "A few speedups for calibre startup, should add up to a few seconds of startup time on slower machines"
|
||||
|
||||
- title: "Support for the Sweem MM300"
|
||||
|
||||
- title: "Add keyboard shorcut for Download metadata and covers"
|
||||
|
||||
bug fixes:
|
||||
- title: "Fix regression in 0.7.5 that broke conversion of malformed HTML files (like those Microsoft Word outputs)"
|
||||
type: major
|
||||
tickets: [5991]
|
||||
|
||||
- title: "Don't download tags from librarything, as the tagging there is not very good"
|
||||
|
||||
- title: "Add mimetype for FB2 so that it can be served by the content server"
|
||||
tickets: [6011]
|
||||
|
||||
- title: "Ensure cover is not resized to less than the available space in the Edit Meta Information dialog"
|
||||
tickets: [6001]
|
||||
|
||||
- title: "SONY driver: Only update collections when sending book to device for the first time"
|
||||
|
||||
- title: "calibre should now work on windows when the location for the library contains non-ascii characters"
|
||||
tickets: [5983]
|
||||
|
||||
- title: "Cover browser once again distorts instead of cropping covers that have an incorrect aspect ratio"
|
||||
|
||||
- title: "ISBNDb metadata plugin: Fix bug causing only first page of results to be fetched"
|
||||
|
||||
- title: "Move iTunes driver to the bottom so that it doesn't interfere with device detection for people that have iphones and an ereader plugged in"
|
||||
|
||||
improved recipes:
|
||||
- Houston Chronicle
|
||||
- Hindu
|
||||
- Times of India
|
||||
- New York Times
|
||||
|
||||
new recipes:
|
||||
- title: Winnipeg Sun
|
||||
author: rty
|
||||
|
||||
- version: 0.7.5
|
||||
date: 2010-06-25
|
||||
|
||||
|
@ -28,7 +28,7 @@ class OldNewThing(BasicNewsRecipe):
|
||||
}
|
||||
|
||||
remove_attributes = ['width','height']
|
||||
keep_only_tags = [dict(attrs={'class':['postsub','comment']})]
|
||||
|
||||
keep_only_tags = [dict(attrs={'class':'full-post'})]
|
||||
remove_tags = [dict(attrs={'class':['post-attributes','post-tags','post-actions']})]
|
||||
feeds = [(u'Posts', u'http://blogs.msdn.com/oldnewthing/rss.xml')]
|
||||
|
||||
|
@ -153,6 +153,18 @@
|
||||
<Property Id="WixShellExecTarget" Value="[#{exe_map[calibre]}]" />
|
||||
<CustomAction Id="LaunchApplication" BinaryKey="WixCA"
|
||||
DllEntry="WixShellExec" Impersonate="yes"/>
|
||||
<InstallExecuteSequence>
|
||||
<FileCost Suppress="yes" />
|
||||
</InstallExecuteSequence>
|
||||
<InstallUISequence>
|
||||
<FileCost Suppress="yes" />
|
||||
</InstallUISequence>
|
||||
<AdminExecuteSequence>
|
||||
<FileCost Suppress="yes" />
|
||||
</AdminExecuteSequence>
|
||||
<AdminUISequence>
|
||||
<FileCost Suppress="yes" />
|
||||
</AdminUISequence>
|
||||
|
||||
</Product>
|
||||
</Wix>
|
||||
|
@ -30,6 +30,7 @@ mimetypes.add_type('application/epub+zip', '.epub')
|
||||
mimetypes.add_type('text/x-sony-bbeb+xml', '.lrs')
|
||||
mimetypes.add_type('application/xhtml+xml', '.xhtml')
|
||||
mimetypes.add_type('image/svg+xml', '.svg')
|
||||
mimetypes.add_type('text/fb2+xml', '.fb2')
|
||||
mimetypes.add_type('application/x-sony-bbeb', '.lrf')
|
||||
mimetypes.add_type('application/x-sony-bbeb', '.lrx')
|
||||
mimetypes.add_type('application/x-dtbncx+xml', '.ncx')
|
||||
|
@ -2,7 +2,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = 'calibre'
|
||||
__version__ = '0.7.5'
|
||||
__version__ = '0.7.6'
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
|
||||
import re
|
||||
|
@ -298,6 +298,7 @@ class USBMS(CLI, Device):
|
||||
# Clear the _new_book indication, as we are supposed to be done with
|
||||
# adding books at this point
|
||||
for blist in booklists:
|
||||
if blist is not None:
|
||||
for book in blist:
|
||||
book._new_book = False
|
||||
|
||||
|
@ -151,6 +151,7 @@ cpalmdoc_do_compress(buffer *b, char *output) {
|
||||
for (j=0; j < temp.len; j++) *(output++) = (char)temp.data[j];
|
||||
}
|
||||
}
|
||||
PyMem_Free(temp.data);
|
||||
return output - head;
|
||||
}
|
||||
|
||||
@ -168,7 +169,9 @@ cpalmdoc_compress(PyObject *self, PyObject *args) {
|
||||
for (j = 0; j < input_len; j++)
|
||||
b.data[j] = (_input[j] < 0) ? _input[j]+256 : _input[j];
|
||||
b.len = input_len;
|
||||
output = (char *)PyMem_Malloc(sizeof(char) * b.len);
|
||||
// Make the output buffer larger than the input as sometimes
|
||||
// compression results in a larger block
|
||||
output = (char *)PyMem_Malloc(sizeof(char) * (int)(1.25*b.len));
|
||||
if (output == NULL) return PyErr_NoMemory();
|
||||
j = cpalmdoc_do_compress(&b, output);
|
||||
if ( j == 0) return PyErr_NoMemory();
|
||||
|
@ -313,6 +313,8 @@ def search(title=None, author=None, publisher=None, isbn=None, isbndb_key=None,
|
||||
def sort_func(x, y):
|
||||
|
||||
def cleanup_title(s):
|
||||
if s is None:
|
||||
s = _('Unknown')
|
||||
s = s.strip().lower()
|
||||
s = prefix_pat.sub(' ', s)
|
||||
s = trailing_paren_pat.sub('', s)
|
||||
|
@ -133,10 +133,10 @@ def get_social_metadata(title, authors, publisher, isbn, username=None,
|
||||
if match is not None:
|
||||
si = float(match.group())
|
||||
mi.series_index = si
|
||||
tags = root.xpath('//div[@class="tags"]/span[@class="tag"]/a')
|
||||
if tags:
|
||||
mi.tags = [html.tostring(x, method='text', encoding=unicode) for x
|
||||
in tags]
|
||||
#tags = root.xpath('//div[@class="tags"]/span[@class="tag"]/a')
|
||||
#if tags:
|
||||
# mi.tags = [html.tostring(x, method='text', encoding=unicode) for x
|
||||
# in tags]
|
||||
span = root.xpath(
|
||||
'//table[@class="wsltable"]/tr[@class="wslcontent"]/td[4]//span')
|
||||
if span:
|
||||
|
@ -882,7 +882,7 @@ class Manifest(object):
|
||||
"<?xml version='1.0' encoding='utf-8'?><o:p></o:p>",
|
||||
'')
|
||||
data = data.replace("<?xml version='1.0' encoding='utf-8'??>", '')
|
||||
data = etree.fromstring(data)
|
||||
data = etree.fromstring(data, parser=RECOVER_PARSER)
|
||||
elif namespace(data.tag) != XHTML_NS:
|
||||
# OEB_DOC_NS, but possibly others
|
||||
ns = namespace(data.tag)
|
||||
|
@ -87,6 +87,9 @@ class MetadataWidget(Widget, Ui_Form):
|
||||
if not pm.isNull():
|
||||
self.cover.setPixmap(pm)
|
||||
self.cover_data = cover
|
||||
else:
|
||||
self.cover.setPixmap(QPixmap(I('default_cover.svg')))
|
||||
|
||||
|
||||
def initialize_combos(self):
|
||||
self.initalize_authors()
|
||||
|
@ -20,36 +20,6 @@
|
||||
<string>Book Cover</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="_3">
|
||||
<item>
|
||||
<widget class="ImageView" name="cover">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../../../resources/images.qrc">:/images/book.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="opt_prefer_metadata_cover">
|
||||
<property name="text">
|
||||
<string>Use cover from &source file</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QVBoxLayout" name="_4">
|
||||
<property name="spacing">
|
||||
@ -101,6 +71,30 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="opt_prefer_metadata_cover">
|
||||
<property name="text">
|
||||
<string>Use cover from &source file</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="_3">
|
||||
<item>
|
||||
<widget class="ImageView" name="cover" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>opt_prefer_metadata_cover</zorder>
|
||||
<zorder></zorder>
|
||||
@ -308,11 +302,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ImageView</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EnLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
@ -328,6 +317,12 @@
|
||||
<extends>QLineEdit</extends>
|
||||
<header>widgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ImageView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>calibre/gui2/widgets.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>title</tabstop>
|
||||
|
@ -11,7 +11,7 @@ import re
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from PyQt4.Qt import SIGNAL, QObject, QCoreApplication, Qt, QTimer, QThread, QDate, \
|
||||
from PyQt4.Qt import SIGNAL, QObject, Qt, QTimer, QThread, QDate, \
|
||||
QPixmap, QListWidgetItem, QDialog
|
||||
|
||||
from calibre.gui2 import error_dialog, file_icon_provider, dynamic, \
|
||||
@ -25,7 +25,6 @@ from calibre.ebooks import BOOK_EXTENSIONS
|
||||
from calibre.ebooks.metadata import string_to_authors, \
|
||||
authors_to_string, check_isbn
|
||||
from calibre.ebooks.metadata.library_thing import cover_from_isbn
|
||||
from calibre import islinux, isfreebsd
|
||||
from calibre.ebooks.metadata.meta import get_metadata
|
||||
from calibre.utils.config import prefs, tweaks
|
||||
from calibre.utils.date import qt_to_dt
|
||||
@ -311,7 +310,6 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
||||
self.formats.setAcceptDrops(True)
|
||||
self.cover_changed = False
|
||||
self.cpixmap = None
|
||||
self.cover.setAcceptDrops(True)
|
||||
self.pubdate.setMinimumDate(QDate(100,1,1))
|
||||
pubdate_format = tweaks['gui_pubdate_display_format']
|
||||
if pubdate_format is not None:
|
||||
@ -399,11 +397,6 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
||||
self.series.lineEdit().editingFinished.connect(self.increment_series_index)
|
||||
|
||||
self.show()
|
||||
height_of_rest = self.frameGeometry().height() - self.cover.height()
|
||||
width_of_rest = self.frameGeometry().width() - self.cover.width()
|
||||
ag = QCoreApplication.instance().desktop().availableGeometry(self)
|
||||
self.cover.MAX_HEIGHT = ag.height()-(25 if (islinux or isfreebsd) else 0)-height_of_rest
|
||||
self.cover.MAX_WIDTH = ag.width()-(25 if (islinux or isfreebsd) else 0)-width_of_rest
|
||||
pm = QPixmap()
|
||||
if cover:
|
||||
pm.loadFromData(cover)
|
||||
|
@ -576,22 +576,13 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="ImageView" name="cover">
|
||||
<widget class="ImageView" name="cover" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
<verstretch>100</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../../../resources/images.qrc">:/images/book.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@ -707,11 +698,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ImageView</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EnLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
@ -732,6 +718,12 @@
|
||||
<extends>QListWidget</extends>
|
||||
<header location="global">calibre/gui2/widgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ImageView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>calibre/gui2/widgets.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>title</tabstop>
|
||||
|
@ -13,7 +13,7 @@ from PyQt4.Qt import QListView, QIcon, QFont, QLabel, QListWidget, \
|
||||
QRegExp, QSettings, QSize, QModelIndex, QSplitter, \
|
||||
QAbstractButton, QPainter, QLineEdit, QComboBox, \
|
||||
QMenu, QStringListModel, QCompleter, QStringList, \
|
||||
QTimer
|
||||
QTimer, QRect
|
||||
|
||||
from calibre.gui2 import NONE, error_dialog, pixmap_to_data, gprefs
|
||||
|
||||
@ -146,10 +146,15 @@ class FormatList(QListWidget):
|
||||
return QListWidget.keyPressEvent(self, event)
|
||||
|
||||
|
||||
class ImageView(QLabel):
|
||||
class ImageView(QWidget):
|
||||
|
||||
MAX_WIDTH = 400
|
||||
MAX_HEIGHT = 300
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
self._pixmap = QPixmap(self)
|
||||
self.setMinimumSize(QSize(150, 200))
|
||||
self.setAcceptDrops(True)
|
||||
|
||||
# Drag 'n drop {{{
|
||||
DROPABBLE_EXTENSIONS = IMAGE_EXTENSIONS
|
||||
|
||||
@classmethod
|
||||
@ -186,13 +191,45 @@ class ImageView(QLabel):
|
||||
|
||||
def dragMoveEvent(self, event):
|
||||
event.acceptProposedAction()
|
||||
# }}}
|
||||
|
||||
def setPixmap(self, pixmap):
|
||||
QLabel.setPixmap(self, pixmap)
|
||||
width, height = fit_image(pixmap.width(), pixmap.height(), self.MAX_WIDTH, self.MAX_HEIGHT)[1:]
|
||||
self.setMaximumWidth(width)
|
||||
self.setMaximumHeight(height)
|
||||
if not isinstance(pixmap, QPixmap):
|
||||
raise TypeError('Must use a QPixmap')
|
||||
self._pixmap = pixmap
|
||||
self.updateGeometry()
|
||||
self.update()
|
||||
|
||||
def pixmap(self):
|
||||
return self._pixmap
|
||||
|
||||
def sizeHint(self):
|
||||
if self._pixmap.isNull():
|
||||
return self.minimumSize()
|
||||
return self._pixmap.size()
|
||||
|
||||
def paintEvent(self, event):
|
||||
QWidget.paintEvent(self, event)
|
||||
pmap = self._pixmap
|
||||
if pmap.isNull():
|
||||
return
|
||||
w, h = pmap.width(), pmap.height()
|
||||
cw, ch = self.rect().width(), self.rect().height()
|
||||
scaled, nw, nh = fit_image(w, h, cw, ch)
|
||||
if scaled:
|
||||
pmap = pmap.scaled(nw, nh, Qt.IgnoreAspectRatio,
|
||||
Qt.SmoothTransformation)
|
||||
w, h = pmap.width(), pmap.height()
|
||||
x = int(abs(cw - w)/2.)
|
||||
y = int(abs(ch - h)/2.)
|
||||
target = QRect(x, y, w, h)
|
||||
p = QPainter(self)
|
||||
p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
|
||||
p.drawPixmap(target, pmap)
|
||||
p.end()
|
||||
|
||||
|
||||
# Clipboard copy/paste # {{{
|
||||
def contextMenuEvent(self, ev):
|
||||
cm = QMenu(self)
|
||||
copy = cm.addAction(_('Copy Image'))
|
||||
@ -215,6 +252,7 @@ class ImageView(QLabel):
|
||||
self.setPixmap(pmap)
|
||||
self.emit(SIGNAL('cover_changed(PyQt_PyObject)'),
|
||||
pixmap_to_data(pmap))
|
||||
# }}}
|
||||
|
||||
|
||||
class LocationModel(QAbstractListModel):
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user