mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
IGN: Miscellaneous minor fixes
This commit is contained in:
parent
14e62aa99c
commit
941de96559
2
Makefile
2
Makefile
@ -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 && \
|
||||
|
@ -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)
|
||||
@ -157,8 +162,33 @@ _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():
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
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
2388
src/calibre/translations/ru.po
Normal file
2388
src/calibre/translations/ru.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
162
src/calibre/utils/single_qt_application.py
Normal file
162
src/calibre/utils/single_qt_application.py
Normal file
@ -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_()
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user