Gobby::ClosableFrame::ClosableFrame(const Glib::ustring& title, const Glib::ustring& icon_name, Preferences::Option<bool>& option): m_option(option), m_allow_visible(true) { CloseButton* button = Gtk::manage(new CloseButton); button->set_hexpand(true); button->set_halign(Gtk::ALIGN_END); button->signal_clicked().connect( sigc::mem_fun(*this, &ClosableFrame::on_clicked)); m_option.signal_changed().connect( sigc::mem_fun(*this, &ClosableFrame::on_option)); button->show(); Gtk::Image* image = Gtk::manage( new Gtk::Image); image->set_from_icon_name(icon_name, Gtk::ICON_SIZE_MENU); image->show(); Gtk::Label* label_title = Gtk::manage( new Gtk::Label(title, Gtk::ALIGN_START)); label_title->show(); m_grid.set_border_width(6); m_grid.set_column_spacing(6); m_grid.set_row_spacing(6); m_grid.attach(*image, 0, 0, 1, 1); m_grid.attach(*label_title, 1, 0, 1, 1); m_grid.attach(*button, 2, 0, 1, 1); m_grid.show(); add(m_grid); on_option(); }
Gobby::StatusBar::MessageHandle Gobby::StatusBar::add_message(Gobby::StatusBar::MessageType type, const Glib::ustring& message, const Glib::ustring& dialog_message, unsigned int timeout) { if(m_visible_messages >= 12) { for(MessageHandle iter = m_list.begin(); iter != m_list.end(); ++iter) { if(*iter) { if((*iter)->is_error()) remove_message(iter); else // only hide message because whoever // installed it is expecting to be // able to call remove_message on it hide_message(iter); break; } } } Gtk::Grid* grid = Gtk::manage(new Gtk::Grid()); grid->set_column_spacing(6); grid->set_margin_start(2); grid->set_margin_end(2); Gtk::Image* image = Gtk::manage(new Gtk::Image); image->set_from_icon_name(message_type_to_icon_name(type), Gtk::ICON_SIZE_MENU); grid->attach(*image, 0, 0, 1, 1); image->show(); Gtk::Label* label = Gtk::manage( new Gtk::Label(message, Gtk::ALIGN_START)); label->set_ellipsize(Pango::ELLIPSIZE_END); // If we set halign instead, the label will not behave correctly // when ellipsized, because then it has always all space around it // allocated, and the alignment "jumps" around whin resizing the // window due to new characters appearing or disappearing as a result // of the ellipsization. #if GTK_CHECK_VERSION(3, 16, 0) gtk_label_set_xalign(label->gobj(), 0.0); #else label->set_alignment(0.0, 0.0); #endif label->show(); grid->attach(*label, 1, 0, 1, 1); Gtk::Frame* frame = Gtk::manage(new Gtk::Frame); m_list.push_back(0); Gobby::StatusBar::MessageHandle iter(--m_list.end()); sigc::connection timeout_conn; if(timeout) { timeout_conn = Glib::signal_timeout().connect_seconds( sigc::bind( sigc::bind_return( sigc::mem_fun( *this, &StatusBar::remove_message), false), iter), timeout); } *iter = new Message(frame, message, dialog_message, timeout_conn); ++m_visible_messages; if(dialog_message.empty()) { frame->add(*grid); } else { Gtk::EventBox *eventbox = Gtk::manage(new Gtk::EventBox); frame->add(*eventbox); eventbox->add(*grid); eventbox->signal_button_press_event().connect( sigc::bind_return(sigc::bind( sigc::mem_fun( *this, &StatusBar::on_message_clicked), iter), false)); eventbox->show(); } grid->show(); // Insert at front gtk_grid_attach_next_to( gobj(), GTK_WIDGET(frame->gobj()), NULL, GTK_POS_LEFT, 1, 1); frame->set_halign(Gtk::ALIGN_START); frame->set_hexpand(false); frame->set_shadow_type(Gtk::SHADOW_NONE); frame->show(); return iter; }
void Gobby::BrowserContextCommands::on_populate_popup(Gtk::Menu* menu) { // TODO: Can this happen? Should we close the old popup here? g_assert(m_popup_menu == NULL); // Cancel previous attempts m_watch.reset(NULL); m_dialog.reset(NULL); InfBrowser* browser; InfBrowserIter iter; if(!m_browser.get_selected_browser(&browser)) return; if(!m_browser.get_selected_iter(browser, &iter)) { InfBrowserStatus browser_status; g_object_get(G_OBJECT(browser), "status", &browser_status, NULL); if(browser_status == INF_BROWSER_CLOSED) { Gtk::ImageMenuItem *remove_item = Gtk::manage( new Gtk::ImageMenuItem(_("_Remove"), true)); remove_item->set_image(*Gtk::manage(new Gtk::Image( Gtk::Stock::CLOSE, Gtk::ICON_SIZE_MENU))); remove_item->signal_activate().connect(sigc::bind( sigc::mem_fun(*this, &BrowserContextCommands::on_remove), browser)); remove_item->show(); menu->append(*remove_item); } return; } InfBrowserIter dummy_iter = iter; bool is_subdirectory = inf_browser_is_subdirectory(browser, &iter); bool is_toplevel = !inf_browser_get_parent(browser, &dummy_iter); // Watch the node, and close the popup menu when the node // it refers to is removed. m_watch.reset(new NodeWatch(browser, &iter)); m_watch->signal_node_removed().connect(sigc::mem_fun( *this, &BrowserContextCommands::on_menu_node_removed)); menu->signal_deactivate().connect(sigc::mem_fun( *this, &BrowserContextCommands::on_menu_deactivate)); bool have_toplevel_entries = false; // Add "Disconnect" menu option if the connection // item has been clicked at if(is_toplevel && INFC_IS_BROWSER(browser)) { Gtk::ImageMenuItem* disconnect_item = Gtk::manage( new Gtk::ImageMenuItem( _("_Disconnect from Server"), true)); disconnect_item->set_image(*Gtk::manage(new Gtk::Image( Gtk::Stock::DISCONNECT, Gtk::ICON_SIZE_MENU))); disconnect_item->signal_activate().connect(sigc::bind( sigc::mem_fun(*this, &BrowserContextCommands::on_disconnect), INFC_BROWSER(browser))); disconnect_item->show(); menu->append(*disconnect_item); have_toplevel_entries = true; } // Add create account option if the connection item has been clicked at if(is_toplevel) { const InfAclAccount* account = inf_browser_get_acl_local_account(browser); const InfAclAccountId acc_id = (account != NULL) ? account->id : 0; InfAclMask mask; inf_acl_mask_set1(&mask, INF_ACL_CAN_CREATE_ACCOUNT); inf_browser_check_acl(browser, &iter, acc_id, &mask, &mask); if(inf_acl_mask_has(&mask, INF_ACL_CAN_CREATE_ACCOUNT)) { Gtk::Image* image = Gtk::manage(new Gtk::Image); image->set_from_icon_name("application-certificate", Gtk::ICON_SIZE_MENU); Gtk::ImageMenuItem* item = Gtk::manage(new Gtk::ImageMenuItem( _("Create _Account..."), true)); item->set_image(*image); item->signal_activate().connect(sigc::bind( sigc::mem_fun( *this, &BrowserContextCommands:: on_create_account), browser)); item->show(); menu->append(*item); have_toplevel_entries = true; } } // Separator, if we have entries dedicated to the browser itself if(have_toplevel_entries) { Gtk::SeparatorMenuItem* sep_item = Gtk::manage(new Gtk::SeparatorMenuItem); sep_item->show(); menu->append(*sep_item); } // Create Document Gtk::ImageMenuItem* new_document_item = Gtk::manage( new Gtk::ImageMenuItem(_("Create Do_cument..."), true)); new_document_item->set_image(*Gtk::manage(new Gtk::Image( Gtk::Stock::NEW, Gtk::ICON_SIZE_MENU))); new_document_item->signal_activate().connect(sigc::bind( sigc::mem_fun(*this, &BrowserContextCommands::on_new), browser, iter, false)); new_document_item->set_sensitive(is_subdirectory); new_document_item->show(); menu->append(*new_document_item); // Create Directory // Check whether we have the folder-new icon, fall back to // Stock::DIRECTORY otherwise Glib::RefPtr<Gdk::Screen> screen = menu->get_screen(); Glib::RefPtr<Gtk::IconTheme> icon_theme( Gtk::IconTheme::get_for_screen(screen)); Gtk::Image* new_directory_image = Gtk::manage(new Gtk::Image); if(icon_theme->lookup_icon("folder-new", Gtk::ICON_SIZE_MENU, Gtk::ICON_LOOKUP_USE_BUILTIN)) { new_directory_image->set_from_icon_name( "folder-new", Gtk::ICON_SIZE_MENU); } else { new_directory_image->set( Gtk::Stock::DIRECTORY, Gtk::ICON_SIZE_MENU); } Gtk::ImageMenuItem* new_directory_item = Gtk::manage( new Gtk::ImageMenuItem(_("Create Di_rectory..."), true)); new_directory_item->set_image(*new_directory_image); new_directory_item->signal_activate().connect(sigc::bind( sigc::mem_fun(*this, &BrowserContextCommands::on_new), browser, iter, true)); new_directory_item->set_sensitive(is_subdirectory); new_directory_item->show(); menu->append(*new_directory_item); // Open Document Gtk::ImageMenuItem* open_document_item = Gtk::manage( new Gtk::ImageMenuItem(_("_Open Document..."), true)); open_document_item->set_image(*Gtk::manage(new Gtk::Image( Gtk::Stock::OPEN, Gtk::ICON_SIZE_MENU))); open_document_item->signal_activate().connect(sigc::bind( sigc::mem_fun(*this, &BrowserContextCommands::on_open), browser, iter)); open_document_item->set_sensitive(is_subdirectory); open_document_item->show(); menu->append(*open_document_item); // Separator Gtk::SeparatorMenuItem* sep_item = Gtk::manage(new Gtk::SeparatorMenuItem); sep_item->show(); menu->append(*sep_item); // Permissions Gtk::ImageMenuItem* permissions_item = Gtk::manage( new Gtk::ImageMenuItem(_("_Permissions..."), true)); permissions_item->set_image(*Gtk::manage(new Gtk::Image( Gtk::Stock::PROPERTIES, Gtk::ICON_SIZE_MENU))); permissions_item->signal_activate().connect(sigc::bind( sigc::mem_fun(*this, &BrowserContextCommands::on_permissions), browser, iter)); permissions_item->show(); menu->append(*permissions_item); // Delete Gtk::ImageMenuItem* delete_item = Gtk::manage( new Gtk::ImageMenuItem(_("D_elete"), true)); delete_item->set_image(*Gtk::manage(new Gtk::Image( Gtk::Stock::DELETE, Gtk::ICON_SIZE_MENU))); delete_item->signal_activate().connect(sigc::bind( sigc::mem_fun(*this, &BrowserContextCommands::on_delete), browser, iter)); delete_item->set_sensitive(!is_toplevel); delete_item->show(); menu->append(*delete_item); m_popup_menu = menu; menu->signal_selection_done().connect( sigc::mem_fun( *this, &BrowserContextCommands::on_popdown)); }