Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Gimp/app/propgui/   (Gimp Bildeditor Version 3.2.0©)  Datei vom 14.2.2026 mit Größe 24 kB image not shown  

Quelle  gimppropgui.c   Sprache: C

 

/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
 *
 * gimppropgui.c
 * Copyright (C) 2002-2017  Michael Natterer <mitch@gimp.org>
 *                          Sven Neumann <sven@gimp.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


#include "config.h"

#include <string.h>

#include <gegl.h>
#include <gegl-paramspecs.h>
#include <gtk/gtk.h>

#include "libgimpcolor/gimpcolor.h"
#include "libgimpconfig/gimpconfig.h"
#include "libgimpwidgets/gimpwidgets.h"

#include "propgui-types.h"

#include "gegl/gimp-gegl-utils.h"

#include "operations/gimp-operation-config.h"

#include "core/gimpcontext.h"

#include "widgets/gimpcolorpanel.h"
#include "widgets/gimpmessagebox.h"
#include "widgets/gimppropwidgets.h"

#include "gimppropgui.h"
#include "gimppropgui-channel-mixer.h"
#include "gimppropgui-color-balance.h"
#include "gimppropgui-color-rotate.h"
#include "gimppropgui-color-to-alpha.h"
#include "gimppropgui-convolution-matrix.h"
#include "gimppropgui-diffraction-patterns.h"
#include "gimppropgui-eval.h"
#include "gimppropgui-focus-blur.h"
#include "gimppropgui-generic.h"
#include "gimppropgui-hue-saturation.h"
#include "gimppropgui-motion-blur-circular.h"
#include "gimppropgui-motion-blur-linear.h"
#include "gimppropgui-motion-blur-zoom.h"
#include "gimppropgui-newsprint.h"
#include "gimppropgui-panorama-projection.h"
#include "gimppropgui-recursive-transform.h"
#include "gimppropgui-shadows-highlights.h"
#include "gimppropgui-spiral.h"
#include "gimppropgui-supernova.h"
#include "gimppropgui-utils.h"
#include "gimppropgui-vignette.h"

#include "gimp-intl.h"


#define HAS_KEY(p,k,v) gimp_gegl_param_spec_has_key (p, k, v)


static gboolean      gimp_prop_string_to_boolean       (GBinding       *binding,
                                                        const GValue   *from_value,
                                                        GValue         *to_value,
                                                        gpointer        user_data);
static void          gimp_prop_config_notify           (GObject        *config,
                                                        GParamSpec     *pspec,
                                                        GtkWidget      *widget);
static void          gimp_prop_widget_show             (GtkWidget      *widget,
                                                        GObject        *config);
static void          gimp_prop_free_label_ref          (GWeakRef       *label_ref);

/*  public functions  */

GtkWidget *
gimp_prop_widget_new (GObject                  *config,
                      const gchar              *property_name,
                      GeglRectangle            *area,
                      GimpContext              *context,
                      GimpCreatePickerFunc      create_picker_func,
                      GimpCreateControllerFunc  create_controller_func,
                      gpointer                  creator,
                      const gchar             **label)
{
  GParamSpec *pspec;

  g_return_val_if_fail (G_IS_OBJECT (config), NULL);

  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
                                        property_name);

  return gimp_prop_widget_new_from_pspec (config, pspec, area, context,
                                          create_picker_func,
                                          create_controller_func,
                                          creator,
                                          label);
}

