glom r2008 - in trunk: . glom glom/bakery
- From: murrayc svn gnome org
- To: svn-commits-list gnome org
- Subject: glom r2008 - in trunk: . glom glom/bakery
- Date: Fri, 20 Mar 2009 00:31:11 +0000 (UTC)
Author: murrayc
Date: Fri Mar 20 00:31:11 2009
New Revision: 2008
URL: http://svn.gnome.org/viewvc/glom?rev=2008&view=rev
Log:
2009-03-20 Murray Cumming <murrayc murrayc com>
* configure.ac: Depend on libunique-1.0
* glom/bakery/App_WithDoc_Gtk.[h|cc]: Added set_unique_app(), to make
the app handle UniqueApp messages, to start new instances or open files.
* glom/main.cc: Use set_unique_app() and send messages to the existing
instance instead of starting a new instance, if one is already running.
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/glom/bakery/App_WithDoc_Gtk.cc
trunk/glom/bakery/App_WithDoc_Gtk.h
trunk/glom/main.cc
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Fri Mar 20 00:31:11 2009
@@ -106,7 +106,7 @@
# Do not require, goocanvas and gtksourceviewmm in client only mode
-REQUIRED_LIBS="gtkmm-2.4 >= 2.14 gthread-2.0 gconfmm-2.6 libxml++-2.6 libxslt >= 1.1.10 pygda-4.0 >= 2.25.3 pygtk-2.0 >= 2.6.0 libgdamm-4.0 >= 3.99.14 libgda-4.0 >= 4.0.0 libgda-postgres-4.0 goocanvasmm-1.0 >= 0.13.0"
+REQUIRED_LIBS="gtkmm-2.4 >= 2.14 gthread-2.0 gconfmm-2.6 libxml++-2.6 libxslt >= 1.1.10 pygda-4.0 >= 2.25.3 pygtk-2.0 >= 2.6.0 libgdamm-4.0 >= 3.99.14 libgda-4.0 >= 4.0.0 libgda-postgres-4.0 goocanvasmm-1.0 >= 0.13.0 unique-1.0"
if test $enable_client_only != yes; then
REQUIRED_LIBS="$REQUIRED_LIBS gtksourceviewmm-2.0"
fi
Modified: trunk/glom/bakery/App_WithDoc_Gtk.cc
==============================================================================
--- trunk/glom/bakery/App_WithDoc_Gtk.cc (original)
+++ trunk/glom/bakery/App_WithDoc_Gtk.cc Fri Mar 20 00:31:11 2009
@@ -315,4 +315,76 @@
document_history_remove(uri);
}
+void App_WithDoc_Gtk::set_unique_app(UniqueApp* unique_app)
+{
+ if(!unique_app)
+ return;
+
+ m_unique_app = unique_app;
+ g_object_ref(m_unique_app); //Keep it alive. unrefed in the destructor.
+
+ // The UniqueApp instance must "watch" all the top-level windows the application
+ // creates, so that it can terminate the startup notification sequence for us
+ unique_app_watch_window (unique_app, GTK_WINDOW(gobj()));
+
+ // Handle messages from other instances that try to start:
+ g_signal_connect (unique_app, "message-received", G_CALLBACK(&App_WithDoc_Gtk::on_unique_app_message_received), this /* user_data */);
+
+}
+
+// This handles messages from other UniqueApp instances,
+// to our single instance,
+// sent to the signal instance before the extra instances quit,
+// soon after they start.
+UniqueResponse App_WithDoc_Gtk::on_unique_app_message_received(UniqueApp* app,
+ UniqueCommand command,
+ UniqueMessageData* message,
+ guint time_,
+ gpointer user_data)
+{
+ App_WithDoc_Gtk* pApp = static_cast<App_WithDoc_Gtk*>(user_data);
+ if(!pApp)
+ return UNIQUE_RESPONSE_FAIL;
+
+ switch(command)
+ {
+ case UNIQUE_ACTIVATE:
+ {
+ Glib::RefPtr<Gdk::Screen> screen = Glib::wrap(unique_message_data_get_screen(message), true);
+ pApp->set_screen(screen);
+ pApp->present();
+
+ return UNIQUE_RESPONSE_OK;
+ }
+
+ case UNIQUE_NEW:
+ {
+ pApp->on_menu_file_new();
+
+ return UNIQUE_RESPONSE_OK;
+ break;
+ }
+
+ case UNIQUE_OPEN:
+ {
+ char* uri = unique_message_data_get_text(message);
+ std::cout << "DEBUG: uri=" << uri << std::endl;
+
+ pApp->open_document(uri);
+ pApp->present();
+
+ g_free(uri);
+
+ return UNIQUE_RESPONSE_OK;
+ break;
+ }
+
+ default:
+ {
+ std::cerr << "Unexpected UniqueApp command: " << command << std::endl;
+ return UNIQUE_RESPONSE_FAIL;
+ }
+ }
+}
+
} //namespace
Modified: trunk/glom/bakery/App_WithDoc_Gtk.h
==============================================================================
--- trunk/glom/bakery/App_WithDoc_Gtk.h (original)
+++ trunk/glom/bakery/App_WithDoc_Gtk.h Fri Mar 20 00:31:11 2009
@@ -25,6 +25,7 @@
#include <gtkmm/toolbutton.h>
#include <gtkmm/recentmanager.h>
#include <gtkmm/recentchooser.h>
+#include <unique/unique.h>
namespace GlomBakery
{
@@ -52,6 +53,12 @@
virtual void init(); //Unique final overrider.
+ /** Connect a signal handler for UniqueApp messages,
+ * which handles the default commands, for instance to open new instances
+ * an to open files.
+ */
+ virtual void set_unique_app(UniqueApp* unique_app);
+
protected:
virtual void init_menus_file(); //overridden to add open/save/save as.
virtual void init_menus_file_recentfiles(const Glib::ustring& path); // call this in init_menus_file()
@@ -70,8 +77,14 @@
void on_recent_files_activate(Gtk::RecentChooser& recent_chooser);
+ static UniqueResponse on_unique_app_message_received(UniqueApp* app, UniqueCommand command, UniqueMessageData* message, guint time_, gpointer user_data);
+
//Menu stuff:
Glib::RefPtr<Gtk::Action> m_action_save, m_action_saveas;
+
+ //We keep this around just so we can keep a ref on it.
+ //This will only be non-null for the first instance.
+ UniqueApp* m_unique_app;
};
} //namespace
Modified: trunk/glom/main.cc
==============================================================================
--- trunk/glom/main.cc (original)
+++ trunk/glom/main.cc Fri Mar 20 00:31:11 2009
@@ -112,15 +112,17 @@
//to help valgrind to detect memory leaks:
atexit(__libc_freeres);
#else
+ //Allow use of the Windows Sockets API:
WSADATA data;
- int errcode = WSAStartup(MAKEWORD(2, 0), &data);
+ const int errcode = WSAStartup(MAKEWORD(2, 0), &data);
if(errcode != 0)
{
std::cerr << "Failed to initialize WinSock: " << errcode << std::endl;
return -1;
}
- gchar* installation_dir_c = g_win32_get_package_installation_directory_of_module(NULL);
+ //Get the installation directory for use in other MS Windows initialization later:
+ gchar* installation_dir_c = g_win32_get_package_installation_directory_of_module(0);
const std::string installation_dir(installation_dir_c);
g_free(installation_dir_c);
#endif
@@ -129,7 +131,7 @@
// correctly according to getenv(), but python still does not look in it.
// For now, the installer installs all the python stuff directly into the
// application directory, although I would like to move this to a python/
- // subdirectory.
+ // subdirectory. Armin.
#if 0
#ifdef G_OS_WIN32
// Set PYTHONPATH to point to python/ because that's where the installer
@@ -150,16 +152,20 @@
Glib::setenv("PATH", Glib::getenv("PATH") + ";" + Glib::build_filename(installation_dir, "bin"));
#endif
+
+ // Make this application use the current locale for _() translation:
#ifdef G_OS_WIN32
- // Load translations relative to glom.exe on Windows
+ // Load translations relative to glom.exe on Windows:
bindtextdomain(GETTEXT_PACKAGE, Glib::build_filename(installation_dir, "share/locale").c_str());
#else
- //Make this application use the current locale for _() translation:
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); //LOCALEDIR is defined in the Makefile.am
#endif
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);
+
+ //Initialize gtkmm, Python, etc:
+
g_thread_init(NULL); //So we can use GMutex.
Gnome::Gda::init();
@@ -167,31 +173,35 @@
Hildon::init();
#endif
- Glib::OptionContext context;
-
- Glom::OptionGroup group;
- context.set_main_group(group);
//We use python for calculated-fields:
Py_Initialize();
PySys_SetArgv(argc, argv);
- Gtk::Main mainInstance(argc, argv, context);
+
+
+ //Parse command-line arguments:
+ Glib::OptionContext context;
+ Glom::OptionGroup group;
+ context.set_main_group(group);
+ Gtk::Main mainInstance(argc, argv, context); //Parses standard GTK+ command-line arguments.
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
+ {
#else
std::auto_ptr<Glib::Error> error;
#endif // GLIBMM_EXCEPTIONS_ENABLED
- {
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
context.parse(argc, argv);
#else
context.parse(argc, argv, error);
#endif // GLIBMM_EXCEPTIONS_ENABLED
- }
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
+ }
catch(const Glib::OptionError& ex)
#else
- if(error.get() != NULL)
+ if(error.get())
#endif
{
#ifndef GLIBMM_EXCEPTIONS_ENABLED
@@ -215,7 +225,12 @@
return 0;
}
+#ifndef GLOM_ENABLE_CLIENT_ONLY
+ gtksourceview::init();
+ Goocanvas::init(PACKAGE, VERSION, argc, argv ) ;
+#endif //!GLOM_ENABLE_CLIENT_ONLY
+ //Show the application version:
if(group.m_arg_version)
{
std::cout << VERSION << std::endl;
@@ -226,11 +241,6 @@
try
#endif
{
-#ifndef GLOM_ENABLE_CLIENT_ONLY
- gtksourceview::init();
- Goocanvas::init(PACKAGE, VERSION, argc, argv ) ;
-#endif //!GLOM_ENABLE_CLIENT_ONLY
-
//Get command-line parameters, if any:
Glib::ustring input_uri = group.m_arg_filename;
@@ -255,6 +265,42 @@
//debugging:
//input_uri = "file:///home/murrayc/cvs/gnome212/glom/examples/example_smallbusiness.glom";
+
+ //Ensure that only one instance of Glom is ever started,
+ //so that the file menu's new/open/quit menu items can be aware of other open files/windows:
+ //
+ //If an instance is already running then ask that instance to do something instead,
+ //and close this instance.
+ UniqueApp* unique_app = unique_app_new("org.glom", NULL /* startup_id */);
+ if( unique_app_is_running(unique_app) )
+ {
+ //There is an existing instance:
+
+ UniqueResponse response = UNIQUE_RESPONSE_OK;
+
+ if(!input_uri.empty())
+ {
+ //Tell the existing instance to do a File/Open:
+ UniqueMessageData *message = unique_message_data_new();
+ unique_message_data_set_text(message, input_uri.c_str(), -1); //TODO: Use set_uris().
+ response = unique_app_send_message(unique_app, UNIQUE_OPEN, message);
+ unique_message_data_free(message);
+ }
+ else
+ {
+ //Tell the existing instance to do a File/New:
+ response = unique_app_send_message(unique_app, UNIQUE_NEW, 0);
+ }
+
+ g_object_unref(unique_app);
+ unique_app = 0;
+ if(response != UNIQUE_RESPONSE_OK)
+ std::cerr << "unique_app_send_message() failed." << std::endl;
+
+ return 0;
+ }
+ //Else this is the first instance:
+
#ifdef GLOM_ENABLE_POSTGRESQL
bool install_complete = false;
#ifndef GLOM_ENABLE_CLIENT_ONLY
@@ -300,18 +346,20 @@
}
#endif
-
+ //Create the main window (the application):
Glom::App_Glom* pApp_Glom = 0;
refXml->get_widget_derived("window_main", pApp_Glom);
+ pApp_Glom->set_unique_app(unique_app);
+ g_object_unref(unique_app);
+ unique_app = 0;
+
pApp_Glom->set_command_line_args(argc, argv);
pApp_Glom->set_show_sql_debug(group.m_arg_debug_sql);
- bool test = pApp_Glom->init(input_uri); //Sets it up and shows it.
+ const bool test = pApp_Glom->init(input_uri); //Sets it up and shows it.
if(test) //The user could cancel the offer of a new or existing database.
- {
Gtk::Main::run();
- }
else
delete pApp_Glom;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]