interface_thread = None\r
CONFIG_FILE = r'''..\ppt-control.ini'''\r
LOGFILE = r'''..\ppt-control.log'''\r
+REFRESH_INTERVAL = 2\r
logger = None\r
refresh_daemon = None\r
status_label = None\r
http_server = None\r
reset_ppt_button = None\r
icon = None\r
+ws_stop_event = False\r
\r
\r
class Handler(server.SimpleHTTPRequestHandler):\r
\r
\r
def notify_state():\r
+ logger.debug("Notifying state")\r
global STATE\r
if current_slideshow and STATE["connected"] == 1:\r
try:\r
if data["action"] == "prev":\r
if current_slideshow:\r
current_slideshow.prev()\r
- notify_state()\r
+ #notify_state()\r
elif data["action"] == "next":\r
if current_slideshow:\r
current_slideshow.next()\r
- notify_state()\r
+ #notify_state()\r
elif data["action"] == "first":\r
if current_slideshow:\r
current_slideshow.first()\r
- notify_state()\r
+ #notify_state()\r
elif data["action"] == "last":\r
if current_slideshow:\r
current_slideshow.last()\r
- notify_state()\r
+ #notify_state()\r
elif data["action"] == "black":\r
if current_slideshow:\r
if current_slideshow.visible() == 3:\r
current_slideshow.normal()\r
else:\r
current_slideshow.black()\r
- notify_state()\r
+ #notify_state()\r
elif data["action"] == "white":\r
if current_slideshow:\r
if current_slideshow.visible() == 4:\r
current_slideshow.normal()\r
else:\r
current_slideshow.white()\r
- notify_state()\r
+ #notify_state()\r
elif data["action"] == "goto":\r
if current_slideshow:\r
current_slideshow.goto(int(data["value"]))\r
- notify_state()\r
+ #notify_state()\r
else:\r
logger.error("Received unnsupported event: {}", data)\r
finally:\r
ws_daemon.start()\r
logger.info("Started websocket server")\r
\r
+def restart_ws():\r
+ global ws_daemon\r
+ global ws_stop_event\r
+ if ws_daemon and not ws_stop_event:\r
+ ws_stop_event = True\r
+ logger.debug("Stopped WebSocket server")\r
+ refresh_status()\r
+ #ws_daemon = None\r
+ time.sleep(2)\r
+ #start_ws()\r
+ refresh_status()\r
+ \r
+\r
+class ApplicationEvents:\r
+ def OnSlideShowNextSlide(self, *args):\r
+ notify_state()\r
+ logger.debug("Slide changed")\r
+ current_slideshow.export_current_next()\r
+\r
+ def OnSlideShowPrevSlide(self, *args):\r
+ notify_state()\r
+ logger.debug("Slide changed")\r
+ current_slideshow.export_current_next()\r
+\r
class Slideshow:\r
def __init__(self, instance, blackwhite):\r
self.instance = instance\r
\r
if self.instance.SlideShowWindows.Count == 0:\r
raise ValueError("PPT instance has no slideshow windows")\r
- self.view = self.instance.SlideShowWindows[0].View\r
+ self.view = self.instance.SlideShowWindows(1).View\r
\r
if self.instance.ActivePresentation is None:\r
- raise ValueError("PPT instance has no active presentation")\r
+ raise ValueError("PPT instance has no active presentation")\r
self.presentation = self.instance.ActivePresentation\r
\r
self.blackwhite = blackwhite\r
\r
- self.export_current_next()\r
+ if config.prefs["Main"]["cache_init"]:\r
+ self.export_all()\r
+ else:\r
+ self.export_current_next()\r
+\r
+ events = win32com.client.WithEvents(win32com.client.GetActiveObject("Powerpoint.Application"), ApplicationEvents)\r
+ logger.debug("Dispatched events")\r
\r
def unload(self):\r
connect_ppt()\r
\r
if self.instance.SlideShowWindows.Count == 0:\r
raise ValueError("PPT instance has no slideshow windows")\r
- self.view = self.instance.SlideShowWindows[0].View\r
+ self.view = self.instance.SlideShowWindows(1).View\r
\r
if self.instance.ActivePresentation is None:\r
- raise ValueError("PPT instance has no active presentation")\r
+ raise ValueError("PPT instance has no active presentation")\r
except:\r
self.unload()\r
\r
\r
def export(self, slide):\r
destination = config.prefs["Main"]["cache"] + "\\" + self.name() + "\\" + str(slide) + ".jpg"\r
+ logger.debug("Exporting slide " + str(slide))\r
os.makedirs(os.path.dirname(destination), exist_ok=True)\r
if not os.path.exists(destination) or time.time() - os.path.getmtime(destination) > config.prefs.getint("Main", "cache_timeout"):\r
if slide <= self.total_slides():\r
pass\r
\r
def export_all(self):\r
- for i in range(1, self.total_slides()):\r
+ for i in range(1, self.total_slides() + 2):\r
self.export(i)\r
\r
def get_ppt_instance():\r
\r
def refresh_interval():\r
while getattr(refresh_daemon, "do_run", True):\r
+ logger.debug("Refreshing general")\r
+ pythoncom.PumpWaitingMessages()\r
current_slideshow.refresh()\r
- notify_state()\r
- refresh_status()\r
- time.sleep(0.5)\r
+ if current_slideshow.visible != STATE["visible"]:\r
+ notify_state()\r
+ #refresh_status()\r
+ time.sleep(REFRESH_INTERVAL)\r
\r
def refresh_status():\r
- if interface_root is not None and interface_root.state == "normal":\r
+ if interface_root is not None:\r
logger.debug("Refreshing UI")\r
if status_label is not None:\r
status_label.config(text="PowerPoint status: " + ("not " if not STATE["connected"] else "") + "connected")\r
def open_settings(_=None):\r
global interface_root\r
global interface_thread\r
- interface_root = tk.Tk()\r
- interface_root.protocol("WM_DELETE_WINDOW", on_closing)\r
- interface_root.iconphoto(False, tk.PhotoImage(file=os.path.dirname(os.path.realpath(__file__)) + r'''\static\icons\ppt.png'''))\r
- interface_root.geometry("600x300+300+300")\r
- app = Interface(interface_root)\r
- interface_thread = threading.Thread(target=interface_root.mainloop())\r
- interface_thread.setDaemon(True)\r
- interface_thread.start()\r
+ if interface_root is None:\r
+ interface_root = tk.Tk()\r
+ interface_root.protocol("WM_DELETE_WINDOW", on_closing)\r
+ interface_root.iconphoto(False, tk.PhotoImage(file=os.path.dirname(os.path.realpath(__file__)) + r'''\static\icons\ppt.png'''))\r
+ interface_root.geometry("600x300+300+300")\r
+ app = Interface(interface_root)\r
+ interface_thread = threading.Thread(target=interface_root.mainloop())\r
+ interface_thread.setDaemon(True)\r
+ interface_thread.start()\r
\r
def null_action():\r
pass\r
reset_http_button = ttk.Button(self, text="Restart", command=restart_http)\r
reset_http_button.place(x=300, y=30)\r
\r
- #reset_ws_button = ttk.Button(self, text="Restart", command=null_action)\r
+ #reset_ws_button = ttk.Button(self, text="Restart", command=restart_ws)\r
#reset_ws_button.place(x=300, y=50)\r
\r
status_label = ttk.Label(self)\r
\r
def exit_action(icon):\r
logger.debug("User requested shutdown")\r
+ if interface_root is not None:\r
+ try:\r
+ interface_root.destroy()\r
+ except:\r
+ pass\r
icon.visible = False\r
icon.stop()\r
\r
def refresh_menu():\r
icon.menu = (pystray.MenuItem("Status: " + "dis"*(not STATE["connected"]) + "connected", lambda: null_action(), enabled=False),\r
pystray.MenuItem("Stop", lambda: exit_action(icon)),\r
- pystray.MenuItem("Settings", lambda: open_settings(), enabled=False)\r
+ pystray.MenuItem("Settings", lambda: open_settings(), enabled=True)\r
)\r
\r
def show_icon():\r