forked from openlp/openlp
Head
This commit is contained in:
commit
3c66e2f304
|
@ -2,6 +2,7 @@
|
|||
*.*~
|
||||
\#*\#
|
||||
*.eric4project
|
||||
*.eric5project
|
||||
*.ropeproject
|
||||
*.e4*
|
||||
.eric4project
|
||||
|
|
|
@ -1 +1 @@
|
|||
2.0.1
|
||||
2.0.3
|
||||
|
|
|
@ -129,9 +129,10 @@ sup {
|
|||
}
|
||||
|
||||
function show_text(newtext){
|
||||
var fade_direction = 0;
|
||||
var match = /-webkit-text-fill-color:[^;\"]+/gi;
|
||||
if(timer != null)
|
||||
clearTimeout(timer);
|
||||
if (timer != null)
|
||||
clearInterval(timer);
|
||||
/*
|
||||
QtWebkit bug with outlines and justify causing outline alignment
|
||||
problems. (Bug 859950) Surround each word with a <span> to workaround,
|
||||
|
@ -150,39 +151,45 @@ sup {
|
|||
newtext = '<span>' + newtext + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
text_fade('lyricsmain', newtext);
|
||||
text_fade('lyricsoutline', newtext);
|
||||
text_fade('lyricsshadow', newtext.replace(match, ''));
|
||||
if(text_opacity() == 1) return;
|
||||
timer = setTimeout(function(){
|
||||
show_text(newtext);
|
||||
timer = setInterval(function(){
|
||||
text_fade('lyricsmain', newtext);
|
||||
text_fade('lyricsoutline', newtext);
|
||||
text_fade('lyricsshadow', newtext.replace(match, ''));
|
||||
if(text_opacity() == 1) clearInterval(timer);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function text_fade(id, newtext){
|
||||
/*
|
||||
Using -webkit-transition: opacity 1s linear; would have been preferred
|
||||
but it isn't currently quick enough when animating multiple layers of
|
||||
large areas of large text. Therefore do it manually as best we can.
|
||||
Hopefully in the future we can revisit and do more interesting
|
||||
transitions using -webkit-transition and -webkit-transform.
|
||||
However we need to ensure interrupted transitions (quickly change 2
|
||||
slides) still looks pretty and is zippy.
|
||||
*/
|
||||
var text = document.getElementById(id);
|
||||
if(text == null) return;
|
||||
if(!transition){
|
||||
text.innerHTML = newtext;
|
||||
return;
|
||||
}
|
||||
if(newtext == text.innerHTML){
|
||||
text.style.opacity = parseFloat(text.style.opacity) + 0.3;
|
||||
if(text.style.opacity > 0.7)
|
||||
text.style.opacity = 1;
|
||||
} else {
|
||||
text.style.opacity = parseFloat(text.style.opacity) - 0.3;
|
||||
if(text.style.opacity <= 0.1){
|
||||
function text_fade(id, newtext){
|
||||
/*
|
||||
Using -webkit-transition: opacity 1s linear; would have been preferred
|
||||
but it isn't currently quick enough when animating multiple layers of
|
||||
large areas of large text. Therefore do it manually as best we can.
|
||||
Hopefully in the future we can revisit and do more interesting
|
||||
transitions using -webkit-transition and -webkit-transform.
|
||||
However we need to ensure interrupted transitions (quickly change 2
|
||||
slides) still looks pretty and is zippy.
|
||||
*/
|
||||
var text = document.getElementById(id);
|
||||
if(text == null) return;
|
||||
if(!transition){
|
||||
text.innerHTML = newtext;
|
||||
return;
|
||||
}
|
||||
if(fade_direction != 1){
|
||||
text.style.opacity = parseFloat(text.style.opacity) - 0.3;
|
||||
if(text.style.opacity <= 0.1){
|
||||
text.innerHTML = newtext;
|
||||
fade_direction = 1;
|
||||
}
|
||||
}else{
|
||||
text.style.opacity = parseFloat(text.style.opacity) + 0.3;
|
||||
if(text.style.opacity > 0.7){
|
||||
text.style.opacity = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ class ServiceItem(object):
|
|||
self.add_icon(header[u'icon'])
|
||||
self.raw_footer = header[u'footer']
|
||||
self.audit = header[u'audit']
|
||||
self.notes = header[u'notes']
|
||||
self.notes = unicode(header[u'notes'])
|
||||
self.from_plugin = header[u'from_plugin']
|
||||
self.capabilities = header[u'capabilities']
|
||||
# Added later so may not be present in older services.
|
||||
|
|
|
@ -45,7 +45,7 @@ from openlp.core.lib import translate, PluginStatus, Receiver, build_icon, \
|
|||
check_directory_exists
|
||||
from openlp.core.lib.settings import Settings
|
||||
from openlp.core.utils import get_web_page, AppLocation, join_url, \
|
||||
get_filesystem_encoding
|
||||
get_filesystem_encoding, get_application_version
|
||||
from firsttimewizard import Ui_FirstTimeWizard, FirstTimePage
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -106,7 +106,8 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||
# url is defined in 'download.cfg' file.
|
||||
self.baseurl = None
|
||||
# Check to see if we have web access
|
||||
self.webAccess = get_web_page(u'%s%s' % (self.web, u'download.cfg'))
|
||||
user_agent = u'OpenLP/' + get_application_version()[u'version']
|
||||
self.webAccess = get_web_page(u'%s%s' % (self.web, u'download.cfg'), header=(u'User-Agent', user_agent))
|
||||
if self.webAccess:
|
||||
files = self.webAccess.read()
|
||||
self.config.readfp(io.BytesIO(files))
|
||||
|
|
|
@ -175,8 +175,10 @@ class MainDisplay(Display):
|
|||
def setTransparency(self, enabled):
|
||||
if enabled:
|
||||
self.setAutoFillBackground(False)
|
||||
self.setStyleSheet("QGraphicsView {background: transparent; border: 0px;}")
|
||||
else:
|
||||
self.setAttribute(QtCore.Qt.WA_NoSystemBackground, False)
|
||||
self.setStyleSheet("QGraphicsView {}")
|
||||
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, enabled)
|
||||
self.repaint()
|
||||
|
||||
|
|
|
@ -423,10 +423,11 @@ class MediaController(object):
|
|||
controller.volumeSlider.blockSignals(False)
|
||||
return False
|
||||
if status:
|
||||
display.frame.evaluateJavaScript(u'show_blank("desktop");')
|
||||
if not controller.media_info.is_background:
|
||||
display.frame.evaluateJavaScript(u'show_blank("desktop");')
|
||||
self.curDisplayMediaPlayer[display].set_visible(display,
|
||||
True)
|
||||
if controller.isLive:
|
||||
if controller.isLive and not controller.media_info.is_background:
|
||||
if controller.hideMenu.defaultAction().isChecked():
|
||||
controller.hideMenu.defaultAction().trigger()
|
||||
# Start Timer for ui updates
|
||||
|
|
|
@ -796,7 +796,7 @@ class ServiceManager(QtGui.QWidget):
|
|||
self.serviceItems[item][u'service_item'].notes)
|
||||
if self.serviceNoteForm.exec_():
|
||||
self.serviceItems[item][u'service_item'].notes = \
|
||||
self.serviceNoteForm.textEdit.toPlainText()
|
||||
unicode(self.serviceNoteForm.textEdit.toPlainText())
|
||||
self.repaintServiceList(item, -1)
|
||||
self.setModified()
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ from PyQt4 import QtGui
|
|||
from openlp.core.lib import translate, SpellTextEdit
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
class ServiceNoteForm(QtGui.QDialog):
|
||||
"""
|
||||
This is the form that is used to edit the verses of the song.
|
||||
|
|
|
@ -79,7 +79,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||
self.keyReleaseEvent(event)
|
||||
elif self.primaryPushButton.isChecked() or \
|
||||
self.alternatePushButton.isChecked():
|
||||
event.ignore()
|
||||
self.keyReleaseEvent(event)
|
||||
elif event.key() == QtCore.Qt.Key_Escape:
|
||||
event.accept()
|
||||
self.close()
|
||||
|
|
|
@ -44,6 +44,7 @@ from openlp.core.utils.actions import ActionList, CategoryOrder
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SlideList(QtGui.QTableWidget):
|
||||
"""
|
||||
Customised version of QTableWidget which can respond to keyboard
|
||||
|
@ -390,7 +391,7 @@ class SlideController(Controller):
|
|||
self._slideShortcutActivated)
|
||||
# Signals
|
||||
QtCore.QObject.connect(self.previewListWidget,
|
||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
|
||||
QtCore.SIGNAL(u'itemSelectionChanged()'), self.onSlideSelected)
|
||||
if self.isLive:
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
|
||||
|
|
|
@ -38,6 +38,7 @@ from subprocess import Popen, PIPE
|
|||
import sys
|
||||
import urllib2
|
||||
import urlparse
|
||||
from random import randint
|
||||
|
||||
from openlp.core.lib.settings import Settings
|
||||
|
||||
|
@ -60,6 +61,27 @@ UNO_CONNECTION_TYPE = u'pipe'
|
|||
#UNO_CONNECTION_TYPE = u'socket'
|
||||
CONTROL_CHARS = re.compile(r'[\x00-\x1F\x7F-\x9F]', re.UNICODE)
|
||||
INVALID_FILE_CHARS = re.compile(r'[\\/:\*\?"<>\|\+\[\]%]', re.UNICODE)
|
||||
USER_AGENTS = {
|
||||
u'win32': [
|
||||
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36'
|
||||
],
|
||||
u'darwin': [
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11'
|
||||
],
|
||||
u'linux2': [
|
||||
'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22',
|
||||
'Mozilla/5.0 (X11; CrOS armv7l 2913.260.0) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.99 Safari/537.11',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.27 (KHTML, like Gecko) Chrome/26.0.1389.0 Safari/537.27'
|
||||
],
|
||||
u'default': [
|
||||
'Mozilla/5.0 (X11; NetBSD amd64; rv:18.0) Gecko/20130120 Firefox/18.0'
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
class VersionThread(QtCore.QThread):
|
||||
"""
|
||||
|
@ -92,7 +114,7 @@ class AppLocation(object):
|
|||
VersionDir = 5
|
||||
CacheDir = 6
|
||||
LanguageDir = 7
|
||||
|
||||
|
||||
# Base path where data/config/cache dir is located
|
||||
BaseDir = None
|
||||
|
||||
|
@ -364,6 +386,7 @@ def get_images_filter():
|
|||
visible_formats, actual_formats)
|
||||
return IMAGES_FILTER
|
||||
|
||||
|
||||
def is_not_image_file(file_name):
|
||||
"""
|
||||
Validate that the file is not an image file.
|
||||
|
@ -380,6 +403,7 @@ def is_not_image_file(file_name):
|
|||
return False
|
||||
return True
|
||||
|
||||
|
||||
def join_url(base, *args):
|
||||
"""
|
||||
Join one or more url components with the base url.
|
||||
|
@ -438,6 +462,17 @@ def delete_file(file_path_name):
|
|||
return False
|
||||
|
||||
|
||||
def _get_user_agent():
|
||||
"""
|
||||
Return a user agent customised for the platform the user is on.
|
||||
"""
|
||||
browser_list = USER_AGENTS.get(sys.platform, None)
|
||||
if not browser_list:
|
||||
browser_list = USER_AGENTS[u'default']
|
||||
random_index = randint(0, len(browser_list) - 1)
|
||||
return browser_list[random_index]
|
||||
|
||||
|
||||
def get_web_page(url, header=None, update_openlp=False):
|
||||
"""
|
||||
Attempts to download the webpage at url and returns that page or None.
|
||||
|
@ -458,13 +493,20 @@ def get_web_page(url, header=None, update_openlp=False):
|
|||
if not url:
|
||||
return None
|
||||
req = urllib2.Request(url)
|
||||
if header:
|
||||
req.add_header(header[0], header[1])
|
||||
if not header or header[0].lower() != u'user-agent':
|
||||
user_agent = _get_user_agent()
|
||||
req.add_header('User-Agent', str(user_agent))
|
||||
elif header:
|
||||
req.add_header(str(header[0]), str(header[1]))
|
||||
page = None
|
||||
log.debug(u'Downloading URL = %s' % url)
|
||||
try:
|
||||
page = urllib2.urlopen(req)
|
||||
log.debug(u'Downloaded URL = %s' % page.geturl())
|
||||
downloaded_url = page.geturl()
|
||||
# Sometimes we get redirected, in this case page.geturl is encoded in utf-8
|
||||
if not isinstance(downloaded_url, unicode):
|
||||
downloaded_url = downloaded_url.decode('utf-8')
|
||||
log.debug(u'Downloaded URL = %s' % downloaded_url)
|
||||
except urllib2.URLError:
|
||||
log.exception(u'The web page could not be downloaded')
|
||||
if not page:
|
||||
|
|
|
@ -39,6 +39,7 @@ from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BiblesTab(SettingsTab):
|
||||
"""
|
||||
BiblesTab is the Bibles settings tab in the settings dialog.
|
||||
|
@ -293,7 +294,7 @@ class BiblesTab(SettingsTab):
|
|||
translate('BiblesPlugin.BiblesTab', 'English'))
|
||||
|
||||
def onBibleThemeComboBoxChanged(self):
|
||||
self.bible_theme = self.bibleThemeComboBox.currentText()
|
||||
self.bible_theme = unicode(self.bibleThemeComboBox.currentText())
|
||||
|
||||
def onDisplayStyleComboBoxChanged(self):
|
||||
self.display_style = self.displayStyleComboBox.currentIndex()
|
||||
|
|
|
@ -32,9 +32,11 @@ import logging
|
|||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
import time
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from sqlalchemy import Column, ForeignKey, or_, Table, types, func
|
||||
from sqlalchemy.exc import OperationalError
|
||||
from sqlalchemy.orm import class_mapper, mapper, relation
|
||||
from sqlalchemy.orm.exc import UnmappedClassError
|
||||
|
||||
|
@ -48,6 +50,7 @@ log = logging.getLogger(__name__)
|
|||
|
||||
RESERVED_CHARACTERS = u'\\.^$*+?{}[]()'
|
||||
|
||||
|
||||
class BibleMeta(BaseModel):
|
||||
"""
|
||||
Bible Meta Data
|
||||
|
@ -257,7 +260,12 @@ class BibleDB(QtCore.QObject, Manager):
|
|||
text=verse_text
|
||||
)
|
||||
self.session.add(verse)
|
||||
self.session.commit()
|
||||
try:
|
||||
self.session.commit()
|
||||
except OperationalError:
|
||||
# Wait 10ms and try again.
|
||||
time.sleep(0.01)
|
||||
self.session.commit()
|
||||
|
||||
def create_verse(self, book_id, chapter, verse, text):
|
||||
"""
|
||||
|
@ -363,7 +371,7 @@ class BibleDB(QtCore.QObject, Manager):
|
|||
|
||||
``book``
|
||||
The name of the book, according to the selected language.
|
||||
|
||||
|
||||
``language_selection``
|
||||
The language selection the user has chosen in the settings
|
||||
section of the Bible.
|
||||
|
@ -1061,7 +1069,7 @@ class OldBibleDB(QtCore.QObject, Manager):
|
|||
QtCore.QObject.__init__(self)
|
||||
if u'path' not in kwargs:
|
||||
raise KeyError(u'Missing keyword argument "path".')
|
||||
if u'file' not in kwargs:
|
||||
if u'file' not in kwargs:
|
||||
raise KeyError(u'Missing keyword argument "file".')
|
||||
if u'path' in kwargs:
|
||||
self.path = kwargs[u'path']
|
||||
|
|
|
@ -47,6 +47,7 @@ from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BibleSearch(object):
|
||||
"""
|
||||
Enumeration class for the different search methods for the "quick search".
|
||||
|
@ -62,7 +63,6 @@ class BibleMediaItem(MediaManagerItem):
|
|||
log.info(u'Bible Media Item loaded')
|
||||
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'songs/song'
|
||||
self.lockIcon = build_icon(u':/bibles/bibles_search_lock.png')
|
||||
self.unlockIcon = build_icon(u':/bibles/bibles_search_unlock.png')
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
|
@ -180,6 +180,8 @@ class BibleMediaItem(MediaManagerItem):
|
|||
tab.setVisible(False)
|
||||
QtCore.QObject.connect(lockButton, QtCore.SIGNAL(u'toggled(bool)'),
|
||||
self.onLockButtonToggled)
|
||||
QtCore.QObject.connect(secondComboBox, QtCore.SIGNAL(u'currentIndexChanged(QString)'),
|
||||
self.onSecondBibleComboBoxCurrentIndexChanged)
|
||||
setattr(self, prefix + u'VersionLabel', versionLabel)
|
||||
setattr(self, prefix + u'VersionComboBox', versionComboBox)
|
||||
setattr(self, prefix + u'SecondLabel', secondLabel)
|
||||
|
@ -299,15 +301,15 @@ class BibleMediaItem(MediaManagerItem):
|
|||
log.debug(u'configUpdated')
|
||||
if Settings().value(self.settingsSection + u'/second bibles',
|
||||
QtCore.QVariant(True)).toBool():
|
||||
self.advancedSecondLabel.setVisible(True)
|
||||
self.advancedSecondComboBox.setVisible(True)
|
||||
self.quickSecondLabel.setVisible(True)
|
||||
self.quickSecondComboBox.setVisible(True)
|
||||
self.advancedSecondLabel.setVisible(True)
|
||||
self.advancedSecondComboBox.setVisible(True)
|
||||
else:
|
||||
self.advancedSecondLabel.setVisible(False)
|
||||
self.advancedSecondComboBox.setVisible(False)
|
||||
self.quickSecondLabel.setVisible(False)
|
||||
self.quickSecondComboBox.setVisible(False)
|
||||
self.advancedSecondLabel.setVisible(False)
|
||||
self.advancedSecondComboBox.setVisible(False)
|
||||
self.quickStyleComboBox.setCurrentIndex(self.settings.layout_style)
|
||||
self.advancedStyleComboBox.setCurrentIndex(self.settings.layout_style)
|
||||
|
||||
|
@ -542,6 +544,14 @@ class BibleMediaItem(MediaManagerItem):
|
|||
books.sort(cmp=locale_compare)
|
||||
set_case_insensitive_completer(books, self.quickSearchEdit)
|
||||
|
||||
def onSecondBibleComboBoxCurrentIndexChanged(self, text):
|
||||
if text is None or not unicode(text):
|
||||
self.quickStyleComboBox.setEnabled(True)
|
||||
self.advancedStyleComboBox.setEnabled(True)
|
||||
else:
|
||||
self.quickStyleComboBox.setEnabled(False)
|
||||
self.advancedStyleComboBox.setEnabled(False)
|
||||
|
||||
def onImportClick(self):
|
||||
if not hasattr(self, u'import_wizard'):
|
||||
self.import_wizard = BibleImportForm(self, self.plugin.manager,
|
||||
|
|
|
@ -153,7 +153,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
if self.controllers[item].enabled():
|
||||
self.displayTypeComboBox.addItem(item)
|
||||
if self.displayTypeComboBox.count() > 1:
|
||||
self.displayTypeComboBox.insertItem(0, self.Automatic)
|
||||
self.displayTypeComboBox.insertItem(0, self.Automatic, userData=u'automatic')
|
||||
self.displayTypeComboBox.setCurrentIndex(0)
|
||||
if Settings().value(self.settingsSection + u'/override app',
|
||||
QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
|
||||
|
@ -277,13 +277,13 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
service_item.shortname = unicode(self.displayTypeComboBox.currentText())
|
||||
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
||||
service_item.add_capability(ItemCapabilities.HasDetailedTitleDisplay)
|
||||
shortname = service_item.shortname
|
||||
if not shortname:
|
||||
if not service_item.shortname:
|
||||
return False
|
||||
for bitem in items:
|
||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||
if os.path.exists(filename):
|
||||
if shortname == self.Automatic:
|
||||
if self.displayTypeComboBox.itemData(
|
||||
self.displayTypeComboBox.currentIndex()) == u'automatic':
|
||||
service_item.shortname = self.findControllerByType(filename)
|
||||
if not service_item.shortname:
|
||||
return False
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
import os
|
||||
import logging
|
||||
import sys
|
||||
|
||||
if os.name == u'nt':
|
||||
from ctypes import cdll
|
||||
|
@ -125,11 +126,16 @@ class PptviewDocument(PresentationDocument):
|
|||
renderer = self.controller.plugin.renderer
|
||||
rect = renderer.screens.current[u'size']
|
||||
rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
|
||||
filepath = str(self.filepath.replace(u'/', u'\\'))
|
||||
file_system_encoding = 'utf-16-le'
|
||||
file_path = os.path.normpath(self.filepath)
|
||||
preview_path = os.path.join(self.get_temp_folder(), u'slide')
|
||||
# Ensure that the paths are null terminated
|
||||
file_path = file_path.encode(file_system_encoding) + '\0'
|
||||
preview_path = preview_path.encode(file_system_encoding) + '\0'
|
||||
if not os.path.isdir(self.get_temp_folder()):
|
||||
os.makedirs(self.get_temp_folder())
|
||||
self.pptid = self.controller.process.OpenPPT(filepath, None, rect,
|
||||
str(self.get_temp_folder()) + '\\slide')
|
||||
self.pptid = self.controller.process.OpenPPT(file_path, None, rect,
|
||||
preview_path)
|
||||
if self.pptid >= 0:
|
||||
self.create_thumbnails()
|
||||
self.stop_presentation()
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from PyQt4 import QtGui, QtCore
|
||||
from ctypes import *
|
||||
from ctypes.wintypes import RECT
|
||||
|
@ -172,9 +174,8 @@ class PPTViewer(QtGui.QWidget):
|
|||
oldid = self.pptid;
|
||||
rect = RECT(int(self.xEdit.text()), int(self.yEdit.text()),
|
||||
int(self.widthEdit.text()), int(self.heightEdit.text()))
|
||||
filename = str(self.pptEdit.text().replace(u'/', u'\\'))
|
||||
folder = str(self.folderEdit.text().replace(u'/', u'\\'))
|
||||
print filename, folder
|
||||
filename = os.path.normpath(unicode(self.pptEdit.text())).encode('utf-16-le') + '\0'
|
||||
folder = os.path.normpath(unicode(self.folderEdit.text())).encode('utf-16-le') + '\0'
|
||||
self.pptid = self.pptdll.OpenPPT(filename, None, rect, folder)
|
||||
print u'id: ' + unicode(self.pptid)
|
||||
if oldid >= 0:
|
||||
|
|
|
@ -61,18 +61,18 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReasonForCall,
|
|||
switch(ulReasonForCall)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DEBUG("PROCESS_ATTACH\n");
|
||||
DEBUG(L"PROCESS_ATTACH\n");
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
//DEBUG("THREAD_ATTACH\n");
|
||||
//DEBUG(L"THREAD_ATTACH\n");
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
//DEBUG("THREAD_DETACH\n");
|
||||
//DEBUG(L"THREAD_DETACH\n");
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
// Clean up... hopefully there is only the one process attached?
|
||||
// We'll find out soon enough during tests!
|
||||
DEBUG("PROCESS_DETACH\n");
|
||||
DEBUG(L"PROCESS_DETACH\n");
|
||||
for (int i = 0; i < MAX_PPTS; i++)
|
||||
ClosePPT(i);
|
||||
break;
|
||||
|
@ -84,18 +84,18 @@ DllExport void SetDebug(BOOL onOff)
|
|||
{
|
||||
printf("SetDebug\n");
|
||||
debug = onOff;
|
||||
DEBUG("enabled\n");
|
||||
DEBUG(L"enabled\n");
|
||||
}
|
||||
|
||||
DllExport BOOL CheckInstalled()
|
||||
{
|
||||
char cmdLine[MAX_PATH * 2];
|
||||
wchar_t cmdLine[MAX_PATH * 2];
|
||||
|
||||
DEBUG("CheckInstalled\n");
|
||||
DEBUG(L"CheckInstalled\n");
|
||||
BOOL found = GetPPTViewerPath(cmdLine, sizeof(cmdLine));
|
||||
if(found)
|
||||
{
|
||||
DEBUG("Exe: %s\n", cmdLine);
|
||||
DEBUG(L"Exe: %s\n", cmdLine);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
@ -106,20 +106,20 @@ DllExport BOOL CheckInstalled()
|
|||
// "<n>.bmp" will be appended to complete the path. E.g. "c:\temp\slide" would
|
||||
// create "c:\temp\slide1.bmp" slide2.bmp, slide3.bmp etc.
|
||||
// It will also create a *info.txt containing information about the ppt
|
||||
DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
||||
char *previewPath)
|
||||
DllExport int OpenPPT(wchar_t *filename, HWND hParentWnd, RECT rect,
|
||||
wchar_t *previewPath)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
char cmdLine[MAX_PATH * 2];
|
||||
wchar_t cmdLine[MAX_PATH * 2];
|
||||
int id;
|
||||
|
||||
DEBUG("OpenPPT start: %s; %s\n", filename, previewPath);
|
||||
DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top,
|
||||
DEBUG(L"OpenPPT start: %s; %s\n", filename, previewPath);
|
||||
DEBUG(L"OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top,
|
||||
rect.left, rect.bottom, rect.right);
|
||||
if (GetPPTViewerPath(cmdLine, sizeof(cmdLine)) == FALSE)
|
||||
{
|
||||
DEBUG("OpenPPT: GetPPTViewerPath failed\n");
|
||||
DEBUG(L"OpenPPT: GetPPTViewerPath failed\n");
|
||||
return -1;
|
||||
}
|
||||
id = -1;
|
||||
|
@ -133,12 +133,12 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||
}
|
||||
if (id < 0)
|
||||
{
|
||||
DEBUG("OpenPPT: Too many PPTs\n");
|
||||
DEBUG(L"OpenPPT: Too many PPTs\n");
|
||||
return -1;
|
||||
}
|
||||
memset(&pptView[id], 0, sizeof(PPTVIEW));
|
||||
strcpy_s(pptView[id].filename, MAX_PATH, filename);
|
||||
strcpy_s(pptView[id].previewPath, MAX_PATH, previewPath);
|
||||
wcscpy_s(pptView[id].filename, MAX_PATH, filename);
|
||||
wcscpy_s(pptView[id].previewPath, MAX_PATH, previewPath);
|
||||
pptView[id].state = PPT_CLOSED;
|
||||
pptView[id].slideCount = 0;
|
||||
pptView[id].currentSlide = 0;
|
||||
|
@ -169,9 +169,9 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||
pptView[id].rect.bottom = rect.bottom;
|
||||
pptView[id].rect.right = rect.right;
|
||||
}
|
||||
strcat_s(cmdLine, MAX_PATH * 2, " /F /S \"");
|
||||
strcat_s(cmdLine, MAX_PATH * 2, filename);
|
||||
strcat_s(cmdLine, MAX_PATH * 2, "\"");
|
||||
wcscat_s(cmdLine, MAX_PATH * 2, L" /F /S \"");
|
||||
wcscat_s(cmdLine, MAX_PATH * 2, filename);
|
||||
wcscat_s(cmdLine, MAX_PATH * 2, L"\"");
|
||||
memset(&si, 0, sizeof(si));
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
BOOL gotInfo = GetPPTInfo(id);
|
||||
|
@ -190,7 +190,7 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||
globalHook = SetWindowsHookEx(WH_CBT, CbtProc, hInstance, NULL);
|
||||
if (globalHook == 0)
|
||||
{
|
||||
DEBUG("OpenPPT: SetWindowsHookEx failed\n");
|
||||
DEBUG(L"OpenPPT: SetWindowsHookEx failed\n");
|
||||
ClosePPT(id);
|
||||
return -1;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||
Sleep(10);
|
||||
if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi))
|
||||
{
|
||||
DEBUG("OpenPPT: CreateProcess failed: %s\n", cmdLine);
|
||||
DEBUG(L"OpenPPT: CreateProcess failed: %s\n", cmdLine);
|
||||
ClosePPT(id);
|
||||
return -1;
|
||||
}
|
||||
|
@ -210,13 +210,13 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||
Sleep(10);
|
||||
if (gotInfo)
|
||||
{
|
||||
DEBUG("OpenPPT: Info loaded, no refresh\n");
|
||||
DEBUG(L"OpenPPT: Info loaded, no refresh\n");
|
||||
pptView[id].state = PPT_LOADED;
|
||||
Resume(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG("OpenPPT: Get info\n");
|
||||
DEBUG(L"OpenPPT: Get info\n");
|
||||
pptView[id].steps = 0;
|
||||
int steps = 0;
|
||||
while (pptView[id].state == PPT_OPENED)
|
||||
|
@ -224,18 +224,18 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||
if (steps <= pptView[id].steps)
|
||||
{
|
||||
Sleep(20);
|
||||
DEBUG("OpenPPT: Step %d/%d\n", steps, pptView[id].steps);
|
||||
DEBUG(L"OpenPPT: Step %d/%d\n", steps, pptView[id].steps);
|
||||
steps++;
|
||||
NextStep(id);
|
||||
}
|
||||
Sleep(10);
|
||||
}
|
||||
DEBUG("OpenPPT: Slides %d, Steps %d, first slide steps %d\n",
|
||||
DEBUG(L"OpenPPT: Slides %d, Steps %d, first slide steps %d\n",
|
||||
pptView[id].slideCount, pptView[id].steps,
|
||||
pptView[id].firstSlideSteps);
|
||||
for(int i = 1; i <= pptView[id].slideCount; i++)
|
||||
{
|
||||
DEBUG("OpenPPT: Slide %d = %d\n", i, pptView[id].slideNos[i]);
|
||||
DEBUG(L"OpenPPT: Slide %d = %d\n", i, pptView[id].slideNos[i]);
|
||||
}
|
||||
SavePPTInfo(id);
|
||||
if (pptView[id].state == PPT_CLOSING
|
||||
|
@ -257,7 +257,7 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||
}
|
||||
pptView[id].msgHook = NULL;
|
||||
}
|
||||
DEBUG("OpenPPT: Exit: id=%i\n", id);
|
||||
DEBUG(L"OpenPPT: Exit: id=%i\n", id);
|
||||
return id;
|
||||
}
|
||||
// Load information about the ppt from an info.txt file.
|
||||
|
@ -270,75 +270,75 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||
BOOL GetPPTInfo(int id)
|
||||
{
|
||||
struct _stat fileStats;
|
||||
char info[MAX_PATH];
|
||||
wchar_t info[MAX_PATH];
|
||||
FILE* pFile;
|
||||
char buf[100];
|
||||
wchar_t buf[100];
|
||||
|
||||
DEBUG("GetPPTInfo: start\n");
|
||||
if (_stat(pptView[id].filename, &fileStats) != 0)
|
||||
DEBUG(L"GetPPTInfo: start\n");
|
||||
if (_wstat(pptView[id].filename, &fileStats) != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
sprintf_s(info, MAX_PATH, "%sinfo.txt", pptView[id].previewPath);
|
||||
int err = fopen_s(&pFile, info, "r");
|
||||
swprintf_s(info, MAX_PATH, L"%sinfo.txt", pptView[id].previewPath);
|
||||
int err = _wfopen_s(&pFile, info, L"r");
|
||||
if (err != 0)
|
||||
{
|
||||
DEBUG("GetPPTInfo: file open failed - %d\n", err);
|
||||
DEBUG(L"GetPPTInfo: file open failed - %d\n", err);
|
||||
return FALSE;
|
||||
}
|
||||
fgets(buf, 100, pFile); // version == 1
|
||||
fgets(buf, 100, pFile);
|
||||
if (fileStats.st_mtime != atoi(buf))
|
||||
fgetws(buf, 100, pFile); // version == 1
|
||||
fgetws(buf, 100, pFile);
|
||||
if (fileStats.st_mtime != _wtoi(buf))
|
||||
{
|
||||
DEBUG("GetPPTInfo: date changed\n");
|
||||
DEBUG(L"GetPPTInfo: date changed\n");
|
||||
fclose (pFile);
|
||||
return FALSE;
|
||||
}
|
||||
fgets(buf, 100, pFile);
|
||||
if (fileStats.st_size != atoi(buf))
|
||||
fgetws(buf, 100, pFile);
|
||||
if (fileStats.st_size != _wtoi(buf))
|
||||
{
|
||||
DEBUG("GetPPTInfo: size changed\n");
|
||||
DEBUG(L"GetPPTInfo: size changed\n");
|
||||
fclose (pFile);
|
||||
return FALSE;
|
||||
}
|
||||
fgets(buf, 100, pFile); // slidecount
|
||||
int slideCount = atoi(buf);
|
||||
fgets(buf, 100, pFile); // first slide steps
|
||||
int firstSlideSteps = atoi(buf);
|
||||
fgetws(buf, 100, pFile); // slidecount
|
||||
int slideCount = _wtoi(buf);
|
||||
fgetws(buf, 100, pFile); // first slide steps
|
||||
int firstSlideSteps = _wtoi(buf);
|
||||
// check all the preview images still exist
|
||||
for (int i = 1; i <= slideCount; i++)
|
||||
{
|
||||
sprintf_s(info, MAX_PATH, "%s%i.bmp", pptView[id].previewPath, i);
|
||||
swprintf_s(info, MAX_PATH, L"%s%i.bmp", pptView[id].previewPath, i);
|
||||
if (GetFileAttributes(info) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
DEBUG("GetPPTInfo: bmp not found\n");
|
||||
DEBUG(L"GetPPTInfo: bmp not found\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fclose(pFile);
|
||||
pptView[id].slideCount = slideCount;
|
||||
pptView[id].firstSlideSteps = firstSlideSteps;
|
||||
DEBUG("GetPPTInfo: exit ok\n");
|
||||
DEBUG(L"GetPPTInfo: exit ok\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SavePPTInfo(int id)
|
||||
{
|
||||
struct _stat fileStats;
|
||||
char info[MAX_PATH];
|
||||
wchar_t info[MAX_PATH];
|
||||
FILE* pFile;
|
||||
|
||||
DEBUG("SavePPTInfo: start\n");
|
||||
if (_stat(pptView[id].filename, &fileStats) != 0)
|
||||
DEBUG(L"SavePPTInfo: start\n");
|
||||
if (_wstat(pptView[id].filename, &fileStats) != 0)
|
||||
{
|
||||
DEBUG("SavePPTInfo: stat of %s failed\n", pptView[id].filename);
|
||||
DEBUG(L"SavePPTInfo: stat of %s failed\n", pptView[id].filename);
|
||||
return FALSE;
|
||||
}
|
||||
sprintf_s(info, MAX_PATH, "%sinfo.txt", pptView[id].previewPath);
|
||||
int err = fopen_s(&pFile, info, "w");
|
||||
swprintf_s(info, MAX_PATH, L"%sinfo.txt", pptView[id].previewPath);
|
||||
int err = _wfopen_s(&pFile, info, L"w");
|
||||
if (err != 0)
|
||||
{
|
||||
DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err);
|
||||
DEBUG(L"SavePPTInfo: fopen of %s failed%i\n", info, err);
|
||||
return FALSE;
|
||||
}
|
||||
fprintf(pFile, "1\n");
|
||||
|
@ -347,21 +347,21 @@ BOOL SavePPTInfo(int id)
|
|||
fprintf(pFile, "%u\n", pptView[id].slideCount);
|
||||
fprintf(pFile, "%u\n", pptView[id].firstSlideSteps);
|
||||
fclose(pFile);
|
||||
DEBUG("SavePPTInfo: exit ok\n");
|
||||
DEBUG(L"SavePPTInfo: exit ok\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Get the path of the PowerPoint viewer from the registry
|
||||
BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize)
|
||||
BOOL GetPPTViewerPath(wchar_t *pptViewerPath, int stringSize)
|
||||
{
|
||||
char cwd[MAX_PATH];
|
||||
wchar_t cwd[MAX_PATH];
|
||||
|
||||
DEBUG("GetPPTViewerPath: start\n");
|
||||
DEBUG(L"GetPPTViewerPath: start\n");
|
||||
if(GetPPTViewerPathFromReg(pptViewerPath, stringSize))
|
||||
{
|
||||
if(_access(pptViewerPath, 0) != -1)
|
||||
if(_waccess(pptViewerPath, 0) != -1)
|
||||
{
|
||||
DEBUG("GetPPTViewerPath: exit registry\n");
|
||||
DEBUG(L"GetPPTViewerPath: exit registry\n");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -370,37 +370,37 @@ BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize)
|
|||
// upset those who like to put things somewhere else
|
||||
|
||||
// Viewer 2007 in 64bit Windows:
|
||||
if(_access("C:\\Program Files (x86)\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||
if(_waccess(L"C:\\Program Files (x86)\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||
0) != -1)
|
||||
{
|
||||
strcpy_s(
|
||||
"C:\\Program Files (x86)\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||
wcscpy_s(
|
||||
L"C:\\Program Files (x86)\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||
stringSize, pptViewerPath);
|
||||
DEBUG("GetPPTViewerPath: exit 64bit 2007\n");
|
||||
DEBUG(L"GetPPTViewerPath: exit 64bit 2007\n");
|
||||
return TRUE;
|
||||
}
|
||||
// Viewer 2007 in 32bit Windows:
|
||||
if(_access("C:\\Program Files\\Microsoft Office\\Office12\\PPTVIEW.EXE", 0)
|
||||
if(_waccess(L"C:\\Program Files\\Microsoft Office\\Office12\\PPTVIEW.EXE", 0)
|
||||
!= -1)
|
||||
{
|
||||
strcpy_s("C:\\Program Files\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||
wcscpy_s(L"C:\\Program Files\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||
stringSize, pptViewerPath);
|
||||
DEBUG("GetPPTViewerPath: exit 32bit 2007\n");
|
||||
DEBUG(L"GetPPTViewerPath: exit 32bit 2007\n");
|
||||
return TRUE;
|
||||
}
|
||||
// Give them the opportunity to place it in the same folder as the app
|
||||
_getcwd(cwd, MAX_PATH);
|
||||
strcat_s(cwd, MAX_PATH, "\\PPTVIEW.EXE");
|
||||
if(_access(cwd, 0) != -1)
|
||||
_wgetcwd(cwd, MAX_PATH);
|
||||
wcscat_s(cwd, MAX_PATH, L"\\PPTVIEW.EXE");
|
||||
if(_waccess(cwd, 0) != -1)
|
||||
{
|
||||
strcpy_s(pptViewerPath, stringSize, cwd);
|
||||
DEBUG("GetPPTViewerPath: exit local\n");
|
||||
wcscpy_s(pptViewerPath, stringSize, cwd);
|
||||
DEBUG(L"GetPPTViewerPath: exit local\n");
|
||||
return TRUE;
|
||||
}
|
||||
DEBUG("GetPPTViewerPath: exit fail\n");
|
||||
DEBUG(L"GetPPTViewerPath: exit fail\n");
|
||||
return FALSE;
|
||||
}
|
||||
BOOL GetPPTViewerPathFromReg(char *pptViewerPath, int stringSize)
|
||||
BOOL GetPPTViewerPathFromReg(wchar_t *pptViewerPath, int stringSize)
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD dwType, dwSize;
|
||||
|
@ -411,17 +411,17 @@ BOOL GetPPTViewerPathFromReg(char *pptViewerPath, int stringSize)
|
|||
// PPT Viewer 2003 (recent versions)
|
||||
// PPT Viewer 2003 (older versions)
|
||||
// PPT Viewer 97
|
||||
if ((RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
||||
"PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
||||
if ((RegOpenKeyExW(HKEY_CLASSES_ROOT,
|
||||
L"PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
||||
!= ERROR_SUCCESS)
|
||||
&& (RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
||||
"PowerPointViewer.Show.11\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
||||
&& (RegOpenKeyExW(HKEY_CLASSES_ROOT,
|
||||
L"PowerPointViewer.Show.11\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
||||
!= ERROR_SUCCESS)
|
||||
&& (RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
||||
"Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hKey)
|
||||
&& (RegOpenKeyExW(HKEY_CLASSES_ROOT,
|
||||
L"Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hKey)
|
||||
!= ERROR_SUCCESS)
|
||||
&& (RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
||||
"Applications\\PPTVIEW.EXE\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
||||
&& (RegOpenKeyExW(HKEY_CLASSES_ROOT,
|
||||
L"Applications\\PPTVIEW.EXE\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
||||
!= ERROR_SUCCESS))
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -436,14 +436,14 @@ BOOL GetPPTViewerPathFromReg(char *pptViewerPath, int stringSize)
|
|||
return FALSE;
|
||||
}
|
||||
// remove "%1" from end of key value
|
||||
pptViewerPath[strlen(pptViewerPath) - 4] = '\0';
|
||||
pptViewerPath[wcslen(pptViewerPath) - 4] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Unhook the Windows hook
|
||||
void Unhook(int id)
|
||||
{
|
||||
DEBUG("Unhook: start %d\n", id);
|
||||
DEBUG(L"Unhook: start %d\n", id);
|
||||
if (pptView[id].hook != NULL)
|
||||
{
|
||||
UnhookWindowsHookEx(pptView[id].hook);
|
||||
|
@ -454,13 +454,13 @@ void Unhook(int id)
|
|||
}
|
||||
pptView[id].hook = NULL;
|
||||
pptView[id].msgHook = NULL;
|
||||
DEBUG("Unhook: exit ok\n");
|
||||
DEBUG(L"Unhook: exit ok\n");
|
||||
}
|
||||
|
||||
// Close the PowerPoint viewer, release resources
|
||||
DllExport void ClosePPT(int id)
|
||||
{
|
||||
DEBUG("ClosePPT: start%d\n", id);
|
||||
DEBUG(L"ClosePPT: start%d\n", id);
|
||||
pptView[id].state = PPT_CLOSED;
|
||||
Unhook(id);
|
||||
if (pptView[id].hWnd == 0)
|
||||
|
@ -474,13 +474,13 @@ DllExport void ClosePPT(int id)
|
|||
CloseHandle(pptView[id].hThread);
|
||||
CloseHandle(pptView[id].hProcess);
|
||||
memset(&pptView[id], 0, sizeof(PPTVIEW));
|
||||
DEBUG("ClosePPT: exit ok\n");
|
||||
DEBUG(L"ClosePPT: exit ok\n");
|
||||
return;
|
||||
}
|
||||
// Moves the show back onto the display
|
||||
DllExport void Resume(int id)
|
||||
{
|
||||
DEBUG("Resume: %d\n", id);
|
||||
DEBUG(L"Resume: %d\n", id);
|
||||
MoveWindow(pptView[id].hWnd, pptView[id].rect.left,
|
||||
pptView[id].rect.top,
|
||||
pptView[id].rect.right - pptView[id].rect.left,
|
||||
|
@ -490,7 +490,7 @@ DllExport void Resume(int id)
|
|||
// Moves the show off the screen so it can't be seen
|
||||
DllExport void Stop(int id)
|
||||
{
|
||||
DEBUG("Stop:%d\n", id);
|
||||
DEBUG(L"Stop:%d\n", id);
|
||||
MoveWindow(pptView[id].hWnd, -32000, -32000,
|
||||
pptView[id].rect.right - pptView[id].rect.left,
|
||||
pptView[id].rect.bottom - pptView[id].rect.top, TRUE);
|
||||
|
@ -499,7 +499,7 @@ DllExport void Stop(int id)
|
|||
// Return the total number of slides
|
||||
DllExport int GetSlideCount(int id)
|
||||
{
|
||||
DEBUG("GetSlideCount:%d\n", id);
|
||||
DEBUG(L"GetSlideCount:%d\n", id);
|
||||
if (pptView[id].state == 0)
|
||||
{
|
||||
return -1;
|
||||
|
@ -513,7 +513,7 @@ DllExport int GetSlideCount(int id)
|
|||
// Return the number of the slide currently viewing
|
||||
DllExport int GetCurrentSlide(int id)
|
||||
{
|
||||
DEBUG("GetCurrentSlide:%d\n", id);
|
||||
DEBUG(L"GetCurrentSlide:%d\n", id);
|
||||
if (pptView[id].state == 0)
|
||||
{
|
||||
return -1;
|
||||
|
@ -527,7 +527,7 @@ DllExport int GetCurrentSlide(int id)
|
|||
// Take a step forwards through the show
|
||||
DllExport void NextStep(int id)
|
||||
{
|
||||
DEBUG("NextStep:%d (%d)\n", id, pptView[id].currentSlide);
|
||||
DEBUG(L"NextStep:%d (%d)\n", id, pptView[id].currentSlide);
|
||||
if (pptView[id].currentSlide > pptView[id].slideCount) return;
|
||||
if (pptView[id].currentSlide < pptView[id].slideCount)
|
||||
{
|
||||
|
@ -540,7 +540,7 @@ DllExport void NextStep(int id)
|
|||
// Take a step backwards through the show
|
||||
DllExport void PrevStep(int id)
|
||||
{
|
||||
DEBUG("PrevStep:%d (%d)\n", id, pptView[id].currentSlide);
|
||||
DEBUG(L"PrevStep:%d (%d)\n", id, pptView[id].currentSlide);
|
||||
if (pptView[id].currentSlide > 1)
|
||||
{
|
||||
pptView[id].guess = pptView[id].currentSlide - 1;
|
||||
|
@ -556,7 +556,7 @@ DllExport void Blank(int id)
|
|||
// So send random unmapped letter first (say 'A'), then we can
|
||||
// better guarantee B will blank instead of trying to guess
|
||||
// whether it was already blank or not.
|
||||
DEBUG("Blank:%d\n", id);
|
||||
DEBUG(L"Blank:%d\n", id);
|
||||
HWND h1 = GetForegroundWindow();
|
||||
HWND h2 = GetFocus();
|
||||
SetForegroundWindow(pptView[id].hWnd);
|
||||
|
@ -573,7 +573,7 @@ DllExport void Blank(int id)
|
|||
// Unblank the show
|
||||
DllExport void Unblank(int id)
|
||||
{
|
||||
DEBUG("Unblank:%d\n", id);
|
||||
DEBUG(L"Unblank:%d\n", id);
|
||||
// Pressing any key resumes.
|
||||
// For some reason SendMessage works for unblanking, but not blanking.
|
||||
SendMessage(pptView[id].hWnd2, WM_CHAR, 'A', 0);
|
||||
|
@ -582,7 +582,7 @@ DllExport void Unblank(int id)
|
|||
// Go directly to a slide
|
||||
DllExport void GotoSlide(int id, int slideNo)
|
||||
{
|
||||
DEBUG("GotoSlide %i %i:\n", id, slideNo);
|
||||
DEBUG(L"GotoSlide %i %i:\n", id, slideNo);
|
||||
// Did try WM_KEYDOWN/WM_CHAR/WM_KEYUP with SendMessage but didn't work
|
||||
// perhaps I was sending to the wrong window? No idea.
|
||||
// Anyway fall back to keybd_event, which is OK as long we makesure
|
||||
|
@ -619,7 +619,7 @@ DllExport void RestartShow(int id)
|
|||
// Only way I've found to get around this is to step backwards all the way
|
||||
// through. Lets move the window out of the way first so the audience
|
||||
// doesn't see this.
|
||||
DEBUG("RestartShow:%d\n", id);
|
||||
DEBUG(L"RestartShow:%d\n", id);
|
||||
Stop(id);
|
||||
GotoSlide(id, pptView[id].slideCount);
|
||||
for (int i=0; i <= pptView[id].steps - pptView[id].lastSlideSteps; i++)
|
||||
|
@ -644,12 +644,12 @@ LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam)
|
|||
HHOOK hook = globalHook;
|
||||
if (nCode == HCBT_CREATEWND)
|
||||
{
|
||||
char csClassName[16];
|
||||
wchar_t csClassName[32];
|
||||
HWND hCurrWnd = (HWND)wParam;
|
||||
DWORD retProcId = NULL;
|
||||
GetClassName(hCurrWnd, csClassName, sizeof(csClassName));
|
||||
if ((strcmp(csClassName, "paneClassDC") == 0)
|
||||
||(strcmp(csClassName, "screenClass") == 0))
|
||||
if ((wcscmp(csClassName, L"paneClassDC") == 0)
|
||||
||(wcscmp(csClassName, L"screenClass") == 0))
|
||||
{
|
||||
int id = -1;
|
||||
DWORD windowThread = GetWindowThreadProcessId(hCurrWnd, NULL);
|
||||
|
@ -663,7 +663,7 @@ LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
if (id >= 0)
|
||||
{
|
||||
if (strcmp(csClassName, "paneClassDC") == 0)
|
||||
if (wcscmp(csClassName, L"paneClassDC") == 0)
|
||||
{
|
||||
pptView[id].hWnd2 = hCurrWnd;
|
||||
}
|
||||
|
@ -737,7 +737,7 @@ LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){
|
|||
CWPSTRUCT *cwp;
|
||||
cwp = (CWPSTRUCT *)lParam;
|
||||
HHOOK hook = NULL;
|
||||
char filename[MAX_PATH];
|
||||
wchar_t filename[MAX_PATH];
|
||||
|
||||
DWORD windowThread = GetWindowThreadProcessId(cwp->hwnd, NULL);
|
||||
int id = -1;
|
||||
|
@ -758,9 +758,9 @@ LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){
|
|||
{
|
||||
if ((pptView[id].currentSlide > 0)
|
||||
&& (pptView[id].previewPath != NULL
|
||||
&& strlen(pptView[id].previewPath) > 0))
|
||||
&& wcslen(pptView[id].previewPath) > 0))
|
||||
{
|
||||
sprintf_s(filename, MAX_PATH, "%s%i.bmp",
|
||||
swprintf_s(filename, MAX_PATH, L"%s%i.bmp",
|
||||
pptView[id].previewPath,
|
||||
pptView[id].currentSlide);
|
||||
CaptureAndSaveWindow(cwp->hwnd, filename);
|
||||
|
@ -820,7 +820,7 @@ LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){
|
|||
return CallNextHookEx(hook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename)
|
||||
VOID CaptureAndSaveWindow(HWND hWnd, wchar_t* filename)
|
||||
{
|
||||
HBITMAP hBmp;
|
||||
if ((hBmp = CaptureWindow(hWnd)) == NULL)
|
||||
|
@ -863,7 +863,7 @@ VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename)
|
|||
|
||||
// Writing:
|
||||
FILE* pFile;
|
||||
int err = fopen_s(&pFile, filename, "wb");
|
||||
int err = _wfopen_s(&pFile, filename, L"wb");
|
||||
if (err == 0)
|
||||
{
|
||||
fwrite(&bmf, sizeof(bmf), 1, pFile);
|
||||
|
@ -893,7 +893,7 @@ HBITMAP CaptureWindow(HWND hWnd)
|
|||
if ((hMemDC = CreateCompatibleDC(hDC)) != NULL)
|
||||
{
|
||||
hDCBmp = (HBITMAP)SelectObject(hMemDC, hImage);
|
||||
HMODULE hLib = LoadLibrary("User32");
|
||||
HMODULE hLib = LoadLibrary(L"User32");
|
||||
// PrintWindow works for windows outside displayable area
|
||||
// but was only introduced in WinXP. BitBlt requires the window to
|
||||
// be topmost and within the viewable area of the display
|
||||
|
|
|
@ -26,13 +26,13 @@
|
|||
|
||||
#define DllExport extern "C" __declspec( dllexport )
|
||||
|
||||
#define DEBUG(...) if (debug) printf(__VA_ARGS__)
|
||||
#define DEBUG(...) if (debug) wprintf(__VA_ARGS__)
|
||||
|
||||
enum PPTVIEWSTATE {PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED,
|
||||
PPT_CLOSING};
|
||||
|
||||
DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
||||
char *previewPath);
|
||||
DllExport int OpenPPT(wchar_t *filename, HWND hParentWnd, RECT rect,
|
||||
wchar_t *previewPath);
|
||||
DllExport BOOL CheckInstalled();
|
||||
DllExport void ClosePPT(int id);
|
||||
DllExport int GetCurrentSlide(int id);
|
||||
|
@ -50,11 +50,11 @@ DllExport void SetDebug(BOOL onOff);
|
|||
LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize);
|
||||
BOOL GetPPTViewerPathFromReg(char *pptViewerPath, int stringSize);
|
||||
BOOL GetPPTViewerPath(wchar_t *pptViewerPath, int stringSize);
|
||||
BOOL GetPPTViewerPathFromReg(wchar_t *pptViewerPath, int stringSize);
|
||||
HBITMAP CaptureWindow(HWND hWnd);
|
||||
VOID SaveBitmap(CHAR* filename, HBITMAP hBmp) ;
|
||||
VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename);
|
||||
VOID SaveBitmap(wchar_t* filename, HBITMAP hBmp) ;
|
||||
VOID CaptureAndSaveWindow(HWND hWnd, wchar_t* filename);
|
||||
BOOL GetPPTInfo(int id);
|
||||
BOOL SavePPTInfo(int id);
|
||||
void Unhook(int id);
|
||||
|
@ -80,8 +80,8 @@ struct PPTVIEW
|
|||
int lastSlideSteps;
|
||||
int steps;
|
||||
int guess;
|
||||
char filename[MAX_PATH];
|
||||
char previewPath[MAX_PATH];
|
||||
wchar_t filename[MAX_PATH];
|
||||
wchar_t previewPath[MAX_PATH];
|
||||
int slideNos[MAX_SLIDES];
|
||||
PPTVIEWSTATE state;
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
|
@ -93,7 +93,7 @@
|
|||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
|
|
|
@ -593,8 +593,11 @@ class HttpConnection(object):
|
|||
for header, value in response.headers.iteritems():
|
||||
http += '%s: %s\r\n' % (header, value)
|
||||
http += '\r\n'
|
||||
self.socket.write(http)
|
||||
self.socket.write(response.content)
|
||||
if self.socket:
|
||||
# Write to the socket if it's open, else ignore it.
|
||||
# See http://support.openlp.org/scp/tickets.php?id=2112
|
||||
self.socket.write(http)
|
||||
self.socket.write(response.content)
|
||||
|
||||
def disconnected(self):
|
||||
"""
|
||||
|
|
|
@ -132,6 +132,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.audioListWidget.setAlternatingRowColors(True)
|
||||
self.findVerseSplit = re.compile(u'---\[\]---\n', re.UNICODE)
|
||||
self.whitespace = re.compile(r'\W+', re.UNICODE)
|
||||
self.find_tags = re.compile(u'\{/?\w+\}', re.UNICODE)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
"""
|
||||
|
@ -720,8 +721,53 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.manager.save_object(book)
|
||||
else:
|
||||
return False
|
||||
cnt_errors = 0
|
||||
error_list = ''
|
||||
verse_tag = []
|
||||
verse_num = []
|
||||
for i in range(self.verseListWidget.rowCount()):
|
||||
item = self.verseListWidget.item(i, 0)
|
||||
tags = self.find_tags.findall(item.text())
|
||||
if self._validate_tags(tags) == False:
|
||||
field = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
verse_tag.append(VerseType.translated_name(field[0]))
|
||||
verse_num.append(field[1:])
|
||||
cnt_errors += 1;
|
||||
if cnt_errors > 0:
|
||||
for i in range(cnt_errors):
|
||||
error_list += '%s %s' % (verse_tag[i], verse_num[i])
|
||||
if i < cnt_errors-1:
|
||||
error_list += ', '
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.EditSongForm',
|
||||
'There are misplaced formatting tags in the following verses:\n\n%s\n\n'
|
||||
'Please correct these tags before continuing.' % error_list))
|
||||
return False
|
||||
return True
|
||||
|
||||
def _validate_tags(self, _tags):
|
||||
"""
|
||||
Validates a list of tags
|
||||
Deletes the first affiliated tag pair which is located side by side in the list
|
||||
and call itself recursively with the shortened tag list.
|
||||
If there is any misplaced tag in the list, either the lenght of the tag list is not even,
|
||||
or the function won't find any tag pairs side by side.
|
||||
If there is no misplaced tag, the length of the list will be zero on any recursive run.
|
||||
|
||||
Return:
|
||||
True if the function can't find any mismatched tags
|
||||
False if there are mismatched tags.
|
||||
"""
|
||||
if len(_tags) == 0:
|
||||
return True
|
||||
if len(_tags) % 2 != 0:
|
||||
return False
|
||||
for i in range(len(_tags)-1):
|
||||
if _tags[i+1] == "{/" + _tags[i][1:]:
|
||||
del _tags[i:i+2]
|
||||
return self._validate_tags(_tags)
|
||||
return False
|
||||
|
||||
def onCopyrightInsertButtonTriggered(self):
|
||||
text = self.copyrightEdit.text()
|
||||
pos = self.copyrightEdit.cursorPosition()
|
||||
|
|
|
@ -79,18 +79,6 @@ NAMESPACE = u'http://openlyrics.info/namespace/2009/song'
|
|||
NSMAP = '{' + NAMESPACE + '}' + '%s'
|
||||
|
||||
|
||||
def clean_xml_string(xml):
|
||||
"""
|
||||
Filter out invalid characters in xml
|
||||
Source <http://stackoverflow.com/questions/8733233/filtering-out-certain-bytes-in-python>
|
||||
|
||||
``xml``
|
||||
The actual text to be checked.
|
||||
|
||||
"""
|
||||
return ''.join(char for char in xml if valid_XML_char_ordinal(ord(char)))
|
||||
|
||||
|
||||
def valid_XML_char_ordinal(char):
|
||||
"""
|
||||
Undertake the filter test.
|
||||
|
@ -103,7 +91,19 @@ def valid_XML_char_ordinal(char):
|
|||
or char in (0x9, 0xA, 0xD)
|
||||
or 0xE000 <= char <= 0xFFFD
|
||||
or 0x10000 <= char <= 0x10FFFF
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def clean_xml_string(xml):
|
||||
"""
|
||||
Filter out invalid characters in xml
|
||||
Source <http://stackoverflow.com/questions/8733233/filtering-out-certain-bytes-in-python>
|
||||
|
||||
``xml``
|
||||
The actual text to be checked.
|
||||
|
||||
"""
|
||||
return ''.join(char for char in xml if valid_XML_char_ordinal(ord(char)))
|
||||
|
||||
|
||||
class SongXML(object):
|
||||
|
|
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
1342
resources/i18n/nl.ts
1342
resources/i18n/nl.ts
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…
Reference in New Issue