PYMPRESS(1) | pympress | PYMPRESS(1) |
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 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.
- 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=1712711127.300247)
- 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.
- 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
- 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.
- 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.
- 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)
- action (Action) -- The action activatd
- ( (param) -- class:~`GLib.Variant`): The desired level as an int wrapped in a GLib.Variant
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.
- 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.
- 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
- 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.
- 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
- 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
- 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.
- 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.
- 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
- 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
- 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.
- 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.
- 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
- 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.
- 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.
- widget (Widget) -- the widget in which the event occurred
- event (Event) -- the event that occurred
- Returns
- whether the event was consumed
- Return type
- bool
- int or None, may keep track of the Gtk.Application inhibit request
- laser = None
- Software-implemented laser pointer, Pointer
- 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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
- 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.
- 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)
- widget (Widget) -- the widget in which the event occurred (ignored)
- evt (Event) -- the event that occurred
- on_scroll(widget, event)
- Manage scroll events.
- 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.
- 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
- Callback for the recent document menu.
Gets the URI and requests the document swap.
- gaction (Action) -- the action triggering the call
- is_opening (Variant) -- a wrapped boolean indicating whether the menu is opening or closing.
- ToolButton big button for touch screens, go to previous slide
- preview_page = -1
- number of page currently displayed in Presenter window's miniatures
- 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
- 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.
- 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.
- 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
- 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.
- 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
- Toggle the display of big buttons (nice for touch screens).
- switch_blanked(gaction, param)
- Switch the blanked mode of the content screen.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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)
- 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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
- 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.
- 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
- pos (int) -- The number of the annotation
- value (str) -- The new contents of the annotation
- class pympress.document.PdfPage(value, names=None, *, 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.
- 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.
- 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.
- 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.
- 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!).
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
- 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.
- 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.
- 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.
- 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
- 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.
- 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()
- key_event(widget, event)
- Handle key events to activate the eraser while the shortcut is held
- 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.
- 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.
- 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()
- Handle drawing the eraser button.
- widget (Widget) -- the widget to update
- cairo_context (Context) -- the Cairo context (or None if called directly)
- Handle drawing the marker/pencil buttons, with appropriate thickness and color.
- 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
- 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
- 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
- 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
- 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
- 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.
- 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.
- 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.
- 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.
- 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
- 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.
- 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).
- change_pointermode(action, target)
- Callback for a radio item selection as pointer mode (continuous, manual, none).
- 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 0x7f579aa63200 (GdkPixbuf at 0x3ad8b40)>
- 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.
- 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.
- 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.
- 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.
- 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=None, *, 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
- 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
- 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.)
- 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
- 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_dialog = None
- A Dialog to contain the layout edition dialog
- layout_selected(widget, event=None)
- Manage events for the layout selector drop-down menu
- 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
- 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.
- 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
- 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
- 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.
- 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
- 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.
- 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.
- 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.
- 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
- 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
- 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
- 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.
- 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
- remove_annotation(gaction, param=None)
- Remove an annotation to the from the page’s annotation list
- gaction (Action) -- the action triggering the call, which identifies which backend
- param (Variant) -- an optional parameter
- rewrap_annotations()
- Update the wrap-width of the annotation column to fit its actual width
- 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'.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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)
- 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.
- 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.
- 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()
- set_action_enabled = None
- callback, to be connected to set_action_enabled()
- 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.
- 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.
- 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_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.
- 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
- 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
- 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
- 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
- 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.
- 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.
- 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.
- 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.
- 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
- 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
- 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.
- 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
- paint_backdrop(widget, context)
- Draw behind/around the video, aka the black bars
- 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
09 April, 2024 | 1.8.5 |