Ejemplo n.º 1
0
void Gobby::Browser::on_set_browser(GtkTreeIter* iter,
                                    InfBrowser* old_browser,
                                    InfBrowser* new_browser)
{
	if(new_browser)
	{
		if(INFC_IS_BROWSER(new_browser))
		{
			InfcBrowser* browser = INFC_BROWSER(new_browser);
			infc_browser_add_plugin(browser, Plugins::C_TEXT);
			infc_browser_add_plugin(browser, Plugins::C_CHAT);
		}
		else if(INFD_IS_DIRECTORY(new_browser))
		{
			InfdDirectory* directory =
				INFD_DIRECTORY(new_browser);
			infd_directory_add_plugin(directory, Plugins::D_TEXT);
		}
	}
}
Ejemplo n.º 2
0
BrowserIter::BrowserIter( const Browser &browser )
    : m_infBrowser( INFC_BROWSER(browser.gobject()) )
{
    Q_ASSERT(browser.connectionStatus() == INF_BROWSER_OPEN);
    inf_browser_get_root(INF_BROWSER(m_infBrowser), &m_infBrowserIter);
}
Ejemplo n.º 3
0
void Gobby::BrowserContextCommands::on_account_created(
	gnutls_x509_privkey_t key,
	InfCertificateChain* certificate,
	const InfAclAccount* account)
{
	InfBrowser* browser;
	g_object_get(G_OBJECT(m_dialog->gobj()), "browser", &browser, NULL);
	const InfAclAccount* own_account =
		inf_browser_get_acl_local_account(browser);
	const InfAclAccountId default_id =
		inf_acl_account_id_from_string("default");
	const bool is_default_account = (own_account->id == default_id);
	g_object_unref(browser);

	gnutls_x509_crt_t cert =
		inf_certificate_chain_get_own_certificate(certificate);
	gchar* name = inf_cert_util_get_dn_by_oid(
		cert, GNUTLS_OID_X520_COMMON_NAME, 0);
	const std::string cn = name;
	g_free(name);

	std::string host;
	if(INFC_IS_BROWSER(browser))
	{
		InfXmlConnection* xml =
			infc_browser_get_connection(INFC_BROWSER(browser));
		if(INF_IS_XMPP_CONNECTION(xml))
		{
			gchar* hostname;
			g_object_get(G_OBJECT(xml), "remote-hostname",
			             &hostname, NULL);
			host = hostname;
			g_free(hostname);
		}
	}

	if(host.empty())
		host = "local";

	gnutls_x509_crt_t* certs = inf_certificate_chain_get_raw(certificate);
	const unsigned int n_certs =
		inf_certificate_chain_get_n_certificates(certificate);

	std::auto_ptr<Gtk::MessageDialog> dlg;

	try
	{
		const std::string filename = make_certificate_filename(cn, host);

		GError* error = NULL;
		inf_cert_util_write_certificate_with_key(
			key, certs, n_certs, filename.c_str(), &error);

		if(error != NULL)
		{
			const std::string message = error->message;
			g_error_free(error);
			throw std::runtime_error(message);
		}

		if(is_default_account &&
		   (m_cert_manager.get_private_key() == NULL ||
		    m_cert_manager.get_certificates() == NULL))
		{
			m_preferences.security.key_file = filename;
			m_preferences.security.certificate_file = filename;

			dlg.reset(new Gtk::MessageDialog(
				m_parent, _("Account successfully created"),
				false, Gtk::MESSAGE_INFO,
				Gtk::BUTTONS_CLOSE));
			dlg->set_secondary_text(
				_("When re-connecting to the server, the "
				  "new account will be used."));
		}
		else
		{
			// TODO: Gobby should support multiple certificates
			dlg.reset(new Gtk::MessageDialog(
				m_parent, _("Account successfully created"),
				false, Gtk::MESSAGE_INFO,
				Gtk::BUTTONS_CLOSE));
			dlg->set_secondary_text(Glib::ustring::compose(
				_("The certificate has been stored at %1.\n\n"
				  "To login to this account, set the "
				  "certificate in Gobby's preferences "
				  "and re-connect to the server."),
				filename));
		}
	}
	catch(const std::exception& ex)
	{
		// This is actually a bit unfortunate, because the
		// account was actually created and we have a valid
		// certificate for it, but we cannot keep it...
		dlg.reset(new Gtk::MessageDialog(
			m_parent, _("Failed to create account"),
			false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE));
		dlg->set_secondary_text(Glib::ustring::compose(
			_("Could not save the certificate for the "
			  "account: %1"), ex.what()));
	}

	m_dialog = dlg;
	m_dialog->signal_response().connect(
		sigc::mem_fun(
			*this,
			&BrowserContextCommands::
				on_account_created_response));
	m_dialog->present();
}
Ejemplo n.º 4
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, &iter))
		return;

	InfBrowserStatus browser_status;
	g_object_get(G_OBJECT(browser), "status", &browser_status, NULL);
	if(browser_status != INF_BROWSER_OPEN)
		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));

	// 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);

		// Separator
		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);

	// Rename
	Gtk::ImageMenuItem* rename_item = Gtk::manage(
		new Gtk::ImageMenuItem(_("Re_name"), true));
	rename_item->set_image(*Gtk::manage(new Gtk::Image(
		Gtk::Stock::EDIT, Gtk::ICON_SIZE_MENU)));
	rename_item->signal_activate().connect(sigc::bind(
		sigc::mem_fun(*this,
			&BrowserContextCommands::on_rename),
		browser, iter));
	rename_item->set_sensitive(!is_toplevel);
	rename_item->show();
	menu->append(*rename_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));
}
Ejemplo n.º 5
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));
}