📄 gsegysaveimage.c
字号:
/* * GTKSEISVIEWUI - Library of interface elements for GSEGYView * * Copyright (C) 2006 Vladimir Bashkardin * * 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 2 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 av. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Author: Vladimir Bashkardin <vovizmus@users.sourceforge.net> */#include "gsegyfileaux.h"#include "gsegysaveimage.h"#define MAX_DIMENSION 32767G_DEFINE_TYPE (GSEGYSaveImage, g_segy_save_image, G_TYPE_OBJECT)#define G_SEGY_SAVE_IMAGE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), G_SEGY_TYPE_SAVE_IMAGE, GSEGYSaveImagePrivate))typedef struct _GSEGYSaveImagePrivate GSEGYSaveImagePrivate;struct _GSEGYSaveImagePrivate { GtkWidget *window; GtkWidget *vbox; GtkWidget *warning_frame; GtkWidget *warning_label; GtkWidget *frame; GtkWidget *vbox1; GtkWidget *file_chooser; GtkWidget *dimensions_frame; GtkWidget *hbox; GtkWidget *width_label; GtkWidget *width_spin; GtkWidget *height_label; GtkWidget *height_spin; GtkWidget *progress_bar; GtkWidget *button_box; GtkWidget *ok_button; GtkWidget *cancel_button; GAsyncQueue *render_progress; GAsyncQueue *render_finished; gboolean in_progress; gulong pixbuf_progress_signal_id; gulong pixbuf_rendered_signal_id; GdkCursor *watch_cursor; GtkWidget *parent_window; GtkSeisViewGl *seis_view; gboolean seis_view_is_threaded;};static void g_segy_save_image_init (GSEGYSaveImage *self) { GSEGYSaveImagePrivate *private = G_SEGY_SAVE_IMAGE_GET_PRIVATE (self); private->window = NULL; private->vbox = NULL; private->warning_frame = NULL; private->warning_label = NULL; private->frame = NULL; private->vbox1 = NULL; private->file_chooser = NULL; private->dimensions_frame = NULL; private->hbox = NULL; private->width_label = NULL; private->width_spin = NULL; private->height_label = NULL; private->height_spin = NULL; private->progress_bar = NULL; private->button_box = NULL; private->ok_button = NULL; private->cancel_button = NULL; private->in_progress = FALSE; private->pixbuf_progress_signal_id = 0; private->pixbuf_rendered_signal_id = 0; private->seis_view = NULL; private->seis_view_is_threaded = FALSE; private->parent_window = NULL; private->render_progress = g_async_queue_new (); private->render_finished = g_async_queue_new (); private->watch_cursor = gdk_cursor_new (GDK_WATCH);#ifdef DEBUG g_print ("<GSEGYSaveImage is inited>\n");#endif}static void g_segy_save_image_finalize (GObject *object) { GSEGYSaveImage *self = G_SEGY_SAVE_IMAGE (object); GSEGYSaveImagePrivate *private = G_SEGY_SAVE_IMAGE_GET_PRIVATE (self); if (private->in_progress) { g_async_queue_push (private->render_progress, self); g_async_queue_pop (private->render_finished); } while (g_idle_remove_by_data ((gpointer)self)); g_signal_handler_disconnect (G_OBJECT (private->seis_view), private->pixbuf_progress_signal_id); g_signal_handler_disconnect (G_OBJECT (private->seis_view), private->pixbuf_rendered_signal_id); if (private->window) gtk_widget_destroy (private->window); if (private->seis_view) g_object_unref (G_OBJECT (private->seis_view)); if (private->parent_window) gtk_widget_unref (private->parent_window); if (private->render_progress) g_async_queue_unref (private->render_progress); if (private->render_finished) g_async_queue_unref (private->render_finished); if (private->watch_cursor) gdk_cursor_unref (private->watch_cursor);#ifdef DEBUG g_print ("<GSEGYSaveImage is finalized>\n");#endif if (G_OBJECT_CLASS (g_segy_save_image_parent_class)->finalize) G_OBJECT_CLASS (g_segy_save_image_parent_class)->finalize (object);}static void g_segy_save_image_class_init (GSEGYSaveImageClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = g_segy_save_image_finalize; g_type_class_add_private (klass, sizeof (GSEGYSaveImagePrivate));#ifdef DEBUG g_print ("<GSEGYSaveImage class is inited>\n");#endif}static gboolean g_segy_save_image_check_filename (GSEGYSaveImage *self) { GSEGYSaveImagePrivate *private = G_SEGY_SAVE_IMAGE_GET_PRIVATE (self); const gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (private->file_chooser)); if (NULL == filename) return FALSE; if (g_file_test (filename, G_FILE_TEST_EXISTS)) { GtkWidget *rewrite_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (private->window)), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("File %s exists. Would you like t overwrite it?"), g_basename (filename)); if (GTK_RESPONSE_NO == gtk_dialog_run (GTK_DIALOG (rewrite_dialog))) { gtk_widget_destroy (rewrite_dialog); return FALSE; } else gtk_widget_destroy (rewrite_dialog); } GError *gerror = NULL; GIOChannel* io_channel = g_io_channel_new_file (filename, "a", &gerror); if (NULL == io_channel) { GtkWidget *failure_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (private->window)), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Failed to open %s: %s"), g_basename (filename), gerror->message); g_error_free (gerror); gtk_dialog_run (GTK_DIALOG (failure_dialog)); gtk_widget_destroy (failure_dialog); return FALSE; } else g_io_channel_unref (io_channel); return TRUE;}static gboolean g_segy_save_image_render_finished (gpointer data) { GSEGYSaveImagePrivate *private = G_SEGY_SAVE_IMAGE_GET_PRIVATE (G_SEGY_SAVE_IMAGE (data)); g_async_queue_try_pop (private->render_progress); g_async_queue_try_pop (private->render_finished); private->in_progress = FALSE; gtk_widget_set_sensitive (private->vbox1, TRUE); gtk_widget_set_sensitive (private->ok_button, TRUE); gtk_widget_set_sensitive (private->cancel_button, TRUE); gtk_widget_hide (private->progress_bar); gtk_seis_view_gl_redraw (private->seis_view); return FALSE;}static gboolean g_segy_save_image_pixbuf_progress_handler (GtkSeisViewGl *seis_view, gfloat fraction, GdkPixbuf *pixbuf, gpointer data) { GSEGYSaveImage *self = G_SEGY_SAVE_IMAGE (data); GSEGYSaveImagePrivate *private = G_SEGY_SAVE_IMAGE_GET_PRIVATE (self); if (g_async_queue_try_pop (private->render_progress) || fraction < 0.f) { g_async_queue_push (private->render_finished, self); g_idle_add ((GSourceFunc)g_segy_save_image_render_finished, (gpointer)self); return FALSE; } gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (private->progress_bar), fraction); return TRUE;}static void g_segy_save_image_pixbuf_rendered_handler (GtkSeisViewGl *seis_view, GdkPixbuf *pixbuf, gpointer data) { GSEGYSaveImage *self = G_SEGY_SAVE_IMAGE (data); GSEGYSaveImagePrivate *private = G_SEGY_SAVE_IMAGE_GET_PRIVATE (self); if (private->seis_view_is_threaded) gdk_threads_enter (); if (g_async_queue_try_pop (private->render_progress)) { g_async_queue_push (private->render_finished, self); if (pixbuf) g_object_unref (pixbuf); g_idle_add ((GSourceFunc)g_segy_save_image_render_finished, (gpointer)self); if (private->seis_view_is_threaded) gdk_threads_leave (); return; } gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (private->progress_bar), 1.0); GError *save_error = NULL; const gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (private->file_chooser)); const gchar *format = gtk_file_filter_get_name (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (private->file_chooser))); gtk_widget_set_sensitive (private->cancel_button, FALSE); gdk_window_set_cursor (private->window->window, private->watch_cursor); if (private->seis_view_is_threaded) gdk_threads_leave (); gdk_pixbuf_save (pixbuf, filename, format, &save_error, NULL); if (private->seis_view_is_threaded) gdk_threads_enter (); g_object_unref (pixbuf); gdk_window_set_cursor (private->window->window, NULL); if (save_error) { GtkWidget *failure_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (private->window)), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Failed to save %s: %s"), g_basename (filename), save_error->message);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -