예제 #1
0
static GwyContainer*
gwyfile_load(const gchar *filename)
{
    GObject *object, *dfield;
    GError *err = NULL;
    guchar *buffer = NULL;
    gsize size = 0;
    gsize pos = 0;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        g_warning("Cannot read file %s", filename);
        g_clear_error(&err);
        return NULL;
    }
    if (size < MAGIC_SIZE
        || (memcmp(buffer, MAGIC, MAGIC_SIZE)
            && memcmp(buffer, MAGIC2, MAGIC_SIZE))) {
        g_warning("File %s doesn't seem to be a .gwy file", filename);
        if (!gwy_file_abandon_contents(buffer, size, &err)) {
            g_critical("%s", err->message);
            g_clear_error(&err);
        }
        return NULL;
    }

    if (!memcmp(buffer, MAGIC, MAGIC_SIZE))
        object = gwy_serializable_deserialize(buffer + MAGIC_SIZE,
                                              size - MAGIC_SIZE, &pos);
    else
        object = gwy_container_deserialize2(buffer + MAGIC_SIZE,
                                            size - MAGIC_SIZE, &pos);

    if (!gwy_file_abandon_contents(buffer, size, &err)) {
        g_critical("%s", err->message);
        g_clear_error(&err);
    }
    if (!object) {
        g_warning("File %s deserialization failed", filename);
        return NULL;
    }
    if (!GWY_IS_CONTAINER(object)) {
        g_warning("File %s contains some strange object", filename);
        g_object_unref(object);
        return NULL;
    }
    dfield = gwy_container_get_object_by_name(GWY_CONTAINER(object), "/0/data");
    if (!dfield || !GWY_IS_DATA_FIELD(dfield)) {
        g_warning("File %s contains no data field", filename);
        g_object_unref(object);
        return NULL;
    }

    return (GwyContainer*)object;
}
예제 #2
0
static GwyContainer*
gwyfile_load(const gchar *filename,
             G_GNUC_UNUSED GwyRunType mode,
             GError **error)
{
    GObject *object;
    GError *err = NULL;
    guchar *buffer = NULL;
    gsize size = 0;
    gsize pos = 0;

    if (!gwy_file_get_contents(filename, &buffer, &size, &err)) {
        err_GET_FILE_CONTENTS(error, &err);
        return NULL;
    }
    if (size < MAGIC_SIZE
        || (memcmp(buffer, MAGIC, MAGIC_SIZE)
            && memcmp(buffer, MAGIC2, MAGIC_SIZE))) {
        err_FILE_TYPE(error, "Gwyddion");
        gwy_file_abandon_contents(buffer, size, &err);
        return NULL;
    }

    if (!memcmp(buffer, MAGIC, MAGIC_SIZE)) {
        object = gwy_container_deserialize_old(buffer + MAGIC_SIZE,
                                               size - MAGIC_SIZE, &pos);
        gwyfile_remove_old_data(object);
    }
    else
        object = gwy_serializable_deserialize(buffer + MAGIC_SIZE,
                                              size - MAGIC_SIZE, &pos);

    gwy_file_abandon_contents(buffer, size, &err);
    if (!object) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Data deserialization failed."));
        return NULL;
    }
    if (!GWY_IS_CONTAINER(object)) {
        g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA,
                    _("Data deserialization succeeded, but resulted in "
                      "an unexpected object %s."),
                    g_type_name(G_TYPE_FROM_INSTANCE(object)));
        g_object_unref(object);
        return NULL;
    }
    gwyfile_pack_metadata(GWY_CONTAINER(object));

    return GWY_CONTAINER(object);
}
예제 #3
0
/**
 * gwy_app_recent_file_list_update:
 * @data: A data container corresponding to the file.
 * @filename_utf8: A recent file to insert or move to the first position in
 *                 document history, in UTF-8.
 * @filename_sys: A recent file to insert or move to the first position in
 *                 document history, in GLib encoding.
 * @hint: Preferred channel id to use for thumbnail, pass 0 if no channel
 *        is specificaly preferred.
 *
 * Moves @filename_utf8 to the first position in document history, possibly
 * adding it if not present yet.
 *
 * At least one of @filename_utf8, @filename_sys should be set.
 **/
