/* Screem: skel-plugin.c * * Copyright (C) 2004 David A Knight * * 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include "screem-skel-plugin.h" /* setup your plugin here */ #include "fileops.h" #include "support.h" /* plugin name should only include a-zA-Z */ static const gchar *plugin_name = "ScreemObjectWizard"; static const gchar *authors[] = { "David A Knight ", NULL }; static const gchar *displayed_name = N_( "Screem Object and Image Wizard" ); static const gchar *description = N_( "A wizard to insert and tags in HTML documents" ); static const gchar *version = "2.0.0"; /* add any per instance data items here */ struct ScreemSkelPluginPrivate { gchar *type; const gchar *tag; /* img or object */ }; static GnomeThumbnailFactory *factory = NULL; static void object_wizard_display( GtkAction *action, gpointer user_data ); static void insert_object_href_changed( GtkWidget *entry, ScreemPlugin *plugin ); static void insert_object_markup( ScreemPlugin *plugin, GtkWidget *widget ); /** * setup: * * this function will be called once for each window, * you should add any actions / ui here, eg. * * screem_plugin_add_action( plugin, name, label, tip, stock_id, * callback, error ); * screem_plugin_add_menu( plugin, path, action, error ); * screem_plugin_add_toolbar( plugin, path, action, error ); * * * to insert text into the current page being edited your callbacks * should make use of * screem_plugin_get_cursor_position( plugin ) * screem_plugin_set_cursor_position( plugin, pos ) * screem_plugin_insert( plugin, pos, text, length, indent ) * **/ static gboolean setup( ScreemPlugin *plugin ) { GError *error; gboolean ret; ret = TRUE; if( ! screem_plugin_add_interface( plugin, "ObjectWizard", _( "Object" ), _( "Insert an object, such as a video clip, sound clip, image etc." ), "Screem_Object", G_CALLBACK( object_wizard_display ), &error ) ) { ret = FALSE; g_print( "Add interface failed: %s\n", error->message ); g_error_free( error ); } if( ret && ! screem_plugin_add_interface( plugin, "ImageWizard", _( "Image" ), _( "Insert an Image" ), "Screem_Image", G_CALLBACK( object_wizard_display ), &error ) ) { ret = FALSE; g_print( "Add interface failed: %s\n", error->message ); g_error_free( error ); } return ret; } /** * cleanup: * * this function will be called once for each window when * it is closed, you should cleanup any data items you * have in ScreemSkelPluginPrivate here **/ static void cleanup( ScreemSkelPluginPrivate *priv ) { g_free( priv->type ); } static void object_wizard_display( GtkAction *action, gpointer user_data ) { ScreemPlugin *plugin; ScreemSkelPluginPrivate *priv; ScreemSite *site; ScreemPage *page; GtkWidget *widget; GladeXML *xml; gint button; const gchar *pathname; plugin = SCREEM_PLUGIN( user_data ); priv = SCREEM_SKEL_PLUGIN( plugin )->priv; page = screem_plugin_get_current_document( plugin ); if( page ) { if( ! strcmp( "ObjectWizard", gtk_action_get_name( action ) ) ) { priv->tag = "object"; } else { priv->tag = "img"; } site = screem_plugin_get_current_site( plugin ); pathname = screem_site_get_pathname( site ); xml = glade_xml_new( GLADE_PATH"/object-wizard.glade", "insert_object", NULL ); widget = glade_xml_get_widget( xml, "data" ); g_object_set_data( G_OBJECT( widget ), "plugin", plugin ); if( pathname ) { gtk_file_chooser_set_current_folder_uri( GTK_FILE_CHOOSER( widget ), pathname ); } g_signal_connect( G_OBJECT( widget ), "selection-changed", G_CALLBACK( insert_object_href_changed ), plugin ); widget = glade_xml_get_widget( xml, "alt" ); screem_gtk_add_history( widget ); widget = glade_xml_get_widget( xml, "alignment" ); gtk_combo_box_set_active( GTK_COMBO_BOX( widget ), 0 ); widget = glade_xml_get_widget( xml, "copy" ); pathname = screem_page_get_pathname( page ); gtk_widget_set_sensitive( widget, pathname != NULL ); glade_xml_signal_autoconnect( xml ); widget = glade_xml_get_widget( xml, "insert_object" ); screem_plugin_restore_from_session( plugin, widget ); button = gtk_dialog_run( GTK_DIALOG( widget ) ); screem_plugin_store_in_session( plugin, widget ); if( button == GTK_RESPONSE_APPLY ) { insert_object_markup( plugin, widget ); } widget = glade_xml_get_widget( xml, "insert_object" ); gtk_widget_destroy( widget ); g_object_unref( G_OBJECT( xml ) ); } } static void insert_object_href_changed( GtkWidget *entry, ScreemPlugin *plugin ) { ScreemSkelPluginPrivate *priv; GladeXML *xml; gchar *href; GnomeVFSFileInfo *info; gchar *uri; GdkPixbuf *pixbuf; GtkWidget *preview; gint width; gint height; priv = SCREEM_SKEL_PLUGIN( plugin )->priv; xml = glade_get_widget_tree( entry ); href = gtk_file_chooser_get_uri( GTK_FILE_CHOOSER( entry ) ); info = gnome_vfs_file_info_new(); g_free( priv->type ); priv->type = NULL; pixbuf = NULL; if( gnome_vfs_get_file_info( href, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE | GNOME_VFS_FILE_INFO_FOLLOW_LINKS ) == GNOME_VFS_OK ) { priv->type = g_strdup( info->mime_type ); pixbuf = gnome_gdk_pixbuf_new_from_uri( href ); if( pixbuf ) { width = gdk_pixbuf_get_width( pixbuf ); height = gdk_pixbuf_get_height( pixbuf ); g_object_unref( G_OBJECT( pixbuf ) ); } else { width = 0; height = 0; } entry = glade_xml_get_widget( xml, "width" ); gtk_spin_button_set_value( GTK_SPIN_BUTTON( entry ), width ); entry = glade_xml_get_widget( xml, "height" ); gtk_spin_button_set_value( GTK_SPIN_BUTTON( entry ), height ); uri = gnome_thumbnail_factory_lookup( factory, href, info->mtime ); if( uri ) { pixbuf = gdk_pixbuf_new_from_file( uri, NULL ); g_free( uri ); } else { pixbuf = gnome_thumbnail_factory_generate_thumbnail( factory, href, info->mime_type ); if( pixbuf ) { gnome_thumbnail_factory_save_thumbnail( factory, pixbuf, href, info->mtime ); } } } preview = glade_xml_get_widget( xml, "preview" ); gtk_image_set_from_pixbuf( GTK_IMAGE( preview ), pixbuf ); entry = glade_xml_get_widget( xml, "thumb" ); gtk_widget_set_sensitive( entry, pixbuf != NULL ); if( pixbuf ) { g_object_unref( G_OBJECT( pixbuf ) ); } else { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( entry ), FALSE ); } /* FIXME: would be nice to read any metadata the image has * and autoset an alt="" */ gnome_vfs_file_info_unref( info ); g_free( href ); } static void insert_object_markup( ScreemPlugin *plugin, GtkWidget *widget ) { ScreemSkelPluginPrivate *priv; const gchar *fmt; const gchar *tfmt; GladeXML *xml; gchar *markup; gint width; gint height; const gchar *alt; gchar *href; ScreemPage *page; const gchar *pathname; gchar *thumbnail; gchar *base; gchar *uri; gchar *thumb; gchar *tmp; GString *deprecated; gboolean copy; gboolean dothumb; GdkPixbuf *pixbuf; priv = SCREEM_SKEL_PLUGIN( plugin )->priv; if( ! strcmp( "object", priv->tag ) ) { fmt = "%s"; } else { fmt = "\"%s%s\"%s"; g_free( priv->type ); priv->type = g_strdup( "" ); } tfmt = "\"%s\"%s"; page = screem_plugin_get_current_document( plugin ); pathname = screem_page_get_pathname( page ); xml = glade_get_widget_tree( widget ); widget = glade_xml_get_widget( xml, "alt" ); widget = GTK_BIN( widget )->child; alt = gtk_entry_get_text( GTK_ENTRY( widget ) ); widget = glade_xml_get_widget( xml, "data" ); href = gtk_file_chooser_get_uri( GTK_FILE_CHOOSER( widget ) ); if( ! priv->type ) { priv->type = g_strdup( "application/octet-stream" ); } widget = glade_xml_get_widget( xml, "copy" ); copy = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ); if( href ) { thumbnail = gnome_thumbnail_path_for_uri( href, GNOME_THUMBNAIL_SIZE_NORMAL ); if( copy ) { base = g_path_get_basename( href ); thumb = g_strconcat( "thumb-", base, NULL ); g_free( base ); } else { thumb = g_strdup( thumbnail ); } } else { copy = FALSE; href = g_strdup( "" ); thumb = g_strdup( "" ); thumbnail = NULL; } if( pathname ) { base = g_path_get_dirname( pathname ); uri = relative_path( href, base ); } else { base = NULL; uri = g_strdup( href ); } deprecated = g_string_new( "" ); widget = glade_xml_get_widget( xml, "apply_deprecated" ); if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ) ) { widget = glade_xml_get_widget( xml, "alignment" ); tmp = gtk_combo_box_get_active_text( GTK_COMBO_BOX( widget ) ); g_string_append_printf( deprecated, " align=\"%s\"", tmp ); g_free( tmp ); widget = glade_xml_get_widget( xml, "border" ); g_string_append_printf( deprecated, " border=\"%i\"", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget ) ) ); widget = glade_xml_get_widget( xml, "hspace" ); g_string_append_printf( deprecated, " hspace=\"%i\"", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget ) ) ); widget = glade_xml_get_widget( xml, "vspace" ); g_string_append_printf( deprecated, " vspace=\"%i\"", gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget ) ) ); } widget = glade_xml_get_widget( xml, "thumb" ); dothumb = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) ); if( dothumb ) { pixbuf = NULL; if( thumbnail ) { pixbuf = gdk_pixbuf_new_from_file( thumbnail, NULL ); } if( pixbuf ) { width = gdk_pixbuf_get_width( pixbuf ); height = gdk_pixbuf_get_height( pixbuf ); g_object_unref( G_OBJECT( pixbuf ) ); } else { width = 0; height = 0; } markup = g_strdup_printf( tfmt, uri, thumb, width, height, alt, deprecated->str ); } else { widget = glade_xml_get_widget( xml, "width" ); width = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget ) ); widget = glade_xml_get_widget( xml, "height" ); height = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( widget ) ); markup = g_strdup_printf( fmt, uri, width, height, priv->type, alt, deprecated->str ); } g_string_free( deprecated, TRUE ); screem_plugin_insert( plugin, -1, markup, strlen( markup ), TRUE ); g_free( uri ); g_free( markup ); if( copy ) { uri = g_path_get_basename( href ); tmp = g_build_path( G_DIR_SEPARATOR_S, base, uri, NULL ); copy_file( href, tmp, GNOME_VFS_XFER_OVERWRITE_MODE_QUERY, screem_plugin_file_op, plugin ); g_free( tmp ); if( dothumb ) { tmp = g_build_path( G_DIR_SEPARATOR_S, base, thumb, NULL ); copy_file( thumbnail, tmp, GNOME_VFS_XFER_OVERWRITE_MODE_QUERY, screem_plugin_file_op, plugin ); g_free( tmp ); } g_free( uri ); } g_free( thumbnail ); g_free( thumb ); g_free( base ); g_free( href ); } /* There should be no need to change any code below here */ enum { ARG_0 }; static void screem_skel_plugin_class_init( ScreemSkelPluginClass *klass ); static void screem_skel_plugin_init( ScreemSkelPlugin *skel_plugin ); static void screem_skel_plugin_finalize( GObject *object ); /* G Object stuff */ #define PARENT_TYPE SCREEM_TYPE_PLUGIN static gpointer parent_class; static void screem_skel_plugin_class_init( ScreemSkelPluginClass *klass ) { GObjectClass *object_class; object_class = G_OBJECT_CLASS( klass ); object_class->finalize = screem_skel_plugin_finalize; parent_class = g_type_class_peek_parent( klass ); } static void screem_skel_plugin_init( ScreemSkelPlugin *skel_plugin ) { skel_plugin->priv = g_new0( ScreemSkelPluginPrivate, 1 ); SCREEM_PLUGIN( skel_plugin )->setup = setup; } static void screem_skel_plugin_finalize( GObject *object ) { ScreemSkelPlugin *skel_plugin; ScreemSkelPluginPrivate *priv; skel_plugin = SCREEM_SKEL_PLUGIN( object ); priv = skel_plugin->priv; cleanup( priv ); g_free( priv ); G_OBJECT_CLASS( parent_class )->finalize( object ); } static GType screem_skel_plugin_get_type() { static GType type = 0; if( ! type ) { static const GTypeInfo info = { sizeof( ScreemSkelPluginClass ), NULL, /* base init */ NULL, /* base finalise */ (GClassInitFunc)screem_skel_plugin_class_init, NULL, /* class finalise */ NULL, /* class data */ sizeof( ScreemSkelPlugin ), 0, /* n_preallocs */ (GInstanceInitFunc)screem_skel_plugin_init }; type = g_type_register_static( PARENT_TYPE, plugin_name, &info, 0 ); } return type; } static ScreemSkelPlugin *screem_skel_plugin_new( void ) { ScreemSkelPlugin *skel_plugin; skel_plugin = SCREEM_SKEL_PLUGIN( g_object_new( SCREEM_TYPE_SKEL_PLUGIN, "name", plugin_name, NULL ) ); return skel_plugin; } G_MODULE_EXPORT void get_details( ScreemPluginDetails **ret ) { ScreemPluginDetails *details; if( ! factory ) { factory = gnome_thumbnail_factory_new( GNOME_THUMBNAIL_SIZE_LARGE ); } details = g_new0( ScreemPluginDetails, 1 ); details->name = plugin_name; details->displayed_name = displayed_name; details->authors = authors; details->description = description; details->version = version; details->create = screem_skel_plugin_new; details->api_version = SCREEM_PLUGIN_REQUIRED_VERSION; *ret = details; }