GtkWidget *
gimp_prop_widget_new_from_pspec (GObject                  *config,
                                 GParamSpec               *pspec,
                                 GeglRectangle            *area,
                                 GimpContext              *context,
                                 GimpCreatePickerFunc      create_picker_func,
                                 GimpCreateControllerFunc  create_controller_func,
                                 gpointer                  creator,
                                 const gchar             **label)
{
  GtkWidget *widget = NULL;

  g_return_val_if_fail (G_IS_OBJECT (config), NULL);
  g_return_val_if_fail (pspec != NULL, NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (label != NULL, NULL);

  *label = NULL;

  if (GEGL_IS_PARAM_SPEC_SEED (pspec))
    {
      widget = gimp_prop_random_seed_new (config, pspec->name);

      *label = g_param_spec_get_nick (pspec);
    }
  else if (G_IS_PARAM_SPEC_INT (pspec)   ||
           G_IS_PARAM_SPEC_UINT (pspec)  ||
           G_IS_PARAM_SPEC_FLOAT (pspec) ||
           G_IS_PARAM_SPEC_DOUBLE (pspec))
    {
      gdouble lower;
      gdouble upper;
      gdouble step;
      gdouble page;
      gint    digits;

      if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
        {
          GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);

          lower  = gspec->ui_minimum;
          upper  = gspec->ui_maximum;
          step   = gspec->ui_step_small;
          page   = gspec->ui_step_big;
          digits = gspec->ui_digits;
        }
      else if (GEGL_IS_PARAM_SPEC_INT (pspec))
        {
          GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);

          lower  = gspec->ui_minimum;
          upper  = gspec->ui_maximum;
          step   = gspec->ui_step_small;
          page   = gspec->ui_step_big;
          digits = 0;
        }
      else
        {
          gdouble value;

          /* Get the min and max for the given property. */
          _gimp_prop_widgets_get_numeric_values (config, pspec,
                                                 &value, &lower, &upper,
                                                 G_STRFUNC);

          if ((upper - lower <= 1.0) &&
              (G_IS_PARAM_SPEC_FLOAT (pspec) ||
               G_IS_PARAM_SPEC_DOUBLE (pspec)))
            {
              step   = 0.01;
              page   = 0.1;
              digits = 4;
            }
          else if ((upper - lower <= 10.0) &&
                   (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                    G_IS_PARAM_SPEC_DOUBLE (pspec)))
            {
              step   = 0.1;
              page   = 1.0;
              digits = 3;
            }
          else
            {
              step   = 1.0;
              page   = 10.0;
              digits = (G_IS_PARAM_SPEC_FLOAT (pspec) ||
                        G_IS_PARAM_SPEC_DOUBLE (pspec)) ? 2 : 0;
            }
        }

      widget = gimp_prop_spin_scale_new (config, pspec->name,
                                         step, page, digits);

      if (HAS_KEY (pspec, "unit", "degree") &&
          (upper - lower) == 360.0)
        {
          GtkWidget *hbox;
          GtkWidget *dial;

          gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE);

          hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
          gtk_widget_show (widget);

          dial = gimp_prop_angle_dial_new (config, pspec->name);
          g_object_set (dial,
                        "clockwise-angles", HAS_KEY (pspec, "direction", "cw"),
                        NULL);
          gtk_box_pack_start (GTK_BOX (hbox), dial, FALSE, FALSE, 0);
          gtk_widget_show (dial);

          gimp_help_set_help_data (hbox, g_param_spec_get_blurb (pspec), NULL);
          gimp_prop_gui_bind_label (hbox, widget);

          widget = hbox;
        }
      else if (HAS_KEY (pspec, "unit", "kelvin"))
        {
          GtkWidget *hbox;
          GtkWidget *button;

          hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

          gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
          gtk_widget_show (widget);

          button = gimp_prop_kelvin_presets_new (config, pspec->name);
          gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
          gtk_widget_show (button);

          gimp_help_set_help_data (hbox, g_param_spec_get_blurb (pspec), NULL);
          gimp_prop_gui_bind_label (hbox, widget);

          widget = hbox;
        }
      else
        {
          gimp_prop_gui_bind_label (widget, widget);

          if (area &&
              (HAS_KEY (pspec, "unit", "pixel-coordinate") ||
               HAS_KEY (pspec, "unit", "pixel-distance")) &&
              (HAS_KEY (pspec, "axis", "x") ||
               HAS_KEY (pspec, "axis", "y")))
            {
              gdouble min = lower;
              gdouble max = upper;

              if (HAS_KEY (pspec, "unit", "pixel-coordinate"))
                {
                  /* limit pixel coordinate scales to the actual area */

                  gint off_x = area->x;
                  gint off_y = area->y;

                  if (HAS_KEY (pspec, "axis", "x"))
                    {
                      min = MAX (lower, off_x);
                      max = MIN (upper, off_x + area->width);
                    }
                  else if (HAS_KEY (pspec, "axis","y"))
                    {
                      min = MAX (lower, off_y);
                      max = MIN (upper, off_y + area->height);
                    }
                }
              else if (HAS_KEY (pspec, "unit", "pixel-distance"))
                {
                  /* limit pixel distance scales to the same value on the
                   * x and y axes, so linked values have the same range,
                   * we use MAX (width, height), see issue #2540
                   */


                  max = MIN (upper, MAX (area->width, area->height));
                }

              gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (widget),
                                                min, max);
            }
        }
    }
  else if (G_IS_PARAM_SPEC_STRING (pspec))
    {
      *label = g_param_spec_get_nick (pspec);

      if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (pspec))
        {
          widget =
            gimp_prop_file_chooser_button_new (config, pspec->name,
                                               g_param_spec_get_nick (pspec),
                                               GTK_FILE_CHOOSER_ACTION_OPEN);
        }
      else if (HAS_KEY (pspec, "multiline", "true"))
        {
          GtkTextBuffer *buffer;
          GtkWidget     *view;

          buffer = gimp_prop_text_buffer_new (config, pspec->name, -1);
          view = gtk_text_view_new_with_buffer (buffer);
          g_object_unref (buffer);

          widget = gtk_scrolled_window_new (NULL, NULL);
          gtk_widget_set_size_request (widget, -1, 150);
          gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget),
                                               GTK_SHADOW_IN);
          gtk_container_add (GTK_CONTAINER (widget), view);
          gtk_widget_show (view);
        }
      else if (HAS_KEY (pspec, "error", "true"))
        {
          GtkWidget *l;

          widget = gimp_message_box_new (GIMP_ICON_WILBER_EEK);
          gimp_message_box_set_primary_text (GIMP_MESSAGE_BOX (widget), "%s",
                                             *label);
          gimp_message_box_set_text (GIMP_MESSAGE_BOX (widget), "%s", "");

          l = GIMP_MESSAGE_BOX (widget)->label[1];

          g_object_bind_property (config, pspec->name,
                                  l,  "label",
                                  G_BINDING_SYNC_CREATE);
          g_object_bind_property_full (config, pspec->name,
                                       widget, "visible",
                                       G_BINDING_SYNC_CREATE,
                                       gimp_prop_string_to_boolean,
                                       NULL,
                                       NULL, NULL);
          *label = NULL;
        }
      else
        {
          widget = gimp_prop_entry_new (config, pspec->name, -1);
        }

    }
  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
    {
      widget = gimp_prop_check_button_new (config, pspec->name,
                                           g_param_spec_get_nick (pspec));

      gimp_prop_gui_bind_label (widget, widget);
    }
  else if (G_IS_PARAM_SPEC_ENUM (pspec))
    {
      widget = gimp_prop_enum_combo_box_new (config, pspec->name, 0, 0);
      gimp_int_combo_box_set_label (GIMP_INT_COMBO_BOX (widget),
                                    g_param_spec_get_nick (pspec));

      gimp_prop_gui_bind_label (widget, widget);
    }
  else if (GIMP_IS_PARAM_SPEC_COLOR (pspec))
    {
      gboolean   has_alpha;
      GtkWidget *button;

      has_alpha = gimp_param_spec_color_has_alpha (pspec);

      widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);

      button = gimp_prop_color_button_new (config, pspec->name,
                                           g_param_spec_get_nick (pspec),
                                           FALSE, 128, 24,
                                           has_alpha ?
                                           GIMP_COLOR_AREA_SMALL_CHECKS :
                                           GIMP_COLOR_AREA_FLAT);
      gimp_color_button_set_update (GIMP_COLOR_BUTTON (button), TRUE);
      gimp_color_panel_set_context (GIMP_COLOR_PANEL (button), context);
      gtk_box_pack_start (GTK_BOX (widget), button, TRUE, TRUE, 0);
      gtk_widget_show (button);

      gimp_prop_gui_bind_tooltip (button, widget);

      if (create_picker_func)
        {
          button = create_picker_func (creator,
                                       pspec->name,
                                       GIMP_ICON_COLOR_PICKER_GRAY,
                                       _("Pick color from the image"),
                                       /* pick_abyss = */ FALSE,
                                       NULL, NULL);
          gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
          gtk_widget_show (button);
        }

      *label = g_param_spec_get_nick (pspec);
    }
  else
    {
      g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
                 g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
    }

  /* if we have any keys for dynamic properties, listen to config's notify
   * signal, and update the properties accordingly.
   */

  if (gegl_param_spec_get_property_key (pspec, "sensitive") ||
      gegl_param_spec_get_property_key (pspec, "visible")   ||
      gegl_param_spec_get_property_key (pspec, "label")     ||
      gegl_param_spec_get_property_key (pspec, "description"))
    {
      g_object_set_data (G_OBJECT (widget), "gimp-prop-pspec", pspec);

      g_signal_connect_object (config, "notify",
                               G_CALLBACK (gimp_prop_config_notify),
                               widget, 0);

      if (gegl_param_spec_get_property_key (pspec, "visible"))
        {
          /* a bit of a hack: if we have a dynamic "visible" property key,
           * connect to the widget's "show" signal, so that we can intercept
           * our caller's gtk_widget_show() call, and keep the widget hidden if
           * necessary.
           */

          g_signal_connect (widget, "show",
                            G_CALLBACK (gimp_prop_widget_show),
                            config);
        }

      /* update all the properties now */
      gimp_prop_config_notify (config, NULL, widget);
    }

  gtk_widget_show (widget);

  return widget;
}


