[Goodies-commits] r7340 - in xfce4-screenshooter/trunk: . lib src
Jerome Guelfucci
jeromeg at xfce.org
Fri May 15 18:23:26 CEST 2009
Author: jeromeg
Date: 2009-05-15 16:23:26 +0000 (Fri, 15 May 2009)
New Revision: 7340
Added:
xfce4-screenshooter/trunk/lib/exo-job.c
xfce4-screenshooter/trunk/lib/exo-job.h
xfce4-screenshooter/trunk/lib/exo-simple-job.c
xfce4-screenshooter/trunk/lib/exo-simple-job.h
xfce4-screenshooter/trunk/lib/screenshooter-job.c
xfce4-screenshooter/trunk/lib/screenshooter-job.h
xfce4-screenshooter/trunk/lib/screenshooter-marshal.list
xfce4-screenshooter/trunk/lib/screenshooter-simple-job.c
xfce4-screenshooter/trunk/lib/screenshooter-simple-job.h
Modified:
xfce4-screenshooter/trunk/ChangeLog
xfce4-screenshooter/trunk/configure.ac.in
xfce4-screenshooter/trunk/lib/
xfce4-screenshooter/trunk/lib/Makefile.am
xfce4-screenshooter/trunk/lib/screenshooter-actions.c
xfce4-screenshooter/trunk/lib/screenshooter-zimagez.c
xfce4-screenshooter/trunk/lib/screenshooter-zimagez.h
xfce4-screenshooter/trunk/src/main.c
Log:
* src/main.c:
- add the glib and stdlib headers.
- use RETURN_SUCCESS and RETURN_FAILURE instead of 0 and 1.
* lib/exo-simple-job.{c,h}, lib/exo-job.{c,h}: take the job framework
from Exo written by Jannis Pohlmann. Thank you Jannis!
* lib/screenshooter-job.{c,h}, lib/screenshooter-simple-job.{c,h}:
ScreenshooterJob is based on ExoJob, it provides to additional signals,
ask and image-uploaded.
* lib/screenshooter-marshal.list: add some marshallers for the new
signals.
* lib/screenshooter-zimagez.{c,h}: port the existing code to use a
ScreenshooterJob. Thanks to Jannis for his great help! This fixes
a bunch of problems that occured with the previous implementation.
The dialogs still need to be polished.
* lib/screenshooter-actions.c: use the new function.
* lib/Makefile.am:
- add some magic to generate the marshallers.
- sort the source files by alphabetical order.
* configure.ac.in: bump the GThreads required version to 2.16.
Modified: xfce4-screenshooter/trunk/ChangeLog
===================================================================
--- xfce4-screenshooter/trunk/ChangeLog 2009-05-15 06:58:00 UTC (rev 7339)
+++ xfce4-screenshooter/trunk/ChangeLog 2009-05-15 16:23:26 UTC (rev 7340)
@@ -1,3 +1,25 @@
+2009-05-15 jeromeg
+
+ * src/main.c:
+ - add the glib and stdlib headers.
+ - use RETURN_SUCCESS and RETURN_FAILURE instead of 0 and 1.
+ * lib/exo-simple-job.{c,h}, lib/exo-job.{c,h}: take the job framework
+ from Exo written by Jannis Pohlmann. Thank you Jannis!
+ * lib/screenshooter-job.{c,h}, lib/screenshooter-simple-job.{c,h}:
+ ScreenshooterJob is based on ExoJob, it provides to additional signals,
+ ask and image-uploaded.
+ * lib/screenshooter-marshal.list: add some marshallers for the new
+ signals.
+ * lib/screenshooter-zimagez.{c,h}: port the existing code to use a
+ ScreenshooterJob. Thanks to Jannis for his great help! This fixes
+ a bunch of problems that occured with the previous implementation.
+ The dialogs still need to be polished.
+ * lib/screenshooter-actions.c: use the new function.
+ * lib/Makefile.am:
+ - add some magic to generate the marshallers.
+ - sort the source files by alphabetical order.
+ * configure.ac.in: bump the GThreads required version to 2.16.
+
2009-05-05 jeromeg
* lib/screenshooter-zimagez.c: make the dialog unresizable and destroy
Modified: xfce4-screenshooter/trunk/configure.ac.in
===================================================================
--- xfce4-screenshooter/trunk/configure.ac.in 2009-05-15 06:58:00 UTC (rev 7339)
+++ xfce4-screenshooter/trunk/configure.ac.in 2009-05-15 16:23:26 UTC (rev 7340)
@@ -53,7 +53,7 @@
XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-1.0], [4.4.0])
XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.4.0])
XDT_CHECK_PACKAGE([LIBXFCEGUI4], [libxfcegui4-1.0], [4.4.0])
-XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.6.0])
+XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.16.0])
XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.12.0])
XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.16.0])
Property changes on: xfce4-screenshooter/trunk/lib
___________________________________________________________________
Modified: svn:ignore
- Makefile.in
Makefile
.deps
+ Makefile.in
Makefile
.deps
stamp-screenshooter-marshal.h
screenshooter-marshal.c
screenshooter-marshal.h
Modified: xfce4-screenshooter/trunk/lib/Makefile.am
===================================================================
--- xfce4-screenshooter/trunk/lib/Makefile.am 2009-05-15 06:58:00 UTC (rev 7339)
+++ xfce4-screenshooter/trunk/lib/Makefile.am 2009-05-15 16:23:26 UTC (rev 7340)
@@ -1,15 +1,23 @@
noinst_LTLIBRARIES = \
libscreenshooter.la
+libscreenshooter_built_sources = \
+ screenshooter-marshal.c screenshooter-marshal.h
+
libscreenshooter_la_SOURCES = \
+ $(libscreenshooter_built_sources) \
libscreenshooter.h \
+ exo-job.c exo-job.h \
+ exo-simple-job.c exo-simple-job.h \
+ screenshooter-actions.c screenshooter-actions.h \
+ screenshooter-capture.c screenshooter-capture.h \
+ screenshooter-dialogs.c screenshooter-dialogs.h \
screenshooter-global.h \
+ screenshooter-job.c screenshooter-job.h \
+ screenshooter-simple-job.c screenshooter-simple-job.h \
screenshooter-utils.c screenshooter-utils.h \
- sexy-url-label.c sexy-url-label.h \
- screenshooter-capture.c screenshooter-capture.h \
- screenshooter-dialogs.c screenshooter-dialogs.h \
- screenshooter-actions.c screenshooter-actions.h \
- screenshooter-zimagez.c screenshooter-zimagez.h
+ screenshooter-zimagez.c screenshooter-zimagez.h \
+ sexy-url-label.c sexy-url-label.h
libscreenshooter_la_CFLAGS = \
-I$(top_srcdir) \
@@ -26,3 +34,40 @@
@LIBXFCE4UTIL_LIBS@ \
@LIBXFCEGUI4_LIBS@ \
@GLIB_LIBS@
+
+##
+## Rules to auto-generate built sources
+##
+## This is a bit tricky with automake, and non-trivial to implement. The
+## rules below seem to work fine and don't seem to break the build, but
+## they are only enabled in maintainer mode, so arbitrary users don't get
+## trapped in automake's oddities. Therefore we ship the autogenerated
+## files as part of the dist tarball.
+##
+
+DISTCLEANFILES = \
+ stamp-screenshooter-marshal.h \
+ $(libscreenshooter_built_sources)
+
+BUILT_SOURCES = \
+ $(libscreenshooter_built_sources)
+
+screenshooter-marshal.h: stamp-screenshooter-marshal.h
+ @true
+stamp-screenshooter-marshal.h: screenshooter-marshal.list Makefile
+ ( cd $(srcdir) && glib-genmarshal \
+ --prefix=_screenshooter_marshal \
+ --header screenshooter-marshal.list ) >> xgen-emh \
+ && ( cmp -s xgen-emh screenshooter-marshal.h || cp xgen-emh screenshooter-marshal.h ) \
+ && rm -f xgen-emh \
+ && echo timestamp > $(@F)
+
+screenshooter-marshal.c: screenshooter-marshal.list Makefile
+ ( cd $(srcdir) && glib-genmarshal \
+ --prefix=_screenshooter_marshal \
+ --body screenshooter-marshal.list ) >> xgen-emc \
+ && cp xgen-emc screenshooter-marshal.c \
+ && rm -f xgen-emc
+
+EXTRA_DIST = \
+ screenshooter-marshal.list
Added: xfce4-screenshooter/trunk/lib/exo-job.c
===================================================================
--- xfce4-screenshooter/trunk/lib/exo-job.c (rev 0)
+++ xfce4-screenshooter/trunk/lib/exo-job.c 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,631 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+#include "exo-job.h"
+
+
+
+#define EXO_JOB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EXO_TYPE_JOB, ExoJobPrivate))
+
+
+
+/* Signal identifiers */
+enum
+{
+ ERROR,
+ FINISHED,
+ INFO_MESSAGE,
+ PERCENT,
+ LAST_SIGNAL,
+};
+
+
+
+typedef struct _ExoJobSignalData ExoJobSignalData;
+
+
+
+static void exo_job_class_init (ExoJobClass *klass);
+static void exo_job_init (ExoJob *job);
+static void exo_job_finalize (GObject *object);
+static void exo_job_error (ExoJob *job,
+ GError *error);
+static void exo_job_finished (ExoJob *job);
+
+
+
+struct _ExoJobPrivate
+{
+ GIOSchedulerJob *scheduler_job;
+ GCancellable *cancellable;
+ guint running : 1;
+};
+
+struct _ExoJobSignalData
+{
+ gpointer instance;
+ GQuark signal_detail;
+ guint signal_id;
+ va_list var_args;
+};
+
+
+
+static GObjectClass *exo_job_parent_class = NULL;
+static guint job_signals[LAST_SIGNAL];
+
+
+
+GType
+exo_job_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ {
+ type = g_type_register_static_simple (G_TYPE_OBJECT,
+ "ExoJob",
+ sizeof (ExoJobClass),
+ (GClassInitFunc) exo_job_class_init,
+ sizeof (ExoJob),
+ (GInstanceInitFunc) exo_job_init,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+
+
+static void
+exo_job_class_init (ExoJobClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ g_type_class_add_private (klass, sizeof (ExoJobPrivate));
+
+ /* Determine the parent type class */
+ exo_job_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = exo_job_finalize;
+
+ klass->execute = NULL;
+ klass->error = NULL;
+ klass->finished = NULL;
+ klass->info_message = NULL;
+ klass->percent = NULL;
+
+ /**
+ * ExoJob::error:
+ * @job : an #ExoJob.
+ * @error : a #GError describing the cause.
+ *
+ * Emitted whenever an error occurs while executing the @job.
+ **/
+ job_signals[ERROR] =
+ g_signal_new ("error",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_NO_HOOKS,
+ G_STRUCT_OFFSET (ExoJobClass, error),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+ /**
+ * ExoJob::finished:
+ * @job : an #ExoJob.
+ *
+ * This signal will be automatically emitted once the @job finishes
+ * its execution, no matter whether @job completed successfully or
+ * was cancelled by the user.
+ **/
+ job_signals[FINISHED] =
+ g_signal_new ("finished",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_NO_HOOKS,
+ G_STRUCT_OFFSET (ExoJobClass, finished),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * ExoJob::info-message:
+ * @job : an #ExoJob.
+ * @message : information to be displayed about @job.
+ *
+ * This signal is emitted to display information about the * @job.
+ * Examples of messages are "Preparing..." or "Cleaning up...".
+ *
+ * The @message is garanteed to contain valid UTF-8, so it can be
+ * displayed by #GtkWidget<!---->s out of the box.
+ **/
+ job_signals[INFO_MESSAGE] =
+ g_signal_new ("info-message",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_NO_HOOKS,
+ G_STRUCT_OFFSET (ExoJobClass, info_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ /**
+ * ExoJob::percent:
+ * @job : an #ExoJob.
+ * @percent : the percentage of completeness.
+ *
+ * This signal is emitted to present the state of the overall
+ * progress. The @percent value is garantied to be in the range 0.0
+ * to 100.0.
+ **/
+ job_signals[PERCENT] =
+ g_signal_new ("percent",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_NO_HOOKS,
+ G_STRUCT_OFFSET (ExoJobClass, percent),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__DOUBLE,
+ G_TYPE_NONE, 1, G_TYPE_DOUBLE);
+}
+
+
+
+static void
+exo_job_init (ExoJob *job)
+{
+ job->priv = EXO_JOB_GET_PRIVATE (job);
+ job->priv->cancellable = g_cancellable_new ();
+ job->priv->running = FALSE;
+ job->priv->scheduler_job = NULL;
+}
+
+
+
+static void
+exo_job_finalize (GObject *object)
+{
+ ExoJob *job = EXO_JOB (object);
+
+ exo_job_cancel (job);
+ g_object_unref (job->priv->cancellable);
+
+ (*G_OBJECT_CLASS (exo_job_parent_class)->finalize) (object);
+}
+
+
+
+/**
+ * exo_job_finish:
+ * @job : an #ExoJob.
+ * @result : the #GSimpleAsyncResult of the job.
+ * @error : return location for errors.
+ *
+ * Finishes the execution of an operation by propagating errors
+ * from the @result into @error.
+ *
+ * Return value: %TRUE if there was no error during the operation,
+ * %FALSE otherwise.
+ **/
+static gboolean
+exo_job_finish (ExoJob *job,
+ GSimpleAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (EXO_IS_JOB (job), FALSE);
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ return !g_simple_async_result_propagate_error (result, error);
+}
+
+
+
+/**
+ * exo_job_async_ready:
+ * @object : an #ExoJob.
+ * @result : the #GAsyncResult of the job.
+ *
+ * This function is called by the #GIOScheduler at the end of the
+ * operation. It checks if there were errors during the operation
+ * and emits "error" and "finished" signals.
+ **/
+static void
+exo_job_async_ready (GObject *object,
+ GAsyncResult *result)
+{
+ ExoJob *job = EXO_JOB (object);
+ GError *error = NULL;
+
+ g_return_if_fail (EXO_IS_JOB (job));
+ g_return_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result));
+
+ if (!exo_job_finish (job, G_SIMPLE_ASYNC_RESULT (result), &error))
+ {
+ g_assert (error != NULL);
+
+ /* don't treat cancellation as an error for now */
+ if (error->code != G_IO_ERROR_CANCELLED)
+ exo_job_error (job, error);
+
+ g_error_free (error);
+ }
+
+ exo_job_finished (job);
+}
+
+
+
+/**
+ * exo_job_scheduler_job_func:
+ * @scheduler_job : the #GIOSchedulerJob running the operation.
+ * @cancellable : the #GCancellable associated with the job.
+ * @user_data : a #GSimpleAsyncResult.
+ *
+ * This function is called by the #GIOScheduler to execute the
+ * operation associated with the job. It basically calls the
+ * ExoJobClass#execute function.
+ *
+ * Return value: %FALSE, to stop the thread at the end of the
+ * operation.
+ **/
+static gboolean
+exo_job_scheduler_job_func (GIOSchedulerJob *scheduler_job,
+ GCancellable *cancellable,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result = user_data;
+ ExoJob *job;
+ GError *error = NULL;
+ gboolean success;
+
+ job = g_simple_async_result_get_op_res_gpointer (result);
+ job->priv->scheduler_job = scheduler_job;
+
+ success = (*EXO_JOB_GET_CLASS (job)->execute) (job, &error);
+
+ /* TODO why was this necessary again? */
+ g_io_scheduler_job_send_to_mainloop (scheduler_job, (GSourceFunc) gtk_false,
+ NULL, NULL);
+
+ if (!success)
+ {
+ g_simple_async_result_set_from_error (result, error);
+ g_error_free (error);
+ }
+
+ g_simple_async_result_complete_in_idle (result);
+
+ return FALSE;
+}
+
+
+
+/**
+ * exo_job_emit_valist_in_mainloop:
+ * @user_data : an #ExoJobSignalData.
+ *
+ * Called from the main loop of the application to emit the signal
+ * specified by the @user_data.
+ *
+ * Return value: %FALSE, to keep the function from being called
+ * multiple times in a row.
+ **/
+static gboolean
+exo_job_emit_valist_in_mainloop (gpointer user_data)
+{
+ ExoJobSignalData *data = user_data;
+
+ g_signal_emit_valist (data->instance, data->signal_id, data->signal_detail,
+ data->var_args);
+
+ return FALSE;
+}
+
+
+/**
+ * exo_job_emit_valist:
+ * @job : an #ExoJob.
+ * @signal_id : the signal id.
+ * @signal_detail : the signal detail.
+ * @var_args : a list of parameters to be passed to the signal,
+ * followed by a location for the return value. If the
+ * return type of the signal is G_TYPE_NONE, the return
+ * value location can be omitted.
+ *
+ * Send a the signal with the given @signal_id and @signal_detail to the
+ * main loop of the application and waits for the listeners to handle
+ * it.
+ **/
+static void
+exo_job_emit_valist (ExoJob *job,
+ guint signal_id,
+ GQuark signal_detail,
+ va_list var_args)
+{
+ ExoJobSignalData data;
+
+ g_return_if_fail (EXO_IS_JOB (job));
+ g_return_if_fail (job->priv->scheduler_job != NULL);
+
+ data.instance = job;
+ data.signal_id = signal_id;
+ data.signal_detail = signal_detail;
+
+ /* copy the variable argument list */
+ G_VA_COPY (data.var_args, var_args);
+
+ /* emit the signal in the main loop */
+ g_io_scheduler_job_send_to_mainloop (job->priv->scheduler_job,
+ exo_job_emit_valist_in_mainloop,
+ &data, NULL);
+}
+
+
+
+/**
+ * exo_job_error:
+ * @job : an #ExoJob.
+ * @error : a #GError.
+ *
+ * Emits the "error" signal and passes the @error to it so that the
+ * application can handle it (e.g. by displaying an error dialog).
+ *
+ * This function should never be called from outside the application's
+ * main loop.
+ **/
+static void
+exo_job_error (ExoJob *job,
+ GError *error)
+{
+ g_return_if_fail (EXO_IS_JOB (job));
+ g_return_if_fail (error != NULL);
+
+ g_signal_emit (job, job_signals[ERROR], 0, error);
+}
+
+
+
+/**
+ * exo_job_finished:
+ * @job : an #ExoJob.
+ *
+ * Emits the "finished" signal to notify listeners of the end of the
+ * operation.
+ *
+ * This function should never be called from outside the application's
+ * main loop.
+ **/
+static void
+exo_job_finished (ExoJob *job)
+{
+ g_return_if_fail (EXO_IS_JOB (job));
+ g_signal_emit (job, job_signals[FINISHED], 0);
+}
+
+
+
+/**
+ * exo_job_launch:
+ * @job : an #ExoJob.
+ *
+ * This functions schedules the @job to be run as soon as possible, in
+ * a separate thread. The caller can then connect to the signals of the
+ * returned #ExoJob in order to be notified on errors, progress updates
+ * and the end of the operation.
+ *
+ * Return value: the @job itself.
+ **/
+ExoJob *
+exo_job_launch (ExoJob *job)
+{
+ GSimpleAsyncResult *result;
+
+ g_return_val_if_fail (EXO_IS_JOB (job), NULL);
+ g_return_val_if_fail (!job->priv->running, NULL);
+ g_return_val_if_fail (EXO_JOB_GET_CLASS (job)->execute != NULL, NULL);
+
+ /* mark the job as running */
+ job->priv->running = TRUE;
+
+ result = g_simple_async_result_new (G_OBJECT (job),
+ (GAsyncReadyCallback) exo_job_async_ready,
+ NULL, exo_job_launch);
+
+ g_simple_async_result_set_op_res_gpointer (result, g_object_ref (job),
+ (GDestroyNotify) g_object_unref);
+
+ g_io_scheduler_push_job (exo_job_scheduler_job_func, result,
+ (GDestroyNotify) g_object_unref,
+ G_PRIORITY_HIGH, job->priv->cancellable);
+
+ return job;
+}
+
+
+
+/**
+ * exo_job_cancel:
+ * @job : a #ExoJob.
+ *
+ * Attempts to cancel the operation currently performed by @job. Even
+ * after the cancellation of @job, it may still emit signals, so you
+ * must take care of disconnecting all handlers appropriately if you
+ * cannot handle signals after cancellation.
+ **/
+void
+exo_job_cancel (ExoJob *job)
+{
+ g_return_if_fail (EXO_IS_JOB (job));
+ g_cancellable_cancel (job->priv->cancellable);
+}
+
+
+
+/**
+ * exo_job_is_cancelled:
+ * @job : a #ExoJob.
+ *
+ * Checks whether @job was previously cancelled
+ * by a call to exo_job_cancel().
+ *
+ * Return value: %TRUE if @job is cancelled.
+ **/
+gboolean
+exo_job_is_cancelled (const ExoJob *job)
+{
+ g_return_val_if_fail (EXO_IS_JOB (job), FALSE);
+ return g_cancellable_is_cancelled (job->priv->cancellable);
+}
+
+
+
+/**
+ * exo_job_get_cancellable:
+ * @job : an #ExoJob.
+ *
+ * Returns the #GCancellable that can be used to cancel the @job.
+ *
+ * Return value: the #GCancellable associated with the @job. It
+ * is owned by the @job and must not be released.
+ **/
+GCancellable *
+exo_job_get_cancellable (const ExoJob *job)
+{
+ g_return_val_if_fail (EXO_IS_JOB (job), NULL);
+ return job->priv->cancellable;
+}
+
+
+
+/**
+ * exo_job_set_error_if_cancelled:
+ * @job : an #ExoJob.
+ * @error : error to be set if the @job was cancelled.
+ *
+ * Sets the @error if the @job was cancelled. This is a convenience
+ * function that is equivalent to
+ * <informalexample><programlisting>
+ * GCancellable *cancellable;
+ * cancellable = exo_job_get_cancllable (job);
+ * g_cancellable_set_error_if_cancelled (cancellable, error);
+ * </programlisting></informalexample>
+ *
+ * Return value: %TRUE if the job was cancelled and @error is now set,
+ * %FALSE otherwise.
+ **/
+gboolean
+exo_job_set_error_if_cancelled (ExoJob *job,
+ GError **error)
+{
+ g_return_val_if_fail (EXO_IS_JOB (job), FALSE);
+ return g_cancellable_set_error_if_cancelled (job->priv->cancellable, error);
+}
+
+
+
+/**
+ * exo_job_emit:
+ * @job : an #ExoJob.
+ * @signal_id : the signal id.
+ * @signal_detail : the signal detail.
+ * ... : a list of parameters to be passed to the signal,
+ * followed by a location for the return value. If the
+ * return type of the signal is G_TYPE_NONE, the return
+ * value location can be omitted.
+ *
+ * Sends the signal with @signal_id and @signal_id to the application's
+ * main loop and waits for listeners to handle it.
+ **/
+void
+exo_job_emit (ExoJob *job,
+ guint signal_id,
+ GQuark signal_detail,
+ ...)
+{
+ va_list var_args;
+
+ g_return_if_fail (EXO_IS_JOB (job));
+
+ va_start (var_args, signal_detail);
+ exo_job_emit_valist (job, signal_id, signal_detail, var_args);
+ va_end (var_args);
+}
+
+
+
+/**
+ * exo_job_info_message:
+ * @job : an #ExoJob.
+ * @format : a format string.
+ * ... : parameters for the format string.
+ *
+ * Generates and emits an "info-message" signal and sends it to the
+ * application's main loop.
+ **/
+void
+exo_job_info_message (ExoJob *job,
+ const gchar *format,
+ ...)
+{
+ va_list var_args;
+ gchar *message;
+
+ g_return_if_fail (EXO_IS_JOB (job));
+ g_return_if_fail (format != NULL);
+
+ va_start (var_args, format);
+ message = g_strdup_vprintf (format, var_args);
+
+ exo_job_emit (job, job_signals[INFO_MESSAGE], 0, message);
+
+ g_free (message);
+ va_end (var_args);
+}
+
+
+
+/**
+ * exo_job_percent:
+ * @job : an #ExoJob.
+ * @percent : percentage of completeness of the operation.
+ *
+ * Emits a "percent" signal and sends it to the application's main
+ * loop. Also makes sure that @percent is between 0.0 and 100.0.
+ **/
+void
+exo_job_percent (ExoJob *job,
+ gdouble percent)
+{
+ g_return_if_fail (EXO_IS_JOB (job));
+
+ percent = MAX (0.0, MIN (100.0, percent));
+ exo_job_emit (job, job_signals[PERCENT], 0, percent);
+}
+
Added: xfce4-screenshooter/trunk/lib/exo-job.h
===================================================================
--- xfce4-screenshooter/trunk/lib/exo-job.h (rev 0)
+++ xfce4-screenshooter/trunk/lib/exo-job.h 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,85 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __EXO_JOB_H__
+#define __EXO_JOB_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define EXO_TYPE_JOB (exo_job_get_type ())
+#define EXO_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXO_TYPE_JOB, ExoJob))
+#define EXO_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EXO_TYPE_JOB, ExoJobClass))
+#define EXO_IS_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXO_TYPE_JOB))
+#define EXO_IS_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EXO_TYPE_JOB)
+#define EXO_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EXO_TYPE_JOB, ExoJobClass))
+
+typedef struct _ExoJobPrivate ExoJobPrivate;
+typedef struct _ExoJobClass ExoJobClass;
+typedef struct _ExoJob ExoJob;
+
+struct _ExoJobClass
+{
+ GObjectClass __parent__;
+
+ /* virtual methods */
+ gboolean (*execute) (ExoJob *job,
+ GError **error);
+
+ /* signals */
+ void (*error) (ExoJob *job,
+ GError *error);
+ void (*finished) (ExoJob *job);
+ void (*info_message) (ExoJob *job,
+ const gchar *message);
+ void (*percent) (ExoJob *job,
+ gdouble percent);
+};
+
+struct _ExoJob
+{
+ GObject __parent__;
+
+ /*< private >*/
+ ExoJobPrivate *priv;
+};
+
+GType exo_job_get_type (void) G_GNUC_CONST;
+
+ExoJob *exo_job_launch (ExoJob *job);
+void exo_job_cancel (ExoJob *job);
+gboolean exo_job_is_cancelled (const ExoJob *job);
+GCancellable *exo_job_get_cancellable (const ExoJob *job);
+gboolean exo_job_set_error_if_cancelled (ExoJob *job,
+ GError **error);
+void exo_job_emit (ExoJob *job,
+ guint signal_id,
+ GQuark signal_detail,
+ ...);
+void exo_job_info_message (ExoJob *job,
+ const gchar *format,
+ ...);
+void exo_job_percent (ExoJob *job,
+ gdouble percent);
+
+G_END_DECLS
+
+#endif /* !__EXO_JOB_H__ */
Added: xfce4-screenshooter/trunk/lib/exo-simple-job.c
===================================================================
--- xfce4-screenshooter/trunk/lib/exo-simple-job.c (rev 0)
+++ xfce4-screenshooter/trunk/lib/exo-simple-job.c 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,219 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <gobject/gvaluecollector.h>
+
+#include "exo-job.h"
+#include "exo-simple-job.h"
+
+
+
+static void exo_simple_job_class_init (ExoSimpleJobClass *klass);
+static void exo_simple_job_finalize (GObject *object);
+static gboolean exo_simple_job_execute (ExoJob *job,
+ GError **error);
+
+
+
+struct _ExoSimpleJobClass
+{
+ ExoJobClass __parent__;
+};
+
+struct _ExoSimpleJob
+{
+ ExoJob __parent__;
+ ExoSimpleJobFunc func;
+ GValueArray *param_values;
+};
+
+
+
+static GObjectClass *exo_simple_job_parent_class;
+
+
+
+GType
+exo_simple_job_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ {
+ type = g_type_register_static_simple (EXO_TYPE_JOB,
+ "ExoSimpleJob",
+ sizeof (ExoSimpleJobClass),
+ (GClassInitFunc) exo_simple_job_class_init,
+ sizeof (ExoSimpleJob),
+ NULL,
+ 0);
+ }
+
+ return type;
+}
+
+
+
+static void
+exo_simple_job_class_init (ExoSimpleJobClass *klass)
+{
+ ExoJobClass *exojob_class;
+ GObjectClass *gobject_class;
+
+ /* determine the parent type class */
+ exo_simple_job_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = exo_simple_job_finalize;
+
+ exojob_class = EXO_JOB_CLASS (klass);
+ exojob_class->execute = exo_simple_job_execute;
+}
+
+
+
+static void
+exo_simple_job_finalize (GObject *object)
+{
+ ExoSimpleJob *simple_job = EXO_SIMPLE_JOB (object);
+
+ /* release the param values */
+ g_value_array_free (simple_job->param_values);
+
+ (*G_OBJECT_CLASS (exo_simple_job_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+exo_simple_job_execute (ExoJob *job,
+ GError **error)
+{
+ ExoSimpleJob *simple_job = EXO_SIMPLE_JOB (job);
+ gboolean success = TRUE;
+ GError *err = NULL;
+
+ g_return_val_if_fail (EXO_IS_SIMPLE_JOB (job), FALSE);
+ g_return_val_if_fail (simple_job->func != NULL, FALSE);
+
+ /* try to execute the job using the supplied function */
+ success = (*simple_job->func) (job, simple_job->param_values, &err);
+
+ if (!success)
+ {
+ g_assert (err != NULL || exo_job_is_cancelled (job));
+
+ /* set error if the job was cancelled. otherwise just propagate
+ * the results of the processing function */
+ if (exo_job_set_error_if_cancelled (job, error))
+ {
+ g_clear_error (&err);
+ }
+ else
+ {
+ if (err != NULL)
+ g_propagate_error (error, err);
+ }
+
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+
+
+/**
+ * exo_simple_job_launch:
+ * @func : the #ExoSimpleJobFunc to execute the job.
+ * @n_param_values : the number of parameters to pass to the @func.
+ * @... : a list of #GType and parameter pairs (exactly
+ * @n_param_values pairs) that are passed to @func.
+ *
+ * Allocates a new #ExoJob which executes the specified @func with
+ * the specified parameters.
+ *
+ * An example could be:
+ *
+ * <informalexample><programlisting>
+ * exo_simple_job_launch (list_directory_job, 1, G_TYPE_FILE, file);
+ * </programlisting></informalexample>
+ *
+ * The caller is responsible to release the returned object using
+ * g_object_unref() when no longer needed.
+ *
+ * Return value: the launched #ExoJob.
+ **/
+ExoJob*
+exo_simple_job_launch (ExoSimpleJobFunc func,
+ guint n_param_values,
+ ...)
+{
+ ExoSimpleJob *simple_job;
+ va_list var_args;
+ GValue value = { 0, };
+ gchar *error_message;
+ gint n;
+
+ /* allocate and initialize the simple job */
+ simple_job = g_object_new (EXO_TYPE_SIMPLE_JOB, NULL);
+ simple_job->func = func;
+ simple_job->param_values = g_value_array_new (n_param_values);
+
+ /* collect the parameters */
+ va_start (var_args, n_param_values);
+ for (n = 0; n < n_param_values; ++n)
+ {
+ /* initialize the value to hold the next parameter */
+ g_value_init (&value, va_arg (var_args, GType));
+
+ /* collect the value from the stack */
+ G_VALUE_COLLECT (&value, var_args, 0, &error_message);
+
+ /* check if an error occurred */
+ if (G_UNLIKELY (error_message != NULL))
+ {
+ g_error ("%s: %s", G_STRLOC, error_message);
+ g_free (error_message);
+ }
+
+ g_value_array_insert (simple_job->param_values, n, &value);
+ g_value_unset (&value);
+ }
+ va_end (var_args);
+
+ /* launch the job */
+ return exo_job_launch (EXO_JOB (simple_job));
+}
Added: xfce4-screenshooter/trunk/lib/exo-simple-job.h
===================================================================
--- xfce4-screenshooter/trunk/lib/exo-simple-job.h (rev 0)
+++ xfce4-screenshooter/trunk/lib/exo-simple-job.h 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,63 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __EXO_SIMPLE_JOB_H__
+#define __EXO_SIMPLE_JOB_H__
+
+#include "exo-job.h"
+
+G_BEGIN_DECLS
+
+/**
+ * ExoSimpleJobFunc:
+ * @job : an #ExoJob.
+ * @param_values : a #GValueArray of the #GValue<!---->s passed to
+ * exo_simple_job_launch().
+ * @error : return location for errors.
+ *
+ * Used by the #ExoSimpleJob to process the @job. See exo_simple_job_launch()
+ * for further details.
+ *
+ * Return value: %TRUE on success, %FALSE in case of an error.
+ **/
+typedef gboolean (*ExoSimpleJobFunc) (ExoJob *job,
+ GValueArray *param_values,
+ GError **error);
+
+
+#define EXO_TYPE_SIMPLE_JOB (exo_simple_job_get_type ())
+#define EXO_SIMPLE_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXO_TYPE_SIMPLE_JOB, ExoSimpleJob))
+#define EXO_SIMPLE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EXO_TYPE_SIMPLE_JOB, ExoSimpleJobClass))
+#define EXO_IS_SIMPLE_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXO_TYPE_SIMPLE_JOB))
+#define EXO_IS_SIMPLE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EXO_TYPE_SIMPLE_JOB))
+#define EXO_SIMPLE_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EXO_TYPE_SIMPLE_JOB, ExoSimpleJobClass))
+
+typedef struct _ExoSimpleJobClass ExoSimpleJobClass;
+typedef struct _ExoSimpleJob ExoSimpleJob;
+
+GType exo_simple_job_get_type (void) G_GNUC_CONST;
+
+ExoJob *exo_simple_job_launch (ExoSimpleJobFunc func,
+ guint n_param_values,
+ ...) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+G_END_DECLS
+
+#endif /* !__EXO_SIMPLE_JOB_H__ */
Modified: xfce4-screenshooter/trunk/lib/screenshooter-actions.c
===================================================================
--- xfce4-screenshooter/trunk/lib/screenshooter-actions.c 2009-05-15 06:58:00 UTC (rev 7339)
+++ xfce4-screenshooter/trunk/lib/screenshooter-actions.c 2009-05-15 16:23:26 UTC (rev 7340)
@@ -56,11 +56,7 @@
}
else
{
- const gchar *upload_name =
- screenshooter_upload_to_zimagez (screenshot_path);
-
- if (upload_name != NULL)
- screenshooter_display_zimagez_links (upload_name);
+ screenshooter_upload_to_zimagez (screenshot_path);
}
}
Added: xfce4-screenshooter/trunk/lib/screenshooter-job.c
===================================================================
--- xfce4-screenshooter/trunk/lib/screenshooter-job.c (rev 0)
+++ xfce4-screenshooter/trunk/lib/screenshooter-job.c 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,195 @@
+/* $Id$
+ *
+ * Copyright © 2008-2009 Jérôme Guelfucci <jerome.guelfucci at gmail.com>
+ *
+ * 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 Library General Public License for more details.
+ *
+ * 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.
+ */
+
+#include "screenshooter-job.h"
+
+
+
+#define SCREENSHOOTER_JOB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SCREENSHOOTER_TYPE_JOB, ScreenshooterJobPrivate))
+
+
+
+/* Signal identifiers */
+enum
+{
+ ASK,
+ IMAGE_UPLOADED,
+ LAST_SIGNAL,
+};
+
+
+
+static void screenshooter_job_class_init (ScreenshooterJobClass *klass);
+static void screenshooter_job_init (ScreenshooterJob *job);
+static void screenshooter_job_finalize (GObject *object);
+/*static void screenshooter_job_real_ask (ScreenshooterJob *job,
+ GtkListStore *liststore,
+ const gchar *message);*/
+
+
+
+static ExoJobClass *screenshooter_job_parent_class;
+static guint job_signals[LAST_SIGNAL];
+
+
+
+GType
+screenshooter_job_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ {
+ type = g_type_register_static_simple (EXO_TYPE_JOB,
+ "ScreenshooterJob",
+ sizeof (ScreenshooterJobClass),
+ (GClassInitFunc) screenshooter_job_class_init,
+ sizeof (ScreenshooterJob),
+ (GInstanceInitFunc) screenshooter_job_init,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+
+
+static void
+screenshooter_job_class_init (ScreenshooterJobClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ /* determine the parent class */
+ screenshooter_job_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = screenshooter_job_finalize;
+
+ klass->ask = NULL;
+
+ /**
+ * ScreenshooterJob::ask:
+ * @job : a #ScreenshooterJob.
+ * @info : a #GtkListStore.
+ * @message : message to display to the user.
+ *
+ * The @message is garantied to contain valid UTF-8.
+ *
+ * @info contains the information already gathered. The first column tells you the
+ * name of the information, the second its contents. Some contents might be empty,
+ * it means that the user did not provide the correct information as explained per
+ * @message.
+ *
+ * The callback asks for the information which is not valid and updates @info.
+ **/
+ job_signals[ASK] =
+ g_signal_new ("ask",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_NO_HOOKS | G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ScreenshooterJobClass, ask),
+ NULL, NULL,
+ _screenshooter_marshal_VOID__POINTER_STRING,
+ G_TYPE_NONE,
+ 2, G_TYPE_POINTER, G_TYPE_STRING);
+
+ /**
+ * ScreenshooterJob::image-uploaded:
+ * @job : a #ScreenshooterJob.
+ * @file_name : the name of the uploaded image on ZimageZ.com.
+ *
+ * This signal is emitted when the upload is finished. If it was successful,
+ * @file_name contains the name of the file on ZimageZ.com, else it is NULL.
+ **/
+ job_signals[IMAGE_UPLOADED] =
+ g_signal_new ("image-uploaded",
+ G_TYPE_FROM_CLASS (klass), G_SIGNAL_NO_HOOKS,
+ 0, NULL, NULL,
+ _screenshooter_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+}
+
+
+
+static void
+screenshooter_job_init (ScreenshooterJob *job)
+{
+
+}
+
+
+
+static void
+screenshooter_job_finalize (GObject *object)
+{
+ (*G_OBJECT_CLASS (screenshooter_job_parent_class)->finalize) (object);
+}
+
+
+
+/*static void
+screenshooter_job_real_ask (ScreenshooterJob *job,
+ GtkListStore *liststore,
+ const gchar *message)
+{
+ g_return_if_fail (SCREENSHOOTER_IS_JOB (job));
+
+ TRACE ("Emit ask signal.");
+ g_signal_emit (job, job_signals[ASK], 0, liststore, message);
+}*/
+
+
+
+/* Public */
+
+
+
+void screenshooter_job_ask_info (ScreenshooterJob *job,
+ GtkListStore *info,
+ const gchar *format,
+ ...)
+{
+ va_list va_args = NULL;
+ gchar *message;
+
+ g_return_if_fail (SCREENSHOOTER_IS_JOB (job));
+ g_return_if_fail (GTK_IS_LIST_STORE (info));
+ g_return_if_fail (format != NULL);
+
+ if (G_UNLIKELY (exo_job_is_cancelled (EXO_JOB (job))))
+
+ va_start (va_args, format);
+ message = g_strdup_vprintf (format, va_args);
+ va_end (va_args);
+
+ exo_job_emit (EXO_JOB (job), job_signals[ASK], 0, info, message);
+
+ g_free (message);
+}
+
+
+
+void
+screenshooter_job_image_uploaded (ScreenshooterJob *job, const gchar *file_name)
+{
+ g_return_if_fail (SCREENSHOOTER_IS_JOB (job));
+
+ TRACE ("Emit image-uploaded signal.");
+ exo_job_emit (EXO_JOB (job), job_signals[IMAGE_UPLOADED], 0, file_name);
+}
Added: xfce4-screenshooter/trunk/lib/screenshooter-job.h
===================================================================
--- xfce4-screenshooter/trunk/lib/screenshooter-job.h (rev 0)
+++ xfce4-screenshooter/trunk/lib/screenshooter-job.h 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,77 @@
+/* $Id$
+ *
+ * Copyright © 2008-2009 Jérôme Guelfucci <jerome.guelfucci at gmail.com>
+ *
+ * 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 Library General Public License for more details.
+ *
+ * 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.
+ */
+
+#ifndef __SCREENSHOOTER_JOB_H__
+#define __SCREENSHOOTER_JOB_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include "exo-simple-job.h"
+#include "screenshooter-marshal.h"
+
+G_BEGIN_DECLS
+
+typedef struct _ScreenshooterJobClass ScreenshooterJobClass;
+typedef struct _ScreenshooterJob ScreenshooterJob;
+
+#define SCREENSHOOTER_TYPE_JOB (screenshooter_job_get_type ())
+#define SCREENSHOOTER_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCREENSHOOTER_TYPE_JOB, ScreenshooterJob))
+#define SCREENSHOOTER_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SCREENSHOOTER_TYPE_JOB, ScreenshooterJobClass))
+#define SCREENSHOOTER_IS_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCREENSHOOTER_TYPE_JOB))
+#define SCREENSHOOTER_IS_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SCREENSHOOTER_TYPE_JOB))
+#define SCREENSHOOTER_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SCREENSHOOTER_TYPE_JOB, ScreenshooterJobClass))
+
+struct _ScreenshooterJobClass
+{
+ /*< private >*/
+ ExoJobClass __parent__;
+
+ /*< public >*/
+
+ /* signals */
+ void (*ask) (ScreenshooterJob *job, GtkListStore *info, const gchar *message);
+};
+
+struct _ScreenshooterJob
+{
+ /*< private >*/
+ ExoJob __parent__;
+};
+
+GType screenshooter_job_get_type (void) G_GNUC_CONST;
+
+void screenshooter_job_ask_info (ScreenshooterJob *job,
+ GtkListStore *info,
+ const gchar *format,
+ ...);
+
+
+void screenshooter_job_image_uploaded (ScreenshooterJob *job,
+ const gchar *file_name);
+
+G_END_DECLS
+
+#endif /* !__SCREENSHOOTER_JOB_H__ */
+
Property changes on: xfce4-screenshooter/trunk/lib/screenshooter-job.h
___________________________________________________________________
Added: svn:executable
+ *
Added: xfce4-screenshooter/trunk/lib/screenshooter-marshal.list
===================================================================
--- xfce4-screenshooter/trunk/lib/screenshooter-marshal.list (rev 0)
+++ xfce4-screenshooter/trunk/lib/screenshooter-marshal.list 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,2 @@
+VOID:STRING
+VOID:POINTER,STRING
Added: xfce4-screenshooter/trunk/lib/screenshooter-simple-job.c
===================================================================
--- xfce4-screenshooter/trunk/lib/screenshooter-simple-job.c (rev 0)
+++ xfce4-screenshooter/trunk/lib/screenshooter-simple-job.c 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,202 @@
+/* $Id$
+ *
+ * Copyright © 2008-2009 Jérôme Guelfucci <jerome.guelfucci at gmail.com>
+ *
+ * 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 Library General Public License for more details.
+ *
+ * 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.
+ */
+
+#include "screenshooter-simple-job.h"
+
+static void screenshooter_simple_job_class_init (ScreenshooterSimpleJobClass *klass);
+static void screenshooter_simple_job_finalize (GObject *object);
+static gboolean screenshooter_simple_job_execute (ExoJob *job,
+ GError **error);
+
+
+
+struct _ScreenshooterSimpleJobClass
+{
+ ScreenshooterJobClass __parent__;
+};
+
+struct _ScreenshooterSimpleJob
+{
+ ScreenshooterJob __parent__;
+ ScreenshooterSimpleJobFunc func;
+ GValueArray *param_values;
+};
+
+
+
+static GObjectClass *screenshooter_simple_job_parent_class;
+
+
+
+GType
+screenshooter_simple_job_get_type (void)
+{
+ static GType type = G_TYPE_INVALID;
+
+ if (G_UNLIKELY (type == G_TYPE_INVALID))
+ {
+ type = g_type_register_static_simple (SCREENSHOOTER_TYPE_JOB,
+ "ScreenshooterSimpleJob",
+ sizeof (ScreenshooterSimpleJobClass),
+ (GClassInitFunc) screenshooter_simple_job_class_init,
+ sizeof (ScreenshooterSimpleJob),
+ NULL,
+ 0);
+ }
+
+ return type;
+}
+
+
+
+static void
+screenshooter_simple_job_class_init (ScreenshooterSimpleJobClass *klass)
+{
+ GObjectClass *gobject_class;
+ ExoJobClass *exojob_class;
+
+ /* determine the parent type class */
+ screenshooter_simple_job_parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = screenshooter_simple_job_finalize;
+
+ exojob_class = EXO_JOB_CLASS (klass);
+ exojob_class->execute = screenshooter_simple_job_execute;
+}
+
+
+
+static void
+screenshooter_simple_job_finalize (GObject *object)
+{
+ ScreenshooterSimpleJob *simple_job = SCREENSHOOTER_SIMPLE_JOB (object);
+
+ /* release the param values */
+ g_value_array_free (simple_job->param_values);
+
+ (*G_OBJECT_CLASS (screenshooter_simple_job_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+screenshooter_simple_job_execute (ExoJob *job,
+ GError **error)
+{
+ ScreenshooterSimpleJob *simple_job = SCREENSHOOTER_SIMPLE_JOB (job);
+ gboolean success = TRUE;
+ GError *err = NULL;
+
+ g_return_val_if_fail (SCREENSHOOTER_IS_SIMPLE_JOB (job), FALSE);
+ g_return_val_if_fail (simple_job->func != NULL, FALSE);
+
+ /* try to execute the job using the supplied function */
+ success = (*simple_job->func) (SCREENSHOOTER_JOB (job), simple_job->param_values, &err);
+
+ if (!success)
+ {
+ g_assert (err != NULL || exo_job_is_cancelled (job));
+
+ /* set error if the job was cancelled. otherwise just propagate
+ * the results of the processing function */
+ if (exo_job_set_error_if_cancelled (job, error))
+ {
+ g_clear_error (&err);
+ }
+ else
+ {
+ if (err != NULL)
+ g_propagate_error (error, err);
+ }
+
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+
+
+/**
+ * screenshooter_simple_job_launch:
+ * @func : the #ScreenshooterSimpleJobFunc to execute the job.
+ * @n_param_values : the number of parameters to pass to the @func.
+ * @... : a list of #GType and parameter pairs (exactly
+ * @n_param_values pairs) that are passed to @func.
+ *
+ * Allocates a new #ScreenshooterSimpleJob, which executes the specified
+ * @func with the specified parameters.
+ *
+ * The caller is responsible to release the returned object using
+ * screenshooter_job_unref() when no longer needed.
+ *
+ * Return value: the launched #ScreenshooterJob.
+ **/
+ScreenshooterJob *
+screenshooter_simple_job_launch (ScreenshooterSimpleJobFunc func,
+ guint n_param_values,
+ ...)
+{
+ ScreenshooterSimpleJob *simple_job;
+ va_list var_args;
+ GValue value = { 0, };
+ gchar *error_message;
+ gint n;
+
+ /* allocate and initialize the simple job */
+ simple_job = g_object_new (SCREENSHOOTER_TYPE_SIMPLE_JOB, NULL);
+ simple_job->func = func;
+ simple_job->param_values = g_value_array_new (n_param_values);
+
+ /* collect the parameters */
+ va_start (var_args, n_param_values);
+ for (n = 0; n < n_param_values; ++n)
+ {
+ /* initialize the value to hold the next parameter */
+ g_value_init (&value, va_arg (var_args, GType));
+
+ /* collect the value from the stack */
+ G_VALUE_COLLECT (&value, var_args, 0, &error_message);
+
+ /* check if an error occurred */
+ if (G_UNLIKELY (error_message != NULL))
+ {
+ g_error ("%s: %s", G_STRLOC, error_message);
+ g_free (error_message);
+ }
+
+ g_value_array_insert (simple_job->param_values, n, &value);
+ g_value_unset (&value);
+ }
+ va_end (var_args);
+
+ /* launch the job */
+ return SCREENSHOOTER_JOB (exo_job_launch (EXO_JOB (simple_job)));
+}
+
+
+
+GValueArray *
+screenshooter_simple_job_get_param_values (ScreenshooterSimpleJob *job)
+{
+ g_return_val_if_fail (SCREENSHOOTER_IS_SIMPLE_JOB (job), NULL);
+
+ return job->param_values;
+}
Added: xfce4-screenshooter/trunk/lib/screenshooter-simple-job.h
===================================================================
--- xfce4-screenshooter/trunk/lib/screenshooter-simple-job.h (rev 0)
+++ xfce4-screenshooter/trunk/lib/screenshooter-simple-job.h 2009-05-15 16:23:26 UTC (rev 7340)
@@ -0,0 +1,70 @@
+/* $Id$
+ *
+ * Copyright © 2008-2009 Jérôme Guelfucci <jerome.guelfucci at gmail.com>
+ *
+ * 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 Library General Public License for more details.
+ *
+ * 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.
+ */
+
+#ifndef __SCREENSHOOTER_SIMPLE_JOB_H__
+#define __SCREENSHOOTER_SIMPLE_JOB_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "screenshooter-job.h"
+
+#include <gobject/gvaluecollector.h>
+#include <string.h>
+
+G_BEGIN_DECLS
+
+/**
+ * ScreenshooterSimpleJobFunc:
+ * @job : a #ScreenshooterJob.
+ * @param_values : a #GValueArray of the #GValue<!---->s passed to
+ * screenshooter_simple_job_launch().
+ * @error : return location for errors.
+ *
+ * Used by the #ScreenshooterSimpleJob to process the @job. See
+ * screenshooter_simple_job_launch() for further details.
+ *
+ * Return value: %TRUE on success, %FALSE in case of an error.
+ **/
+typedef gboolean (*ScreenshooterSimpleJobFunc) (ScreenshooterJob *job,
+ GValueArray *param_values,
+ GError **error);
+
+
+typedef struct _ScreenshooterSimpleJobClass ScreenshooterSimpleJobClass;
+typedef struct _ScreenshooterSimpleJob ScreenshooterSimpleJob;
+
+#define SCREENSHOOTER_TYPE_SIMPLE_JOB (screenshooter_simple_job_get_type ())
+#define SCREENSHOOTER_SIMPLE_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SCREENSHOOTER_TYPE_SIMPLE_JOB, ScreenshooterSimpleJob))
+#define SCREENSHOOTER_SIMPLE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SCREENSHOOTER_TYPE_SIMPLE_JOB, ScreenshooterSimpleJobClass))
+#define SCREENSHOOTER_IS_SIMPLE_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCREENSHOOTER_TYPE_SIMPLE_JOB))
+#define SCREENSHOOTER_IS_SIMPLE_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SCREENSHOOTER_TYPE_SIMPLE_JOB))
+#define SCREENSHOOTER_SIMPLE_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SCREENSHOOTER_TYPE_SIMPLE_JOB, ScreenshooterSimpleJobClass))
+
+GType screenshooter_simple_job_get_type (void) G_GNUC_CONST;
+
+ScreenshooterJob *screenshooter_simple_job_launch (ScreenshooterSimpleJobFunc func,
+ guint n_param_values,
+ ...) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+GValueArray *screenshooter_simple_job_get_param_values (ScreenshooterSimpleJob *job);
+
+G_END_DECLS
+
+#endif /* !__SCREENSHOOTER_SIMPLE_JOB_H__ */
Modified: xfce4-screenshooter/trunk/lib/screenshooter-zimagez.c
===================================================================
--- xfce4-screenshooter/trunk/lib/screenshooter-zimagez.c 2009-05-15 06:58:00 UTC (rev 7339)
+++ xfce4-screenshooter/trunk/lib/screenshooter-zimagez.c 2009-05-15 16:23:26 UTC (rev 7340)
@@ -45,43 +45,36 @@
-static gboolean
-warn_if_fault_occurred (xmlrpc_env * const envP);
+static void open_url_hook (GtkLinkButton *button,
+ const gchar *link,
+ gpointer user_data);
+static void open_zimagez_link (gpointer unused);
+static ScreenshooterJob *zimagez_upload_to_zimagez (const gchar *file_name);
+static gboolean zimagez_upload_job (ScreenshooterJob *job,
+ GValueArray *param_values,
+ GError **error);
+static void cb_ask_for_information (ScreenshooterJob *job,
+ GtkListStore *liststore,
+ const gchar *message,
+ gpointer unused);
+static void cb_image_uploaded (ScreenshooterJob *job,
+ gchar *upload_name,
+ gpointer unused);
+static void cb_error (ExoJob *job,
+ GError *error,
+ gpointer unused);
+static void cb_finished (ExoJob *job,
+ GtkWidget *dialog);
+static void cb_update_info (ExoJob *job,
+ gchar *message,
+ GtkWidget *label);
-static void
-open_url_hook (GtkLinkButton *button,
- const gchar *link,
- gpointer user_data);
-static void
-open_zimagez_link (gpointer unused);
-
-
/* Private */
-static gboolean warn_if_fault_occurred (xmlrpc_env * const envP)
-{
- gboolean error_occured = FALSE;
-
- if (envP->fault_occurred)
- {
- TRACE ("An error occured during the XML transaction %s, %d",
- envP->fault_string, envP->fault_code );
-
- xfce_err (_("An error occurred during the XML exchange: %s (%d).\n The screenshot "
- "could not be uploaded."),
- envP->fault_string, envP->fault_code );
-
- error_occured = TRUE;
- }
-
- return error_occured;
-}
-
-
static void
open_url_hook (GtkLinkButton *button, const gchar *link, gpointer user_data)
{
@@ -105,27 +98,24 @@
}
-/* Public */
+static gboolean
+zimagez_upload_job (ScreenshooterJob *job, GValueArray *param_values, GError **error)
+{
+ const gchar *encoded_data;
+ const gchar *image_path;
+ gchar *comment = g_strdup ("");
+ gchar *data = NULL;
+ gchar *encoded_password = NULL;
+ gchar *file_name = NULL;
+ gchar *login_response = NULL;
+ gchar *online_file_name = NULL;
+ gchar *password = g_strdup ("");
+ gchar *title = g_strdup ("");
+ gchar *user = g_strdup ("");
+ gsize data_length;
-/**
- * screenshooter_upload_to_zimagez:
- * @image_path: the local path of the image that should be uploaded to
- * ZimageZ.com.
- *
- * Uploads the image whose path is @image_path: a dialog asks for the user
- * login, password, a title for the image and a comment; then the image is
- * uploaded. The dialog is shown again with a warning is the password did
- * match the user name. The user can also cancel the upload procedure.
- *
- * Returns: NULL is the upload failed or was cancelled, a #gchar* with the name of
- * the image on Zimagez.com (see the API at the beginning of this file for more
- * details).
- **/
-
-gchar *screenshooter_upload_to_zimagez (const gchar *image_path)
-{
xmlrpc_env env;
xmlrpc_value *resultP = NULL;
xmlrpc_bool response = 0;
@@ -135,233 +125,184 @@
const gchar * const method_logout = "apiXml.xmlrpcLogout";
const gchar * const method_upload = "apiXml.xmlrpcUpload";
- gchar *data;
- gchar *password = NULL;
- gchar *user = NULL;
- gchar *title = NULL;
- gchar *comment = NULL;
- gchar *encoded_password = NULL;
- const gchar *encoded_data;
- const gchar *file_name = g_path_get_basename (image_path);
- const gchar *online_file_name;
- const gchar *login_response;
- gsize data_length;
+ GtkTreeIter iter;
+ GtkListStore *liststore;
- GtkWidget *dialog;
- GtkWidget *information_label;
- GtkWidget *vbox, *main_alignment;
- GtkWidget *table;
- GtkWidget *user_entry, *password_entry, *title_entry, *comment_entry;
- GtkWidget *user_label, *password_label, *title_label, *comment_label;
+ g_return_val_if_fail (SCREENSHOOTER_IS_JOB (job), FALSE);
+ g_return_val_if_fail (param_values != NULL, FALSE);
+ g_return_val_if_fail (param_values->n_values == 1, FALSE);
+ g_return_val_if_fail (G_VALUE_HOLDS_STRING (¶m_values->values[0]), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- /* Get the user information */
- /* Create the information dialog */
- dialog =
- xfce_titled_dialog_new_with_buttons (_("Details about the screenshot for ZimageZ©"),
- NULL,
- GTK_DIALOG_NO_SEPARATOR,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK,
- GTK_RESPONSE_OK,
- NULL);
+ if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
+ return FALSE;
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG(dialog)->vbox), 12);
+ /* Get the path of the image that is to be uploaded */
+ image_path = g_value_get_string (g_value_array_get_nth (param_values, 0));
- gtk_window_set_icon_name (GTK_WINDOW (dialog), "gtk-info");
- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+ /* Start the user XML RPC session */
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ exo_job_info_message (EXO_JOB (job), _("Initialize the connexion..."));
- /* Create the main alignment for the dialog */
+ TRACE ("Initialize the RPC environment");
+ xmlrpc_env_init(&env);
- main_alignment = gtk_alignment_new (0, 0, 1, 1);
+ TRACE ("Initialize the RPC client");
+ xmlrpc_client_init2 (&env, XMLRPC_CLIENT_NO_FLAGS, PACKAGE_NAME, PACKAGE_VERSION,
+ NULL, 0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (main_alignment), 6, 0, 12, 12);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_alignment, TRUE, TRUE, 0);
+ if (env.fault_occurred)
+ {
+ GError *tmp_error =
+ g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("An error occurred during the XML exchange: %s (%d).\n "
+ "The screenshot could not be uploaded."),
+ env.fault_string, env.fault_code);
- /* Create the main box for the dialog */
+ xmlrpc_env_clean (&env);
+ xmlrpc_client_cleanup ();
- vbox = gtk_vbox_new (FALSE, 10);
+ g_propagate_error (error, tmp_error);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+ return FALSE;
+ }
- gtk_container_add (GTK_CONTAINER (main_alignment), vbox);
+ TRACE ("Get the information liststore ready.");
- /* Create the information label */
+ liststore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- information_label = sexy_url_label_new ();
+ TRACE ("Append the user");
- /* Note for translators : make sure to put the <a>....</a> on the first line */
- sexy_url_label_set_markup (SEXY_URL_LABEL (information_label),
- _("Please file the following fields with your "
- "<a href=\"http://www.zimagez.com\">ZimageZ©</a> \n"
- "user name, passsword and details about the screenshot."));
+ gtk_list_store_append (liststore, &iter);
+ gtk_list_store_set (liststore, &iter,
+ 0, g_strdup ("user"),
+ 1, user,
+ -1);
- g_signal_connect_swapped (G_OBJECT (information_label), "url-activated",
- G_CALLBACK (open_zimagez_link), NULL);
+ TRACE ("Append the password");
- gtk_misc_set_alignment (GTK_MISC (information_label), 0, 0);
+ gtk_list_store_append (liststore, &iter);
+ gtk_list_store_set (liststore, &iter,
+ 0, g_strdup ("password"),
+ 1, password,
+ -1);
- gtk_container_add (GTK_CONTAINER (vbox), information_label);
+ TRACE ("Append the title");
- /* Create the layout table */
+ gtk_list_store_append (liststore, &iter);
+ gtk_list_store_set (liststore, &iter,
+ 0, g_strdup ("title"),
+ 1, title,
+ -1);
- table = gtk_table_new (4, 2, FALSE);
+ TRACE ("Append the comment");
- gtk_table_set_col_spacings (GTK_TABLE (table), 6);
- gtk_table_set_row_spacings (GTK_TABLE (table), 12);
+ gtk_list_store_append (liststore, &iter);
+ gtk_list_store_set (liststore, &iter,
+ 0, g_strdup ("comment"),
+ 1, comment,
+ -1);
- gtk_container_add (GTK_CONTAINER (vbox), table);
+ TRACE ("Ask for the user information");
- /* Create the user label */
- user_label = gtk_label_new (_("User:"));
+ screenshooter_job_ask_info (job, liststore,
+ _("Please file the following fields with your "
+ "<a href=\"http://www.zimagez.com\">ZimageZ©</a> \n"
+ "user name, passsword and details about the screenshot."));
- gtk_misc_set_alignment (GTK_MISC (user_label), 0, 0.5);
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (liststore), &iter);
- gtk_table_attach (GTK_TABLE (table), user_label,
- 0, 1,
- 0, 1,
- GTK_FILL, GTK_FILL,
- 0, 0);
+ do
+ {
+ gchar *field_name = NULL;
+ gchar *field_value = NULL;
- /* Create the user entry */
- user_entry = gtk_entry_new ();
+ gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter,
+ 0, &field_name,
+ 1, &field_value,
+ -1);
- gtk_widget_set_tooltip_text (user_entry,
- _("Your Zimagez user name, if you do not have one yet"
- "please create one on the Web page linked above"));
+ if (g_str_equal (field_name, "user"))
+ {
+ user = g_strdup (field_value);
+ }
+ else if (g_str_equal (field_name, "password"))
+ {
+ password = g_strdup (field_value);
+ }
+ else if (g_str_equal (field_name, "title"))
+ {
+ title = g_strdup (field_value);
+ }
+ else if (g_str_equal (field_name, "comment"))
+ {
+ comment = g_strdup (field_value);
+ }
+ g_free (field_name);
+ g_free (field_value);
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (liststore), &iter));
- gtk_table_attach_defaults (GTK_TABLE (table), user_entry, 1, 2, 0, 1);
-
- /* Create the password label */
- password_label = gtk_label_new (_("Password:"));
-
- gtk_misc_set_alignment (GTK_MISC (password_label), 0, 0.5);
-
- gtk_table_attach (GTK_TABLE (table), password_label,
- 0, 1,
- 1, 2,
- GTK_FILL, GTK_FILL,
- 0, 0);
-
- /* Create the password entry */
- password_entry = gtk_entry_new ();
-
- gtk_widget_set_tooltip_text (password_entry, _("The password for the user above"));
-
- gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE);
-
- gtk_table_attach_defaults (GTK_TABLE (table), password_entry, 1, 2, 1, 2);
-
- /* Create the title label */
- title_label = gtk_label_new (_("Title:"));
-
- gtk_misc_set_alignment (GTK_MISC (title_label), 0, 0.5);
-
- gtk_table_attach (GTK_TABLE (table), title_label,
- 0, 1,
- 2, 3,
- GTK_FILL, GTK_FILL,
- 0, 0);
-
- /* Create the title entry */
- title_entry = gtk_entry_new ();
-
- gtk_widget_set_tooltip_text (title_entry,
- _("The title of the screenshot, it will be used when"
- " displaying the screenshot on ZimageZ"));
-
- gtk_table_attach_defaults (GTK_TABLE (table), title_entry, 1, 2, 2, 3);
-
- /* Create the comment label */
- comment_label = gtk_label_new (_("Comment:"));
-
- gtk_misc_set_alignment (GTK_MISC (comment_label), 0, 0.5);
-
- gtk_table_attach (GTK_TABLE (table), comment_label,
- 0, 1,
- 3, 4,
- GTK_FILL, GTK_FILL,
- 0, 0);
-
- /* Create the comment entry */
- comment_entry = gtk_entry_new ();
-
- gtk_widget_set_tooltip_text (title_entry,
- _("A comment on the screenshot, it will be used when"
- " displaying the screenshot on ZimageZ"));
-
- gtk_table_attach_defaults (GTK_TABLE (table), comment_entry, 1, 2, 3, 4);
-
- /* Show the widgets of the dialog main box*/
-
- gtk_widget_show_all (GTK_DIALOG(dialog)->vbox);
-
- /* Start the user XML RPC session */
-
- TRACE ("Initiate the RPC environment");
- xmlrpc_env_init(&env);
-
- TRACE ("Initiate the RPC client");
- xmlrpc_client_init2 (&env, XMLRPC_CLIENT_NO_FLAGS, PACKAGE_NAME, PACKAGE_VERSION,
- NULL, 0);
-
- if (warn_if_fault_occurred (&env))
+ if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
{
xmlrpc_env_clean (&env);
xmlrpc_client_cleanup ();
- return NULL;
+ TRACE ("The upload job was cancelled.");
+
+ return FALSE;
}
while (!response)
{
- gint dialog_response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gboolean empty_field = FALSE;
- if (dialog_response == GTK_RESPONSE_CANCEL)
+ if (exo_job_set_error_if_cancelled (EXO_JOB (job), error))
{
xmlrpc_env_clean (&env);
xmlrpc_client_cleanup ();
- return NULL;
+ g_free (user);
+ g_free (password);
+ g_free (title);
+ g_free (comment);
+ if (encoded_password != NULL)
+ g_free (encoded_password);
+
+ TRACE ("The upload job was cancelled.");
+
+ return FALSE;
}
- user = g_strdup (gtk_entry_get_text (GTK_ENTRY (user_entry)));
- password = g_strdup (gtk_entry_get_text (GTK_ENTRY (password_entry)));
- title = g_strdup (gtk_entry_get_text (GTK_ENTRY (title_entry)));
- comment = g_strdup (gtk_entry_get_text (GTK_ENTRY (comment_entry)));
+ exo_job_info_message (EXO_JOB (job), _("Check the user information..."));
- if ((dialog_response == GTK_RESPONSE_OK) && (g_str_equal (user, "") ||
- g_str_equal (password, "") ||
- g_str_equal (title, "") ||
- g_str_equal (comment, "")))
+ /* Test if one of the information fields is empty */
+ TRACE ("Check for empty fields");
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (liststore), &iter);
+
+ do
{
- TRACE ("One of the fields was empty, let the user file it.");
+ gchar *field = NULL;
- gtk_label_set_markup (GTK_LABEL (information_label),
- _("<span weight=\"bold\" foreground=\"darkred\" "
- "stretch=\"semiexpanded\">You must fill all the "
- " fields.</span>"));
+ gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, 1, &field, -1);
+ empty_field = g_str_equal (field, "");
- g_free (user);
- g_free (password);
- g_free (title);
- g_free (comment);
+ g_free (field);
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (liststore), &iter));
+ if (empty_field)
+ {
+ TRACE ("One of the fields was empty, let the user file it.");
+
+ screenshooter_job_ask_info (job, liststore,
+ _("<span weight=\"bold\" foreground=\"darkred\" "
+ "stretch=\"semiexpanded\">You must fill all the "
+ " fields.</span>"));
continue;
}
- else
- {
- TRACE ("All fields were filed");
- gtk_widget_hide (dialog);
- }
- while (gtk_events_pending ())
- gtk_main_iteration_do (FALSE);
-
encoded_password = g_strdup (g_strreverse (rot13 (password)));
TRACE ("User: %s", user);
@@ -369,11 +310,19 @@
/* Start the user session */
TRACE ("Call the login method");
+ exo_job_info_message (EXO_JOB (job), _("Login on ZimageZ.com..."));
+
resultP = xmlrpc_client_call (&env, serverurl, method_login,
"(ss)", user, encoded_password);
- if (warn_if_fault_occurred (&env))
+ if (env.fault_occurred)
{
+ GError *tmp_error =
+ g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("An error occurred during the XML exchange: %s (%d).\n "
+ "The screenshot could not be uploaded."),
+ env.fault_string, env.fault_code);
+
xmlrpc_env_clean (&env);
xmlrpc_client_cleanup ();
@@ -383,7 +332,9 @@
g_free (comment);
g_free (encoded_password);
- return NULL;
+ g_propagate_error (error, tmp_error);
+
+ return FALSE;
}
TRACE ("Read the login response");
@@ -393,8 +344,14 @@
{
xmlrpc_read_bool (&env, resultP, &response);
- if (warn_if_fault_occurred (&env))
+ if (env.fault_occurred)
{
+ GError *tmp_error =
+ g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("An error occurred during the XML exchange: %s (%d).\n "
+ "The screenshot could not be uploaded."),
+ env.fault_string, env.fault_code);
+
xmlrpc_env_clean (&env);
xmlrpc_client_cleanup ();
@@ -404,9 +361,10 @@
g_free (comment);
g_free (encoded_password);
- return NULL;
+ g_propagate_error (error, tmp_error);
+
+ return FALSE;
}
-
}
/* Else we read the string response to get the session ID */
else
@@ -414,35 +372,101 @@
TRACE ("Read the session ID");
xmlrpc_read_string (&env, resultP, (const gchar ** const)&login_response);
- if (warn_if_fault_occurred (&env))
- {
- xmlrpc_env_clean (&env);
- xmlrpc_client_cleanup ();
+ if (env.fault_occurred)
+ {
+ GError *tmp_error =
+ g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("An error occurred during the XML exchange: %s (%d).\n "
+ "The screenshot could not be uploaded."),
+ env.fault_string, env.fault_code);
- g_free (user);
- g_free (password);
- g_free (title);
- g_free (comment);
- g_free (encoded_password);
+ xmlrpc_env_clean (&env);
+ xmlrpc_client_cleanup ();
- return NULL;
- }
+ g_free (user);
+ g_free (password);
+ g_free (title);
+ g_free (comment);
+ g_free (encoded_password);
+ g_propagate_error (error, tmp_error);
+
+ return FALSE;
+ }
+
response = 1;
}
if (!response)
- gtk_label_set_markup (GTK_LABEL (information_label),
- _("<span weight=\"bold\" foreground=\"darkred\" "
- "stretch=\"semiexpanded\">The user and the password you"
- " entered do not match.</span>"));
+ {
+ /* Login failed, erase the password and ask for the correct on to the
+ user */
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (liststore), &iter);
+ do
+ {
+ gchar *field_name = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter, 0, &field_name, -1);
+
+ if (g_str_equal (field_name, "password"))
+ {
+ gtk_list_store_set (liststore, &iter, 1, g_strdup (""), -1);
+
+ g_free (field_name);
+
+ break;
+ }
+
+ g_free (field_name);
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (liststore), &iter));
+
+ screenshooter_job_ask_info (job, liststore,
+ _("<span weight=\"bold\" foreground=\"darkred\" "
+ "stretch=\"semiexpanded\">The user and the "
+ "password you entered do not match. "
+ "Please correct this.</span>"));
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (liststore), &iter);
+
+ do
+ {
+ gchar *field_name = NULL;
+ gchar *field_value = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter,
+ 0, &field_name,
+ 1, &field_value,
+ -1);
+
+ if (g_str_equal (field_name, "user"))
+ {
+ user = g_strdup (field_value);
+ }
+ else if (g_str_equal (field_name, "password"))
+ {
+ password = g_strdup (field_value);
+ }
+ else if (g_str_equal (field_name, "title"))
+ {
+ title = g_strdup (field_value);
+ }
+ else if (g_str_equal (field_name, "comment"))
+ {
+ comment = g_strdup (field_value);
+ }
+
+ g_free (field_name);
+ g_free (field_value);
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (liststore), &iter));
+ }
}
xmlrpc_DECREF (resultP);
- gtk_widget_destroy (dialog);
-
+ g_free (user);
g_free (password);
g_free (encoded_password);
@@ -453,21 +477,34 @@
g_free (data);
+ /* Get the basename of the image path */
+ file_name = g_path_get_basename (image_path);
+
+ exo_job_info_message (EXO_JOB (job), _("Upload the screenshot..."));
+
TRACE ("Call the upload method");
resultP = xmlrpc_client_call (&env, serverurl, method_upload,
"(sssss)", encoded_data, file_name, title, comment,
login_response);
- g_free (user);
g_free (title);
g_free (comment);
+ g_free (file_name);
- if (warn_if_fault_occurred (&env))
+ if (env.fault_occurred)
{
+ GError *tmp_error =
+ g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("An error occurred during the XML exchange: %s (%d).\n "
+ "The screenshot could not be uploaded."),
+ env.fault_string, env.fault_code);
+
xmlrpc_env_clean (&env);
xmlrpc_client_cleanup ();
- return NULL;
+ g_propagate_error (error, tmp_error);
+
+ return FALSE;
}
/* If the response is a boolean, there was an error */
@@ -477,25 +514,35 @@
xmlrpc_read_bool (&env, resultP, &response_upload);
- if (warn_if_fault_occurred (&env))
+ if (env.fault_occurred)
{
+ GError *tmp_error =
+ g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("An error occurred during the XML exchange: %s (%d).\n "
+ "The screenshot could not be uploaded."),
+ env.fault_string, env.fault_code);
+
xmlrpc_env_clean (&env);
xmlrpc_client_cleanup ();
- return NULL;
+ g_propagate_error (error, tmp_error);
+
+ return FALSE;
}
- if (!response_upload)
- {
- xfce_err (_("An error occurred while uploading the screenshot."));
+ if (!response_upload)
+ {
+ GError *tmp_error =
+ g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("An error occurred while uploading the screenshot."));
- TRACE ("Error while uploading the screenshot.");
+ xmlrpc_env_clean (&env);
+ xmlrpc_client_cleanup ();
- xmlrpc_env_clean (&env);
- xmlrpc_client_cleanup ();
+ g_propagate_error (error, tmp_error);
- return NULL;
- }
+ return FALSE;
+ }
}
/* Else we get the file name */
else
@@ -504,12 +551,20 @@
TRACE ("The screenshot has been uploaded, get the file name.");
- if (warn_if_fault_occurred (&env))
+ if (env.fault_occurred)
{
+ GError *tmp_error =
+ g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("An error occurred during the XML exchange: %s (%d).\n "
+ "The screenshot could not be uploaded."),
+ env.fault_string, env.fault_code);
+
xmlrpc_env_clean (&env);
xmlrpc_client_cleanup ();
- return NULL;
+ g_propagate_error (error, tmp_error);
+
+ return FALSE;
}
}
@@ -517,6 +572,8 @@
/* End the user session */
+ exo_job_info_message (EXO_JOB (job), _("Close the session on ZimageZ.com..."));
+
TRACE ("Closing the user session");
xmlrpc_client_call (&env, serverurl, method_logout, "(s)", login_response);
@@ -525,29 +582,309 @@
xmlrpc_env_clean (&env);
xmlrpc_client_cleanup ();
- return g_strdup (online_file_name);
+ screenshooter_job_image_uploaded (job, online_file_name);
+
+ return TRUE;
}
-/**
- * screenshooter_display_zimagez_links:
- * @upload_name: the name of the image on ZimageZ.com
- *
- * Shows a dialog linking to the different images hosted on ZimageZ.com:
- * the full size image, the large thumbnail and the small thumbnail.
- * Links can be clicked to open the given page in a browser.
- **/
-void screenshooter_display_zimagez_links (const gchar *upload_name)
+static ScreenshooterJob
+*zimagez_upload_to_zimagez (const gchar *file_path)
{
+ g_return_val_if_fail (file_path != NULL, NULL);
+
+ return screenshooter_simple_job_launch (zimagez_upload_job, 1,
+ G_TYPE_STRING, file_path);
+}
+
+
+
+static void
+cb_ask_for_information (ScreenshooterJob *job,
+ GtkListStore *liststore,
+ const gchar *message,
+ gpointer unused)
+{
GtkWidget *dialog;
+ GtkWidget *information_label;
+ GtkWidget *vbox, *main_alignment;
+ GtkWidget *table;
+ GtkWidget *user_entry, *password_entry, *title_entry, *comment_entry;
+ GtkWidget *user_label, *password_label, *title_label, *comment_label;
+
+ GtkTreeIter iter;
+ gint response;
+
+ g_return_if_fail (SCREENSHOOTER_IS_JOB (job));
+ g_return_if_fail (GTK_IS_LIST_STORE (liststore));
+ g_return_if_fail (message != NULL);
+
+ TRACE ("Create the dialog to ask for user information.");
+
+ /* Create the information dialog */
+ dialog =
+ xfce_titled_dialog_new_with_buttons (_("Details about the screenshot for ZimageZ©"),
+ NULL,
+ GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG(dialog)->vbox), 12);
+
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "gtk-info");
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ /* Create the main alignment for the dialog */
+ main_alignment = gtk_alignment_new (0, 0, 1, 1);
+
+ gtk_alignment_set_padding (GTK_ALIGNMENT (main_alignment), 6, 0, 12, 12);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_alignment, TRUE, TRUE, 0);
+
+ /* Create the main box for the dialog */
+ vbox = gtk_vbox_new (FALSE, 10);
+
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+ gtk_container_add (GTK_CONTAINER (main_alignment), vbox);
+
+ /* Create the information label */
+ information_label = sexy_url_label_new ();
+
+ sexy_url_label_set_markup (SEXY_URL_LABEL (information_label), message);
+
+ g_signal_connect_swapped (G_OBJECT (information_label), "url-activated",
+ G_CALLBACK (open_zimagez_link), NULL);
+
+ gtk_misc_set_alignment (GTK_MISC (information_label), 0, 0);
+ gtk_container_add (GTK_CONTAINER (vbox), information_label);
+
+ /* Create the layout table */
+ table = gtk_table_new (4, 2, FALSE);
+
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 12);
+
+ gtk_container_add (GTK_CONTAINER (vbox), table);
+
+ /* Create the user label */
+ user_label = gtk_label_new (_("User:"));
+
+ gtk_misc_set_alignment (GTK_MISC (user_label), 0, 0.5);
+
+ gtk_table_attach (GTK_TABLE (table), user_label,
+ 0, 1,
+ 0, 1,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ /* Create the user entry */
+ user_entry = gtk_entry_new ();
+
+ gtk_widget_set_tooltip_text (user_entry,
+ _("Your Zimagez user name, if you do not have one yet"
+ "please create one on the Web page linked above"));
+
+
+ gtk_table_attach_defaults (GTK_TABLE (table), user_entry, 1, 2, 0, 1);
+
+ /* Create the password label */
+ password_label = gtk_label_new (_("Password:"));
+
+ gtk_misc_set_alignment (GTK_MISC (password_label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), password_label,
+ 0, 1,
+ 1, 2,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ /* Create the password entry */
+ password_entry = gtk_entry_new ();
+
+ gtk_widget_set_tooltip_text (password_entry, _("The password for the user above"));
+
+ gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE);
+ gtk_table_attach_defaults (GTK_TABLE (table), password_entry, 1, 2, 1, 2);
+
+ /* Create the title label */
+ title_label = gtk_label_new (_("Title:"));
+
+ gtk_misc_set_alignment (GTK_MISC (title_label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), title_label,
+ 0, 1,
+ 2, 3,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ /* Create the title entry */
+ title_entry = gtk_entry_new ();
+
+ gtk_widget_set_tooltip_text (title_entry,
+ _("The title of the screenshot, it will be used when"
+ " displaying the screenshot on ZimageZ"));
+
+ gtk_table_attach_defaults (GTK_TABLE (table), title_entry, 1, 2, 2, 3);
+
+ /* Create the comment label */
+ comment_label = gtk_label_new (_("Comment:"));
+
+ gtk_misc_set_alignment (GTK_MISC (comment_label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), comment_label,
+ 0, 1,
+ 3, 4,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ /* Create the comment entry */
+ comment_entry = gtk_entry_new ();
+
+ gtk_widget_set_tooltip_text (title_entry,
+ _("A comment on the screenshot, it will be used when"
+ " displaying the screenshot on ZimageZ"));
+
+ gtk_table_attach_defaults (GTK_TABLE (table), comment_entry, 1, 2, 3, 4);
+
+ /* Set the values */
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (liststore), &iter);
+
+ do
+ {
+ gchar *field_name = NULL;
+ gchar *field_value = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter,
+ 0, &field_name,
+ 1, &field_value,
+ -1);
+
+ if (g_str_equal (field_name, "user"))
+ {
+ gtk_entry_set_text (GTK_ENTRY (user_entry), field_value);
+ }
+ else if (g_str_equal (field_name, "password"))
+ {
+ gtk_entry_set_text (GTK_ENTRY (password_entry), field_value);
+ }
+ else if (g_str_equal (field_name, "title"))
+ {
+ gtk_entry_set_text (GTK_ENTRY (title_entry), field_value);
+ }
+ else if (g_str_equal (field_name, "comment"))
+ {
+ gtk_entry_set_text (GTK_ENTRY (comment_entry), field_value);
+ }
+
+ g_free (field_name);
+ g_free (field_value);
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (liststore), &iter));
+
+ gtk_widget_show_all (GTK_DIALOG(dialog)->vbox);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_hide (dialog);
+
+ if (response == GTK_RESPONSE_CANCEL)
+ {
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_image_uploaded,
+ NULL);
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_error,
+ NULL);
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_ask_for_information,
+ NULL);
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_update_info,
+ NULL);
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_finished,
+ NULL);
+
+ exo_job_cancel (EXO_JOB (job));
+ }
+ else if (response == GTK_RESPONSE_OK)
+ {
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (liststore), &iter);
+
+ do
+ {
+ gchar *field_name = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (liststore), &iter,
+ 0, &field_name, -1);
+
+ if (g_str_equal (field_name, "user"))
+ {
+ gtk_list_store_set (liststore, &iter,
+ 1, gtk_entry_get_text (GTK_ENTRY (user_entry)),
+ -1);
+ }
+ else if (g_str_equal (field_name, "password"))
+ {
+ gtk_list_store_set (liststore, &iter,
+ 1, gtk_entry_get_text (GTK_ENTRY (password_entry)),
+ -1);
+ }
+ else if (g_str_equal (field_name, "title"))
+ {
+ gtk_list_store_set (liststore, &iter,
+ 1, gtk_entry_get_text (GTK_ENTRY (title_entry)),
+ -1);
+ }
+ else if (g_str_equal (field_name, "comment"))
+ {
+ gtk_list_store_set (liststore, &iter,
+ 1, gtk_entry_get_text (GTK_ENTRY (comment_entry)),
+ -1);
+ }
+
+ g_free (field_name);
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL (liststore), &iter));
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+
+
+static void cb_image_uploaded (ScreenshooterJob *job, gchar *upload_name, gpointer unused)
+{
+ GtkWidget *dialog;
GtkWidget *image_link, *thumbnail_link, *small_thumbnail_link;
- gchar *image_url =
- g_strdup_printf ("http://www.zimagez.com/zimage/%s.php", upload_name);
- gchar *thumbnail_url =
+ gchar *image_url;
+ gchar *thumbnail_url;
+ gchar *small_thumbnail_url;
+
+ g_return_if_fail (upload_name != NULL);
+
+ image_url = g_strdup_printf ("http://www.zimagez.com/zimage/%s.php", upload_name);
+ thumbnail_url =
g_strdup_printf ("http://www.zimagez.com/miniature/%s.php", upload_name);
- gchar *small_thumbnail_url =
+ small_thumbnail_url =
g_strdup_printf ("http://www.zimagez.com/avatar/%s.php", upload_name);
dialog =
@@ -567,14 +904,12 @@
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
/* Create the image link */
-
image_link =
gtk_link_button_new_with_label (image_url, _("Link to the full-size screenshot"));
gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), image_link);
/* Create the thumbnail link */
-
thumbnail_link =
gtk_link_button_new_with_label (thumbnail_url,
_("Link to a thumbnail of the screenshot"));
@@ -582,7 +917,6 @@
gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), thumbnail_link);
/* Create the small thumbnail link */
-
small_thumbnail_link =
gtk_link_button_new_with_label (small_thumbnail_url,
_("Link to a small thumbnail of the screenshot"));
@@ -590,7 +924,6 @@
gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), small_thumbnail_link);
/* Set the url hook for the buttons */
-
gtk_link_button_set_uri_hook ((GtkLinkButtonUriFunc) open_url_hook, NULL, NULL);
/* Show the dialog and run it */
@@ -600,13 +933,133 @@
gtk_widget_destroy (dialog);
- /* Ugly hack to make sure the dialog is not displayed anymore */
- while (gtk_events_pending ())
- gtk_main_iteration_do (FALSE);
-
g_free (image_url);
g_free (thumbnail_url);
g_free (small_thumbnail_url);
}
+
+static void cb_error (ExoJob *job, GError *error, gpointer unused)
+{
+ GtkWidget *dialog;
+
+ g_return_if_fail (error != NULL);
+
+ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "%s", error->message);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+
+
+static void cb_finished (ExoJob *job, GtkWidget *dialog)
+{
+ g_return_if_fail (EXO_IS_JOB (job));
+ g_return_if_fail (GTK_IS_DIALOG (dialog));
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_image_uploaded,
+ NULL);
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_error,
+ NULL);
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_ask_for_information,
+ NULL);
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_update_info,
+ NULL);
+
+ g_signal_handlers_disconnect_matched (job,
+ G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL,
+ cb_finished,
+ NULL);
+
+ g_object_unref (G_OBJECT (job));
+
+ gtk_widget_destroy (dialog);
+
+ gtk_main_quit ();
+}
+
+
+
+static void cb_update_info (ExoJob *job, gchar *message, GtkWidget *label)
+{
+ g_return_if_fail (EXO_IS_JOB (job));
+ g_return_if_fail (GTK_IS_LABEL (label));
+
+ gtk_label_set_text (GTK_LABEL (label), message);
+}
+
+
+
+/* Public */
+
+
+
+/**
+ * screenshooter_upload_to_zimagez:
+ * @image_path: the local path of the image that should be uploaded to
+ * ZimageZ.com.
+ *
+ * Uploads the image whose path is @image_path: a dialog asks for the user
+ * login, password, a title for the image and a comment; then the image is
+ * uploaded. The dialog is shown again with a warning is the password did
+ * match the user name. The user can also cancel the upload procedure.
+ *
+ **/
+
+void screenshooter_upload_to_zimagez (const gchar *image_path)
+{
+ ScreenshooterJob *job;
+ GtkWidget *dialog = NULL;
+ GtkWidget *label;
+
+ g_return_if_fail (image_path != NULL);
+
+ dialog =
+ gtk_dialog_new_with_buttons (_("Uploading to ZimageZ..."),
+ NULL,
+ GTK_DIALOG_NO_SEPARATOR,
+ NULL);
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), 20);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG(dialog)->vbox), 12);
+ gtk_window_set_deletable (GTK_WINDOW (dialog), FALSE);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "gtk-info");
+
+ label = gtk_label_new ("");
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
+ gtk_widget_show (label);
+
+ job = zimagez_upload_to_zimagez (image_path);
+
+ g_signal_connect (job, "ask", (GCallback) cb_ask_for_information, NULL);
+ g_signal_connect (job, "image-uploaded", (GCallback) cb_image_uploaded, NULL);
+ g_signal_connect (job, "error", (GCallback) cb_error, NULL);
+ g_signal_connect (job, "finished", (GCallback) cb_finished, dialog);
+ g_signal_connect (job, "info-message", (GCallback) cb_update_info, label);
+
+ gtk_widget_show (dialog);
+
+ gtk_main ();
+}
Modified: xfce4-screenshooter/trunk/lib/screenshooter-zimagez.h
===================================================================
--- xfce4-screenshooter/trunk/lib/screenshooter-zimagez.h 2009-05-15 06:58:00 UTC (rev 7339)
+++ xfce4-screenshooter/trunk/lib/screenshooter-zimagez.h 2009-05-15 16:23:26 UTC (rev 7340)
@@ -31,10 +31,11 @@
#include <xmlrpc-c/client.h>
#include "screenshooter-utils.h"
+#include "screenshooter-simple-job.h"
#include "sexy-url-label.h"
-gchar *screenshooter_upload_to_zimagez (const gchar *image_path);
-void screenshooter_display_zimagez_links (const gchar *upload_name);
+void screenshooter_upload_to_zimagez (const gchar *image_path);
+
#endif
Modified: xfce4-screenshooter/trunk/src/main.c
===================================================================
--- xfce4-screenshooter/trunk/src/main.c 2009-05-15 06:58:00 UTC (rev 7339)
+++ xfce4-screenshooter/trunk/src/main.c 2009-05-15 16:23:26 UTC (rev 7340)
@@ -22,6 +22,8 @@
#endif
#include "libscreenshooter.h"
+#include <glib.h>
+#include <stdlib.h>
@@ -194,7 +196,7 @@
-int main(int argc, char **argv)
+int main (int argc, char **argv)
{
GError *cli_error = NULL;
GFile *default_save_dir;
@@ -214,14 +216,15 @@
g_print (_("%s: %s\nTry %s --help to see a full list of"
" available command line options.\n"),
PACKAGE, cli_error->message, PACKAGE_NAME);
-
+
g_error_free (cli_error);
-
- return 1;
+
+ return EXIT_FAILURE;
}
}
- g_thread_init (NULL);
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
/* Read the preferences */
@@ -235,7 +238,7 @@
/* Check if the directory read from the preferences is valid */
default_save_dir = g_file_new_for_uri (sd->screenshot_dir);
-
+
if (G_UNLIKELY (!g_file_query_exists (default_save_dir, NULL)))
{
g_free (sd->screenshot_dir);
@@ -249,8 +252,8 @@
if (version)
{
g_print ("%s\n", PACKAGE_STRING);
-
- return 0;
+
+ return EXIT_SUCCESS;
}
/* If a region cli option is given, take the screenshot accordingly.*/
@@ -269,7 +272,7 @@
{
sd->region = SELECT;
}
-
+
/* Wether to show the save dialog allowing to choose a filename
* and a save location */
no_save_dialog ? (sd->show_save_dialog = 0) : (sd->show_save_dialog = 1);
@@ -339,5 +342,7 @@
g_free (sd->app);
g_free (sd);
- return 0;
+ TRACE ("Ciao");
+
+ return EXIT_SUCCESS;
}
More information about the Goodies-commits
mailing list