Fix blanking between ppt and songs

Fix stutter when timed powerpoint starts

bzr-revno: 1466
This commit is contained in:
Jonathan Corwin 2011-04-15 21:38:47 +01:00
commit 78b3b04afa
6 changed files with 133 additions and 85 deletions

View File

@ -307,7 +307,7 @@ sup {
</head> </head>
<body> <body>
<img id="bgimage" class="size" %s /> <img id="bgimage" class="size" %s />
<img id="image" class="size" style="display:none" /> <img id="image" class="size" %s />
<video id="video1" class="size" style="visibility:hidden" autobuffer preload> <video id="video1" class="size" style="visibility:hidden" autobuffer preload>
</video> </video>
<video id="video2" class="size" style="visibility:hidden" autobuffer preload> <video id="video2" class="size" style="visibility:hidden" autobuffer preload>
@ -320,7 +320,7 @@ sup {
</html> </html>
""" """
def build_html(item, screen, alert, islive, background): def build_html(item, screen, alert, islive, background, image=None):
""" """
Build the full web paged structure for display Build the full web paged structure for display
@ -332,6 +332,10 @@ def build_html(item, screen, alert, islive, background):
Alert display display information Alert display display information
`islive` `islive`
Item is going live, rather than preview/theme building Item is going live, rather than preview/theme building
`background`
Theme background image - bytes
`image`
Image media item - bytes
""" """
width = screen[u'size'].width() width = screen[u'size'].width()
height = screen[u'size'].height() height = screen[u'size'].height()
@ -339,11 +343,15 @@ def build_html(item, screen, alert, islive, background):
webkitvers = webkit_version() webkitvers = webkit_version()
# Image generated and poked in # Image generated and poked in
if background: if background:
image = u'src="data:image/png;base64,%s"' % background bgimage_src = u'src="data:image/png;base64,%s"' % background
elif item.bg_image_bytes: elif item.bg_image_bytes:
image = u'src="data:image/png;base64,%s"' % item.bg_image_bytes bgimage_src = u'src="data:image/png;base64,%s"' % item.bg_image_bytes
else: else:
image = u'style="display:none;"' bgimage_src = u'style="display:none;"'
if image:
image_src = u'src="data:image/png;base64,%s"' % image
else:
image_src = u'style="display:none;"'
html = HTMLSRC % (build_background_css(item, width, height), html = HTMLSRC % (build_background_css(item, width, height),
width, height, width, height,
build_alert_css(alert, width), build_alert_css(alert, width),
@ -351,7 +359,7 @@ def build_html(item, screen, alert, islive, background):
build_lyrics_css(item, webkitvers), build_lyrics_css(item, webkitvers),
u'true' if theme and theme.display_slide_transition and islive \ u'true' if theme and theme.display_slide_transition and islive \
else u'false', else u'false',
image, bgimage_src, image_src,
build_lyrics_html(item, webkitvers)) build_lyrics_html(item, webkitvers))
return html return html

View File

@ -453,7 +453,7 @@ class MainDisplay(DisplayWidget):
painter.end() painter.end()
return preview return preview
def buildHtml(self, serviceItem): def buildHtml(self, serviceItem, image=None):
""" """
Store the serviceItem and build the new HTML from it. Add the Store the serviceItem and build the new HTML from it. Add the
HTML to the display HTML to the display
@ -480,8 +480,12 @@ class MainDisplay(DisplayWidget):
if self.serviceItem.themedata.background_filename: if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.imageManager. \ self.serviceItem.bg_image_bytes = self.imageManager. \
get_image_bytes(self.serviceItem.themedata.theme_name) get_image_bytes(self.serviceItem.themedata.theme_name)
if image:
image_bytes = self.imageManager.get_image_bytes(image)
else:
image_bytes = None
html = build_html(self.serviceItem, self.screen, self.alertTab, html = build_html(self.serviceItem, self.screen, self.alertTab,
self.isLive, background) self.isLive, background, image_bytes)
log.debug(u'buildHtml - pre setHtml') log.debug(u'buildHtml - pre setHtml')
self.webView.setHtml(html) self.webView.setHtml(html)
log.debug(u'buildHtml - post setHtml') log.debug(u'buildHtml - post setHtml')

View File

@ -365,14 +365,14 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'config_screen_changed'), self.screenSizeChanged) QtCore.SIGNAL(u'config_screen_changed'), self.screenSizeChanged)
def setPreviewHotkeys(self, parent=None): def setPreviewHotkeys(self, parent=None):
self.previousItem.setObjectName(u'previousItemPreview') self.previousItem.setObjectName(u'previousItemPreview')
self.nextItem.setObjectName(u'nextItemPreview') self.nextItem.setObjectName(u'nextItemPreview')
action_list = ActionList.get_instance() action_list = ActionList.get_instance()
action_list.add_action(self.previousItem) action_list.add_action(self.previousItem)
action_list.add_action(self.nextItem) action_list.add_action(self.nextItem)
def setLiveHotkeys(self, parent=None): def setLiveHotkeys(self, parent=None):
self.previousItem.setObjectName(u'previousItemLive') self.previousItem.setObjectName(u'previousItemLive')
self.nextItem.setObjectName(u'nextItemLive') self.nextItem.setObjectName(u'nextItemLive')
action_list = ActionList.get_instance() action_list = ActionList.get_instance()
action_list.add_category( action_list.add_category(
@ -465,7 +465,7 @@ class SlideController(QtGui.QWidget):
request = unicode(self.sender().text()) request = unicode(self.sender().text())
slideno = self.slideList[request] slideno = self.slideList[request]
self.__updatePreviewSelection(slideno) self.__updatePreviewSelection(slideno)
self.onSlideSelected() self.slideSelected()
def receiveSpinDelay(self, value): def receiveSpinDelay(self, value):
""" """
@ -561,7 +561,7 @@ class SlideController(QtGui.QWidget):
# If service item is the same as the current on only change slide # If service item is the same as the current on only change slide
if item.__eq__(self.serviceItem): if item.__eq__(self.serviceItem):
self.__checkUpdateSelectedSlide(slideno) self.__checkUpdateSelectedSlide(slideno)
self.onSlideSelected() self.slideSelected()
return return
self._processItem(item, slideno) self._processItem(item, slideno)
@ -572,24 +572,15 @@ class SlideController(QtGui.QWidget):
""" """
log.debug(u'processManagerItem live = %s' % self.isLive) log.debug(u'processManagerItem live = %s' % self.isLive)
self.onStopLoop() self.onStopLoop()
# If old item was a command tell it to stop old_item = self.serviceItem
if self.serviceItem: self.serviceItem = serviceItem
if self.serviceItem.is_command(): if old_item and self.isLive and old_item.is_capable(
Receiver.send_message(u'%s_stop' % ItemCapabilities.ProvidesOwnDisplay):
self.serviceItem.name.lower(), [serviceItem, self.isLive]) self._resetBlank()
if self.serviceItem.is_media():
self.onMediaClose()
if self.isLive:
if serviceItem.is_capable(ItemCapabilities.ProvidesOwnDisplay):
self._forceUnblank()
blanked = self.blankScreen.isChecked()
else:
blanked = False
Receiver.send_message(u'%s_start' % serviceItem.name.lower(), Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
[serviceItem, self.isLive, blanked, slideno]) [serviceItem, self.isLive, self.hideMode(), slideno])
self.slideList = {} self.slideList = {}
width = self.parent.controlSplitter.sizes()[self.split] width = self.parent.controlSplitter.sizes()[self.split]
self.serviceItem = serviceItem
self.previewListWidget.clear() self.previewListWidget.clear()
self.previewListWidget.setRowCount(0) self.previewListWidget.setRowCount(0)
self.previewListWidget.setColumnWidth(0, width) self.previewListWidget.setColumnWidth(0, width)
@ -648,12 +639,25 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.viewport().size().width()) self.previewListWidget.viewport().size().width())
self.__updatePreviewSelection(slideno) self.__updatePreviewSelection(slideno)
self.enableToolBar(serviceItem) self.enableToolBar(serviceItem)
# Pass to display for viewing # Pass to display for viewing.
self.display.buildHtml(self.serviceItem) # Postpone image build, we need to do this later to avoid the theme
# flashing on the screen
if not self.serviceItem.is_image():
self.display.buildHtml(self.serviceItem)
if serviceItem.is_media(): if serviceItem.is_media():
self.onMediaStart(serviceItem) self.onMediaStart(serviceItem)
self.onSlideSelected() self.slideSelected(True)
self.previewListWidget.setFocus() self.previewListWidget.setFocus()
if old_item:
# Close the old item after the new one is opened
# This avoids the service theme/desktop flashing on screen
# However opening a new item of the same type will automatically
# close the previous, so make sure we don't close the new one.
if old_item.is_command() and not serviceItem.is_command():
Receiver.send_message(u'%s_stop' %
old_item.name.lower(), [old_item, self.isLive])
if old_item.is_media() and not serviceItem.is_media():
self.onMediaClose()
Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix, Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix,
[serviceItem]) [serviceItem])
@ -700,7 +704,7 @@ class SlideController(QtGui.QWidget):
self.updatePreview() self.updatePreview()
else: else:
self.previewListWidget.selectRow(0) self.previewListWidget.selectRow(0)
self.onSlideSelected() self.slideSelected()
def onSlideSelectedIndex(self, message): def onSlideSelectedIndex(self, message):
""" """
@ -715,7 +719,7 @@ class SlideController(QtGui.QWidget):
self.updatePreview() self.updatePreview()
else: else:
self.__checkUpdateSelectedSlide(index) self.__checkUpdateSelectedSlide(index)
self.onSlideSelected() self.slideSelected()
def mainDisplaySetBackground(self): def mainDisplaySetBackground(self):
""" """
@ -758,15 +762,13 @@ class SlideController(QtGui.QWidget):
self.themeScreen.setChecked(False) self.themeScreen.setChecked(False)
self.desktopScreen.setChecked(False) self.desktopScreen.setChecked(False)
if checked: if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Blank)
QtCore.QSettings().setValue( QtCore.QSettings().setValue(
self.parent.generalSettingsSection + u'/screen blank', self.parent.generalSettingsSection + u'/screen blank',
QtCore.QVariant(u'blanked')) QtCore.QVariant(u'blanked'))
else: else:
Receiver.send_message(u'maindisplay_show')
QtCore.QSettings().remove( QtCore.QSettings().remove(
self.parent.generalSettingsSection + u'/screen blank') self.parent.generalSettingsSection + u'/screen blank')
self.blankPlugin(checked) self.blankPlugin()
self.updatePreview() self.updatePreview()
def onThemeDisplay(self, checked=None): def onThemeDisplay(self, checked=None):
@ -781,15 +783,13 @@ class SlideController(QtGui.QWidget):
self.themeScreen.setChecked(checked) self.themeScreen.setChecked(checked)
self.desktopScreen.setChecked(False) self.desktopScreen.setChecked(False)
if checked: if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Theme)
QtCore.QSettings().setValue( QtCore.QSettings().setValue(
self.parent.generalSettingsSection + u'/screen blank', self.parent.generalSettingsSection + u'/screen blank',
QtCore.QVariant(u'themed')) QtCore.QVariant(u'themed'))
else: else:
Receiver.send_message(u'maindisplay_show')
QtCore.QSettings().remove( QtCore.QSettings().remove(
self.parent.generalSettingsSection + u'/screen blank') self.parent.generalSettingsSection + u'/screen blank')
self.blankPlugin(checked) self.blankPlugin()
self.updatePreview() self.updatePreview()
def onHideDisplay(self, checked=None): def onHideDisplay(self, checked=None):
@ -804,28 +804,31 @@ class SlideController(QtGui.QWidget):
self.themeScreen.setChecked(False) self.themeScreen.setChecked(False)
self.desktopScreen.setChecked(checked) self.desktopScreen.setChecked(checked)
if checked: if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
QtCore.QSettings().setValue( QtCore.QSettings().setValue(
self.parent.generalSettingsSection + u'/screen blank', self.parent.generalSettingsSection + u'/screen blank',
QtCore.QVariant(u'hidden')) QtCore.QVariant(u'hidden'))
else: else:
Receiver.send_message(u'maindisplay_show')
QtCore.QSettings().remove( QtCore.QSettings().remove(
self.parent.generalSettingsSection + u'/screen blank') self.parent.generalSettingsSection + u'/screen blank')
self.hidePlugin(checked) self.hidePlugin(checked)
self.updatePreview() self.updatePreview()
def blankPlugin(self, blank): def blankPlugin(self):
""" """
Blank the display screen within a plugin if required. Blank/Hide the display screen within a plugin if required.
""" """
log.debug(u'blankPlugin %s ', blank) hide_mode = self.hideMode()
log.debug(u'blankPlugin %s ', hide_mode)
if self.serviceItem is not None: if self.serviceItem is not None:
if blank: if hide_mode:
if not self.serviceItem.is_command():
Receiver.send_message(u'maindisplay_hide', hide_mode)
Receiver.send_message(u'%s_blank' Receiver.send_message(u'%s_blank'
% self.serviceItem.name.lower(), % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive]) [self.serviceItem, self.isLive, hide_mode])
else: else:
if not self.serviceItem.is_command():
Receiver.send_message(u'maindisplay_show')
Receiver.send_message(u'%s_unblank' Receiver.send_message(u'%s_unblank'
% self.serviceItem.name.lower(), % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive]) [self.serviceItem, self.isLive])
@ -837,15 +840,24 @@ class SlideController(QtGui.QWidget):
log.debug(u'hidePlugin %s ', hide) log.debug(u'hidePlugin %s ', hide)
if self.serviceItem is not None: if self.serviceItem is not None:
if hide: if hide:
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
Receiver.send_message(u'%s_hide' Receiver.send_message(u'%s_hide'
% self.serviceItem.name.lower(), % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive]) [self.serviceItem, self.isLive])
else: else:
if not self.serviceItem.is_command():
Receiver.send_message(u'maindisplay_show')
Receiver.send_message(u'%s_unblank' Receiver.send_message(u'%s_unblank'
% self.serviceItem.name.lower(), % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive]) [self.serviceItem, self.isLive])
def onSlideSelected(self): def onSlideSelected(self, start=False):
"""
Slide selected in controller
"""
self.slideSelected()
def slideSelected(self, start=False):
""" """
Generate the preview when you click on a slide. Generate the preview when you click on a slide.
if this is the Live Controller also display on the screen if this is the Live Controller also display on the screen
@ -854,7 +866,7 @@ class SlideController(QtGui.QWidget):
self.selectedRow = 0 self.selectedRow = 0
if row > -1 and row < self.previewListWidget.rowCount(): if row > -1 and row < self.previewListWidget.rowCount():
if self.serviceItem.is_command(): if self.serviceItem.is_command():
if self.isLive: if self.isLive and not start:
Receiver.send_message( Receiver.send_message(
u'%s_slide' % self.serviceItem.name.lower(), u'%s_slide' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive, row]) [self.serviceItem, self.isLive, row])
@ -864,7 +876,11 @@ class SlideController(QtGui.QWidget):
if self.serviceItem.is_text(): if self.serviceItem.is_text():
frame = self.display.text(toDisplay) frame = self.display.text(toDisplay)
else: else:
frame = self.display.image(toDisplay) if start:
self.display.buildHtml(self.serviceItem, toDisplay)
frame = self.display.preview()
else:
frame = self.display.image(toDisplay)
# reset the store used to display first image # reset the store used to display first image
self.serviceItem.bg_image_bytes = None self.serviceItem.bg_image_bytes = None
self.slidePreview.setPixmap(QtGui.QPixmap.fromImage(frame)) self.slidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
@ -930,7 +946,7 @@ class SlideController(QtGui.QWidget):
Receiver.send_message('servicemanager_next_item') Receiver.send_message('servicemanager_next_item')
return return
self.__checkUpdateSelectedSlide(row) self.__checkUpdateSelectedSlide(row)
self.onSlideSelected() self.slideSelected()
def onSlideSelectedPreviousNoloop(self): def onSlideSelectedPreviousNoloop(self):
self.onSlideSelectedPrevious(False) self.onSlideSelectedPrevious(False)
@ -953,7 +969,7 @@ class SlideController(QtGui.QWidget):
else: else:
row = 0 row = 0
self.__checkUpdateSelectedSlide(row) self.__checkUpdateSelectedSlide(row)
self.onSlideSelected() self.slideSelected()
def __checkUpdateSelectedSlide(self, row): def __checkUpdateSelectedSlide(self, row):
if row + 1 < self.previewListWidget.rowCount(): if row + 1 < self.previewListWidget.rowCount():
@ -974,7 +990,7 @@ class SlideController(QtGui.QWidget):
else: else:
self.previewListWidget.selectRow( self.previewListWidget.selectRow(
self.previewListWidget.rowCount() - 1) self.previewListWidget.rowCount() - 1)
self.onSlideSelected() self.slideSelected()
def onStartLoop(self): def onStartLoop(self):
""" """
@ -1106,20 +1122,32 @@ class SlideController(QtGui.QWidget):
self.slidePreview.clear() self.slidePreview.clear()
self.slidePreview.show() self.slidePreview.show()
def _forceUnblank(self): def _resetBlank(self):
""" """
Used by command items which provide their own displays to reset the Used by command items which provide their own displays to reset the
screen hide attributes screen hide attributes
""" """
blank = None hide_mode = self.hideMode()
if self.blankScreen.isChecked: if hide_mode == HideMode.Blank:
blank = self.blankScreen self.onBlankDisplay(True)
if self.themeScreen.isChecked: elif hide_mode == HideMode.Theme:
blank = self.themeScreen self.onThemeDisplay(True)
if self.desktopScreen.isChecked: elif hide_mode == HideMode.Screen:
blank = self.desktopScreen self.onHideDisplay(True)
if blank: else:
blank.setChecked(False) self.hidePlugin(False)
self.hideMenu.setDefaultAction(blank)
QtCore.QSettings().remove( def hideMode(self):
self.parent.generalSettingsSection + u'/screen blank') """
Determine what the hide mode should be according to the blank button
"""
if not self.isLive:
return None
elif self.blankScreen.isChecked():
return HideMode.Blank
elif self.themeScreen.isChecked():
return HideMode.Theme
elif self.desktopScreen.isChecked():
return HideMode.Screen
else:
return None