typedef GtkWidget * (* GimpPropGuiNewFunc) (GObject                  *config,
                                            GParamSpec              **param_specs,
                                            guint                     n_param_specs,
                                            GeglRectangle            *area,
                                            GimpContext              *context,
                                            GimpCreatePickerFunc      create_picker_func,
                                            GimpCreateControllerFunc  create_controller_func,
                                            gpointer                  creator);

static const struct
{
  const gchar        *config_type;
  GimpPropGuiNewFunc  gui_new_func;
}
gui_new_funcs[] =
{
  { "GimpColorBalanceConfig",
    _gimp_prop_gui_new_color_balance },
  { "GimpHueSaturationConfig",
    _gimp_prop_gui_new_hue_saturation },
  { "GimpGegl-gegl-color-rotate-config",
    _gimp_prop_gui_new_color_rotate },
  { "GimpGegl-gegl-color-to-alpha-config",
    _gimp_prop_gui_new_color_to_alpha },
  { "GimpGegl-gegl-convolution-matrix-config",
    _gimp_prop_gui_new_convolution_matrix },
  { "GimpGegl-gegl-channel-mixer-config",
    _gimp_prop_gui_new_channel_mixer },
  { "GimpGegl-gegl-diffraction-patterns-config",
    _gimp_prop_gui_new_diffraction_patterns },
  { "GimpGegl-gegl-focus-blur-config",
    _gimp_prop_gui_new_focus_blur },
  { "GimpGegl-gegl-motion-blur-circular-config",
    _gimp_prop_gui_new_motion_blur_circular },
  { "GimpGegl-gegl-motion-blur-linear-config",
    _gimp_prop_gui_new_motion_blur_linear },
  { "GimpGegl-gegl-motion-blur-zoom-config",
    _gimp_prop_gui_new_motion_blur_zoom },
  { "GimpGegl-gegl-newsprint-config",
    _gimp_prop_gui_new_newsprint },
  { "GimpGegl-gegl-panorama-projection-config",
    _gimp_prop_gui_new_panorama_projection },
  { "GimpGegl-gegl-recursive-transform-config",
    _gimp_prop_gui_new_recursive_transform },
  { "GimpGegl-gegl-shadows-highlights-config",
    _gimp_prop_gui_new_shadows_highlights },
  { "GimpGegl-gegl-spiral-config",
    _gimp_prop_gui_new_spiral },
  { "GimpGegl-gegl-supernova-config",
    _gimp_prop_gui_new_supernova },
  { "GimpGegl-gegl-vignette-config",
    _gimp_prop_gui_new_vignette },
  { NULL,
    _gimp_prop_gui_new_generic }
};