void
gwy_app_recent_file_list_update(GwyContainer *data,
                                const gchar *filename_utf8,
                                const gchar *filename_sys,
                                gint hint)
{
    gboolean free_utf8 = FALSE, free_sys = FALSE;;

    g_return_if_fail(!data || GWY_IS_CONTAINER(data));

    if (!gcontrols.store)
        return;

    if (!filename_utf8 && filename_sys) {
        filename_utf8 = g_filename_to_utf8(filename_sys, -1,
                                           NULL, NULL, NULL);
        free_utf8 = TRUE;
    }

    if (!filename_sys && filename_utf8) {
        filename_sys = g_filename_from_utf8(filename_utf8, -1,
                                            NULL, NULL, NULL);
        free_sys = TRUE;
    }

    if (filename_utf8) {
        GtkTreeIter iter;
        GwyRecentFile *rf;

        if (gwy_app_recent_file_find(filename_utf8, &iter, &rf))
            gtk_list_store_move_after(gcontrols.store, &iter, NULL);
        else {
            rf = gwy_app_recent_file_new(gwy_canonicalize_path(filename_utf8),
                                         gwy_canonicalize_path(filename_sys));
            gtk_list_store_prepend(gcontrols.store, &iter);
            gtk_list_store_set(gcontrols.store, &iter, FILELIST_RAW, rf, -1);
        }

        if (data)
            gwy_recent_file_update_thumbnail(rf, data, hint, NULL);
    }

    if (free_utf8)
        g_free((gpointer)filename_utf8);
    if (free_sys)
        g_free((gpointer)filename_sys);

    gwy_app_recent_file_list_update_menu(&gcontrols);
}
예제 #4
0
/**
 * gwy_data_view_new:
 * @data: A #GwyContainer containing the data to display.
 *
 * Creates a new data-displaying widget for @data.
 *
 * A newly created #GwyDataView doesn't display anything.  You have to add
 * some layers to it, at least a base layer with
 * gwy_data_view_set_base_layer(), and possibly others with
 * gwy_data_view_set_alpha_layer() and gwy_data_view_set_top_layer().
 *
 * The top layer is special. It must be a vector layer and can receive
 * mouse and keyboard events.
 *
 * The base layer it also special. It must be always present, and must not be
 * transparent or vector.
 *
 * Returns: A newly created data view as a #GtkWidget.
 **/
GtkWidget*
gwy_data_view_new(GwyContainer *data)
{
    GtkWidget *data_view;

    gwy_debug(" ");
    g_return_val_if_fail(GWY_IS_CONTAINER(data), NULL);

    data_view = gtk_widget_new(GWY_TYPE_DATA_VIEW, NULL);

    g_object_ref(data);
    GWY_DATA_VIEW(data_view)->data = data;

    return data_view;
}
예제 #5
0
/**
 * gwy_set_data_preview_size:
 * @data_view: A data view used for module preview.
 * @max_size: Maximum allowed @data_view size (width and height).
 *
 * Sets up data view zoom to not exceed specified size.
 *
 * Before calling this function, data keys have be set, data fields and layers
 * have to be present and physically square mode set in the container.
 * Sizing of both pixel-wise square and physically square displays is performed
 * correctly.
 *
 * Since: 2.7
 **/
void
gwy_set_data_preview_size(GwyDataView *data_view,
                          gint max_size)
{
    GwyContainer *container;
    GwyDataField *data_field;
    GwyPixmapLayer *layer;
    gdouble zoomval, scale, xreal, yreal;
    gboolean realsquare;
    gint xres, yres;
    const gchar *prefix;
    gchar *key;

    g_return_if_fail(GWY_IS_DATA_VIEW(data_view));
    g_return_if_fail(max_size >= 2);

    container = gwy_data_view_get_data(data_view);
    g_return_if_fail(GWY_IS_CONTAINER(container));

    layer = gwy_data_view_get_base_layer(data_view);
    g_return_if_fail(GWY_IS_PIXMAP_LAYER(layer));
    prefix = gwy_pixmap_layer_get_data_key(layer);
    g_return_if_fail(prefix);

    data_field = gwy_container_get_object_by_name(container, prefix);
    g_return_if_fail(GWY_IS_DATA_FIELD(data_field));

    prefix = gwy_data_view_get_data_prefix(data_view);
    g_return_if_fail(prefix);
    key = g_strconcat(prefix, "/realsquare", NULL);
    realsquare = FALSE;
    gwy_container_gis_boolean_by_name(container, key, &realsquare);
    g_free(key);

    xres = gwy_data_field_get_xres(data_field);
    yres = gwy_data_field_get_yres(data_field);
    if (!realsquare)
        zoomval = max_size/(gdouble)MAX(xres, yres);
    else {
        xreal = gwy_data_field_get_xreal(data_field);
        yreal = gwy_data_field_get_yreal(data_field);
        scale = MAX(xres/xreal, yres/yreal);
        zoomval = max_size/(scale*MAX(xreal, yreal));
    }
    gwy_data_view_set_zoom(data_view, zoomval);
}
예제 #6
0
/**
 * gwy_app_add_graph_or_curves:
 * @gmodel: A graph model with curves to add.
 * @data: Data container where the graph would be added.
 * @target_graph: Graph where curves would be added.
 * @colorstep: Curve block size as in gwy_graph_model_append_curves().
 *
 * Puts the curves of a graph to another graph if possible, or adds the graph
 * as new.
 *
 * If the units of @gmodel are compatible with the units of the graph
 * identified by @target_graph the curves are copied to the target graph with
 * gwy_graph_model_append_curves().
 *
 * In all other cases, including when @target_graph does not refer to any
 * existing graph, the graph model is added to @data as a new graph.
 *
 * Either way, the caller usually need to release its own reference afterwards.
 *
 * This function is useful particularly in modules that create graphs and can
 * be run non-interactively.
 *
 * Returns: The numerical identifier of the newly-created graph of one was
 *          created.  Value -1 is returned if curves were added to
 *          @target_graph.
 *
 * Since: 2.41
 **/
gint
gwy_app_add_graph_or_curves(GwyGraphModel *gmodel,
                            GwyContainer *data,
                            const GwyAppDataId *target_graph,
                            gint colorstep)
{
    GwyAppDataId tgtgraph = *target_graph;

    if (gwy_app_data_id_verify_graph(&tgtgraph)) {
        GQuark quark = gwy_app_get_graph_key_for_id(tgtgraph.id);
        GwyContainer *data2 = gwy_app_data_browser_get(tgtgraph.datano);
        GwyGraphModel *target_gmodel = gwy_container_get_object(data2, quark);

        g_return_val_if_fail(GWY_IS_GRAPH_MODEL(target_gmodel), -1);
        if (gwy_graph_model_units_are_compatible(gmodel, target_gmodel)) {
            gwy_graph_model_append_curves(target_gmodel, gmodel, colorstep);
            return -1;
        }
    }
    g_return_val_if_fail(GWY_IS_CONTAINER(data), FALSE);
    return gwy_app_data_browser_add_graph_model(gmodel, data, TRUE);
}
예제 #7
0
static void
gwyfile_remove_old_data(GObject *object)
{
    GwyContainer *data;
    GwySelection *rect, *point, *line;

    if (!object || !GWY_IS_CONTAINER(object))
        return;

    data = GWY_CONTAINER(object);

    /* Selections */
    rect = gwyfile_gather_old_rect_selection(data);
    point = gwyfile_gather_old_point_selection(data);
    line = gwyfile_gather_old_line_selection(data);
    gwy_container_remove_by_prefix(data, "/0/select");
    if (rect) {
        gwy_container_set_object_by_name(data, "/0/select/rectangle", rect);
        g_object_unref(rect);
    }
    if (point) {
        gwy_container_set_object_by_name(data, "/0/select/point", point);
        g_object_unref(point);
    }
    if (line) {
        gwy_container_set_object_by_name(data, "/0/select/line", line);
        g_object_unref(line);
    }

    /* 3D */
    gwy_container_remove_by_prefix(data, "/0/3d/labels");
    gwy_container_remove_by_name(data, "/0/3d/rot_x");
    gwy_container_remove_by_name(data, "/0/3d/rot_y");
    gwy_container_remove_by_name(data, "/0/3d/view_scale");
    gwy_container_remove_by_name(data, "/0/3d/deformation_z");
    gwy_container_remove_by_name(data, "/0/3d/light_z");
    gwy_container_remove_by_name(data, "/0/3d/light_y");
}