Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
doc_screenshot.c File Reference
#include "gui/actions/doc_screenshot.h"
#include "common/conf.h"
#include "common/l10n.h"
#include "gui/application.h"
#include "gui/window_manager.h"
#include "system/macros.h"
#include "system/mem_alloc.h"
#include "widgets/bauhaus.h"
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gtk/gtk.h>
+ Include dependency graph for doc_screenshot.c:

Go to the source code of this file.

Data Structures

struct  _doc_screenshot_capture_t
 
struct  _doc_source_t
 

Macros

#define DOC_SCREENSHOT_FILENAME_ALLOWED    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."
 
#define DOC_SCREENSHOT_PREVIEW_SIZE   360
 
#define DOC_SCREENSHOT_MAP_FILE   "screenshots.map"
 
#define DOC_SCREENSHOT_SELECTION_CONF_KEY   "doc_screenshot/selection"
 
#define DOC_SCREENSHOT_SEPARATOR   "\x1f"
 

Typedefs

typedef enum _doc_screenshot_select_t _doc_screenshot_select_t
 
typedef enum _doc_screenshot_column_t _doc_screenshot_column_t
 
typedef struct _doc_screenshot_capture_t _doc_screenshot_capture_t
 
typedef struct _doc_source_t _doc_source_t
 

Enumerations

enum  _doc_screenshot_select_t {
  DOC_SCREENSHOT_SELECT_NONE = 0 ,
  DOC_SCREENSHOT_SELECT_ALL ,
  DOC_SCREENSHOT_SELECT_MAPPED
}
 
enum  _doc_screenshot_column_t {
  COL_CHECKED = 0 ,
  COL_LABEL ,
  COL_PAGE ,
  COL_TARGET ,
  COL_ROW ,
  COL_CAPTURABLE ,
  COL_ENABLED ,
  COL_COUNT
}
 

Functions

void dt_gui_doc_screenshot_enable (void)
 
gboolean dt_gui_doc_screenshot_enabled (void)
 
void dt_gui_doc_screenshot_set_directory (const char *path)
 
static void _load_selection (void)
 
static void _save_selection (void)
 
static int _write_surface (cairo_surface_t *surface, const char *filename)
 
static cairo_surface_t * _render_area (GtkWidget *widget, const GdkRectangle *area)
 
static gboolean _tree_row_area (GtkTreeView *view, GtkTreeRowReference *row, GdkRectangle *area)
 
static cairo_surface_t * _render_target (GtkWidget *target, GtkTreeRowReference *row)
 
static int _save_target_as_image (GtkWidget *target, GtkTreeRowReference *row, const char *filename)
 
static gboolean _widget_has_text (GtkWidget *widget)
 
static gchar * _localized_path (const char *relative, const char *code)
 
static void _load_pages (void)
 
static const char * _first_text (GtkWidget *widget)
 
static GtkWidget_unwrap (GtkWidget *widget)
 
static gchar * _widget_label (GtkWidget *widget, const int index)
 
static void _append_placeholder (GtkTreeIter *parent)
 
static void _append_row (GtkTreeIter *parent, GtkWidget *target, const char *label_override, const int index)
 
static gchar * _tree_row_text (GtkTreeView *view, GtkTreeModel *model, GtkTreeIter *item)
 
static void _append_tree_row (GtkTreeIter *parent, GtkTreeView *view, GtkTreeModel *model, GtkTreeIter *item, const int index)
 
static void _append_tree_rows (GtkTreeIter *parent, GtkTreeView *view, GtkTreeRowReference *under)
 
void dt_gui_doc_screenshot_register_source (const char *section, dt_gui_doc_screenshot_source_t source)
 
void dt_gui_doc_screenshot_add_target (void *inventory, GtkWidget *widget, const char *name)
 
static void _append_section (const char *title, GtkTreeIter *section)
 
static void _on_row_expanded (GtkTreeView *view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data)
 
static gchar * _label_chain (GtkTreePath *path)
 
static void _collect_expanded (GtkTreeView *view, GtkTreePath *path, gpointer user_data)
 
static gboolean _find_row (const char *chain, GtkTreeIter *found)
 
static gboolean _is_application_window (GtkWindow *window)
 
static gint _compare_window_titles (gconstpointer a, gconstpointer b)
 
static GList * _application_windows (void)
 
static void _populate (GtkWidget *widget, gpointer user_data)
 
static void _on_row_selected (GtkTreeSelection *selection, gpointer user_data)
 
static void _on_toggled (GtkCellRendererToggle *renderer, gchar *path_string, gpointer user_data)
 
static gboolean _select_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
 
static void _on_select (GtkButton *button, gpointer user_data)
 
static gboolean _capture_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
 
static void _on_capture (GtkButton *button, gpointer user_data)
 
static void _on_destroy (GtkWidget *widget, gpointer user_data)
 
void dt_gui_doc_screenshot_window_show (void)
 

Variables

struct { 
 
   GtkWidget *   window 
 
   GtkWidget *   view 
 the tree view More...
 
   GtkTreeStore *   store 
 its model, owned by the view More...
 
   GtkWidget *   folder 
 destination folder chooser More...
 
   GtkWidget *   status 
 result of the last capture More...
 
   GtkWidget *   preview 
 what the selected row actually captures More...
 
   GtkWidget *   geometry 
 its size, under the preview More...
 
