glom r2033 - in trunk: . glom glom/bakery glom/libglom glom/libglom/connectionpool_backends glom/libglom/document
- From: murrayc svn gnome org
- To: svn-commits-list gnome org
- Subject: glom r2033 - in trunk: . glom glom/bakery glom/libglom glom/libglom/connectionpool_backends glom/libglom/document
- Date: Fri, 27 Mar 2009 16:54:07 +0000 (UTC)
Author: murrayc
Date: Fri Mar 27 16:54:06 2009
New Revision: 2033
URL: http://svn.gnome.org/viewvc/glom?rev=2033&view=rev
Log:
2009-03-27 Murray Cumming <murrayc murrayc com>
* glom/bakery/app_withdoc.[h|cc]: Added on_document_close() virtual method
now that we can break this ABI.
* glom/application.[h|cc]: Override on_document_close().
* glom/libglom/document/document_glom.cc: Destructor: Don't shutdown the
database here. Do in App_Glom::on_document_close() instead.
* glom/libglom/Makefile.am:
* glom/libglom/spawn_with_feedback.[h|cc]: execute_command_line_and_wait(),
execute_command_line_and_wait_until_second_command_returns_success():
Take a SlotProgress callback instead of a parent window, and don't take
a human-readable message string to show, allowing the caller to show UI if
it wants, removing UI code from this part of libglom.
Use a Glib::MainLoop to block instead of using the Gtk::Main in
Gtk::Dialog::run().
* glom/libglom/connectionpool.[h|cc]: initialize(), startup, cleanup():
* glom/libglom/connectionpool_backends/backend.[h|cc]: initialize(),
startup(), cleanup():
* glom/libglom/connectionpool_backends/postgres_self.cc: initialize(),
startup, cleanup(): Take a SlotProgress callback instead of a parent window,
allowing the caller to show UI if it wants, removing UI code from this part of
libglom.
glom/Makefile.am:
* glom/libglom/dialog_progress_creating.[h|cc]: moved to
* glom/glom/glade_utils.[h|cc]: Moved get_and_show_pulse_dialog() here.
* glom/dialog_new_self_hosted_connection.[h|cc]:
* glom/frame_glom.[h|cc]:
connection_request_password_and_choose_new_database_name(),
connection_request_password_and_attempt(): Adapted.
Added:
trunk/glom/dialog_progress_creating.cc (contents, props changed)
- copied, changed from r2030, /trunk/glom/libglom/dialog_progress_creating.cc
trunk/glom/dialog_progress_creating.h (props changed)
- copied unchanged from r2030, /trunk/glom/libglom/dialog_progress_creating.h
Removed:
trunk/glom/libglom/dialog_progress_creating.cc
trunk/glom/libglom/dialog_progress_creating.h
Modified:
trunk/ChangeLog
trunk/glom/Makefile.am
trunk/glom/application.cc
trunk/glom/application.h
trunk/glom/bakery/app_withdoc.cc
trunk/glom/bakery/app_withdoc.h
trunk/glom/dialog_new_self_hosted_connection.cc
trunk/glom/dialog_new_self_hosted_connection.h
trunk/glom/frame_glom.cc
trunk/glom/frame_glom.h
trunk/glom/glade_utils.h
trunk/glom/libglom/Makefile.am
trunk/glom/libglom/connectionpool.cc
trunk/glom/libglom/connectionpool.h
trunk/glom/libglom/connectionpool_backends/backend.cc
trunk/glom/libglom/connectionpool_backends/backend.h
trunk/glom/libglom/connectionpool_backends/postgres_self.cc
trunk/glom/libglom/connectionpool_backends/postgres_self.h
trunk/glom/libglom/document/document_glom.cc
trunk/glom/libglom/spawn_with_feedback.cc
trunk/glom/libglom/spawn_with_feedback.h
Modified: trunk/glom/Makefile.am
==============================================================================
--- trunk/glom/Makefile.am (original)
+++ trunk/glom/Makefile.am Fri Mar 27 16:54:06 2009
@@ -48,10 +48,11 @@
dialog_existing_or_new.h dialog_existing_or_new.cc \
dialog_invalid_data.h dialog_invalid_data.cc \
filechooser_export.h filechooser_export.cc \
+ dialog_progress_creating.h dialog_progress_creating.cc \
box_reports.h box_reports.cc \
xsl_utils.h xsl_utils.cc \
variablesmap.h variablesmap.cc \
- signal_reemitter.h glade_utils.h
+ signal_reemitter.h glade_utils.h glade_utils.cc
if !GLOM_ENABLE_CLIENT_ONLY
glom_SOURCES += dialog_new_self_hosted_connection.h \
Modified: trunk/glom/application.cc
==============================================================================
--- trunk/glom/application.cc (original)
+++ trunk/glom/application.cc Fri Mar 27 16:54:06 2009
@@ -23,7 +23,7 @@
#include "application.h"
#include "dialog_existing_or_new.h"
-#include <libglom/dialog_progress_creating.h>
+#include <glom/dialog_progress_creating.h>
#ifndef GLOM_ENABLE_CLIENT_ONLY
#include <glom/translation/dialog_change_language.h>
@@ -1048,7 +1048,7 @@
{
// TODO: Do we need to call connection_pool->cleanup() here, for
// stopping self-hosted databases? armin.
- connection_pool->cleanup(this);
+ connection_pool->cleanup( sigc::mem_fun(*this, &App_Glom::on_connection_close_progress) );
//If the database was not successfully recreated:
if(!user_cancelled)
{
@@ -1093,6 +1093,24 @@
}
}
+void App_Glom::on_connection_close_progress()
+{
+ //TODO_murrayc
+}
+
+void App_Glom::on_document_close()
+{
+#ifndef GLOM_ENABLE_CLIENT_ONLY
+ //TODO: It would be better to do this in a Application::on_document_closed() virtual method,
+ //but that would need an ABI break in Bakery:
+ ConnectionPool* connection_pool = ConnectionPool::get_instance();
+ if(!connection_pool)
+ return;
+
+ connection_pool->cleanup( sigc::mem_fun(*this, &App_Glom::on_connection_close_progress) );
+#endif // !GLOM_ENABLE_CLIENT_ONLY
+}
+
/*
void App_Glom::statusbar_set_text(const Glib::ustring& strText)
{
@@ -2267,7 +2285,7 @@
if(!connection_pool)
return;
- connection_pool->cleanup(this);
+ connection_pool->cleanup( sigc::mem_fun(*this, &App_Glom::on_connection_close_progress ));
}
}
@@ -2396,6 +2414,7 @@
}
#endif
+
} //namespace Glom
Modified: trunk/glom/application.h
==============================================================================
--- trunk/glom/application.h (original)
+++ trunk/glom/application.h Fri Mar 27 16:54:06 2009
@@ -91,6 +91,7 @@
virtual void init_toolbars(); //override
virtual void init_create_document(); //override
virtual bool on_document_load(); //override.
+ virtual void on_document_close(); //override.
bool offer_new_or_existing();
@@ -131,6 +132,8 @@
virtual void document_history_add(const Glib::ustring& file_uri); //overridden.
virtual void new_instance(const Glib::ustring& uri = Glib::ustring()); //Override
+
+ void on_connection_close_progress();
#ifndef G_OS_WIN32
void open_browsed_document(const EpcServiceInfo* server, const Glib::ustring& service_name);
Modified: trunk/glom/bakery/app_withdoc.cc
==============================================================================
--- trunk/glom/bakery/app_withdoc.cc (original)
+++ trunk/glom/bakery/app_withdoc.cc Fri Mar 27 16:54:06 2009
@@ -47,7 +47,7 @@
}
//static
-void App_WithDoc::add_mime_type(const Glib::ustring& mime_type)
+void App_WithDoc::add_mime_type(const Glib::ustring& mime_type)
{
if( std::find(m_mime_types.begin(), m_mime_types.end(), mime_type) == m_mime_types.end() )
m_mime_types.push_back(mime_type);
@@ -64,6 +64,8 @@
if(!get_operation_cancelled())
ui_hide();
+
+ on_document_close();
}
bool App_WithDoc::open_document_from_data(const guchar* data, std::size_t length)
@@ -123,7 +125,7 @@
else
{
//if open succeeded then let the App respond:
- bool test = pApp->on_document_load();
+ const bool test = pApp->on_document_load();
if(!test)
bOpenFailed = true; //The application didn't like something about the just-loaded document.
else
@@ -412,6 +414,10 @@
//If you are not using Views, then override this to fill your various windows with stuff according to the contents of the document.
}
+void App_WithDoc::on_document_close()
+{
+}
+
void App_WithDoc::update_window_title()
{
Modified: trunk/glom/bakery/app_withdoc.h
==============================================================================
--- trunk/glom/bakery/app_withdoc.h (original)
+++ trunk/glom/bakery/app_withdoc.h Fri Mar 27 16:54:06 2009
@@ -131,6 +131,9 @@
///override this to show document contents.
virtual bool on_document_load();
+
+ ///override this to do extra cleanup.
+ virtual void on_document_close();
virtual void offer_to_save_changes();
Modified: trunk/glom/dialog_new_self_hosted_connection.cc
==============================================================================
--- trunk/glom/dialog_new_self_hosted_connection.cc (original)
+++ trunk/glom/dialog_new_self_hosted_connection.cc Fri Mar 27 16:54:06 2009
@@ -21,6 +21,7 @@
#include "dialog_new_self_hosted_connection.h"
#include "box_withbuttons.h" //For Box_WithButtons::connect_to_server().
#include <glom/frame_glom.h> //For Frame_Glom::show_ok_dialog
+#include <glom/glade_utils.h>
#include <glibmm/i18n.h>
namespace Glom
@@ -30,7 +31,8 @@
: Gtk::Dialog(cobject),
Base_DB(),
m_entry_user(0),
- m_entry_password(0)
+ m_entry_password(0),
+ m_dialog_progess_connection_initialize(0)
{
builder->get_widget("entry_user", m_entry_user);
builder->get_widget("entry_password", m_entry_password);
@@ -39,6 +41,19 @@
Dialog_NewSelfHostedConnection::~Dialog_NewSelfHostedConnection()
{
+ if(m_dialog_progess_connection_initialize)
+ {
+ delete m_dialog_progess_connection_initialize;
+ m_dialog_progess_connection_initialize = 0;
+ }
+}
+
+void Dialog_NewSelfHostedConnection::on_connection_initialization_progress()
+{
+ if(!m_dialog_progess_connection_initialize)
+ m_dialog_progess_connection_initialize = Utils::get_and_show_pulse_dialog(_("Creating Database Data"), this);
+
+ m_dialog_progess_connection_initialize->pulse();
}
bool Dialog_NewSelfHostedConnection::create_self_hosted()
@@ -62,7 +77,8 @@
connection_pool->set_user(m_entry_user->get_text());
connection_pool->set_password(m_entry_password->get_text());
//std::cout << "debug: Dialog_NewSelfHostedConnection::create_self_hosted() user=" << m_entry_user->get_text() << ", password=" << m_entry_password->get_text() << std::endl;
- const bool created = connection_pool->initialize(this /* parent_window for errors */);
+ const bool created = connection_pool->initialize(
+ sigc::mem_fun(*this, &Dialog_NewSelfHostedConnection::on_connection_initialization_progress) );
if(!created)
{
return false;
Modified: trunk/glom/dialog_new_self_hosted_connection.h
==============================================================================
--- trunk/glom/dialog_new_self_hosted_connection.h (original)
+++ trunk/glom/dialog_new_self_hosted_connection.h Fri Mar 27 16:54:06 2009
@@ -31,6 +31,8 @@
namespace Glom
{
+class Dialog_ProgressCreating;
+
class Dialog_NewSelfHostedConnection
: public Gtk::Dialog,
public Base_DB
@@ -47,9 +49,13 @@
private:
+ void on_connection_initialization_progress();
+
Gtk::Entry* m_entry_user;
Gtk::Entry* m_entry_password;
Gtk::Entry* m_entry_password_confirm;
+
+ Dialog_ProgressCreating* m_dialog_progess_connection_initialize;
};
} //namespace Glom
Copied: trunk/glom/dialog_progress_creating.cc (from r2030, /trunk/glom/libglom/dialog_progress_creating.cc)
==============================================================================
--- /trunk/glom/libglom/dialog_progress_creating.cc (original)
+++ trunk/glom/dialog_progress_creating.cc Fri Mar 27 16:54:06 2009
@@ -18,7 +18,7 @@
* Boston, MA 02111-1307, USA.
*/
-#include "dialog_progress_creating.h"
+#include <glom/dialog_progress_creating.h>
#include <gtkmm/main.h>
#include <gtkmm/dialog.h>
#include <glibmm/i18n.h>
Modified: trunk/glom/frame_glom.cc
==============================================================================
--- trunk/glom/frame_glom.cc (original)
+++ trunk/glom/frame_glom.cc Fri Mar 27 16:54:06 2009
@@ -102,7 +102,9 @@
m_dialog_addrelatedtable(0),
m_dialog_relationships_overview(0),
#endif // !GLOM_ENABLE_CLIENT_ONLY
- m_pDialogConnection(0)
+ m_pDialogConnection(0),
+ m_dialog_progess_connection_startup(0),
+ m_dialog_progess_connection_cleanup(0)
{
//Load widgets from glade file:
builder->get_widget("label_table_name", m_pLabel_Table);
@@ -177,6 +179,18 @@
delete m_pDialogConnection;
m_pDialogConnection = 0;
}
+
+ if(m_dialog_progess_connection_startup)
+ {
+ delete m_dialog_progess_connection_startup;
+ m_dialog_progess_connection_startup = 0;
+ }
+
+ if(m_dialog_progess_connection_cleanup)
+ {
+ delete m_dialog_progess_connection_cleanup;
+ m_dialog_progess_connection_cleanup = 0;
+ }
#ifndef GLOM_ENABLE_CLIENT_ONLY
if(m_pBox_Reports)
@@ -1692,6 +1706,22 @@
}
}
+void Frame_Glom::on_connection_startup_progress()
+{
+ if(!m_dialog_progess_connection_startup)
+ m_dialog_progess_connection_startup = Utils::get_and_show_pulse_dialog(_("Starting Database Server"), get_app_window());
+
+ m_dialog_progess_connection_startup->pulse();
+}
+
+void Frame_Glom::on_connection_cleanup_progress()
+{
+ if(!m_dialog_progess_connection_cleanup)
+ m_dialog_progess_connection_cleanup = Utils::get_and_show_pulse_dialog(_("Stopping Database Server"), get_app_window());
+
+ m_dialog_progess_connection_cleanup->pulse();
+}
+
bool Frame_Glom::connection_request_password_and_choose_new_database_name()
{
Document_Glom* document = dynamic_cast<Document_Glom*>(get_document());
@@ -1797,14 +1827,15 @@
//Ask for connection details:
m_pDialogConnection->load_from_document(); //Get good defaults.
m_pDialogConnection->set_transient_for(*get_app_window());
- int response = Glom::Utils::dialog_run_with_help(m_pDialogConnection, "dialog_connection");
+ const int response = Glom::Utils::dialog_run_with_help(m_pDialogConnection, "dialog_connection");
m_pDialogConnection->hide();
if(response == Gtk::RESPONSE_OK)
{
// We are not self-hosting, but we also call initialize() for
// consistency (the backend will ignore it anyway).
- if(!connection_pool->initialize(get_app_window()))
+ ConnectionPool::SlotProgress slot_ignored;
+ if(!connection_pool->initialize(slot_ignored))
return false;
}
else
@@ -1835,8 +1866,14 @@
}
// Do startup, such as starting the self-hosting database server
- if(!connection_pool->startup(get_app_window()))
+ if(!connection_pool->startup( sigc::mem_fun(*this, &Frame_Glom::on_connection_startup_progress) ))
return false;
+
+ if(m_dialog_progess_connection_startup)
+ {
+ delete m_dialog_progess_connection_startup;
+ m_dialog_progess_connection_startup = 0;
+ }
const Glib::ustring database_name = document->get_connection_database();
@@ -1929,10 +1966,23 @@
}
}
- connection_pool->cleanup(get_app_window());
+ cleanup_connection();
+
return false;
}
+void Frame_Glom::cleanup_connection()
+{
+ ConnectionPool* connection_pool = ConnectionPool::get_instance();
+ connection_pool->cleanup( sigc::mem_fun(*this, &Frame_Glom::on_connection_cleanup_progress) );
+
+ if(m_dialog_progess_connection_cleanup)
+ {
+ delete m_dialog_progess_connection_cleanup;
+ m_dialog_progess_connection_cleanup = 0;
+ }
+}
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
bool Frame_Glom::connection_request_password_and_attempt(const Glib::ustring known_username, const Glib::ustring& known_password)
#else
@@ -1951,8 +2001,14 @@
ConnectionPool* connection_pool = ConnectionPool::get_instance();
setup_connection_pool_from_document(document);
- if(!connection_pool->startup(get_app_window()))
+ if(!connection_pool->startup( sigc::mem_fun(*this, &Frame_Glom::on_connection_startup_progress) ))
return false;
+
+ if(m_dialog_progess_connection_startup)
+ {
+ delete m_dialog_progess_connection_startup;
+ m_dialog_progess_connection_startup = 0;
+ }
while(true) //Loop until a return
{
@@ -2015,7 +2071,7 @@
m_pDialogConnection->hide();
if(response != Gtk::RESPONSE_OK)
{
- connection_pool->cleanup(get_app_window());
+ cleanup_connection();
return false; //The user cancelled.
}
}
@@ -2023,7 +2079,7 @@
{
g_warning("Frame_Glom::connection_request_password_and_attempt(): rethrowing exception.");
- connection_pool->cleanup(get_app_window());
+ cleanup_connection();
//The connection to the server is OK, but the specified database does not exist:
#ifdef GLIBMM_EXCEPTIONS_ENABLED
@@ -2039,7 +2095,7 @@
}
else
{
- connection_pool->cleanup(get_app_window());
+ cleanup_connection();
return false; //The user cancelled.
}
}
Modified: trunk/glom/frame_glom.h
==============================================================================
--- trunk/glom/frame_glom.h (original)
+++ trunk/glom/frame_glom.h Fri Mar 27 16:54:06 2009
@@ -52,6 +52,7 @@
class Window_PrintLayout_Edit;
class Dialog_AddRelatedTable;
class Dialog_RelationshipsOverview;
+class Dialog_ProgressCreating;
#endif // !GLOM_ENABLE_CLIENT_ONLY
class Frame_Glom :
@@ -217,6 +218,10 @@
void on_dialog_add_related_table_response(int response);
#endif // !GLOM_ENABLE_CLIENT_ONLY
+ void on_connection_startup_progress();
+ void on_connection_cleanup_progress();
+ void cleanup_connection();
+
//Member data:
Glib::ustring m_table_name;
@@ -259,10 +264,12 @@
Dialog_Relationships* m_pDialog_Relationships;
Dialog_AddRelatedTable* m_dialog_addrelatedtable;
Dialog_RelationshipsOverview* m_dialog_relationships_overview;
-
+
#endif // !GLOM_ENABLE_CLIENT_ONLY
Dialog_Connection* m_pDialogConnection;
+ Dialog_ProgressCreating* m_dialog_progess_connection_startup;
+ Dialog_ProgressCreating* m_dialog_progess_connection_cleanup;
};
} //namespace Glom
Modified: trunk/glom/glade_utils.h
==============================================================================
--- trunk/glom/glade_utils.h (original)
+++ trunk/glom/glade_utils.h Fri Mar 27 16:54:06 2009
@@ -23,7 +23,7 @@
#include <iostream> // For std::cerr
#include <gtkmm/builder.h>
-#include <gtkmm/builder.h>
+#include <glom/dialog_progress_creating.h>
namespace Glom
{
@@ -123,6 +123,8 @@
}
}
+Dialog_ProgressCreating* get_and_show_pulse_dialog(const Glib::ustring& message, Gtk::Window* parent_window);
+
} //namespace Utils
} //namespace Glom
Modified: trunk/glom/libglom/Makefile.am
==============================================================================
--- trunk/glom/libglom/Makefile.am (original)
+++ trunk/glom/libglom/Makefile.am Fri Mar 27 16:54:06 2009
@@ -29,7 +29,6 @@
busy_cursor.h \
calcinprogress.h \
connectionpool.h \
- dialog_progress_creating.h \
spawn_with_feedback.h \
utils.h \
gst-package.h
@@ -38,7 +37,6 @@
busy_cursor.cc \
calcinprogress.cc \
connectionpool.cc \
- dialog_progress_creating.cc \
spawn_with_feedback.cc \
utils.cc \
gst-package.c
Modified: trunk/glom/libglom/connectionpool.cc
==============================================================================
--- trunk/glom/libglom/connectionpool.cc (original)
+++ trunk/glom/libglom/connectionpool.cc Fri Mar 27 16:54:06 2009
@@ -602,9 +602,8 @@
if(signum == SIGSEGV)
{
- //TODO: Make this dialog transient for the parent window,
- //though this is obviously an unusual case.
- connection_pool->cleanup(0 /* parent_window */);
+ ConnectionPool::SlotProgress slot_ignored;
+ connection_pool->cleanup(slot_ignored);
//Let GNOME/Ubuntu's crash handler still handle this?
if(previous_sig_handler)
@@ -614,12 +613,12 @@
}
}
-bool ConnectionPool::startup(Gtk::Window* parent_window)
+bool ConnectionPool::startup(const SlotProgress& slot_progress)
{
if(!m_backend.get())
return false;
- if(!m_backend->startup(parent_window))
+ if(!m_backend->startup(slot_progress))
return false;
#ifndef G_OS_WIN32
@@ -634,10 +633,10 @@
return true;
}
-void ConnectionPool::cleanup(Gtk::Window* parent_window)
+void ConnectionPool::cleanup(const SlotProgress& slot_progress)
{
if(m_backend.get())
- m_backend->cleanup(parent_window);
+ m_backend->cleanup(slot_progress);
//Make sure that connect() makes a new connection:
connection_cached.clear();
@@ -781,10 +780,10 @@
}
#endif // !GLOM_ENABLE_CLIENT_ONLY
-bool ConnectionPool::initialize(Gtk::Window* parent_window)
+bool ConnectionPool::initialize(const SlotProgress& slot_progress)
{
if(m_backend.get())
- return m_backend->initialize(parent_window, get_user(), get_password());
+ return m_backend->initialize(slot_progress, get_user(), get_password());
else
return false;
}
Modified: trunk/glom/libglom/connectionpool.h
==============================================================================
--- trunk/glom/libglom/connectionpool.h (original)
+++ trunk/glom/libglom/connectionpool.h Fri Mar 27 16:54:06 2009
@@ -41,7 +41,6 @@
namespace Gtk
{
- class Window;
class Dialog;
}
@@ -150,22 +149,27 @@
const FieldTypes* get_field_types() const;
Glib::ustring get_string_find_operator() const;
+ /** This callback should show UI to indicate that work is still happening.
+ * For instance, a pulsing ProgressBar.
+ */
+ typedef sigc::slot<void> SlotProgress;
+
/** Do one-time initialization, such as creating required database
* files on disk for later use by their own database server instance.
* @param parent_window A parent window to use as the transient window when displaying errors.
*/
- bool initialize(Gtk::Window* parent_window);
+ bool initialize(const SlotProgress& slot_progress);
/** Start a database server instance for the exisiting database files.
* @param parent_window The parent window (transient for) of any dialogs shown during this operation.
* @result Whether the operation was successful.
*/
- bool startup(Gtk::Window* parent_window);
+ bool startup(const SlotProgress& slot_progress);
/** Stop the database server instance for the database files.
* @param parent_window The parent window (transient for) of any dialogs shown during this operation.
*/
- void cleanup(Gtk::Window* parent_window);
+ void cleanup(const SlotProgress& slot_progress);
#ifndef GLOM_ENABLE_CLIENT_ONLY
#ifdef GLIBMM_EXCEPTIONS_ENABLED
Modified: trunk/glom/libglom/connectionpool_backends/backend.cc
==============================================================================
--- trunk/glom/libglom/connectionpool_backends/backend.cc (original)
+++ trunk/glom/libglom/connectionpool_backends/backend.cc Fri Mar 27 16:54:06 2009
@@ -45,18 +45,19 @@
namespace ConnectionPoolBackends
{
-bool Backend::initialize(Gtk::Window* /* parent_window */, const Glib::ustring& /* initial_username */, const Glib::ustring& /* password */)
+bool Backend::initialize(const SlotProgress& /* slot_progress */, const Glib::ustring& /* initial_username */, const Glib::ustring& /* password */)
{
return true;
}
-bool Backend::startup(Gtk::Window* /* parent_window */)
+bool Backend::startup(const SlotProgress& /* slot_progress */)
{
return true;
}
-void Backend::cleanup(Gtk::Window* /* parent_window */)
-{}
+void Backend::cleanup(const SlotProgress& /* slot_progress */)
+{
+}
bool Backend::set_server_operation_value(const Glib::RefPtr<Gnome::Gda::ServerOperation>& operation, const Glib::ustring& path, const Glib::ustring& value, std::auto_ptr<Glib::Error>& error)
{
Modified: trunk/glom/libglom/connectionpool_backends/backend.h
==============================================================================
--- trunk/glom/libglom/connectionpool_backends/backend.h (original)
+++ trunk/glom/libglom/connectionpool_backends/backend.h Fri Mar 27 16:54:06 2009
@@ -101,23 +101,34 @@
*/
virtual Glib::ustring get_string_find_operator() const = 0;
+ /** This callback should show UI to indicate that work is still happening.
+ * For instance, a pulsing ProgressBar.
+ */
+ typedef sigc::slot<void> SlotProgress;
+
/** This method is called for one-time initialization of the database
* storage. No need to implement this function if the data is centrally
* hosted, not managed by Glom.
+ *
+ * @slot_progress A callback to call while the work is still happening.
*/
- virtual bool initialize(Gtk::Window* parent_window, const Glib::ustring& initial_username, const Glib::ustring& password);
+ virtual bool initialize(const SlotProgress& slot_progress, const Glib::ustring& initial_username, const Glib::ustring& password);
/** This method is called before the backend is used otherwise. This can
* be used to start a self-hosted database server. There is no need to implement
* this function if there is no need for extra startup code.
+ *
+ * @slot_progress A callback to call while the work is still happening.
*/
- virtual bool startup(Gtk::Window* parent_window);
+ virtual bool startup(const SlotProgress& slot_progress);
/** This method is called when the backend is no longer used. This can be
* used to shut down a self-hosted database server. There is no need to
* implement this function if there is no need for extra cleanup code.
+ *
+ * @slot_progress A callback to call while the work is still happening.
*/
- virtual void cleanup(Gtk::Window* parent_window);
+ virtual void cleanup(const SlotProgress& slot_progress);
/** This method is called to create a connection to the database server.
* There exists only the variant with an error variable as last parameter
Modified: trunk/glom/libglom/connectionpool_backends/postgres_self.cc
==============================================================================
--- trunk/glom/libglom/connectionpool_backends/postgres_self.cc (original)
+++ trunk/glom/libglom/connectionpool_backends/postgres_self.cc Fri Mar 27 16:54:06 2009
@@ -194,7 +194,7 @@
/** Try to install postgres on the distro, though this will require a
* distro-specific patch to the implementation.
*/
-bool PostgresSelfHosted::install_postgres(Gtk::Window* /* parent_window */)
+bool PostgresSelfHosted::install_postgres(const SlotProgress& /* slot_progress */)
{
#if 0
// This is example code for Ubuntu, and possibly Debian,
@@ -229,8 +229,10 @@
#endif // #if 0
}
-bool PostgresSelfHosted::initialize(Gtk::Window* parent_window, const Glib::ustring& initial_username, const Glib::ustring& password)
+bool PostgresSelfHosted::initialize(const SlotProgress& slot_progress, const Glib::ustring& initial_username, const Glib::ustring& password)
{
+ Gtk::Window* parent_window = 0; //TODO: Replace the dialog with some callback or exception?
+
if(m_self_hosting_data_uri.empty())
{
std::cerr << "PostgresSelfHosted::initialize: m_self_hosting_data_uri is empty." << std::endl;
@@ -322,7 +324,7 @@
" -U " + initial_username + " --pwfile=\"" + temp_pwfile + "\"";
//Note that --pwfile takes the password from the first line of a file. It's an alternative to supplying it when prompted on stdin.
- const bool result = Glom::Spawn::execute_command_line_and_wait(command_initdb, _("Creating Database Data"), parent_window);
+ const bool result = Glom::Spawn::execute_command_line_and_wait(command_initdb, slot_progress);
if(!result)
{
std::cerr << "Error while attempting to create self-hosting database." << std::endl;
@@ -334,7 +336,7 @@
return result;
}
-bool PostgresSelfHosted::startup(Gtk::Window* parent_window)
+bool PostgresSelfHosted::startup(const SlotProgress& slot_progress)
{
// Don't risk random crashes, although this really shouldn't be called
// twice of course.
@@ -405,7 +407,7 @@
const std::string second_command_success_text = "is running"; //TODO: This is not a stable API. Also, watch out for localisation.
//The first command does not return, but the second command can check whether it succeeded:
- const bool result = Glom::Spawn::execute_command_line_and_wait_until_second_command_returns_success(command_postgres_start, command_check_postgres_has_started, _("Starting Database Server"), parent_window, second_command_success_text);
+ const bool result = Glom::Spawn::execute_command_line_and_wait_until_second_command_returns_success(command_postgres_start, command_check_postgres_has_started, slot_progress, second_command_success_text);
if(!result)
{
std::cerr << "Error while attempting to self-host a database." << std::endl;
@@ -417,7 +419,7 @@
return true;
}
-void PostgresSelfHosted::cleanup(Gtk::Window* parent_window)
+void PostgresSelfHosted::cleanup(const SlotProgress& slot_progress)
{
// This seems to be called twice sometimes, so we don't assert here until
// this is fixed.
@@ -445,14 +447,14 @@
// Make sure to use double quotes for the executable path, because the
// CreateProcess() API used on Windows does not support single quotes.
const std::string command_postgres_stop = "\"" + get_path_to_postgres_executable("pg_ctl") + "\" -D \"" + dbdir_data + "\" stop -m fast";
- const bool result = Glom::Spawn::execute_command_line_and_wait(command_postgres_stop, _("Stopping Database Server"), parent_window);
+ const bool result = Glom::Spawn::execute_command_line_and_wait(command_postgres_stop, slot_progress);
if(!result)
{
std::cerr << "Error while attempting to stop self-hosting of the database. Trying again." << std::endl;
//I've seen it fail when running under valgrind, and there are reports of failures in bug #420962.
//Maybe it will help to try again:
- const bool result = Glom::Spawn::execute_command_line_and_wait(command_postgres_stop, _("Stopping Database Server (retrying)"), parent_window);
+ const bool result = Glom::Spawn::execute_command_line_and_wait(command_postgres_stop, slot_progress);
if(!result)
{
std::cerr << "Error while attempting (for a second time) to stop self-hosting of the database." << std::endl;
Modified: trunk/glom/libglom/connectionpool_backends/postgres_self.h
==============================================================================
--- trunk/glom/libglom/connectionpool_backends/postgres_self.h (original)
+++ trunk/glom/libglom/connectionpool_backends/postgres_self.h Fri Mar 27 16:54:06 2009
@@ -64,13 +64,13 @@
/** Try to install postgres on the distro, though this will require a
* distro-specific patch to the implementation.
*/
- static bool install_postgres(Gtk::Window* parent_window);
+ static bool install_postgres(const SlotProgress& slot_progress);
private:
- virtual bool initialize(Gtk::Window* parent_window, const Glib::ustring& initial_username, const Glib::ustring& password);
+ virtual bool initialize(const SlotProgress& slot_progress, const Glib::ustring& initial_username, const Glib::ustring& password);
- virtual bool startup(Gtk::Window* parent_window);
- virtual void cleanup(Gtk::Window* parent_window);
+ virtual bool startup(const SlotProgress& slot_progress);
+ virtual void cleanup(const SlotProgress& slot_progress);
virtual Glib::RefPtr<Gnome::Gda::Connection> connect(const Glib::ustring& database, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<ExceptionConnection>& error);
Modified: trunk/glom/libglom/document/document_glom.cc
==============================================================================
--- trunk/glom/libglom/document/document_glom.cc (original)
+++ trunk/glom/libglom/document/document_glom.cc Fri Mar 27 16:54:06 2009
@@ -271,15 +271,6 @@
Document_Glom::~Document_Glom()
{
-#ifndef GLOM_ENABLE_CLIENT_ONLY
- //TODO: It would be better to do this in a Application::on_document_closed() virtual method,
- //but that would need an ABI break in Bakery:
- ConnectionPool* connection_pool = ConnectionPool::get_instance();
- if(!connection_pool)
- return;
-
- connection_pool->cleanup(m_parent_window);
-#endif // !GLOM_ENABLE_CLIENT_ONLY
}
Document_Glom::HostingMode Document_Glom::get_hosting_mode() const
Modified: trunk/glom/libglom/spawn_with_feedback.cc
==============================================================================
--- trunk/glom/libglom/spawn_with_feedback.cc (original)
+++ trunk/glom/libglom/spawn_with_feedback.cc Fri Mar 27 16:54:06 2009
@@ -19,12 +19,15 @@
*/
#include <libglom/spawn_with_feedback.h>
-#include <libglom/dialog_progress_creating.h>
-#include <glom/glade_utils.h>
-#include <gtkmm/main.h>
-#include <gtkmm/messagedialog.h>
+#include <glibmm/main.h>
+#include <glibmm/spawn.h>
+#include <glibmm/thread.h>
+#include <glibmm/iochannel.h>
+#include <glibmm/shell.h>
+#include <glibmm/miscutils.h>
#include <glibmm/i18n.h>
#include <memory> //For auto_ptr.
+#include <stdexcept>
#include <iostream>
#ifdef G_OS_WIN32
@@ -50,9 +53,17 @@
bool* m_result;
};
-// This is a simple process launching API wrapping g_spawn_async on linux and
-// CreateProcess() on Windows. We need to use CreateProcess on Windows to be
+static void on_spawn_info_finished(const Glib::RefPtr<Glib::MainLoop>& mainloop)
+{
+ //Allow our mainloop.run() to return:
+ if(mainloop)
+ mainloop->quit();
+}
+
+// This is a simple-process launching API wrapping g_spawn_async on linux and
+// CreateProcess() on Windows. We need to use CreateProcess() on Windows to be
// able to suppress the console window.
+// TODO: File a bug about the console window on Windows.
namespace Impl
{
@@ -120,7 +131,7 @@
char buffer[1024 + 1];
gsize bytes_read;
- Glib::IOStatus status;
+ Glib::IOStatus status = Glib::IO_STATUS_NORMAL;
#ifdef GLIBMM_EXCEPTIONS_ENABLED
try
{
@@ -341,11 +352,14 @@
if(stderr_text)
redirect_flags |= REDIRECT_STDERR;
+ Glib::RefPtr<Glib::MainLoop> mainloop = Glib::MainLoop::create(false);
+
std::auto_ptr<const SpawnInfo> info = spawn_async(command_line, redirect_flags);
- info->signal_finished().connect(sigc::ptr_fun(&Gtk::Main::quit));
-
- // Wait for termination
- Gtk::Main::run();
+ info->signal_finished().connect(
+ sigc::bind(sigc::ptr_fun(&on_spawn_info_finished), sigc::ref(mainloop) ) );
+
+ // Block until signal_finished is emitted:
+ mainloop->run();
int return_status = 0;
bool returned = spawn_async_end(info, stdout_text, stderr_text, &return_status);
@@ -355,69 +369,30 @@
} // namespace Impl
-static Dialog_ProgressCreating* get_and_show_pulse_dialog(const Glib::ustring& message, Gtk::Window* parent_window)
-{
- if(!parent_window)
- std::cerr << "debug: Glom: get_and_show_pulse_dialog(): parent_window is NULL" << std::endl;
-
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- Glib::RefPtr<Gtk::Builder> refXml = Gtk::Builder::create_from_file(Utils::get_glade_file_path("glom.glade"), "window_progress");
-#else
- std::auto_ptr<Glib::Error> error;
- Glib::RefPtr<Gtk::Builder> refXml = Gtk::Builder::create_from_file(Utils::get_glade_file_path("glom.glade"), "window_progress", "", error);
- if(error.get())
- return 0;
-#endif
-
- if(refXml)
- {
- Dialog_ProgressCreating* dialog_progress = 0;
- refXml->get_widget_derived("window_progress", dialog_progress);
- if(dialog_progress)
- {
- dialog_progress->set_message(_("Processing"), message);
- dialog_progress->set_modal();
-
- if(parent_window)
- dialog_progress->set_transient_for(*parent_window);
- dialog_progress->show();
-
- return dialog_progress;
- }
- }
-
- return NULL;
-}
-
-
-
-bool execute_command_line_and_wait(const std::string& command, const Glib::ustring& message, Gtk::Window* parent_window)
+bool execute_command_line_and_wait(const std::string& command, const SlotProgress& slot_progress)
{
- if(!parent_window)
- std::cerr << "debug: Glom: execute_command_line_and_wait(): parent_window is NULL" << std::endl;
-
- //Show a dialog with a pulsing progress bar and a human-readable message, while we wait for the command to finish:
- //
- //Put the dialog in an auto_ptr so that it will be deleted (and hidden) when the current function returns.
- Dialog_ProgressCreating* dialog_temp = get_and_show_pulse_dialog(message, parent_window);
- std::auto_ptr<Dialog_ProgressCreating> dialog_progress;
- dialog_progress.reset(dialog_temp);
-
+ //Show UI progress feedback while we wait for the command to finish:
+
std::auto_ptr<const Impl::SpawnInfo> info = Impl::spawn_async(command, 0);
+
+ Glib::RefPtr<Glib::MainLoop> mainloop = Glib::MainLoop::create(false);
info->signal_finished().connect(
- sigc::bind(sigc::mem_fun(*dialog_progress, &Dialog_ProgressCreating::response), Gtk::RESPONSE_ACCEPT));
+ sigc::bind(sigc::ptr_fun(&on_spawn_info_finished), sigc::ref(mainloop) ) );
- // Pulse two times a second
+ // Pulse two times a second:
Glib::signal_timeout().connect(
- sigc::bind_return(sigc::mem_fun(*dialog_progress, &Dialog_ProgressCreating::pulse), true),
+ sigc::bind_return( slot_progress, true),
500);
+ slot_progress(); //Make sure it is called at least once.
- dialog_progress->run();
+ //Block until signal_finished is called.
+ mainloop->run();
- int return_status;
- bool returned = Impl::spawn_async_end(info, NULL, NULL, &return_status);
- if(!returned) return false; // User closed the dialog prematurely?
+ int return_status = false;
+ const bool returned = Impl::spawn_async_end(info, NULL, NULL, &return_status);
+ if(!returned)
+ return false; // User closed the dialog prematurely?
return (return_status == 0);
}
@@ -426,7 +401,7 @@
namespace
{
- bool on_timeout(const std::string& second_command, const std::string& success_text, Dialog_ProgressCreating* dialog_progress)
+ bool second_command_on_timeout(const std::string& second_command, const std::string& success_text, const SlotProgress& slot_progress, const Glib::RefPtr<Glib::MainLoop>& mainloop)
{
Glib::ustring stored_env_lang;
Glib::ustring stored_env_language;
@@ -485,9 +460,9 @@
if(success)
{
- std::cout << "Success, do response" << std::endl;
+ std::cout << "debug: Success, do response" << std::endl;
// Exit from run() in execute_command_line_and_wait_until_second_command_returns_success().
- dialog_progress->response(Gtk::RESPONSE_OK);
+ mainloop->quit();
// Cancel timeout. Actually, we also could return true here since
// the signal is disconnect explicetely after run() anyway.
return false;
@@ -498,22 +473,24 @@
std::cout << " debug: second command failed. output=" << stdout_output << std::endl;
}
- dialog_progress->pulse();
+ slot_progress(); //Show UI progress feedback.
return true;
}
} //Anonymous namespace
-bool execute_command_line_and_wait_until_second_command_returns_success(const std::string& command, const std::string& second_command, const Glib::ustring& message, Gtk::Window* parent_window, const std::string& success_text)
+static bool on_timeout_delay(const Glib::RefPtr<Glib::MainLoop>& mainloop)
{
- if(!parent_window)
- std::cerr << "debug: Glom: execute_command_line_and_wait_until_second_command_returns_success(): parent_window is NULL" << std::endl;
-
- Dialog_ProgressCreating* dialog_temp = get_and_show_pulse_dialog(message, parent_window);
- std::auto_ptr<Dialog_ProgressCreating> dialog_progress;
- dialog_progress.reset(dialog_temp);
+ //Allow our mainloop.run() to return:
+ if(mainloop)
+ mainloop->quit();
+
+ return false;
+}
- std::cout << "Command: " << command << std::endl;
+bool execute_command_line_and_wait_until_second_command_returns_success(const std::string& command, const std::string& second_command, const SlotProgress& slot_progress, const std::string& success_text)
+{
+ std::cout << "debug: Command: " << command << std::endl;
std::auto_ptr<const Impl::SpawnInfo> info = Impl::spawn_async(command, Impl::REDIRECT_STDERR);
@@ -523,35 +500,41 @@
// b) Get stderr data, to display an error message in case the command
// fails:
- // Hide dialog when the first command finished for some reason
- sigc::connection watch_conn = info->signal_finished().connect(sigc::bind(sigc::mem_fun(*dialog_temp, &Dialog_ProgressCreating::response), Gtk::RESPONSE_REJECT));
+ Glib::RefPtr<Glib::MainLoop> mainloop = Glib::MainLoop::create(false);
+ sigc::connection watch_conn = info->signal_finished().connect(
+ sigc::bind(sigc::ptr_fun(&on_spawn_info_finished), sigc::ref(mainloop) ) );
// Call the second command once every second
- sigc::connection timeout_conn = Glib::signal_timeout().connect(sigc::bind(sigc::ptr_fun(&on_timeout), sigc::ref(second_command), sigc::ref(success_text), dialog_temp), 1000);
+ sigc::connection timeout_conn = Glib::signal_timeout().connect(sigc::bind(sigc::ptr_fun(&second_command_on_timeout), sigc::ref(second_command), sigc::ref(success_text), slot_progress, sigc::ref(mainloop)), 1000);
+ slot_progress(); //Make sure it is called at least once.
- // Enter the main loop
- int response = dialog_temp->run();
+ // Block until signal_finished is emitted:
+ mainloop->run();
timeout_conn.disconnect();
watch_conn.disconnect();
std::string stderr_text;
- Impl::spawn_async_end(info, NULL, &stderr_text, NULL);
+ const bool success = Impl::spawn_async_end(info, NULL, &stderr_text, NULL);
- if(response == Gtk::RESPONSE_OK)
+ if(success) //response == Gtk::RESPONSE_OK)
{
//Sleep for a bit more, because I think that pg_ctl sometimes reports success too early.
- Glib::signal_timeout().connect(sigc::bind_return(sigc::ptr_fun(&Gtk::Main::quit), false), 3000);
- Gtk::Main::run();
+ Glib::RefPtr<Glib::MainLoop> mainloop = Glib::MainLoop::create(false);
+ Glib::signal_timeout().connect(
+ sigc::bind(sigc::ptr_fun(&on_timeout_delay), sigc::ref(mainloop)),
+ 3000);
+ mainloop->run();
return true;
}
else
{
// The user either cancelled, or the first command failed, or exited prematurely
- if(response == Gtk::RESPONSE_REJECT)
+ if(true) //response == Gtk::RESPONSE_REJECT)
{
+ /* TODO: Allow the caller to show a dialog?
// Command failed
std::auto_ptr<Gtk::MessageDialog> error_dialog;
if(parent_window)
@@ -562,6 +545,9 @@
// TODO: i18n
error_dialog->set_secondary_text("The command was:\n\n" + Glib::Markup::escape_text(command) + (stderr_text.empty() ? Glib::ustring("") : ("\n\n<small>" + Glib::Markup::escape_text(stderr_text) + "</small>")), true);
error_dialog->run();
+ */
+
+ std::cerr << "Glom: execute_command_line_and_wait_until_second_command_returns_success(): Child command failed. The command was: " << std::endl << stderr_text << std::endl;
}
else
{
Modified: trunk/glom/libglom/spawn_with_feedback.h
==============================================================================
--- trunk/glom/libglom/spawn_with_feedback.h (original)
+++ trunk/glom/libglom/spawn_with_feedback.h Fri Mar 27 16:54:06 2009
@@ -21,7 +21,8 @@
#ifndef GLOM_SPAWN_WITH_FEEDBACK_H
#define GLOM_SPAWN_WITH_FEEDBACK_H
-#include <gtkmm/window.h>
+#include <glibmm/ustring.h>
+#include <sigc++/sigc++.h>
namespace Glom
{
@@ -29,23 +30,25 @@
namespace Spawn
{
+/** This callback should show UI to indicate that work is still happening.
+ * For instance, a pulsing ProgressBar.
+ */
+typedef sigc::slot<void> SlotProgress;
/** Execute a command-line command, and wait for it to return.
* @param command The command-line command.
* @param message A human-readable message to be shown, for instance in a dialog, while waiting.
- * @parent_window Make the dialog transient to this window.
+ * @slot_progress A callback to call while the work is still happening.
*/
-bool execute_command_line_and_wait(const std::string& command, const Glib::ustring& message, Gtk::Window* parent_window);
+bool execute_command_line_and_wait(const std::string& command, const SlotProgress& slot_progress);
/** Execute a command-line command, and repeatedly call a second command that tests whether the first command has finished.
* @param command The command-line command.
* @param message A human-readable message to be shown, for instance in a dialog, while waiting.
- * @parent_window Make the dialog transient to this window.
+ * @slot_progress A callback to call while the work is still happening.
* @success_text If this is not empty, then the second command will only be considered to have succeeded when this text is found in its stdout output.
*/
-bool execute_command_line_and_wait_until_second_command_returns_success(const std::string& command, const std::string& second_command, const Glib::ustring& message, Gtk::Window* parent_window, const std::string& success_text = std::string());
-
-//bool execute_command_line_and_wait_fixed_seconds(const std::string& command, unsigned int seconds, const Glib::ustring& message, Gtk::Window* parent_window);
+bool execute_command_line_and_wait_until_second_command_returns_success(const std::string& command, const std::string& second_command, const SlotProgress& slot_progress, const std::string& success_text = std::string());
} //Spawn
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]