예제 #1
0
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();
}
예제 #2
0
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;
}
예제 #3
0
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));
}