📄 tray_icon.cpp
字号:
/* Copyright (C) 2004 Chris VineThis program is distributed under the General Public Licence, version 2.For particulars of this and relevant disclaimers see the fileCOPYING distributed with the source files.*/#include <string>#include <gtkmm/stock.h>#include <gtkmm/image.h>#include <gdkmm/pixbuf.h>#include <gtk/gtkeventbox.h>#include <gtk/gtkimage.h>#include <gdk/gdkpixbuf.h>#include "tray_icon.h"#include "efax_controller.h"#ifdef ENABLE_NLS#include <libintl.h>#endifTrayItem* TrayItem::tray_item_p = 0;TrayItem::TrayItem(Gtk::Window& window): prog_window(window), embedded(false) { if (tray_item_p) { // something has gone wrong - report the error and return write_error("TrayItem object has already been created - cannot create another\n"); return; } tray_item_p = this; // build menu for right mouse button { using namespace Gtk::Menu_Helpers; MenuList& menu_list = popup_menu.items(); Gtk::Image* image_p = manage(new Gtk::Image(Gtk::Stock::INDEX, Gtk::ICON_SIZE_MENU)); menu_list.push_back(ImageMenuElem(gettext("List received faxes"), *image_p, sigc::bind(sigc::mem_fun(*this, &TrayItem::popup_menu_slot), TrayItem::list_received_faxes))); image_p = manage(new Gtk::Image(Gtk::Stock::INDEX, Gtk::ICON_SIZE_MENU)); menu_list.push_back(ImageMenuElem(gettext("List sent faxes"), *image_p, sigc::bind(sigc::mem_fun(*this, &TrayItem::popup_menu_slot), TrayItem::list_sent_faxes))); menu_list.push_back(SeparatorElem()); menu_list.push_back(MenuElem(gettext("Take over call"), sigc::bind(sigc::mem_fun(*this, &TrayItem::popup_menu_slot), TrayItem::receive_takeover))); receive_takeover_item_p = &menu_list.back(); menu_list.push_back(MenuElem(gettext("Answer call"), sigc::bind(sigc::mem_fun(*this, &TrayItem::popup_menu_slot), TrayItem::receive_answer))); receive_answer_item_p = &menu_list.back(); menu_list.push_back(MenuElem(gettext("Receive standby"), sigc::bind(sigc::mem_fun(*this, &TrayItem::popup_menu_slot), TrayItem::receive_standby))); receive_standby_item_p = &menu_list.back(); image_p = manage(new Gtk::Image(Gtk::Stock::STOP, Gtk::ICON_SIZE_MENU)); menu_list.push_back(ImageMenuElem(gettext("Stop"), *image_p, sigc::bind(sigc::mem_fun(*this, &TrayItem::popup_menu_slot), TrayItem::stop))); stop_item_p = &menu_list.back(); menu_list.push_back(SeparatorElem()); image_p = manage(new Gtk::Image(Gtk::Stock::QUIT, Gtk::ICON_SIZE_MENU)); menu_list.push_back(ImageMenuElem(gettext("Quit"), *image_p, sigc::bind(sigc::mem_fun(*this, &TrayItem::popup_menu_slot), TrayItem::quit))); } // now create and register the tray icon container (parcel out the // C stuff to another method to make it more bearable) tray_icon_init();}void TrayItem::button_press_handler(GdkEventButton* event_p) { if (event_p->button == 1 || event_p->button == 2) left_button_pressed(); if (event_p->button == 3) { if (get_state() == EfaxController::inactive) { stop_item_p->set_sensitive(false); receive_takeover_item_p->set_sensitive(true); receive_answer_item_p->set_sensitive(true); receive_standby_item_p->set_sensitive(true); } else { stop_item_p->set_sensitive(true); receive_takeover_item_p->set_sensitive(false); receive_answer_item_p->set_sensitive(false); receive_standby_item_p->set_sensitive(false); } popup_menu.popup(event_p->button, event_p->time); }}void TrayItem::popup_menu_slot(int item) { menu_item_chosen(item);}////////////////// start of the raw GTK+ C stuff ///////////////////////////////////////////////// callbacks ///////////////////////////void embedded_cback(GtkWidget*, gpointer) { TrayItem::tray_item_p->embedded = true; // for debugging - there is no error, we use write_error() for reporting //write_error("In embedded callback\n");}void destroy_cback(GtkWidget*, gpointer) { TrayItem::tray_item_p->embedded = false; TrayItem::tray_item_p->tray_icon_destroy(); // now bring up the program window in case it was hidden when the system tray // was removed from the panel TrayItem::tray_item_p->prog_window.present(); // for debugging - there is no error, we use write_error() for reporting //write_error("In destroy callback\n");}gboolean button_press_cback(GtkWidget* widget_p, GdkEventButton* event_p, gpointer) { TrayItem::tray_item_p->button_press_handler(event_p); return true; // processing stops here}////////////////////////// tray icon code //////////////////////////void TrayItem::tray_icon_init(void) { Glib::RefPtr<Gdk::Pixbuf> icon_r(prog_config.window_icon_r->scale_simple(18, 18, Gdk::INTERP_HYPER)); // we can use icon_r->gobj() rather than icon_r->gobj_copy() here, as // gtk_image_new_from_pixbuf() will increase the reference count GtkWidget* image_p = gtk_image_new_from_pixbuf(icon_r->gobj()); event_box_p = gtk_event_box_new(); gtk_container_add (GTK_CONTAINER(event_box_p), GTK_WIDGET(image_p)); gtk_widget_add_events(event_box_p, GDK_BUTTON_PRESS_MASK); // set a tooltip tooltips_p = gtk_tooltips_new(); // we have now initialiased event_box_p and tooltips_p, so we can call set_tooltip_slot() set_tooltip_slot(gettext("Inactive")); g_signal_connect(G_OBJECT(event_box_p), "button_press_event", G_CALLBACK(button_press_cback), 0); tray_icon_p = egg_tray_icon_new("efax-gtk"); g_signal_connect(G_OBJECT(tray_icon_p), "embedded", G_CALLBACK(embedded_cback), 0); g_signal_connect(G_OBJECT(tray_icon_p), "destroy", G_CALLBACK(destroy_cback), 0); gtk_container_add(GTK_CONTAINER(tray_icon_p), GTK_WIDGET(event_box_p)); gtk_widget_show_all(GTK_WIDGET(tray_icon_p)); // add a reference count to the tray icon container so that we that we keep // ownership of its destiny - we will need this for tray_icon_destroy() below g_object_ref(G_OBJECT(tray_icon_p));}void TrayItem::tray_icon_destroy(void) { // extract this event box from the defunct tray icon container // first we need to add a reference count to our event box so that // extracting it from the container doesn't destroy it g_object_ref(G_OBJECT(event_box_p)); gtk_container_remove(GTK_CONTAINER(tray_icon_p), GTK_WIDGET(event_box_p)); // now destroy the old tray icon g_object_unref(G_OBJECT(tray_icon_p)); // create a new tray icon in case another GNOME notification area (system tray) // is inserted in the panel by the user, or the user has more than one tray tray_icon_p = egg_tray_icon_new("efax-gtk"); gtk_container_add(GTK_CONTAINER(tray_icon_p), GTK_WIDGET(event_box_p)); // now remove the additional reference count we added at the outset to the // the event box g_object_unref(G_OBJECT(event_box_p)); g_signal_connect(G_OBJECT(tray_icon_p), "embedded", G_CALLBACK(embedded_cback), 0); g_signal_connect(G_OBJECT(tray_icon_p), "destroy", G_CALLBACK(destroy_cback), 0); gtk_widget_show_all(GTK_WIDGET(tray_icon_p)); // add a reference count to the tray icon container so that we that we keep ownership // of its destiny - we will need this for any further calls to tray_icon_destroy() g_object_ref(G_OBJECT(tray_icon_p));}void TrayItem::set_tooltip_slot(const char* text) { // we might as well use a std::string rather than a Glib::ustring here // as it is just a temporary transparent holder of any UTF-8 encoding std::string tooltip_text(gettext("efax-gtk: ")); tooltip_text += text; gtk_tooltips_set_tip(tooltips_p, event_box_p, tooltip_text.c_str(), 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -