diff --git a/openlp/core/ui/firsttimeform.py b/openlp/core/ui/firsttimeform.py index 08e240b5c..708571f8d 100644 --- a/openlp/core/ui/firsttimeform.py +++ b/openlp/core/ui/firsttimeform.py @@ -160,6 +160,16 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): self._performWizard() self._postWizard() + def _getFileSize(self, url): + site = urllib.urlopen(url) + meta = site.info() + return int(meta.getheaders("Content-Length")[0]) + + def _downloadProgress(self, count, block_size, total_size): + increment = (count * block_size) - self.previous_size + self._incrementProgressBar(None, increment) + self.previous_size = count * block_size + def _incrementProgressBar(self, status_text, increment=1): """ Update the wizard progress page. @@ -184,19 +194,27 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): max_progress = 2 # Loop through the songs list and increase for each selected item for i in xrange(self.songsListWidget.count()): - if self.songsListWidget.item(i).checkState() == QtCore.Qt.Checked: - max_progress += 1 + item = self.songsListWidget.item(i) + if item.checkState() == QtCore.Qt.Checked: + filename = item.data(QtCore.Qt.UserRole).toString() + size = self._getFileSize(u'%s%s' % (self.web, filename)) + max_progress += size # Loop through the Bibles list and increase for each selected item iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget) while iterator.value(): item = iterator.value() if item.parent() and item.checkState(0) == QtCore.Qt.Checked: - max_progress += 1 + filename = item.data(0, QtCore.Qt.UserRole).toString() + size = self._getFileSize(u'%s%s' % (self.web, filename)) + max_progress += size iterator += 1 # Loop through the themes list and increase for each selected item for i in xrange(self.themesListWidget.count()): - if self.themesListWidget.item(i).checkState() == QtCore.Qt.Checked: - max_progress += 1 + item = self.themesListWidget.item(i) + if item.checkState() == QtCore.Qt.Checked: + filename = item.data(QtCore.Qt.UserRole).toString() + size = self._getFileSize(u'%s%s' % (self.web, filename)) + max_progress += size self.finishButton.setVisible(False) self.progressBar.setValue(0) self.progressBar.setMinimum(0) @@ -241,27 +259,33 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): item = self.songsListWidget.item(i) if item.checkState() == QtCore.Qt.Checked: filename = item.data(QtCore.Qt.UserRole).toString() - self._incrementProgressBar(self.downloading % filename) + self._incrementProgressBar(self.downloading % filename, 0) + self.previous_size = 0 destination = os.path.join(songs_destination, unicode(filename)) - urllib.urlretrieve(u'%s%s' % (self.web, filename), destination) + urllib.urlretrieve(u'%s%s' % (self.web, filename), destination, + self._downloadProgress) # Download Bibles bibles_iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget) while bibles_iterator.value(): item = bibles_iterator.value() if item.parent() and item.checkState(0) == QtCore.Qt.Checked: bible = unicode(item.data(0, QtCore.Qt.UserRole).toString()) - self._incrementProgressBar(self.downloading % bible) + self._incrementProgressBar(self.downloading % bible, 0) + self.previous_size = 0 urllib.urlretrieve(u'%s%s' % (self.web, bible), - os.path.join(bibles_destination, bible)) + os.path.join(bibles_destination, bible), + self._downloadProgress) bibles_iterator += 1 # Download themes for i in xrange(self.themesListWidget.count()): item = self.themesListWidget.item(i) if item.checkState() == QtCore.Qt.Checked: theme = unicode(item.data(QtCore.Qt.UserRole).toString()) - self._incrementProgressBar(self.downloading % theme) + self._incrementProgressBar(self.downloading % theme, 0) + self.previous_size = 0 urllib.urlretrieve(u'%s%s' % (self.web, theme), - os.path.join(themes_destination, theme)) + os.path.join(themes_destination, theme), + self._downloadProgress) # Set Default Display if self.displayComboBox.currentIndex() != -1: QtCore.QSettings().setValue(u'General/monitor', diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index 1dbbb3559..eabccd301 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -32,27 +32,6 @@ from openlp.core.lib.ui import UiStrings log = logging.getLogger(__name__) -class ValidEdit(QtGui.QLineEdit): - """ - Only allow numeric characters to be edited - """ - def __init__(self, parent): - """ - Set up Override and Validator - """ - QtGui.QLineEdit.__init__(self, parent) - self.setValidator(QtGui.QIntValidator(0, 9999, self)) - - def validText(self): - """ - Only return Integers. Space is 0 - """ - if self.text().isEmpty(): - return QtCore.QString(u'0') - else: - return self.text() - - class GeneralTab(SettingsTab): """ GeneralTab is the general settings tab in the settings dialog. @@ -164,30 +143,6 @@ class GeneralTab(SettingsTab): self.displayGroupBox.setObjectName(u'displayGroupBox') self.displayLayout = QtGui.QGridLayout(self.displayGroupBox) self.displayLayout.setObjectName(u'displayLayout') - self.currentXLabel = QtGui.QLabel(self.displayGroupBox) - self.currentXLabel.setObjectName(u'currentXLabel') - self.displayLayout.addWidget(self.currentXLabel, 0, 0) - self.currentXValueLabel = QtGui.QLabel(self.displayGroupBox) - self.currentXValueLabel.setObjectName(u'currentXValueLabel') - self.displayLayout.addWidget(self.currentXValueLabel, 1, 0) - self.currentYLabel = QtGui.QLabel(self.displayGroupBox) - self.currentYLabel.setObjectName(u'currentYLabel') - self.displayLayout.addWidget(self.currentYLabel, 0, 1) - self.currentYValueLabel = QtGui.QLabel(self.displayGroupBox) - self.currentYValueLabel.setObjectName(u'currentYValueLabel') - self.displayLayout.addWidget(self.currentYValueLabel, 1, 1) - self.currentWidthLabel = QtGui.QLabel(self.displayGroupBox) - self.currentWidthLabel.setObjectName(u'currentWidthLabel') - self.displayLayout.addWidget(self.currentWidthLabel, 0, 2) - self.currentWidthValueLabel = QtGui.QLabel(self.displayGroupBox) - self.currentWidthValueLabel.setObjectName(u'currentWidthValueLabel') - self.displayLayout.addWidget(self.currentWidthValueLabel, 1, 2) - self.currentHeightLabel = QtGui.QLabel(self.displayGroupBox) - self.currentHeightLabel.setObjectName(u'currentHeightLabel') - self.displayLayout.addWidget(self.currentHeightLabel, 0, 3) - self.currentHeightValueLabel = QtGui.QLabel(self.displayGroupBox) - self.currentHeightValueLabel.setObjectName(u'Height') - self.displayLayout.addWidget(self.currentHeightValueLabel, 1, 3) self.overrideCheckBox = QtGui.QCheckBox(self.displayGroupBox) self.overrideCheckBox.setObjectName(u'overrideCheckBox') self.displayLayout.addWidget(self.overrideCheckBox, 2, 0, 1, 4) @@ -196,26 +151,30 @@ class GeneralTab(SettingsTab): self.customXLabel = QtGui.QLabel(self.displayGroupBox) self.customXLabel.setObjectName(u'customXLabel') self.displayLayout.addWidget(self.customXLabel, 3, 0) - self.customXValueEdit = ValidEdit(self.displayGroupBox) + self.customXValueEdit = QtGui.QSpinBox(self.displayGroupBox) self.customXValueEdit.setObjectName(u'customXValueEdit') + self.customXValueEdit.setMaximum(9999) self.displayLayout.addWidget(self.customXValueEdit, 4, 0) self.customYLabel = QtGui.QLabel(self.displayGroupBox) self.customYLabel.setObjectName(u'customYLabel') self.displayLayout.addWidget(self.customYLabel, 3, 1) - self.customYValueEdit = ValidEdit(self.displayGroupBox) + self.customYValueEdit = QtGui.QSpinBox(self.displayGroupBox) self.customYValueEdit.setObjectName(u'customYValueEdit') + self.customYValueEdit.setMaximum(9999) self.displayLayout.addWidget(self.customYValueEdit, 4, 1) self.customWidthLabel = QtGui.QLabel(self.displayGroupBox) self.customWidthLabel.setObjectName(u'customWidthLabel') self.displayLayout.addWidget(self.customWidthLabel, 3, 2) - self.customWidthValueEdit = ValidEdit(self.displayGroupBox) + self.customWidthValueEdit = QtGui.QSpinBox(self.displayGroupBox) self.customWidthValueEdit.setObjectName(u'customWidthValueEdit') + self.customWidthValueEdit.setMaximum(9999) self.displayLayout.addWidget(self.customWidthValueEdit, 4, 2) self.customHeightLabel = QtGui.QLabel(self.displayGroupBox) self.customHeightLabel.setObjectName(u'customHeightLabel') self.displayLayout.addWidget(self.customHeightLabel, 3, 3) - self.customHeightValueEdit = ValidEdit(self.displayGroupBox) + self.customHeightValueEdit = QtGui.QSpinBox(self.displayGroupBox) self.customHeightValueEdit.setObjectName(u'customHeightValueEdit') + self.customHeightValueEdit.setMaximum(9999) self.displayLayout.addWidget(self.customHeightValueEdit, 4, 3) self.rightLayout.addWidget(self.displayGroupBox) self.rightLayout.addStretch() @@ -223,17 +182,13 @@ class GeneralTab(SettingsTab): QtCore.QObject.connect(self.overrideCheckBox, QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideCheckBoxToggled) QtCore.QObject.connect(self.customHeightValueEdit, - QtCore.SIGNAL(u'textEdited(const QString&)'), - self.onDisplayPositionChanged) + QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayPositionChanged) QtCore.QObject.connect(self.customWidthValueEdit, - QtCore.SIGNAL(u'textEdited(const QString&)'), - self.onDisplayPositionChanged) + QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayPositionChanged) QtCore.QObject.connect(self.customYValueEdit, - QtCore.SIGNAL(u'textEdited(const QString&)'), - self.onDisplayPositionChanged) + QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayPositionChanged) QtCore.QObject.connect(self.customXValueEdit, - QtCore.SIGNAL(u'textEdited(const QString&)'), - self.onDisplayPositionChanged) + QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayPositionChanged) # Reload the tab, as the screen resolution/count may have changed. QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_screen_changed'), self.load) @@ -273,8 +228,7 @@ class GeneralTab(SettingsTab): 'Automatically preview next item in service')) self.timeoutLabel.setText(translate('OpenLP.GeneralTab', 'Slide loop delay:')) - self.timeoutSpinBox.setSuffix( - translate('OpenLP.GeneralTab', ' sec')) + self.timeoutSpinBox.setSuffix(translate('OpenLP.GeneralTab', ' sec')) self.ccliGroupBox.setTitle( translate('OpenLP.GeneralTab', 'CCLI Details')) self.numberLabel.setText(UiStrings.CCLINumberLabel) @@ -285,22 +239,11 @@ class GeneralTab(SettingsTab): # Moved from display tab self.displayGroupBox.setTitle( translate('OpenLP.GeneralTab', 'Display Position')) - self.currentXLabel.setText(translate('OpenLP.GeneralTab', 'X')) - self.currentXValueLabel.setText(u'0') - self.currentYLabel.setText(translate('OpenLP.GeneralTab', 'Y')) - self.currentYValueLabel.setText(u'0') - self.currentHeightLabel.setText( - translate('OpenLP.GeneralTab', 'Height')) - self.currentHeightValueLabel.setText(u'0') - self.currentWidthLabel.setText( - translate('OpenLP.GeneralTab', 'Width')) - self.currentWidthValueLabel.setText(u'0') self.overrideCheckBox.setText(translate('OpenLP.GeneralTab', 'Override display position')) self.customXLabel.setText(translate('OpenLP.GeneralTab', 'X')) self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y')) - self.customHeightLabel.setText( - translate('OpenLP.GeneralTab', 'Height')) + self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height')) self.customWidthLabel.setText(translate('OpenLP.GeneralTab', 'Width')) def load(self): @@ -310,8 +253,7 @@ class GeneralTab(SettingsTab): settings = QtCore.QSettings() settings.beginGroup(self.settingsSection) self.monitorComboBox.clear() - for screen in self.screens.get_screen_list(): - self.monitorComboBox.addItem(screen) + self.monitorComboBox.addItems(self.screens.get_screen_list()) self.numberEdit.setText(unicode(settings.value( u'ccli number', QtCore.QVariant(u'')).toString())) self.usernameEdit.setText(unicode(settings.value( @@ -334,26 +276,16 @@ class GeneralTab(SettingsTab): QtCore.QVariant(False)).toBool()) self.timeoutSpinBox.setValue(settings.value(u'loop delay', QtCore.QVariant(5)).toInt()[0]) - self.currentXValueLabel.setText( - unicode(self.screens.current[u'size'].x())) - self.currentYValueLabel.setText( - unicode(self.screens.current[u'size'].y())) - self.currentHeightValueLabel.setText( - unicode(self.screens.current[u'size'].height())) - self.currentWidthValueLabel.setText( - unicode(self.screens.current[u'size'].width())) self.overrideCheckBox.setChecked(settings.value(u'override position', QtCore.QVariant(False)).toBool()) - self.customXValueEdit.setText(settings.value(u'x position', - QtCore.QVariant(self.screens.current[u'size'].x())).toString()) - self.customYValueEdit.setText(settings.value(u'y position', - QtCore.QVariant(self.screens.current[u'size'].y())).toString()) - self.customHeightValueEdit.setText( - settings.value(u'height', QtCore.QVariant( - self.screens.current[u'size'].height())).toString()) - self.customWidthValueEdit.setText( - settings.value(u'width', QtCore.QVariant( - self.screens.current[u'size'].width())).toString()) + self.customXValueEdit.setValue(settings.value(u'x position', + QtCore.QVariant(self.screens.current[u'size'].x())).toInt()[0]) + self.customYValueEdit.setValue(settings.value(u'y position', + QtCore.QVariant(self.screens.current[u'size'].y())).toInt()[0]) + self.customHeightValueEdit.setValue(settings.value(u'height', + QtCore.QVariant(self.screens.current[u'size'].height())).toInt()[0]) + self.customWidthValueEdit.setValue(settings.value(u'width', + QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0]) settings.endGroup() self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked()) @@ -391,13 +323,13 @@ class GeneralTab(SettingsTab): settings.setValue(u'songselect password', QtCore.QVariant(self.passwordEdit.displayText())) settings.setValue(u'x position', - QtCore.QVariant(self.customXValueEdit.text())) + QtCore.QVariant(self.customXValueEdit.value())) settings.setValue(u'y position', - QtCore.QVariant(self.customYValueEdit.text())) + QtCore.QVariant(self.customYValueEdit.value())) settings.setValue(u'height', - QtCore.QVariant(self.customHeightValueEdit.text())) + QtCore.QVariant(self.customHeightValueEdit.value())) settings.setValue(u'width', - QtCore.QVariant(self.customWidthValueEdit.text())) + QtCore.QVariant(self.customWidthValueEdit.value())) settings.setValue(u'override position', QtCore.QVariant(self.overrideCheckBox.isChecked())) settings.endGroup() @@ -421,10 +353,10 @@ class GeneralTab(SettingsTab): # Reset screens after initial definition if self.overrideChanged: self.screens.override[u'size'] = QtCore.QRect( - int(self.customXValueEdit.validText()), - int(self.customYValueEdit.validText()), - int(self.customWidthValueEdit.validText()), - int(self.customHeightValueEdit.validText())) + self.customXValueEdit.value(), + self.customYValueEdit.value(), + self.customWidthValueEdit.value(), + self.customHeightValueEdit.value()) if self.overrideCheckBox.isChecked(): self.screens.set_override_display() else: diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index f220f558a..5b19ac246 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -80,8 +80,7 @@ class PowerpointController(PresentationController): log.debug(u'start_process') if not self.process: self.process = Dispatch(u'PowerPoint.Application') - if float(self.process.Version) < 13: - self.process.Visible = True + self.process.Visible = True self.process.WindowState = 2 def kill(self): diff --git a/openlp/plugins/presentations/lib/pptviewlib/ppttest.py b/openlp/plugins/presentations/lib/pptviewlib/ppttest.py index f8d0fabd9..9730659c3 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/ppttest.py +++ b/openlp/plugins/presentations/lib/pptviewlib/ppttest.py @@ -30,19 +30,32 @@ from ctypes import * from ctypes.wintypes import RECT class PPTViewer(QtGui.QWidget): + """ + Standalone Test Harness for the pptviewlib library + """ def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.pptid = -1 self.setWindowTitle(u'PowerPoint Viewer Test') - PPTLabel = QtGui.QLabel(u'Open PowerPoint file') - slideLabel = QtGui.QLabel(u'Go to slide #') - self.PPTEdit = QtGui.QLineEdit() + ppt_label = QtGui.QLabel(u'Open PowerPoint file') + slide_label = QtGui.QLabel(u'Go to slide #') + self.pptEdit = QtGui.QLineEdit() self.slideEdit = QtGui.QLineEdit() + x_label = QtGui.QLabel(u'X pos') + y_label = QtGui.QLabel(u'Y pos') + width_label = QtGui.QLabel(u'Width') + height_label = QtGui.QLabel(u'Height') + self.xEdit = QtGui.QLineEdit(u'100') + self.yEdit = QtGui.QLineEdit(u'100') + self.widthEdit = QtGui.QLineEdit(u'900') + self.heightEdit = QtGui.QLineEdit(u'700') self.total = QtGui.QLabel() - PPTBtn = QtGui.QPushButton(u'Open') - PPTDlgBtn = QtGui.QPushButton(u'...') - slideBtn = QtGui.QPushButton(u'Go') + ppt_btn = QtGui.QPushButton(u'Open') + ppt_dlg_btn = QtGui.QPushButton(u'...') + folder_label = QtGui.QLabel(u'Slide .bmp path') + self.folderEdit = QtGui.QLineEdit(u'slide') + slide_btn = QtGui.QPushButton(u'Go') prev = QtGui.QPushButton(u'Prev') next = QtGui.QPushButton(u'Next') blank = QtGui.QPushButton(u'Blank') @@ -51,122 +64,149 @@ class PPTViewer(QtGui.QWidget): close = QtGui.QPushButton(u'Close') resume = QtGui.QPushButton(u'Resume') stop = QtGui.QPushButton(u'Stop') - pptwindow = QtGui.QWidget() - grid = QtGui.QGridLayout() - grid.addWidget(PPTLabel, 0, 0) - grid.addWidget(self.PPTEdit, 0, 1) - grid.addWidget(PPTDlgBtn, 0, 2) - grid.addWidget(PPTBtn, 0, 3) - grid.addWidget(slideLabel, 1, 0) - grid.addWidget(self.slideEdit, 1, 1) - grid.addWidget(slideBtn, 1, 3) - grid.addWidget(prev, 2, 0) - grid.addWidget(next, 2, 1) - grid.addWidget(blank, 3, 0) - grid.addWidget(unblank, 3, 1) - grid.addWidget(restart, 4, 0) - grid.addWidget(close, 4, 1) - grid.addWidget(stop, 5, 0) - grid.addWidget(resume, 5, 1) - grid.addWidget(pptwindow, 6, 0, 10, 3) - self.connect(PPTBtn, QtCore.SIGNAL(u'clicked()'), self.OpenClick) - self.connect(PPTDlgBtn, QtCore.SIGNAL(u'clicked()'), self.OpenDialog) - self.connect(slideBtn, QtCore.SIGNAL(u'clicked()'), self.GotoClick) - self.connect(prev, QtCore.SIGNAL(u'clicked()'), self.PrevClick) - self.connect(next, QtCore.SIGNAL(u'clicked()'), self.NextClick) - self.connect(blank, QtCore.SIGNAL(u'clicked()'), self.BlankClick) - self.connect(unblank, QtCore.SIGNAL(u'clicked()'), self.UnblankClick) - self.connect(restart, QtCore.SIGNAL(u'clicked()'), self.RestartClick) - self.connect(close, QtCore.SIGNAL(u'clicked()'), self.CloseClick) - self.connect(stop, QtCore.SIGNAL(u'clicked()'), self.StopClick) - self.connect(resume, QtCore.SIGNAL(u'clicked()'), self.ResumeClick) - + row = 0 + grid.addWidget(folder_label, 0, 0) + grid.addWidget(self.folderEdit, 0, 1) + row = row + 1 + grid.addWidget(x_label, row, 0) + grid.addWidget(self.xEdit, row, 1) + grid.addWidget(y_label, row, 2) + grid.addWidget(self.yEdit, row, 3) + row = row + 1 + grid.addWidget(width_label, row, 0) + grid.addWidget(self.widthEdit, row, 1) + grid.addWidget(height_label, row, 2) + grid.addWidget(self.heightEdit, row, 3) + row = row + 1 + grid.addWidget(ppt_label, row, 0) + grid.addWidget(self.pptEdit, row, 1) + grid.addWidget(ppt_dlg_btn, row, 2) + grid.addWidget(ppt_btn, row, 3) + row = row + 1 + grid.addWidget(slide_label, row, 0) + grid.addWidget(self.slideEdit, row, 1) + grid.addWidget(slide_btn, row, 2) + row = row + 1 + grid.addWidget(prev, row, 0) + grid.addWidget(next, row, 1) + row = row + 1 + grid.addWidget(blank, row, 0) + grid.addWidget(unblank, row, 1) + row = row + 1 + grid.addWidget(restart, row, 0) + grid.addWidget(close, row, 1) + row = row + 1 + grid.addWidget(stop, row, 0) + grid.addWidget(resume, row, 1) + self.connect(ppt_btn, QtCore.SIGNAL(u'clicked()'), self.openClick) + self.connect(ppt_dlg_btn, QtCore.SIGNAL(u'clicked()'), self.openDialog) + self.connect(slide_btn, QtCore.SIGNAL(u'clicked()'), self.gotoClick) + self.connect(prev, QtCore.SIGNAL(u'clicked()'), self.prevClick) + self.connect(next, QtCore.SIGNAL(u'clicked()'), self.nextClick) + self.connect(blank, QtCore.SIGNAL(u'clicked()'), self.blankClick) + self.connect(unblank, QtCore.SIGNAL(u'clicked()'), self.unblankClick) + self.connect(restart, QtCore.SIGNAL(u'clicked()'), self.restartClick) + self.connect(close, QtCore.SIGNAL(u'clicked()'), self.closeClick) + self.connect(stop, QtCore.SIGNAL(u'clicked()'), self.stopClick) + self.connect(resume, QtCore.SIGNAL(u'clicked()'), self.resumeClick) self.setLayout(grid) - self.resize(300, 150) - def PrevClick(self): - if self.pptid<0: return - pptdll.PrevStep(self.pptid) - self.UpdateCurrSlide() + def prevClick(self): + if self.pptid < 0: + return + self.pptdll.PrevStep(self.pptid) + self.updateCurrSlide() app.processEvents() - def NextClick(self): - if(self.pptid<0): return - pptdll.NextStep(self.pptid) - self.UpdateCurrSlide() + def nextClick(self): + if self.pptid < 0: + return + self.pptdll.NextStep(self.pptid) + self.updateCurrSlide() app.processEvents() - def BlankClick(self): - if(self.pptid<0): return - pptdll.Blank(self.pptid) + def blankClick(self): + if self.pptid < 0: + return + self.pptdll.Blank(self.pptid) app.processEvents() - def UnblankClick(self): - if(self.pptid<0): return - pptdll.Unblank(self.pptid) + def unblankClick(self): + if self.pptid < 0: + return + self.pptdll.Unblank(self.pptid) app.processEvents() - def RestartClick(self): - if(self.pptid<0): return - pptdll.RestartShow(self.pptid) - self.UpdateCurrSlide() + def restartClick(self): + if self.pptid < 0: + return + self.pptdll.RestartShow(self.pptid) + self.updateCurrSlide() app.processEvents() - def StopClick(self): - if(self.pptid<0): return - pptdll.Stop(self.pptid) + def stopClick(self): + if self.pptid < 0: + return + self.pptdll.Stop(self.pptid) app.processEvents() - def ResumeClick(self): - if(self.pptid<0): return - pptdll.Resume(self.pptid) + def resumeClick(self): + if self.pptid < 0: + return + self.pptdll.Resume(self.pptid) app.processEvents() - def CloseClick(self): - if(self.pptid<0): return - pptdll.ClosePPT(self.pptid) + def closeClick(self): + if self.pptid < 0: + return + self.pptdll.ClosePPT(self.pptid) self.pptid = -1 app.processEvents() - def OpenClick(self): + def openClick(self): oldid = self.pptid; - rect = RECT(100,100,900,700) - filename = str(self.PPTEdit.text().replace(u'/', u'\\')) - print filename - self.pptid = pptdll.OpenPPT(filename, None, rect, 'c:\\temp\\slide') - print "id: " + unicode(self.pptid) - if oldid>=0: - pptdll.ClosePPT(oldid); - slides = pptdll.GetSlideCount(self.pptid) - print "slidecount: " + unicode(slides) - self.total.setNum(pptdll.GetSlideCount(self.pptid)) - self.UpdateCurrSlide() + 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 + self.pptid = self.pptdll.OpenPPT(filename, None, rect, folder) + print u'id: ' + unicode(self.pptid) + if oldid >= 0: + self.pptdll.ClosePPT(oldid); + slides = self.pptdll.GetSlideCount(self.pptid) + print u'slidecount: ' + unicode(slides) + self.total.setNum(self.pptdll.GetSlideCount(self.pptid)) + self.updateCurrSlide() - def UpdateCurrSlide(self): - if(self.pptid<0): return - slide = unicode(pptdll.GetCurrentSlide(self.pptid)) - print "currslide: " + slide + def updateCurrSlide(self): + if self.pptid < 0: + return + slide = unicode(self.pptdll.GetCurrentSlide(self.pptid)) + print u'currslide: ' + slide self.slideEdit.setText(slide) app.processEvents() - def GotoClick(self): - if(self.pptid<0): return + def gotoClick(self): + if self.pptid < 0: + return print self.slideEdit.text() - pptdll.GotoSlide(self.pptid, int(self.slideEdit.text())) - self.UpdateCurrSlide() + self.pptdll.GotoSlide(self.pptid, int(self.slideEdit.text())) + self.updateCurrSlide() app.processEvents() - def OpenDialog(self): - self.PPTEdit.setText(QtGui.QFileDialog.getOpenFileName(self, 'Open file')) + def openDialog(self): + self.pptEdit.setText(QtGui.QFileDialog.getOpenFileName(self, + u'Open file')) if __name__ == '__main__': - #pptdll = cdll.LoadLibrary(r'C:\Documents and Settings\jonathan\Desktop\pptviewlib.dll') pptdll = cdll.LoadLibrary(r'pptviewlib.dll') pptdll.SetDebug(1) - print "Begin..." + print u'Begin...' app = QtGui.QApplication(sys.argv) - qb = PPTViewer() - qb.show() + window = PPTViewer() + window.pptdll = pptdll + window.show() sys.exit(app.exec_()) diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp index 86876a836..f8a07d940 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp @@ -1,21 +1,26 @@ -/* - * PPTVIEWLIB - Control PowerPoint Viewer 2003/2007 (for openlp.org) - * Copyright (C) 2008 Jonathan Corwin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - +/****************************************************************************** +* PptViewLib - PowerPoint Viewer 2003/2007 Controller * +* OpenLP - Open Source Lyrics Projection * +* --------------------------------------------------------------------------- * +* Copyright (c) 2008-2011 Raoul Snyman * +* Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael * +* Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, * +* Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon * +* Tibble, Carsten Tinggaard, Frode Woldsund * +* --------------------------------------------------------------------------- * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation; version 2 of the License. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, write to the Free Software Foundation, Inc., 59 * +* Temple Place, Suite 330, Boston, MA 02111-1307 USA * +******************************************************************************/ #define WIN32_LEAN_AND_MEAN #include @@ -27,67 +32,63 @@ #include #include "pptviewlib.h" - -// Because of the callbacks used by SetWindowsHookEx, the memory used needs to be -// sharable across processes (the callbacks are done from a different process) -// Therefore use data_seg with RWS memory. +// Because of the callbacks used by SetWindowsHookEx, the memory used needs to +// be sharable across processes (the callbacks are done from a different +// process) Therefore use data_seg with RWS memory. // -// See http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx for alternative -// method of holding memory, removing fixed limits which would allow dynamic number -// of items, rather than a fixed number. Use a Local\ mapping, since global has UAC -// issues in Vista. +// See http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx for +// alternative method of holding memory, removing fixed limits which would allow +// dynamic number of items, rather than a fixed number. Use a Local\ mapping, +// since global has UAC issues in Vista. + #pragma data_seg(".PPTVIEWLIB") -PPTVIEWOBJ pptviewobj[MAX_PPTOBJS] = {NULL}; -HHOOK globalhook = NULL; +PPTVIEW pptView[MAX_PPTS] = {NULL}; +HHOOK globalHook = NULL; BOOL debug = FALSE; #pragma data_seg() #pragma comment(linker, "/SECTION:.PPTVIEWLIB,RWS") -#define DEBUG(...) if(debug) printf(__VA_ARGS__) - - HINSTANCE hInstance = NULL; -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReasonForCall, + LPVOID lpReserved) { hInstance = (HINSTANCE)hModule; - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - DEBUG("PROCESS_ATTACH\n"); - break; - case DLL_THREAD_ATTACH: - DEBUG("THREAD_ATTACH\n"); - break; - case DLL_THREAD_DETACH: - DEBUG("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"); - for(int i = 0; i.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(char *filename, HWND hParentWnd, RECT rect, + char *previewPath) { - STARTUPINFO si; - PROCESS_INFORMATION pi; - char cmdline[MAX_PATH * 2]; - int id; + STARTUPINFO si; + PROCESS_INFORMATION pi; + char 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, rect.left, rect.bottom, rect.right); - if(GetPPTViewerPath(cmdline, sizeof(cmdline))==FALSE) - { - DEBUG("OpenPPT: GetPPTViewerPath failed\n"); - return -1; - } - id = -1; - for(int i = 0; ibottom-wndrect->top; - pptviewobj[id].rect.right = wndrect->right-wndrect->left; - } - else - { - pptviewobj[id].rect.top = rect.top; - pptviewobj[id].rect.left = rect.left; - pptviewobj[id].rect.bottom = rect.bottom; - pptviewobj[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, "\""); - memset(&si, 0, sizeof(si)); - memset(&pi, 0, sizeof(pi)); - BOOL gotinfo = GetPPTInfo(id); - /* - * I'd really like to just hook on the new threadid. However this always gives - * error 87. Perhaps I'm hooking to soon? No idea... however can't wait - * since I need to ensure I pick up the WM_CREATE as this is the only - * time the window can be resized in such away the content scales correctly - * - * hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId); - */ - if(globalhook!=NULL) - UnhookWindowsHookEx(globalhook); - globalhook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,NULL); - if(globalhook==0) - { - DEBUG("OpenPPT: SetWindowsHookEx failed\n"); - ClosePPT(id); - return -1; - } - pptviewobj[id].state = PPT_STARTED; + DEBUG("OpenPPT start: %s; %s\n", filename, previewPath); + DEBUG("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"); + return -1; + } + id = -1; + for (int i = 0; i < MAX_PPTS; i++) + { + if (pptView[i].state == PPT_CLOSED) + { + id = i; + break; + } + } + if (id < 0) + { + DEBUG("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); + pptView[id].state = PPT_CLOSED; + pptView[id].slideCount = 0; + pptView[id].currentSlide = 0; + pptView[id].firstSlideSteps = 0; + pptView[id].lastSlideSteps = 0; + pptView[id].guess = 0; + pptView[id].hParentWnd = hParentWnd; + pptView[id].hWnd = NULL; + pptView[id].hWnd2 = NULL; + for (int i = 0; i < MAX_SLIDES; i++) + { + pptView[id].slideNos[i] = 0; + } + if (hParentWnd != NULL && rect.top == 0 && rect.bottom == 0 + && rect.left == 0 && rect.right == 0) + { + LPRECT windowRect = NULL; + GetWindowRect(hParentWnd, windowRect); + pptView[id].rect.top = 0; + pptView[id].rect.left = 0; + pptView[id].rect.bottom = windowRect->bottom - windowRect->top; + pptView[id].rect.right = windowRect->right - windowRect->left; + } + else + { + pptView[id].rect.top = rect.top; + pptView[id].rect.left = rect.left; + 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, "\""); + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); + BOOL gotInfo = GetPPTInfo(id); + /* + * I'd really like to just hook on the new threadid. However this always + * gives error 87. Perhaps I'm hooking to soon? No idea... however can't + * wait since I need to ensure I pick up the WM_CREATE as this is the only + * time the window can be resized in such away the content scales correctly + * + * hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId); + */ + if (globalHook != NULL) + { + UnhookWindowsHookEx(globalHook); + } + globalHook = SetWindowsHookEx(WH_CBT, CbtProc, hInstance, NULL); + if (globalHook == 0) + { + DEBUG("OpenPPT: SetWindowsHookEx failed\n"); + ClosePPT(id); + return -1; + } + pptView[id].state = PPT_STARTED; Sleep(10); - if(!CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) - { - DEBUG("OpenPPT: CreateProcess failed\n"); - ClosePPT(id); - return -1; - } - pptviewobj[id].dwProcessId = pi.dwProcessId; - pptviewobj[id].dwThreadId = pi.dwThreadId; - pptviewobj[id].hThread = pi.hThread; - pptviewobj[id].hProcess = pi.hProcess; - while(pptviewobj[id].state==PPT_STARTED) - Sleep(10); - if(gotinfo) - { - DEBUG("OpenPPT: Info loaded, no refresh\n"); - pptviewobj[id].state = PPT_LOADED; - Resume(id); - } - else - { - DEBUG("OpenPPT: Get info\n"); - pptviewobj[id].steps = 0; - int steps = 0; - while(pptviewobj[id].state==PPT_OPENED) - { - if(steps<=pptviewobj[id].steps) - { - Sleep(20); - DEBUG("OpenPPT: Step %d/%d\n",steps,pptviewobj[id].steps); - steps++; - NextStep(id); - } - Sleep(10); - } - DEBUG("OpenPPT: Steps %d, first slide steps %d\n",pptviewobj[id].steps,pptviewobj[id].firstSlideSteps); - SavePPTInfo(id); - if(pptviewobj[id].state==PPT_CLOSING||pptviewobj[id].slideCount<=0){ - ClosePPT(id); - id=-1; - } - else - RestartShow(id); - } - if(id>=0) - { - if(pptviewobj[id].mhook!=NULL) - UnhookWindowsHookEx(pptviewobj[id].mhook); - pptviewobj[id].mhook = NULL; - } - DEBUG("OpenPPT: Exit: id=%i\n", id); - return id; + if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) + { + DEBUG("OpenPPT: CreateProcess failed\n"); + ClosePPT(id); + return -1; + } + pptView[id].dwProcessId = pi.dwProcessId; + pptView[id].dwThreadId = pi.dwThreadId; + pptView[id].hThread = pi.hThread; + pptView[id].hProcess = pi.hProcess; + while (pptView[id].state == PPT_STARTED) + Sleep(10); + if (gotInfo) + { + DEBUG("OpenPPT: Info loaded, no refresh\n"); + pptView[id].state = PPT_LOADED; + Resume(id); + } + else + { + DEBUG("OpenPPT: Get info\n"); + pptView[id].steps = 0; + int steps = 0; + while (pptView[id].state == PPT_OPENED) + { + if (steps <= pptView[id].steps) + { + Sleep(20); + DEBUG("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", + 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]); + } + SavePPTInfo(id); + if (pptView[id].state == PPT_CLOSING + || pptView[id].slideCount <= 0) + { + ClosePPT(id); + id=-1; + } + else + { + RestartShow(id); + } + } + if (id >= 0) + { + if (pptView[id].msgHook != NULL) + { + UnhookWindowsHookEx(pptView[id].msgHook); + } + pptView[id].msgHook = NULL; + } + DEBUG("OpenPPT: Exit: id=%i\n", id); + return id; } // Load information about the ppt from an info.txt file. // Format: @@ -236,292 +260,316 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewp // first slide steps BOOL GetPPTInfo(int id) { - struct _stat filestats; - char info[MAX_PATH]; - FILE* pFile; - char buf[100]; + struct _stat fileStats; + char info[MAX_PATH]; + FILE* pFile; + char buf[100]; - DEBUG("GetPPTInfo: start\n"); - if(_stat(pptviewobj[id].filename, &filestats)!=0) - return FALSE; - sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath); - int err = fopen_s(&pFile, info, "r"); - if(err!=0) - { - DEBUG("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)) - { - fclose (pFile); - return FALSE; - } - fgets(buf, 100, pFile); - if(filestats.st_size!=atoi(buf)) - { - fclose (pFile); - return FALSE; - } - fgets(buf, 100, pFile); // slidecount - int slidecount = atoi(buf); - fgets(buf, 100, pFile); // first slide steps - int firstslidesteps = atoi(buf); - // check all the preview images still exist - for(int i = 1; i<=slidecount; i++) - { - sprintf_s(info, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, i); - if(GetFileAttributes(info)==INVALID_FILE_ATTRIBUTES) - return FALSE; - } - fclose(pFile); - pptviewobj[id].slideCount = slidecount; - pptviewobj[id].firstSlideSteps = firstslidesteps; - DEBUG("GetPPTInfo: exit ok\n"); - return TRUE; + DEBUG("GetPPTInfo: start\n"); + if (_stat(pptView[id].filename, &fileStats) != 0) + { + return FALSE; + } + sprintf_s(info, MAX_PATH, "%sinfo.txt", pptView[id].previewPath); + int err = fopen_s(&pFile, info, "r"); + if (err != 0) + { + DEBUG("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)) + { + DEBUG("GetPPTInfo: date changed\n"); + fclose (pFile); + return FALSE; + } + fgets(buf, 100, pFile); + if (fileStats.st_size != atoi(buf)) + { + DEBUG("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); + // 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); + if (GetFileAttributes(info) == INVALID_FILE_ATTRIBUTES) + { + DEBUG("GetPPTInfo: bmp not found\n"); + return FALSE; + } + } + fclose(pFile); + pptView[id].slideCount = slideCount; + pptView[id].firstSlideSteps = firstSlideSteps; + DEBUG("GetPPTInfo: exit ok\n"); + return TRUE; } BOOL SavePPTInfo(int id) { - struct _stat filestats; - char info[MAX_PATH]; - FILE* pFile; + struct _stat fileStats; + char info[MAX_PATH]; + FILE* pFile; - DEBUG("SavePPTInfo: start\n"); - if(_stat(pptviewobj[id].filename, &filestats)!=0) - { - DEBUG("SavePPTInfo: stat of %s failed\n", pptviewobj[id].filename); - return FALSE; - } - sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath); - int err = fopen_s(&pFile, info, "w"); - if(err!=0) - { - DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err); - return FALSE; - } - fprintf(pFile, "1\n"); - fprintf(pFile, "%u\n", filestats.st_mtime); - fprintf(pFile, "%u\n", filestats.st_size); - fprintf(pFile, "%u\n", pptviewobj[id].slideCount); - fprintf(pFile, "%u\n", pptviewobj[id].firstSlideSteps); - fclose (pFile); - DEBUG("SavePPTInfo: exit ok\n"); - return TRUE; + DEBUG("SavePPTInfo: start\n"); + if (_stat(pptView[id].filename, &fileStats) != 0) + { + DEBUG("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"); + if (err != 0) + { + DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err); + return FALSE; + } + fprintf(pFile, "1\n"); + fprintf(pFile, "%u\n", fileStats.st_mtime); + fprintf(pFile, "%u\n", fileStats.st_size); + fprintf(pFile, "%u\n", pptView[id].slideCount); + fprintf(pFile, "%u\n", pptView[id].firstSlideSteps); + fclose(pFile); + DEBUG("SavePPTInfo: exit ok\n"); + return TRUE; } // Get the path of the PowerPoint viewer from the registry -BOOL GetPPTViewerPath(char *pptviewerpath, int strsize) +BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize) { - HKEY hkey; - DWORD dwtype, dwsize; - LRESULT lresult; + HKEY hKey; + DWORD dwType, dwSize; + LRESULT lResult; - DEBUG("GetPPTViewerPath: start\n"); - if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) - if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) - if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\Show\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) - return FALSE; - dwtype = REG_SZ; - dwsize = (DWORD)strsize; - lresult = RegQueryValueEx(hkey, NULL, NULL, &dwtype, (LPBYTE)pptviewerpath, &dwsize ); - RegCloseKey(hkey); - if(lresult!=ERROR_SUCCESS) - return FALSE; - pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value - DEBUG("GetPPTViewerPath: exit ok\n"); - return TRUE; + DEBUG("GetPPTViewerPath: start\n"); + if ((RegOpenKeyEx(HKEY_CLASSES_ROOT, + "PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hKey) + != ERROR_SUCCESS) + && (RegOpenKeyEx(HKEY_CLASSES_ROOT, + "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) + != ERROR_SUCCESS)) + { + return FALSE; + } + dwType = REG_SZ; + dwSize = (DWORD)stringSize; + lResult = RegQueryValueEx(hKey, NULL, NULL, &dwType, (LPBYTE)pptViewerPath, + &dwSize); + RegCloseKey(hKey); + if (lResult != ERROR_SUCCESS) + { + return FALSE; + } + // remove "%1" from end of key value + pptViewerPath[strlen(pptViewerPath) - 4] = '\0'; + DEBUG("GetPPTViewerPath: exit ok\n"); + return TRUE; } // Unhook the Windows hook void Unhook(int id) { - DEBUG("Unhook: start %d\n", id); - if(pptviewobj[id].hook!=NULL) - UnhookWindowsHookEx(pptviewobj[id].hook); - if(pptviewobj[id].mhook!=NULL) - UnhookWindowsHookEx(pptviewobj[id].mhook); - pptviewobj[id].hook = NULL; - pptviewobj[id].mhook = NULL; - DEBUG("Unhook: exit ok\n"); + DEBUG("Unhook: start %d\n", id); + if (pptView[id].hook != NULL) + { + UnhookWindowsHookEx(pptView[id].hook); + } + if (pptView[id].msgHook != NULL) + { + UnhookWindowsHookEx(pptView[id].msgHook); + } + pptView[id].hook = NULL; + pptView[id].msgHook = NULL; + DEBUG("Unhook: exit ok\n"); } // Close the PowerPoint viewer, release resources DllExport void ClosePPT(int id) { - DEBUG("ClosePPT: start%d\n", id); - pptviewobj[id].state = PPT_CLOSED; - Unhook(id); - if(pptviewobj[id].hWnd==0) - TerminateThread(pptviewobj[id].hThread, 0); - else - PostMessage(pptviewobj[id].hWnd, WM_CLOSE, 0, 0); - CloseHandle(pptviewobj[id].hThread); - CloseHandle(pptviewobj[id].hProcess); - memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ)); - DEBUG("ClosePPT: exit ok\n"); - return; + DEBUG("ClosePPT: start%d\n", id); + pptView[id].state = PPT_CLOSED; + Unhook(id); + if (pptView[id].hWnd == 0) + { + TerminateThread(pptView[id].hThread, 0); + } + else + { + PostMessage(pptView[id].hWnd, WM_CLOSE, 0, 0); + } + CloseHandle(pptView[id].hThread); + CloseHandle(pptView[id].hProcess); + memset(&pptView[id], 0, sizeof(PPTVIEW)); + DEBUG("ClosePPT: exit ok\n"); + return; } // Moves the show back onto the display DllExport void Resume(int id) { - DEBUG("Resume: %d\n", id); - MoveWindow(pptviewobj[id].hWnd, pptviewobj[id].rect.left, pptviewobj[id].rect.top, - pptviewobj[id].rect.right - pptviewobj[id].rect.left, - pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE); - Unblank(id); + DEBUG("Resume: %d\n", id); + MoveWindow(pptView[id].hWnd, pptView[id].rect.left, + pptView[id].rect.top, + pptView[id].rect.right - pptView[id].rect.left, + pptView[id].rect.bottom - pptView[id].rect.top, TRUE); + Unblank(id); } // Moves the show off the screen so it can't be seen DllExport void Stop(int id) { - DEBUG("Stop:%d\n", id); - MoveWindow(pptviewobj[id].hWnd, -32000, -32000, - pptviewobj[id].rect.right - pptviewobj[id].rect.left, - pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE); + DEBUG("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); } // Return the total number of slides DllExport int GetSlideCount(int id) { - DEBUG("GetSlideCount:%d\n", id); - if(pptviewobj[id].state==0) - return -1; - else - return pptviewobj[id].slideCount; + DEBUG("GetSlideCount:%d\n", id); + if (pptView[id].state == 0) + { + return -1; + } + else + { + return pptView[id].slideCount; + } } // Return the number of the slide currently viewing DllExport int GetCurrentSlide(int id) { - DEBUG("GetCurrentSlide:%d\n", id); - if(pptviewobj[id].state==0) - return -1; - else - return pptviewobj[id].currentSlide; + DEBUG("GetCurrentSlide:%d\n", id); + if (pptView[id].state == 0) + { + return -1; + } + else + { + return pptView[id].currentSlide; + } } // Take a step forwards through the show DllExport void NextStep(int id) { - DEBUG("NextStep:%d\n", id); - if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) - return; - PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), 0); + DEBUG("NextStep:%d (%d)\n", id, pptView[id].currentSlide); + if (pptView[id].currentSlide > pptView[id].slideCount) return; + if (pptView[id].currentSlide < pptView[id].slideCount) + { + pptView[id].guess = pptView[id].currentSlide + 1; + } + PostMessage(pptView[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), + 0); } // Take a step backwards through the show DllExport void PrevStep(int id) { - DEBUG("PrevStep:%d\n", id); - PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), 0); + DEBUG("PrevStep:%d (%d)\n", id, pptView[id].currentSlide); + if (pptView[id].currentSlide > 1) + { + pptView[id].guess = pptView[id].currentSlide - 1; + } + PostMessage(pptView[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), + 0); } // Blank the show (black screen) DllExport void Blank(int id) -{ - // B just toggles blank on/off. However pressing any key unblanks. - // 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); - HWND h1 = GetForegroundWindow(); - HWND h2 = GetFocus(); - SetForegroundWindow(pptviewobj[id].hWnd); - SetFocus(pptviewobj[id].hWnd); - Sleep(50); // slight pause, otherwise event triggering this call may grab focus back! - keybd_event((int)'A', 0, 0, 0); - keybd_event((int)'A', 0, KEYEVENTF_KEYUP, 0); - keybd_event((int)'B', 0, 0, 0); - keybd_event((int)'B', 0, KEYEVENTF_KEYUP, 0); - SetForegroundWindow(h1); - SetFocus(h2); - //PostMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, 'B', 0x00300001); - //PostMessage(pptviewobj[id].hWnd2, WM_CHAR, 'b', 0x00300001); - //PostMessage(pptviewobj[id].hWnd2, WM_KEYUP, 'B', 0xC0300001); +{ + // B just toggles blank on/off. However pressing any key unblanks. + // 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); + HWND h1 = GetForegroundWindow(); + HWND h2 = GetFocus(); + SetForegroundWindow(pptView[id].hWnd); + SetFocus(pptView[id].hWnd); + // slight pause, otherwise event triggering this call may grab focus back! + Sleep(50); + keybd_event((int)'A', 0, 0, 0); + keybd_event((int)'A', 0, KEYEVENTF_KEYUP, 0); + keybd_event((int)'B', 0, 0, 0); + keybd_event((int)'B', 0, KEYEVENTF_KEYUP, 0); + SetForegroundWindow(h1); + SetFocus(h2); } // Unblank the show DllExport void Unblank(int id) -{ - DEBUG("Unblank:%d\n", id); - // Pressing any key resumes. - // For some reason SendMessage works for unblanking, but not blanking. -// SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, 'A', 0); - SendMessage(pptviewobj[id].hWnd2, WM_CHAR, 'A', 0); -// SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, 'A', 0); -// HWND h1 = GetForegroundWindow(); -// HWND h2 = GetFocus(); -// Sleep(50); // slight pause, otherwise event triggering this call may grab focus back! -// SetForegroundWindow(pptviewobj[id].hWnd); -// SetFocus(pptviewobj[id].hWnd); -// keybd_event((int)'A', 0, 0, 0); -// SetForegroundWindow(h1); -// SetFocus(h2); +{ + DEBUG("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); } // Go directly to a slide -DllExport void GotoSlide(int id, int slideno) -{ - DEBUG("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 - // the slideshow has focus first - char ch[10]; +DllExport void GotoSlide(int id, int slideNo) +{ + DEBUG("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 + // the slideshow has focus first + char ch[10]; - if(slideno<0) return; - _itoa_s(slideno, ch, 10, 10); - HWND h1 = GetForegroundWindow(); - HWND h2 = GetFocus(); - SetForegroundWindow(pptviewobj[id].hWnd); - SetFocus(pptviewobj[id].hWnd); - Sleep(50); // slight pause, otherwise event triggering this call may grab focus back! - for(int i=0;i<10;i++) - { - if(ch[i]=='\0') break; - keybd_event((BYTE)ch[i], 0, 0, 0); - keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0); - } - keybd_event(VK_RETURN, 0, 0, 0); - keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0); - SetForegroundWindow(h1); - SetFocus(h2); - - //for(int i=0;i<10;i++) - //{ - // if(ch[i]=='\0') break; - // SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, ch[i], 0); - // SendMessage(pptviewobj[id].hWnd2, WM_CHAR, ch[i], 0); - // SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, ch[i], 0); - //} - //SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, VK_RETURN, 0); - //SendMessage(pptviewobj[id].hWnd2, WM_CHAR, VK_RETURN, 0); - //SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, VK_RETURN, 0); - //keybd_event(VK_RETURN, 0, 0, 0); + if (slideNo < 0) return; + pptView[id].guess = slideNo; + _itoa_s(slideNo, ch, 10, 10); + HWND h1 = GetForegroundWindow(); + HWND h2 = GetFocus(); + SetForegroundWindow(pptView[id].hWnd); + SetFocus(pptView[id].hWnd); + // slight pause, otherwise event triggering this call may grab focus back! + Sleep(50); + for (int i=0; i<10; i++) + { + if (ch[i] == '\0') break; + keybd_event((BYTE)ch[i], 0, 0, 0); + keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0); + } + keybd_event(VK_RETURN, 0, 0, 0); + keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0); + SetForegroundWindow(h1); + SetFocus(h2); } // Restart the show from the beginning DllExport void RestartShow(int id) { - // If we just go direct to slide one, then it remembers that all other slides have - // been animated, so ends up just showing the completed slides of those slides that - // have been animated next time we advance. - // 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); - Stop(id); - GotoSlide(id, pptviewobj[id].slideCount); - while(pptviewobj[id].currentSlide>1) - { - PrevStep(id); - Sleep(10); - } - for(int i=0;i<=pptviewobj[id].firstSlideSteps;i++) - { - PrevStep(id); - Sleep(10); - } - Resume(id); + // If we just go direct to slide one, then it remembers that all other + // slides have been animated, so ends up just showing the completed slides + // of those slides that have been animated next time we advance. + // 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); + Stop(id); + GotoSlide(id, pptView[id].slideCount); + for (int i=0; i <= pptView[id].steps - pptView[id].lastSlideSteps; i++) + { + PrevStep(id); + Sleep(10); + } + int i = 0; + while ((pptView[id].currentSlide > 1) && (i++ < 30000)) + { + Sleep(10); + } + Resume(id); } // This hook is started with the PPTVIEW.EXE process and waits for the @@ -530,234 +578,287 @@ DllExport void RestartShow(int id) // Release the hook as soon as we're complete to free up resources LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam) { - HHOOK hook = globalhook; - if(nCode==HCBT_CREATEWND) + HHOOK hook = globalHook; + if (nCode == HCBT_CREATEWND) { - char csClassName[16]; + char csClassName[16]; HWND hCurrWnd = (HWND)wParam; - DWORD retProcId = NULL; - GetClassName(hCurrWnd, csClassName, sizeof(csClassName)); - if((strcmp(csClassName, "paneClassDC")==0) - ||(strcmp(csClassName, "screenClass")==0)) - { - int id=-1; - DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL); - for(int i=0; i=0) - { - if(strcmp(csClassName, "paneClassDC")==0) - pptviewobj[id].hWnd2=hCurrWnd; - else - { - pptviewobj[id].hWnd=hCurrWnd; - CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam; - if(pptviewobj[id].hParentWnd!=NULL) - cw->lpcs->hwndParent = pptviewobj[id].hParentWnd; - cw->lpcs->cy=(pptviewobj[id].rect.bottom-pptviewobj[id].rect.top); - cw->lpcs->cx=(pptviewobj[id].rect.right-pptviewobj[id].rect.left); - cw->lpcs->y=-32000; - cw->lpcs->x=-32000; - } - if((pptviewobj[id].hWnd!=NULL)&&(pptviewobj[id].hWnd2!=NULL)) - { - UnhookWindowsHookEx(globalhook); - globalhook=NULL; - pptviewobj[id].hook = SetWindowsHookEx(WH_CALLWNDPROC,CwpProc,hInstance,pptviewobj[id].dwThreadId); - pptviewobj[id].mhook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInstance,pptviewobj[id].dwThreadId); - Sleep(10); - pptviewobj[id].state = PPT_OPENED; - } - } - } + DWORD retProcId = NULL; + GetClassName(hCurrWnd, csClassName, sizeof(csClassName)); + if ((strcmp(csClassName, "paneClassDC") == 0) + ||(strcmp(csClassName, "screenClass") == 0)) + { + int id = -1; + DWORD windowThread = GetWindowThreadProcessId(hCurrWnd, NULL); + for (int i=0; i < MAX_PPTS; i++) + { + if (pptView[i].dwThreadId == windowThread) + { + id = i; + break; + } + } + if (id >= 0) + { + if (strcmp(csClassName, "paneClassDC") == 0) + { + pptView[id].hWnd2 = hCurrWnd; + } + else + { + pptView[id].hWnd = hCurrWnd; + CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam; + if (pptView[id].hParentWnd != NULL) + { + cw->lpcs->hwndParent = pptView[id].hParentWnd; + } + cw->lpcs->cy = pptView[id].rect.bottom + - pptView[id].rect.top; + cw->lpcs->cx = pptView[id].rect.right + - pptView[id].rect.left; + cw->lpcs->y = -32000; + cw->lpcs->x = -32000; + } + if ((pptView[id].hWnd != NULL) && (pptView[id].hWnd2 != NULL)) + { + UnhookWindowsHookEx(globalHook); + globalHook = NULL; + pptView[id].hook = SetWindowsHookEx(WH_CALLWNDPROC, + CwpProc, hInstance, pptView[id].dwThreadId); + pptView[id].msgHook = SetWindowsHookEx(WH_GETMESSAGE, + GetMsgProc, hInstance, pptView[id].dwThreadId); + Sleep(10); + pptView[id].state = PPT_OPENED; + } + } + } } - return CallNextHookEx(hook,nCode,wParam,lParam); + return CallNextHookEx(hook, nCode, wParam, lParam); } // This hook exists whilst the slideshow is loading but only listens on the // slideshows thread. It listens out for mousewheel events LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { - HHOOK hook = NULL; - MSG *pMSG = (MSG *)lParam; - DWORD windowthread = GetWindowThreadProcessId(pMSG->hwnd,NULL); - int id=-1; - for(int i=0; i=0&&nCode==HC_ACTION&&wParam==PM_REMOVE&&pMSG->message==WM_MOUSEWHEEL) + HHOOK hook = NULL; + MSG *pMSG = (MSG *)lParam; + DWORD windowThread = GetWindowThreadProcessId(pMSG->hwnd, NULL); + int id = -1; + for (int i = 0; i < MAX_PPTS; i++) { - if(pptviewobj[id].state!=PPT_LOADED) - { - if(pptviewobj[id].currentSlide==1) - pptviewobj[id].firstSlideSteps++; - pptviewobj[id].steps++; - } + if (pptView[i].dwThreadId == windowThread) + { + id = i; + hook = pptView[id].msgHook; + break; + } + } + if (id >= 0 && nCode == HC_ACTION && wParam == PM_REMOVE + && pMSG->message == WM_MOUSEWHEEL) + { + if (pptView[id].state != PPT_LOADED) + { + if (pptView[id].currentSlide == 1) + { + pptView[id].firstSlideSteps++; + } + pptView[id].steps++; + pptView[id].lastSlideSteps++; + } } return CallNextHookEx(hook, nCode, wParam, lParam); } // This hook exists whilst the slideshow is running but only listens on the // slideshows thread. It listens out for slide changes, message WM_USER+22. LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){ - CWPSTRUCT *cwp; - cwp = (CWPSTRUCT *)lParam; - HHOOK hook = NULL; - char filename[MAX_PATH]; + CWPSTRUCT *cwp; + cwp = (CWPSTRUCT *)lParam; + HHOOK hook = NULL; + char filename[MAX_PATH]; - DWORD windowthread = GetWindowThreadProcessId(cwp->hwnd,NULL); - int id=-1; - for(int i=0; i=0)&&(nCode==HC_ACTION)) - { - if(cwp->message==WM_USER+22) - { - if(pptviewobj[id].state != PPT_LOADED) - { - if((pptviewobj[id].currentSlide>0) - && (pptviewobj[id].previewpath!=NULL&&strlen(pptviewobj[id].previewpath)>0)) - { - sprintf_s(filename, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, pptviewobj[id].currentSlide); - CaptureAndSaveWindow(cwp->hwnd, filename); - } - } - if(cwp->wParam==0) - { - if(pptviewobj[id].currentSlide>0) - { - pptviewobj[id].state = PPT_LOADED; - pptviewobj[id].currentSlide = pptviewobj[id].slideCount+1; - } - } - else - { - pptviewobj[id].currentSlide = cwp->wParam - 255; - if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) - pptviewobj[id].slideCount = pptviewobj[id].currentSlide; - } - } - if((pptviewobj[id].state != PPT_CLOSED)&&(cwp->message==WM_CLOSE||cwp->message==WM_QUIT)) - pptviewobj[id].state = PPT_CLOSING; - } - return CallNextHookEx(hook,nCode,wParam,lParam); + DWORD windowThread = GetWindowThreadProcessId(cwp->hwnd, NULL); + int id = -1; + for (int i = 0; i < MAX_PPTS; i++) + { + if (pptView[i].dwThreadId == windowThread) + { + id = i; + hook = pptView[id].hook; + break; + } + } + if ((id >= 0) && (nCode == HC_ACTION)) + { + if (cwp->message == WM_USER + 22) + { + if (pptView[id].state != PPT_LOADED) + { + if ((pptView[id].currentSlide > 0) + && (pptView[id].previewPath != NULL + && strlen(pptView[id].previewPath) > 0)) + { + sprintf_s(filename, MAX_PATH, "%s%i.bmp", + pptView[id].previewPath, + pptView[id].currentSlide); + CaptureAndSaveWindow(cwp->hwnd, filename); + } + if (((cwp->wParam == 0) + || (pptView[id].slideNos[1] == cwp->wParam)) + && (pptView[id].currentSlide > 0)) + { + pptView[id].state = PPT_LOADED; + pptView[id].currentSlide = pptView[id].slideCount + 1; + } + else + { + if (cwp->wParam > 0) + { + pptView[id].currentSlide = pptView[id].currentSlide + 1; + pptView[id].slideNos[pptView[id].currentSlide] + = cwp->wParam; + pptView[id].slideCount = pptView[id].currentSlide; + pptView[id].lastSlideSteps = 0; + } + } + } + else + { + if (cwp->wParam > 0) + { + if(pptView[id].guess > 0 + && pptView[id].slideNos[pptView[id].guess] == 0) + { + pptView[id].currentSlide = 0; + } + for(int i = 1; i <= pptView[id].slideCount; i++) + { + if(pptView[id].slideNos[i] == cwp->wParam) + { + pptView[id].currentSlide = i; + break; + } + } + if(pptView[id].currentSlide == 0) + { + pptView[id].slideNos[pptView[id].guess] = cwp->wParam; + pptView[id].currentSlide = pptView[id].guess; + } + pptView[id].guess = 0; + } + } + } + if ((pptView[id].state != PPT_CLOSED) + + &&(cwp->message == WM_CLOSE || cwp->message == WM_QUIT)) + { + pptView[id].state = PPT_CLOSING; + } + } + return CallNextHookEx(hook, nCode, wParam, lParam); } VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename) { - HBITMAP hBmp; - if ((hBmp = CaptureWindow(hWnd)) == NULL) - return; + HBITMAP hBmp; + if ((hBmp = CaptureWindow(hWnd)) == NULL) + { + return; + } + RECT client; + GetClientRect(hWnd, &client); + UINT uiBytesPerRow = 3 * client.right; // RGB takes 24 bits + UINT uiRemainderForPadding; - RECT client; - GetClientRect (hWnd, &client); - UINT uiBytesPerRow = 3 * client.right; // RGB takes 24 bits - UINT uiRemainderForPadding; + if ((uiRemainderForPadding = uiBytesPerRow % sizeof(DWORD)) > 0) + uiBytesPerRow += (sizeof(DWORD) - uiRemainderForPadding); - if ((uiRemainderForPadding = uiBytesPerRow % sizeof (DWORD)) > 0) - uiBytesPerRow += (sizeof (DWORD) - uiRemainderForPadding); + UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom; + PBYTE pDataBits; - UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom; - PBYTE pDataBits; + if ((pDataBits = new BYTE[uiBytesPerAllRows]) != NULL) + { + BITMAPINFOHEADER bmi = {0}; + BITMAPFILEHEADER bmf = {0}; - if ((pDataBits = new BYTE [uiBytesPerAllRows]) != NULL) - { - BITMAPINFOHEADER bmi = {0}; - BITMAPFILEHEADER bmf = {0}; + // Prepare to get the data out of HBITMAP: + bmi.biSize = sizeof(bmi); + bmi.biPlanes = 1; + bmi.biBitCount = 24; + bmi.biHeight = client.bottom; + bmi.biWidth = client.right; - // Prepare to get the data out of HBITMAP: - bmi.biSize = sizeof (bmi); - bmi.biPlanes = 1; - bmi.biBitCount = 24; - bmi.biHeight = client.bottom; - bmi.biWidth = client.right; + // Get it: + HDC hDC = GetDC(hWnd); + GetDIBits(hDC, hBmp, 0, client.bottom, pDataBits, (BITMAPINFO*) &bmi, + DIB_RGB_COLORS); + ReleaseDC(hWnd, hDC); - // Get it: - HDC hDC = GetDC (hWnd); - GetDIBits (hDC, hBmp, 0, client.bottom, pDataBits, - (BITMAPINFO*) &bmi, DIB_RGB_COLORS); - ReleaseDC (hWnd, hDC); + // Fill the file header: + bmf.bfOffBits = sizeof(bmf) + sizeof(bmi); + bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows; + bmf.bfType = 0x4D42; - // Fill the file header: - bmf.bfOffBits = sizeof (bmf) + sizeof (bmi); - bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows; - bmf.bfType = 0x4D42; - - // Writing: - FILE* pFile; - int err = fopen_s(&pFile, filename, "wb"); - if (err == 0) - { - fwrite (&bmf, sizeof (bmf), 1, pFile); - fwrite (&bmi, sizeof (bmi), 1, pFile); - fwrite (pDataBits, sizeof (BYTE), uiBytesPerAllRows, pFile); - fclose (pFile); - } - delete [] pDataBits; - } - DeleteObject (hBmp); + // Writing: + FILE* pFile; + int err = fopen_s(&pFile, filename, "wb"); + if (err == 0) + { + fwrite(&bmf, sizeof(bmf), 1, pFile); + fwrite(&bmi, sizeof(bmi), 1, pFile); + fwrite(pDataBits, sizeof(BYTE), uiBytesPerAllRows, pFile); + fclose(pFile); + } + delete [] pDataBits; + } + DeleteObject(hBmp); } -HBITMAP CaptureWindow (HWND hWnd) { - HDC hDC; - BOOL bOk = FALSE; - HBITMAP hImage = NULL; +HBITMAP CaptureWindow(HWND hWnd) +{ + HDC hDC; + BOOL bOk = FALSE; + HBITMAP hImage = NULL; - hDC = GetDC (hWnd); - RECT rcClient; - GetClientRect (hWnd, &rcClient); - if ((hImage = CreateCompatibleBitmap (hDC, rcClient.right, rcClient.bottom)) != NULL) - { - HDC hMemDC; - HBITMAP hDCBmp; + hDC = GetDC(hWnd); + RECT rcClient; + GetClientRect(hWnd, &rcClient); + if ((hImage = CreateCompatibleBitmap(hDC, rcClient.right, rcClient.bottom)) + != NULL) + { + HDC hMemDC; + HBITMAP hDCBmp; - if ((hMemDC = CreateCompatibleDC (hDC)) != NULL) - { - hDCBmp = (HBITMAP) SelectObject (hMemDC, hImage); - HMODULE hLib = LoadLibrary("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 - if(GetProcAddress(hLib, "PrintWindow")==NULL) - { - SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); - BitBlt (hMemDC, 0, 0, rcClient.right, rcClient.bottom, hDC, 0, 0, SRCCOPY); - SetWindowPos(hWnd, HWND_NOTOPMOST, -32000, -32000, 0, 0, SWP_NOSIZE); - } - else - { - PrintWindow(hWnd, hMemDC, 0); - } - SelectObject (hMemDC, hDCBmp); - DeleteDC (hMemDC); - bOk = TRUE; - } - } - ReleaseDC (hWnd, hDC); - if (! bOk) - { - if (hImage) - { - DeleteObject (hImage); - hImage = NULL; - } - } - return hImage; + if ((hMemDC = CreateCompatibleDC(hDC)) != NULL) + { + hDCBmp = (HBITMAP)SelectObject(hMemDC, hImage); + HMODULE hLib = LoadLibrary("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 + if (GetProcAddress(hLib, "PrintWindow") == NULL) + { + SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); + BitBlt(hMemDC, 0, 0, rcClient.right, rcClient.bottom, hDC, 0, + 0, SRCCOPY); + SetWindowPos(hWnd, HWND_NOTOPMOST, -32000, -32000, 0, 0, + SWP_NOSIZE); + } + else + { + PrintWindow(hWnd, hMemDC, 0); + } + SelectObject(hMemDC, hDCBmp); + DeleteDC(hMemDC); + bOk = TRUE; + } + } + ReleaseDC(hWnd, hDC); + if (!bOk) + { + if (hImage) + { + DeleteObject(hImage); + hImage = NULL; + } + } + return hImage; } diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll index f8a0de0d3..36581e00b 100644 Binary files a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll and b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll differ diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h index 6012b0467..714376f63 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h @@ -1,55 +1,84 @@ +/****************************************************************************** +* PptViewLib - PowerPoint Viewer 2003/2007 Controller * +* OpenLP - Open Source Lyrics Projection * +* --------------------------------------------------------------------------- * +* Copyright (c) 2008-2011 Raoul Snyman * +* Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael * +* Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, * +* Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon * +* Tibble, Carsten Tinggaard, Frode Woldsund * +* --------------------------------------------------------------------------- * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the Free * +* Software Foundation; version 2 of the License. * +* * +* This program is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, write to the Free Software Foundation, Inc., 59 * +* Temple Place, Suite 330, Boston, MA 02111-1307 USA * +******************************************************************************/ #define DllExport extern "C" __declspec( dllexport ) -enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING}; +#define DEBUG(...) if (debug) printf(__VA_ARGS__) -DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); +enum PPTVIEWSTATE {PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, + PPT_CLOSING}; + +DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, + char *previewPath); DllExport BOOL CheckInstalled(); DllExport void ClosePPT(int id); DllExport int GetCurrentSlide(int id); DllExport int GetSlideCount(int id); DllExport void NextStep(int id); DllExport void PrevStep(int id); -DllExport void GotoSlide(int id, int slideno); +DllExport void GotoSlide(int id, int slide_no); DllExport void RestartShow(int id); DllExport void Blank(int id); DllExport void Unblank(int id); DllExport void Stop(int id); DllExport void Resume(int id); -DllExport void SetDebug(BOOL onoff); +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 strsize); -HBITMAP CaptureWindow (HWND hWnd); -VOID SaveBitmap (CHAR* filename, HBITMAP hBmp) ; +BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize); +HBITMAP CaptureWindow(HWND hWnd); +VOID SaveBitmap(CHAR* filename, HBITMAP hBmp) ; VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename); BOOL GetPPTInfo(int id); BOOL SavePPTInfo(int id); - - void Unhook(int id); -#define MAX_PPTOBJS 50 +#define MAX_PPTS 16 +#define MAX_SLIDES 256 -struct PPTVIEWOBJ +struct PPTVIEW { - HHOOK hook; - HHOOK mhook; - HWND hWnd; - HWND hWnd2; - HWND hParentWnd; - HANDLE hProcess; - HANDLE hThread; - DWORD dwProcessId; - DWORD dwThreadId; - RECT rect; - int slideCount; - int currentSlide; - int firstSlideSteps; - int steps; - char filename[MAX_PATH]; - char previewpath[MAX_PATH]; - PPTVIEWSTATE state; + HHOOK hook; + HHOOK msgHook; + HWND hWnd; + HWND hWnd2; + HWND hParentWnd; + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + RECT rect; + int slideCount; + int currentSlide; + int firstSlideSteps; + int lastSlideSteps; + int steps; + int guess; + char filename[MAX_PATH]; + char previewPath[MAX_PATH]; + int slideNos[MAX_SLIDES]; + PPTVIEWSTATE state; }; diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index b63d775a0..4c9645834 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -297,7 +297,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.verseOrderEdit.setText(u' '.join(translated)) else: self.verseOrderEdit.setText(u'') - self.verseListWidget.resizeRowsToContents() self.tagRows() # clear the results self.authorsListView.clear() @@ -312,10 +311,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) self.topicsListView.addItem(topic_name) self.titleEdit.setFocus(QtCore.Qt.OtherFocusReason) - # if not preview hide the preview button - self.previewButton.setVisible(False) - if preview: - self.previewButton.setVisible(True) + # Hide or show the preview button. + self.previewButton.setVisible(preview) def tagRows(self): """ @@ -329,6 +326,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): row_def = u'%s%s' % (verse_tag, verse_def[1:]) row_label.append(row_def) self.verseListWidget.setVerticalHeaderLabels(row_label) + self.verseListWidget.setColumnWidth(0, self.width) + self.verseListWidget.resizeRowsToContents() + self.verseListWidget.repaint() def onAuthorAddButtonClicked(self): item = int(self.authorsComboBox.currentIndex()) @@ -453,9 +453,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.verseListWidget.setRowCount( self.verseListWidget.rowCount() + 1) self.verseListWidget.setItem( - int(self.verseListWidget.rowCount() - 1), 0, item) - self.verseListWidget.setColumnWidth(0, self.width) - self.verseListWidget.resizeRowsToContents() + self.verseListWidget.rowCount() - 1, 0, item) self.tagRows() def onVerseEditButtonClicked(self): @@ -482,8 +480,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): item = QtGui.QTableWidgetItem(tempList[row], 0) item.setData(QtCore.Qt.UserRole, tempId[row]) self.verseListWidget.setItem(row, 0, item) - self.verseListWidget.resizeRowsToContents() - self.verseListWidget.repaint() self.tagRows() def onVerseEditAllButtonClicked(self): @@ -500,53 +496,50 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.verse_form.setVerse(verse_list) else: self.verse_form.setVerse(u'') - if self.verse_form.exec_(): - verse_list = self.verse_form.getVerseAll() - verse_list = unicode(verse_list.replace(u'\r\n', u'\n')) - self.verseListWidget.clear() - self.verseListWidget.setRowCount(0) - for row in self.findVerseSplit.split(verse_list): - for match in row.split(u'---['): - for count, parts in enumerate(match.split(u']---\n')): - if len(parts) > 1: - if count == 0: - # handling carefully user inputted versetags - separator = parts.find(u':') - if separator >= 0: - verse_name = parts[0:separator].strip() - verse_num = parts[separator+1:].strip() - else: - verse_name = parts - verse_num = u'1' - verse_index = \ - VerseType.from_loose_input(verse_name) - verse_tag = VerseType.Tags[verse_index] - # Later we need to handle v1a as well. - #regex = re.compile(r'(\d+\w.)') - regex = re.compile(r'\D*(\d+)\D*') - match = regex.match(verse_num) - if match: - verse_num = match.group(1) - else: - verse_num = u'1' - verse_def = u'%s%s' % (verse_tag, verse_num) - else: - if parts.endswith(u'\n'): - parts = parts.rstrip(u'\n') - item = QtGui.QTableWidgetItem(parts) - item.setData(QtCore.Qt.UserRole, - QtCore.QVariant(verse_def)) - self.verseListWidget.setRowCount( - self.verseListWidget.rowCount() + 1) - self.verseListWidget.setItem( - int(self.verseListWidget.rowCount() - 1), - 0, item) - self.verseListWidget.setColumnWidth(0, self.width) - self.verseListWidget.resizeRowsToContents() - self.verseListWidget.repaint() - self.tagRows() - self.verseEditButton.setEnabled(False) - self.verseDeleteButton.setEnabled(False) + if not self.verse_form.exec_(): + return + verse_list = self.verse_form.getVerseAll() + verse_list = unicode(verse_list.replace(u'\r\n', u'\n')) + self.verseListWidget.clear() + self.verseListWidget.setRowCount(0) + for row in self.findVerseSplit.split(verse_list): + for match in row.split(u'---['): + for count, parts in enumerate(match.split(u']---\n')): + if len(parts) <= 1: + continue + if count == 0: + # handling carefully user inputted versetags + separator = parts.find(u':') + if separator >= 0: + verse_name = parts[0:separator].strip() + verse_num = parts[separator+1:].strip() + else: + verse_name = parts + verse_num = u'1' + verse_index = VerseType.from_loose_input(verse_name) + verse_tag = VerseType.Tags[verse_index] + # Later we need to handle v1a as well. + #regex = re.compile(r'(\d+\w.)') + regex = re.compile(r'\D*(\d+)\D*') + match = regex.match(verse_num) + if match: + verse_num = match.group(1) + else: + verse_num = u'1' + verse_def = u'%s%s' % (verse_tag, verse_num) + else: + if parts.endswith(u'\n'): + parts = parts.rstrip(u'\n') + item = QtGui.QTableWidgetItem(parts) + item.setData(QtCore.Qt.UserRole, + QtCore.QVariant(verse_def)) + self.verseListWidget.setRowCount( + self.verseListWidget.rowCount() + 1) + self.verseListWidget.setItem( + self.verseListWidget.rowCount() - 1, 0, item) + self.tagRows() + self.verseEditButton.setEnabled(False) + self.verseDeleteButton.setEnabled(False) def onVerseDeleteButtonClicked(self): self.verseListWidget.removeRow(self.verseListWidget.currentRow()) @@ -728,7 +721,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.song.title = unicode(self.titleEdit.text()) self.song.alternate_title = unicode(self.alternativeEdit.text()) self.song.copyright = unicode(self.copyrightEdit.text()) - # Values will be set when cleaning the song. + # Values will be set when cleaning the song. self.song.search_title = u'' self.song.search_lyrics = u'' self.song.verse_order = u'' @@ -753,7 +746,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.song.theme_name = theme_name else: self.song.theme_name = None - self.processLyrics() + self._processLyrics() self.song.authors = [] for row in range(self.authorsListView.count()): item = self.authorsListView.item(row) @@ -769,12 +762,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if not preview: self.song = None - def processLyrics(self): + def _processLyrics(self): """ Process the lyric data entered by the user into the OpenLP XML format. """ # This method must only be run after the self.song = Song() assignment. - log.debug(u'processLyrics') + log.debug(u'_processLyrics') try: sxml = SongXML() multiple = [] diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index ee826af77..c1b5ee5c1 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -89,8 +89,8 @@ class SongXML(object): Add a verse to the ```` tag. ``type`` - A string denoting the type of verse. Possible values are *Verse*, - *Chorus*, *Bridge*, *Pre-Chorus*, *Intro*, *Ending* and *Other*. + A string denoting the type of verse. Possible values are *v*, + *c*, *b*, *p*, *i*, *e* and *o*. Any other type is **not** allowed, this also includes translated types. @@ -128,8 +128,8 @@ class SongXML(object): The returned list has the following format:: - [[{'lang': 'en', 'type': 'Verse', 'label': '1'}, u"English verse"], - [{'lang': 'en', 'type': 'Chorus', 'label': '1'}, u"English chorus"]] + [[{'lang': 'en', 'type': 'v', 'label': '1'}, u"English verse"], + [{'lang': 'en', 'type': 'c', 'label': '1'}, u"English chorus"]] """ self.song_xml = None if xml[:5] == u'