mirror of
https://github.com/kovidgoyal/calibre.git
synced 2026-05-28 09:42:33 -04:00
IGN: Miscellaneous minor fixes
This commit is contained in:
@@ -25,7 +25,7 @@ manual:
|
||||
|
||||
pictureflow :
|
||||
mkdir -p src/calibre/plugins && rm -f src/calibre/plugins/*pictureflow* && \
|
||||
cd src/calibre/gui2/pictureflow && \
|
||||
cd src/calibre/gui2/pictureflow && rm *.o && \
|
||||
mkdir -p .build && cd .build && rm -f * && \
|
||||
qmake ../pictureflow-lib.pro && make && \
|
||||
cd ../PyQt && \
|
||||
|
||||
+35
-2
@@ -3,7 +3,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
''' Create an OSX installer '''
|
||||
|
||||
import sys, re, os, shutil, subprocess, stat
|
||||
import sys, re, os, shutil, subprocess, stat, glob
|
||||
from setup import VERSION, APPNAME, scripts, main_modules, basenames, main_functions
|
||||
from setuptools import setup
|
||||
from py2app.build_app import py2app
|
||||
@@ -132,7 +132,12 @@ _check_symlinks_prescript()
|
||||
fp = '@executable_path/../Frameworks/'
|
||||
print 'Fixing qt dependencies for:', os.path.basename(path)
|
||||
for dep in deps:
|
||||
module = re.search(r'(Qt\w+?)\.framework', dep).group(1)
|
||||
match = re.search(r'(Qt\w+?)\.framework', dep)
|
||||
if not match:
|
||||
print dep
|
||||
raise Exception('a')
|
||||
continue
|
||||
module = match.group(1)
|
||||
newpath = fp + '%s.framework/Versions/Current/%s'%(module, module)
|
||||
cmd = ' '.join(['install_name_tool', '-change', dep, newpath, path])
|
||||
subprocess.check_call(cmd, shell=True)
|
||||
@@ -156,9 +161,34 @@ _check_symlinks_prescript()
|
||||
|
||||
|
||||
#deps = BuildAPP.qt_dependencies(path)
|
||||
|
||||
def build_plugins(self):
|
||||
cwd = os.getcwd()
|
||||
qmake = '/Users/kovid/qt/bin/qmake'
|
||||
files = []
|
||||
try:
|
||||
print 'Building pictureflow'
|
||||
os.chdir('src/calibre/gui2/pictureflow')
|
||||
for f in glob.glob('*.o'): os.unlink(f)
|
||||
subprocess.check_call([qmake, 'pictureflow-lib.pro'])
|
||||
subprocess.check_call(['make'])
|
||||
files.append((os.path.abspath(os.path.realpath('libpictureflow.dylib')), 'libpictureflow.dylib'))
|
||||
os.chdir('PyQt/.build')
|
||||
subprocess.check_call(['python', '../configure.py'])
|
||||
subprocess.check_call(['make'])
|
||||
files.append((os.path.abspath('pictureflow.so'), 'pictureflow.so'))
|
||||
subprocess.check_call(['install_name_tool', '-change', 'libpictureflow.0.dylib', '@executable_path/../Frameworks/libpictureflow.dylib', 'pictureflow.so'])
|
||||
for i in range(2):
|
||||
deps = BuildAPP.qt_dependencies(files[i][0])
|
||||
BuildAPP.fix_qt_dependencies(files[i][0], deps)
|
||||
|
||||
return files
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
def run(self):
|
||||
plugin_files = self.build_plugins()
|
||||
py2app.run(self)
|
||||
self.add_qt_plugins()
|
||||
resource_dir = os.path.join(self.dist_dir,
|
||||
@@ -188,6 +218,9 @@ _check_symlinks_prescript()
|
||||
print
|
||||
print 'Adding pdftohtml'
|
||||
os.link(os.path.expanduser('~/pdftohtml'), os.path.join(frameworks_dir, 'pdftohtml'))
|
||||
print 'Adding plugins'
|
||||
for src, dest in plugin_files:
|
||||
os.link(src, os.path.join(frameworks_dir, dest))
|
||||
print
|
||||
print 'Installing prescipt'
|
||||
sf = [os.path.basename(s) for s in all_names]
|
||||
|
||||
@@ -40,7 +40,7 @@ def xml_to_unicode(raw, verbose=False):
|
||||
return u'', encoding
|
||||
if isinstance(raw, unicode):
|
||||
return raw, encoding
|
||||
match = re.compile('^\s*<\?.*encoding=[\'"](.*?)[\'"].*\?>', re.IGNORECASE).match(raw)
|
||||
match = re.compile(r'<[^<>]+encoding=[\'"](.*?)[\'"][^<>]*>', re.IGNORECASE).search(raw)
|
||||
if match is None:
|
||||
match = re.compile(r'<meta.*?content=[\'"].*?charset=([^\s\'"]+).*?[\'"]', re.IGNORECASE).search(raw)
|
||||
if match is not None:
|
||||
|
||||
@@ -5,11 +5,11 @@ import sys, os, re, StringIO, traceback
|
||||
from PyQt4.QtCore import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, \
|
||||
QByteArray, QLocale, QTranslator, QUrl
|
||||
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
|
||||
QIcon, QTableView
|
||||
QIcon, QTableView, QDialogButtonBox
|
||||
|
||||
ORG_NAME = 'KovidsBrain'
|
||||
APP_UID = 'libprs500'
|
||||
from calibre import __author__, islinux, iswindows, Settings
|
||||
from calibre import __author__, islinux, iswindows, Settings, isosx
|
||||
|
||||
NONE = QVariant() #: Null value to return from the data function of item models
|
||||
|
||||
@@ -339,3 +339,42 @@ def pixmap_to_data(pixmap, format='JPEG'):
|
||||
buf.open(QBuffer.WriteOnly)
|
||||
pixmap.save(buf, format)
|
||||
return str(ba.data())
|
||||
|
||||
class TranslatedDialogButtonBox(QDialogButtonBox):
|
||||
|
||||
STRINGS = {
|
||||
QDialogButtonBox.Ok : (_('&OK'), QDialogButtonBox.AcceptRole),
|
||||
QDialogButtonBox.Open : (_('&Open'), QDialogButtonBox.AcceptRole),
|
||||
QDialogButtonBox.Save : (_('&Save'), QDialogButtonBox.AcceptRole),
|
||||
QDialogButtonBox.Cancel : (_('Cancel'), QDialogButtonBox.RejectRole),
|
||||
QDialogButtonBox.Close : (_('&Close'), QDialogButtonBox.RejectRole),
|
||||
QDialogButtonBox.Discard : (_("&Don't Save") if isosx else _('&Discard'), QDialogButtonBox.DestructiveRole),
|
||||
QDialogButtonBox.Apply : (_('&Apply'), QDialogButtonBox.ApplyRole),
|
||||
QDialogButtonBox.Reset : (_('&Reset'), QDialogButtonBox.ResetRole),
|
||||
QDialogButtonBox.RestoreDefaults : (_('Restore &Defaults'), QDialogButtonBox.ResetRole),
|
||||
QDialogButtonBox.Help : (_('&Help'), QDialogButtonBox.HelpRole),
|
||||
QDialogButtonBox.SaveAll : (_('Save &All'), QDialogButtonBox.AcceptRole),
|
||||
QDialogButtonBox.Yes : (_('&Yes'), QDialogButtonBox.YesRole),
|
||||
QDialogButtonBox.YesToAll : (_('Yes to &All'), QDialogButtonBox.YesRole),
|
||||
QDialogButtonBox.No : (_('&No'), QDialogButtonBox.NoRole),
|
||||
QDialogButtonBox.NoToAll : (_('N&o to All'), QDialogButtonBox.NoRole),
|
||||
QDialogButtonBox.Abort : (_('A&bort'), QDialogButtonBox.RejectRole),
|
||||
QDialogButtonBox.Retry : (_('Re&try'), QDialogButtonBox.AcceptRole),
|
||||
QDialogButtonBox.Ignore : (_('I&gnore'), QDialogButtonBox.AcceptRole),
|
||||
}
|
||||
|
||||
def setStandardButtons(self, buttons):
|
||||
default = False
|
||||
for i in self.STRINGS.keys():
|
||||
if i & buttons:
|
||||
msg, role = self.STRINGS[i]
|
||||
button = self.addButton(msg, role)
|
||||
if not default:
|
||||
default = True
|
||||
button.setDefault(True)
|
||||
|
||||
|
||||
try:
|
||||
from calibre.utils.single_qt_application import SingleApplication
|
||||
except:
|
||||
SingleApplication = None
|
||||
@@ -33,11 +33,11 @@ class Matches(QAbstractTableModel):
|
||||
return NONE
|
||||
text = ""
|
||||
if orientation == Qt.Horizontal:
|
||||
if section == 0: text = "Title"
|
||||
elif section == 1: text = "Author(s)"
|
||||
elif section == 2: text = "Author Sort"
|
||||
elif section == 3: text = "Publisher"
|
||||
elif section == 4: text = "ISBN"
|
||||
if section == 0: text = _("Title")
|
||||
elif section == 1: text = _("Author(s)")
|
||||
elif section == 2: text = _("Author Sort")
|
||||
elif section == 3: text = _("Publisher")
|
||||
elif section == 4: text = _("ISBN")
|
||||
|
||||
return QVariant(self.trUtf8(text))
|
||||
else:
|
||||
|
||||
@@ -320,7 +320,7 @@ class BooksModel(QAbstractTableModel):
|
||||
elif col == 5:
|
||||
pub = self.db.publisher(row)
|
||||
if pub:
|
||||
return QVariant(BooksView.wrap(pub, 20))
|
||||
return QVariant(pub)
|
||||
elif col == 6:
|
||||
tags = self.db.tags(row)
|
||||
if tags:
|
||||
|
||||
@@ -102,10 +102,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">For help visit <a href="http://__appname__.kovidgoyal.net/user_manual"><span style=" text-decoration: underline; color:#0000ff;">__appname__.kovidgoyal.net</span></a><br /><br /><span style=" font-weight:600;">__appname__</span>: %1 by <span style=" font-weight:600;">Kovid Goyal</span> %2<br />%3</p></body></html></string>
|
||||
<string></string>
|
||||
</property>
|
||||
<property name="textFormat" >
|
||||
<enum>Qt::RichText</enum>
|
||||
|
||||
@@ -39,7 +39,9 @@ def build_forms(forms):
|
||||
dat = dat.replace('import images_rc', 'from calibre.gui2 import images_rc')
|
||||
dat = dat.replace('from library import', 'from calibre.gui2.library import')
|
||||
dat = dat.replace('from widgets import', 'from calibre.gui2.widgets import')
|
||||
dat += '\nfrom calibre.gui2 import TranslatedDialogButtonBox'
|
||||
dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(?<!\\)",.+?\)', re.DOTALL).sub(r'_("\1")', dat)
|
||||
dat = re.compile(r'QtGui.QDialogButtonBox').sub('TranslatedDialogButtonBox', dat)
|
||||
open(compiled_form, 'wb').write(dat)
|
||||
|
||||
|
||||
|
||||
@@ -30,8 +30,10 @@ makefile = pyqtconfig.QtGuiModuleMakefile (
|
||||
# Add the library we are wrapping. The name doesn't include any platform
|
||||
# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
|
||||
# ".dll" extension on Windows).
|
||||
makefile.extra_lib_dirs = ['../../.build', '..\\..\\release']
|
||||
makefile.extra_libs = ['pictureflow0' if 'win' in sys.platform else "pictureflow"]
|
||||
makefile.extra_lib_dirs = ['../../.build', '..\\..\\release', '../../']
|
||||
makefile.extra_libs = ['pictureflow0' if 'win' in sys.platform and 'darwin' not in sys.platform else "pictureflow"]
|
||||
makefile.extra_cflags = ['-arch i386', '-arch ppc']
|
||||
makefile.extra_cxxflags = makefile.extra_cflags
|
||||
if 'linux' in sys.platform:
|
||||
makefile.extra_lflags = ['-Wl,--rpath=.']
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from PyQt4.QtGui import QListView, QIcon, QFont, QLabel, QListWidget, \
|
||||
QSyntaxHighlighter, QCursor, QColor, QWidget, \
|
||||
QAbstractItemDelegate, QStyle
|
||||
from PyQt4.QtCore import QAbstractListModel, QVariant, Qt, QRect, SIGNAL, \
|
||||
QObject, QRegExp, QSize, QRectF
|
||||
QObject, QRegExp, QRectF
|
||||
|
||||
from calibre.gui2.jobs import DetailView
|
||||
from calibre.gui2 import human_readable, NONE, TableView, qstring_to_unicode, error_dialog
|
||||
@@ -18,6 +18,8 @@ from calibre import fit_image, get_font_families, Settings
|
||||
from calibre.ebooks.metadata.meta import get_filename_pat, metadata_from_filename, \
|
||||
set_filename_pat
|
||||
|
||||
|
||||
|
||||
class FilenamePattern(QWidget, Ui_Form):
|
||||
|
||||
def __init__(self, parent):
|
||||
|
||||
@@ -26,6 +26,7 @@ TRANSLATIONS = [
|
||||
'it',
|
||||
'bg',
|
||||
'nds',
|
||||
'ru',
|
||||
]
|
||||
|
||||
def source_files():
|
||||
|
||||
+482
-400
File diff suppressed because it is too large
Load Diff
+475
-393
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+475
-393
File diff suppressed because it is too large
Load Diff
+475
-393
File diff suppressed because it is too large
Load Diff
+475
-393
File diff suppressed because it is too large
Load Diff
+502
-405
File diff suppressed because it is too large
Load Diff
+482
-400
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+482
-400
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env python
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
'''
|
||||
Enforces running of only a single application instance and allows for messaging between
|
||||
applications using a local socket.
|
||||
'''
|
||||
import atexit
|
||||
|
||||
from PyQt4.QtCore import QByteArray, QDataStream, QIODevice, SIGNAL, QObject, Qt
|
||||
from PyQt4.QtNetwork import QLocalSocket, QLocalServer
|
||||
|
||||
timeout_read = 5000
|
||||
timeout_connect = 500
|
||||
|
||||
def write_message(socket, message, timeout = 5000):
|
||||
block = QByteArray()
|
||||
out = QDataStream(block, QIODevice.WriteOnly)
|
||||
|
||||
out.writeInt32(0)
|
||||
out.writeString(message)
|
||||
out.device().seek(0)
|
||||
out.writeInt32(len(message))
|
||||
|
||||
socket.write(block)
|
||||
|
||||
return getattr(socket, 'state', lambda : None)() == QLocalSocket.ConnectedState and \
|
||||
bool(socket.waitForBytesWritten(timeout))
|
||||
|
||||
def read_message(socket):
|
||||
if getattr(socket, 'state', lambda : None)() != QLocalSocket.ConnectedState:
|
||||
return ''
|
||||
|
||||
while socket.bytesAvailable() < 4:
|
||||
if not socket.waitForReadyRead(timeout_read):
|
||||
return ''
|
||||
|
||||
message = ''
|
||||
ins = QDataStream(socket)
|
||||
block_size = ins.readInt32()
|
||||
while socket.bytesAvailable() < block_size:
|
||||
if not socket.waitForReadyRead(timeout_read):
|
||||
return message
|
||||
return str(ins.readString())
|
||||
|
||||
class Connection(QObject):
|
||||
|
||||
def __init__(self, socket, name):
|
||||
QObject.__init__(self)
|
||||
self.socket = socket
|
||||
self.name = name
|
||||
self.magic = self.name + ':'
|
||||
self.connect(self.socket, SIGNAL('readyRead()'), self.read_msg, Qt.QueuedConnection)
|
||||
self.write_succeeded = write_message(self.socket, self.name)
|
||||
self.connect(self.socket, SIGNAL('disconnected()'), self.disconnected)
|
||||
if not self.write_succeeded:
|
||||
self.socket.abort()
|
||||
|
||||
def read_msg(self):
|
||||
while self.socket.bytesAvailable() > 0:
|
||||
msg = read_message(self.socket)
|
||||
if msg.startswith(self.magic):
|
||||
self.emit(SIGNAL('message_received(PyQt_PyObject)'), msg[len(self.magic):])
|
||||
|
||||
def disconnected(self):
|
||||
self.emit(SIGNAL('disconnected()'))
|
||||
|
||||
|
||||
class LocalServer(QLocalServer):
|
||||
|
||||
def __init__(self, server_id, parent=None):
|
||||
QLocalServer.__init__(self, parent)
|
||||
self.server_id = str(server_id)
|
||||
self.mr = lambda x : self.emit(SIGNAL('message_received(PyQt_PyObject)'), x)
|
||||
self.connections = []
|
||||
self.connect(self, SIGNAL('newConnection()'), self.new_connection)
|
||||
|
||||
def new_connection(self):
|
||||
socket = self.nextPendingConnection()
|
||||
conn = Connection(socket, self.server_id)
|
||||
if conn.socket.state() != QLocalSocket.UnconnectedState:
|
||||
self.connect(conn, SIGNAL('message_received(PyQt_PyObject)'), self.mr)
|
||||
self.connect(conn, SIGNAL('disconnected()'), self.free)
|
||||
self.connections.append(conn)
|
||||
|
||||
def free(self):
|
||||
pop = []
|
||||
for conn in self.connections:
|
||||
if conn.socket.state() == QLocalSocket.UnconnectedState:
|
||||
pop.append(conn)
|
||||
|
||||
for conn in pop:
|
||||
self.connections.remove(conn)
|
||||
|
||||
|
||||
|
||||
class SingleApplication(QObject):
|
||||
|
||||
def __init__(self, name, parent=None, server_name='calibre_server'):
|
||||
QObject.__init__(self, parent)
|
||||
self.name = name
|
||||
self.server_name = server_name
|
||||
self.running = False
|
||||
self.mr = lambda x : self.emit(SIGNAL('message_received(PyQt_PyObject)'), x)
|
||||
|
||||
# Check if server is already running
|
||||
self.socket = QLocalSocket(self)
|
||||
self.socket.connectToServer(self.server_name)
|
||||
if self.socket.waitForConnected(timeout_connect):
|
||||
msg = read_message(self.socket)
|
||||
if msg == self.name:
|
||||
self.running = True
|
||||
|
||||
|
||||
# Start server
|
||||
self.server = None
|
||||
if not self.running:
|
||||
self.socket.abort()
|
||||
self.socket = None
|
||||
self.server = LocalServer(self.name, self)
|
||||
self.connect(self.server, SIGNAL('message_received(PyQt_PyObject)'),
|
||||
self.mr, Qt.QueuedConnection)
|
||||
|
||||
if not self.server.listen(self.server_name):
|
||||
if not self.server.listen(self.server_name):
|
||||
self.server = None
|
||||
if self.server is not None:
|
||||
atexit.register(self.server.close)
|
||||
|
||||
|
||||
def is_running(self, name=None):
|
||||
return self.running if name is None else SingleApplication().is_running()
|
||||
|
||||
def send_message(self, msg, timeout=3000):
|
||||
return self.running and write_message(self.socket, self.name+':'+msg, timeout)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from PyQt4.Qt import QWidget, QApplication
|
||||
class Test(QWidget):
|
||||
|
||||
def __init__(self, sa):
|
||||
QWidget.__init__(self)
|
||||
self.sa = sa
|
||||
self.connect(sa, SIGNAL('message_received(PyQt_PyObject)'), self.mr)
|
||||
|
||||
def mr(self, msg):
|
||||
print 'Message received:', msg
|
||||
|
||||
app = QApplication([])
|
||||
app.connect(app, SIGNAL('lastWindowClosed()'), app.quit)
|
||||
sa = SingleApplication('test SA')
|
||||
if sa.is_running():
|
||||
sa.send_message('test message')
|
||||
else:
|
||||
widget = Test(sa)
|
||||
widget.show()
|
||||
app.exec_()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user