Provided by: pympress_1.8.5-1_all
NAME
pympress - pympress documentation
CONTENTS
What is Pympress? Pympress is a PDF presentation tool designed for dual-screen setups such as presentations and public talks. Highly configurable, fully-featured, and portable It comes with many great features (more below): • supports embedded gifs (out of the box), videos, and audios (with VLC or Gstreamer integration) • text annotations displayed in the presenter window • natively supports beamer's notes on second screen, as well as Libreoffice notes pages! Pympress is a free software, distributed under the terms of the GPL license (version 2 or, at your option, any later version). Pympress was originally created and maintained by Schnouki <https://github.com/Schnouki>, on his repo <https://github.com/Schnouki/pympress>. Installing • Ubuntu 20.04 focal or newer, Debian 11 Bullseye or newer (maintained by @mans0954 <https://github.com/mans0954>) apt-get install pympress libgtk-3-0 libpoppler-glib8 libcairo2 python3-gi python3-gi-cairo gobject-introspection libgirepository-1.0-1 gir1.2-gtk-3.0 gir1.2-poppler-0.18 • RPM-based Linux (Fedora, CentOS, Mageia, OpenSuse, RHEL) You can get pympress from the pympress COPR repo of your system. With yum or dnf, simply do: dnf copr enable cimbali/pympress dnf install python3-pympress With zypper, fetch the link of the .repo in the table at the bottom of the COPR page and add it as a source. zypper addrepo https://copr.fedorainfracloud.org/coprs/cimbali/pympress/repo/opensuse-tumbleweed/cimbali-pympress-opensuse-tumbleweed.repo zypper install python3-pympress • Arch Linux from AUR (maintained by @Jose1711 <https://github.com/jose1711>) git clone https://aur.archlinux.org/python-pympress.git cd python-pympress makepkg -si Or using any other tool to manage AUR packages (yay, pacaur, etc.): yay -S python-pympress • macOS using Homebrew <https://brew.sh/> brew install pympress • Windows with Chocolatey <https://chocolatey.org/> (maintained by @ComFreek <https://github.com/ComFreek>) choco install pympress Or using the Windows Package Manager (winget) winget install pympress Or download the latest installer from the latest Github release <https://github.com/Cimbali/pympress/releases/latest>. • If you get an error message along the lines of "MSVCP100.dll is missing", get the Visual C++ 2010 redistributables from Microsoft (x86 (32 bit) <https://www.microsoft.com/en-in/download/details.aspx?id=5555> or x64 (64 bits) <https://www.microsoft.com/en-us/download/details.aspx?id=14632>). Those libraries really should already be installed on your system. • Other systems, directly from PyPI − requires python, gtk+3, poppler, and their python bindings: python3 -m pip install "pympress" • Make sure you have all the dependencies. (These are already included in binary packages or their dependencies.) • Using pip, you may want to install with the --user option, or install from github or downloaded sources. See the python documentation on installing <https://docs.python.org/3.7/installing/index.html>. • If your python environment lacks the Gobject Introspections module, try 1. using --system-site-packages for virtual environments <https://docs.python.org/3.7/library/venv.html>, 2. installing pygobject from pip (pip install pygobject, which requires the correct development/header packages. See the PyPI installation instructions of PyGObject for your system <https://pygobject.readthedocs.io/en/latest/getting_started.html>). Notes To support playing embedded videos in the PDFs, your system must have VLC installed (with the same bitness as pympress). VLC is not distributed with pympress, but it is certainly available in your system’s package manager and on their website <https://www.videolan.org/vlc/>. Usage Opening a file Simply start Pympress and it will ask you what file you want to open. You can also start pympress from the command line with a file to open like so: pympress slides.pdf or python3 -m pympress slides.pdf Functionalities All functionalities are available from the menus of the window with slide previews. Don't be afraid to experiment with them! Keyboard shortcuts are also listed in these menus. Some more usual shortcuts are often available, for example Ctrl+L, and F11 also toggle fullscreen, though the main shortcut is just F. A few of the fancier functionalities are listed here: • Two-screen display: See on your laptop or tablet display the current slide, the next slide, the talk time and wall-clock time, and annotations (either PDF annotations, beamer notes on second slide, or Libreoffice notes pages). The position of the beamer or Libreoffice notes in the slide is detected automatically and can be overridden via a menu option. If you do not want to use second-slide beamer notes but prefer to have notes on their own pages, you can enable auto-detection of these notes. Use the following snippet that prefixes the page labels with notes: on notes pages: \addtobeamertemplate{note page}{}{\thispdfpagelabel{notes:\insertframenumber}} • Media support: supports playing video, audio, and gif files embedded in (or linked from) the PDF file, with optional start/end times and looping. • Highlight mode: Allows one to draw freehand on the slide currently on screen. • Go To Slide: To jump to a selected slide without flashing through the whole presentation on the projector, press G or click the "current slide" box. Using J or clicking the slide label will allow you to navigate slide labels instead of page numbers, useful e.g. for multi-page slides from beamer \pause. A spin box will appear, and you will be able to navigate through your slides in the presenter window only by scrolling your mouse, with the Home/Up/Down/End keys, with the + and - buttons of the spin box, or simply by typing in the number of the slide. Press Enter to validate going to the new slide or Esc to cancel. • Deck Overview: Pressing D will open an overview of your whole slide deck, and any slide can be opened from can simply clicking it. • Software pointer: Clicking on the slide (in either window) while holding ctrl down will display a software laser pointer on the slide. Or press L to permanently switch on the laser pointer. • Talk time breakdown: The Presentation > Timing Breakdown menu item displays a breakdown of how much time was spent on each slide, with a hierarchical breakdown per chapters/sections/etc. if available in the PDF. • Automatic file reloading: If the file is modified, pympress will reload it (and preserve the current slide, current time, etc.) • Big button mode: Add big buttons (duh) for touch displays. • Swap screens: If Pympress mixed up which screen is the projector and which is not, press S • Automatic full screen: pympress will automatically put the content window fullscreen on your non-primay screen when: • connecting a second screen, • extending your desktop to a second screen that was mirroring your main screen, • when starting pympress on a two-screen display. To disable this behaviour, untick “Content fullscreen” under the “Starting configuration” menu. • Estimated talk time: Click the Time estimation box and set your planned talk duration. The color will allow you to see at a glance how much time you have left. • Adjust screen centering: If your slides' form factor doesn't fit the projectors' and you don't want the slide centered in the window, use the "Screen Center" option in the "Presentation" menu. • Resize Current/Next slide: You can drag the bar between both slides on the Presenter window to adjust their relative sizes to your liking. • Caching: For efficiency, Pympress caches rendered pages (up to 200 by default). If this is too memory consuming for you, you can change this number in the configuration file. • Configurability: Your preferences are saved in a configuration file, and many options are accessible there directly. These include: • Customisable key bindings (or shortcuts), • Configurable layout of the presenter window, with 1 to 16 next slides preview • and many more. See the configuration file documentation for more details, • Editable PDF annotations: Annotations can be added, removed, or changed, and the modified PDF files can be saved • Automatic next slide and looping Command line arguments • -h, --help: Shows a list of all command line arguments. • -t mm[:ss], --talk-time=mm[:ss]: The estimated (intended) talk time in minutes and optionally seconds. • -n position, --notes=position: Set the position of notes on the pdf page (none, left, right, top, or bottom). Overrides the detection from the file. • --log=level: Set level of verbosity in log file (DEBUG, INFO, WARNING, ERROR). Media and autoplay To enable media playback, you need to have either: • Gstreamer installed (enabled by default), with its gtk plugin (libgstgtk) which is sometimes packaged separately (e.g. as gst-plugin-gtk or gstreamer1.0-gtk3), and plugins gstreamer-good/-bad/-ugly based on which codecs you need, or • VLC installed (and the python-vlc module), with enabled = on under the [vlc] section of your config file. On macOS, issues with the gstreamer brew formula may require users to set GST_PLUGIN_SYSTEM_PATH manually. For default homebrew configurations the value should be /opt/homebrew/lib/gstreamer-1.0/. Make sure to set this environmental variable globally, or pympress might not pick it up. To produce PDFs with media inclusion, the ideal method is to use beamer’s multimedia package, always with \movie: \documentclass{beamer} \usepackage{multimedia} \begin{frame}{Just a mp4 here} \centering \movie[width=0.3\textwidth]{\includegraphics[width=0.9\textwidth]{frame1.png}}{movie.mp4} \movie[width=0.3\textwidth]{}{animation.gif} \movie[width=0.3\textwidth]{}{ding.ogg} \end{frame} If you desire autoplay, ensure you have pympress ≥ 1.7.0 and poppler ≥ 21.04, and use the movie15 package as follows: \documentclass{beamer} \usepackage{movie15} \begin{document} \begin{frame} \begin{center} \includemovie[attach=false,autoplay,text={% \includegraphics{files/mailto.png}% }]{0.4\linewidth}{0.3\linewidth}{files/random.mpg} \end{center} \end{frame} \end{document} Dependencies Pympress relies on: • Python (version ≥ 3.4, python 2.7 is supported only until pympress 1.5.1, and 3.x < 3.4 until v1.6.4). • Poppler <http://poppler.freedesktop.org/>, the PDF rendering library. • Gtk+ 3 <http://www.gtk.org/>, a toolkit for creating graphical user interfaces, and its dependencies <https://www.gtk.org/overview.php>, specifically: • Cairo <https://www.cairographics.org/> (and python bindings for cairo), the graphics library which is used to pre-render and draw over PDF pages. • Gdk, a lower-level graphics library to handle icons. • PyGi, the python bindings for Gtk+3 <https://wiki.gnome.org/Projects/PyGObject>. PyGi is also known as pygobject3, just pygobject or python3-gi. • Introspection bindings for poppler may be shipped separately, ensure you have those as well (typelib-1_0-Poppler-0_18 on OpenSUSE, gir1.2-poppler-0.18 on Ubuntu) • optionally VLC <https://www.videolan.org/vlc/>, to play videos (with the same bitness as Python) and the python-vlc <https://pypi.org/project/python-vlc/> bindings. • optionally Gstreamer to play videos (which is a Gtk library) On linux platforms The dependencies are often installed by default, or easily available through your package or software manager. For example, on ubuntu, you can run the following as root to make sure you have all the prerequisites assuming you use python3: apt-get install python3 python3-pip libgtk-3-0 libpoppler-glib8 libcairo2 python3-gi python3-cairo python3-gi-cairo gobject-introspection libgirepository-1.0-1 libgirepository1.0-dev gir1.2-gtk-3.0 gir1.2-poppler-0.18 Different distributions might have different package naming conventions, for example the equivalent on OpenSUSE would be: zypper install python3 python3-pip libgtk-3-0 libpoppler-glib8 libcairo2 python3-gobject python3-gobject-Gdk python3-cairo python3-gobject-cairo typelib-1_0-GdkPixbuf-2_0 typelib-1_0-Gtk-3_0 typelib-1_0-Poppler-0_18 On CentOS/RHEL/Fedora the dependencies would be: yum install python36 python3-pip gtk3 poppler-glib cairo gdk-pixbuf2 python3-gobject python3-cairo And on Arch Linux: pacman -S --needed python python-pip gtk3 poppler cairo gobject-introspection poppler-glib python-gobject gst-plugin-gtk On macOS Dependencies can be installed using Homebrew <https://brew.sh/>: brew install --only-dependencies pympress On windows The binary installer for windows comes with pympress and all its dependencies packaged. Alternately, in order to install from pypi or from source on windows, there are two ways to get the dependencies: 1. using MSYS2 (replace x86_64 with i686 if you're using a 32 bit machine). Warning: this can take a substantial amount of disk size as it requires a full software distribution and building platform. pacman -S --needed mingw-w64-x86_64-gtk3 mingw-w64-x86_64-cairo mingw-w64-x86_64-poppler mingw-w64-x86_64-python3 mingw-w64-x86_64-vlc python3-pip mingw-w64-x86_64-python3-pip mingw-w64-x86_64-python3-gobject mingw-w64-x86_64-python3-cairo This is also the strategy used to automate builds on appveyor <https://github.com/Cimbali/pympress/tree/master/scripts/build_msi_mingw.sh>. 2. Using PyGobjectWin32. Be sure to check the supported Python versions (up to 3.4 at the time of writing), they appear in the FEATURES list in the linked page. • Install native python for windows <https://www.python.org/downloads/windows/> • Get GTK+3, Poppler and their python bindings by executing the PyGi installer <https://sourceforge.net/projects/pygobjectwin32/>. Be sure to tick all the necessary dependencies in the installer (Poppler, Cairo, Gdk-Pixbuf). Alternately, you can build your Gtk+3 stack from source using MSVC, see the Gnome wiki <https://wiki.gnome.org/Projects/GTK+/Win32/MSVCCompilationOfGTKStack> and this python script that compiles the whole Gtk+3 stack <https://github.com/wingtk/gvsbuild/>. This strategy has not been used successfully yet, due to problems building Poppler with its introspection bidings (i.e. typelib) − see #109 <https://github.com/Cimbali/pympress/issues/109>. Contributing Feel free to clone this repo and use it, modify it, redistribute it, etc, under the GPLv2+. A number of contributors <https://github.com/Cimbali/pympress/graphs/contributors> have taken part in the development of pympress and submitted pull requests to improve it. Be respectful of everyone and keep this community friendly, welcoming, and harrasment-free. Abusive behaviour will not be tolerated, and can be reported by email at me@cimba.li − wrongdoers may be permanently banned. Pympress has inline sphinx documentation (Google style <http://www.sphinx- doc.org/en/latest/ext/example_google.html>, contains rst syntax), and the docs generated from it are hosted on the github pages of this repo <https://pympress.github.io/>. Translations • Chinese (simplified) • Chinese (traditional) • Czech • Hindi • Italian • Japanese • Polish • French • German • Spanish We thank the many contributors of translations: Agnieszka, atsuyaw, Cherrywoods, Dongwang, Estel-f, Fabio Pagnotta, Ferdinand Fichtner, Frederik. blome, FriedrichFröbel, GM, He. yifan. xs, Jaroslav Svoboda, Jeertmans, Kristýna, lazycat, Leonvincenterd, LogCreative, Lorenzo. pacchiardi, Luis Sibaja, Marcin Dohnalik, marquitul, Morfit, Mzn, Nico, Ogawa, Paul, Pierre BERTHOU, polaksta, Saulpierotti, Shebangmed, Stanisław Polak, susobaco, Tapia, Tejas, Timo Zhang, Tkoyama010, Toton95, Vojta Netrh, Vulpeculus, and Cimbali. If you also want to add or contribute to a translation, check pympress’ page on POEditor <https://poeditor.com/join/project/nKfRxeN8pS>. Note that old strings are kept and tagged removed, to give context and keep continuity between translations of succcessive versions. This means removed strings are unused and do not need translating. Packages Official releases are made to PyPI <https://pypi.org/> and with github releases <https://github.com/Cimbali/pympress/releases>. The community maintains a number of other packages or recipes to install pympress (see Install section). Any additions welcome. Configuration file Pympress has a number of options available from its configuration file. This file is usually located in: • ~/.config/pympress on Linux, • %APPDATA%/pympress.ini on Windows, • ~/Library/Preferences/pympress on macOS, • in the top-level of the pympress install directory for portable installations. The path to the currently used configuration file can be checked in the Help > About information window. Shortcuts The shortcuts are parsed using Gtk.accelerator_parse() <https://lazka.github.io/pgi- docs/#Gtk-3.0/functions.html#Gtk.accelerator_parse>: The format looks like “<Control>a” or “<Shift><Alt>F1” or “<Release>z” (the last one is for key release). The parser is fairly liberal and allows lower or upper case, and also abbreviations such as “<Ctl>” and “<Ctrl>”. Key names are parsed using Gdk.keyval_from_name() <https://lazka.github.io/pgi-docs/#Gdk-3.0/functions.html#Gdk.keyval_from_name>. For character keys the name is not the symbol, but the lowercase name, e.g. one would use “<Ctrl>minus” instead of “<Ctrl>-”. This means that any value in this list of key constants <https://lazka.github.io/pgi- docs/#Gdk-3.0/constants.html#Gdk.KEY_0> is valid (removing the initial Gdk.KEY_ part). You can verify that this value is parsed correctly from the Help > Shortcuts information window. Layouts The panes (current slide, next slide, notes, annotations, etc.) can be rearranged arbitrarily by setting the entries of the layout section in the configuration file. Here are a couple examples of layouts, with Cu the current slide, No the notes half of the slide, Nx the next slide: • All-horizontal layout: +----+----+----+ | Cu | No | Nx | +----+----+----+ Setting: notes = {"children": ["current", "notes", "next"], "proportions": [0.33, 0.33, 0.33], "orientation": "horizontal", "resizeable": true} • All-vertical layout: +----+ | Cu | +----+ | No | +----+ | Nx | +----+ Setting: notes = {"children": ["current", "notes", "next"], "proportions": [0.33, 0.33, 0.33], "orientation": "vertical", "resizeable": true} • Vertical layout with horizontally divided top pane: +----+----+ | Cu | No | +----+----+ | Nx | +---------+ Setting: notes = {"children": [ {"children": ["current", "notes"], "proportions": [0.5, 0.5], "orientation": "horizontal", "resizeable": true}, "next" ], "proportions": [0.5, 0.5], "orientation": "vertical", "resizeable": true} • Horizontal layout with horizontally divided right pane: +----+----+ | | Nx | + Cu +----+ | | No | +---------+ Setting: notes = {"children": [ "current", {"children": ["next", "notes"], "proportions": [0.5, 0.5], "orientation": "vertical", "resizeable": true} ], "proportions": [0.5, 0.5], "orientation": "horizontal", "resizeable": true} And so on. You can play with the items, their nesting, their order, and the orientation in which a set of widgets appears. For each entry the widgets (strings that are leaves of "children" nodes in this representation) must be: • for notes: "current", "notes", "next" • for plain: "current", "next" and "annotations" (the annotations widget is toggled with the A key by default) • for highlight: same as plain with "highlight" instead of "current" A few further remarks: • If you set "resizeable" to false, the panes won’t be resizeable dynamically with a handle in the middle • "proportions" are normalized, and saved on exit if you resize panes during the execution. If you set them to 4 and 1, the panes will be 4 / (4 + 1) = 20% and 1 / (4 + 1) = 100%, so the ini will contain something like 0.2 and 0.8 after executing pympress. Themes on Windows Pympress uses the default Gtk theme of your system, which makes it easy to change on many OSs either globally via your Gtk preferences or per application <https://www.linuxuprising.com/2019/10/how-to-use-different-gtk-3-theme-for.html>. Here’s the way to do it on windows: 1. Install a theme There are 2 locations, either install the theme for all your gtk apps, e.g. in C:\Users\%USERNAME%\AppData\Local\themes, or just for pympress, so in %INSTALLDIR%\share\themes (for me that’s C:\Users\%USERNAME%\AppData\Local\Programs\pympress\share\themes) Basically pick a theme e.g. from this list of dark themes <https://www.gnome- look.org/browse/cat/135/ord/rating/?tag=dark> and make sure to unpack it in the selected directory, it needs at least %THEMENAME%\gtk-3.0\gtk.css and %THEMENAME%\index.theme, where THEMENAME is the name of the theme. There are 2 pitfalls to be aware of, to properly install a theme: • themes that are not self-contained (relying on re-using css from default linux themes that you might not have), and • linux links (files under gtk-3.0/ that point to a directory above and that need to be replaced by a directory containing the contents of the target directory that has the same name as the link file). 2. Set the theme as default Create a settings.ini file, either under C:\Users\%USERNAME%\AppData\Local\gtk-3.0 (global setting) or %INSTALLDIR%\etc\gtk-3.0 (just pympress) and set the contents: [Settings] gtk-theme-name=THEMENAME In testing this found these 2 stackoverflow questions useful: • Change GTK+3 look on Windows <https://stackoverflow.com/a/39041558/1387346> which contains a list of all interesting directories • How to get native windows decorations on GTK3 on Windows 7+ and MSYS2 <https://stackoverflow.com/a/37060369/1387346> which details the process Pympress package This page contains the inline documentation, generated from the code using sphinx. The code is documented in the source using the Google style <https://google.github.io/styleguide/pyguide.html> for docstrings. Sphinx has gathered a set of examples <http://www.sphinx-doc.org/en/latest/ext/example_google.html> which serves as a better crash course than the full style reference. Retructured text (rst) can be used inside the comments and docstrings. Modules pympress.__main__ -- The entry point of pympress pympress.__main__.main(argv=['/usr/lib/python3/dist-packages/sphinx/__main__.py', '-N', '-bman', 'docs/', 'build/man']) Entry point of pympress. Parse command line arguments, instantiate the UI, and start the main loop. pympress.__main__.uncaught_handler(*exc_info) Exception handler, to log uncaught exceptions to our log file. pympress.app -- The Gtk.Application managing the lifetime and CLI class pympress.app.Pympress Bases: Application Class representing the single pympress Gtk application. action_startup_queue = [] list of actions to be passsed to the GUI that were queued before GUI was created activate_action(name, parameter=None) Parse an action name and activate it, with parameter wrapped in a Variant if it is not None. Parameters • name (str) -- the name of the stateful action • parameter -- an object or None to pass as a parameter to the action, wrapped in a GLib.Variant auto_log_level = True bool to automatically upgrade log level (DEBUG / INFO at init, then ERROR), False if user set log level config = None The Config object that holds pympress conferences do_activate(timestamp=1715161371.4645379) Activate: show UI windows. Build them if they do not exist, otherwise bring to front. do_handle_local_options(opts_variant_dict) Parse command line options, returned as a VariantDict Returns estimated talk time, log level, notes positions. Return type tuple do_open(files, n_files, hint) Handle opening files. In practice we only open once, the last one. Parameters • files (list of File) -- representing an array of files to open • n_files (int) -- the number of files passed. • hint (str) -- a hint, such as view, edit, etc. Should always be the empty string. do_shutdown() Perform various cleanups and save preferences. do_startup() Common start-up tasks for primary and remote instances. NB. super(self) causes segfaults, Gtk.Application needs to be used as base. get_action_state(name) Parse an action name and return its unwrapped state from the Variant. Parameters name (str) -- the name of the stateful action Returns the value contained in the action Return type str, int, bool or float gui = None The UI object that is the interface of pympress option_descriptions = {'blank': ('Blank/unblank content screen', None), 'first': ('First slide', None), 'last': ('Last slide', None), 'log': ('Set level of verbosity in log file: DEBUG, INFO, WARNING, ERROR, or CRITICAL', '<level>'), 'next': ('Next slide', None), 'notes': ('Set the position of notes on the pdf page (none, left, right, top, bottom, after, odd, or prefix). Overrides the detection from the file.', '<position>'), 'pause': ('Toggle pause of talk timer', None), 'prev': ('Previous slide', None), 'quit': ('Close opened pympress instance', None), 'reset': ('Reset talk timer', None), 'talk-time': ('The estimated (intended) talk time in minutes (and optionally seconds)', 'mm[:ss]'), 'version': ('Print version and exit', None)} options = {'blank': (98, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>), 'first': (102, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>), 'last': (108, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>), 'log': (0, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_STRING of type GLib.OptionArg>), 'next': (110, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>), 'notes': (78, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_STRING of type GLib.OptionArg>), 'pause': (80, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>), 'prev': (112, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>), 'quit': (113, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>), 'reset': (114, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>), 'talk-time': (116, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_STRING of type GLib.OptionArg>), 'version': (118, <flags 0 of type GLib.OptionFlags>, <enum G_OPTION_ARG_NONE of type GLib.OptionArg>)} quit(*args) Quit and ignore other arguments e.g. sent by signals. set_action_enabled(name, value) Parse an action name and set its enabled state to True or False. Parameters • name (str) -- the name of the stateful action • value (bool) -- wheether the action should be enabled or disabled set_action_state(name, value) Parse an action name and set its state wrapped in a Variant. Parameters • name (str) -- the name of the stateful action • value (str, int, bool or float) -- the value to set. set_log_level(action, param) Action that sets the logging level (on the root logger of the active instance) Parameters • action (Action) -- The action activatd • ( (param) -- class:~`GLib.Variant`): The desired level as an int wrapped in a GLib.Variant version_string = 'Pympress: 1.8.5 ; Python: 3.12.3 ; OS: Linux 5.4.0-177-generic #197-Ubuntu SMP Thu Mar 28 22:45:47 UTC 2024 ; Gtk 3.24.41 ; GLib 2.80.1 ; Poppler 24.02.0 cairo ; Cairo 1.18.0 , pycairo 1.26.0' pympress.ui -- GUI management This module contains the whole graphical user interface of pympress, which is made of two separate windows: the Content window, which displays only the current page in full size, and the Presenter window, which displays both the current and the next page, as well as a time counter and a clock. Both windows are managed by the UI class. class pympress.ui.UI(app, config) Bases: Builder Pympress GUI management. accel_group = None A AccelGroup to store the shortcuts adjust_bottom_bar_font() Scale baseline font size of bottom bar, clipped to 6px..13px. Fonts are then scaled by CSS em indications. adjust_frame_position(*args) Select how to align the frame on screen. annotations = None Class Annotations managing the display of annotations app = None The Pympress instance autoplay = None AutoPlay popup to configure automatic playing blanked = False track whether we blank the screen c_da = None DrawingArea for the Content window. c_frame = None AspectFrame for the Content window. c_win = None Content window, as a Window instance. cache = None SurfaceCache instance. cancel_current_input(gaction, param=None) Handle the action cancelling the input, if applicable. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None change_notes_pos(gaction, target, force=False) Switch the position of the nodes in the slide. Returns the action triggering the call target (Variant): the notes position as a string variant force (bool): Whether to force the notes switch even if it’s already enabled Return type gaction (Action) Returns whether the notes position has been toggled Return type bool chosen_notes_mode = 4 Current choice of mode to toggle notes cleanup(*args) Save configuration and exit the main loop. clear_zoom_cache() Callback to clear the cache of zoomed widgets. click_link(widget, event) Check whether a link was clicked and follow it. Handles a click on a slide. Parameters • widget (Widget) -- the widget in which the event occurred • event (Event) -- the event that occurred Returns whether the event was consumed Return type bool close_file(*args) Remove the current document. close_shortcuts(*args) Destroy the shortcuts window once it is hidden. compute_frame_grid(grid_ar, n_frames) Determine the arragement of frames in a grid to maximise their size given respective aspect ratios Parameters • grid_ar (float) -- aspect ratio of grid containing the slides • n_frames (int) -- the number of frames config = None Config to remember preferences current_page = -1 number of page currently displayed in Content window's miniatures deck = None Class Overview displaying a view of all slides do_page_change(unpause=True, autoplay=False) Switch to another page and display it. This is a kind of event which is supposed to be called only from the Document class. Parameters • is_preview (bool) -- True if the page change should not update the content • unpause (bool) -- True if the page change should unpause the timer, False otherwise • autoplay (bool) -- True if the page change is triggered automatically, otherwise cancel auto play doc = <pympress.document.EmptyDocument object> Current Document instance. doc_goto_end(gaction=None, param=None) Handle going to the end of the document Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None doc_goto_home(gaction=None, param=None) Handle going to the start of the document Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None doc_goto_next(gaction=None, param=None) Handle going to the previous page. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None doc_goto_prev(gaction=None, param=None) Handle going to the next page. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None doc_hist_next(gaction=None, param=None) Handle going to the next page in the history of visited pages Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None doc_hist_prev(gaction=None, param=None) Handle going to the previous page in the history of visited pages Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None doc_label_next(gaction=None, param=None) Handle going to the next page with a different label. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None doc_label_prev(gaction=None, param=None) Handle going to the previous page with a different label. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None error_opening_file(uri) Remove the current document. Parameters uri (str) -- the URI of the document est_time = None EstimatedTalkTime to set estimated/remaining talk time file_watcher = None A FileWatcher object to reload modified files get_notes_mode() Simple getter. Returns Truthy when we split slides in content + notes Return type PdfPage goto_page(page, autoplay=False) Handle going to the page passed as argument Parameters • page (int) -- the page to which to go. Will be clipped to document pages. • autoplay (bool) -- whether this page change was triggered automatically grid_next = None Grid for the next slide(s) in the Presenter window. highlight_button = None ToolButton big button for touch screens, go to scribble on screen hover_link(widget, event) Manage events related to hyperlinks, setting the cursor to a pointer if the hovered region is clickable. Parameters • widget (Widget) -- the widget in which the event occurred • event (Event) -- the event that occurred Returns whether the event was consumed Return type bool inhibit_cookie = None int or None, may keep track of the Gtk.Application inhibit request laser = None Software-implemented laser pointer, Pointer laser_button = None ToolButton big button for touch screens, go toggle the pointer layout_editor = None LayoutEditor popup to configure the layouts of the presenter window layout_name(notes_mode) Return the layout made for the selected notes_mode Parameters notes_mode (PdfPage) -- the mode/positioning of notes Returns a string representing the appropriate layout Return type str load_icons() Set the icon list for both windows. load_layout(new) Replace the current layout Parameters new (str) -- the name of the layout to load, None to use current layout automatically make_cwin() Initializes the content window. make_pwin() Initializes the presenter window. medias = None Class Media managing keeping track of and callbacks on media overlays menu_about(*args) Display the "About pympress" dialog. Handles clicks on the "about" menu. move_window(win, from_bounds, to_bounds) Move window from monitor number from_monitor to monitor to_monitor. next_button = None ToolButton big button for touch screens, go to next slide next_frames_count = 16 int the number of next slides currently on display in the “Next slides” pane, initialized to the maximal number notes_mode = 0 Whether to use notes mode or not on_configure_da(widget, event) Manage "configure" events for all drawing areas, e.g. resizes. We tell the local SurfaceCache cache about it, so that it can invalidate its internal cache for the specified widget and pre-render next pages at a correct size. Warning: Some not-explicitly sent signals contain wrong values! Just don't resize in that case, since these always seem to happen after a correct signal that was sent explicitly. Parameters • widget (Widget) -- the widget which has been resized • event (Event) -- the GTK event, which contains the new dimensions of the widget on_configure_win(widget, event) Manage "configure" events for both window widgets. Parameters • widget (Widget) -- the window which has been moved or resized • event (Event) -- the GTK event, which contains the new dimensions of the widget on_drag_drop(widget, drag_context, x, y, data, info, time) Receive the drag-drops (as text only). If a file is dropped, open it. Parameters • widget (Widget) -- The widget on which the dragged item was dropped • drag_context (DragContext) -- Context object of the dragging • x (float) -- position of the drop • y (float) -- position of the drop • data (SelectionData) -- container for the dropped data • info (int) -- info on the target • time (int) -- time of the drop on_draw(widget, cairo_context) Manage draw events for both windows. This callback may be called either directly on a page change or as an event handler by GTK. In both cases, it determines which widget needs to be updated, and updates it, using the SurfaceCache if possible. Parameters • widget (Widget) -- the widget to update • cairo_context (Context) -- the Cairo context (or None if called directly) on_key_input(widget, event) Handle key strokes at top level, only for when editing needs to bypass action accelerators Parameters • widget (Widget) -- the widget which has received the key stroke • event (Event) -- the GTK event, which contains the key stroke details on_page_change(widget, event=None) Signal handler for current page editing. Parameters • widget (Widget) -- the editable widget which has received the event. • event (Event) -- the GTK event. on_pane_event(widget, evt) Signal handler for gtk.paned events. This function allows one to delay drawing events when resizing, and to speed up redrawing when moving the middle pane is done (which happens at the end of a mouse resize) Parameters • widget (Widget) -- the widget in which the event occurred (ignored) • evt (Event) -- the event that occurred on_scroll(widget, event) Manage scroll events. Parameters • widget (Widget) -- the widget in which the event occurred (ignored) • event (Event) -- the event that occurred Returns whether the event was consumed Return type bool open_file(gaction, target) Open a document. Parameters • gaction (Action) -- the action triggering the call • target (Variant) -- the file to open as a string variant p_central = None Box for the Presenter window. p_da_cur = None DrawingArea for the current slide copy in the Presenter window. p_da_notes = None DrawingArea for the current slide in the Presenter window. p_das_next = None DrawingArea for the next slide in the Presenter window. p_frame_annot = None Frame for the annotations in the Presenter window. p_frame_cur = None list of AspectFrame for the current slide copy in the Presenter window. p_frame_notes = None AspectFrame for the current slide in the Presenter window. p_frames_next = None list of AspectFrame for the next slide in the Presenter window. p_win = None Presenter window, as a Window instance. page_number = None PageNumber displaying and setting current page numbers pane_handle_pos = {} Map of Paned to the relative position (float between 0 and 1) of its handle pick_file(*args) Ask the user which file he means to open. placeable_widgets = {} Dictionary of Widget from the presenter window that can be dynamically rearranged populate_recent_menu(gaction, is_opening=None) Callback for the recent document menu. Gets the URI and requests the document swap. Parameters • gaction (Action) -- the action triggering the call • is_opening (Variant) -- a wrapped boolean indicating whether the menu is opening or closing. prev_button = None ToolButton big button for touch screens, go to previous slide preview_page = -1 number of page currently displayed in Presenter window's miniatures recent_menu = None A Menu to display the recent files to open reconfigure_next_frames(gaction, param) Callback to set the number of next frames to preview the the “next slides” panel Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the number of slides as a GVariant redraw_current_slide() Callback to queue a redraw of the current slides (in both winows). redraw_panes() Handler for Paned's resizing signal. Used for delayed drawing events of drawing areas inside the panes. This is very useful on windows where resizing gets sluggish if we try to redraw while resizing. redraw_timeout = 0 Tracks return values of GLib.timeout_add to cancel gtk.paned's redraw callbacks reflow_next_frames(n_frames=None) Set the number of next frames to preview the the “next slides” panel Parameters n_frames (int) -- the number of frames reload_document() Reload the current document. resize_panes = False Indicates whether we should delay redraws on some drawing areas to fluidify resizing gtk.paned save_file(*args) Remove the current document. save_file_as(*args) Remove the current document. screens_changed(screen) Handle ::monitors-changed events Parameters screen (Screen) -- the screen scribbler = None Class Scribble managing drawing by the user on top of the current slide. set_screensaver(disabled) Disable or re-enable the screensaver. Parameters disabled (bool) -- True iff the screensaver should be disabled, otherwise enabled. setup_screens(screen, event_name='') If multiple monitors, fullscreen windows on monitors according to config. Parameters • screen (Screen) -- the screen • event_name (str) -- a description of what caused the screen setup event, for debugging shortcuts_window = None A ShortcutsWindow to show the shortcuts show_annotations = True Whether to display annotations or not show_bigbuttons = True Whether to display big buttons or not show_shortcuts(*args) Display the shortcuts window. swap_document(doc_uri, page=0, reloading=False) Replace the currently open document with a new one. The new document is possibly and EmptyDocument if doc_uri is None. The state of the ui and cache are updated accordingly. Parameters • doc_uri (str) -- the URI to the new document • page (int) -- the page at which to start the presentation • reloading (bool) -- whether we are reloading or detecting stuff from the document swap_screens(*args) Swap the monitors on which each window is displayed (if there are 2 monitors at least). switch_annotations(gaction, target) Switch the display to show annotations or to hide them. Returns the action triggering the call target (Variant): the parameter as a variant, or None Return type gaction (Action) Returns whether the mode has been toggled. Return type bool switch_bigbuttons(*args) Toggle the display of big buttons (nice for touch screens). switch_blanked(gaction, param) Switch the blanked mode of the content screen. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None Returns whether the notes blanking has been toggled. Return type bool switch_fullscreen(gaction, target) Switch the Content window to fullscreen (if in normal mode) or to normal mode (if fullscreen). Screensaver will be disabled when entering fullscreen mode, and enabled when leaving fullscreen mode. Parameters widget (Widget) -- the widget in which the event occurred Returns whether some window's full screen status got toggled Return type bool switch_mode(gaction, target_mode=None, force=False) Switch the display mode to "Notes mode" or "Normal mode" (without notes). Returns the action triggering the call target_mode (PdfPage): the mode to which we should switch force (bool): Whether to force the mode switch even if it’s already enabled Return type gaction (Action) Returns whether the notes mode has been toggled Return type bool talk_time = None TimeCounter clock tracking talk time (elapsed, and remaining) timing = None TimingReport popup to show how much time was spent on which part track_clicks(widget, event) Track mouse press and release events. Handles clicks on the slides. Parameters • widget (Widget) -- the widget that received the click • event (Event) -- the GTK event containing the click position Returns whether the event was consumed Return type bool track_motions(widget, event) Track mouse motion events. Handles mouse motions on the "about" menu. Parameters • widget (Widget) -- the widget that received the mouse motion • event (Event) -- the GTK event containing the mouse position Returns whether the event was consumed Return type bool unsaved_changes(reload=False) Prompt the user about what to do with changes in the document: save, discard, or cancel action Parameters reload (bool) -- The unsaved changes is prompted by reloading the file Returns True iff we need to cancel the current action Return type bool update_frame_position(widget, user_data) Callback to preview the frame alignment, called from the Gtk.SpinButton. Parameters • widget (SpinButton) -- The button updating the slide alignment in the drawing area widget • user_data (str) -- The property being set, either the x or y alignment (resp. xalign and yalign). validate_current_input(gaction, param=None) Handle the action validating the input, if applicable. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None zoom = None Class Zoom managing the zoom level of the current slide. pympress.document -- document handling This module contains several classes that are used for managing documents (only PDF documents are supported at the moment, but other formats may be added in the future). An important point is that this module is completely independent from the GUI: there should not be any GUI-related code here, except for page rendering (and only rendering itself: the preparation of the target surface must be done elsewhere). class pympress.document.Document(builder, pop_doc, uri) Bases: object This is the main document handling class. The page numbering starts as 0 and is aware of notes (i.e. number of pages may change to account for note pages). The document page numbers are the same as in Poppler, and also start at 0 but do not depend on notes. Parameters • builder (pympress.builder.Builder) -- A builder to load callbacks • pop_doc (Document) -- Instance of the Poppler document that this class will wrap • uri (str) -- URI of the PDF file to open • page (int) -- page number to which the file should be opened changes = False bool indicating whether there were modifications to the document cleanup_media_files() Removes all files that were extracted from the pdf into the filesystem. static create(builder, uri) Initializes a Document by passing it a Document. Parameters • builder (pympress.builder.Builder) -- A builder to load callbacks • uri (str) -- URI to the PDF file to open • page (int) -- page number to which the file should be opened Returns The initialized document Return type Document doc = None Current PDF document (Document instance) doc_page_labels = [] list of all the page labels, indexed on document page numbers get_full_path(filename) Returns full path, extrapolated from a path relative to this document or to the current directory. Parameters filename (Path or str) -- Name of the file or relative path to it Returns the full path to the file or None if it doesn't exist Return type Path get_last_label_pages() Return the last page number for each consecutively distinct page label In other words, squash together consecutive same labels get_structure(index_iter=None) Gets the structure of the document from its index. Recursive, pass the iterator. Parameters index_iter (IndexIter or None) -- the iterator for the child index to explore. Returns A list of tuples (depth, page number, title) Return type list get_uri() Gives access to the URI, rather than the path, of this document. Returns the URI to the file currently opened. Return type str goto(number) Switch to another page. Validates the number and returns one in the correct range. Also updates history. Parameters number (int) -- number of the destination page guess_notes(horizontal, vertical, current_page=0) Get our best guess for the document mode. Parameters • horizontal (str) -- A string representing the preference for horizontal slides • vertical (str) -- A string representing the preference for vertical slides Returns the notes mode Return type PdfPage has_changes() Return whether that some changes were made (e.g. annotations edited) has_labels() Return whether this document has useful labels. Returns False iff there are no labels or they are just the page numbers Return type bool hist_next(*args) Switch to the page we viewed next. hist_pos = -1 Our position in the history hist_prev(*args) Switch to the page we viewed before. history = [] History of pages we have visited, using note-aware page numbers label_after(page) Switch to the next page with different label. If we're within a set of pages with the same label we want to go to the last one. label_before(page) Switch to the previous page with different label. If we're within a set of pages with the same label we want to go before the first one. lookup_label(label, prefix_unique=True) Find a page from its label. Parameters • label (str) -- the label we are searching for • prefix_unique (bool) -- whether a prefix match should be unique, e.g. when the user is still typing Returns the page Return type int made_changes() Notify the document that some changes were made (e.g. annotations edited) navigate() callback, to be connected to goto_page() nb_pages = -1 Number of pages in the document notes_mapping = None list of (slide's document page number, notes' document page number) tuples, or None if there are no notes notes_page(number) Get the specified page. Parameters number (int) -- number of the page to return Returns the wanted page, or None if it does not exist Return type Page page(number) Get the specified page. Parameters number (int) -- number of the page to return Returns the wanted page, or None if it does not exist Return type Page page_labels = [] list of slide page labels, indexed on note-aware page numbers pages_cache = {} Pages cache (dict of Page). This makes navigation in the document faster by avoiding calls to Poppler when loading a page that has already been loaded. pages_number() Get the number of pages in the document. Returns the number of pages in the document Return type int path = None URI Type Path to pdf if uri is a file play_media() callback, to be connected to play() remove_on_exit(filename) Remember a temporary file to delete later. Parameters filename (Path) -- The path to the file to delete save_changes(dest_uri=None) Save the changes Parameters dest_uri (str or None) -- The URI where to save the file, or None to save in-place set_notes_pos(notes_direction) Set whether where the notes pages are relative to normal pages Valid values are returned by direction() - page number (aka Libreoffice notes mode) - page parity (can not be detected automatically, where every other page contains notes) - page mapping (where labels of notes pages are corresponding slide labels prefixed with “notes:”) Parameters notes_direction (str) -- Where the notes pages are start_editing_page_number() callback, to be connected to start_editing() temp_files = {} set of Path representing the temporary files which need to be removed uri = None str full path to pdf class pympress.document.EmptyDocument Bases: Document A dummy document, placeholder for when no document is open. notes_page(number) Retrieve a page from the document. Parameters number (int) -- page number to be retrieved Returns -1 returns the empty page so we can display something. Return type EmptyPage or None page(number) Retrieve a page from the document. Parameters number (int) -- page number to be retrieved Returns -1 returns the empty page so we can display something. Return type EmptyPage or None class pympress.document.EmptyPage(parent) Bases: Page A dummy page, placeholder for when there are no valid pages around. This page is a non-notes page with an aspect ratio of 1.3 and nothing else inside. Also, it has no "rendering" capability, and is made harmless by overriding its render function. can_render() Informs that rendering is not necessary (avoids checking the type). Returns False, no rendering Return type bool render_cairo(cr, ww, wh, dtype=PdfPage.FULL) Overriding this purely for safety: make sure we do not accidentally try to render. Parameters • cr (CairoContext) -- target surface • ww (int) -- target width in pixels • wh (int) -- target height in pixels • dtype (PdfPage) -- the type of document that should be rendered class pympress.document.Link(x1, y1, x2, y2, action) Bases: object This class encapsulates one hyperlink of the document. Parameters • x1 (float) -- first x coordinate of the link rectangle • y1 (float) -- first y coordinate of the link rectangle • x2 (float) -- second x coordinate of the link rectangle • y2 (float) -- second y coordinate of the link rectangle • action (function) -- action to perform when the link is clicked static build_closure(fun, *args, **kwargs) Return a lambda that calls fun(*args, **kwargs), with the current value of args and kwargs. By creating the lambda in a new scope, we bind the arguments. Parameters • fun (function) -- The function to be called • args (tuple) -- non-keyworded variable-length argument list to pass to fun() • kwargs (dict) -- keyworded variable-length argument dict to pass to fun() follow(**kwargs) function, action to be perform to follow this link is_over(x, y) Tell if the input coordinates are on the link rectangle. Parameters • x (float) -- input x coordinate • y (float) -- input y coordinate Returns True if the input coordinates are within the link rectangle, False otherwise Return type bool x1 = None float, first x coordinate of the link rectangle x2 = None float, second x coordinate of the link rectangle y1 = None float, first y coordinate of the link rectangle y2 = None float, second y coordinate of the link rectangle class pympress.document.Media(relative_margins, filename, autoplay, repeat, poster, show_controls, type, start_pos, duration) Bases: tuple A class that holds all the properties for media files autoplay Alias for field number 2 duration Alias for field number 8 filename Alias for field number 1 poster Alias for field number 4 relative_margins Alias for field number 0 repeat Alias for field number 3 show_controls Alias for field number 5 start_pos Alias for field number 7 type Alias for field number 6 class pympress.document.Page(page, number, parent) Bases: object Class representing a single page. It provides several methods used by the GUI for preparing windows for displaying pages, managing hyperlinks, etc. Parameters • doc (Page) -- the poppler object around the page • number (int) -- number of the page to fetch in the document • parent (Document) -- the parent Document class annotations = [] All text annotations can_render() Informs that rendering is necessary (avoids checking the type). Returns True, do rendering Return type bool get_annot_action(link_type, action, rect) Get the function to be called when the link is followed. Parameters • link_type (ActionType) -- The link type • action (Action) -- The action to be performed when the link is clicked • rect (Rectangle) -- The region of the page where the link is Returns The function to be called to follow the link Return type function get_annotations() Get the list of text annotations on this page. Returns annotations on this page Return type list of str get_aspect_ratio(dtype=PdfPage.FULL) Get the page aspect ratio. Parameters dtype (PdfPage) -- the type of document to consider Returns page aspect ratio Return type float get_link_action(link_type, action) Get the function to be called when the link is followed. Parameters • link_type (ActionType) -- The type of action to be performed • action (Action) -- The atcion to be performed Returns The function to be called to follow the link Return type function get_link_at(x, y, dtype=PdfPage.FULL) Get the Link corresponding to the given position. Returns None if there is no link at this position. Parameters • x (float) -- horizontal coordinate • y (float) -- vertical coordinate • dtype (PdfPage) -- the type of document to consider Returns the link at the given coordinates if one exists, None otherwise Return type Link get_media() Get the list of medias this page might want to play. Returns medias in this page Return type list get_size(dtype=PdfPage.FULL) Get the page size. Parameters dtype (PdfPage) -- the type of document to consider Returns page size Return type (float, float) label() Get the page label. links = [] All the links in the page, as a list of Link instances medias = [] All the media in the page, as a list of Media new_annotation(pos, rect=None, value='') Add an annotation to this page Parameters • pos (int) -- The position in the list of annotations in which to insert this annotation • rect (Rectangle) -- A rectangle for the position of this annotation • value (str) -- The contents of the annotation number() Get the page number. page = None Page handled by this class (instance of Page) page_label = None str representing the page label page_nb = -1 int, number of the current page (starting from 0) parent = None Instance of Document that contains this page. ph = 0.0 float, page height pw = 0.0 float, page width remove_annotation(pos) Remove an annotation from this page Parameters pos (int) -- The number of the annotation render_cairo(cr, ww, wh, dtype=PdfPage.FULL) Render the page on a Cairo surface. Parameters • cr (CairoContext) -- target surface • ww (int) -- target width in pixels • wh (int) -- target height in pixels • dtype (PdfPage) -- the type of document that should be rendered set_annotation(pos, value) Update an annotation on this page Parameters • pos (int) -- The number of the annotation • value (str) -- The new contents of the annotation class pympress.document.PdfPage(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None) Bases: IntEnum Represents the part of a PDF page that we want to draw. AFTER = 6 Full page + draw another page for notes, which is after the slides BEFORE = 7 for a notes page, the slide page is BEFORE by half a document Type Complementary of AFTER BOTTOM = 2 Bottom half of PDF page EVEN = 9 Complementary of ODD FULL = 1 Full PDF page (without notes) LEFT = 5 Left half of PDF page MAP = 10 An arbitrary mapping of notes pages to slide pages NONE = 0 No notes on PDF page, only falsy value ODD = 8 Slides on even pages (0-indexed), notes on uneven pages RIGHT = 4 Right half of PDF page RMAP = 11 Reverse the arbitrary mapping MAP TOP = 3 Top half of PDF page complement() Return the enum value for the other part of the page. direction() Returns whether the pdf page/notes mode is horizontal or vertical. Returns a string representing the direction that can be used as the key in the config section Return type str from_screen(x, y, x2=None, y2=None) Transform visible part of the page coordinates to full page coordinates. Pass 2 floats to transform coordinates, 4 to transform margins, i.e. the second pair of coordinates is taken from the opposite corner. Parameters • x (float) -- x coordinate on the screen, on a scale 0..1 • y (float) -- y coordinate on the screen, on a scale 0..1 • x2 (float) -- second x coordinate on the screen, from the other side, on a scale 0..1 • y2 (float) -- second y coordinate on the screen, from the other side, on a scale 0..1 scale() Return the enum value that does only scaling not shifting. to_screen(x, y, x2=None, y2=None) Transform full page coordinates to visible part coordinates. Pass 2 floats to transform coordinates, 4 to transform margins, i.e. the second pair of coordinates is taken from the opposite corner. Parameters • x (float) -- x coordinate on the page, on a scale 0..1 • y (float) -- y coordinate on the page, on a scale 0..1 • x2 (float) -- second x coordinate on the page, from the other side, on a scale 0..1 • y2 (float) -- second y coordinate on the page, from the other side, on a scale 0..1 pympress.document.get_extension(mime_type) Returns a valid filename extension (recognized by python) for a given mime type. Parameters mime_type (str) -- The mime type for which to find an extension Returns A file extension used for the given mimetype Return type str pympress.ui_builder -- abstract GUI management This module contains the tools to load the graphical user interface of pympress, building the widgets/objects from XML (glade) files, applying translation "manually" to avoid dealing with all the mess of C/GNU gettext's bad portability. class pympress.builder.Builder Bases: Builder GUI builder, inherits from Builder to read XML descriptions of GUIs and load them. connect_signals(base_target) Signal connector connecting to properties of base_target, or properties of its properties, etc. Parameters • base_target (Builder) -- The target object, that has functions to be connected to • builder. (signals loaded in this) -- get_callback_handler(handler_name) Returns the handler from its name, searching in target. Parse handler names and split on '.' to use recursion. Parameters • target (object) -- An object that has a method called handler_name • handler_name (str) -- The name of the function to be connected to a signal Returns A function bound to an object Return type function list_attributes(target) List the None-valued attributes of target. Parameters target (dict) -- An object with None-valued attributes load_ui(resource_name, **kwargs) Loads the UI defined in the file named resource_name using the builder. Parameters resource_name (str) -- the basename of the glade file (without extension), identifying the resource to load. load_widgets(target) Fill in target with the missing elements introspectively. This means that all attributes of target that are None now must exist under the same name in the builder. Parameters target (dict) -- An object with None-valued properties whose names correspond to ids of built widgets. pending_pane_resizes = {} dict mapping Paned names to a tuple of (handler id of the size-allocate signal, remaining number of times we allow this signal to run), and we run the signal 2 * (depth + 1) for each pane. This is because size allocation is done bottom-up but each pane sets a top-down constraint. replace_layout(layout, top_widget, leaf_widgets, pane_resize_handler=None) Remix the layout below top_widget with the layout configuration given in 'layout' (assumed to be valid!). Parameters • layout (dict) -- the json-parsed config string, thus a hierarchy of lists/dicts, with strings as leaves • top_widget (Container) -- The top-level widget under which we build the hierachyy • leaf_widgets (dict) -- the map of valid leaf identifiers (strings) to the corresponding Widget • pane_resize_handler (function) -- callback function to be called when the panes are resized Returns The mapping of the used Paned widgets to their relative handle position (in 0..1). Return type dict resize_paned(paned, rect, relpos) Resize paned to have its handle at relpos, then disconnect this signal handler. Called from the Gtk.Widget.signals.size_allocate() signal. Parameters • paned (Paned) -- Panel whose size has just been allocated, and whose handle needs initial placement. • rect (Rectangle) -- The rectangle specifying the size that has just been allocated to paned • relpos (float) -- A number between 0. and 1. that specifies the handle position Returns True static setup_actions(actions, action_map=None) Sets up actions with a given prefix, using the Application as the ActionMap. Parameters • actions (dict) -- Maps the action names to dictionaries containing their parameters. • action_map (ActionMap) -- The object implementing the action map interface to register actions signal_connector(builder, obj, signal_name, handler_name, connect_object, flags, *user_data) Callback for signal connection. Implements the BuilderConnectFunc function interface. Parameters • builder (Builder) -- The builder, unused • obj (Object) -- The object (usually a wiget) that has a signal to be connected • signal_name (str) -- The name of the signal • handler_name (str) -- The name of the function to be connected to the signal • connect_object (Object) -- unused • flags (ConnectFlags) -- unused • user_data (tuple) -- supplementary positional arguments to be passed to the handler pympress.surfacecache -- pages prerendering and caching This modules contains stuff needed for caching pages and prerendering them. This is done by the SurfaceCache class, using several dict of ImageSurface for storing rendered pages. The problem is, neither Gtk+ nor Poppler are particularly threadsafe. Hence the prerendering isn't really done in parallel in another thread, but scheduled on the main thread at idle times using GLib.idle_add(). class pympress.surfacecache.SurfaceCache(doc, max_pages) Bases: object Pages caching and prerendering made (almost) easy. Parameters • doc (Document) -- the current document • max_pages (int) -- The maximum page number. active_widgets = {} Set of active widgets add_widget(widget, wtype, prerender_enabled=True, zoomed=False, ignore_max=False) Add a widget to the list of widgets that have to be managed (for caching and prerendering). This creates new entries for widget_name in the needed internal data structures, and creates a new thread for prerendering pages for this widget. Parameters • widget (Widget) -- The widget for which we need to cache • wtype (int) -- type of document handled by the widget (see surface_type) • prerender_enabled (bool) -- whether this widget is initially in the list of widgets to prerender • zoomed (bool) -- whether we will cache a zoomed portion of the widget • ignore_max (bool) -- whether we will cache an unlimited number of slides clear_cache(widget_name=None) Remove all cached values for a given widget. Useful for zoomed views. Parameters widget_name (str) -- name of the widget that is resized, None for all widgets. disable_prerender(widget_name) Remove a widget from the ones to be prerendered. Parameters widget_name (str) -- string used to identify a widget doc = None The current Document. doc_lock = None Lock used to manage conccurent accesses to doc. enable_prerender(widget_name) Add a widget to the ones to be prerendered. Parameters widget_name (str) -- string used to identify a widget get(widget_name, page_nb) Fetch a cached, prerendered page for the specified widget. Parameters • widget_name (str) -- name of the concerned widget • page_nb (int) -- number of the page to fetch in the cache Returns the cached page if available, or None otherwise Return type ImageSurface get_widget_type(widget_name) Get the document type of a widget. Parameters widget_name (str) -- string used to identify a widget Returns type of document handled by the widget (see surface_type) Return type int locks = {} Dictionary of Lock used for managing conccurent accesses to surface_cache and surface_size max_pages = 200 maximum number fo pages we keep in cache prerender(page_nb) Queue a page for prerendering. The specified page will be prerendered for all the registered widgets. Parameters page_nb (int) -- number of the page to be prerendered put(widget_name, page_nb, val) Store a rendered page in the cache. Parameters • widget_name (str) -- name of the concerned widget • page_nb (int) -- number of the page to store in the cache • val (ImageSurface) -- content to store in the cache renderer(widget_name, page_nb) Rendering function. This function is meant to be scheduled on the GLib main loop. When run, it will go through the following steps: • check if the job's result is not already available in the cache • render it in a new ImageSurface if necessary • store it in the cache if it was not added there since the beginning of the process and the widget configuration is still valid Parameters • widget_name (str) -- name of the concerned widget • page_nb (int) -- number of the page to store in the cache resize_widget(widget_name, width, height) Change the size of a registered widget, thus invalidating all the cached pages. Parameters • widget_name (str) -- name of the widget that is resized • width (int) -- new width of the widget • height (int) -- new height of the widget set_widget_type(widget_name, wtype) Set the document type of a widget. Parameters • widget_name (str) -- string used to identify a widget • wtype (int) -- type of document handled by the widget (see surface_type) surface_cache = {} The actual cache. The dict`s keys are widget names and its values are :class:`~collections.OrderedDict, whose keys are page numbers and values are instances of ImageSurface. In each OrderedDict keys are ordered by Least Recently Used (get or set), when the size is beyond max_pages, pages are popped from the start of the cache. surface_factory = {} dict containing functions that return a Surface given a Format, width int and height int, see create_similar_image_surface() surface_size = {} Size of the different managed widgets, as a dict of tuples surface_type = {} its keys are widget names and its values are document types from ui. Type Type of document handled by each widget. It is a dict swap_document(new_doc) Replaces the current document for which to cache slides with a new one. This function also clears the cached pages, since they now belong to an outdated document. Parameters new_doc (Document) -- the new document unlimited = {} Set of widgets for which we ignore the max pympress.scribble -- Manage user drawings on the current slide class pympress.scribble.Scribbler(config, builder, notes_mode) Bases: Builder UI that allows to draw free-hand on top of the current slide. Parameters • config (Config) -- A config object containing preferences • builder (Builder) -- A builder from which to load widgets • notes_mode (bool) -- The current notes mode, i.e. whether we display the notes on second slide active_preset = -1 int that is the currently selected element adjust_buttons() Properly enable and disable buttons based on scribblings lists. adjust_tools_orientation() Actually change the highlight tool elements orientations according to self.tools_orientation c_da = None The DrawingArea in the content window clear_scribble(*args) Callback for the scribble clear button, to remove all scribbles. current_page = (None, None) tuple of (int, str) indicating the current page number and label disable_scribbling() Disable the scribbling mode. Returns whether it was possible to disable (thus if it was not disabled already) Return type bool draw_scribble(widget, cairo_context) Perform the drawings by user. Parameters • widget (DrawingArea) -- The widget where to draw the scribbles. • cairo_context (Context) -- The canvas on which to render the drawings enable_scribbling() Enable the scribbling mode. Returns whether it was possible to enable (thus if it was not enabled already) Return type bool get_slide_point() callback, to be connected to get_slide_point() highlight_mode = 'single-page' key_event(widget, event) Handle key events to activate the eraser while the shortcut is held Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool load_layout() callback, to be connected to load_layout() load_preset(gaction=None, target=None) Loads the preset color of a given number or designed by a given widget, as an event handler. Parameters • gaction (Action) -- the action triggering the call • target (Variant) -- the new preset to load, as a string wrapped in a GLib.Variant Returns whether the preset was loaded Return type bool mouse_pos = None The position of the mouse on the slide as tuple of float next_render = 0 The next scribble to render (i.e. that is not rendered in cache) on_configure_da(widget, event) Transfer configure resize to the cache. Parameters • widget (Widget) -- the widget which has been resized • event (Event) -- the GTK event, which contains the new dimensions of the widget on_draw() callback, to be connected to on_draw() on_eraser_button_draw(widget, cairo_context) Handle drawing the eraser button. Parameters • widget (Widget) -- the widget to update • cairo_context (Context) -- the Cairo context (or None if called directly) on_preset_button_draw(widget, cairo_context) Handle drawing the marker/pencil buttons, with appropriate thickness and color. Parameters • widget (Widget) -- the widget to update • cairo_context (Context) -- the Cairo context (or None if called directly) p_central = None Box in the Presenter window, where we insert scribbling. page_change(page_number, page_label) Called when we change pages, to clear or restore scribbles Parameters • page_number (int) -- The number of the new page • page_label (str) -- The label of the new page page_change_action(gaction, param) Change whether we exit or stay in highlighting mode on page changes Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the new mode as a string wrapped in a GLib.Variant page_change_exits = True bool indicating whether we exit highlighting mode on page change static parse_color(text) Transform a string to a Gdk object in a single function call Parameters text (str) -- A string describing a color Returns A new color object parsed from the string Return type RGBA pen_action = None The Action that contains the currently selected pen points_to_curves(points) Transform a list of points from scribbles to bezier curves Returns control points of a bezier curves to draw Return type list pop_scribble(*args) Callback for the scribble undo button, to undo the last scribble. prerender() Commit scribbles to cache so they are faster to draw on the slide preset_toolbar = None Box containing the presets previous_preset = -1 int to remember the previously selected element, before holding “eraser” redo_scribble(*args) Callback for the scribble undo button, to undo the last scribble. redraw_current_slide() callback, to be connected to redraw_current_slide() remembered_scribbles = {} dict of scribbles per page render_scribble(cairo_context, color, width, points, pressures) Draw a single scribble, i.e. a bezier curve, on the cairo context Parameters • cairo_context (Context) -- The canvas on which to render the drawings • color (RGBA) -- The color of the scribble • width (float) -- The width of the curve • points (list) -- The control points of the curve, scaled to the surface. • pressures (list) -- The relative line width at each point as float values in 0..1 reset_scribble_cache() Clear the cached scribbles. resize_cache() callback, to be connected to resize_widget() scribble_c_eb = None EventBox for the scribbling in the Content window, captures freehand drawing scribble_cache = None A Surface to hold drawn highlights scribble_clear = None Button for removing all drawn scribbles scribble_color = Gdk.RGBA(red=1.000000, green=1.000000, blue=1.000000, alpha=1.000000) RGBA current color of the scribbling tool scribble_color_selector = None The ColorButton selecting the color of the pen scribble_color_toolbox = None Box containing the scribble color and width selectors scribble_drawing = False Whether the current mouse movements are drawing strokes or should be ignored scribble_list = [] list of scribbles to be drawn, as tuples of color RGBA, width int, a list of points, and a list of pressure values. scribble_off_render = None A OffscreenWindow where we render the scribbling interface when it's not shown scribble_overlay = None HBox that replaces normal panes when scribbling is on, contains buttons and scribble drawing area. scribble_p_da = None DrawingArea for the scribbles in the Presenter window. Actually redraws the slide. scribble_p_eb = None EventBox for the scribbling in the Presenter window, captures freehand drawing scribble_p_frame = None AspectFrame for the slide in the Presenter's highlight mode scribble_preset_buttons = [] The list containing the radio buttons ModelButton scribble_redo = None Button for drawing the last removed scribble scribble_redo_list = [] list of undone scribbles to possibly redo scribble_toolbar = None Box containing the scribble buttons scribble_undo = None Button for removing the last drawn scribble scribble_width = 1 int current stroke width of the scribbling tool scribble_width_selector = None The Scale selecting the size of the pen scribbling_mode = False Whether we are displaying the interface to scribble on screen and the overlays containing said scribbles set_mode(gaction, param) Change the mode of clearing and restoring highlights Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the new mode as a string wrapped in a GLib.Variant set_tools_orientation(gaction, target) Changes the orientation of the highlighting tool box. Parameters • gaction (Action) -- the action triggering the call • target (Variant) -- the new orientation to set, as a string wrapped in a GLib.Variant Returns whether the preset was loaded Return type bool start_zooming() callback, to be connected to start_zooming() stop_zooming() callback, to be connected to stop_zooming() switch_scribbling(gaction, target=None) Starts the mode where one can read on top of the screen. Args: Returns whether the event was consumed Return type bool toggle_erase_modifiers = [] list that contains the modifiers which, when held on scribble start, toggle the eraser toggle_erase_shortcuts = [] list that contains the non-modifier shortcuts which, when held on scribble start, toggle the eraser toggle_erase_source = None str or None that indicates whether a modifier + click or a held shortcut is toggling the eraser toggle_scribble(widget, event) Start/stop drawing scribbles. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool tools_orientation = 'vertical' str indicating the current layout of the highlight toolbar track_clicks() callback, to be connected to track_clicks() track_motions() callback, to be connected to track_motions() track_scribble(widget, event) Draw the scribble following the mouse's moves. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool try_cancel() Cancel scribbling, if it is enabled. Returns True if scribbling got cancelled, False if it was already disabled. Return type bool update_active_color_width() Update modifications to the active scribble color and width, on the pen button and config object update_color(widget) Callback for the color chooser button, to set scribbling color. Parameters widget (ColorButton) -- the clicked button to trigger this event, if any update_width(widget, event, value) Callback for the width chooser slider, to set scribbling width. Parameters • widget (Scale) -- The slider control used to select the scribble width • event (Event) -- the GTK event triggering this update. • value (int) -- the width of the scribbles to be drawn zoom_stop_button = None Button that is clicked to stop zooming, unsensitive when there is no zooming pympress.pointer -- Manage when and where to draw a software-emulated laser pointer on screen class pympress.pointer.Pointer(config, builder) Bases: object Manage and draw the software “laser pointer” to point at the slide. Displays a pointer of chosen color on the current slide (in both windows), either on all the time or only when clicking while ctrl pressed. Parameters • config (Config) -- A config object containing preferences • builder (Builder) -- A builder from which to load widgets activate_pointermode(mode=None) Activate the pointer as given by mode. Depending on the given mode, shows or hides the laser pointer and the normal mouse pointer. Parameters mode (PointerMode) -- The mode to activate c_da = None DrawingArea Slide in the Contents window, used to reliably set cursors. c_frame = None AspectFrame Frame of the Contents window, used to reliably set cursors. change_pointercolor(action, target) Callback for a radio item selection as pointer mode (continuous, manual, none). Parameters • action (Action) -- The action activatd • target (Variant) -- The selected mode change_pointermode(action, target) Callback for a radio item selection as pointer mode (continuous, manual, none). Parameters • action (Action) -- The action activatd • target (Variant) -- The selected mode config = None A reference to the UI's Config, to update the pointer preference load_pointer(name) Perform the change of pointer using its color name. Parameters name (str) -- Name of the pointer to load old_pointer_mode = 2 The PointerMode to which we toggle back p_da_cur = None DrawingArea Slide in the Presenter window, used to reliably set cursors. pointer = <GdkPixbuf.Pixbuf object at 0x7f0ec4a400c0 (GdkPixbuf at 0x21e5850)> Pixbuf to read XML descriptions of GUIs and load them. pointer_mode = 1 PointerMode indicating the pointer mode pointer_pos = (0.5, 0.5) (float, float) of position relative to slide, where the pointer should appear pointermode_radios = {} a dict of the RadioMenuItem selecting the pointer mode redraw_current_slide() callback, to be connected to redraw_current_slide() render_pointer(cairo_context, ww, wh) Draw the laser pointer on screen. Parameters • cairo_context (Context) -- The canvas on which to render the pointer • ww (int) -- The widget width • wh (int) -- The widget height set_action_state = None callback, to be connected to set_action_state() show_pointer = False bool indicating whether we should show the pointer toggle_pointer(widget, event) Track events defining when the laser is pointing. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool track_enter_leave(widget, event) Switches laser off/on in continuous mode on leave/enter slides. In continuous mode, the laser pointer is switched off when the mouse leaves the slide (otherwise the laser pointer "sticks" to the edge of the slide). It is switched on again when the mouse reenters the slide. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool track_pointer(widget, event) Move the laser pointer at the mouse location. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool class pympress.pointer.PointerMode(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None) Bases: Enum Possible values for the pointer. CONTINUOUS = 2 Pointer switched on continuously DISABLED = 0 Pointer never switched on MANUAL = 1 Pointer switched on only manual pympress.editable_label -- A label that can be swapped out for an editable entry class pympress.editable_label.EditableLabel Bases: object A label that can switch between simply displaying a value, and allowing user input to edit this value. cancel() Cancel editing the label. Needs to be reimplemented by children classes. editing = False bool tracking whether we are currently editing the label. event_box = None EventBox around the label, used to sense clicks on_keypress(widget, event) Manage key presses for the editable label. Needs to be reimplemented by children classes. If we are editing the label, intercept some key presses (to validate or cancel editing or other specific behaviour), otherwise pass the key presses on to the button for normal behaviour. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. • name (str) -- the name of the key stroke • command (str) -- the name of the command in case this function is called by on_key_input Returns whether the event was consumed Return type bool on_label_event(widget_or_action, event=None) Manage events on the current slide label/entry. This function triggers replacing the label with an entry when clicked or otherwise toggled. Parameters • widget (Widget) -- the widget in which the event occurred • event (Event or None) -- the event that occurred, None if tf we called from a menu item Returns whether the event was consumed Return type bool restore_label() Make sure that the editable label is not in entry mode. If it is an entry, then replace it with the label. start_editing() Start the editing of the label if it is disabled. stop_editing() Disable the editing of the label if it was enabled. swap_label_for_entry() Perform the actual work of starting the editing. try_cancel() Cancel editing the label, if it is being edited. Returns True if editing got cancelled, False if the label was not being edited. Return type bool try_validate() Validate the page choice, if the page label is being edited. Returns True if editing got validated, False if the label was not being edited. Return type bool validate() Validate the input to the label. Needs to be reimplemented by children classes. class pympress.editable_label.EstimatedTalkTime(builder) Bases: EditableLabel A label that displays the time elapsed since the start of the talk, that can be edited to select talk duration. The duration of the talk will cause the label to blink and change colour as the elapsed time gets closer to the targeted talk duration. Parameters builder (builder.Builder) -- The builder from which to load widgets. eb_ett = None EventBox associated with the estimated talk time. entry_ett = None Entry used to set the estimated talk time. est_time = 0 Estimated talk time, int in seconds. label_ett = None Estimated talk time Label for the talk. label_time = None Elapsed time Label. on_keypress(widget, event) Pass on keystrokes to do_key_press_event(). restore_label(gaction=None, param=None) Make sure that the current page number is displayed in a label and not in an entry. If it is an entry, then replace it with the label. set_time(gaction, param) Set the talk time. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- The time in seconds, as an int64 variant stop_editing_page_number() callback, to be connected to stop_editing() swap_label_for_entry(*args) Perform the actual work of starting the editing. validate() Update estimated talk time from the input. class pympress.editable_label.PageNumber(builder, page_num_scroll) Bases: EditableLabel A label that displays "current page / max page", that can be edited to select a page to which to go. Parameters builder (Builder) -- A builder from which to load widgets cancel(gaction=None, param=None) Make the UI re-display the pages from before editing the current page. changed_page_label(*args) Get the page number from the spinner and go to that page. eb_cur = None EventBox associated with the slide counter label in the Presenter window. edit_label = None Entry used to switch to another slide by typing its label. enable_labels(enable) Allow one to use or ignore labels. Parameters enable (bool) -- Whether to enable labels find_label() callback, to be connected to lookup_label() goto_page() callback, to be connected to goto() hb_cur = None HBox containing the slide counter label in the Presenter window. invert_scroll = True bool whether to scroll with the pages (True) or with the page numbers (False) label_after() callback, to be connected to label_before() label_before() callback, to be connected to label_after() label_cur = None Slide counter Label for the current slide. label_last = None Slide counter Label for the last slide. label_sep = None Label separating spin_cur and edit_label max_page_number = 1 int holding the maximum page number in the document on_keypress(widget, event) Implement directions (left/right/home/end) keystrokes. Otherwise pass on to do_key_press_event(). on_scroll(widget, event) Scroll event. Pass it on to the spin button if we're currently editing the page number. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool page_change() callback, to be connected to do_page_change() page_labels = True bool holding whether we display or ignore page labels restore_label() Make sure that the current page number is displayed in a label and not in an entry. If it is an entry, then replace it with the label. set_last(num_pages) Set the max number of pages, both on display and as the range of values for the spinner. Parameters num_pages (int) -- The maximum page number setup_doc_callbacks(doc) Callbacks that need to be setup again at every new document Parameters doc (Document) -- The new document that got loaded spin_cur = None SpinButton used to switch to another slide by typing its number. swap_label_for_entry(hint=None) Perform the actual work of starting the editing. update_page_numbers(cur_nb, label) Update the displayed page numbers. Parameters • cur_nb (int) -- The current page number, in documentation numbering (range [0..max - 1]) • label (str) -- The current page label validate() Get the page number from the spinner and go to that page. pympress.talk_time -- Manages the clock of elapsed talk time class pympress.talk_time.TimeCounter(builder, ett, timing_tracker, autoplay) Bases: object A double counter, that displays the time elapsed in the talk and a clock. Parameters • builder (builder.Builder) -- The builder from which to load widgets. • ett (int) -- the estimated time for the talk, in seconds. • timing_tracker -- (TimingReport): to inform when the slides change • autoplay -- (AutoPlay): to adjust the timer display if we’re auto-playing/looping slides autoplay = None The AutoPlay, to adjust the timer display if we’re auto-playing/looping slides current_time() Returns the time elapsed in the presentation. Returns the time since the presentation started in seconds. Return type int elapsed_time = 0 Time elapsed since the beginning of the presentation, int in seconds ett = None EstimatedTalkTime that handles changing the ett label_clock = None Clock Label label_colorer = None TimeLabelColorer that handles setting the colors of label_time label_time = None Elapsed time Label pause() Pause the timer if it is not paused, otherwise do nothing. Returns whether the clock's pause was toggled. Return type bool pause_action = None The pause-timer Action paused = True Timer paused status, bool reset_timer(*args) Reset the timer. restart_time = 0 Time at which the counter was started, int in seconds as returned by time() switch_pause(gaction, param=None) Switch the timer between paused mode and running (normal) mode. Returns whether the clock's pause was toggled. Return type bool timing_tracker = None The TimingReport, needs to know when the slides change unpause() Unpause the timer if it is paused, otherwise do nothing. Returns whether the clock's pause was toggled. Return type bool update_time() Update the timer and clock labels. Returns True (to prevent the timer from stopping) Return type bool class pympress.talk_time.TimeLabelColorer(label_time) Bases: object Manage the colors of a label with a set of colors between which to fade, based on how much time remains. Times are given in seconds (<0 has run out of time). In between timestamps the color will interpolated linearly, outside of the intervals the closest color will be used. Parameters label_time (Gtk.Label) -- the label where the talk time is displayed color_map = [] list of tuples (int, RGBA), which are the desired colors at the corresponding timestamps. Sorted on the timestamps. color_override = None CssProvider affecting the style context of the labels default_color() Forces to reset the default colors on the label. label_color_default = None RGBA The default color of the info labels label_time = None The Gtk.Label whose colors need updating load_color_from_css(style_context, class_name=None) Add class class_name to the time label and return its color. Parameters • label_time (Gtk.Label) -- the label where the talk time is displayed • style_context (StyleContext) -- the CSS context managing the color of the label • class_name (str or None) -- The name of the class, if any Returns The color of the label with class "class_name" Return type RGBA update_time_color(remaining) Update the color of the time label based on how much time is remaining. Parameters remaining (int) -- Remaining time until estimated talk time is reached, in seconds. pympress.config -- Configuration class pympress.config.Config Bases: ConfigParser, object Manage configuration :Get the configuration from its file and store its back. get_layout(layout_name) Getter for the layout_name layout. getboolean(*args, **kwargs) Wrapper for configparser’s getboolean to handle parsing errors when a fallback is given. getboolean() getfloat(*args, **kwargs) Wrapper for configparser’s to handle parsing errors when a fallback is given. See getfloat() getint(*args, **kwargs) Wrapper for configparser’s getint to handle parsing errors when a fallback is given. See getint() getlist(*args) Parse a config value and return the list by splitting the value on commas. i.e. bar = foo,qux returns the list ['foo', 'qux'] Returns a config value split into a list. Return type list layout = {} dict-tree of presenter layouts for various modes load_window_layouts() Parse and validate layouts loaded from config, with fallbacks if needed. static path_to_config(search_legacy_locations=False) Return the path to the currently used configuration file. Parameters search_legacy_locations (bool) -- whether to look in previously used locations Returns The path to the config file to use Return type Path placeable_widgets = {'annotations': 'p_frame_annot', 'current': 'p_frame_cur', 'highlight': 'scribble_overlay', 'next': 'grid_next', 'notes': 'p_frame_notes'} dict of strings that are the valid representations of widgets from the presenter window that can be dynamically rearranged, mapping to their names register_actions(builder) Register actions that impact the config file only. Parameters builder (pympress.builder.Builder) -- a builder to setup the actions save_config() Save the configuration to its file. shortcuts = {} dict mapping accelerator keys to actions static_layout = {'deck-overview': 'deck'} dict-tree of presenter layouts that are not configurable static toggle_portable_config(gaction, param=None) Create or remove a configuration file for portable installs. The portable install file will be used by default, and deleting it causes the config to fall back to the user profile location. No need to populate the new config file, this will be done on pympress exit. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None toggle_start(gaction, param=None) Generic function to toggle some boolean startup configuration. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None update_layout_from_widgets(layout_name, widget, pane_handle_pos) Setter for the notes layout. Parameters • layout_name (str) -- the name of the layout to update • widget (Widget) -- the widget that will contain the layout. • pane_handle_pos (dict) -- Map of Paned to the relative handle position (float in 0..1) update_layout_tree(layout_name, layout) Update the layout named layout_name. Throws ValueError on invalid layouts. Parameters • layout_name (str) -- the name of the layout to update • layout (dict) -- the hierarchy of dictionaries, lists, and strings representing the layout upgrade() Update obsolete config options when pympress updates. static using_portable_config() Checks which configuration file location is in use. Returns True iff we are using the portable (i.e. in install dir) location Return type bool validate_layout(layout, expected_widgets, optional_widgets={}) Validate layout: check whether the layout of widgets built from the config string is valid. Parameters • layout (dict) -- the json-parsed config string • expected_widgets (set) -- strings with the names of widgets that have to be used in this layout • optional_widgets (set) -- strings with the names of widgets that may or may not be used in this layout Layout must have all self.placeable_widgets (leaves of the tree, as str) and only allowed properties on the nodes of the tree (as dict). Constraints on the only allowed properties of the nodes are: - resizeable: bool (optional, defaults to no), - orientation: str, either "vertical" or "horizontal" (mandatory) - children: list of size >= 2, containing str`s or `dict`s (mandatory) - proportions: `list of float with sum = 1, length == len(children), representing the relative sizes of all the resizeable items (if and only if resizeable). widget_layout_to_tree(widget, pane_handle_pos) Build a tree representing a widget hierarchy, leaves are strings and nodes are dict. Recursive function. See validate_layout() for more info on the tree structure. Parameters • widget (Widget) -- the widget where to start • pane_handle_pos (dict) -- Map of Paned to the relative handle position (float in 0..1) Returns A tree of dicts reprensenting the widget hierarchy Return type dict widget_reqs = {'highlight': ({'highlight'}, {'annotations', 'current', 'next', 'notes'}), 'highlight_notes': ({'highlight'}, {'annotations', 'current', 'next', 'notes'}), 'note_pages': ({'annotations', 'next', 'notes'},), 'notes': ({'current', 'next', 'notes'}, {'annotations'}), 'plain': ({'annotations', 'current', 'next'},)} dict mapping layout ids to tuples of their expected and optional widgets pympress.extras -- Manages the display of fancy extras such as annotations, videos and cursors class pympress.dialog.AutoPlay(parent) Bases: Builder Widget and machinery to setup and play slides automatically, optionally in a loop autoplay_button_loop = None The CheckButton to loop autoplay_dialog = None A Dialog to contain the layout edition dialog autoplay_spin_lower = None The SpinButton for the lower page autoplay_spin_time = None The SpinButton for the transition between slides autoplay_spin_upper = None The SpinButton for the upper page get_page_range() Return the autoplay info Returns (first page, stop page, looping, delay i ms) Return type tuple goto_page() callback, to be connected to goto_page() is_looping() Return whether an auto-playing next_page(it) Callback to turn the page to the next slide Parameters it (iterator) -- An iterator that contains the next pages to load. Stop when there are no more pages. Returns True if he callback needs to be called again, otherwise False Return type bool page_changed(spin_button, scroll_direction) Callback for when a page spin button is modified, maintains a delta of at least 2 pages between first and last page of the intended loop. (No loops needed to loop a single slide.) Parameters • spin_button (SpinButton) -- The button whose value was changed • scroll_direction (ScrollType) -- The speed and amount of change pause() Pause the looping if it’s running remain = None if the timeout has been paused, int which represents the number of milliseconds until the next page slide run(gaction, param=None) Show the dialog to setup auto-play, and start the autoplay if « apply » is selected Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None set_doc_pages(n_pages) Callback for when a document number of pages changes Parameters n_pages (int) -- the number of pages of the loaded document source = None Source which is the source id of the periodic slide transition, or None if there is no autoplay start_looping() Start the auto-playing stop_looping() Stop the auto-playing unpause() Unpause the looping if it’s paused class pympress.dialog.LayoutEditor(parent, config) Bases: Builder Widget tracking and displaying hierachically how much time was spent in each page/section of the presentation. config = None Config to remember preferences current_layout = 'plain' str containing the layout currently edited get_info(path) Given a path string, look up the appropriate item in both the actual and GtkStore models Parameters path (str) -- A string representing a path in the treemodel Returns the node and iterator representing the position in the layout and model Return type dict, TreeIter hltools_orientation_action = None Action containing the orientation layout_description = None A Label to contain the description of the layout layout_descriptions = {'highlight': 'Layout to draw on the current slide', 'highlight_notes': 'Layout to draw on the current slide with notes displayed', 'note_pages': 'Layout for libreoffice notes on separate pages (with current slide preview in notes)', 'notes': 'Layout for beamer notes on second screen (no current slide preview in notes)', 'plain': 'Plain layout, without note slides'} layout_dialog = None A Dialog to contain the layout edition dialog layout_selected(widget, event=None) Manage events for the layout selector drop-down menu Parameters • widget (ComboBox) -- the widget which has been modified • event (Event) -- the GTK event layout_selector = None A ComboBoxText to select the layout to edit layout_treemodel = None The TreeModel containing the model of the layouts to view in the treeview layout_treeview = None The TreeView displaying the hierarchical layouts load_layout() Load the given layout in the treemodel for display and manipulation in the treeview next_frames_action = None Action containing the number of next frames next_slide_count_edited(widget, path, value) Handle when the next slide count is modified Parameters • widget (ComboBox) -- the widget which has been modified • path (str) -- A string representing the path to the modfied item • value (int) -- the new number of next slides normalize_layout(widget=None, drag_context=None, reload=True) Handler at the end of a drag-and-drop in the treeview Here we transform the listmodel modified by drag-and-drop back to a valid dict and str hierarchy, and then trigger the loading of the layout again to display the corrected layout. Parameters • widget (Widget) -- The object which received the signal • drag_context (DragContext) -- the drag context • reload (bool) -- whether to reload the layout into the treemodel orientation_changed(widget, path, orient_it) Handle when the orientation of a box is changed Parameters • widget (ComboBox) -- the widget which has been modified • path (str) -- A string representing the path to the modfied item • orient_it (TreeIter) -- the row of the newly selected value in the orientations liststore model orientations_model = None The ListModel containing the possible orientations resizeable_toggled(widget, path) Handle when box’ resizeable value is toggled Parameters • widget (ComboBox) -- the widget which has been modified • path (str) -- A string representing the path to the modfied item set_current_layout(layout) Update which is the layout currently used by the UI Parameters layout (str) -- the layout id show_editor(gaction, param=None) Show the popup to edit the layout. Gather info to populate it, and handle apply/cancel at the end. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None treemodel_to_tree(iterator, parent_horizontal=False, parent_resizeable=False) Recursive function to transform the treemodel back into our dict-based representation of the layout Parameters • iterator (TreeIter) -- the position in the treemodel • parent_horizontal (bool) -- whether the parent node is horizontal • parent_resieable (bool) -- whether the parent node is resizeable Returns the list of dict or str representing the widgets at this level Return type list ui_load_layout() callback, to be connected to load_layout() class pympress.dialog.TimingReport(parent) Bases: Builder Widget tracking and displaying hierachically how much time was spent in each page/section of the presentation. clear_on_next_transition = False bool marking whether next page transition should reset the history of page timings doc_structure = {} A dict containing the structure of the current document document_open = False bool tracking whether a document is opened end_time = -1 int the time at which the clock was reset static format_time(secs) Formats a number of seconds as minutes:seconds. Returns The formatted time, with 2+ digits for minutes and 2 digits for seconds. Return type str page_labels = [] A list with the page label of each page of the current document page_time = [] list of time at which each page was reached reset(reset_time) A timer reset. Clear the history as soon as we start changing pages again. set_document_metadata(doc_structure, page_labels) Show the popup with the timing infortmation. Parameters • doc_structure (dict) -- the structure of the document • page_labels (list) -- the page labels for each of the pages show_report(gaction, param=None) Show the popup with the timing infortmation. Parameters • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None time_report_dialog = None A Dialog to contain the timing to show timing_treeview = None The TreeView containing the timing data to display in the dialog transition(page, time) Record a transition time between slides. Parameters • page (int) -- the page number of the current slide • time (int) -- the number of seconds elapsed since the beginning of the presentation pympress.extras -- Manages the display of fancy extras such as annotations, videos and cursors class pympress.extras.Annotations(builder) Bases: object Widget displaying a PDF’s text annotations. add_annotation(gaction, param=None) Add an annotation to the the page’s annotation list Parameters • gaction (Action) -- the action triggering the call, which identifies which backend • param (Variant) -- an optional parameter annotation_column = None The TreeViewColumn where the text is rendered annotation_renderer = None The CellRendererText defining how text is rendered annotations_liststore = None The containing ListStore storing the annotations to be displayed annotations_treeview = None The containing TreeView widget for the annotations editing = None The Entry in which we are currently editing an annotation, or None editing_finished(cell_renderer) Handle the end of editing Parameters cell_renderer (CellRenderer) -- The renderer which received the signal editing_started(cell_renderer, widget, entry_number) Handle edit start Parameters • cell_renderer (CellRenderer) -- The renderer which received the signal • widget (CellEditable) -- the Gtk entry editing the annotation entry • entry_number (str) -- the string representation of the path identifying the edited cell editing_validated(cell_renderer, entry_number, new_content) Handle successful edit: store the new cell value in the model and the document Parameters • cell_renderer (CellRenderer) -- The renderer which received the signal • entry_number (str) -- the string representation of the path identifying the edited cell • new_content (str) -- the new value of the edited cell key_event(widget, event) Handle a key (press/release) event. Needed to forward events directly to the Entry, bypassing the global action accelerators. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool load_annotations(annot_page) Add annotations to be displayed (typically on going to a new slide). Parameters annot_page (Page) -- The page object that contains the annotations new_doc_annotation() remove_annotation(gaction, param=None) Remove an annotation to the from the page’s annotation list Parameters • gaction (Action) -- the action triggering the call, which identifies which backend • param (Variant) -- an optional parameter remove_doc_annotation() rewrap_annotations() Update the wrap-width of the annotation column to fit its actual width set_doc_annotation() try_cancel() Try to cancel editing Returns whether editing was enabled and thus canceled Return type bool class pympress.extras.Cursor Bases: object Class managing cursors statically for displays, so we can select the mouse cursor with a simple string. classmethod set_cursor(widget, cursor_name='parent') Set the cursor named cursor_name'. Parameters • widget (Widget) -- The widget triggering the cursor change, used to retrieve a Gdk.Window • cursor_name (str) -- Name of the cursor to be set class pympress.extras.FileWatcher Bases: object A class that wraps watchdog objects, to trigger callbacks when a file changes. callback() Callback to be called on file changes, usually connected to reload_document() monitor = None A FileSystemEventHandler to get notified when the file changes observer = None A Observer to watch when the file changes path = None The Path to the file being watched stop_watching() Remove all files that are being watched. timeout = 0 watch_file(uri, callback, *args, **kwargs) Watches a new file with a new callback. Removes any precedent watched files. If the optional watchdog dependency is missing, does nothing. Parameters • uri (str) -- URI of the file to watch • callback (function) -- callback to call with all the further arguments when the file changes class pympress.extras.Media(builder, conf) Bases: object Class managing statically the medias and media player backends, to enable play/pause callbacks. Parameters • builder (Builder) -- A builder from which to load widgets • conf (Config) -- An object containing the preferences adjust_margins_for_mode(page_type) Adjust the relative margins of child widgets for notes mode update. Parameters page_type (PdfPage) -- The part of the page to display c_overlay = None Overlay for the Content window. get_factory(mime_type) Returns a class of type _backend. hide(media_id, gaction=None, param=None) Stops playing a media and hides the player. Used as a callback. Parameters • media_id (int) -- A unique identifier of the media to start playing • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None hide_all() Stops all playing medias and hides the players. Used before exit. p_overlay = None Overlay for the Presenter window. play(media_id, gaction=None, param=None) Starts playing a media. Used as a callback. Parameters • media_id (int) -- A unique identifier of the media to start playing • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None play_pause(media_id, gaction=None, param=None) Toggles playing and pausing a media. Used as a callback. Parameters • media_id (int) -- A unique idientifier of the media to start playing • gaction (Action) -- the action triggering the call • param (Variant) -- the parameter as a variant, or None purge_media_overlays() Remove current media overlays. remove_media_overlays() Remove current media overlays. replace_media_overlays(current_page, page_type) Remove current media overlays, add new ones if page contains media. Parameters • current_page (Page) -- The page for which to prepare medias • page_type (PdfPage) -- The part of the page to consider resize(which=None) Resize all media overlays that are a child of an overlay. set_time(media_id, gaction=None, param=None) Set the player of a given media at time t. Used as a callback. Parameters • media_id (int) -- A unique idientifier of the media to start playing • gaction (Action) -- the action triggering the call • param (Variant) -- A wrapped float containing the time to which we have to go. toggle(gaction, param=None) Toggle a backend (if it was loaded correctly) Parameters • gaction (Action) -- the action triggering the call, which identifies which backend • param (Variant) -- an optional parameter types_list = {} dict containing backends and their mappings to mime type lists for which they are enabled. A default backend is marked by an empty list. class pympress.extras.Zoom(builder) Bases: object Manage the zoom level (using a cairo matrix), draw area that will be zoomed while it is being selected. Parameters builder (Builder) -- A builder from which to load widgets clear_cache() callback, to be connected to clear_cache() draw_zoom_target(widget, cairo_context) Perform the drawings by user. Parameters • widget (DrawingArea) -- The widget where to draw the scribbles. • cairo_context (Context) -- The canvas on which to render the drawings get_matrix(ww, wh) Returns the Matrix used to perform the zoom for the widget of size ww x wh. Parameters • ww (float) -- widget width • wh (float) -- widget height Returns the zoom transformation matrix Return type Matrix get_slide_point(widget, event) Gets the point on the slide on a scale (0..1, 0..1), from its position in the widget. nop(**kwargs) Do nothing p_central = None Box in the Presenter window, used to reliably set cursors. redraw_current_slide() callback, to be connected to redraw_current_slide() scale = 1.0 set_action_enabled = None callback, to be connected to set_action_enabled() shift = (0, 0) start_zooming(*args) Setup for the user to select the zooming area. Returns whether the event was consumed Return type bool stop_zooming(*args) Cancel the zooming, reset the zoom level to full page. Returns whether the event was consumed Return type bool toggle_zoom_target(widget, event) Start/stop drawing the zoom's target rectangle. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool track_zoom_target(widget, event) Draw the zoom's target rectangle. Parameters • widget (Widget) -- the widget which has received the event. • event (Event) -- the GTK event. Returns whether the event was consumed Return type bool try_cancel() Cancel the zoom selection, if it was enabled. Returns True if the zoom was cancelled, False if a zoom selection was not in progress. Return type bool zoom_points = None zoom_selecting = False Whether we are displaying the interface to scribble on screen and the overlays containing said scribbles pympress.deck -- Manage user drawings on the current slide class pympress.deck.Overview(config, builder, notes_mode) Bases: Builder UI that allows to draw free-hand on top of the current slide. Parameters • config (Config) -- A config object containing preferences • builder (Builder) -- A builder from which to load widgets • notes_mode (bool) -- The current notes mode, i.e. whether we display the notes on second slide all_pages = False bool whether we show all pages or remove consecutive identically labeled pages, keeping only the last c_da = None The DrawingArea in the content window cache = None SurfaceCache instance. compute_frame_grid() callback, to be connected to compute_frame_grid() create_drawing_areas() Build DrawingArea and AspectFrame elements to display later on deck0 = None The DrawingArea for the first slide deck_grid = None Grid that displays all the slides of the overview deck_mode = False Whether we are displaying the deck overview on screen deck_off_render = None A OffscreenWindow where we render the deck interface when it's not shown deck_viewport = None Viewport that replaces normal panes when deck is shown disable_deck_overview() Disable the deck view. Returns whether it was possible to disable (thus if it was not disabled already) Return type bool enable_deck_overview() Enable the deck view. Returns whether it was possible to enable (thus if it was not enabled already) Return type bool goto_page() callback, to be connected to goto_page() grid_size = (0, 0) tuple of rows/columns in the grid load_layout() callback, to be connected to load_layout() max_row_size = 6 int How large (at most) to make rows on_deck_click(widget, event) A slide has been clicked, go to it Parameters • widget (Widget) -- the widget which has received the key stroke • event (Event) -- the GTK event, which contains the key stroke details on_deck_draw(widget, cairo_context) Actually draw the deck slide -- only do this from cache, to limit overhead Parameters • widget (Widget) -- the widget to update • cairo_context (Context) -- the Cairo context (or None if called directly) on_deck_hover(widget, event) Track when each deck in the slide is hovered p_central = None Box in the Presenter window, where we insert deck. prerender(da) Perform in-cache rendering Parameters da (DrawingArea) -- the widget for which we’re rendering reset_grid(*args) Set the slides configuration and size in the grid resize_cache() callback, to be connected to resize_widget() setup_doc_callbacks(doc) Callbacks that need to be setup again at every new document Parameters doc (Document) -- The new document that got loaded switch_deck_overview(gaction, target=None) Starts the mode where one can read on top of the screen. Args: Returns whether the event was consumed Return type bool try_cancel() Cancel deck, if it is enabled. Returns True if deck got cancelled, False if it was already disabled. Return type bool pympress.util -- various utility functions class pympress.util.Monitor(obj, id_=None, num=None) Bases: ScreenArea A specialised ScreenArea representing a monitor, with an descriptive string and a monitor number static lookup_monitors(display, *windows) Get the info on the monitors Parameters • display (Display) -- the current screen • *windows (tuple of Window) -- windows for which to look up the monitor position Returns The monitors for each window, followed by the best monitors for presenter and content Return type tuple of Monitor monitor_number = -1 An int that identifies the monitor in Display name = '' A str to represent a user-friendly name for the monitor exception pympress.util.NoMonitorPositions Bases: Exception The Exception we raise when there is no way of figuring out the monitor position of windows class pympress.util.ScreenArea(obj) Bases: object Convenience class to represent monitors or windows in terms of the area (position and size) they use on screen This is similar to Monitor, but necessary as we want to handle “mirrored” monitors as if they were a single monitor, and only use “extended” monitors as target for content window position and/or fullscreening. contains(other) Check whether this area contains other Parameters other (ScreenArea) -- The screen area to compare with Returns True iff the area is contained Return type bool equal(other) Check whether 2 areas cover the exact same space Parameters other (ScreenArea) -- The screen area to compare with Returns True iff the areas are identical Return type bool intersection(other) Compute the intersection of 2 screen areas Parameters other (ScreenArea) -- The screen area to compare with Returns An area representing the intersection, or None if there is no intersection Return type ScreenArea or None intersects(other) Check whether this area intersects other Parameters other (ScreenArea) -- The screen area to compare with Returns True iff the areas have an intersection Return type bool least_intersection(candidates) Find the rectangle that intersects least with rect in candidates Parameters candidates (iterable of ` ScreenArea`s) -- The monitor areas to check for intersection Returns The best candidate screen area, i.e. that has the smallest intersection Return type ScreenArea most_intersection(candidates) Find the rectangle that intersects most with rect in candidates Parameters candidates (iterable of ` ScreenArea`s) -- The monitor areas to check for intersection Returns The best candidate screen area, i.e. that has the largest intersection Return type ScreenArea pympress.util.close_opened_resources() Close all importlib context managers for resources that we needed over the program lifetime. pympress.util.fileopen(f) Call the right function to open files, based on the platform. Parameters f (path-like) -- path to the file to open pympress.util.get_default_config() Returns the path to the configuration file containing the defaults. Returns The path to the portable configuration file. Return type Path pympress.util.get_icon_path(name) Get the path for an image from pympress' resources Parameters name (str) -- The name of the icon to load Returns The path to the icon to load Return type str pympress.util.get_log_path() Returns the appropriate path to the log file in the user app dirs. Returns path to the log file. Return type Path pympress.util.get_portable_config() Returns the path to the configuration file for a portable install (i.e. in the install root). May return None if the install root is not a real directory (e.g. in a zip file). Returns The path to the portable configuration file. Return type Path or None pympress.util.get_pympress_meta() Get metadata (version, etc) from pympress' __init__.py or git describe. Returns metadata properties (version, contributors) mapped to their values Return type dict pympress.util.get_translation(domain) Returns a gettext translation object. This re-implements gettext’s translation() and find() to allow using a python 3.9 Traversable as localedir Returns A gettext translation object with the strings for the domain loaded Return type NullTranslations pympress.util.get_ui_resource_file(name, ext='.glade') Load an UI definition file from pympress' resources Parameters • name (str) -- The name of the UI to load • ext (str) -- The extension of the file Returns The full path to the glade file Return type str pympress.util.get_user_config() Returns the path to the configuration file in the user config directory Returns path to the user configuration file. Return type Path pympress.util.hard_set_screensaver(disabled) Enable or disable the screensaver. Parameters disabled (bool) -- if True, indicates that the screensaver must be disabled; otherwise it will be enabled pympress.util.introspect_flag_value(flags_class, nick, fallback) Get the value of a flag from its class, given a value’s name (or nick) Introspection technique (in particular __flags_values__ dict) inspired from pygtkcompat. This is needed because there is no typelib for libgstplayback. Parameters • flags_class (a type inheriting from GFlags) -- the flags class to introspect • nick (str) -- a name or nick of the flag value that should be returned • fallback (int) -- the documented flag value, if lookup fails pympress.util.list_icons() List the icons from pympress' resources. Returns The paths to the icons in the pixmaps directory Return type list of str pympress.util.load_style_provider(style_provider) Load the css and in a style provider Parameters style_provider (CssProvider) -- The style provider in which to load CSS Returns The style provider with CSS loaded Return type CssProvider pympress.util.make_windows_dpi_aware() Set to avoid blurriness issues on High-DPI resolutions with scaling. pympress.media_overlays.base -- base widget to play videos with an unspecified backend class pympress.media_overlays.base.VideoOverlay(container, page_type, action_map, media) Bases: Builder Simple Video widget. All do_X() functions are meant to be called from the main thread, through e.g. idle_add(), for thread-safety in the handling of video backends. Parameters • container (Overlay) -- The container with the slide, at the top of which we add the movie area • page_type (PdfPage) -- the part of the page to display • action_map (ActionMap) -- the action map that contains the actions for this media • media (Media) -- the object defining the properties of the video such as position etc. action_map = None ActionMap containing the actios for this video overlay autoplay = False bool that tracks whether we should play automatically do_hide(*args) Remove widget from overlays. Needs to be called via idle_add(). Returns True iff this function should be run again (idle_add() convention) Return type bool do_play() Start playing the media file. Should run on the main thread to ensure we avoid reentrency problems. Returns True iff this function should be run again (idle_add() convention) Return type bool do_play_pause() Toggle pause mode of the media. Should run on the main thread to ensure we avoid reentrency problems. Returns True iff this function should be run again (idle_add() convention) Return type bool do_set_time(t) Set the player at time t. Should run on the main thread to ensure we avoid vlc plugins' reentrency problems. Parameters t (float) -- the timestamp, in s Returns True iff this function should be run again (idle_add() convention) Return type bool do_stop() Stops playing in the backend player. dragging_paused = False bool that tracks whether the playback was paused when the user started dragging the position dragging_position = False bool that tracks whether the user is dragging the position end_pos = None float giving the end position for playback, if any format_millis(sc, prog) Callback to format the current timestamp (in milliseconds) as minutes:seconds. Parameters • sc (Scale) -- The scale whose position we are formatting • prog (float) -- The position of the Scale, i.e. the number of seconds elapsed handle_embed(mapped_widget) Handler to embed the video player in the window, connected to the map signal. handle_end() End of the stream reached: restart if looping, otherwise hide overlay is_playing() Returns whether the media is currently playing (and not paused). Returns True iff the media is playing. Return type bool is_shown() Returns whether the media overlay is currently added to the overlays, or hidden. Returns True iff the overlay is currently displayed. Return type bool last_timestamp = 0.0 float representing the last know timestamp at which the progress bar updated maxval = 1 float holding the max time in s media_overlay = None VBox that contains all the elements to be overlayed. media_type = '' str representing the mime type of the media file movie_zone = None DrawingArea where the media is rendered. parent = None Overlay that is the parent of the VideoOverlay widget. play_pause(*args) Callback to toggle play/pausing from clicking on the DrawingArea progress = None Scale that is the progress bar in the controls toolbar - if we have one. progress_moved(rng, sc, val) Callback to update the position of the video when the user moved the progress bar. Parameters • rng (Range) -- The range corresponding to the scale whose position we are formatting • sc (Scale) -- The scale whose position we are updating • val (float) -- The position of the Scale, which is the number of seconds elapsed in the video relative_margins = None tuple containing the left/top/right/bottom space around the drawing area in the visible slide relative_page_margins = None tuple containing the left/top/right/bottom space around the drawing area in the PDF page repeat = False bool that tracks whether we should play after we finished playing resize() Adjust the position and size of the media overlay. show() Bring the widget to the top of the overlays if necessary. start_pos = 0.0 float giving the initial starting position for playback time_format = '{:01}:{:02}' ss / m:ss when the max time is known Type Format of the video time, defaults to m Type ss, changed to m toolbar = None A HBox containing a toolbar with buttons and progress the progress bar update_margins_for_page(page_type) Recalculate the margins around the media in the event of a page type change. Parameters page_type (PdfPage) -- the part of the page to display update_progress(time) Update the toolbar slider to the current time. Parameters time (float) -- The time in this video in s update_range(max_time) Update the toolbar slider size. Parameters max_time (float) -- The maximum time in this video in s pympress.media_overlays.gif -- widget to play gif images as videos class pympress.media_overlays.gif_backend.GifOverlay(*args, **kwargs) Bases: VideoOverlay A simple overlay mimicking the functionality of showing videos, but showing gifs instead. advance_gif() Advance the gif, queue redrawing if the frame changed, and schedule the next frame. anim = None A PixbufAnimation containing all the frames and their timing for the displayed gif anim_iter = None A PixbufAnimationIter which will provide the timely access to the frames in anim base_size = None A tuple of (int, int) indicating the size of the bounding box of the gif do_play() Start playing the media file. Should run on the main thread to ensure we avoid reentrency problems. Returns True iff this function should be run again (idle_add() convention) Return type bool do_play_pause() Toggle pause mode of the media. Should run on the main thread to ensure we avoid reentrency problems. Returns True iff this function should be run again (idle_add() convention) Return type bool do_set_time(t) Set the player at time t. Should run on the main thread to ensure we avoid reentrency problems. Parameters t (int) -- the timestamp, in ms Returns True iff this function should be run again (idle_add() convention) Return type bool do_stop() Stops playing in the backend player. draw(widget, ctx) Simple resized drawing: get the pixbuf, set the transform, draw the image. is_playing() Returns whether the media is currently playing (and not paused). Returns True iff the media is playing. Return type bool mute(*args) set_transform(*args) Compute the transform to scale (not stretch nor crop) the gif. classmethod setup_backend() Returns the name of this backend. transform = None The Matrix defining the zoom & shift to scale the gif pympress.media_overlays.gst -- widget to play videos using Gstreamer's Gst class pympress.media_overlays.gst_backend.GstOverlay(*args, **kwargs) Bases: VideoOverlay Simple Gstramer widget. Wraps a simple gstreamer playbin. do_play() Start playing the media file. Returns True iff this function should be run again (idle_add() convention) Return type bool do_play_pause() Toggle pause mode of the media. Should run on the main thread to ensure we avoid reentrency problems. Returns True iff this function should be run again (idle_add() convention) Return type bool do_set_time(time) Set the player at time time. Should run on the main thread to ensure we avoid reentrency problems. Parameters time (float) -- the timestamp, in s Returns True iff this function should be run again (idle_add() convention) Return type bool do_stop() Stops playing in the backend player. do_update_duration(*args) Transmit the change of file duration to the UI to adjust the scroll bar. do_update_time() Update the current position in the progress bar. Returns True iff this function should be run again (timeout_add() convention) Return type bool is_playing() Returns whether the media is currently playing (and not paused). Returns True iff the media is playing. Return type bool mute(value) Mutes or unmutes the player. Parameters value (bool) -- True iff this player should be muted on_initial_play() Set starting position, start scrollbar updates, unhide overlay. on_state_changed(bus, msg) Callback triggered by playbin state changes. Parameters • bus (Bus) -- the bus that we are connected to • msg (Message) -- the "state-changed" message playbin = None A Playbin to be play videos classmethod setup_backend(gst_opts=[]) Prepare/check the Gst backend. Returns the version of Gst used by the backend Return type str sink = None A Sink to display video content update_freq = 200 int number of milliseconds between updates pympress.media_overlays.vlc -- widget to play videos using VLC class pympress.media_overlays.vlc_backend.VlcOverlay(*args, **kwargs) Bases: VideoOverlay Simple VLC widget. Its player can be controlled through the 'player' attribute, which is a MediaPlayer instance. do_play() Start playing the media file. Should run on the main thread to ensure we avoid vlc plugins' reentrency problems. Returns True iff this function should be run again (idle_add() convention) Return type bool do_play_pause() Toggle pause mode of the media. Should run on the main thread to ensure we avoid vlc plugins' reentrency problems. Returns True iff this function should be run again (idle_add() convention) Return type bool do_set_time(time) Set the player at time time. Should run on the main thread to ensure we avoid vlc plugins' reentrency problems. Parameters time (float) -- the timestamp, in s Returns True iff this function should be run again (idle_add() convention) Return type bool do_stop() Stops playing in the backend player. handle_embed(mapped_widget) Handler to embed the VLC player in the window, connected to the map signal. handle_end() End of the stream reached: restart if looping, otherwise hide overlay Overrided because, to implement looping, vlc plugin needs to be told to start on stream end, not to seek is_playing() Returns whether the media is currently playing (and not paused). Returns True iff the media is playing. Return type bool mute(value) Mutes the player. Parameters value (bool) -- True iff this player should be muted paint_backdrop(widget, context) Draw behind/around the video, aka the black bars Parameters • widget (Widget) -- the widget to update • context (Context) -- the Cairo context (or None if called directly) classmethod setup_backend(vlc_opts=['--no-video-title-show']) Prepare/check the VLC backend. Parameters vlc_opts (list) -- the arguments for starting vlc Returns the version of VLC used by the backend Return type str show() Bring the widget to the top of the overlays if necessary − also force redraw of movie zone time_changed(event) Handle time passing Parameters event (Event) -- The event that triggered the handler pympress.media_overlays.vlc_backend.get_window_handle(window) Uses ctypes to call gdk_win32_window_get_handle which is not available in python gobject introspection porting. Solution from http://stackoverflow.com/a/27236258/1387346 Parameters window (Window) -- The window for which we want to get the handle Returns The handle to the win32 window
AUTHOR
Cimbali
COPYRIGHT
2009-2024, Thomas Jost; 2015-2023 Cimbali