View File

@ -58,6 +58,7 @@ class BibleMediaItem(MediaManagerItem):
MediaManagerItem.__init__(self, parent, plugin, icon) MediaManagerItem.__init__(self, parent, plugin, icon)
# Place to store the search results for both bibles. # Place to store the search results for both bibles.
self.settings = self.parent.settings_tab self.settings = self.parent.settings_tab
self.quickPreviewAllowed = True
self.search_results = {} self.search_results = {}
self.second_search_results = {} self.second_search_results = {}
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),

View File

@ -49,7 +49,7 @@ class Controller(object):
self.doc = None self.doc = None
log.info(u'%s controller loaded' % live) log.info(u'%s controller loaded' % live)
def add_handler(self, controller, file, is_blank): def add_handler(self, controller, file, hide_mode, slide_no):
""" """
Add a handler, which is an instance of a presentation and Add a handler, which is an instance of a presentation and
slidecontroller combination. If the slidecontroller has a display slidecontroller combination. If the slidecontroller has a display
@ -64,12 +64,21 @@ class Controller(object):
# Display error message to user # Display error message to user
# Inform slidecontroller that the action failed? # Inform slidecontroller that the action failed?
return return
self.doc.slidenumber = slide_no
if self.is_live: if self.is_live:
self.doc.start_presentation() if hide_mode == HideMode.Screen:
if is_blank: Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
self.blank() self.stop()
Receiver.send_message(u'maindisplay_hide', HideMode.Screen) elif hide_mode == HideMode.Theme:
self.doc.slidenumber = 0 self.blank(hide_mode)
elif hide_mode == HideMode.Blank:
self.blank(hide_mode)
else:
self.doc.start_presentation()
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
self.doc.slidenumber = 0
if slide_no > 1:
self.slide(slide_no)
def activate(self): def activate(self):
""" """
@ -164,14 +173,10 @@ class Controller(object):
Based on the handler passed at startup triggers slide show to shut down Based on the handler passed at startup triggers slide show to shut down
""" """
log.debug(u'Live = %s, shutdown' % self.is_live) log.debug(u'Live = %s, shutdown' % self.is_live)
if self.is_live:
Receiver.send_message(u'maindisplay_show')
self.doc.close_presentation() self.doc.close_presentation()
self.doc = None self.doc = None
#self.doc.slidenumber = 0
#self.timer.stop()
def blank(self): def blank(self, hide_mode):
""" """
Instruct the controller to blank the presentation Instruct the controller to blank the presentation
""" """
@ -182,6 +187,8 @@ class Controller(object):
return return
if not self.doc.is_active(): if not self.doc.is_active():
return return
if hide_mode == HideMode.Theme:
Receiver.send_message(u'maindisplay_hide', HideMode.Theme)
self.doc.blank_screen() self.doc.blank_screen()
def stop(self): def stop(self):
@ -261,7 +268,7 @@ class MessageListener(object):
is_live = message[1] is_live = message[1]
item = message[0] item = message[0]
log.debug(u'Startup called with message %s' % message) log.debug(u'Startup called with message %s' % message)
is_blank = message[2] hide_mode = message[2]
file = os.path.join(item.get_frame_path(), file = os.path.join(item.get_frame_path(),
item.get_frame_title()) item.get_frame_title())
self.handler = item.title self.handler = item.title
@ -273,7 +280,8 @@ class MessageListener(object):
controller = self.live_handler controller = self.live_handler
else: else:
controller = self.preview_handler controller = self.preview_handler
controller.add_handler(self.controllers[self.handler], file, is_blank) controller.add_handler(self.controllers[self.handler], file, hide_mode,
message[3])
def slide(self, message): def slide(self, message):
""" """
@ -333,7 +341,6 @@ class MessageListener(object):
""" """
is_live = message[1] is_live = message[1]
if is_live: if is_live:
Receiver.send_message(u'maindisplay_show')
self.live_handler.shutdown() self.live_handler.shutdown()
else: else:
self.preview_handler.shutdown() self.preview_handler.shutdown()
@ -351,8 +358,9 @@ class MessageListener(object):
React to the message to blank the display React to the message to blank the display
""" """
is_live = message[1] is_live = message[1]
hide_mode = message[2]
if is_live: if is_live:
self.live_handler.blank() self.live_handler.blank(hide_mode)
def unblank(self, message): def unblank(self, message):
""" """

View File

@ -251,14 +251,13 @@ class PowerpointDocument(PresentationDocument):
win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88) win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
except win32ui.error: except win32ui.error:
dpi = 96 dpi = 96
self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.GotoSlide(1)
rendermanager = self.controller.plugin.renderManager rendermanager = self.controller.plugin.renderManager
rect = rendermanager.screens.current[u'size'] rect = rendermanager.screens.current[u'size']
self.presentation.SlideShowWindow.Top = rect.y() * 72 / dpi ppt_window = self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.Height = rect.height() * 72 / dpi ppt_window.Top = rect.y() * 72 / dpi
self.presentation.SlideShowWindow.Left = rect.x() * 72 / dpi ppt_window.Height = rect.height() * 72 / dpi
self.presentation.SlideShowWindow.Width = rect.width() * 72 / dpi ppt_window.Left = rect.x() * 72 / dpi
ppt_window.Width = rect.width() * 72 / dpi
def get_slide_number(self): def get_slide_number(self):
""" """