cmdassist/src/applet.c
author asano
Mon, 27 Sep 2010 19:04:59 +0900
changeset 31 4d19a4859e94
parent 27 cd26fa2b171e
permissions -rw-r--r--
(for Jeffrey Chen) cmdassistant crash issue with Help invocation

/*
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
*/

/*
#
# Copyright (c) 2010. Oracle and/or its affiliates. All rights reserved.
# Use is subject to license terms.
#
*/

#include <locale.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <panel-applet.h>

#include "applet.h"
#include "about.h"
#include "common.h"
#include "search.h"
#include "pre-dialog.h"
#include "../config.h"

extern GtkWidget *cmdassist_panel_input_entry;

GtkWidget *main_panel = NULL ;
//PanelApplet *panel_applet;

static void
position_window_popup (PanelApplet *cd,
			GtkWidget *window,
			GtkWidget *button)
{
	GtkRequisition  req;
	GtkWidget *align_widget;
	gint our_width, our_height;
	gint entry_x, entry_y, entry_width, entry_height;
	gint x, y;
	GdkGravity gravity = GDK_GRAVITY_NORTH_WEST;

	align_widget = button;

	gdk_flush ();
 
	gtk_window_get_size (GTK_WINDOW (window), &our_width, &our_height);
 
	gtk_window_stick (GTK_WINDOW (window));
	gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
	gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);

	gtk_widget_realize (align_widget);

	gdk_window_get_origin (align_widget->window,
			&entry_x,
			&entry_y);
	gdk_window_get_geometry (align_widget->window,
                           NULL,
                           NULL,
                           &entry_width,
                           &entry_height,
                           NULL);

	if (entry_x + our_width < gdk_screen_width ())
		x = entry_x + 1;
	else
	{
		x = entry_x + entry_width - our_width - 1;

		gravity = GDK_GRAVITY_NORTH_EAST;
	}

	if (entry_y + entry_height + our_height < gdk_screen_height ())
		y = entry_y + entry_height - 1;
	else
	{
		y = entry_y - our_height + 1;

		if (gravity == GDK_GRAVITY_NORTH_EAST)
			gravity = GDK_GRAVITY_SOUTH_EAST;
		else
			gravity = GDK_GRAVITY_SOUTH_WEST;
	}

	gtk_window_set_gravity (GTK_WINDOW (window), gravity);
	gtk_window_move (GTK_WINDOW (window), x, y);
}

static void
position_window_popupA (PanelApplet *cd,
			GtkWidget *window,
			GtkWidget *button)
{
	GtkRequisition  req;
	GdkScreen      *screen;
	GdkRectangle    monitor;
	int             button_w, button_h;
	int             x, y;
	int             w, h;
	int             i, n;
	gboolean        found_monitor = FALSE;
             
	gdk_window_get_origin (button->window, &x, &y);
 
	gtk_window_get_size (GTK_WINDOW (window), &w, &h);
	gtk_widget_size_request (window, &req);
	w = req.width;
	h = req.height;
 
	button_w = button->allocation.width;
	button_h = button->allocation.height;
 
	screen = gtk_window_get_screen (GTK_WINDOW (window));
 
	n = gdk_screen_get_n_monitors (screen);
	for (i = 0; i < n; i++) {
		gdk_screen_get_monitor_geometry (screen, i, &monitor);
		if (x >= monitor.x && x <= monitor.x + monitor.width &&
			y >= monitor.y && y <= monitor.y + monitor.height) {
			found_monitor = TRUE;
			break;
		}
	}
 
	if ( ! found_monitor) {
		monitor.x = 0;
		monitor.y = 0;
		monitor.width = gdk_screen_get_width (screen);
		monitor.height = gdk_screen_get_height (screen);
	}
             
	PanelAppletOrient orient = panel_applet_get_orient (PANEL_APPLET (cd));

	switch (orient) {
	case PANEL_APPLET_ORIENT_RIGHT:
		x += button_w;
		if ((y + h) > monitor.y + monitor.height)
			y -= (y + h) - (monitor.y + monitor.height);
	break;
	case PANEL_APPLET_ORIENT_LEFT:
		x -= w;
		if ((y + h) > monitor.y + monitor.height)
			y -= (y + h) - (monitor.y + monitor.height);
	break;
	case PANEL_APPLET_ORIENT_DOWN:
		y += button_h;
		if ((x + w) > monitor.x + monitor.width)
			x -= (x + w) - (monitor.x + monitor.width);
	break;
	case PANEL_APPLET_ORIENT_UP:
		y -= h;
		if ((x + w) > monitor.x + monitor.width)
			x -= (x + w) - (monitor.x + monitor.width);
	break;
	}
             
	gtk_window_move (GTK_WINDOW (window), x, y);
}

GtkWidget *
applet_build_window (PanelApplet *applet)
{
	GtkWidget *window = create_window();

	return window;
}


gboolean
applet_icon_toggled_cb (GtkWidget   *widget,
			 PanelApplet *applet)
{
	GtkWidget *input_entry = cmdassist_panel_input_entry;
	GtkWidget *window = main_panel;

	if(window == NULL) {
		window = applet_build_window (applet);
		main_panel = window;
	}

	if(! gtk_window_has_toplevel_focus(window)) {
		position_window_popup(applet, window, widget);
		
		gtk_widget_hide (window);
		gtk_widget_show (window);
		gtk_window_deiconify (window);
		gtk_widget_grab_focus(input_entry);
	}
	else {
		gtk_widget_hide (GTK_WIDGET (window));
	}
	//gtk_toggle_button_set_active(widget, !window_shown);

	return TRUE;
}

static gboolean
applet_icon_button_press_event_cb (GtkWidget *widget,
					GdkEventButton *event,
					PanelApplet    *applet)
{
	if (event->button != 1)
		g_signal_stop_emission_by_name (GTK_BUTTON(widget), "button-press-event");

	return FALSE;
}

static void
applet_cmd_preferences (BonoboUIComponent *component,
                         PanelApplet       *applet,
                         const gchar       *cname)
{
	create_pre_dialog();
}

static void
applet_cmd_help (BonoboUIComponent *component,
                         PanelApplet       *applet,
                         const gchar       *cname)
{
	GError *error; 
	error = NULL;

	gchar* name = g_strdup_printf ("%s%s/C/CommandAssistant.xml", "ghelp://", CMDASSIST_HELPDIR);
	gnome_help_display_uri(name, &error);
	g_free(name);

	if (error) {
		GtkWidget *dialog;
		dialog = gtk_message_dialog_new (NULL,
						0,
						GTK_MESSAGE_ERROR,
						GTK_BUTTONS_CLOSE,
						_("Could not display help for the "
						"Command Assistant.\n"
						"%s"),
						error->message);
		g_signal_connect_swapped (dialog, "response",
					G_CALLBACK (gtk_widget_destroy),
					dialog);
		gtk_widget_show (dialog);
		g_error_free (error);
	}

}

static void
applet_cmd_about (BonoboUIComponent *component,
                         PanelApplet       *applet,
                         const gchar       *cname)
{
	show_about_dialog (GTK_WIDGET (applet));
}

static const BonoboUIVerb 
commandAssistant_applet_menu_verbs[] =
{
	BONOBO_UI_UNSAFE_VERB ("Preferences", applet_cmd_preferences),
	BONOBO_UI_UNSAFE_VERB ("Help", applet_cmd_help),
	BONOBO_UI_UNSAFE_VERB ("About", applet_cmd_about),

	BONOBO_UI_VERB_END
};

static const char Context_menu_xml [] =
   "<popup name=\"button3\">\n"
   "   <menuitem name=\"Preferences Item\" "
   "             verb=\"Preferences\" "
   "           _label=\"_Preferences...\"\n"
   "          pixtype=\"stock\" "
   "          pixname=\"gtk-properties\"/>\n"
   "   <separator/>\n"
   "   <menuitem name=\"Help Item\" "
   "             verb=\"Help\" "
   "           _label=\"_Help...\"\n"
   "          pixtype=\"stock\" "
   "          pixname=\"gtk-help\"/>\n"
   "   <menuitem name=\"About Item\" "
   "             verb=\"About\" "
   "           _label=\"_About...\"\n"
   "          pixtype=\"stock\" "
   "          pixname=\"gtk-about\"/>\n"
   "</popup>\n";

gboolean commandAssistant_applet_fill (PanelApplet *applet,
		const gchar *iid,
		gpointer data)
{

        setlocale(LC_ALL,"");
        bindtextdomain (GETTEXT_PACKAGE, CMDASSIST_LOCALEDIR);
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
        textdomain (GETTEXT_PACKAGE);

	//panel_applet = applet;
	
	GtkWidget *box;
	GtkWidget *hbox;
	GdkPixbuf *icon;
	GtkWidget *image;
	GtkEventBox *event_box;
	GtkWidget *applet_button;

	if (strcmp (iid, "OAFIID:CommandAssistantApplet") != 0)
		return FALSE;

	/* Set up the menu */
	panel_applet_setup_menu (applet,
			Context_menu_xml,
			commandAssistant_applet_menu_verbs,
			applet);

	gtk_widget_show (GTK_WIDGET (applet));

	panel_applet_set_background_widget (PANEL_APPLET (applet),
			GTK_WIDGET (applet));


	box = gtk_hbox_new (FALSE, 0);
	gtk_container_add (GTK_CONTAINER (applet), box);
	gtk_widget_show (box);

	applet_button = gtk_toggle_button_new ();
	gtk_widget_set_tooltip_text (applet_button, _("Click here to show input window!"));
	gtk_button_set_relief (GTK_BUTTON (applet_button),
			GTK_RELIEF_NONE);
	g_signal_connect (applet_button, "toggled",
			G_CALLBACK (applet_icon_toggled_cb),
			applet);
	g_signal_connect (applet_button, "button-press-event",
			G_CALLBACK (applet_icon_button_press_event_cb),
			applet);
	gtk_box_pack_start (GTK_BOX (box), applet_button, FALSE, FALSE, 0);
	gtk_widget_show(applet_button);

	hbox = gtk_hbox_new(FALSE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
	gtk_container_add (GTK_CONTAINER (applet_button), hbox);
	gtk_widget_show (hbox);

	
        gchar* icon_name = g_strdup_printf ("%s/command_assistant_applet.png", CMDASSIST_PIXDIR);
        icon = gdk_pixbuf_new_from_file (icon_name, NULL);
        g_free(icon_name);

	image = gtk_image_new();
	guint size = 26;
	gtk_image_set_pixel_size (GTK_IMAGE (image), size - 10);

	GdkPixbuf *scaled;
	scaled = gdk_pixbuf_scale_simple (icon,
                                        size - 1,
                                        size - 1,
                                        GDK_INTERP_BILINEAR);
	gtk_image_set_from_pixbuf (GTK_IMAGE (image), scaled);
	g_object_unref (scaled);
	
	gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
	gtk_widget_show (image);
	
	gtk_widget_show_all (GTK_WIDGET (applet));

	//init index table
	initIndex();

	return TRUE;
}