GtkWidget *
gimp_prop_gui_new (GObject                  *config,
                   GType                     owner_type,
                   GParamFlags               flags,
                   GeglRectangle            *area,
                   GimpContext              *context,
                   GimpCreatePickerFunc      create_picker_func,
                   GimpCreateControllerFunc  create_controller_func,
                   gpointer                  creator)
{
  GtkWidget    *gui = NULL;
  GParamSpec  **param_specs;
  guint         n_param_specs;

  g_return_val_if_fail (G_IS_OBJECT (config), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);

  param_specs = gimp_operation_config_list_properties (config,
                                                       owner_type, flags,
                                                       &n_param_specs);

  if (param_specs)
    {
      const gchar *config_type_name = G_OBJECT_TYPE_NAME (config);
      gint         i;

      for (i = 0; i < G_N_ELEMENTS (gui_new_funcs); i++)
        {
          if (! gui_new_funcs[i].config_type ||
              ! strcmp (gui_new_funcs[i].config_type, config_type_name))
            {
              g_printerr ("GUI new func match: %s\n",
                          gui_new_funcs[i].config_type ?
                          gui_new_funcs[i].config_type : "generic fallback");

              gui = gui_new_funcs[i].gui_new_func (config,
                                                   param_specs, n_param_specs,
                                                   area,
                                                   context,
                                                   create_picker_func,
                                                   create_controller_func,
                                                   creator);
              break;
            }
        }

      g_free (param_specs);
    }
  else
    {
      gui = gtk_label_new (_("This operation has no editable properties"));
      gimp_label_set_attributes (GTK_LABEL (gui),
                                 PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
                                 -1);
      g_object_set (gui,
                    "margin-top",    4,
                    "margin-bottom", 4,
                    NULL);
    }

  gtk_widget_show (gui);

  return gui;
}

void
gimp_prop_gui_bind_container (GtkWidget *source,
                              GtkWidget *target)
{
  g_object_bind_property (source, "sensitive",
                          target, "sensitive",
                          G_BINDING_SYNC_CREATE);
  g_object_bind_property (source, "visible",
                          target, "visible",
                          G_BINDING_SYNC_CREATE);
}

void
gimp_prop_gui_bind_label (GtkWidget *source,
                          GtkWidget *target)
{
  GWeakRef    *label_ref;
  const gchar *label;

  /* we want to update "target"'s "label" property whenever the label
   * expression associated with "source" is reevaluated, however, "source"
   * might not itself have a "label" property we can bind to.  just keep around
   * a reference to "target", and update its label manually.
   */

  g_return_if_fail (g_object_get_data (G_OBJECT (source),
                                       "gimp-prop-label-ref") == NULL);

  label_ref = g_slice_new (GWeakRef);

  g_weak_ref_init (label_ref, target);

  g_object_set_data_full (G_OBJECT (source),
                          "gimp-prop-label-ref", label_ref,
                          (GDestroyNotify) gimp_prop_free_label_ref);

  label = g_object_get_data (G_OBJECT (source), "gimp-prop-label");

  if (label)
    g_object_set (target, "label", label, NULL);

  /* note that "source" might be its own label widget, in which case there's no
   * need to bind the rest of the properties.
   */

  if (source != target)
    gimp_prop_gui_bind_tooltip (source, target);
}

void
gimp_prop_gui_bind_tooltip (GtkWidget *source,
                            GtkWidget *target)
{
  g_object_bind_property (source, "tooltip-text",
                          target, "tooltip-text",
                          G_BINDING_SYNC_CREATE);
}


/*  private functions  */

static gboolean
gimp_prop_string_to_boolean (GBinding     *binding,
                             const GValue *from_value,
                             GValue       *to_value,
                             gpointer      user_data)
{
  const gchar *string = g_value_get_string (from_value);

  g_value_set_boolean (to_value, string && *string);

  return TRUE;
}

static void
gimp_prop_config_notify (GObject    *config,
                         GParamSpec *pspec,
                         GtkWidget  *widget)
{
  GParamSpec *widget_pspec;
  GWeakRef   *label_ref;
  GtkWidget  *label_widget;
  gboolean    sensitive;
  gboolean    visible;
  gchar      *label;
  gchar      *description;

  widget_pspec = g_object_get_data (G_OBJECT (widget), "gimp-prop-pspec");
  label_ref    = g_object_get_data (G_OBJECT (widget), "gimp-prop-label-ref");

  if (label_ref)
    label_widget = g_weak_ref_get (label_ref);
  else
    label_widget = NULL;

  sensitive   = gimp_prop_eval_boolean (config, widget_pspec, "sensitive", TRUE);
  visible     = gimp_prop_eval_boolean (config, widget_pspec, "visible", TRUE);
  label       = gimp_prop_eval_string (config, widget_pspec, "label",
                                       g_param_spec_get_nick (widget_pspec));
  description = gimp_prop_eval_string (config, widget_pspec, "description",
                                       g_param_spec_get_blurb (widget_pspec));

  /* we store the label in (and pass ownership over it to) the widget's
   * "gimp-prop-label" key, so that we can use it to initialize the label
   * widget's label in gimp_prop_gui_bind_label() upon binding.
   */

  g_object_set_data_full (G_OBJECT (widget), "gimp-prop-label", label, g_free);

  g_signal_handlers_block_by_func (widget,
                                   gimp_prop_widget_show, config);

  gtk_widget_set_sensitive (widget, sensitive);
  gtk_widget_set_visible (widget, visible);
  if (label_widget) g_object_set (label_widget, "label", label, NULL);
  gimp_help_set_help_data (widget, description, NULL);

  g_signal_handlers_unblock_by_func (widget,
                                     gimp_prop_widget_show, config);

  g_free (description);

  if (label_widget)
    g_object_unref (label_widget);
}

static void
gimp_prop_widget_show (GtkWidget *widget,
                       GObject   *config)
{
  GParamSpec *widget_pspec;
  gboolean    visible;

  widget_pspec = g_object_get_data (G_OBJECT (widget), "gimp-prop-pspec");

  visible = gimp_prop_eval_boolean (config, widget_pspec, "visible", TRUE);

  gtk_widget_set_visible (widget, visible);
}

static void
gimp_prop_free_label_ref (GWeakRef *label_ref)
{
  g_weak_ref_clear (label_ref);

  g_slice_free (GWeakRef, label_ref);
}

Messung
CHZG
849610093

¤ Dauer der Verarbeitung: 0.4 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.