   GHashTable *   names 
 GtkWidget* -> the name the application knows it by. More...
 
   GHashTable *   pages 
 row label -> path of the illustration, relative to the destination More...
 
   GHashTable *   selected 
 set of checked row labels, mirrored to conf on every change More...
 
   gchar *   directory 
 documentation root given after –doc, or NULL More...
 
   gboolean   enabled 
 –doc was passed on the command line More...
 
_g = { 0 } 
 
static GList * _sources = NULL
 

Macro Definition Documentation

◆ DOC_SCREENSHOT_FILENAME_ALLOWED

#define DOC_SCREENSHOT_FILENAME_ALLOWED    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_."

Characters kept as-is in a generated file name. Everything else – spaces, accents, slashes, parentheses – is replaced by an underscore by g_strcanon(). Applies only to names derived from a row label: a path coming from the map is the documentation's own and is used verbatim.

Definition at line 37 of file doc_screenshot.c.

◆ DOC_SCREENSHOT_MAP_FILE

#define DOC_SCREENSHOT_MAP_FILE   "screenshots.map"

Name of the widget-to-page map, looked up at the root of the destination folder.

Definition at line 44 of file doc_screenshot.c.

◆ DOC_SCREENSHOT_PREVIEW_SIZE

#define DOC_SCREENSHOT_PREVIEW_SIZE   360

Longest side of the preview shown for the selected row, in logical pixels.

Definition at line 41 of file doc_screenshot.c.

◆ DOC_SCREENSHOT_SELECTION_CONF_KEY

#define DOC_SCREENSHOT_SELECTION_CONF_KEY   "doc_screenshot/selection"

Conf key holding the labels of the checked rows, joined by DOC_SCREENSHOT_SEPARATOR.

Deliberately NOT a confgen key and absent from Preferences: this is developer-mode state, meaningless to anyone who never passed –doc. It is what makes a documentation pass reproducible – the same selection comes back for the next language instead of being rebuilt from memory.

The separator mirrors DT_FOLDER_SURVEY_STYLES_SEPARATOR for the same reason: a widget label may contain any printable character, so only a control character can neither appear in one nor break the one-value-per-line conf file. The same separator joins the labels of a row's ancestors into the chain that identifies it across a refresh.

Rows are remembered by label, the same key the map uses. Two rows sharing a label – two anonymous GtkBox rows, say – therefore come back checked together; the rows that matter to a documentation pass are the mapped ones, whose labels are unique by construction.

Definition at line 63 of file doc_screenshot.c.

◆ DOC_SCREENSHOT_SEPARATOR

#define DOC_SCREENSHOT_SEPARATOR   "\x1f"

Definition at line 64 of file doc_screenshot.c.

Typedef Documentation

◆ _doc_screenshot_capture_t

Carried through the model walk of one capture run.

◆ _doc_screenshot_column_t

Columns of the widget tree.

COL_TARGET is a G_TYPE_OBJECT, not a pointer: the store then references the widget it holds, which is what keeps the row valid when a view change destroys the modules of the view being left under an open window. A destroyed widget is merely unmapped afterwards, and _save_target_as_image() reports it as "cannot be drawn".

A NULL target below the top level marks a lazy-expansion placeholder – see _append_row().

COL_ROW is what makes a row of a GtkTreeView capturable: such a row is no widget, only cells its view paints, so the panel row keeps the view as its target and the item as a GtkTreeRowReference – which follows the item through insertions and removals, and holds the model alive, so it can be checked against the model the view shows at capture time.

◆ _doc_screenshot_select_t

What the three selection buttons ask of the model walk.

◆ _doc_source_t

typedef struct _doc_source_t _doc_source_t

Enumeration Type Documentation

◆ _doc_screenshot_column_t

Columns of the widget tree.

COL_TARGET is a G_TYPE_OBJECT, not a pointer: the store then references the widget it holds, which is what keeps the row valid when a view change destroys the modules of the view being left under an open window. A destroyed widget is merely unmapped afterwards, and _save_target_as_image() reports it as "cannot be drawn".

A NULL target below the top level marks a lazy-expansion placeholder – see _append_row().

COL_ROW is what makes a row of a GtkTreeView capturable: such a row is no widget, only cells its view paints, so the panel row keeps the view as its target and the item as a GtkTreeRowReference – which follows the item through insertions and removals, and holds the model alive, so it can be checked against the model the view shows at capture time.

Enumerator
COL_CHECKED 

the capture check box

COL_LABEL 

displayed name, also the key into the widget-to-page map

COL_PAGE 

illustration this widget stands for, from the map. "" when unmapped

COL_TARGET 

widget this row captures, or the tree view drawing the item COL_ROW names. NULL on a section header and on a placeholder

COL_ROW 

the tree view item this row captures. NULL when it captures a whole widget

COL_CAPTURABLE 

there is a target, so a check box is worth showing at all

COL_ENABLED 

the target is currently displayed. Always TRUE on a section header

COL_COUNT 

Definition at line 88 of file doc_screenshot.c.

◆ _doc_screenshot_select_t

What the three selection buttons ask of the model walk.

Enumerator
DOC_SCREENSHOT_SELECT_NONE 

clear everything, displayed or not

DOC_SCREENSHOT_SELECT_ALL 

check every displayed row

DOC_SCREENSHOT_SELECT_MAPPED 

check exactly the displayed rows the map names

Definition at line 67 of file doc_screenshot.c.

Function Documentation

◆ _append_placeholder()

static void _append_placeholder ( GtkTreeIter *  parent)
static

Give parent a single row with no target – which is what gives the tree view its expander arrow – for _on_row_expanded() to swap for the real children the first time it is opened.

Definition at line 545 of file doc_screenshot.c.

References _g, COL_CAPTURABLE, COL_CHECKED, COL_ENABLED, COL_LABEL, COL_PAGE, COL_TARGET, and FALSE.

Referenced by _append_row(), and _append_tree_row().

◆ _append_row()

static void _append_row ( GtkTreeIter *  parent,
GtkWidget target,
const char *  label_override,
const int  index 
)
static

Append one capturable row under parent, and make it expandable if the widget has children of its own.

Children are not built here: a full walk of the main window would materialise thousands of rows the user will never open. Instead a container gets a single placeholder child – a row with no target, which is what gives the tree view its expander arrow – and _on_row_expanded() swaps it for the real children the first time it is opened.

Parameters
label_overridethe application's own name for this widget, or NULL to derive one.

Definition at line 564 of file doc_screenshot.c.

References _append_placeholder(), _g, _unwrap(), _widget_label(), COL_CAPTURABLE, COL_CHECKED, COL_ENABLED, COL_LABEL, COL_PAGE, COL_TARGET, dt_free, IS_NULL_PTR, items, and TRUE.

Referenced by _on_row_expanded(), _populate(), and dt_gui_doc_screenshot_add_target().

◆ _append_section()

static void _append_section ( const char *  title,
GtkTreeIter *  section 
)
static

Append a top-level grouping row. It captures nothing: it is a way in, not a target.

Definition at line 731 of file doc_screenshot.c.

References _g, COL_CAPTURABLE, COL_CHECKED, COL_ENABLED, COL_LABEL, COL_PAGE, COL_TARGET, FALSE, and TRUE.

Referenced by _populate().

◆ _append_tree_row()

static void _append_tree_row ( GtkTreeIter *  parent,
GtkTreeView *  view,
GtkTreeModel *  model,
GtkTreeIter *  item,
const int  index 
)
static

Append one tree view item under parent, and make it expandable if it has children of its own. The row captures the item's band of its view – see _tree_row_area().

Definition at line 641 of file doc_screenshot.c.

References _append_placeholder(), _g, _tree_row_area(), _tree_row_text(), COL_CAPTURABLE, COL_CHECKED, COL_ENABLED, COL_LABEL, COL_PAGE, COL_ROW, COL_TARGET, dt_free, IS_NULL_PTR, model, row, TRUE, and view.

Referenced by _append_tree_rows().

◆ _append_tree_rows()

static void _append_tree_rows ( GtkTreeIter *  parent,
GtkTreeView *  view,
GtkTreeRowReference *  under 
)
static

Append the items of view under parent: the model's top level when under is NULL, else the children of that item.

Lists nothing when the view now shows another model than the one under was taken in: that panel row is stale, and a refresh rebuilds it from the model on screen. All the items of a level are listed, displayed or not, like the widgets are; only the levels someone unfolds are ever built.

Definition at line 677 of file doc_screenshot.c.

References _append_tree_row(), FALSE, IS_NULL_PTR, model, and view.

Referenced by _on_row_expanded().

◆ _application_windows()

static GList * _application_windows ( void  )
static

The application's windows other than the main one: the shape manager, the module order graph, the tag manager, the event supervisor...

Found by asking GTK for every toplevel rather than by naming them: they belong to modules several layers above gui/, and a window added later must show up without this panel learning about it. A window built once and hidden on close – the shape manager, the tag manager – is listed all along and greyed out while closed; one built on demand appears from the first refresh after it is opened.

Returns
the windows sorted by title, since GTK enumerates them in no defined order. The list is the caller's, the windows are not referenced.

Definition at line 918 of file doc_screenshot.c.

References _compare_window_titles(), and _is_application_window().

Referenced by _populate().

◆ _capture_row()

◆ _collect_expanded()

static void _collect_expanded ( GtkTreeView *  view,
GtkTreePath *  path,
gpointer  user_data 
)
static

Collect one expanded row, as the "map expanded rows" callback.

Definition at line 817 of file doc_screenshot.c.

References _label_chain().

Referenced by _populate().

◆ _compare_window_titles()

static gint _compare_window_titles ( gconstpointer  a,
gconstpointer  b 
)
static

Definition at line 900 of file doc_screenshot.c.

Referenced by _application_windows().

◆ _find_row()

static gboolean _find_row ( const char *  chain,
GtkTreeIter *  found 
)
static

Walk a saved label chain back down the rebuilt tree.

Each level is unfolded on the way through, because that is what builds the next one: the children behind a placeholder do not exist until the row is expanded. The last level is deliberately left folded – the caller decides whether it should be expanded, selected, or both.

Returns
TRUE and the iter of the last label, FALSE if the chain no longer resolves (the module was unloaded, the view changed, the widget tree moved under it).

Definition at line 834 of file doc_screenshot.c.

References _g, COL_LABEL, DOC_SCREENSHOT_SEPARATOR, dt_free, FALSE, model, and TRUE.

Referenced by _populate().

◆ _first_text()

static const char * _first_text ( GtkWidget widget)
static

First text found under this widget, or NULL if there is none.

Only a hint, used to tell anonymous containers apart: a row reading GtkBox says nothing, and the tree grows dozens of them; GtkBox: Add to library names the thing the reader is actually looking at. Borrowed from the widget that owns it, so it is copied on sight.

Definition at line 448 of file doc_screenshot.c.

References _first_text(), dt_bauhaus_widget_get_label(), DT_IS_BAUHAUS_WIDGET, and IS_NULL_PTR.

Referenced by _first_text(), and _widget_label().

◆ _is_application_window()

static gboolean _is_application_window ( GtkWindow *  window)
static

Is this toplevel one of the application's own windows, worth a row of its own?

The main window has its row already, and this panel has no business in its own captures. Beyond those two, what a manual illustrates is a window a user opens and reads a title on:

  • a GTK_WINDOW_POPUP is a menu, a tooltip or a combo list, and dies with the gesture that opened it;
  • an untitled toplevel is plumbing – the splash screen, the tagging module's floating entry;
  • a window transient for this panel is this panel's own, the folder chooser's dialog.

Definition at line 891 of file doc_screenshot.c.

References _g, dt_gui_main_window(), IS_NULL_PTR, and window.

Referenced by _application_windows().

◆ _label_chain()

static gchar * _label_chain ( GtkTreePath *  path)
static

Identify a row by the chain of labels from the root down to it.

A refresh rebuilds every row, so a GtkTreePath saved beforehand means nothing afterwards – it is a position in a model that no longer exists. The labels do survive: they are derived from the widgets themselves, and are what the reader was looking at.

Definition at line 789 of file doc_screenshot.c.

References _g, COL_LABEL, DOC_SCREENSHOT_SEPARATOR, dt_free, FALSE, IS_NULL_PTR, and model.

Referenced by _collect_expanded(), and _populate().

◆ _load_pages()

static void _load_pages ( void  )
static

Read the widget-to-page map at the root of the destination folder.

One entry per line, # starts a comment:

Exposure    = content/modules/exposure/exposure.jpg
Left panel  = content/interface/left-panel.png

The key is the row label as the tree displays it; the value is where the illustration lives, relative to the destination folder, extension included – the documentation's own extension, which is what lets its .jpg files be refreshed rather than shadowed.

A missing map is not a failure: the panel then writes PNGs named after the rows.

Definition at line 412 of file doc_screenshot.c.

References _g, DOC_SCREENSHOT_MAP_FILE, dt_free, folder, and IS_NULL_PTR.

Referenced by _populate().

◆ _load_selection()

static void _load_selection ( void  )
static

Read back the selection of the previous run.

Definition at line 151 of file doc_screenshot.c.

References _g, DOC_SCREENSHOT_SELECTION_CONF_KEY, DOC_SCREENSHOT_SEPARATOR, dt_conf_get_string(), dt_free, and IS_NULL_PTR.

Referenced by dt_gui_doc_screenshot_window_show().

◆ _localized_path()

static gchar * _localized_path ( const char *  relative,
const char *  code 
)
static

Insert the language code before the extension: modules/exposure.jpg for "fr" becomes modules/exposure.fr.jpg. The extension is looked for after the last separator, so a dot in a folder name is not mistaken for one.

Definition at line 389 of file doc_screenshot.c.

References extension(), and IS_NULL_PTR.

Referenced by _capture_row().

◆ _on_capture()

static void _on_capture ( GtkButton *  button,
gpointer  user_data 
)
static

◆ _on_destroy()

static void _on_destroy ( GtkWidget widget,
gpointer  user_data 
)
static

Definition at line 1253 of file doc_screenshot.c.

References _g.

Referenced by dt_gui_doc_screenshot_window_show().

◆ _on_row_expanded()

static void _on_row_expanded ( GtkTreeView *  view,
GtkTreeIter *  iter,
GtkTreePath *  path,
gpointer  user_data 
)
static

Replace a row's placeholder by its widget's real children, the first time it is opened.

Definition at line 740 of file doc_screenshot.c.

References _append_row(), _append_tree_rows(), _g, _unwrap(), COL_ROW, COL_TARGET, IS_NULL_PTR, model, and row.

Referenced by dt_gui_doc_screenshot_window_show().

◆ _on_row_selected()

static void _on_row_selected ( GtkTreeSelection *  selection,
gpointer  user_data 
)
static

Draw the selected row's widget into the preview.

This is the answer to "which of these twenty GtkBox rows is the one I want": a name can only go so far on anonymous plumbing, and the picture is unambiguous. It costs one render per selection change, which is what this panel does for a living anyway.

Definition at line 1046 of file doc_screenshot.c.

References _g, _render_target(), COL_ROW, COL_TARGET, DOC_SCREENSHOT_PREVIEW_SIZE, dt_free, height, IS_NULL_PTR, MAX, MIN, model, row, size, and width.

Referenced by dt_gui_doc_screenshot_window_show().

◆ _on_select()

static void _on_select ( GtkButton *  button,
gpointer  user_data 
)
static

Check or uncheck rows: all, none, or exactly the ones the map names. Only rows that are currently built are affected – rows still folded behind a placeholder do not exist yet. The mode arrives as the user data of the three buttons sharing this callback.

Definition at line 1147 of file doc_screenshot.c.

References _g, _save_selection(), _select_row(), and DOC_SCREENSHOT_SELECT_NONE.

Referenced by dt_gui_doc_screenshot_window_show().

◆ _on_toggled()

static void _on_toggled ( GtkCellRendererToggle *  renderer,
gchar *  path_string,
gpointer  user_data 
)
static

Flip one check box. The model owns the state; the renderer only reports the click.

Definition at line 1089 of file doc_screenshot.c.

References _g, _save_selection(), COL_CHECKED, COL_LABEL, dt_free, and FALSE.

Referenced by dt_gui_doc_screenshot_window_show().

◆ _populate()

static void _populate ( GtkWidget widget,
gpointer  user_data 
)
static

Rebuild the tree from the application's own registries, against the current destination.

The top level is the handful of entry points a manual actually starts from – the module lists, the panels, the windows – and everything below is the live widget tree, reached by drilling down. Both routes name a module identically because _widget_label() consults the same map, built here.

Carries the "clicked" signature so the Refresh button and the folder chooser call it directly; the arguments are unused.

Definition at line 940 of file doc_screenshot.c.

References _append_row(), _append_section(), _application_windows(), _collect_expanded(), _find_row(), _g, _label_chain(), _load_pages(), _sources, dt_free, dt_gui_get_ui(), dt_gui_main_window(), dt_ui_center_base(), DT_UI_PANEL_BOTTOM, DT_UI_PANEL_LEFT, DT_UI_PANEL_RIGHT, DT_UI_PANEL_TOP, FALSE, _doc_source_t::fill, IS_NULL_PTR, model, dt_ui_t::panels, _doc_source_t::section, selected, dt_ui_t::top_panel, and window.

Referenced by dt_gui_doc_screenshot_window_show().

◆ _render_area()

static cairo_surface_t * _render_area ( GtkWidget widget,
const GdkRectangle *  area 
)
static

Draw one widget into an offscreen surface, at its on-screen size.

The widget is re-drawn rather than grabbed from the screen: this panel sits on top of the application, and a screen grab would photograph it (and whatever else overlaps). gtk_widget_draw() replays the widget's own draw handlers, children included, at its current allocation, so the file holds exactly what the user sees – occluded or not.

The background of the window holding the widget is painted first because containers mostly declare no background of their own: without it every gap between children comes out transparent. The holding window, not the main one: a widget of the shape manager's panel sits on that panel's background.

Note this deliberately does NOT call gtk_widget_show_all() on the widget first. That is the right move for a widget built offscreen and never displayed; here every target is a live widget inside the main window, and showing it recursively would reveal every child the application deliberately hides – collapsed module bodies, conditional buttons, mask indicators – and would not undo itself once the screenshot is taken.

Parameters
widgetthe widget to draw, already known to be mapped.
areathe part of it to keep, in the widget's own coordinates: its whole allocation for a widget, one row's band for a tree view item.
Returns
the surface, caller-owned.

Definition at line 238 of file doc_screenshot.c.

Referenced by _render_target().

◆ _render_target()

static cairo_surface_t * _render_target ( GtkWidget target,
GtkTreeRowReference *  row 
)
static

Draw what one row of the panel stands for into an offscreen surface.

Parameters
targetthe widget, or the tree view drawing row. Must be mapped: an unmapped one has no meaningful allocation, and a widget destroyed since the row was built is unmapped.
rowthe tree view item to draw, or NULL to draw the whole widget.
Returns
the surface, caller-owned, or NULL when the target is not displayed right now.

Definition at line 309 of file doc_screenshot.c.

References _render_area(), _tree_row_area(), IS_NULL_PTR, and row.

Referenced by _on_row_selected(), and _save_target_as_image().

◆ _save_selection()

static void _save_selection ( void  )
static

Mirror the selection to conf. Called on every change rather than at capture time, so a session that ends without capturing – or crashes – still leaves the work behind.

Definition at line 167 of file doc_screenshot.c.

References _g, DOC_SCREENSHOT_SELECTION_CONF_KEY, DOC_SCREENSHOT_SEPARATOR, dt_conf_set_string(), TRUE, and value.

Referenced by _on_select(), and _on_toggled().

◆ _save_target_as_image()

static int _save_target_as_image ( GtkWidget target,
GtkTreeRowReference *  row,
const char *  filename 
)
static

Render one target into an image file, creating the intermediate directories.

Returns
0 on success, 1 if the target cannot be drawn, 2 if the file cannot be written.

Definition at line 331 of file doc_screenshot.c.

References _render_target(), _write_surface(), directory, dt_free, IS_NULL_PTR, and row.

Referenced by _capture_row().

◆ _select_row()

static gboolean _select_row ( GtkTreeModel *  model,
GtkTreePath *  path,
GtkTreeIter *  iter,
gpointer  user_data 
)
static

◆ _tree_row_area()

static gboolean _tree_row_area ( GtkTreeView *  view,
GtkTreeRowReference *  row,
GdkRectangle *  area 
)
static

Where one item of a tree view is drawn, in the view's own widget coordinates.

The row is the view's whole width, as the view paints it, selection highlight included.

Returns
FALSE when the item is not wholly on screen right now: the view is not mapped, it no longer shows the model the reference was taken in (a list rebuilt into a new store), an ancestor item is collapsed, or the item is scrolled out of sight, even partly – a row cut in half is not an illustration.

Definition at line 269 of file doc_screenshot.c.

References FALSE, row, and view.

Referenced by _append_tree_row(), and _render_target().

◆ _tree_row_text()

static gchar * _tree_row_text ( GtkTreeView *  view,
GtkTreeModel *  model,
GtkTreeIter *  item 
)
static

The text one item of a tree view shows, as the view itself would draw it.

Read from the renderers rather than from the model: a model column may hold an id, a pointer or a sort key, and what a cell displays often comes from a cell data function. The renderers are loaded with this item first, the way the view loads them before painting a row – between two draws they hold whichever row was painted last.

Returns
a newly allocated string, "" when no visible text cell shows anything.

Definition at line 605 of file doc_screenshot.c.

References dt_free, FALSE, IS_NULL_PTR, model, value, and view.

Referenced by _append_tree_row().

◆ _unwrap()

static GtkWidget * _unwrap ( GtkWidget widget)
static

Walk down a chain of single-child containers that carry no identity of their own.

A panel reaches its modules through GtkScrolledWindow > GtkViewport > GtkBox > ..., each holding exactly one child and covering the same pixels as it. One row per link is three rows of noise standing for a single picture. So the row stands for the OUTERMOST widget of the chain – the biggest, the one worth capturing, padding included – while its name and its children are taken from the innermost.

The descent only ever folds away pure layout – boxes, grids, scrolled windows, viewports, overlays – and stops at anything with an identity: a widget the application named (a panel, a module), one carrying its own CSS name from ansel.css, or any other kind of container. Those are things a reader asks for by name, and folding them away would make them unreachable.

Definition at line 481 of file doc_screenshot.c.

References _g, and IS_NULL_PTR.

Referenced by _append_row(), and _on_row_expanded().

◆ _widget_has_text()

static gboolean _widget_has_text ( GtkWidget widget)
static

Does this widget, or anything under it, show text?

A capture of a purely graphical element – an icon button, a colour swatch, a separator – is the same picture in every language, so the language code has no business in its file name: it would scatter identical copies through the documentation tree, one per language.

Conservative by construction: whatever cannot be introspected counts as text. The other way round is the expensive mistake – every language would then write the same file, and only the last one captured would survive.

The icon buttons this mainly exists for are correctly seen as text-free: GtkDarktableButton derives from GtkButton and paints its icon itself, so it owns no label child to find.

Definition at line 360 of file doc_screenshot.c.

References _widget_has_text(), DT_IS_BAUHAUS_WIDGET, FALSE, and TRUE.

Referenced by _capture_row(), and _widget_has_text().

◆ _widget_label()

static gchar * _widget_label ( GtkWidget widget,
const int  index 
)
static

Name one widget for the tree, best source first.

The registry map answers for everything the application knows by name – panels and modules – whichever path the user reached it by. Below that we are walking anonymous toolkit plumbing, where the widget's own text (a label, a button, a bauhaus control) says far more than its type, and the CSS name set by ansel.css says more than nothing. gtk_widget_get_name() falls back to the type name when no name was ever set, which is why it is compared against the type rather than tested for NULL.

Returns
a newly allocated string, never NULL.

Definition at line 519 of file doc_screenshot.c.

References _first_text(), _g, dt_bauhaus_widget_get_label(), DT_IS_BAUHAUS_WIDGET, IS_NULL_PTR, name, and type.

Referenced by _append_row().

◆ _write_surface()

static int _write_surface ( cairo_surface_t *  surface,
const char *  filename 
)
static

Encode the rendered surface, choosing the encoder from the file extension.

PNG goes through cairo: lossless, which is what text-heavy UI screenshots want, and the default for anything the map does not name. Everything else goes through gdk-pixbuf, because a documentation tree that already ships .jpg illustrations has to be refreshable in place – a .png dropped beside them would not replace them.

Returns
0 on success, 2 if the file cannot be written.

Definition at line 194 of file doc_screenshot.c.

References extension(), and IS_NULL_PTR.

Referenced by _save_target_as_image().

◆ dt_gui_doc_screenshot_add_target()

void dt_gui_doc_screenshot_add_target ( void inventory,
GtkWidget widget,
const char *  name 
)

The sink a source calls back into, once per widget. inventory is the section iterator handed to the source; the name is copied into the widget-to-name table the capture and the file naming both read.

Definition at line 722 of file doc_screenshot.c.

References _append_row(), _g, IS_NULL_PTR, and name.

Referenced by _doc_screenshot_iop_modules(), and _doc_screenshot_lib_modules().

◆ dt_gui_doc_screenshot_enable()

void dt_gui_doc_screenshot_enable ( void  )

Announce that --doc was given. Called once by the argument parser, before the GUI is built – the menu is assembled later and reads the flag back.

Definition at line 131 of file doc_screenshot.c.

References _g, and TRUE.

Referenced by dt_init().

◆ dt_gui_doc_screenshot_enabled()

gboolean dt_gui_doc_screenshot_enabled ( void  )

TRUE when --doc was given, i.e. when the capture panel may be offered.

Definition at line 137 of file doc_screenshot.c.

References _g.

Referenced by append_run().

◆ dt_gui_doc_screenshot_register_source()

void dt_gui_doc_screenshot_register_source ( const char *  section,
dt_gui_doc_screenshot_source_t  source 
)

Register a named section of the panel's tree and the callback that fills it. The order of registration is the order the sections appear in. section is copied.

Definition at line 709 of file doc_screenshot.c.

References _sources, _doc_source_t::fill, IS_NULL_PTR, and _doc_source_t::section.

Referenced by dt_init().

◆ dt_gui_doc_screenshot_set_directory()

void dt_gui_doc_screenshot_set_directory ( const char *  path)

Root of the documentation tree to write into, as given after --doc. It pre-fills the panel's destination folder and is where the widget-to-page map is looked for, so a documentation pass is one command away from being ready to capture.

Definition at line 143 of file doc_screenshot.c.

References _g, and dt_free.

Referenced by dt_init().

◆ dt_gui_doc_screenshot_window_show()

void dt_gui_doc_screenshot_window_show ( void  )

Show (or raise) the capture panel: a tree of screenshotable widgets going from the whole window down to a single slider, with a check box on every row, a destination folder and a capture button.

Definition at line 1274 of file doc_screenshot.c.

References _g, _load_selection(), _on_capture(), _on_destroy(), _on_row_expanded(), _on_row_selected(), _on_select(), _on_toggled(), _populate(), COL_CAPTURABLE, COL_CHECKED, COL_COUNT, COL_ENABLED, COL_LABEL, COL_PAGE, DOC_SCREENSHOT_MAP_FILE, DOC_SCREENSHOT_PREVIEW_SIZE, dt_free, dt_gui_main_window(), FALSE, IS_NULL_PTR, pages, tooltip, and TRUE.

Referenced by doc_screenshot_callback().

Variable Documentation

◆ [struct]

◆ _sources

GList* _sources = NULL
static

Definition at line 707 of file doc_screenshot.c.

Referenced by _populate(), and dt_gui_doc_screenshot_register_source().

◆ directory

gchar* directory

documentation root given after –doc, or NULL

Definition at line 115 of file doc_screenshot.c.

Referenced by _save_target_as_image(), dt_check_opendir(), dt_control_merge_hdr_job_run(), dt_film_new(), dt_load_from_string(), and main().

◆ enabled

gboolean enabled

◆ folder

◆ geometry

GtkWidget* geometry

its size, under the preview

Definition at line 111 of file doc_screenshot.c.

Referenced by _brush_events_mouse_moved(), _brush_events_post_expose(), _circle_get_points(), _circle_get_points_source(), _darkroom_pipeline_inputs_ready(), _darkroom_zoom_hash(), _delete_current_layer(), _do_get_structure_quad(), _ellipse_get_points(), _ellipse_get_points_source(), _gradient_draw_shape(), _gradient_get_points(), _gradient_get_pts_border(), _ioporder_rebuild_graph(), _picker_get_module_bounds_image_norm(), _picker_initialize_geometry_raw(), _polygon_events_mouse_moved(), _rename_current_layer_from_gui(), button_pressed(), button_released(), dt_dev_coordinates_image_abs_to_image_norm(), dt_dev_coordinates_image_norm_to_image_abs(), dt_dev_coordinates_image_norm_to_widget(), dt_dev_coordinates_raw_abs_to_raw_norm(), dt_dev_coordinates_raw_norm_to_raw_abs(), dt_dev_coordinates_widget_to_image_norm(), dt_dev_darkroom_pipeline(), dt_dev_geometry_get_processed_size(), dt_dev_geometry_get_raw_size(), dt_dev_geometry_snapshot(), dt_dev_get_processed_size(), dt_dev_get_thumbnail_size(), dt_dev_get_zoom_scale(), dt_dev_processed_size_gui(), dt_dev_roi_request_publish(), dt_drawlayer_ensure_layer_cache(), dt_iop_filmic_rgb_compute_spline(), dt_masks_calculate_source_pos_origin(), dt_masks_set_source_pos_initial_value(), filmic_v3_compute_geometry(), filmic_v3_compute_nodes_from_legacy(), filmic_v3_direct_to_legacy(), filmic_v3_legacy_to_direct(), full_screen_callback(), gui_post_expose(), and mouse_moved().

◆ names

◆ pages

GHashTable* pages

row label -> path of the illustration, relative to the destination

Definition at line 113 of file doc_screenshot.c.

Referenced by dt_cache_arena_calc(), dt_cache_arena_free(), dt_cache_arena_init(), dt_gui_doc_screenshot_window_show(), dt_gui_supervisor_window_show(), dt_pdf_finish(), and write_image().

◆ preview

◆ selected

GHashTable* selected

set of checked row labels, mirrored to conf on every change

Definition at line 114 of file doc_screenshot.c.

Referenced by _add_node(), _add_node(), _add_node(), _add_node(), _add_node(), _area_button_press_callback(), _area_button_press_callback(), _area_button_press_callback(), _area_motion_notify_callback(), _area_motion_notify_callback(), _brush_events_post_expose(), _circle_events_post_expose(), _clamp_marker(), _ellipse_draw_handles(), _ellipse_events_post_expose(), _find_selected_node(), _gradient_slider_add_delta_internal(), _gradient_slider_button_release(), _gradient_slider_key_press_event(), _gradient_slider_scroll_event(), _overlay_report(), _polygon_events_post_expose(), _populate(), _sanity_check(), _sanity_check(), _select_toggled_callback(), _setup_selected_images_list(), _studio_draw_one_sample(), _text_set_all_selected(), _time_hit_test(), _time_overlay_form(), _tree_context_menu(), button_pressed(), dt_collection_hint_message(), dt_draw_arrow(), dt_draw_handle(), dt_draw_node(), dt_draw_shape_lines(), dt_draw_source_shape(), dt_draw_stroke_line(), dt_drawlayer_widgets_draw_brush_profiles(), dt_exif_get_thumbnail(), dt_image_synch_xmp(), dt_iop_basecurve_button_press(), dt_iop_basecurve_motion_notify(), dt_iop_tonecurve_button_press(), dt_iop_tonecurve_motion_notify(), dt_l10n_init(), dt_masks_draw_source(), dt_styles_create_from_list(), dt_thumbnail_update_selection(), dt_thumbtable_select_range(), get_lang(), group_images_callback(), init_tab_general(), key_pressed(), language_callback(), reference_mode_changed_callback(), theme_callback(), and ungroup_images_callback().

◆ status

◆ store

◆ view

GtkWidget* view

the tree view

Definition at line 106 of file doc_screenshot.c.

Referenced by _active_modules_popup(), _add_selected_metadata(), _add_tag_button_clicked(), _append_tree_row(), _append_tree_rows(), _apply_smudge_stroke_mode(), _attached_key_pressed(), _blendop_masks_all_rename_callback(), _brush_runtime_view_from_state(), _click_on_metadata_list(), _click_on_view(), _click_on_view_attached(), _click_on_view_dictionary(), _collect_expanded_cb(), _dictionary_key_pressed(), _dt_ctl_switch_mode_to_by_view(), _ensure_widget_cache(), _estimate_alpha_noise_gain(), _folder_survey_styles_for_import(), _import_discarded_files_popup(), _init_treeview(), _menuitem_preferences(), _needs_recompute(), _pop_menu_dictionary_change_path(), _pop_menu_dictionary_create_tag(), _pop_menu_dictionary_delete_node(), _pop_menu_dictionary_edit_tag(), _pop_menu_dictionary_set_as_tag(), _pop_menu_view(), _prepare_analytic_pixel_context(), _prepare_blur_context(), _preview_button_press(), _row_tooltip_setup(), _sample_alpha_noise_raw(), _select_next_user_attached_tag(), _select_previous_user_attached_tag(), _selected_tagids(), _show_iter_on_view(), _show_keyword_on_view(), _show_tag_on_view(), _switch_to_next_picture(), _switch_to_prev_picture(), _time_overlay_form(), _tree_row_area(), _tree_row_text(), _unselect_all_in_view(), _update_attached_count(), _view_button_pressed(), _view_map_add_location(), _view_map_add_marker(), _view_map_add_pin(), _view_map_add_track(), _view_map_center_on_bbox(), _view_map_center_on_location(), _view_map_check_preference_changed(), _view_map_draw_single_image(), _view_map_location_action(), _view_map_remove_marker(), _view_map_remove_pin(), _view_map_remove_track(), _view_map_set_map_source(), _view_map_set_map_source_g_object(), _view_map_show_osd(), _view_print_settings(), _view_row_activated(), _view_row_expanded(), append_views(), available_in_lighttable_callback(), dt_ctl_switch_mode_to_by_view(), dt_drawlayer_brush_rasterize(), dt_drawlayer_compute_view_patch(), dt_lib_export_metadata_configuration_dialog(), dt_lib_init_module(), dt_lib_is_visible_in_view(), dt_lib_load_module(), dt_lib_unload_module(), dt_view_manager_gui_init(), dt_view_unload_module(), export_image_list_callback(), gui_init(), gui_post_expose(), and row_activated().

◆ window

GtkWidget* window

Definition at line 105 of file doc_screenshot.c.

Referenced by _activate_callback_to_action_callback(), _control_set_cursor_on_widget(), _darkroom_edge_pan_tick(), _extract_pointer_input(), _gui_styles_dialog_run(), _gui_styles_edit_style_response(), _gui_styles_new_style_response(), _hm_ask_user_constraints_choice(), _hm_show_merge_report_popup(), _hm_show_toposort_cycle_popup(), _hm_warn_missing_raster_producers(), _ioporder_init_popup(), _ioporder_rebuild_graph(), _is_application_window(), _lib_tagging_tag_show_accel(), _menuitem_delete_preset(), _menuitem_update_preset(), _modulegroups_drag_begin(), _panel_handle_resize(), _populate(), _popup_coordinates(), _queue_action_from_shortcut(), _recovery_reaches_the_plan_without_a_jump(), _recovery_waits_under_the_mark(), _sample_axis_from_device_state(), _sample_raw_segment_cubic_param(), _sample_tablet_state_from_devices(), _shape_manager_popup_position_is_usable(), _view_surface_commit_main(), dt_accels_search(), dt_bauhaus_init(), dt_bauhaus_show_popup(), dt_colorspaces_set_display_profile(), dt_control_button_down(), dt_display_profile_read(), dt_drawlayer_paint_rasterize_segment_to_buffer(), dt_gui_hist_dialog_new(), dt_gui_merge_options_dialog(), dt_gui_show_standalone_string_dialog(), dt_gui_show_standalone_three_choice_dialog(), dt_gui_show_standalone_yes_no_dialog(), dt_key_modifier_state(), dt_osx_disable_fullscreen(), edit_preset(), enter(), full_screen_callback(), main_gui(), menuitem_delete_preset(), menuitem_update_preset(), and wavelet_denoise().