[glom] Use std::shared_ptr<> for Document.



commit 39147bb51313d151ebb8c4048f3af6999325c7e4
Author: Murray Cumming <murrayc murrayc com>
Date:   Wed Feb 3 21:24:02 2016 +0100

    Use std::shared_ptr<> for Document.

 glom/appwindow.cc                                  |  162 ++++++++++----------
 glom/appwindow.h                                   |    4 +-
 glom/bakery/appwindow_withdoc.cc                   |   79 ++++++----
 glom/bakery/appwindow_withdoc.h                    |    6 +-
 glom/base_db.cc                                    |   20 +--
 glom/base_db.h                                     |   12 +-
 glom/base_db_table_data.cc                         |    2 +-
 glom/box_withbuttons.cc                            |    4 +-
 glom/dialog_connection.cc                          |    2 +-
 glom/filechooser_export.cc                         |    2 +-
 glom/filechooser_export.h                          |    4 +-
 glom/frame_glom.cc                                 |   27 ++--
 glom/frame_glom.h                                  |    4 +-
 glom/glom_create_from_example.cc                   |   38 +++---
 glom/glom_export_po.cc                             |   10 +-
 glom/glom_export_po_all.cc                         |   12 +-
 glom/glom_import_po_all.cc                         |   12 +-
 glom/libglom/connectionpool.cc                     |   14 +-
 glom/libglom/connectionpool.h                      |    6 +-
 .../data_structure/layout/layoutitem_portal.cc     |    8 +-
 .../data_structure/layout/layoutitem_portal.h      |    8 +-
 glom/libglom/db_utils.cc                           |   36 +++---
 glom/libglom/db_utils.h                            |   36 +++---
 glom/libglom/document/bakery/document.cc           |    4 +
 glom/libglom/document/bakery/document.h            |    3 +
 glom/libglom/document/bakery/view/view.h           |   26 ++--
 glom/libglom/document/bakery/view/view_composite.h |    6 +-
 glom/libglom/example_document_load.cc              |   20 ++--
 glom/libglom/python_embed/py_glom_record.cc        |    2 +-
 glom/libglom/python_embed/py_glom_record.h         |    4 +-
 glom/libglom/python_embed/py_glom_relatedrecord.cc |    5 +-
 glom/libglom/python_embed/py_glom_relatedrecord.h  |    4 +-
 glom/libglom/report_builder.cc                     |   14 +-
 glom/libglom/report_builder.h                      |    8 +-
 glom/libglom/translations_po.cc                    |    6 +-
 glom/libglom/translations_po.h                     |    6 +-
 glom/libglom/utils.cc                              |   10 +-
 glom/libglom/utils.h                               |   10 +-
 glom/mode_data/box_data.cc                         |    6 +-
 glom/mode_data/box_data_details.cc                 |    8 +-
 glom/mode_data/box_data_list.cc                    |    2 +-
 glom/mode_data/box_data_list_related.cc            |    2 +-
 glom/mode_data/datawidget/cellcreation.cc          |    2 +-
 glom/mode_data/datawidget/cellcreation.h           |    2 +-
 glom/mode_data/datawidget/cellrenderer_dblist.cc   |    2 +-
 glom/mode_data/datawidget/cellrenderer_dblist.h    |    4 +-
 glom/mode_data/datawidget/combo.cc                 |    2 +-
 glom/mode_data/datawidget/combo.h                  |    2 +-
 .../mode_data/datawidget/combo_as_radio_buttons.cc |    2 +-
 glom/mode_data/datawidget/combo_as_radio_buttons.h |    2 +-
 glom/mode_data/datawidget/combochoices.cc          |    4 +-
 glom/mode_data/datawidget/combochoices.h           |    4 +-
 .../datawidget/combochoiceswithtreemodel.cc        |    2 +-
 .../datawidget/combochoiceswithtreemodel.h         |    2 +-
 glom/mode_data/datawidget/datawidget.cc            |    4 +-
 glom/mode_data/datawidget/datawidget.h             |    4 +-
 glom/mode_data/datawidget/dialog_choose_id.h       |    2 +-
 glom/mode_data/db_adddel/db_adddel.cc              |    2 +-
 glom/mode_data/flowtablewithfields.cc              |   16 +-
 glom/mode_design/dialog_design.cc                  |    2 +-
 glom/mode_design/fields/box_db_table_definition.cc |    8 +-
 glom/mode_design/fields/dialog_fielddefinition.cc  |    4 +-
 glom/mode_design/layout/combobox_fields.cc         |    4 +-
 glom/mode_design/layout/combobox_fields.h          |    4 +-
 glom/mode_design/layout/combobox_relationship.cc   |    2 +-
 glom/mode_design/layout/combobox_relationship.h    |    2 +-
 glom/mode_design/layout/dialog_choose_field.cc     |   12 +-
 glom/mode_design/layout/dialog_choose_field.h      |    6 +-
 .../layout/dialog_choose_relationship.cc           |    2 +-
 .../layout/dialog_choose_relationship.h            |    4 +-
 glom/mode_design/layout/dialog_layout.cc           |    2 +-
 glom/mode_design/layout/dialog_layout.h            |    2 +-
 .../layout/dialog_layout_calendar_related.cc       |    4 +-
 .../layout/dialog_layout_calendar_related.h        |    4 +-
 glom/mode_design/layout/dialog_layout_details.cc   |    2 +-
 glom/mode_design/layout/dialog_layout_details.h    |    2 +-
 glom/mode_design/layout/dialog_layout_export.cc    |    2 +-
 glom/mode_design/layout/dialog_layout_export.h     |    2 +-
 .../layout/dialog_layout_list_related.cc           |    2 +-
 .../layout/dialog_layout_list_related.h            |    2 +-
 .../layout/layout_item_dialogs/box_formatting.cc   |    8 +-
 .../print_layouts/window_print_layout_edit.cc      |    6 +-
 .../window_relationships_overview.cc               |    6 +-
 .../report_layout/dialog_layout_report.cc          |    2 +-
 glom/mode_design/users/dialog_groups_list.cc       |   10 +-
 glom/mode_design/users/dialog_groups_list.h        |    2 +-
 glom/mode_design/users/dialog_user.h               |    2 +-
 glom/print_layout/canvas_print_layout.cc           |    2 +-
 glom/print_layout/canvas_print_layout.h            |    2 +-
 glom/print_layout/print_layout_utils.cc            |    6 +-
 glom/print_layout/print_layout_utils.h             |    4 +-
 glom/python_embed/glom_python.cc                   |   20 ++--
 glom/python_embed/glom_python.h                    |    4 +-
 .../python/test_python_execute_func_with_record.cc |   10 +-
 ..._python_execute_func_with_record_field_types.cc |   10 +-
 tests/test_document_autosave.cc                    |   40 +++---
 tests/test_document_change.cc                      |   38 +++---
 tests/test_document_load.cc                        |   54 ++++----
 tests/test_document_load_and_change.cc             |   56 ++++----
 tests/test_document_load_and_save.cc               |   14 +-
 tests/test_document_load_image.cc                  |   12 +-
 tests/test_document_load_translations.cc           |   32 ++--
 tests/test_fake_connection.cc                      |   12 +-
 tests/test_selfhosting_new_empty.cc                |    4 +-
 .../test_selfhosting_new_empty_change_sysprefs.cc  |    6 +-
 tests/test_selfhosting_new_empty_then_users.cc     |   12 +-
 tests/test_selfhosting_new_from_example.cc         |    6 +-
 ...t_selfhosting_new_from_example_defaultvalues.cc |    6 +-
 tests/test_selfhosting_new_from_example_float.cc   |    6 +-
 .../test_selfhosting_new_from_example_operator.cc  |   12 +-
 ...est_selfhosting_new_from_example_strangepath.cc |    4 +-
 tests/test_selfhosting_new_then_alter_table.cc     |    4 +-
 tests/test_selfhosting_new_then_backup_restore.cc  |    8 +-
 tests/test_selfhosting_new_then_change_columns.cc  |    4 +-
 tests/test_selfhosting_new_then_choices.cc         |    4 +-
 tests/test_selfhosting_new_then_get_privs.cc       |    2 +-
 tests/test_selfhosting_new_then_image.cc           |    6 +-
 tests/test_selfhosting_new_then_lookup.cc          |   10 +-
 tests/test_selfhosting_new_then_report.cc          |    6 +-
 tests/test_selfhosting_new_then_report_summary.cc  |    6 +-
 tests/test_selfhosting_non_numeric_primary_keys.cc |    6 +-
 tests/test_selfhosting_sqlinjection.cc             |   26 ++--
 tests/test_selfhosting_utils.cc                    |   58 ++++----
 tests/test_selfhosting_utils.h                     |   18 +-
 tests/test_utils.cc                                |    4 +-
 tests/test_utils.h                                 |    2 +-
 tests/translations_po/test_document_export_po.cc   |    8 +-
 tests/translations_po/test_document_import_po.cc   |   14 +-
 128 files changed, 699 insertions(+), 681 deletions(-)
---
diff --git a/glom/appwindow.cc b/glom/appwindow.cc
index 33ece9d..a2c4520 100644
--- a/glom/appwindow.cc
+++ b/glom/appwindow.cc
@@ -208,8 +208,8 @@ bool AppWindow::init_with_document(const Glib::ustring& document_uri, bool resto
 
   if(document_uri.empty())
   {
-    auto pDocument = static_cast<Document*>(get_document());
-    if(pDocument && pDocument->get_connection_database().empty()) //If it is a new (default) document.
+    auto document = std::static_pointer_cast<Document>(get_document());
+    if(document && document->get_connection_database().empty()) //If it is a new (default) document.
     {
         return offer_new_or_existing();
     }
@@ -706,7 +706,7 @@ void AppWindow::open_browsed_document(const EpcServiceInfo* server, const Glib::
     //so we don't think that opening has failed because it has no URI,
     //and to stop us from allowing developer mode
     //(that would require changes to the original document).
-    auto document = dynamic_cast<Document*>(get_document());
+    auto document = std::dynamic_pointer_cast<Document>(get_document());
     if(document)
     {
       document->set_opened_from_browse();
@@ -769,29 +769,29 @@ void AppWindow::new_instance(const Glib::ustring& uri) //Override
 
 void AppWindow::init_create_document()
 {
-  if(!m_pDocument)
+  if(!m_document)
   {
-    auto document_glom = new Document();
+    auto document_glom = std::make_shared<Document>();
 
     //By default, we assume that the original is in the current locale.
     document_glom->set_translation_original_locale(AppWindow::get_current_locale());
 
-    m_pDocument = document_glom;
+    m_document = document_glom;
     //document_glom->set_parent_window(this); //So that it can show a BusyCursor when loading and saving.
 
 
     //Tell document about view:
-    m_pDocument->set_view(m_pFrame);
+    m_document->set_view(m_pFrame);
 
     //Tell view about document:
     //(This calls set_document() in the child views too.)
-    m_pFrame->set_document(static_cast<Document*>(m_pDocument));
+    m_pFrame->set_document(std::static_pointer_cast<Document>(m_document));
   }
 
   GlomBakery::AppWindow_WithDoc::init_create_document(); //Sets window title. Doesn't recreate doc.
 }
 
-bool AppWindow::check_document_hosting_mode_is_supported(Document* document)
+bool AppWindow::check_document_hosting_mode_is_supported(const std::shared_ptr<Document>& document)
 {
   //If it's an example then the document's hosting mode doesn't matter,
   //because the user will be asked to choose one when saving anyway.
@@ -854,25 +854,25 @@ bool AppWindow::on_document_load()
   //Link to the database described in the document.
   //Need to ask user for user/password:
   //m_pFrame->load_from_document();
-  auto pDocument = static_cast<Document*>(get_document());
-  if(!pDocument)
+  auto document = std::static_pointer_cast<Document>(get_document());
+  if(!document)
     return false;
 
   //Set this so that AppWindow::get_current_locale() works as expected:
-  AppWindow::set_original_locale(pDocument->get_translation_original_locale());
+  AppWindow::set_original_locale(document->get_translation_original_locale());
 
-  if(!pDocument->get_is_new() && !check_document_hosting_mode_is_supported(pDocument))
+  if(!document->get_is_new() && !check_document_hosting_mode_is_supported(document))
     return false;
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
   //Connect signals:
-  pDocument->signal_userlevel_changed().connect( sigc::mem_fun(*this, &AppWindow::on_userlevel_changed) );
+  document->signal_userlevel_changed().connect( sigc::mem_fun(*this, &AppWindow::on_userlevel_changed) );
 
   //Disable/Enable actions, depending on userlevel:
-  pDocument->emit_userlevel_changed();
+  document->emit_userlevel_changed();
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
-  if(pDocument->get_connection_database().empty()) //If it is a new (default) document.
+  if(document->get_connection_database().empty()) //If it is a new (default) document.
   {
     //offer_new_or_existing();
   }
@@ -881,19 +881,19 @@ bool AppWindow::on_document_load()
 #ifndef GLOM_ENABLE_CLIENT_ONLY
     //Prevent saving until we are sure that everything worked.
     //This also stops us from losing the example data as soon as we say the new file (created from the 
example) is not an example.
-    pDocument->set_allow_autosave(false);
+    document->set_allow_autosave(false);
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
     // Example files and backup files are not supported in client only mode because they
     // would need to be saved, but saving support is disabled.
 #ifndef GLOM_ENABLE_CLIENT_ONLY
-    const auto is_example = pDocument->get_is_example_file();
-    const auto is_backup = pDocument->get_is_backup_file();
+    const auto is_example = document->get_is_example_file();
+    const auto is_backup = document->get_is_backup_file();
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
     //Note that the URI will be empty if we are loading from data,
     //such as when loading a backup.
-    const auto original_uri = pDocument->get_file_uri();
+    const auto original_uri = document->get_file_uri();
 
     if(is_example || is_backup)
     {
@@ -905,7 +905,7 @@ bool AppWindow::on_document_load()
       // TODO: This is a weird hack. Find a nicer way. murrayc.
       m_example_uri = original_uri;
 
-      pDocument->set_file_uri(Glib::ustring()); //Prevent it from defaulting to the read-only examples 
directory when offering saveas.
+      document->set_file_uri(Glib::ustring()); //Prevent it from defaulting to the read-only examples 
directory when offering saveas.
       //m_ui_save_extra_* are used by offer_saveas() if it's not empty:
       m_ui_save_extra_showextras = true;
 
@@ -936,17 +936,17 @@ bool AppWindow::on_document_load()
       if(!get_operation_cancelled())
       {
         //Get the results from the extended save dialog:
-        pDocument->set_database_title_original(m_ui_save_extra_newdb_title);
-        pDocument->set_hosting_mode(m_ui_save_extra_newdb_hosting_mode);
+        document->set_database_title_original(m_ui_save_extra_newdb_title);
+        document->set_hosting_mode(m_ui_save_extra_newdb_hosting_mode);
         m_ui_save_extra_newdb_hosting_mode = Document::HostingMode::DEFAULT;
-        pDocument->set_is_example_file(false);
-        pDocument->set_is_backup_file(false);
+        document->set_is_example_file(false);
+        document->set_is_backup_file(false);
 
         // For self-hosting, we will choose a port later. For central
         // hosting, try several default ports. Don't use the values that
         // are set in the example file.
-        pDocument->set_connection_port(0);
-        pDocument->set_connection_try_other_ports(true);
+        document->set_connection_port(0);
+        document->set_connection_try_other_ports(true);
 
         // We have a valid uri, so we can set it to !new and modified here
       }
@@ -956,9 +956,9 @@ bool AppWindow::on_document_load()
 
       if(get_operation_cancelled())
       {
-        pDocument->set_modified(false);
-        pDocument->set_is_new(true);
-        pDocument->set_allow_autosave(true); //Turn this back on.
+        document->set_modified(false);
+        document->set_is_new(true);
+        document->set_allow_autosave(true); //Turn this back on.
         std::cout << "debug: user cancelled creating database" << std::endl;
         return false;
       }
@@ -975,7 +975,7 @@ bool AppWindow::on_document_load()
 #ifndef GLOM_ENABLE_CLIENT_ONLY
     //Warn about read-only files, because users will otherwise wonder why they can't use Developer mode:
     Document::userLevelReason reason = Document::userLevelReason::UNKNOWN;
-    const auto userlevel = pDocument->get_userlevel(reason);
+    const auto userlevel = document->get_userlevel(reason);
     if( (userlevel == AppState::userlevels::OPERATOR) && (reason == 
Document::userLevelReason::FILE_READ_ONLY) )
     {
       Gtk::MessageDialog dialog(UiUtils::bold_message(_("Opening Read-Only File.")), true,  
Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE);
@@ -1020,12 +1020,12 @@ bool AppWindow::on_document_load()
         //we already asked for them when getting the document over the network:
 
         //Use the default username/password if opening as non network-shared:
-        if(!(pDocument->get_network_shared()))
+        if(!(document->get_network_shared()))
         {
           // If the document is centrally hosted, don't pretend to know the
           // username or password, because we don't. The user will enter
           // the login credentials in a dialog.
-          const auto hosting_mode = pDocument->get_hosting_mode();
+          const auto hosting_mode = document->get_hosting_mode();
           if(hosting_mode != Document::HostingMode::POSTGRES_CENTRAL)
             m_temp_username = Privs::get_default_developer_user_name(m_temp_password, hosting_mode);
         }
@@ -1087,20 +1087,20 @@ bool AppWindow::on_document_load()
         {
           //Make sure that the changes (mark as non example, and save the new database name) are really 
saved:
           //Change the user level temporarily so that save_changes() actually saves:
-          const auto user_level = pDocument->get_userlevel();
-          pDocument->set_userlevel(AppState::userlevels::DEVELOPER);
-          pDocument->set_modified(true);
-          pDocument->set_allow_autosave(true); //Turn this back on.
-          pDocument->set_userlevel(user_level); //Change it back.
+          const auto user_level = document->get_userlevel();
+          document->set_userlevel(AppState::userlevels::DEVELOPER);
+          document->set_modified(true);
+          document->set_allow_autosave(true); //Turn this back on.
+          document->set_userlevel(user_level); //Change it back.
         }
       }
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
       //Switch to operator mode when opening new documents:
-      pDocument->set_userlevel(AppState::userlevels::OPERATOR);
+      document->set_userlevel(AppState::userlevels::OPERATOR);
 
       //Make sure that it's saved in history, even if it was saved from an example file:
-      document_history_add(pDocument->get_file_uri());
+      document_history_add(document->get_file_uri());
 
       //Open default table, or show list of tables instead:
       m_pFrame->do_menu_Navigate_Table(true /* open the default if there is one */);
@@ -1113,7 +1113,7 @@ bool AppWindow::on_document_load()
   update_network_shared_ui();
 
   //Run any startup script:
-  const auto script = pDocument->get_startup_script();
+  const auto script = document->get_startup_script();
   if(!script.empty())
   {
     Glib::ustring error_message; //TODO: Check this and tell the user.
@@ -1122,7 +1122,7 @@ bool AppWindow::on_document_load()
     AppPythonUICallbacks callbacks;
     glom_execute_python_function_implementation(script,
       type_map_fields(), //only used when there is a current table and record.
-      pDocument,
+      document,
       Glib::ustring() /* table_name */,
       std::shared_ptr<Field>(), Gnome::Gda::Value(), // primary key - only used when there is a current 
table and record.
       sharedconnection->get_gda_connection(),
@@ -1136,7 +1136,7 @@ bool AppWindow::on_document_load()
   }
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
-  pDocument->set_allow_autosave(true);
+  document->set_allow_autosave(true);
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
   return true; //Loading of the document into the application succeeded.
@@ -1190,7 +1190,7 @@ void AppWindow::statusbar_clear()
 
 void AppWindow::update_network_shared_ui()
 {
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return;
 
@@ -1332,7 +1332,7 @@ bool AppWindow::offer_new_or_existing()
       }
 
       //Check that a document was opened:
-      auto document = dynamic_cast<Document*>(get_document());
+      auto document = std::dynamic_pointer_cast<Document>(get_document());
       if(!document)
       {
         std::cerr << G_STRFUNC << ": document was NULL." << std::endl;
@@ -1376,7 +1376,7 @@ void AppWindow::existing_or_new_new()
   offer_saveas();
 
   //Check that the document was given a location:
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
   {
     std::cerr << G_STRFUNC << ": document is null." << std::endl;
@@ -1497,8 +1497,8 @@ bool AppWindow::recreate_database_from_example(bool& user_cancelled)
   ShowProgressMessage progress_message(_("Creating Glom database from example file."));
 
   //Create a database, based on the information in the current document:
-  const auto pDocument = static_cast<Document*>(get_document());
-  if(!pDocument)
+  const auto document = std::static_pointer_cast<Document>(get_document());
+  if(!document)
     return false;
 
   auto connection_pool = ConnectionPool::get_instance();
@@ -1506,7 +1506,7 @@ bool AppWindow::recreate_database_from_example(bool& user_cancelled)
     return false; //Impossible anyway.
 
   //Check whether the database exists already.
-  const auto db_name = pDocument->get_connection_database();
+  const auto db_name = document->get_connection_database();
   if(db_name.empty())
     return false;
 
@@ -1540,7 +1540,7 @@ bool AppWindow::recreate_database_from_example(bool& user_cancelled)
 
   //Create the database: (This will show a connection dialog)
   connection_pool->set_database( Glib::ustring() );
-  const auto db_created = m_pFrame->create_database(db_name, pDocument->get_database_title_original());
+  const auto db_created = m_pFrame->create_database(db_name, document->get_database_title_original());
 
   if(!db_created)
   {
@@ -1566,26 +1566,26 @@ bool AppWindow::recreate_database_from_example(bool& user_cancelled)
 
   //Create the developer group, and make this user a member of it:
   pulse_progress_message();
-  bool test = DbUtils::add_standard_groups(pDocument);
+  bool test = DbUtils::add_standard_groups(document);
   if(!test)
     return false;
 
   //Add any extra groups from the example file:
   pulse_progress_message();
-  test = DbUtils::add_groups_from_document(pDocument);
+  test = DbUtils::add_groups_from_document(document);
   if(!test)
     return false;
 
   //Create each table:
-  const auto tables = pDocument->get_tables();
+  const auto tables = document->get_tables();
   for(const auto& table_info : tables)
   {
     //Create SQL to describe all fields in this table:
     Glib::ustring sql_fields;
-    Document::type_vec_fields fields = pDocument->get_table_fields(table_info->get_name());
+    Document::type_vec_fields fields = document->get_table_fields(table_info->get_name());
 
     pulse_progress_message();
-    const auto table_creation_succeeded = DbUtils::create_table(pDocument->get_hosting_mode(), table_info, 
fields);
+    const auto table_creation_succeeded = DbUtils::create_table(document->get_hosting_mode(), table_info, 
fields);
     pulse_progress_message();
     if(!table_creation_succeeded)
     {
@@ -1595,11 +1595,11 @@ bool AppWindow::recreate_database_from_example(bool& user_cancelled)
   }
 
   pulse_progress_message();
-  DbUtils::add_standard_tables(pDocument); //Add internal, hidden, tables.
+  DbUtils::add_standard_tables(document); //Add internal, hidden, tables.
 
   //Set table priviliges, using the groups we just added:
   pulse_progress_message();
-  test = DbUtils::set_table_privileges_groups_from_document(pDocument);
+  test = DbUtils::set_table_privileges_groups_from_document(document);
   if(!test)
     return false;
 
@@ -1610,7 +1610,7 @@ bool AppWindow::recreate_database_from_example(bool& user_cancelled)
 
     //try
     //{
-      const auto table_insert_succeeded = DbUtils::insert_example_data(pDocument, table_info->get_name());
+      const auto table_insert_succeeded = DbUtils::insert_example_data(document, table_info->get_name());
 
       if(!table_insert_succeeded)
       {
@@ -1641,8 +1641,8 @@ bool AppWindow::recreate_database_from_backup(const std::string& backup_data_fil
   ShowProgressMessage progress_message(_("Creating Glom database from backup file."));
 
   //Create a database, based on the information in the current document:
-  auto pDocument = static_cast<Document*>(get_document());
-  if(!pDocument)
+  auto document = std::static_pointer_cast<Document>(get_document());
+  if(!document)
     return false;
 
   auto connection_pool = ConnectionPool::get_instance();
@@ -1650,7 +1650,7 @@ bool AppWindow::recreate_database_from_backup(const std::string& backup_data_fil
     return false; //Impossible anyway.
 
   //Check whether the database exists already.
-  const auto db_name = pDocument->get_connection_database();
+  const auto db_name = document->get_connection_database();
   if(db_name.empty())
     return false;
 
@@ -1711,7 +1711,7 @@ bool AppWindow::recreate_database_from_backup(const std::string& backup_data_fil
 
   //Create the developer group, and make this user a member of it:
   pulse_progress_message();
-  bool test = DbUtils::add_standard_groups(pDocument);
+  bool test = DbUtils::add_standard_groups(document);
   if(!test)
   {
     std::cerr << G_STRFUNC << ": DbUtils::add_standard_groups(): failed." << std::endl;
@@ -1724,7 +1724,7 @@ bool AppWindow::recreate_database_from_backup(const std::string& backup_data_fil
   //The backup file refers to these,
   //so the restore will fail if they are not present.
   pulse_progress_message();
-  test = DbUtils::add_groups_from_document(pDocument);
+  test = DbUtils::add_groups_from_document(document);
   if(!test)
     return false;
 
@@ -1744,7 +1744,7 @@ bool AppWindow::recreate_database_from_backup(const std::string& backup_data_fil
 
 AppState::userlevels AppWindow::get_userlevel() const
 {
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
   if(document)
   {
     return document->get_userlevel();
@@ -1807,7 +1807,7 @@ void AppWindow::fill_menu_tables()
     menu->remove(0);
   }
 
-  const auto document = dynamic_cast<Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
   {
     std::cerr << G_STRFUNC << ": document is null." << std::endl;
@@ -1861,7 +1861,7 @@ void AppWindow::fill_menu_reports(const Glib::ustring& table_name)
 
   m_refNavReportsActionGroup = Gio::SimpleActionGroup::create();
 
-  const auto document = dynamic_cast<Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
   {
     std::cerr << G_STRFUNC << ": document is null." << std::endl;
@@ -1941,7 +1941,7 @@ void AppWindow::fill_menu_print_layouts(const Glib::ustring& table_name)
 
   m_refNavPrintLayoutsActionGroup = Gio::SimpleActionGroup::create();
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
   {
     std::cerr << G_STRFUNC << ": document is null." << std::endl;
@@ -1989,7 +1989,7 @@ void AppWindow::on_menu_file_save_as_example()
 
   //Show the save dialog:
   bool bTest = false;
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document) {
     std::cerr << G_STRFUNC << ": document was null." << std::endl;
   } else {
@@ -2101,7 +2101,7 @@ Glib::ustring AppWindow::ui_file_select_save(const Glib::ustring& old_file_uri)
 
 
     //Start with something suitable:
-    auto document = dynamic_cast<Document*>(get_document());
+    auto document = std::dynamic_pointer_cast<Document>(get_document());
     g_assert(document);
     const auto filename = document->get_name(); //Get the filename without the path and extension.
 
@@ -2271,8 +2271,8 @@ Glib::ustring AppWindow::ui_file_select_save(const Glib::ustring& old_file_uri)
 /*
 void AppWindow::stop_self_hosting_of_document_database()
 {
-  auto pDocument = static_cast<Document*>(get_document());
-  if(pDocument)
+  auto document = std::static_pointer_cast<Document>(get_document());
+  if(document)
   {
     auto connection_pool = ConnectionPool::get_instance();
     if(!connection_pool)
@@ -2318,7 +2318,7 @@ void AppWindow::on_menu_developer_translations()
     {
       m_pFrame->add_view(m_window_translations);
       m_window_translations->set_transient_for(*this);
-      m_window_translations->set_document(static_cast<Document*>(m_pDocument));
+      m_window_translations->set_document(std::static_pointer_cast<Document>(m_document));
       m_window_translations->load_from_document();
       m_window_translations->show();
 
@@ -2337,7 +2337,7 @@ void AppWindow::on_menu_developer_active_platform(const Glib::ustring& parameter
   //The state is not changed automatically:
   m_action_menu_developer_active_platform->change_state(parameter);
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document)
    document->set_active_layout_platform(parameter);
 
@@ -2346,7 +2346,7 @@ void AppWindow::on_menu_developer_active_platform(const Glib::ustring& parameter
 
 void AppWindow::on_menu_developer_export_backup()
 {
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return;
 
@@ -2424,7 +2424,7 @@ void AppWindow::do_print_layout(const Glib::ustring& print_layout_name, bool pre
 
 bool AppWindow::do_restore_backup(const Glib::ustring& backup_uri)
 {
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return false;
     
@@ -2500,9 +2500,9 @@ void AppWindow::do_menu_developer_relationships(Gtk::Window& parent, const Glib:
   m_pFrame->do_menu_developer_relationships(parent, table_name);
 }
 
-Document* AppWindow::on_connection_pool_get_document()
+std::shared_ptr<Document> AppWindow::on_connection_pool_get_document()
 {
-  return dynamic_cast<Document*>(get_document());
+  return std::dynamic_pointer_cast<Document>(get_document());
 }
 #endif //GLOM_ENABLE_CLIENT_ONLY
 
@@ -2511,7 +2511,7 @@ void AppWindow::update_window_title()
 {
   //Set application's main window title:
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return;
 
@@ -2800,7 +2800,7 @@ Glib::ustring AppWindow::ui_file_select_open(const Glib::ustring& starting_folde
 
 void AppWindow::ui_show_modification_status()
 {
-  const auto modified = m_pDocument->get_modified();
+  const auto modified = m_document->get_modified();
 
   //Enable Save and SaveAs menu items:
   if(m_action_save)
@@ -2814,11 +2814,11 @@ AppWindow::enumSaveChanges AppWindow::ui_offer_to_save_changes()
 {
   GlomBakery::AppWindow_WithDoc::enumSaveChanges result = 
GlomBakery::AppWindow_WithDoc::enumSaveChanges::Cancel;
 
-  if(!m_pDocument)
+  if(!m_document)
     return result;
 
   GlomBakery::Dialog_OfferSave* pDialogQuestion 
-    = new GlomBakery::Dialog_OfferSave( m_pDocument->get_file_uri() );
+    = new GlomBakery::Dialog_OfferSave( m_document->get_file_uri() );
 
   Gtk::Window* pWindow = this;
   if(pWindow)
diff --git a/glom/appwindow.h b/glom/appwindow.h
index 68f83a5..a9f43c1 100644
--- a/glom/appwindow.h
+++ b/glom/appwindow.h
@@ -237,7 +237,7 @@ private:
   /** Check that the file's hosting mode is supported by this build and
    * tell the user if necessary.
    */
-  bool check_document_hosting_mode_is_supported(Document* document);
+  bool check_document_hosting_mode_is_supported(const std::shared_ptr<Document>& document);
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
   void existing_or_new_new();
@@ -256,7 +256,7 @@ private:
 
   void on_userlevel_changed(AppState::userlevels userlevel);
 
-  Document* on_connection_pool_get_document();
+  std::shared_ptr<Document> on_connection_pool_get_document();
 
   bool recreate_database_from_example(bool& user_cancelled); //return indicates success.
   bool recreate_database_from_backup(const std::string& backup_data_file_path, bool& user_cancelled); 
//return indicates success.
diff --git a/glom/bakery/appwindow_withdoc.cc b/glom/bakery/appwindow_withdoc.cc
index 2d6d6d8..37dff36 100644
--- a/glom/bakery/appwindow_withdoc.cc
+++ b/glom/bakery/appwindow_withdoc.cc
@@ -32,7 +32,7 @@ AppWindow_WithDoc::type_list_strings AppWindow_WithDoc::m_mime_types;
 
 AppWindow_WithDoc::AppWindow_WithDoc(const Glib::ustring& appname)
 : AppWindow(appname),
-  m_pDocument(nullptr),
+  m_document(nullptr),
   m_bCloseAfterSave(false)
 {
 }
@@ -40,8 +40,12 @@ AppWindow_WithDoc::AppWindow_WithDoc(const Glib::ustring& appname)
 AppWindow_WithDoc::~AppWindow_WithDoc()
 {
   //Delete the document:
-  delete m_pDocument; //This will cause Document::signal_forget to be emitted, so the Views will then null 
their pointers as well. A smartpointer might be a better way to do this.
-  m_pDocument = nullptr;
+  if (m_document) {
+    //TODO: Should the views have weak ptr?
+    //This will cause Document::signal_forget to be emitted, so the Views will then null their
+    //pointers as well.
+    m_document->emit_forget();
+  }
 }
 
 //static
@@ -53,7 +57,7 @@ void AppWindow_WithDoc::add_mime_type(const Glib::ustring& mime_type)
 
 void AppWindow_WithDoc::on_menu_file_close()
 {
-  if(m_pDocument->get_modified())
+  if(m_document->get_modified())
   {
     //Offer to save changes:
     m_bCloseAfterSave = true; //Checked in FileChooser signal handler.
@@ -73,7 +77,7 @@ void AppWindow_WithDoc::on_menu_file_close()
 bool AppWindow_WithDoc::open_document_from_data(const guchar* data, std::size_t length)
 {
   int failure_code = 0;
-  const auto bTest = m_pDocument->load_from_data(data, length, failure_code);
+  const auto bTest = m_document->load_from_data(data, length, failure_code);
 
   bool bOpenFailed = false;
   if(!bTest) //if open failed.
@@ -116,9 +120,9 @@ bool AppWindow_WithDoc::open_document(const Glib::ustring& file_uri)
   auto pApp = this; //Replace the default new document in this instance.
 
   //Open it.
-  pApp->m_pDocument->set_file_uri(file_uri);
+  pApp->m_document->set_file_uri(file_uri);
   int failure_code = 0;
-  const auto bTest = pApp->m_pDocument->load(failure_code);
+  const auto bTest = pApp->m_document->load(failure_code);
 
   bool bOpenFailed = false;
   bool bShowError = false;
@@ -141,7 +145,7 @@ bool AppWindow_WithDoc::open_document(const Glib::ustring& file_uri)
       //Update document history list:
       //(Getting the file URI again, in case it has changed while being opened,
       //for instance if it was a template file that was saved as a real file.)
-      if(pApp->m_pDocument)
+      if(pApp->m_document)
         document_history_add(file_uri);
     }
   }
@@ -156,8 +160,15 @@ bool AppWindow_WithDoc::open_document(const Glib::ustring& file_uri)
       document_history_remove(file_uri);
 
     //re-initialize document.
-    delete pApp->m_pDocument;
-    pApp->m_pDocument = nullptr;
+    if(m_document)
+    {
+      //TODO: Should the views have weak ptr?
+      //This will cause Document::signal_forget to be emitted, so the Views will then null their
+      //pointers as well.
+      m_document->emit_forget();
+    }
+
+    pApp->m_document.reset();
     pApp->init_create_document();
 
     return false; //failed.
@@ -215,16 +226,16 @@ void AppWindow_WithDoc::on_menu_file_saveas()
   ui_bring_to_front();
 
   //Show the save dialog:
-  const auto file_uriOld = m_pDocument->get_file_uri();
+  const auto file_uriOld = m_document->get_file_uri();
 
   auto file_uri = ui_file_select_save(file_uriOld); //Also asks for overwrite confirmation.
   if(!file_uri.empty())
   {
     //Enforce the file extension:
-    file_uri = m_pDocument->get_file_uri_with_extension(file_uri);
+    file_uri = m_document->get_file_uri_with_extension(file_uri);
 
-    m_pDocument->set_file_uri(file_uri, true); //true = enforce file extension
-    const auto bTest = m_pDocument->save();
+    m_document->set_file_uri(file_uri, true); //true = enforce file extension
+    const auto bTest = m_document->save();
 
     if(!bTest)
     {
@@ -253,12 +264,12 @@ void AppWindow_WithDoc::on_menu_file_saveas()
 
 void AppWindow_WithDoc::on_menu_file_save()
 {
-  if(m_pDocument)
+  if(m_document)
   {
     //If there is already a filepath, then save to that location:
-    if(!(m_pDocument->get_file_uri().empty()))
+    if(!(m_document->get_file_uri().empty()))
     {
-      auto bTest = m_pDocument->save();
+      auto bTest = m_document->save();
 
       if(bTest)
       {
@@ -307,33 +318,33 @@ void AppWindow_WithDoc::init_create_document()
 {
   //Overrides should call this base method at the end.
 
-  if(!m_pDocument)
+  if(!m_document)
   {
-    m_pDocument = new Document();
+    m_document = std::make_shared<Document>();
   }
 
-  m_pDocument->set_is_new(true); //Can't be modified if it's just been created.
+  m_document->set_is_new(true); //Can't be modified if it's just been created.
 
-  m_pDocument->signal_modified().connect(sigc::mem_fun(*this, &AppWindow_WithDoc::on_document_modified));
+  m_document->signal_modified().connect(sigc::mem_fun(*this, &AppWindow_WithDoc::on_document_modified));
 
   update_window_title();
 }
 
-Document* AppWindow_WithDoc::get_document()
+std::shared_ptr<Document> AppWindow_WithDoc::get_document()
 {
-  return m_pDocument;
+  return m_document;
 }
 
-const Document* AppWindow_WithDoc::get_document() const
+std::shared_ptr<const Document> AppWindow_WithDoc::get_document() const
 {
-  return m_pDocument;
+  return m_document;
 }
 
 void AppWindow_WithDoc::offer_to_save_changes()
 {
-  if(m_pDocument)
+  if(m_document)
   {
-    if(m_pDocument->get_modified())
+    if(m_document->get_modified())
     {
       set_operation_cancelled(false); //Initialize it again. It might be set later in this method by 
cancel_close_or_exit().
 
@@ -384,9 +395,9 @@ void AppWindow_WithDoc::cancel_close_or_exit()
 bool AppWindow_WithDoc::on_document_load()
 {
   //Show document contents:
-  if(m_pDocument)
+  if(m_document)
   {
-    auto pView = m_pDocument->get_view();
+    auto pView = m_document->get_view();
     if(pView)
       pView->load_from_document();
 
@@ -424,7 +435,7 @@ void AppWindow_WithDoc::on_document_modified(bool /* modified */)
 
 void AppWindow_WithDoc::set_document_modified(bool bModified /* = true */)
 {
-  m_pDocument->set_modified(bModified);
+  m_document->set_modified(bModified);
 
   //Enable/Disable Save menu item and toolbar item:
   ui_show_modification_status();
@@ -432,21 +443,21 @@ void AppWindow_WithDoc::set_document_modified(bool bModified /* = true */)
 
 void AppWindow_WithDoc::on_menu_edit_copy()
 {
-  auto pView = m_pDocument->get_view();
+  auto pView = m_document->get_view();
   if(pView)
     pView->clipboard_copy();
 }
 
 void AppWindow_WithDoc::on_menu_edit_paste()
 {
-  auto pView = m_pDocument->get_view();
+  auto pView = m_document->get_view();
   if(pView)
     pView->clipboard_paste();
 }
 
 void AppWindow_WithDoc::on_menu_edit_clear()
 {
-  auto pView = m_pDocument->get_view();
+  auto pView = m_document->get_view();
   if(pView)
     pView->clipboard_clear();
 }
@@ -456,7 +467,7 @@ void AppWindow_WithDoc::after_successful_save()
   set_document_modified(false); //enables/disables menu and toolbar widgets.
 
   //Update document history list:
-  document_history_add(m_pDocument->get_file_uri());
+  document_history_add(m_document->get_file_uri());
 }
 
 void AppWindow_WithDoc::document_history_add(const Glib::ustring& /* file_uri */)
diff --git a/glom/bakery/appwindow_withdoc.h b/glom/bakery/appwindow_withdoc.h
index 70de0e4..5f9b495 100644
--- a/glom/bakery/appwindow_withdoc.h
+++ b/glom/bakery/appwindow_withdoc.h
@@ -81,10 +81,10 @@ protected:
   static void add_mime_type(const Glib::ustring& mime_type);
 
   ///static_cast<> or dynamic_cast<> this pointer to the correct type.
-  virtual Document* get_document();
+  virtual std::shared_ptr<Document> get_document();
 
   ///static_cast<> or dynamic_cast<> this pointer to the correct type.
-  virtual const Document* get_document() const ;
+  virtual std::shared_ptr<const Document> get_document() const ;
 
   virtual void set_document_modified(bool bModified = true);
 
@@ -165,7 +165,7 @@ protected:
   virtual enumSaveChanges ui_offer_to_save_changes() = 0;
 
   //Document:
-  Document* m_pDocument; //An instance of a derived type.
+  std::shared_ptr<Document> m_document; //An instance of a derived type.
   bool m_bCloseAfterSave;
 
   //Mime types which this application can load and save:
diff --git a/glom/base_db.cc b/glom/base_db.cc
index e61329d..c8a5a77 100644
--- a/glom/base_db.cc
+++ b/glom/base_db.cc
@@ -84,7 +84,7 @@ auto find_if_layout_item_is_equal(T_Container& container, const typename T_Conta
 
 Base_DB::Base_DB()
 {
-  //m_pDocument = nullptr;
+  //m_document = nullptr;
 }
 
 bool Base_DB::init_db_details()
@@ -153,7 +153,7 @@ void Base_DB::load_from_document()
 
 AppState::userlevels Base_DB::get_userlevel() const
 {
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
   if(document)
   {
     return document->get_userlevel();
@@ -181,12 +181,10 @@ void Base_DB::on_userlevel_changed(AppState::userlevels /* userlevel */)
 
 
 
-void Base_DB::set_document(Document* pDocument)
+void Base_DB::set_document(const std::shared_ptr<Document>& document)
 {
-  View_Composite_Glom::set_document(pDocument);
+  View_Composite_Glom::set_document(document);
 
-  //Connect to a signal that is only on the derived document class:
-  auto document = get_document();
   if(document)
   {
     document->signal_userlevel_changed().connect( sigc::mem_fun(*this, &Base_DB::on_userlevel_changed) );
@@ -579,7 +577,7 @@ std::shared_ptr<Field> Base_DB::get_field_primary_key_for_table(const Glib::ustr
 
 void Base_DB::get_table_fields_to_show_for_sequence_add_group(const Glib::ustring& table_name, const 
Privileges& table_privs, const type_vec_fields& all_db_fields, const std::shared_ptr<LayoutGroup>& group, 
Base_DB::type_vecConstLayoutFields& vecFields) const
 {
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
 
   //g_warning("Box_Data::get_table_fields_to_show_for_sequence_add_group(): table_name=%s, 
all_db_fields.size()=%d, group->name=%s", table_name.c_str(), all_db_fields.size(), 
group->get_name().c_str());
 
@@ -656,7 +654,7 @@ void Base_DB::get_table_fields_to_show_for_sequence_add_group(const Glib::ustrin
 
 Base_DB::type_vecConstLayoutFields Base_DB::get_table_fields_to_show_for_sequence(const Glib::ustring& 
table_name, const Document::type_list_layout_groups& mapGroupSequence) const
 {
-  const auto pDoc = dynamic_cast<const Document*>(get_document());
+  const auto pDoc = std::dynamic_pointer_cast<const Document>(get_document());
 
   //Get field definitions from the database, with corrections from the document:
   type_vec_fields all_fields = DbUtils::get_fields_for_table(pDoc, table_name);
@@ -932,7 +930,7 @@ bool Base_DB::set_field_value_in_database(const LayoutFieldInRecord& layoutfield
   auto document = get_document();
   g_assert(document);
 
-  const auto field_in_record = layoutfield_in_record.get_fieldinrecord(*document);
+  const auto field_in_record = layoutfield_in_record.get_fieldinrecord(document);
 
   //row is invalid, and ignored, for Box_Data_Details.
   if(!(field_in_record.m_field))
@@ -1129,7 +1127,7 @@ Base_DB::type_list_const_field_items Base_DB::get_calculated_fields(const Glib::
 
   type_list_const_field_items result;
 
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
   if(document)
   {
     //Look at each field in the table, and get lists of what fields trigger their calculations,
@@ -1502,7 +1500,7 @@ bool Base_DB::disable_user(const Glib::ustring& user)
   return true;
 }
 
-Glib::ustring Base_DB::get_active_layout_platform(Document* document)
+Glib::ustring Base_DB::get_active_layout_platform(const std::shared_ptr<Document>& document)
 {
   Glib::ustring result;
   if(document)
diff --git a/glom/base_db.h b/glom/base_db.h
index 4ad9ac3..14da782 100644
--- a/glom/base_db.h
+++ b/glom/base_db.h
@@ -65,7 +65,7 @@ public:
 
   static std::shared_ptr<SharedConnection> connect_to_server(Gtk::Window* parent_window = 0);
 
-  void set_document(Document* pDocument) override; //View override
+  void set_document(const std::shared_ptr<Document>& document) override; //View override
   void load_from_document() override; //View override
 
   std::shared_ptr<Field> change_column(const Glib::ustring& table_name, const std::shared_ptr<const Field>& 
field_old, const std::shared_ptr<const Field>& field, Gtk::Window* parent_window) const;
@@ -79,7 +79,7 @@ public:
 
   //TODO: This is not a very good place for this function.
   /// Get the active layout platform for the document, or get a suitable default.
-  static Glib::ustring get_active_layout_platform(Document* document);
+  static Glib::ustring get_active_layout_platform(const std::shared_ptr<Document>& document);
 
   typedef std::vector< std::shared_ptr<LayoutItem_Field> > type_vecLayoutFields;
   typedef std::vector< std::shared_ptr<const LayoutItem_Field> > type_vecConstLayoutFields;
@@ -138,7 +138,7 @@ protected:
     {
     }
 
-    FieldInRecord(const std::shared_ptr<const LayoutItem_Field>& layout_item, const Glib::ustring& 
parent_table_name, const std::shared_ptr<const Field>& parent_key, const Gnome::Gda::Value& key_value, const 
Document& document)
+    FieldInRecord(const std::shared_ptr<const LayoutItem_Field>& layout_item, const Glib::ustring& 
parent_table_name, const std::shared_ptr<const Field>& parent_key, const Gnome::Gda::Value& key_value, const 
std::shared_ptr<const Document>& document)
     : m_field(layout_item->get_full_field_details()),
       m_key_value(key_value)
     {
@@ -157,13 +157,13 @@ protected:
             if(related_rel)
             {
               //Actually a foreign key in a doubly-related table:
-              m_key = document.get_field(m_table_name, related_rel->get_to_field());
+              m_key = document->get_field(m_table_name, related_rel->get_to_field());
             }
           }
           else
           {
             //Actually a foreign key:
-            m_key = document.get_field(m_table_name, rel->get_to_field());
+            m_key = document->get_field(m_table_name, rel->get_to_field());
           }
         }
       }
@@ -203,7 +203,7 @@ protected:
     LayoutFieldInRecord(LayoutFieldInRecord&& src) = delete;
     LayoutFieldInRecord& operator=(LayoutFieldInRecord&& src) = delete;
 
-    FieldInRecord get_fieldinrecord(const Document& document) const
+    FieldInRecord get_fieldinrecord(const std::shared_ptr<const Document>& document) const
     {
       return FieldInRecord(m_field, m_table_name, m_key, m_key_value, document);
     }
diff --git a/glom/base_db_table_data.cc b/glom/base_db_table_data.cc
index 3b9eb58..73f0a95 100644
--- a/glom/base_db_table_data.cc
+++ b/glom/base_db_table_data.cc
@@ -451,7 +451,7 @@ Base_DB_Table_Data::type_vecConstLayoutFields Base_DB_Table_Data::get_related_fi
 {
   type_vecConstLayoutFields result;
 
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
   if(document)
   {
     const auto field_name = field->get_name(); //At the moment, relationships can not be based on related 
fields on the from side.
diff --git a/glom/box_withbuttons.cc b/glom/box_withbuttons.cc
index 122ea82..47fe9ac 100644
--- a/glom/box_withbuttons.cc
+++ b/glom/box_withbuttons.cc
@@ -35,7 +35,7 @@ Box_WithButtons::Box_WithButtons()
   m_Box_Buttons(Gtk::ORIENTATION_HORIZONTAL, Utils::to_utype(UiUtils::DefaultSpacings::SMALL)),
   m_Button_Cancel(_("_Cancel"))
 {
-  //m_pDocument = nullptr;
+  //m_document = nullptr;
 
   //set_border_width(Utils::to_utype(UiUtils::DefaultSpacings::SMALL));
   set_spacing(Utils::to_utype(UiUtils::DefaultSpacings::SMALL));
@@ -49,7 +49,7 @@ Box_WithButtons::Box_WithButtons(BaseObjectType* cobject, const Glib::RefPtr<Gtk
   m_Box_Buttons(Gtk::ORIENTATION_HORIZONTAL, Utils::to_utype(UiUtils::DefaultSpacings::SMALL)),
   m_Button_Cancel(_("_Cancel"))
 {
-  //m_pDocument = nullptr;
+  //m_document = nullptr;
 
   //set_border_width(Utils::to_utype(UiUtils::DefaultSpacings::SMALL));
   set_spacing(Utils::to_utype(UiUtils::DefaultSpacings::SMALL));
diff --git a/glom/dialog_connection.cc b/glom/dialog_connection.cc
index 5be5289..e825484 100644
--- a/glom/dialog_connection.cc
+++ b/glom/dialog_connection.cc
@@ -95,7 +95,7 @@ std::shared_ptr<SharedConnection> Dialog_Connection::connect_to_server_with_conn
   //Remember the port, 
   //to make opening faster next time,
   //and so we can tell connecting clients (using browse network) what port to use:
-  auto unconst = const_cast<Document*>(document);
+  auto unconst = std::const_pointer_cast<Document>(document);
 
   if(document->get_hosting_mode() == Document::HostingMode::POSTGRES_CENTRAL)
   {
diff --git a/glom/filechooser_export.cc b/glom/filechooser_export.cc
index a257751..958d467 100644
--- a/glom/filechooser_export.cc
+++ b/glom/filechooser_export.cc
@@ -71,7 +71,7 @@ FileChooser_Export::~FileChooser_Export()
 #endif //GLOM_ENABLE_CLIENT_ONLY
 }
 
-void FileChooser_Export::set_export_layout(const Document::type_list_layout_groups& layout_groups, const 
Glib::ustring& table_name, Document* document)
+void FileChooser_Export::set_export_layout(const Document::type_list_layout_groups& layout_groups, const 
Glib::ustring& table_name, const std::shared_ptr<Document>& document)
 {
   m_layout_groups = layout_groups;
   m_table_name = table_name;
diff --git a/glom/filechooser_export.h b/glom/filechooser_export.h
index 04cfc86..51719d6 100644
--- a/glom/filechooser_export.h
+++ b/glom/filechooser_export.h
@@ -36,7 +36,7 @@ public:
   FileChooser_Export();
   virtual ~FileChooser_Export();
 
-  void set_export_layout(const Document::type_list_layout_groups& layout_groups, const Glib::ustring& 
table_name, Document* document);
+  void set_export_layout(const Document::type_list_layout_groups& layout_groups, const Glib::ustring& 
table_name, const std::shared_ptr<Document>& document);
 
   void get_layout_groups(Document::type_list_layout_groups& layout_groups) const;
 
@@ -58,7 +58,7 @@ private:
   Glib::ustring m_table_name;
 
   Document::type_list_layout_groups m_layout_groups;
-  Document* m_document;
+  std::shared_ptr<Document> m_document;
 };
 
 } //namespace Glom
diff --git a/glom/frame_glom.cc b/glom/frame_glom.cc
index 000cdb8..245909e 100644
--- a/glom/frame_glom.cc
+++ b/glom/frame_glom.cc
@@ -455,7 +455,7 @@ void Frame_Glom::show_no_table()
 #ifndef GLOM_ENABLE_CLIENT_ONLY
 bool Frame_Glom::attempt_change_usermode_to_developer()
 {
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return false;
 
@@ -521,7 +521,7 @@ bool Frame_Glom::attempt_change_usermode_to_developer()
 
 bool Frame_Glom::attempt_change_usermode_to_operator()
 {
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return false;
     
@@ -800,7 +800,7 @@ bool Frame_Glom::attempt_toggle_shared(bool shared)
 {
   //Prevent this change if not in developer mode,
   //though the menu item should be disabled then anyway.
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document || document->get_userlevel() != AppState::userlevels::DEVELOPER)
     return false;
 
@@ -1393,7 +1393,7 @@ void Frame_Glom::on_userlevel_changed(AppState::userlevels /* userlevel */)
 
 void Frame_Glom::show_table_title()
 {
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return;
 
@@ -1433,7 +1433,7 @@ void Frame_Glom::update_table_in_document_from_database()
       " Falling back to the field details in the document." << std::endl;
   }
 
-  auto pDoc = dynamic_cast<Document*>(get_document());
+  auto pDoc = std::dynamic_pointer_cast<Document>(get_document());
   if(pDoc)
   {
     bool document_must_be_updated = false;
@@ -1509,11 +1509,10 @@ void Frame_Glom::update_table_in_document_from_database()
 }
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
-void Frame_Glom::set_document(Document* pDocument)
+void Frame_Glom::set_document(const std::shared_ptr<Document>& document)
 {
-  View_Composite_Glom::set_document(pDocument);
+  View_Composite_Glom::set_document(document);
 
-  auto document = get_document();
   if(document)
   {
     //Connect to a signal that is only on the derived document class:
@@ -1526,7 +1525,7 @@ void Frame_Glom::set_document(Document* pDocument)
 
 void Frame_Glom::load_from_document()
 {
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document)
   {
     //Call base class:
@@ -1574,7 +1573,7 @@ void Frame_Glom::do_menu_developer_fields(Gtk::Window& parent, const Glib::ustri
   // Some database backends (SQLite) require the table to change to no longer
   // be in use when changing the records, so we stop the database usage
   // here. We reshow everything in on_developer_dialog_hide() anyway.
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document && document->get_hosting_mode() == Document::HostingMode::SQLITE)
     show_no_table();
 
@@ -1926,7 +1925,7 @@ bool Frame_Glom::connection_request_initial_password(Glib::ustring& user, Glib::
   user = Glib::ustring();
   password = Glib::ustring();
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return false;
 
@@ -1994,7 +1993,7 @@ void Frame_Glom::instantiate_dialog_connection()
 
 bool Frame_Glom::connection_request_password_and_choose_new_database_name()
 {
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return false;
 
@@ -2216,7 +2215,7 @@ bool Frame_Glom::connection_request_password_and_attempt(bool& database_not_foun
   //Initialize output parameter:
   database_not_found = false;
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return false;
 
@@ -2476,7 +2475,7 @@ void Frame_Glom::on_dialog_layout_print_hide()
 void Frame_Glom::on_dialog_tables_hide()
 {
   //If tables could have been added or removed, update the tables menu:
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document)
   {
     // This is never true in client only mode, so we can as well save the
diff --git a/glom/frame_glom.h b/glom/frame_glom.h
index 60c12c3..3a44eef 100644
--- a/glom/frame_glom.h
+++ b/glom/frame_glom.h
@@ -137,7 +137,7 @@ public:
 
   void on_dialog_tables_hide();
 
-  void set_document(Document* pDocument) override; //View override
+  void set_document(const std::shared_ptr<Document>& document) override; //View override
   void load_from_document() override; //View override
 
   enum class enumModes
@@ -189,7 +189,7 @@ public:
 
 private:
 
-  //void set_document(Document* pDocument) override;
+  //void set_document(const std::shared_ptr<Document>& document) override;
 
   /** Show the table, possibly selecting a particular record, possibly showing that in the details tab. This 
allows table_name to be empty in which case no
    * table will be shown.
diff --git a/glom/glom_create_from_example.cc b/glom/glom_create_from_example.cc
index bd87b93..d29d0ee 100644
--- a/glom/glom_create_from_example.cc
+++ b/glom/glom_create_from_example.cc
@@ -358,10 +358,10 @@ int main(int argc, char* argv[])
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(input_uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(input_uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -370,7 +370,7 @@ int main(int argc, char* argv[])
     return EXIT_FAILURE;
   }
 
-  g_assert(document.get_is_example_file());;
+  g_assert(document->get_is_example_file());;
 
   auto connection_pool = Glom::ConnectionPool::get_instance();
 
@@ -402,7 +402,7 @@ int main(int argc, char* argv[])
   if(file_uri.empty())
     return EXIT_FAILURE;
 
-  document.set_file_uri(file_uri);
+  document->set_file_uri(file_uri);
 
   const auto self_hosting = group.m_arg_server_hostname.empty();
   if(self_hosting)
@@ -411,11 +411,11 @@ int main(int argc, char* argv[])
 
 #if GLOM_ENABLE_MYSQL
     if(group.m_arg_use_mysql)
-      document.set_hosting_mode(Glom::Document::HostingMode::MYSQL_SELF);
+      document->set_hosting_mode(Glom::Document::HostingMode::MYSQL_SELF);
     else
 #endif //GLOM_ENABLE_MYSQL
     {
-      document.set_hosting_mode(Glom::Document::HostingMode::POSTGRES_SELF);
+      document->set_hosting_mode(Glom::Document::HostingMode::POSTGRES_SELF);
     }
   }
   else
@@ -424,27 +424,27 @@ int main(int argc, char* argv[])
 
 #if GLOM_ENABLE_MYSQL
     if(group.m_arg_use_mysql)
-      document.set_hosting_mode(Glom::Document::HostingMode::MYSQL_CENTRAL);
+      document->set_hosting_mode(Glom::Document::HostingMode::MYSQL_CENTRAL);
     else
 #endif //GLOM_ENABLE_MYSQL
     {
-      document.set_hosting_mode(Glom::Document::HostingMode::POSTGRES_CENTRAL);
+      document->set_hosting_mode(Glom::Document::HostingMode::POSTGRES_CENTRAL);
     }
   }
    
-  document.set_is_example_file(false);
-  document.set_network_shared(false);
-  const auto saved = document.save();
+  document->set_is_example_file(false);
+  document->set_network_shared(false);
+  const auto saved = document->save();
   g_assert(saved);
 
   //Specify the backend and backend-specific details to be used by the connectionpool.
-  connection_pool->setup_from_document(&document);
+  connection_pool->setup_from_document(document);
 
   //We must specify a default username and password:
   if(self_hosting)
   {
     Glib::ustring password;
-    const auto user = Glom::Privs::get_default_developer_user_name(password, document.get_hosting_mode());
+    const auto user = Glom::Privs::get_default_developer_user_name(password, document->get_hosting_mode());
     connection_pool->set_user(user);
     connection_pool->set_password(password);
   }
@@ -487,13 +487,13 @@ int main(int argc, char* argv[])
     }
     
     const Glib::ustring database_name =
-      Glom::DbUtils::get_unused_database_name(document.get_connection_database());
+      Glom::DbUtils::get_unused_database_name(document->get_connection_database());
     if(database_name.empty())
     {
       std::cerr << G_STRFUNC << ": Could not find an unused database name" << std::endl;
     }
     else
-      document.set_connection_database(database_name);
+      document->set_connection_database(database_name);
   }
         
   //Startup. For instance, create the self-hosting files if necessary:
@@ -511,7 +511,7 @@ int main(int argc, char* argv[])
   }
   g_assert(started == Glom::ConnectionPool::Backend::StartupErrors::NONE);
 
-  const auto recreated = Glom::DbUtils::recreate_database_from_document(&document, &on_recreate_progress);
+  const auto recreated = Glom::DbUtils::recreate_database_from_document(document, &on_recreate_progress);
   if(!recreated)
     cleanup();
   g_assert(recreated);
@@ -520,11 +520,11 @@ int main(int argc, char* argv[])
   std::string output_path_used;
   try
   {
-    output_path_used = Glib::filename_from_uri(document.get_file_uri());
+    output_path_used = Glib::filename_from_uri(document->get_file_uri());
   }
   catch(const Glib::ConvertError& ex)
   {
-    std::cerr << G_STRFUNC << ": Could not convert URI to output filepath: " << document.get_file_uri() << 
std::endl;
+    std::cerr << G_STRFUNC << ": Could not convert URI to output filepath: " << document->get_file_uri() << 
std::endl;
   }
    
   std::cout << "Glom file created at: " << output_path_used << std::endl;
diff --git a/glom/glom_export_po.cc b/glom/glom_export_po.cc
index 820762e..f097d26 100644
--- a/glom/glom_export_po.cc
+++ b/glom/glom_export_po.cc
@@ -199,10 +199,10 @@ int main(int argc, char* argv[])
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(input_uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(input_uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -214,7 +214,7 @@ int main(int argc, char* argv[])
   if(group.m_arg_template)
   {
     const bool succeeded = 
-      Glom::write_pot_file(&document, output_uri);
+      Glom::write_pot_file(document, output_uri);
     if(!succeeded)
     {
       std::cerr << _("Pot file creation failed.") << std::endl;
@@ -226,7 +226,7 @@ int main(int argc, char* argv[])
   else
   {
     const bool succeeded = 
-      Glom::write_translations_to_po_file(&document, output_uri, group.m_arg_locale_id);
+      Glom::write_translations_to_po_file(document, output_uri, group.m_arg_locale_id);
     if(!succeeded)
     {
       std::cerr << _("Po file creation failed.") << std::endl;
diff --git a/glom/glom_export_po_all.cc b/glom/glom_export_po_all.cc
index 8e8f230..034dfe6 100644
--- a/glom/glom_export_po_all.cc
+++ b/glom/glom_export_po_all.cc
@@ -186,10 +186,10 @@ int main(int argc, char* argv[])
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(input_uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(input_uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -198,14 +198,14 @@ int main(int argc, char* argv[])
     return EXIT_FAILURE;
   }
 
-  const auto locales = document.get_translation_available_locales();
+  const auto locales = document->get_translation_available_locales();
   if(locales.empty())
   {
     std::cerr << _("The Glom document has no translations.") << std::endl;
     return EXIT_FAILURE;
   }
 
-  const auto original_locale_id = document.get_translation_original_locale();
+  const auto original_locale_id = document->get_translation_original_locale();
   for(const auto& locale_id : locales)
   {
     if(locale_id == original_locale_id)
@@ -215,7 +215,7 @@ int main(int argc, char* argv[])
     const auto output_uri = file_output_full->get_uri();
 
     const bool succeeded = 
-      Glom::write_translations_to_po_file(&document, output_uri, locale_id);
+      Glom::write_translations_to_po_file(document, output_uri, locale_id);
     if(!succeeded)
     {
       std::cerr << _("Po file creation failed.") << std::endl;
diff --git a/glom/glom_import_po_all.cc b/glom/glom_import_po_all.cc
index 71cc041..90d4ed2 100644
--- a/glom/glom_import_po_all.cc
+++ b/glom/glom_import_po_all.cc
@@ -177,10 +177,10 @@ int main(int argc, char* argv[])
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(input_uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(input_uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -205,16 +205,16 @@ int main(int argc, char* argv[])
     if(locale_id == basename)
       continue;
     
-    document.set_allow_autosave(false); //Prevent saving while we modify the document.
+    document->set_allow_autosave(false); //Prevent saving while we modify the document.
     const bool succeeded = 
-      Glom::import_translations_from_po_file(&document, child->get_uri(), locale_id);
+      Glom::import_translations_from_po_file(document, child->get_uri(), locale_id);
     if(!succeeded)
     {
       std::cerr << Glib::ustring::compose(_("Po file import failed for locale: %1"), locale_id) << std::endl;
       return EXIT_FAILURE;
     }
 
-    if(!document.save()) {
+    if(!document->save()) {
       std::cerr << Glib::ustring::compose(_("Po file import failed during document saving for locale: %1"), 
locale_id) << std::endl;
       return EXIT_FAILURE;
     }
diff --git a/glom/libglom/connectionpool.cc b/glom/libglom/connectionpool.cc
index b6fe7b5..2dc2ade 100644
--- a/glom/libglom/connectionpool.cc
+++ b/glom/libglom/connectionpool.cc
@@ -139,7 +139,7 @@ ConnectionPool* ConnectionPool::get_instance()
   }
 }
 
-void ConnectionPool::setup_from_document(const Document* document)
+void ConnectionPool::setup_from_document(const std::shared_ptr<const Document>& document)
 {
   switch(document->get_hosting_mode())
   {
@@ -147,7 +147,7 @@ void ConnectionPool::setup_from_document(const Document* document)
     {
       auto backend = new ConnectionPoolBackends::PostgresSelfHosted;
       backend->set_database_directory_uri(document->get_connection_self_hosted_directory_uri());
-      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend));
+      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend)); //TODO: Use make_shared()?
     }
     break;
   case Document::HostingMode::POSTGRES_CENTRAL:
@@ -156,21 +156,21 @@ void ConnectionPool::setup_from_document(const Document* document)
       backend->set_host(document->get_connection_server());
       backend->set_port(document->get_connection_port());
       backend->set_try_other_ports(document->get_connection_try_other_ports());
-      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend));
+      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend)); //TODO: Use make_shared()?
     }
     break;
   case Document::HostingMode::SQLITE:
     {
       auto backend = new ConnectionPoolBackends::Sqlite;
       backend->set_database_directory_uri(document->get_connection_self_hosted_directory_uri());
-      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend));
+      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend)); //TODO: Use make_shared()?
     }
     break;
   case Document::HostingMode::MYSQL_SELF:
     {
       auto backend = new ConnectionPoolBackends::MySQLSelfHosted;
       backend->set_database_directory_uri(document->get_connection_self_hosted_directory_uri());
-      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend));
+      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend)); //TODO: Use make_shared()?
     }
     break;
   case Document::HostingMode::MYSQL_CENTRAL:
@@ -179,7 +179,7 @@ void ConnectionPool::setup_from_document(const Document* document)
       backend->set_host(document->get_connection_server());
       backend->set_port(document->get_connection_port());
       backend->set_try_other_ports(document->get_connection_try_other_ports());
-      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend));
+      set_backend(std::shared_ptr<ConnectionPool::Backend>(backend)); //TODO: Use make_shared()?
     }
     break;
 
@@ -813,7 +813,7 @@ ConnectionPool::InitErrors ConnectionPool::initialize(const SlotProgress& slot_p
     return Backend::InitErrors::OTHER;
 }
 
-Document* ConnectionPool::get_document()
+std::shared_ptr<Document> ConnectionPool::get_document()
 {
   if(!m_slot_get_document)
   {
diff --git a/glom/libglom/connectionpool.h b/glom/libglom/connectionpool.h
index aab555b..2c45c52 100644
--- a/glom/libglom/connectionpool.h
+++ b/glom/libglom/connectionpool.h
@@ -110,7 +110,7 @@ public:
   /** Make the ConnectionPool use the correct backend, with the necessary details,
    * as required by the document.
    */
-  void setup_from_document(const Document* document);
+  void setup_from_document(const std::shared_ptr<const Document>& document);
 
   /// Delete the singleton so it doesn't show up as leaked memory in, for instance, valgrind.
   static void delete_instance();
@@ -287,7 +287,7 @@ public:
    * This callback avoids Connection having to link to AppWindow,
    * and avoids us worrying about whether a previously-set document (via a set_document() method) is still 
valid.
    */
-  typedef std::function<Document*()> SlotGetDocument;
+  typedef std::function<std::shared_ptr<Document>()> SlotGetDocument;
   void set_get_document_func(const SlotGetDocument& slot);
 
 #ifndef G_OS_WIN32
@@ -321,7 +321,7 @@ private:
    */
   //static int discover_first_free_port(int start_port, int end_port);
 
-  Document* get_document();
+  std::shared_ptr<Document> get_document();
 
 #ifndef G_OS_WIN32
   /** Advertize self-hosting via avahi:
diff --git a/glom/libglom/data_structure/layout/layoutitem_portal.cc 
b/glom/libglom/data_structure/layout/layoutitem_portal.cc
index 7545502..a11d143 100644
--- a/glom/libglom/data_structure/layout/layoutitem_portal.cc
+++ b/glom/libglom/data_structure/layout/layoutitem_portal.cc
@@ -214,7 +214,7 @@ void LayoutItem_Portal::set_print_layout_line_color(const Glib::ustring& color)
   m_print_layout_line_color = color;
 }
 
-void LayoutItem_Portal::get_suitable_table_to_view_details(Glib::ustring& table_name, std::shared_ptr<const 
UsesRelationship>& relationship, const Document* document) const
+void LayoutItem_Portal::get_suitable_table_to_view_details(Glib::ustring& table_name, std::shared_ptr<const 
UsesRelationship>& relationship, const std::shared_ptr<const Document>& document) const
 {
   //Initialize output parameters:
   table_name = Glib::ustring();
@@ -278,7 +278,7 @@ void LayoutItem_Portal::get_suitable_table_to_view_details(Glib::ustring& table_
   relationship = navigation_relationship;
 }
 
-std::shared_ptr<const UsesRelationship> 
LayoutItem_Portal::get_portal_navigation_relationship_automatic(const Document* document) const
+std::shared_ptr<const UsesRelationship> 
LayoutItem_Portal::get_portal_navigation_relationship_automatic(const std::shared_ptr<const Document>& 
document) const
 {
   if(!document)
   {
@@ -329,7 +329,7 @@ std::shared_ptr<const UsesRelationship> LayoutItem_Portal::get_portal_navigation
   return std::shared_ptr<const UsesRelationship>();
 }
 
-std::shared_ptr<const LayoutItem_Field> LayoutItem_Portal::get_field_is_from_non_hidden_related_record(const 
Document* document) const
+std::shared_ptr<const LayoutItem_Field> LayoutItem_Portal::get_field_is_from_non_hidden_related_record(const 
std::shared_ptr<const Document>& document) const
 {
   //Find the first field that is from a non-hidden related table.
   std::shared_ptr<LayoutItem_Field> result;
@@ -361,7 +361,7 @@ std::shared_ptr<const LayoutItem_Field> LayoutItem_Portal::get_field_is_from_non
   return result;
 }
 
-std::shared_ptr<const LayoutItem_Field> 
LayoutItem_Portal::get_field_identifies_non_hidden_related_record(std::shared_ptr<const Relationship>& 
used_in_relationship, const Document* document) const
+std::shared_ptr<const LayoutItem_Field> 
LayoutItem_Portal::get_field_identifies_non_hidden_related_record(std::shared_ptr<const Relationship>& 
used_in_relationship, const std::shared_ptr<const Document>& document) const
 {
   //Find the first field that is from a non-hidden related table.
   std::shared_ptr<LayoutItem_Field> result;
diff --git a/glom/libglom/data_structure/layout/layoutitem_portal.h 
b/glom/libglom/data_structure/layout/layoutitem_portal.h
index f3f2bd8..f0a136c 100644
--- a/glom/libglom/data_structure/layout/layoutitem_portal.h
+++ b/glom/libglom/data_structure/layout/layoutitem_portal.h
@@ -112,13 +112,13 @@ public:
    * @param table_name The table that should be shown.
    * @param relationship The relationship in the directly related table that should be used to get to that 
table. If this is empty then we should just show the table directly.
    */
-  void get_suitable_table_to_view_details(Glib::ustring& table_name, std::shared_ptr<const 
UsesRelationship>& relationship, const Document* document) const;
+  void get_suitable_table_to_view_details(Glib::ustring& table_name, std::shared_ptr<const 
UsesRelationship>& relationship, const std::shared_ptr<const Document>& document) const;
 
   /** Get the relationship (from the related table) into which the row button should navigate,
    * or none if it should use the portal's directly related table itself.
    * (If that should be chosen automatically, by looking at the fields in the portal.)
    */
-  std::shared_ptr<const UsesRelationship> get_portal_navigation_relationship_automatic(const Document* 
document) const;
+  std::shared_ptr<const UsesRelationship> get_portal_navigation_relationship_automatic(const 
std::shared_ptr<const Document>& document) const;
 
   /// This is used only for the print layouts.
   double get_print_layout_row_height() const;
@@ -156,8 +156,8 @@ public:
 
 private:
 
-  std::shared_ptr<const LayoutItem_Field> get_field_is_from_non_hidden_related_record(const Document* 
document) const;
-  std::shared_ptr<const LayoutItem_Field> 
get_field_identifies_non_hidden_related_record(std::shared_ptr<const Relationship>& used_in_relationship, 
const Document* document) const;
+  std::shared_ptr<const LayoutItem_Field> get_field_is_from_non_hidden_related_record(const 
std::shared_ptr<const Document>& document) const;
+  std::shared_ptr<const LayoutItem_Field> 
get_field_identifies_non_hidden_related_record(std::shared_ptr<const Relationship>& used_in_relationship, 
const std::shared_ptr<const Document>& document) const;
 
 
   std::shared_ptr<UsesRelationship> m_navigation_relationship_specific;
diff --git a/glom/libglom/db_utils.cc b/glom/libglom/db_utils.cc
index 8488947..539f824 100644
--- a/glom/libglom/db_utils.cc
+++ b/glom/libglom/db_utils.cc
@@ -102,7 +102,7 @@ static bool update_gda_metastore_for_table(const Glib::ustring& table_name)
   return true;
 }
 
-bool create_database(Document* document, const Glib::ustring& database_name, const Glib::ustring& title, 
const std::function<void()>& progress)
+bool create_database(const std::shared_ptr<Document>& document, const Glib::ustring& database_name, const 
Glib::ustring& title, const std::function<void()>& progress)
 {
 #if 1
   // This seems to increase the chance that the database creation does not
@@ -215,7 +215,7 @@ bool create_database(Document* document, const Glib::ustring& database_name, con
   }
 }
 
-bool recreate_database_from_document(Document* document, const std::function<void()>& progress)
+bool recreate_database_from_document(const std::shared_ptr<Document>& document, const std::function<void()>& 
progress)
 {
   auto connection_pool = ConnectionPool::get_instance();
   if(!connection_pool)
@@ -348,7 +348,7 @@ bool recreate_database_from_document(Document* document, const std::function<voi
 }
 
 
-SystemPrefs get_database_preferences(const Document* document)
+SystemPrefs get_database_preferences(const std::shared_ptr<const Document>& document)
 {
   //if(get_userlevel() == AppState::userlevels::DEVELOPER)
   //  add_standard_tables(document);
@@ -437,7 +437,7 @@ SystemPrefs get_database_preferences(const Document* document)
 }
 
 
-void set_database_preferences(Document* document, const SystemPrefs& prefs)
+void set_database_preferences(const std::shared_ptr<Document>& document, const SystemPrefs& prefs)
 {
    //The logo field was introduced in a later version of Glom.
   //If the user is not in developer mode then the new field has not yet been added:
@@ -469,7 +469,7 @@ void set_database_preferences(Document* document, const SystemPrefs& prefs)
 }
 
 
-bool add_standard_tables(const Document* document)
+bool add_standard_tables(const std::shared_ptr<const Document>& document)
 {
   try
   {
@@ -573,7 +573,7 @@ bool add_standard_tables(const Document* document)
   }
 }
 
-bool add_standard_groups(Document* document)
+bool add_standard_groups(const std::shared_ptr<Document>& document)
 {
   //Add the glom_developer group if it does not exist:
   const Glib::ustring devgroup = GLOM_STANDARD_GROUP_NAME_DEVELOPER;
@@ -647,7 +647,7 @@ bool add_standard_groups(Document* document)
   return true;
 }
 
-bool add_groups_from_document(const Document* document)
+bool add_groups_from_document(const std::shared_ptr<const Document>& document)
 {
   auto gda_connection = get_connection();
   if(!gda_connection)
@@ -683,7 +683,7 @@ bool add_groups_from_document(const Document* document)
   return true;
 }
 
-bool set_table_privileges_groups_from_document(const Document* document)
+bool set_table_privileges_groups_from_document(const std::shared_ptr<const Document>& document)
 {
   auto gda_connection = get_connection();
   if(!gda_connection)
@@ -969,7 +969,7 @@ type_vec_fields get_fields_for_table_from_database(const Glib::ustring& table_na
 }
 
 //TODO: This is very inefficient, because it is 
-type_vec_fields get_fields_for_table(const Document* document, const Glib::ustring& table_name, bool /* 
including_system_fields */)
+type_vec_fields get_fields_for_table(const std::shared_ptr<const Document>& document, const Glib::ustring& 
table_name, bool /* including_system_fields */)
 {
   //We could also get the field definitions from the database:
   //But that is inefficient because this method is called so often,
@@ -1033,7 +1033,7 @@ type_vec_fields get_fields_for_table(const Document* document, const Glib::ustri
   return result;
 }
 
-std::shared_ptr<Field> get_fields_for_table_one_field(const Document* document, const Glib::ustring& 
table_name, const Glib::ustring& field_name)
+std::shared_ptr<Field> get_fields_for_table_one_field(const std::shared_ptr<const Document>& document, const 
Glib::ustring& table_name, const Glib::ustring& field_name)
 {
   //Initialize output parameter:
   std::shared_ptr<Field> result;
@@ -1143,7 +1143,7 @@ bool get_table_exists_in_database(const Glib::ustring& table_name)
   return Utils::find_exists(tables, table_name);
 }
 
-bool create_table_with_default_fields(Document* document, const Glib::ustring& table_name)
+bool create_table_with_default_fields(const std::shared_ptr<Document>& document, const Glib::ustring& 
table_name)
 {
   if(table_name.empty())
     return false;
@@ -1566,7 +1566,7 @@ void remove_auto_increment(const Glib::ustring& table_name, const Glib::ustring&
     std::cerr << G_STRFUNC << ": UPDATE failed." << std::endl;
 }
 
-bool insert_example_data(const Document* document, const Glib::ustring& table_name)
+bool insert_example_data(const std::shared_ptr<const Document>& document, const Glib::ustring& table_name)
 {
   //TODO_Performance: Avoid copying:
   const auto example_rows = document->get_table_example_data(table_name);
@@ -1843,7 +1843,7 @@ bool query_execute(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder)
   return (exec_retval >= 0);
 }
 
-void layout_item_fill_field_details(const Document* document, const Glib::ustring& parent_table_name, 
std::shared_ptr<LayoutItem_Field>& layout_item)
+void layout_item_fill_field_details(const std::shared_ptr<const Document>& document, const Glib::ustring& 
parent_table_name, std::shared_ptr<LayoutItem_Field>& layout_item)
 {
   if(!document)
   {
@@ -1860,7 +1860,7 @@ void layout_item_fill_field_details(const Document* document, const Glib::ustrin
   layout_item->set_full_field_details( document->get_field(table_name, layout_item->get_name()) );
 }
 
-bool layout_field_should_have_navigation(const Glib::ustring& table_name, const std::shared_ptr<const 
LayoutItem_Field>& layout_item, const Document* document, std::shared_ptr<Relationship>& 
field_used_in_relationship_to_one)
+bool layout_field_should_have_navigation(const Glib::ustring& table_name, const std::shared_ptr<const 
LayoutItem_Field>& layout_item, const std::shared_ptr<const Document>& document, 
std::shared_ptr<Relationship>& field_used_in_relationship_to_one)
 {
   //Initialize output parameter:
   field_used_in_relationship_to_one = std::shared_ptr<Relationship>();
@@ -2093,7 +2093,7 @@ static Glib::ustring build_query_add_user(const Glib::ustring& user, const Glib:
   return strQuery;
 }
 
-bool add_user(const Document* document, const Glib::ustring& user, const Glib::ustring& password, const 
Glib::ustring& group)
+bool add_user(const std::shared_ptr<const Document>& document, const Glib::ustring& user, const 
Glib::ustring& password, const Glib::ustring& group)
 {
   if(!document)
   {
@@ -2152,7 +2152,7 @@ bool add_user(const Document* document, const Glib::ustring& user, const Glib::u
   return true;
 }
 
-bool add_group(const Document* document, const Glib::ustring& group, bool superuser)
+bool add_group(const std::shared_ptr<const Document>& document, const Glib::ustring& group, bool superuser)
 {
   if(!document)
   {
@@ -2248,7 +2248,7 @@ void set_fake_connection()
   connection_pool->set_fake_connection();
 }
 
-Gnome::Gda::Value get_lookup_value(const Document* document, const Glib::ustring& /* table_name */, const 
std::shared_ptr<const Relationship>& relationship, const std::shared_ptr<const Field>& source_field, const 
Gnome::Gda::Value& key_value)
+Gnome::Gda::Value get_lookup_value(const std::shared_ptr<const Document>& document, const Glib::ustring& /* 
table_name */, const std::shared_ptr<const Relationship>& relationship, const std::shared_ptr<const Field>& 
source_field, const Gnome::Gda::Value& key_value)
 {
   Gnome::Gda::Value result;
 
@@ -2283,7 +2283,7 @@ Gnome::Gda::Value get_lookup_value(const Document* document, const Glib::ustring
   return result;
 }
 
-type_map_fields get_record_field_values(const Document* document, const Glib::ustring& table_name, const 
std::shared_ptr<const Field>& primary_key, const Gnome::Gda::Value& primary_key_value)
+type_map_fields get_record_field_values(const std::shared_ptr<const Document>& document, const 
Glib::ustring& table_name, const std::shared_ptr<const Field>& primary_key, const Gnome::Gda::Value& 
primary_key_value)
 {
   type_map_fields field_values;
 
diff --git a/glom/libglom/db_utils.h b/glom/libglom/db_utils.h
index cd7b4ca..d975cb1 100644
--- a/glom/libglom/db_utils.h
+++ b/glom/libglom/db_utils.h
@@ -34,33 +34,33 @@ namespace DbUtils
 /**
  * This also saves the connection port in the document if self-hosting.
  */
-bool create_database(Document* document, const Glib::ustring& database_name, const Glib::ustring& title, 
const std::function<void()>& progress);
+bool create_database(const std::shared_ptr<Document>& document, const Glib::ustring& database_name, const 
Glib::ustring& title, const std::function<void()>& progress);
 
 //TODO: Use this in Glom::AppWindow?
 /** Create the database on an already-connected server.
  * This also saves some details in the document.
  */
-bool recreate_database_from_document(Document* document, const std::function<void()>& progress);
+bool recreate_database_from_document(const std::shared_ptr<Document>& document, const std::function<void()>& 
progress);
 
 /** This creates the standard tables if necessary,
  * filling them with some information from the document.
  */
-SystemPrefs get_database_preferences(const Document* document);
+SystemPrefs get_database_preferences(const std::shared_ptr<const Document>& document);
 
 /**
  * This also saves the preferences in the document.
  */
-void set_database_preferences(Document* document, const SystemPrefs& prefs);
+void set_database_preferences(const std::shared_ptr<Document>& document, const SystemPrefs& prefs);
 
-bool add_standard_tables(const Document* document);
+bool add_standard_tables(const std::shared_ptr<const Document>& document);
 
 /**
  * This also saves the groups in the document.
  */
-bool add_standard_groups(Document* document);
+bool add_standard_groups(const std::shared_ptr<Document>& document);
 
-bool add_groups_from_document(const Document* document);
-bool set_table_privileges_groups_from_document(const Document* document);
+bool add_groups_from_document(const std::shared_ptr<const Document>& document);
+bool set_table_privileges_groups_from_document(const std::shared_ptr<const Document>& document);
 
 typedef std::vector< std::shared_ptr<Field> > type_vec_fields;
 type_vec_fields get_fields_for_table_from_database(const Glib::ustring& table_name, bool 
including_system_fields = false);
@@ -72,7 +72,7 @@ bool get_field_exists_in_database(const Glib::ustring& table_name, const Glib::u
  * @param including_system_fields Whether extra non-user-visible fields should be included in the list.
  * @result A list of fields.
  */
-type_vec_fields get_fields_for_table(const Document* document, const Glib::ustring& table_name, bool 
including_system_fields = false);
+type_vec_fields get_fields_for_table(const std::shared_ptr<const Document>& document, const Glib::ustring& 
table_name, bool including_system_fields = false);
 
 /** Get a single field definition for a table, even if the field is in the datasbase but not yet known in 
the document.
  *
@@ -80,7 +80,7 @@ type_vec_fields get_fields_for_table(const Document* document, const Glib::ustri
  * @param field_name The name of the field for which to get the definition.
  * @result The field definition.
  */
-std::shared_ptr<Field> get_fields_for_table_one_field(const Document* document, const Glib::ustring& 
table_name, const Glib::ustring& field_name);
+std::shared_ptr<Field> get_fields_for_table_one_field(const std::shared_ptr<const Document>& document, const 
Glib::ustring& table_name, const Glib::ustring& field_name);
 
 typedef std::vector<Glib::ustring> type_vec_strings;
 
@@ -94,7 +94,7 @@ bool get_table_exists_in_database(const Glib::ustring& table_name);
 bool create_table(Document::HostingMode hosting_mode, const std::shared_ptr<const TableInfo>& table_info, 
const Document::type_vec_fields& fields);
 
 /// Also saves the table information in the document:
-bool create_table_with_default_fields(Document* document, const Glib::ustring& table_name);
+bool create_table_with_default_fields(const std::shared_ptr<Document>& document, const Glib::ustring& 
table_name);
 
 bool create_table_add_missing_fields(const std::shared_ptr<const TableInfo>& table_info, const 
Document::type_vec_fields& fields);
 
@@ -107,7 +107,7 @@ bool drop_column(const Glib::ustring& table_name, const Glib::ustring& field_nam
 
 /** Insert example data, from the document, into the table on the database server.
  */
-bool insert_example_data(const Document* document, const Glib::ustring& table_name);
+bool insert_example_data(const std::shared_ptr<const Document>& document, const Glib::ustring& table_name);
 
 /** Execute a SQL Select command, returning the result.
  * @param builder The finished SqlBuilder object.
@@ -145,7 +145,7 @@ Gnome::Gda::Value get_next_auto_increment_value(const Glib::ustring& table_name,
  */
 void remove_auto_increment(const Glib::ustring& table_name, const Glib::ustring& field_name);
 
-void layout_item_fill_field_details(const Document* document, const Glib::ustring& parent_table_name, 
std::shared_ptr<LayoutItem_Field>& layout_item);
+void layout_item_fill_field_details(const std::shared_ptr<const Document>& document, const Glib::ustring& 
parent_table_name, std::shared_ptr<LayoutItem_Field>& layout_item);
 
 
 //TODO: It would be nice to use std::shared_ptr<const Relationship>& instead of 
std::shared_ptr<Relationship>&,
@@ -156,7 +156,7 @@ void layout_item_fill_field_details(const Document* document, const Glib::ustrin
  * @param layout_item A field on a layout. This must have full field details.
  * @param field_used_in_relationship_to_one A relationship, if the field identifies a single record, so a 
Find button would also make sense, to choose the ID, in editing mode.
  */
-bool layout_field_should_have_navigation(const Glib::ustring& table_name, const std::shared_ptr<const 
LayoutItem_Field>& layout_item, const Document* document, std::shared_ptr<Relationship>& 
field_used_in_relationship_to_one);
+bool layout_field_should_have_navigation(const Glib::ustring& table_name, const std::shared_ptr<const 
LayoutItem_Field>& layout_item, const std::shared_ptr<const Document>& document, 
std::shared_ptr<Relationship>& field_used_in_relationship_to_one);
 
 /** Discover a database name that is not yet used.
  * This assumes that all other connection details are correctly set.
@@ -201,7 +201,7 @@ Glib::ustring build_query_add_user_to_group(const Glib::ustring& group, const Gl
 /** Add a @a user to the database, with the specified @a password, in the specified @a group.
  * @result true if the addition succeeded.
  */
-bool add_user(const Document* document, const Glib::ustring& user, const Glib::ustring& password, const 
Glib::ustring& group);
+bool add_user(const std::shared_ptr<const Document>& document, const Glib::ustring& user, const 
Glib::ustring& password, const Glib::ustring& group);
 
 /** Remove the @a user from the database.
  * @result true if the removal succeeded.
@@ -211,18 +211,18 @@ bool remove_user(const Glib::ustring& user);
 /** Add a @a group to the database.
  * @result true if the addition succeeded.
  */
-bool add_group(const Document* document, const Glib::ustring& group, bool superuser = false);
+bool add_group(const std::shared_ptr<const Document>& document, const Glib::ustring& group, bool superuser = 
false);
 
 bool remove_user_from_group(const Glib::ustring& user, const Glib::ustring& group);
 
 /** Get the value of the @a source_field from the @a relationship, using the @a key_value.
  */
-Gnome::Gda::Value get_lookup_value(const Document* document, const Glib::ustring& table_name, const 
std::shared_ptr<const Relationship>& relationship, const std::shared_ptr<const Field>& source_field, const 
Gnome::Gda::Value & key_value);
+Gnome::Gda::Value get_lookup_value(const std::shared_ptr<const Document>& document, const Glib::ustring& 
table_name, const std::shared_ptr<const Relationship>& relationship, const std::shared_ptr<const Field>& 
source_field, const Gnome::Gda::Value & key_value);
 
 typedef std::map<Glib::ustring, Gnome::Gda::Value> type_map_fields;
 
 //TODO: Performance: This is massively inefficient:
-type_map_fields get_record_field_values(const Document* document, const Glib::ustring& table_name, const 
std::shared_ptr<const Field>& primary_key, const Gnome::Gda::Value& primary_key_value);
+type_map_fields get_record_field_values(const std::shared_ptr<const Document>& document, const 
Glib::ustring& table_name, const std::shared_ptr<const Field>& primary_key, const Gnome::Gda::Value& 
primary_key_value);
   
 /** Allow a fake connection, so sqlbuilder_get_full_query() can work.
  */
diff --git a/glom/libglom/document/bakery/document.cc b/glom/libglom/document/bakery/document.cc
index c956d53..1af5d1b 100644
--- a/glom/libglom/document/bakery/document.cc
+++ b/glom/libglom/document/bakery/document.cc
@@ -38,6 +38,10 @@ Document::Document()
 
 Document::~Document()
 {
+}
+
+void Document::emit_forget()
+{
   //Tell views to forget the document -  to null their pointers to it. We should maybe use the Document via 
a sharing smartpointer instead.
   signal_forget_.emit();
 }
diff --git a/glom/libglom/document/bakery/document.h b/glom/libglom/document/bakery/document.h
index 615d965..5b3ba7b 100644
--- a/glom/libglom/document/bakery/document.h
+++ b/glom/libglom/document/bakery/document.h
@@ -36,6 +36,9 @@ public:
   Document();
   virtual ~Document();
 
+  //TODO: Properly use a weak pointer instead.
+  void emit_forget();
+
   /* Saves the data to disk.
    * Asks the View to update this document before saving to disk,
    * but you should probably ensure that the document is updated more regularly than this,
diff --git a/glom/libglom/document/bakery/view/view.h b/glom/libglom/document/bakery/view/view.h
index 96278ba..e020d31 100644
--- a/glom/libglom/document/bakery/view/view.h
+++ b/glom/libglom/document/bakery/view/view.h
@@ -22,6 +22,7 @@
 #include <libglom/document/bakery/view/viewbase.h>
 #include <libglom/document/bakery/document.h>
 #include <sigc++/sigc++.h>
+#include <memory>
 
 namespace GlomBakery
 {
@@ -34,7 +35,6 @@ class View : public ViewBase
 {
 public: 
   View()
-  : m_pDocument(0)
   {
   }
 
@@ -42,28 +42,28 @@ public:
 
   //typedef typename T_Document type_document;
 
-  virtual T_Document* get_document()
+  virtual std::shared_ptr<T_Document> get_document()
   {
-    return m_pDocument;
+    return m_document;
   }
 
-  virtual const T_Document* get_document() const
+  virtual std::shared_ptr<const T_Document> get_document() const
   {
-    return m_pDocument;
+    return m_document;
   }
 
-  virtual void set_document(T_Document* pDocument)
+  virtual void set_document(const std::shared_ptr<T_Document>& document)
   {
-    m_pDocument = pDocument;
-    if(m_pDocument)
-      m_pDocument->signal_forget().connect( sigc::mem_fun(*this, &type_self::on_document_forget) );
+    m_document = document;
+    if(m_document)
+      m_document->signal_forget().connect( sigc::mem_fun(*this, &type_self::on_document_forget) );
   }
 
   ///Just a convenience, instead of get_docuement()->set_modified().
   virtual void set_modified(bool val = true)
   {
-    if(m_pDocument)
-      m_pDocument->set_modified(val);
+    if(m_document)
+      m_document->set_modified(val);
   }
 
 protected:
@@ -71,10 +71,10 @@ protected:
   void on_document_forget()
   {
     //This should prevent some segfaults:
-    m_pDocument = 0;
+    m_document.reset();
   }
   
-  T_Document* m_pDocument;
+  std::shared_ptr<T_Document> m_document;
 };
 
 } //namespace
diff --git a/glom/libglom/document/bakery/view/view_composite.h 
b/glom/libglom/document/bakery/view/view_composite.h
index 7ca56eb..2726126 100644
--- a/glom/libglom/document/bakery/view/view_composite.h
+++ b/glom/libglom/document/bakery/view/view_composite.h
@@ -60,16 +60,16 @@ public:
       m_vecViews.erase(iter);
   }
 
-  void set_document(T_Document* pDocument) override
+  void set_document(const std::shared_ptr<T_Document>& document) override
   {
     //Call base class:
-    View<T_Document>::set_document(pDocument);
+    View<T_Document>::set_document(document);
 
     //Change the document in the child views.
     for(const auto& pView : m_vecViews)
     {
       if(pView)
-        pView->set_document(pDocument);
+        pView->set_document(document);
     }
   }
 
diff --git a/glom/libglom/example_document_load.cc b/glom/libglom/example_document_load.cc
index ab78cce..cd30a1e 100644
--- a/glom/libglom/example_document_load.cc
+++ b/glom/libglom/example_document_load.cc
@@ -90,26 +90,26 @@ int main()
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
     return 1;
 
-  std::cout << "Database Title: " << document.get_database_title_original() << std::endl;
-  std::cout << "Default Table: " << document.get_default_table() << std::endl;
+  std::cout << "Database Title: " << document->get_database_title_original() << std::endl;
+  std::cout << "Default Table: " << document->get_default_table() << std::endl;
 
 
   // Look at each table:
-  for(const auto& table_name : document.get_table_names())
+  for(const auto& table_name : document->get_table_names())
   {
     std::cout << "Table: " << table_name << std::endl;
 
     // List the fields for this table:
-    for(const auto& field : document.get_table_fields(table_name))
+    for(const auto& field : document->get_table_fields(table_name))
     {
        if(!field)
          continue;
@@ -123,7 +123,7 @@ int main()
     }
 
     // List the relationships for this table:
-    for(const auto& relationship : document.get_relationships(table_name))
+    for(const auto& relationship : document->get_relationships(table_name))
     {
        if(!relationship)
          continue;
@@ -135,12 +135,12 @@ int main()
 
     //Show the layouts for this table:
     const Glom::Document::type_list_layout_groups layout_list =
-      document.get_data_layout_groups("list", table_name);
+      document->get_data_layout_groups("list", table_name);
     std::cout << "  Layout: List:" << std::endl;
     print_layout(layout_list);
 
     const Glom::Document::type_list_layout_groups layout_details =
-      document.get_data_layout_groups("details", table_name);
+      document->get_data_layout_groups("details", table_name);
     std::cout << "  Layout: Details:" << std::endl;
     print_layout(layout_details);
   }
diff --git a/glom/libglom/python_embed/py_glom_record.cc b/glom/libglom/python_embed/py_glom_record.cc
index 806300b..b2ee0cd 100644
--- a/glom/libglom/python_embed/py_glom_record.cc
+++ b/glom/libglom/python_embed/py_glom_record.cc
@@ -211,7 +211,7 @@ void PyGlomRecord::setitem(const boost::python::object& key, const boost::python
   //TODO: Do dependent calculations and lookups. Or just do them for all fields for this record when 
finishing the script?
 }
 
-void PyGlomRecord::set_fields(const PyGlomRecord::type_map_field_values& field_values, const Document* 
document, const Glib::ustring& table_name, const std::shared_ptr<const Field>& key_field, const 
Gnome::Gda::Value& key_field_value, const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection)
+void PyGlomRecord::set_fields(const PyGlomRecord::type_map_field_values& field_values, const 
std::shared_ptr<const Document>& document, const Glib::ustring& table_name, const std::shared_ptr<const 
Field>& key_field, const Gnome::Gda::Value& key_field_value, const Glib::RefPtr<Gnome::Gda::Connection>& 
opened_connection)
 {
   m_map_field_values = field_values;
   /* Just for debugging:
diff --git a/glom/libglom/python_embed/py_glom_record.h b/glom/libglom/python_embed/py_glom_record.h
index b70b7e9..631696f 100644
--- a/glom/libglom/python_embed/py_glom_record.h
+++ b/glom/libglom/python_embed/py_glom_record.h
@@ -61,14 +61,14 @@ public:
   void setitem(const boost::python::object& /* key */, const boost::python::object& /* value */);
 
   void set_fields(const PyGlomRecord::type_map_field_values& field_values,
-    const Document* document,
+    const std::shared_ptr<const Document>& document,
     const Glib::ustring& table_name,
     const std::shared_ptr<const Field>& key_field,
     const Gnome::Gda::Value& key_field_value,
     const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection);
 
 public:
-  const Document* m_document;
+  std::shared_ptr<const Document> m_document;
   Glib::ustring m_table_name;
   type_map_field_values m_map_field_values;
 private:
diff --git a/glom/libglom/python_embed/py_glom_relatedrecord.cc 
b/glom/libglom/python_embed/py_glom_relatedrecord.cc
index 46a49f2..cfb8003 100644
--- a/glom/libglom/python_embed/py_glom_relatedrecord.cc
+++ b/glom/libglom/python_embed/py_glom_relatedrecord.cc
@@ -257,7 +257,10 @@ boost::python::object PyGlomRelatedRecord::max(const std::string& field_name) co
   return generic_aggregate(field_name, "max");
 }
 
-void PyGlomRelatedRecord::set_relationship(const std::shared_ptr<const Relationship>& relationship, const 
Gnome::Gda::Value& from_key_value, const Document* document)
+void PyGlomRelatedRecord::set_relationship(
+  const std::shared_ptr<const Relationship>& relationship,
+  const Gnome::Gda::Value& from_key_value,
+  const std::shared_ptr<const Document>& document)
 {
   m_relationship = relationship;
   m_from_key_value = from_key_value;
diff --git a/glom/libglom/python_embed/py_glom_relatedrecord.h 
b/glom/libglom/python_embed/py_glom_relatedrecord.h
index 553fef5..ecf126a 100644
--- a/glom/libglom/python_embed/py_glom_relatedrecord.h
+++ b/glom/libglom/python_embed/py_glom_relatedrecord.h
@@ -38,7 +38,7 @@ public:
   PyGlomRelatedRecord();
   ~PyGlomRelatedRecord();
 
-  void set_relationship(const std::shared_ptr<const Relationship>& relationship, const Gnome::Gda::Value& 
from_key_value, const Document* document);
+  void set_relationship(const std::shared_ptr<const Relationship>& relationship, const Gnome::Gda::Value& 
from_key_value, const std::shared_ptr<const Document>& document);
 
   boost::python::object sum(const std::string& field_name) const;
   boost::python::object count(const std::string& field_name) const;
@@ -58,7 +58,7 @@ private:
 
   //PyObject* m_fields_dict; //Dictionary (map) of field names (string) to field values (Gnome::Gda::Value).
   //PyGlomRecord* m_record_parent;
-  const Document* m_document;
+  std::shared_ptr<const Document> m_document;
 
   std::shared_ptr<const Relationship> m_relationship;
   Gnome::Gda::Value m_from_key_value;
diff --git a/glom/libglom/report_builder.cc b/glom/libglom/report_builder.cc
index 2aee4eb..a137ab2 100644
--- a/glom/libglom/report_builder.cc
+++ b/glom/libglom/report_builder.cc
@@ -632,12 +632,12 @@ Glib::ustring ReportBuilder::report_build(const FoundSet& found_set, const std::
   //Create a DOM Document with the XML:
   xmlpp::DomParser dom_parser;;
 
-  auto pDocument = dom_parser.get_document();
-  auto nodeRoot = pDocument->get_root_node();
+  auto document = dom_parser.get_document();
+  auto nodeRoot = document->get_root_node();
   if(!nodeRoot)
   {
     //Add it if it isn't there already:
-    nodeRoot = pDocument->create_root_node("report_print");
+    nodeRoot = document->create_root_node("report_print");
   }
 
   Glib::ustring table_title = get_document()->get_table_title(found_set.m_table_name, m_locale_id);
@@ -716,7 +716,7 @@ Glib::ustring ReportBuilder::report_build(const FoundSet& found_set, const std::
     }
   }
 
-  return GlomXslUtils::transform(*pDocument, "print_report_to_html.xsl");
+  return GlomXslUtils::transform(*document, "print_report_to_html.xsl");
 }
 
 static void fill_standard_list_report_fill(const std::shared_ptr<Report>& report, const 
std::shared_ptr<const LayoutGroup>& layout_group)
@@ -737,7 +737,7 @@ static void fill_standard_list_report_fill(const std::shared_ptr<Report>& report
   }
 }
 
-std::shared_ptr<Report> ReportBuilder::create_standard_list_report(const Document* document, const 
Glib::ustring& table_name)
+std::shared_ptr<Report> ReportBuilder::create_standard_list_report(const std::shared_ptr<const Document>& 
document, const Glib::ustring& table_name)
 {
   auto result = std::make_shared<Report>();
   result->set_name("list");
@@ -755,12 +755,12 @@ std::shared_ptr<Report> ReportBuilder::create_standard_list_report(const Documen
   return result;
 }
 
-void ReportBuilder::set_document(Document* document)
+void ReportBuilder::set_document(const std::shared_ptr<Document>& document)
 {
   m_document = document;
 }
 
-Document* ReportBuilder::get_document()
+std::shared_ptr<Document> ReportBuilder::get_document()
 {
   return m_document;
 }
diff --git a/glom/libglom/report_builder.h b/glom/libglom/report_builder.h
index 688548f..7b5bbbf 100644
--- a/glom/libglom/report_builder.h
+++ b/glom/libglom/report_builder.h
@@ -37,10 +37,10 @@ class ReportBuilder
 public:
   explicit ReportBuilder(const std::locale& locale);
 
-  static std::shared_ptr<Report> create_standard_list_report(const Document* document, const Glib::ustring& 
table_name);
+  static std::shared_ptr<Report> create_standard_list_report(const std::shared_ptr<const Document>& 
document, const Glib::ustring& table_name);
 
   //TODO: Remove set_document() and get_document()?
-  void set_document(Document* document);
+  void set_document(const std::shared_ptr<Document>& document);
 
   //void set_report(const Glib::ustring& table_name, const std::shared_ptr<const Report>& report);
   //std::shared_ptr<Report> get_report();
@@ -73,9 +73,9 @@ private:
   bool report_build_records_image(const FoundSet& found_set, xmlpp::Element& nodeParent, const 
std::shared_ptr<const LayoutItem_Image>& imageobject, bool vertical = false);
   bool report_build_records_vertical_group(const FoundSet& found_set, xmlpp::Element& vertical_group_node, 
const std::shared_ptr<LayoutItem_VerticalGroup>& group, const Glib::RefPtr<Gnome::Gda::DataModel>& datamodel, 
guint row, guint& field_index);
 
-  Document* get_document();
+  std::shared_ptr<Document> get_document();
 
-  Document* m_document;
+  std::shared_ptr<Document> m_document;
 
   std::locale m_locale; //For use with GlomConversions
   Glib::ustring m_locale_id; //To get the appropriate translations.
diff --git a/glom/libglom/translations_po.cc b/glom/libglom/translations_po.cc
index 136fbc1..d494594 100644
--- a/glom/libglom/translations_po.cc
+++ b/glom/libglom/translations_po.cc
@@ -183,13 +183,13 @@ Glib::ustring get_po_context_for_item(const std::shared_ptr<const TranslatableIt
   return result;
 }
 
-bool write_pot_file(Document* document, const Glib::ustring& pot_file_uri)
+bool write_pot_file(const std::shared_ptr<Document>& document, const Glib::ustring& pot_file_uri)
 {
   //A .pot file 
   return write_translations_to_po_file(document, pot_file_uri, Glib::ustring() /* no locale */);
 }
 
-bool write_translations_to_po_file(Document* document, const Glib::ustring& po_file_uri, const 
Glib::ustring& translation_locale, const Glib::ustring& locale_name)
+bool write_translations_to_po_file(const std::shared_ptr<Document>& document, const Glib::ustring& 
po_file_uri, const Glib::ustring& translation_locale, const Glib::ustring& locale_name)
 {
   std::string filename;
 
@@ -244,7 +244,7 @@ bool write_translations_to_po_file(Document* document, const Glib::ustring& po_f
   return true;
 }
 
-bool import_translations_from_po_file(Document* document, const Glib::ustring& po_file_uri, const 
Glib::ustring& translation_locale)
+bool import_translations_from_po_file(const std::shared_ptr<Document>& document, const Glib::ustring& 
po_file_uri, const Glib::ustring& translation_locale)
 {
   std::string filename;
 
diff --git a/glom/libglom/translations_po.h b/glom/libglom/translations_po.h
index 902a2a8..09e9c81 100644
--- a/glom/libglom/translations_po.h
+++ b/glom/libglom/translations_po.h
@@ -30,7 +30,7 @@ namespace Glom
  * @param document The document whose translations should be written to a .po file.
  * @param pot_file The filepath at which to create a .po file.
  */
-bool write_pot_file(Document* document, const Glib::ustring& pot_file_uri);
+bool write_pot_file(const std::shared_ptr<Document>& document, const Glib::ustring& pot_file_uri);
 
 /** Create a po file containing the translations from the Glom document.
  * @param document The document whose translations should be written to a .po file.
@@ -38,14 +38,14 @@ bool write_pot_file(Document* document, const Glib::ustring& pot_file_uri);
  * @param translation_locale For instance, de_DE.
  * @param locale_name For instance, Deutsch, to identify the translation team.
  */
-bool write_translations_to_po_file(Document* document, const Glib::ustring& po_file_uri, const 
Glib::ustring& translation_locale, const Glib::ustring& locale_name = Glib::ustring());
+bool write_translations_to_po_file(const std::shared_ptr<Document>& document, const Glib::ustring& 
po_file_uri, const Glib::ustring& translation_locale, const Glib::ustring& locale_name = Glib::ustring());
 
 /** Parse a po file, storing its translations in the Glom document.
  * @param document The document into which the translations should be stored.
  * @param po_file The filepath at which to find a .po file.
  * @param translation_locale For instance, de_DE.
  */
-bool import_translations_from_po_file(Document* document, const Glib::ustring& po_file_uri, const 
Glib::ustring& translation_locale);
+bool import_translations_from_po_file(const std::shared_ptr<Document>& document, const Glib::ustring& 
po_file_uri, const Glib::ustring& translation_locale);
 
 /** Get a hint about what the text is for.
  * This is also necessary to uniquely identify the item,
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index d472f8e..107d344 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -505,13 +505,13 @@ Glib::RefPtr<Gnome::Gda::SqlBuilder> Utils::build_sql_select_with_key(const Glib
     std::shared_ptr<const Relationship>(), sort_clause, limit);
 }
 
-Utils::type_list_values_with_second Utils::get_choice_values_all(const Document* document, const 
std::shared_ptr<const LayoutItem_Field>& field)
+Utils::type_list_values_with_second Utils::get_choice_values_all(const std::shared_ptr<const Document>& 
document, const std::shared_ptr<const LayoutItem_Field>& field)
 {
   return get_choice_values(document, field,
     Gnome::Gda::Value() /* means get all with no WHERE clause */);
 }
 
-Utils::type_list_values_with_second Utils::get_choice_values(const Document* document, const 
std::shared_ptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& foreign_key_value)
+Utils::type_list_values_with_second Utils::get_choice_values(const std::shared_ptr<const Document>& 
document, const std::shared_ptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& foreign_key_value)
 {
   //TODO: Reduce duplication between this and get_choice_values(field).
 
@@ -1079,7 +1079,7 @@ std::string Utils::sqlbuilder_get_full_query(
   return str;
 }
 
-Gnome::Gda::SqlExpr Utils::get_find_where_clause_quick(const Document* document, const Glib::ustring& 
table_name, const Gnome::Gda::Value& quick_search)
+Gnome::Gda::SqlExpr Utils::get_find_where_clause_quick(const std::shared_ptr<const Document>& document, 
const Glib::ustring& table_name, const Gnome::Gda::Value& quick_search)
 {
   if(table_name.empty())
   {
@@ -1467,7 +1467,7 @@ Glib::ustring Utils::get_temp_directory_uri(const std::string& prefix)
   }
 }
 
-LayoutGroup::type_list_const_items Utils::get_layout_items_plus_primary_key(const 
LayoutGroup::type_list_const_items& items, const Document* document, const Glib::ustring& table_name)
+LayoutGroup::type_list_const_items Utils::get_layout_items_plus_primary_key(const 
LayoutGroup::type_list_const_items& items, const std::shared_ptr<const Document>& document, const 
Glib::ustring& table_name)
 {
   if(!document)
   {
@@ -1495,7 +1495,7 @@ LayoutGroup::type_list_const_items Utils::get_layout_items_plus_primary_key(cons
 }
 
 //TODO: Avoid the horrible code duplication with the const version.
-LayoutGroup::type_list_items Utils::get_layout_items_plus_primary_key(const LayoutGroup::type_list_items& 
items, const Document* document, const Glib::ustring& table_name)
+LayoutGroup::type_list_items Utils::get_layout_items_plus_primary_key(const LayoutGroup::type_list_items& 
items, const std::shared_ptr<const Document>& document, const Glib::ustring& table_name)
 {
   if(!document)
   {
diff --git a/glom/libglom/utils.h b/glom/libglom/utils.h
index d12dcf7..501e8ed 100644
--- a/glom/libglom/utils.h
+++ b/glom/libglom/utils.h
@@ -124,7 +124,7 @@ Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_key(
  */
 Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_count_rows(const Glib::RefPtr<const 
Gnome::Gda::SqlBuilder>& sql_query);
 
-Gnome::Gda::SqlExpr get_find_where_clause_quick(const Document* document, const Glib::ustring& table_name, 
const Gnome::Gda::Value& quick_search);
+Gnome::Gda::SqlExpr get_find_where_clause_quick(const std::shared_ptr<const Document>& document, const 
Glib::ustring& table_name, const Gnome::Gda::Value& quick_search);
 
 /** Generate a SQL statement to UPDATE field values,
  */
@@ -135,9 +135,9 @@ Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_update_with_where_clause(
 
 typedef std::vector<Gnome::Gda::Value> type_list_values;
 typedef std::vector< std::pair<Gnome::Gda::Value, type_list_values> > type_list_values_with_second; //TODO: 
Rename this now that we have more than just 1 extra field.
-type_list_values_with_second get_choice_values_all(const Document* document, const std::shared_ptr<const 
LayoutItem_Field>& field);
+type_list_values_with_second get_choice_values_all(const std::shared_ptr<const Document>& document, const 
std::shared_ptr<const LayoutItem_Field>& field);
 
-type_list_values_with_second get_choice_values(const Document* document, const std::shared_ptr<const 
LayoutItem_Field>& field, const Gnome::Gda::Value& foreign_key_value);
+type_list_values_with_second get_choice_values(const std::shared_ptr<const Document>& document, const 
std::shared_ptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& foreign_key_value);
 
 /// Get the full query string suitable for use with std::cout.
 std::string sqlbuilder_get_full_query(
@@ -223,13 +223,13 @@ Glib::ustring get_list_of_sort_fields_for_display(const Formatting::type_list_so
 /** This returns the provided list of layout items,
  * plus the primary key, if the primary key is not already present in the list
  */
-LayoutGroup::type_list_const_items get_layout_items_plus_primary_key(const 
LayoutGroup::type_list_const_items& items, const Document* document, const Glib::ustring& table_name);
+LayoutGroup::type_list_const_items get_layout_items_plus_primary_key(const 
LayoutGroup::type_list_const_items& items, const std::shared_ptr<const Document>& document, const 
Glib::ustring& table_name);
 
 //TODO: Avoid the overload just for constness.
 /** This returns the provided list of layout items,
  * plus the primary key, if the primary key is not already present in the list
  */
-LayoutGroup::type_list_items get_layout_items_plus_primary_key(const LayoutGroup::type_list_items& items, 
const Document* document, const Glib::ustring& table_name);
+LayoutGroup::type_list_items get_layout_items_plus_primary_key(const LayoutGroup::type_list_items& items, 
const std::shared_ptr<const Document>& document, const Glib::ustring& table_name);
 
 std::string get_temp_file_path(const std::string& prefix = std::string(), const std::string& extension = 
std::string());
 Glib::ustring get_temp_file_uri(const std::string& prefix = std::string(), const std::string& extension = 
std::string());
diff --git a/glom/mode_data/box_data.cc b/glom/mode_data/box_data.cc
index a48ec5a..47cdc8c 100644
--- a/glom/mode_data/box_data.cc
+++ b/glom/mode_data/box_data.cc
@@ -170,7 +170,7 @@ void Box_Data::create_layout()
   set_unstored_data(false);
 
   //Cache the table information, for performance:
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
   m_TableFields = DbUtils::get_fields_for_table(document, m_table_name);
 }
 
@@ -238,7 +238,7 @@ Box_Data::type_vecConstLayoutFields Box_Data::get_fields_to_show() const
 
 Box_Data::type_vecConstLayoutFields Box_Data::get_table_fields_to_show(const Glib::ustring& table_name) const
 {
-  const auto pDoc = dynamic_cast<const Document*>(get_document());
+  const auto pDoc = std::dynamic_pointer_cast<const Document>(get_document());
   if(pDoc)
   {
     Document::type_list_layout_groups mapGroupSequence = 
pDoc->get_data_layout_groups_plus_new_fields(m_layout_name, table_name, m_layout_platform);
@@ -252,7 +252,7 @@ Document::type_list_layout_groups Box_Data::get_data_layout_groups(const Glib::u
 {
   Document::type_list_layout_groups layout_groups;
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document)
   {
     if(!m_table_name.empty())
diff --git a/glom/mode_data/box_data_details.cc b/glom/mode_data/box_data_details.cc
index c8228b0..fdfc4ed 100644
--- a/glom/mode_data/box_data_details.cc
+++ b/glom/mode_data/box_data_details.cc
@@ -215,7 +215,7 @@ void Box_Data_Details::create_layout()
   //Remove existing child widgets:
   m_FlowTable.remove_all();
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document)
   {
     m_FlowTable.set_table(m_table_name); //This allows portals to get full Relationship information
@@ -351,7 +351,7 @@ bool Box_Data_Details::fill_from_database()
 
         if((result && result->get_n_rows()) || primary_key_is_empty) //either a working result or no result 
needed.
         {
-          const auto pDoc = dynamic_cast<const Document*>(get_document());
+          const auto pDoc = std::dynamic_pointer_cast<const Document>(get_document());
           if(pDoc)
           {
             //Get glom-specific field info:
@@ -714,7 +714,7 @@ void Box_Data_Details::on_flowtable_field_edited(const std::shared_ptr<const Lay
 
   auto window = get_app_window();
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
 
   Gnome::Gda::Value primary_key_value = get_primary_key_value_selected();
   //std::cout << "debug: " << G_STRFUNC << ": primary_key_value=" << primary_key_value.to_string() << 
std::endl;
@@ -927,7 +927,7 @@ void Box_Data_Details::print_layout()
   if(!table_privs.m_view)
     return;  //TODO: Warn the user.
    
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
   if(!document)
   {
     std::cerr << G_STRFUNC << ": document was null" << std::endl;
diff --git a/glom/mode_data/box_data_list.cc b/glom/mode_data/box_data_list.cc
index 683a642..a085cb1 100644
--- a/glom/mode_data/box_data_list.cc
+++ b/glom/mode_data/box_data_list.cc
@@ -376,7 +376,7 @@ void Box_Data_List::create_layout()
 {
   Box_Data::create_layout(); //Fills m_TableFields.
 
-  const auto pDoc = dynamic_cast<const Document*>(get_document());
+  const auto pDoc = std::dynamic_pointer_cast<const Document>(get_document());
   if(!pDoc)
     return;
 
diff --git a/glom/mode_data/box_data_list_related.cc b/glom/mode_data/box_data_list_related.cc
index 3946e69..fa3a2e8 100644
--- a/glom/mode_data/box_data_list_related.cc
+++ b/glom/mode_data/box_data_list_related.cc
@@ -398,7 +398,7 @@ void Box_Data_List_Related::create_layout()
 {
   Box_Data::create_layout(); //Fills m_TableFields.
 
-  const auto pDoc = dynamic_cast<const Document*>(get_document());
+  const auto pDoc = std::dynamic_pointer_cast<const Document>(get_document());
   if(!pDoc)
     return;
 
diff --git a/glom/mode_data/datawidget/cellcreation.cc b/glom/mode_data/datawidget/cellcreation.cc
index ba907f0..52e1244 100644
--- a/glom/mode_data/datawidget/cellcreation.cc
+++ b/glom/mode_data/datawidget/cellcreation.cc
@@ -65,7 +65,7 @@ static void apply_formatting(Gtk::CellRenderer* renderer, const std::shared_ptr<
     text_renderer->property_background() = bg;
 }
 
-Gtk::CellRenderer* create_cell(const std::shared_ptr<const LayoutItem>& layout_item, const Glib::ustring& 
table_name, const Document* document, guint fixed_cell_height)
+Gtk::CellRenderer* create_cell(const std::shared_ptr<const LayoutItem>& layout_item, const Glib::ustring& 
table_name, const std::shared_ptr<const Document>& document, guint fixed_cell_height)
 {
   Gtk::CellRenderer* cell = nullptr;
 
diff --git a/glom/mode_data/datawidget/cellcreation.h b/glom/mode_data/datawidget/cellcreation.h
index f238611..173f265 100644
--- a/glom/mode_data/datawidget/cellcreation.h
+++ b/glom/mode_data/datawidget/cellcreation.h
@@ -30,7 +30,7 @@ namespace Glom
 /** Create a Gtk::CellRenderer that's appropriate to display a layout item,
  * for internal use by a DbAddDel or ComboChoices widget.
  */
-Gtk::CellRenderer* create_cell(const std::shared_ptr<const LayoutItem>& layout_item, const Glib::ustring& 
table_name, const Document* document, guint fixed_cell_height);
+Gtk::CellRenderer* create_cell(const std::shared_ptr<const LayoutItem>& layout_item, const Glib::ustring& 
table_name, const std::shared_ptr<const Document>& document, guint fixed_cell_height);
 
 } //namespace Glom
 
diff --git a/glom/mode_data/datawidget/cellrenderer_dblist.cc 
b/glom/mode_data/datawidget/cellrenderer_dblist.cc
index ba96991..acc4aca 100644
--- a/glom/mode_data/datawidget/cellrenderer_dblist.cc
+++ b/glom/mode_data/datawidget/cellrenderer_dblist.cc
@@ -49,7 +49,7 @@ void CellRendererDbList::set_choices_fixed(const Formatting::type_list_values& l
   //The other cells are added in on_editing_started().
 }
 
-void CellRendererDbList::set_choices_related(const Document* document, const std::shared_ptr<const 
LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value)
+void CellRendererDbList::set_choices_related(const std::shared_ptr<const Document>& document, const 
std::shared_ptr<const LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value)
 {
   ComboChoicesWithTreeModel::set_choices_related(document, layout_field, foreign_key_value);
 
diff --git a/glom/mode_data/datawidget/cellrenderer_dblist.h b/glom/mode_data/datawidget/cellrenderer_dblist.h
index 69548fd..a91a9e3 100644
--- a/glom/mode_data/datawidget/cellrenderer_dblist.h
+++ b/glom/mode_data/datawidget/cellrenderer_dblist.h
@@ -43,7 +43,7 @@ public:
   void set_choices_fixed(const Formatting::type_list_values& list_values, bool restricted = false) override;
 
   //This creates a db-based tree model, with appropriate cell renderers:
-  void set_choices_related(const Document* document, const std::shared_ptr<const LayoutItem_Field>& 
layout_field, const Gnome::Gda::Value& foreign_key_value) override;
+  void set_choices_related(const std::shared_ptr<const Document>& document, const std::shared_ptr<const 
LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value) override;
 
   void set_restrict_values_to_list(bool val = true);
 
@@ -62,7 +62,7 @@ private:
 
   bool m_repacked_first_cell;
 
-  const Document* m_document;
+  std::shared_ptr<const Document> m_document;
 };
 
 } //namespace Glom
diff --git a/glom/mode_data/datawidget/combo.cc b/glom/mode_data/datawidget/combo.cc
index a4cc76f..b94aa4e 100644
--- a/glom/mode_data/datawidget/combo.cc
+++ b/glom/mode_data/datawidget/combo.cc
@@ -150,7 +150,7 @@ void ComboGlom::set_choices_fixed(const Formatting::type_list_values& list_value
   }
 }
 
-void ComboGlom::set_choices_related(const Document* document, const std::shared_ptr<const LayoutItem_Field>& 
layout_field, const Gnome::Gda::Value& foreign_key_value)
+void ComboGlom::set_choices_related(const std::shared_ptr<const Document>& document, const 
std::shared_ptr<const LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value)
 {
   ComboChoicesWithTreeModel::set_choices_related(document, layout_field, foreign_key_value);
 
diff --git a/glom/mode_data/datawidget/combo.h b/glom/mode_data/datawidget/combo.h
index 64c94a6..566327c 100644
--- a/glom/mode_data/datawidget/combo.h
+++ b/glom/mode_data/datawidget/combo.h
@@ -51,7 +51,7 @@ public:
   void set_choices_fixed(const Formatting::type_list_values& list_values, bool restricted = false) override;
 
   //This creates a db-based tree model, with appropriate cell renderers:
-  void set_choices_related(const Document* document, const std::shared_ptr<const LayoutItem_Field>& 
layout_field, const Gnome::Gda::Value& foreign_key_value) override;
+  void set_choices_related(const std::shared_ptr<const Document>& document, const std::shared_ptr<const 
LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value) override;
 
   void set_read_only(bool read_only = true) override;
 
diff --git a/glom/mode_data/datawidget/combo_as_radio_buttons.cc 
b/glom/mode_data/datawidget/combo_as_radio_buttons.cc
index 448e1fb..f07ccd0 100644
--- a/glom/mode_data/datawidget/combo_as_radio_buttons.cc
+++ b/glom/mode_data/datawidget/combo_as_radio_buttons.cc
@@ -145,7 +145,7 @@ void ComboAsRadioButtons::set_choices_fixed(const Formatting::type_list_values&
   }
 }
 
-void ComboAsRadioButtons::set_choices_related(const Document* document, const std::shared_ptr<const 
LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value)
+void ComboAsRadioButtons::set_choices_related(const std::shared_ptr<const Document>& document, const 
std::shared_ptr<const LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value)
 {
   const Utils::type_list_values_with_second list_values =
     Utils::get_choice_values(document, layout_field, foreign_key_value);
diff --git a/glom/mode_data/datawidget/combo_as_radio_buttons.h 
b/glom/mode_data/datawidget/combo_as_radio_buttons.h
index f43ed62..abd7afa 100644
--- a/glom/mode_data/datawidget/combo_as_radio_buttons.h
+++ b/glom/mode_data/datawidget/combo_as_radio_buttons.h
@@ -52,7 +52,7 @@ public:
 
   void set_choices_fixed(const Formatting::type_list_values& list_values, bool restricted = false) override;
 
-  void set_choices_related(const Document* document, const std::shared_ptr<const LayoutItem_Field>& 
layout_field, const Gnome::Gda::Value& foreign_key_value) override;
+  void set_choices_related(const std::shared_ptr<const Document>& document, const std::shared_ptr<const 
LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value) override;
 
   void set_read_only(bool read_only = true) override;
 
diff --git a/glom/mode_data/datawidget/combochoices.cc b/glom/mode_data/datawidget/combochoices.cc
index 1f5d1d9..8e011b4 100644
--- a/glom/mode_data/datawidget/combochoices.cc
+++ b/glom/mode_data/datawidget/combochoices.cc
@@ -41,7 +41,7 @@ ComboChoices::ComboChoices()
 {
 }
 
-bool ComboChoices::refresh_data_from_database_with_foreign_key(const Document* /* document */, const 
Gnome::Gda::Value& /* foreign_key_value */)
+bool ComboChoices::refresh_data_from_database_with_foreign_key(const std::shared_ptr<const Document>& /* 
document */, const Gnome::Gda::Value& /* foreign_key_value */)
 {
   /** TODO:
   auto layout_item =
@@ -64,7 +64,7 @@ bool ComboChoices::refresh_data_from_database_with_foreign_key(const Document* /
   return true;
 }
 
-void ComboChoices::set_choices_related(const Document* /* document */, const std::shared_ptr<const 
LayoutItem_Field>& /* layout_field */, const Gnome::Gda::Value& /* foreign_key_value */)
+void ComboChoices::set_choices_related(const std::shared_ptr<const Document>& /* document */, const 
std::shared_ptr<const LayoutItem_Field>& /* layout_field */, const Gnome::Gda::Value& /* foreign_key_value */)
 {
   /* TODO:
   type_list_values_with_second list_values;
diff --git a/glom/mode_data/datawidget/combochoices.h b/glom/mode_data/datawidget/combochoices.h
index a42e067..503423b 100644
--- a/glom/mode_data/datawidget/combochoices.h
+++ b/glom/mode_data/datawidget/combochoices.h
@@ -56,13 +56,13 @@ public:
    *
    * See also refresh_data_from_database_with_foreign_key().
    */
-  virtual void set_choices_related(const Document* document, const std::shared_ptr<const LayoutItem_Field>& 
layout_field, const Gnome::Gda::Value& foreign_key_value) = 0;
+  virtual void set_choices_related(const std::shared_ptr<const Document>& document, const 
std::shared_ptr<const LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value) = 0;
 
   /** Update a choices widget's list of related choices if a relevant value in its parent table has changed.
    *
    * @param foreign_key_value: The value that should be found in this table.
    */
-  bool refresh_data_from_database_with_foreign_key(const Document* document, const Gnome::Gda::Value& 
foreign_key_value);
+  bool refresh_data_from_database_with_foreign_key(const std::shared_ptr<const Document>& document, const 
Gnome::Gda::Value& foreign_key_value);
 
 protected:
 
diff --git a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc 
b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
index aa8fba4..2a4212d 100644
--- a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
+++ b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
@@ -245,7 +245,7 @@ void ComboChoicesWithTreeModel::set_choices_fixed(const Formatting::type_list_va
   //then sets up the view, using the model.
 }
 
-void ComboChoicesWithTreeModel::set_choices_related(const Document* document, const std::shared_ptr<const 
LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value)
+void ComboChoicesWithTreeModel::set_choices_related(const std::shared_ptr<const Document>& document, const 
std::shared_ptr<const LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value)
 {
   if(!document)
   {
diff --git a/glom/mode_data/datawidget/combochoiceswithtreemodel.h 
b/glom/mode_data/datawidget/combochoiceswithtreemodel.h
index 40d7976..c9a5099 100644
--- a/glom/mode_data/datawidget/combochoiceswithtreemodel.h
+++ b/glom/mode_data/datawidget/combochoiceswithtreemodel.h
@@ -43,7 +43,7 @@ public:
   void set_choices_fixed(const Formatting::type_list_values& list_values, bool restricted = false) override;
 
   //This creates a db-based tree model, with appropriate cell renderers:
-  void set_choices_related(const Document* document, const std::shared_ptr<const LayoutItem_Field>& 
layout_field, const Gnome::Gda::Value& foreign_key_value) override;
+  void set_choices_related(const std::shared_ptr<const Document>& document, const std::shared_ptr<const 
LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value) override;
 
 
   //Not named get_model(), to avoid clashing with ComboBox::get_model().
diff --git a/glom/mode_data/datawidget/datawidget.cc b/glom/mode_data/datawidget/datawidget.cc
index 5d569af..0f90ae9 100644
--- a/glom/mode_data/datawidget/datawidget.cc
+++ b/glom/mode_data/datawidget/datawidget.cc
@@ -61,7 +61,7 @@ static DataWidgetChildren::ComboChoices* create_combo_widget_for_field(const std
   return result;
 }
 
-DataWidget::DataWidget(const std::shared_ptr<LayoutItem_Field>& field, const Glib::ustring& table_name, 
const Document* document)
+DataWidget::DataWidget(const std::shared_ptr<LayoutItem_Field>& field, const Glib::ustring& table_name, 
const std::shared_ptr<const Document>& document)
 :  m_child(nullptr),
    m_button_go_to_details(nullptr)
 {
@@ -461,7 +461,7 @@ std::shared_ptr<LayoutItem_Field> DataWidget::offer_field_list(const Glib::ustri
   return offer_field_list(table_name, start_field, get_document(), get_appwindow());
 }
 
-std::shared_ptr<LayoutItem_Field> DataWidget::offer_field_list(const Glib::ustring& table_name, const 
std::shared_ptr<const LayoutItem_Field>& start_field, Document* document, AppWindow* app)
+std::shared_ptr<LayoutItem_Field> DataWidget::offer_field_list(const Glib::ustring& table_name, const 
std::shared_ptr<const LayoutItem_Field>& start_field, const std::shared_ptr<Document>& document, AppWindow* 
app)
 {
   std::shared_ptr<LayoutItem_Field> result;
 
diff --git a/glom/mode_data/datawidget/datawidget.h b/glom/mode_data/datawidget/datawidget.h
index 91de7e0..59daf0c 100644
--- a/glom/mode_data/datawidget/datawidget.h
+++ b/glom/mode_data/datawidget/datawidget.h
@@ -44,7 +44,7 @@ class DataWidget
    public View_Composite_Glom
 {
 public:
-  explicit DataWidget(const std::shared_ptr<LayoutItem_Field>& field, const Glib::ustring& table_name, const 
Document* document);
+  explicit DataWidget(const std::shared_ptr<LayoutItem_Field>& field, const Glib::ustring& table_name, const 
std::shared_ptr<const Document>& document);
 
   Gtk::Label* get_label();
   const Gtk::Label* get_label() const;
@@ -61,7 +61,7 @@ public:
   void set_viewable(bool viewable = true);
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
-  static std::shared_ptr<LayoutItem_Field> offer_field_list(const Glib::ustring& table_name, const 
std::shared_ptr<const LayoutItem_Field>& start_field, Document* document, AppWindow* app);
+  static std::shared_ptr<LayoutItem_Field> offer_field_list(const Glib::ustring& table_name, const 
std::shared_ptr<const LayoutItem_Field>& start_field, const std::shared_ptr<Document>& document, AppWindow* 
app);
   std::shared_ptr<LayoutItem_Field> offer_field_list(const Glib::ustring& table_name);
   std::shared_ptr<LayoutItem_Field> offer_field_list(const Glib::ustring& table_name, const 
std::shared_ptr<const LayoutItem_Field>& start_field);
 
diff --git a/glom/mode_data/datawidget/dialog_choose_id.h b/glom/mode_data/datawidget/dialog_choose_id.h
index 03a6fdd..6337c21 100644
--- a/glom/mode_data/datawidget/dialog_choose_id.h
+++ b/glom/mode_data/datawidget/dialog_choose_id.h
@@ -74,7 +74,7 @@ private:
   Glib::ustring m_table_name;
   Glib::ustring m_layout_platform;
 
-  Document* m_document;
+  std::shared_ptr<Document> m_document;
   Gnome::Gda::Value m_id_chosen;
 
   Box_Data_Details_Find m_box_find;
diff --git a/glom/mode_data/db_adddel/db_adddel.cc b/glom/mode_data/db_adddel/db_adddel.cc
index 50d3117..26f1f2d 100644
--- a/glom/mode_data/db_adddel/db_adddel.cc
+++ b/glom/mode_data/db_adddel/db_adddel.cc
@@ -2121,7 +2121,7 @@ void DbAddDel::user_changed(const Gtk::TreeModel::iterator& row, guint col)
         //plus how to identify the record in that table.
         const auto relationship_name = layout_field->get_relationship_name();
 
-        auto document = dynamic_cast<Document*>(get_document());
+        auto document = std::dynamic_pointer_cast<Document>(get_document());
 
         auto relationship = document->get_relationship(m_found_set.m_table_name, relationship_name);
         if(relationship)
diff --git a/glom/mode_data/flowtablewithfields.cc b/glom/mode_data/flowtablewithfields.cc
index e76182b..964a30a 100644
--- a/glom/mode_data/flowtablewithfields.cc
+++ b/glom/mode_data/flowtablewithfields.cc
@@ -256,8 +256,8 @@ Box_Data_List_Related* FlowTableWithFields::create_related(const std::shared_ptr
   if(!portal)
     return nullptr;
 
-  auto pDocument = static_cast<Document*>(get_document());
-  if(pDocument)
+  auto document = std::static_pointer_cast<Document>(get_document());
+  if(document)
   {
     auto portal_box = Gtk::manage(new Box_Data_List_Related);
     portal_box->set_find_mode(m_find_mode);
@@ -270,7 +270,7 @@ Box_Data_List_Related* FlowTableWithFields::create_related(const std::shared_ptr
       portal_box->init_db_details(m_table_name, show_title);
 
     Glib::ustring to_table;
-    auto relationship = pDocument->get_relationship(m_table_name, portal->get_relationship_name());
+    auto relationship = document->get_relationship(m_table_name, portal->get_relationship_name());
     if(relationship)
       to_table = relationship->get_to_table();
 
@@ -296,8 +296,8 @@ Box_Data_Calendar_Related* FlowTableWithFields::create_related_calendar(const st
   if(!portal)
     return nullptr;
 
-  auto pDocument = static_cast<Document*>(get_document());
-  if(pDocument)
+  auto document = std::static_pointer_cast<Document>(get_document());
+  if(document)
   {
     auto portal_box = Gtk::manage(new Box_Data_Calendar_Related);
     portal_box->set_find_mode(m_find_mode); //TODO: Implement this in the class
@@ -310,7 +310,7 @@ Box_Data_Calendar_Related* FlowTableWithFields::create_related_calendar(const st
       portal_box->init_db_details(m_table_name, show_title);
 
     Glib::ustring to_table;
-    auto relationship = pDocument->get_relationship(m_table_name, portal->get_relationship_name());
+    auto relationship = document->get_relationship(m_table_name, portal->get_relationship_name());
     if(relationship)
       to_table = relationship->get_to_table();
 
@@ -1328,8 +1328,8 @@ std::shared_ptr<LayoutItem_Portal> FlowTableWithFields::get_portal_relationship(
   if(!dialog) //Unlikely and it already warns on stderr.
     return std::shared_ptr<LayoutItem_Portal>();
 
-  Document* pDocument = static_cast<Document*>(get_document());
-  dialog->set_document(pDocument, m_table_name);
+  auto document = std::static_pointer_cast<Document>(get_document());
+  dialog->set_document(document, m_table_name);
   //TODO: dialog->set_transient_for(*get_app_window());
   const auto response = dialog->run();
   dialog->hide();
diff --git a/glom/mode_design/dialog_design.cc b/glom/mode_design/dialog_design.cc
index 3a20609..4e0bba1 100644
--- a/glom/mode_design/dialog_design.cc
+++ b/glom/mode_design/dialog_design.cc
@@ -49,7 +49,7 @@ bool Dialog_Design::init_db_details(const Glib::ustring& table_name)
     Glib::ustring table_label = _("None selected");
 
     //Show the table title (if any) and name:
-     auto document = dynamic_cast<Document*>(get_document());
+     auto document = std::dynamic_pointer_cast<Document>(get_document());
      if(document)
      {
        Glib::ustring table_title = document->get_table_title(table_name, AppWindow::get_current_locale());
diff --git a/glom/mode_design/fields/box_db_table_definition.cc 
b/glom/mode_design/fields/box_db_table_definition.cc
index 97cc5a3..0cacf23 100644
--- a/glom/mode_design/fields/box_db_table_definition.cc
+++ b/glom/mode_design/fields/box_db_table_definition.cc
@@ -212,7 +212,7 @@ void Box_DB_Table_Definition::on_adddel_add(const Gtk::TreeModel::iterator& row)
       // unnecessary extra stuff just to get the field added into the
       // document:
 
-      auto pDoc = static_cast<Document*>(get_document());
+      auto pDoc = std::static_pointer_cast<Document>(get_document());
       if(pDoc)
       {
         std::cout << Utils::to_utype(field->get_glom_type()) << std::endl;
@@ -364,7 +364,7 @@ bool Box_DB_Table_Definition::check_field_change(const std::shared_ptr<const Fie
 void Box_DB_Table_Definition::on_adddel_changed(const Gtk::TreeModel::iterator& row, guint /* col */)
 {
   //Get old field definition:
-  auto pDoc = static_cast<Document*>(get_document());
+  auto pDoc = std::static_pointer_cast<Document>(get_document());
   if(pDoc)
   {
     const auto strFieldNameBeingEdited = m_AddDel.get_value_key(row);
@@ -449,7 +449,7 @@ std::shared_ptr<Field> Box_DB_Table_Definition::get_field_definition(const Gtk::
   const auto strFieldNameBeforeEdit = m_AddDel.get_value_key(row);
 
   //Glom field definition:
-  auto pDoc = static_cast<Document*>(get_document());
+  auto pDoc = std::static_pointer_cast<Document>(get_document());
   if(pDoc)
   {
     Document::type_vec_fields vecFields= pDoc->get_table_fields(m_table_name);
@@ -598,7 +598,7 @@ std::shared_ptr<Field> Box_DB_Table_Definition::change_definition(const std::sha
   }
 
   //Extra Glom field definitions:
-  auto pDoc = static_cast<Document*>(get_document());
+  auto pDoc = std::static_pointer_cast<Document>(get_document());
   if(pDoc)
   {
     //Get Table's fields:
diff --git a/glom/mode_design/fields/dialog_fielddefinition.cc 
b/glom/mode_design/fields/dialog_fielddefinition.cc
index 8cb52ef..2dd3c00 100644
--- a/glom/mode_design/fields/dialog_fielddefinition.cc
+++ b/glom/mode_design/fields/dialog_fielddefinition.cc
@@ -168,7 +168,7 @@ void Dialog_FieldDefinition::set_field(const std::shared_ptr<const Field>& field
   on_check_lookup_toggled();
 
   //Fill the lookup relationships combo:
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document)
   {
     //Get the relationships used by this table, excluding relationships triggered
@@ -343,7 +343,7 @@ void Dialog_FieldDefinition::on_combo_lookup_relationship_changed()
   if(relationship)
   {
     //Get the relationship details:
-    auto document = dynamic_cast<Document*>(get_document());
+    auto document = std::dynamic_pointer_cast<Document>(get_document());
     if(document)
     {
       const auto to_table = relationship->get_to_table();
diff --git a/glom/mode_design/layout/combobox_fields.cc b/glom/mode_design/layout/combobox_fields.cc
index c4da945..dd59205 100644
--- a/glom/mode_design/layout/combobox_fields.cc
+++ b/glom/mode_design/layout/combobox_fields.cc
@@ -102,7 +102,7 @@ void ComboBox_Fields::set_selected_field(const Glib::ustring& field_name)
     unset_active();
 }
 
-void ComboBox_Fields::set_fields(Document* document, const Glib::ustring parent_table_name)
+void ComboBox_Fields::set_fields(const std::shared_ptr<Document>& document, const Glib::ustring 
parent_table_name)
 {
   if(!document)
     return;
@@ -124,7 +124,7 @@ void ComboBox_Fields::set_fields(Document* document, const Glib::ustring parent_
   }
 }
 
-void ComboBox_Fields::set_fields(Document* document, const Glib::ustring parent_table_name, 
Field::glom_field_type field_type)
+void ComboBox_Fields::set_fields(const std::shared_ptr<Document>& document, const Glib::ustring 
parent_table_name, Field::glom_field_type field_type)
 {
   if(!document)
     return;
diff --git a/glom/mode_design/layout/combobox_fields.h b/glom/mode_design/layout/combobox_fields.h
index dcda90a..144a4c8 100644
--- a/glom/mode_design/layout/combobox_fields.h
+++ b/glom/mode_design/layout/combobox_fields.h
@@ -50,14 +50,14 @@ public:
    * @param parent_table_name The table whose fields should be shown.
    * @param field_type Show only fields of this type.
    */
-  void set_fields(Document* document, const Glib::ustring parent_table_name);
+  void set_fields(const std::shared_ptr<Document>& document, const Glib::ustring parent_table_name);
     
   /** Fill the combo box with fields, but only fields of a certain type.
    * @param document The Document, used to get the list of fields.
    * @param parent_table_name The table whose fields should be shown.
    * @param field_type Show only fields of this type.
    */
-  void set_fields(Document* document, const Glib::ustring parent_table_name, Field::glom_field_type 
field_type);
+  void set_fields(const std::shared_ptr<Document>& document, const Glib::ustring parent_table_name, 
Field::glom_field_type field_type);
 
   void set_selected_field(const std::shared_ptr<const Field>& field);
   void set_selected_field(const Glib::ustring& field_name);
diff --git a/glom/mode_design/layout/combobox_relationship.cc 
b/glom/mode_design/layout/combobox_relationship.cc
index a2031d0..f88c027 100644
--- a/glom/mode_design/layout/combobox_relationship.cc
+++ b/glom/mode_design/layout/combobox_relationship.cc
@@ -145,7 +145,7 @@ void ComboBox_Relationship::set_selected_relationship(const Glib::ustring& relat
     unset_active();
 }
 
-void ComboBox_Relationship::set_relationships(Document* document, const Glib::ustring parent_table_name, 
bool show_related_relationships, bool show_parent_table_name)
+void ComboBox_Relationship::set_relationships(const std::shared_ptr<Document>& document, const Glib::ustring 
parent_table_name, bool show_related_relationships, bool show_parent_table_name)
 {
   if(!document)
     return;
diff --git a/glom/mode_design/layout/combobox_relationship.h b/glom/mode_design/layout/combobox_relationship.h
index df06560..88864c1 100644
--- a/glom/mode_design/layout/combobox_relationship.h
+++ b/glom/mode_design/layout/combobox_relationship.h
@@ -42,7 +42,7 @@ public:
 
   void set_relationships_excluding_triggered_by(const type_vec_relationships& relationship, const 
Glib::ustring& excluding_triggered_by_field);
 
-  void set_relationships(Document* document, const Glib::ustring parent_table_name, bool 
show_related_relationships = false, bool show_parent_table = true);
+  void set_relationships(const std::shared_ptr<Document>& document, const Glib::ustring parent_table_name, 
bool show_related_relationships = false, bool show_parent_table = true);
 
   void set_selected_relationship(const std::shared_ptr<const Relationship>& relationship);
   void set_selected_relationship(const std::shared_ptr<const Relationship>& relationship, const 
std::shared_ptr<const Relationship>& related_relationship);
diff --git a/glom/mode_design/layout/dialog_choose_field.cc b/glom/mode_design/layout/dialog_choose_field.cc
index 00a7fe1..8d9e90c 100644
--- a/glom/mode_design/layout/dialog_choose_field.cc
+++ b/glom/mode_design/layout/dialog_choose_field.cc
@@ -73,7 +73,7 @@ Dialog_ChooseField::Dialog_ChooseField(BaseObjectType* cobject, const Glib::RefP
   show_all_children();
 }
 
-void Dialog_ChooseField::set_document(Document* document, const Glib::ustring& table_name, const 
std::shared_ptr<const LayoutItem_Field>& field)
+void Dialog_ChooseField::set_document(const std::shared_ptr<Document>& document, const Glib::ustring& 
table_name, const std::shared_ptr<const LayoutItem_Field>& field)
 {
   set_document(document, table_name);
 
@@ -124,7 +124,7 @@ void Dialog_ChooseField::set_document(Document* document, const Glib::ustring& t
   }
 }
 
-void Dialog_ChooseField::set_document(Document* document, const Glib::ustring& table_name)
+void Dialog_ChooseField::set_document(const std::shared_ptr<Document>& document, const Glib::ustring& 
table_name)
 {
   m_document = document;
   m_table_name = table_name;
@@ -301,17 +301,17 @@ void Dialog_ChooseField::on_combo_relationship_changed()
 {
   auto relationship = m_combo_relationship->get_selected_relationship();
 
-  auto pDocument = m_document;
-  if(pDocument)
+  auto document = m_document;
+  if(document)
   {
     //Show the list of fields from this relationship:
 
     Document::type_vec_fields vecFields;
     if(!relationship)
-      vecFields = pDocument->get_table_fields(m_table_name);
+      vecFields = document->get_table_fields(m_table_name);
     else
     {
-      vecFields = pDocument->get_table_fields(relationship->get_to_table());
+      vecFields = document->get_table_fields(relationship->get_to_table());
     }
 
     m_model->clear();
diff --git a/glom/mode_design/layout/dialog_choose_field.h b/glom/mode_design/layout/dialog_choose_field.h
index a5b7bcd..dc72179 100644
--- a/glom/mode_design/layout/dialog_choose_field.h
+++ b/glom/mode_design/layout/dialog_choose_field.h
@@ -45,8 +45,8 @@ public:
    * @param table_name The table name.
    * @param field The starting field information.
    */
-  void set_document(Document* document, const Glib::ustring& table_name, const std::shared_ptr<const 
LayoutItem_Field>& field);
-  void set_document(Document* document, const Glib::ustring& table_name);
+  void set_document(const std::shared_ptr<Document>& document, const Glib::ustring& table_name, const 
std::shared_ptr<const LayoutItem_Field>& field);
+  void set_document(const std::shared_ptr<Document>& document, const Glib::ustring& table_name);
 
 
   //void select_item(const std::shared_ptr<const Field>& field);
@@ -87,7 +87,7 @@ private:
   Glib::ustring m_table_name;
   std::shared_ptr<LayoutItem_Field> m_start_field; //stored so we can preserve extra information that's not 
changed here.
 
-  Document* m_document;
+  std::shared_ptr<Document> m_document;
 };
 
 } //namespace Glom
diff --git a/glom/mode_design/layout/dialog_choose_relationship.cc 
b/glom/mode_design/layout/dialog_choose_relationship.cc
index aab7b08..79db5b6 100644
--- a/glom/mode_design/layout/dialog_choose_relationship.cc
+++ b/glom/mode_design/layout/dialog_choose_relationship.cc
@@ -59,7 +59,7 @@ Dialog_ChooseRelationship::Dialog_ChooseRelationship(BaseObjectType* cobject, co
   show_all_children();
 }
 
-void Dialog_ChooseRelationship::set_document(Document* document, const Glib::ustring& table_name)
+void Dialog_ChooseRelationship::set_document(const std::shared_ptr<Document>& document, const Glib::ustring& 
table_name)
 {
   m_document = document;
   m_table_name = table_name;
diff --git a/glom/mode_design/layout/dialog_choose_relationship.h 
b/glom/mode_design/layout/dialog_choose_relationship.h
index f39174b..6b015ba 100644
--- a/glom/mode_design/layout/dialog_choose_relationship.h
+++ b/glom/mode_design/layout/dialog_choose_relationship.h
@@ -42,7 +42,7 @@ public:
    * @param document The document, so that the dialog can load the previous layout, and save changes.
    * @param table_name The table name.
    */
-  void set_document(Document* document, const Glib::ustring& table_name);
+  void set_document(const std::shared_ptr<Document>& document, const Glib::ustring& table_name);
 
   void select_item(const std::shared_ptr<const Relationship>& relationship);
 
@@ -72,7 +72,7 @@ private:
 
   Glib::ustring m_table_name;
 
-  Document* m_document;
+  std::shared_ptr<Document> m_document;
 };
 
 } //namespace Glom
diff --git a/glom/mode_design/layout/dialog_layout.cc b/glom/mode_design/layout/dialog_layout.cc
index d62ed2e..03affab 100644
--- a/glom/mode_design/layout/dialog_layout.cc
+++ b/glom/mode_design/layout/dialog_layout.cc
@@ -47,7 +47,7 @@ Dialog_Layout::Dialog_Layout(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Bu
   show_all_children();
 }
 
-void Dialog_Layout::init(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, Document* 
/* document */, const Glib::ustring& table_name, const type_vecConstLayoutFields& /* table_fields */)
+void Dialog_Layout::init(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, const 
std::shared_ptr<Document>& /* document */, const Glib::ustring& table_name, const type_vecConstLayoutFields& 
/* table_fields */)
 {
   m_modified = false;
 
diff --git a/glom/mode_design/layout/dialog_layout.h b/glom/mode_design/layout/dialog_layout.h
index a7e5ebe..efd5c47 100644
--- a/glom/mode_design/layout/dialog_layout.h
+++ b/glom/mode_design/layout/dialog_layout.h
@@ -46,7 +46,7 @@ public:
    * @param table_name The table name.
    * @param table_fields: The actual fields in the table, in case the document does not yet know about them 
all.
    */
-  virtual void init(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, Document* 
document, const Glib::ustring& table_name, const type_vecConstLayoutFields& table_fields);
+  virtual void init(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, const 
std::shared_ptr<Document>& document, const Glib::ustring& table_name, const type_vecConstLayoutFields& 
table_fields);
   
 protected:
 
diff --git a/glom/mode_design/layout/dialog_layout_calendar_related.cc 
b/glom/mode_design/layout/dialog_layout_calendar_related.cc
index 189d0be..e9a8b51 100644
--- a/glom/mode_design/layout/dialog_layout_calendar_related.cc
+++ b/glom/mode_design/layout/dialog_layout_calendar_related.cc
@@ -100,7 +100,7 @@ Dialog_Layout_Calendar_Related::Dialog_Layout_Calendar_Related(BaseObjectType* c
     m_label_table_title->hide(); // We don't use this (it's from the base class).
 }
 
-void Dialog_Layout_Calendar_Related::init_with_portal(const Glib::ustring& layout, const Glib::ustring& 
layout_platform, Document* document, const std::shared_ptr<const LayoutItem_CalendarPortal>& portal)
+void Dialog_Layout_Calendar_Related::init_with_portal(const Glib::ustring& layout, const Glib::ustring& 
layout_platform, const std::shared_ptr<Document>& document, const std::shared_ptr<const 
LayoutItem_CalendarPortal>& portal)
 {
   m_portal = glom_sharedptr_clone(portal);
 
@@ -111,7 +111,7 @@ void Dialog_Layout_Calendar_Related::init_with_portal(const Glib::ustring& layou
   init_with_tablename(layout, layout_platform, document, from_table);
 }
 
-void Dialog_Layout_Calendar_Related::init_with_tablename(const Glib::ustring& layout_name, const 
Glib::ustring& layout_platform, Document* document, const Glib::ustring& from_table)
+void Dialog_Layout_Calendar_Related::init_with_tablename(const Glib::ustring& layout_name, const 
Glib::ustring& layout_platform, const std::shared_ptr<Document>& document, const Glib::ustring& from_table)
 {
   if(!m_portal)
   {
diff --git a/glom/mode_design/layout/dialog_layout_calendar_related.h 
b/glom/mode_design/layout/dialog_layout_calendar_related.h
index 293d071..820371b 100644
--- a/glom/mode_design/layout/dialog_layout_calendar_related.h
+++ b/glom/mode_design/layout/dialog_layout_calendar_related.h
@@ -45,9 +45,9 @@ public:
    * @param table_name The table name.
    * @param table_fields: The actual fields in the table, in case the document does not yet know about them 
all.
    */
-  void init_with_portal(const Glib::ustring& layout, const Glib::ustring& layout_platform, Document* 
document, const std::shared_ptr<const LayoutItem_CalendarPortal>& portal);
+  void init_with_portal(const Glib::ustring& layout, const Glib::ustring& layout_platform, const 
std::shared_ptr<Document>& document, const std::shared_ptr<const LayoutItem_CalendarPortal>& portal);
 
-  void init_with_tablename(const Glib::ustring& layout, const Glib::ustring& layout_platform, Document* 
document, const Glib::ustring& parent_table);
+  void init_with_tablename(const Glib::ustring& layout, const Glib::ustring& layout_platform, const 
std::shared_ptr<Document>& document, const Glib::ustring& parent_table);
 
   void update_ui(bool including_relationships_list = true);
 
diff --git a/glom/mode_design/layout/dialog_layout_details.cc 
b/glom/mode_design/layout/dialog_layout_details.cc
index d170664..1a251f1 100644
--- a/glom/mode_design/layout/dialog_layout_details.cc
+++ b/glom/mode_design/layout/dialog_layout_details.cc
@@ -321,7 +321,7 @@ void Dialog_Layout_Details::add_group(const Gtk::TreeModel::iterator& parent, co
   }
 }
 
-void Dialog_Layout_Details::init(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, 
Document* document, const Glib::ustring& table_name, const type_vecConstLayoutFields& table_fields)
+void Dialog_Layout_Details::init(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, 
const std::shared_ptr<Document>& document, const Glib::ustring& table_name, const type_vecConstLayoutFields& 
table_fields)
 {
   m_modified = false;
 
diff --git a/glom/mode_design/layout/dialog_layout_details.h b/glom/mode_design/layout/dialog_layout_details.h
index 8f54cc9..713cf81 100644
--- a/glom/mode_design/layout/dialog_layout_details.h
+++ b/glom/mode_design/layout/dialog_layout_details.h
@@ -44,7 +44,7 @@ public:
    * @param table_name The table name.
    * @param table_fields: The actual fields in the table, in case the document does not yet know about them 
all.
    */
-  void init(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, Document* document, 
const Glib::ustring& table_name, const type_vecConstLayoutFields& table_fields) override;
+  void init(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, const 
std::shared_ptr<Document>& document, const Glib::ustring& table_name, const type_vecConstLayoutFields& 
table_fields) override;
 
 protected:
 
diff --git a/glom/mode_design/layout/dialog_layout_export.cc b/glom/mode_design/layout/dialog_layout_export.cc
index d6c582f..f46a790 100644
--- a/glom/mode_design/layout/dialog_layout_export.cc
+++ b/glom/mode_design/layout/dialog_layout_export.cc
@@ -93,7 +93,7 @@ Dialog_Layout_Export::Dialog_Layout_Export(BaseObjectType* cobject, const Glib::
   show_all_children();
 }
 
-void Dialog_Layout_Export::set_layout_groups(Document::type_list_layout_groups& mapGroups, Document* 
document, const Glib::ustring& table_name)
+void Dialog_Layout_Export::set_layout_groups(Document::type_list_layout_groups& mapGroups, const 
std::shared_ptr<Document>& document, const Glib::ustring& table_name)
 {
   Base_DB::set_document(document);
 
diff --git a/glom/mode_design/layout/dialog_layout_export.h b/glom/mode_design/layout/dialog_layout_export.h
index 0967719..c15f705 100644
--- a/glom/mode_design/layout/dialog_layout_export.h
+++ b/glom/mode_design/layout/dialog_layout_export.h
@@ -40,7 +40,7 @@ public:
    * @param table_name The table name.
    * @param table_fields: The actual fields in the table, in case the document does not yet know about them 
all.
    */
-  void set_layout_groups(Document::type_list_layout_groups& mapGroups, Document* document, const 
Glib::ustring& table_name);
+  void set_layout_groups(Document::type_list_layout_groups& mapGroups, const std::shared_ptr<Document>& 
document, const Glib::ustring& table_name);
 
   void get_layout_groups(Document::type_list_layout_groups& layout_groups) const;
 
diff --git a/glom/mode_design/layout/dialog_layout_list_related.cc 
b/glom/mode_design/layout/dialog_layout_list_related.cc
index 617b601..9303e6f 100644
--- a/glom/mode_design/layout/dialog_layout_list_related.cc
+++ b/glom/mode_design/layout/dialog_layout_list_related.cc
@@ -128,7 +128,7 @@ Dialog_Layout_List_Related::Dialog_Layout_List_Related(BaseObjectType* cobject,
     m_label_table_title->hide(); // We don't use this (it's from the base class).
 }
 
-void Dialog_Layout_List_Related::init_with_portal(const Glib::ustring& layout_name, const Glib::ustring& 
layout_platform, Document* document, const std::shared_ptr<const LayoutItem_Portal>& portal, const 
Glib::ustring& from_table, bool for_print_layout)
+void Dialog_Layout_List_Related::init_with_portal(const Glib::ustring& layout_name, const Glib::ustring& 
layout_platform, const std::shared_ptr<Document>& document, const std::shared_ptr<const LayoutItem_Portal>& 
portal, const Glib::ustring& from_table, bool for_print_layout)
 {
   m_for_print_layout = for_print_layout;
 
diff --git a/glom/mode_design/layout/dialog_layout_list_related.h 
b/glom/mode_design/layout/dialog_layout_list_related.h
index 06386d5..2d41608 100644
--- a/glom/mode_design/layout/dialog_layout_list_related.h
+++ b/glom/mode_design/layout/dialog_layout_list_related.h
@@ -45,7 +45,7 @@ public:
    * @param portal The layout item, which knows its from_table, for instance.
    * @apram for_print_layout If true, don't show the navigation options, for instance.
    */
-  void init_with_portal(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, Document* 
document, const std::shared_ptr<const LayoutItem_Portal>& portal, const Glib::ustring& from_table, bool 
for_print_layout = false);
+  void init_with_portal(const Glib::ustring& layout_name, const Glib::ustring& layout_platform, const 
std::shared_ptr<Document>& document, const std::shared_ptr<const LayoutItem_Portal>& portal, const 
Glib::ustring& from_table, bool for_print_layout = false);
 
   void update_ui(bool including_relationships_list = true);
 
diff --git a/glom/mode_design/layout/layout_item_dialogs/box_formatting.cc 
b/glom/mode_design/layout/layout_item_dialogs/box_formatting.cc
index e01e1dd..1a49c38 100644
--- a/glom/mode_design/layout/layout_item_dialogs/box_formatting.cc
+++ b/glom/mode_design/layout/layout_item_dialogs/box_formatting.cc
@@ -441,19 +441,19 @@ void Box_Formatting::on_combo_choices_relationship_changed()
 {
   auto relationship = m_combo_choices_relationship->get_selected_relationship();
 
-  auto pDocument = get_document();
-  if(pDocument)
+  auto document = get_document();
+  if(document)
   {
     //Show the list of fields from this relationship:
     if(relationship)
     {
       const auto related_table = relationship->get_to_table();
-      const auto vecFields = pDocument->get_table_fields(related_table);
+      const auto vecFields = document->get_table_fields(related_table);
       m_combo_choices_field->set_fields(vecFields);
 
       //Default to using the Primary Key field from the related table,
       //because this is almost always what people want to use:
-      const auto related_primary_key = pDocument->get_field_primary_key(related_table);
+      const auto related_primary_key = document->get_field_primary_key(related_table);
       if(related_primary_key)
         m_combo_choices_field->set_selected_field(related_primary_key);
 
diff --git a/glom/mode_design/print_layouts/window_print_layout_edit.cc 
b/glom/mode_design/print_layouts/window_print_layout_edit.cc
index d4b6cab..97112b5 100644
--- a/glom/mode_design/print_layouts/window_print_layout_edit.cc
+++ b/glom/mode_design/print_layouts/window_print_layout_edit.cc
@@ -557,7 +557,7 @@ Window_PrintLayout_Edit::~Window_PrintLayout_Edit()
 
 void Window_PrintLayout_Edit::update_table_title()
 {
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
   if(!document)
   {
     std::cerr << G_STRFUNC << ": document was null" << std::endl;
@@ -842,7 +842,7 @@ void Window_PrintLayout_Edit::on_menu_insert_create_standard()
   if(response != Gtk::RESPONSE_OK)
     return;
 
-  const auto document = dynamic_cast<const Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<const Document>(get_document());
   if(!document)
   {
     std::cerr << G_STRFUNC << ": document was null" << std::endl;
@@ -1020,7 +1020,7 @@ void Window_PrintLayout_Edit::on_menu_file_print_preview()
 {
   //Save any recent changes in the document,
   //so that the preview will show them:
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(!document)
     return;
 
diff --git a/glom/mode_design/relationships_overview/window_relationships_overview.cc 
b/glom/mode_design/relationships_overview/window_relationships_overview.cc
index 932e4f9..b672a97 100644
--- a/glom/mode_design/relationships_overview/window_relationships_overview.cc
+++ b/glom/mode_design/relationships_overview/window_relationships_overview.cc
@@ -154,7 +154,7 @@ void Window_RelationshipsOverview::draw_tables()
   while(m_group_tables->get_n_children() > 0)
     m_group_tables->remove_child(0);
 
-  const auto document = dynamic_cast<Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document)
   {
     double max_table_height = 0;
@@ -211,7 +211,7 @@ void Window_RelationshipsOverview::draw_lines()
   while(m_group_lines->get_n_children() > 0)
     m_group_lines->remove_child(0);
 
-  const auto document = dynamic_cast<Document*>(get_document());
+  const auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document)
   {
     //Create the lines linking tables to show relationships:
@@ -413,7 +413,7 @@ void Window_RelationshipsOverview::on_table_moved(const Glib::RefPtr<CanvasItemM
   if(!table)
     return;
 
-  auto document = dynamic_cast<Document*>(get_document());
+  auto document = std::dynamic_pointer_cast<Document>(get_document());
   if(document && table)
   {
     //Save the new position in the document:
diff --git a/glom/mode_design/report_layout/dialog_layout_report.cc 
b/glom/mode_design/report_layout/dialog_layout_report.cc
index e1d4b0d..aec02b5 100644
--- a/glom/mode_design/report_layout/dialog_layout_report.cc
+++ b/glom/mode_design/report_layout/dialog_layout_report.cc
@@ -334,7 +334,7 @@ void Dialog_Layout_Report::add_group(const Glib::RefPtr<type_model>& model_parts
   }
 }
 
-//void Dialog_Layout_Report::set_document(const Glib::ustring& layout, Document* document, const 
Glib::ustring& table_name, const type_vecLayoutFields& table_fields)
+//void Dialog_Layout_Report::set_document(const Glib::ustring& layout, const std::shared_ptr<Document>& 
document, const Glib::ustring& table_name, const type_vecLayoutFields& table_fields)
 void Dialog_Layout_Report::set_report(const Glib::ustring& table_name, const std::shared_ptr<const Report>& 
report)
 {
   m_modified = false;
diff --git a/glom/mode_design/users/dialog_groups_list.cc b/glom/mode_design/users/dialog_groups_list.cc
index 7ea4cea..1c0059b 100644
--- a/glom/mode_design/users/dialog_groups_list.cc
+++ b/glom/mode_design/users/dialog_groups_list.cc
@@ -113,7 +113,7 @@ Dialog_GroupsList::Dialog_GroupsList(BaseObjectType* cobject, const Glib::RefPtr
 }
 
 /*
-void Dialog_GroupsList::set_document(const Glib::ustring& layout, Document* document, const Glib::ustring& 
table_name, const type_vecLayoutFields& table_fields)
+void Dialog_GroupsList::set_document(const Glib::ustring& layout, const std::shared_ptr<Document>& document, 
const Glib::ustring& table_name, const type_vecLayoutFields& table_fields)
 {
   m_modified = false;
 
@@ -379,15 +379,15 @@ void Dialog_GroupsList::fill_table_list(const Glib::ustring& group_name)
   //Fill the model rows:
   m_model_tables->clear();
 
- auto pDocument = get_document();
-  if(pDocument)
+ auto document = get_document();
+  if(document)
   {
     // Make sure that these are in the document,
     // so that the correct groups will be created if we recreate the database from the document:
     GroupInfo group_info;
     group_info.set_name(group_name);
 
-    Document::type_listTableInfo table_list = pDocument->get_tables(true /* plus system prefs */);
+    Document::type_listTableInfo table_list = document->get_tables(true /* plus system prefs */);
 
     for(const auto& table : table_list)
     {
@@ -409,7 +409,7 @@ void Dialog_GroupsList::fill_table_list(const Glib::ustring& group_name)
       group_info.m_map_privileges[table_name] = privs;
     }
 
-    pDocument->set_group(group_info);
+    document->set_group(group_info);
   }
 }
 
diff --git a/glom/mode_design/users/dialog_groups_list.h b/glom/mode_design/users/dialog_groups_list.h
index 799aee1..1f7e1d4 100644
--- a/glom/mode_design/users/dialog_groups_list.h
+++ b/glom/mode_design/users/dialog_groups_list.h
@@ -49,7 +49,7 @@ public:
    * @param table_name The table name.
    * @param table_fields: The actual fields in the table, in case the document does not yet know about them 
all.
    */
-  //virtual void set_document(const Glib::ustring& layout, Document* document, const Glib::ustring& 
table_name, const type_vecLayoutFields& table_fields);
+  //virtual void set_document(const Glib::ustring& layout, const std::shared_ptr<Document>& document, const 
Glib::ustring& table_name, const type_vecLayoutFields& table_fields);
 
 private:
 
diff --git a/glom/mode_design/users/dialog_user.h b/glom/mode_design/users/dialog_user.h
index 01f979e..980686c 100644
--- a/glom/mode_design/users/dialog_user.h
+++ b/glom/mode_design/users/dialog_user.h
@@ -45,7 +45,7 @@ public:
    * @param table_name The table name.
    * @param table_fields: The actual fields in the table, in case the document does not yet know about them 
all.
    */
-  //virtual void set_document(const Glib::ustring& layout, Document* document, const Glib::ustring& 
table_name, const type_vecLayoutFields& table_fields);
+  //virtual void set_document(const Glib::ustring& layout, const std::shared_ptr<Document>& document, const 
Glib::ustring& table_name, const type_vecLayoutFields& table_fields);
 
   Gtk::Entry* m_entry_user;
   Combo_TextGlade* m_combo_group;
diff --git a/glom/print_layout/canvas_print_layout.cc b/glom/print_layout/canvas_print_layout.cc
index c2df05e..a410a23 100644
--- a/glom/print_layout/canvas_print_layout.cc
+++ b/glom/print_layout/canvas_print_layout.cc
@@ -698,7 +698,7 @@ void Canvas_PrintLayout::fill_with_data(const FoundSet& found_set, bool avoid_pa
   fill_with_data(m_items_group, found_set, avoid_page_margins);
 }
 
-void Canvas_PrintLayout::fill_with_data_system_preferences(const Glib::RefPtr<CanvasLayoutItem>& 
canvas_item, Document* document)
+void Canvas_PrintLayout::fill_with_data_system_preferences(const Glib::RefPtr<CanvasLayoutItem>& 
canvas_item, const std::shared_ptr<Document>& document)
 {
   auto layoutitem_field = 
     std::dynamic_pointer_cast<LayoutItem_Field>(canvas_item->get_layout_item());
diff --git a/glom/print_layout/canvas_print_layout.h b/glom/print_layout/canvas_print_layout.h
index d8aa985..1fd7a44 100644
--- a/glom/print_layout/canvas_print_layout.h
+++ b/glom/print_layout/canvas_print_layout.h
@@ -68,7 +68,7 @@ public:
    * show the content instead of the field name,
    * because it will be the same for all records.
    */
-  void fill_with_data_system_preferences(const Glib::RefPtr<CanvasLayoutItem>& canvas_item, Document* 
document);
+  void fill_with_data_system_preferences(const Glib::RefPtr<CanvasLayoutItem>& canvas_item, const 
std::shared_ptr<Document>& document);
 
   void fill_with_data(const FoundSet& found_set, bool avoid_page_margins);
 
diff --git a/glom/print_layout/print_layout_utils.cc b/glom/print_layout/print_layout_utils.cc
index 3f2c46f..1e01528 100644
--- a/glom/print_layout/print_layout_utils.cc
+++ b/glom/print_layout/print_layout_utils.cc
@@ -310,7 +310,7 @@ guint get_page_for_y(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::
   return pages_integral;
 }
 
-std::shared_ptr<PrintLayout> create_standard(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, const 
Glib::ustring& table_name, const Document* document, bool avoid_page_margins)
+std::shared_ptr<PrintLayout> create_standard(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, const 
Glib::ustring& table_name, const std::shared_ptr<const Document>& document, bool avoid_page_margins)
 {
   const Gtk::Unit units = Gtk::UNIT_MM;
   auto print_layout = std::make_shared<PrintLayout>();  
@@ -365,7 +365,7 @@ std::shared_ptr<PrintLayout> create_standard(const Glib::RefPtr<const Gtk::PageS
   return print_layout;
 }
 
-void do_print_layout(const std::shared_ptr<const PrintLayout>& print_layout, const FoundSet& found_set, bool 
preview, const Document* document, bool avoid_page_margins, Gtk::Window* transient_for)
+void do_print_layout(const std::shared_ptr<const PrintLayout>& print_layout, const FoundSet& found_set, bool 
preview, const std::shared_ptr<const Document>& document, bool avoid_page_margins, Gtk::Window* transient_for)
 {
   if(!print_layout)
   {
@@ -387,7 +387,7 @@ void do_print_layout(const std::shared_ptr<const PrintLayout>& print_layout, con
   }
 
   Canvas_PrintLayout canvas;
-  canvas.set_document(const_cast<Document*>(document)); //We const_cast because, for this use, it will not 
be changed.
+  canvas.set_document(std::const_pointer_cast<Document>(document)); //We const_cast because, for this use, 
it will not be changed.
 
   //We cast to unconst because we know that the layout will not be changed by this use: 
   auto unconst = std::const_pointer_cast<PrintLayout>(print_layout);
diff --git a/glom/print_layout/print_layout_utils.h b/glom/print_layout/print_layout_utils.h
index 0b55f01..60cc01b 100644
--- a/glom/print_layout/print_layout_utils.h
+++ b/glom/print_layout/print_layout_utils.h
@@ -45,9 +45,9 @@ const double ITEM_WIDTH_WIDE = GRID_GAP * 10;
 /** Create a print layout based on the on-screen details layout.
  * @param avoid_page_margins If true then do skip page margins.
  */
-std::shared_ptr<PrintLayout> create_standard(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, const 
Glib::ustring& table_name, const Document* document, bool avoid_page_margins);
+std::shared_ptr<PrintLayout> create_standard(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, const 
Glib::ustring& table_name, const std::shared_ptr<const Document>& document, bool avoid_page_margins);
 
-void do_print_layout(const std::shared_ptr<const PrintLayout>& print_layout, const FoundSet& found_set, bool 
preview, const Document* document, bool avoid_page_margins, Gtk::Window* transient_for);
+void do_print_layout(const std::shared_ptr<const PrintLayout>& print_layout, const FoundSet& found_set, bool 
preview, const std::shared_ptr<const Document>& document, bool avoid_page_margins, Gtk::Window* 
transient_for);
 
 double get_page_height(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units);
 double get_page_height(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, double& 
margin_top, double& margin_bottom);
diff --git a/glom/python_embed/glom_python.cc b/glom/python_embed/glom_python.cc
index b1f5f42..732bab9 100644
--- a/glom/python_embed/glom_python.cc
+++ b/glom/python_embed/glom_python.cc
@@ -170,7 +170,7 @@ bool gda_python_module_is_available()
 }
 
 static boost::python::object glom_python_call(Field::glom_field_type result_type,
-  const Document* pDocument,
+  const std::shared_ptr<const Document>& document,
   const Glib::ustring& func_impl,
   Glib::ustring& error_message,
   const boost::python::object& param1,
@@ -224,11 +224,11 @@ static boost::python::object glom_python_call(Field::glom_field_type result_type
   }
 
   //Allow the function to import from our script library:
-  if(pDocument)
+  if(document)
   {
-    for(const auto& name : pDocument->get_library_module_names())
+    for(const auto& name : document->get_library_module_names())
     {
-      const auto script = pDocument->get_library_module(name);
+      const auto script = document->get_library_module(name);
       if(!name.empty() && !script.empty())
       {
         //TODO: Is there a boost::python equivalent for Py_CompileString()?
@@ -372,7 +372,7 @@ static boost::python::object glom_python_call(Field::glom_field_type result_type
 
 void glom_execute_python_function_implementation(const Glib::ustring& func_impl,
   const type_map_fields& field_values,
-  const Document* pDocument,
+  const std::shared_ptr<const Document>& document,
   const Glib::ustring& table_name,
   const std::shared_ptr<const Field>& key_field,
   const Gnome::Gda::Value& key_field_value,
@@ -399,20 +399,20 @@ void glom_execute_python_function_implementation(const Glib::ustring& func_impl,
   if(pParam)
   {
     //Fill the record's details:
-    pParam->set_fields(field_values, pDocument, table_name, key_field, key_field_value, opened_connection);
+    pParam->set_fields(field_values, document, table_name, key_field, key_field_value, opened_connection);
     pParam->set_read_only();
   }
 
   //Pass an additional ui parameter for use by scripts:
   boost::python::object objUI(new PyGlomUI(callbacks));
 
-  glom_python_call(Field::glom_field_type::TEXT, pDocument, func_impl, error_message, objRecord, objUI);
+  glom_python_call(Field::glom_field_type::TEXT, document, func_impl, error_message, objRecord, objUI);
 }
 
 Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field_type result_type,
   const Glib::ustring& func_impl,
   const type_map_fields& field_values,
-  const Document* pDocument,
+  const std::shared_ptr<const Document>& document,
   const Glib::ustring& table_name,
   const std::shared_ptr<const Field>& key_field,
   const Gnome::Gda::Value& key_field_value,
@@ -440,10 +440,10 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
   if(pParam)
   {
     //Fill the record's details:
-    pParam->set_fields(field_values, pDocument, table_name, key_field, key_field_value, opened_connection);
+    pParam->set_fields(field_values, document, table_name, key_field, key_field_value, opened_connection);
   }
 
-  const boost::python::object pyResultCpp = glom_python_call(result_type, pDocument, func_impl, 
error_message, objRecord);
+  const boost::python::object pyResultCpp = glom_python_call(result_type, document, func_impl, 
error_message, objRecord);
 
   //Deal with the various possible return types:
   Gnome::Gda::Value valueResult;
diff --git a/glom/python_embed/glom_python.h b/glom/python_embed/glom_python.h
index b6564c3..554e482 100644
--- a/glom/python_embed/glom_python.h
+++ b/glom/python_embed/glom_python.h
@@ -52,7 +52,7 @@ typedef std::map<Glib::ustring, Gnome::Gda::Value> type_map_fields;
  */
 void glom_execute_python_function_implementation(const Glib::ustring& func_impl,
   const type_map_fields& field_values,
-  const Document* pDocument,
+  const std::shared_ptr<const Document>& document,
   const Glib::ustring& table_name,
   const std::shared_ptr<const Field>& key_field,
   const Gnome::Gda::Value& key_field_value,
@@ -67,7 +67,7 @@ void glom_execute_python_function_implementation(const Glib::ustring& func_impl,
 Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field_type result_type,
   const Glib::ustring& func_impl,
   const type_map_fields& field_values,
-  const Document* pDocument,
+  const std::shared_ptr<const Document>& document,
   const Glib::ustring& table_name,
   const std::shared_ptr<const Field>& key_field,
   const Gnome::Gda::Value& key_field_value,
diff --git a/tests/python/test_python_execute_func_with_record.cc 
b/tests/python/test_python_execute_func_with_record.cc
index d3bdf01..f1d5b71 100644
--- a/tests/python/test_python_execute_func_with_record.cc
+++ b/tests/python/test_python_execute_func_with_record.cc
@@ -53,10 +53,10 @@ int main()
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -65,10 +65,10 @@ int main()
     return EXIT_FAILURE;
   }
 
-  g_assert(!document.get_is_example_file());;
+  g_assert(!document->get_is_example_file());;
 
   auto connection_pool = Glom::ConnectionPool::get_instance();
-  connection_pool->setup_from_document(&document);
+  connection_pool->setup_from_document(document);
 
   //This is not really necessary for sqlite-based databases.
   const Glom::ConnectionPool::StartupErrors started =
diff --git a/tests/python/test_python_execute_func_with_record_field_types.cc 
b/tests/python/test_python_execute_func_with_record_field_types.cc
index 1601b10..4e006c8 100644
--- a/tests/python/test_python_execute_func_with_record_field_types.cc
+++ b/tests/python/test_python_execute_func_with_record_field_types.cc
@@ -30,7 +30,7 @@
 #include <boost/python.hpp>
 #include <iostream>
 
-static bool get_field_result(const Glom::Document& document,
+static bool get_field_result(const std::shared_ptr<Glom::Document>& document,
   const Glib::RefPtr<Gnome::Gda::Connection>& gda_connection,
   const Glib::ustring& table_name,
   const std::shared_ptr<const Glom::Field>& primary_key_field,
@@ -50,7 +50,7 @@ static bool get_field_result(const Glom::Document& document,
     value = Glom::glom_evaluate_python_function_implementation(
       Glom::Field::get_glom_type_for_gda_type(expected_value_gtype),
       calculation, field_values,
-      &document, table_name,
+      document, table_name,
       primary_key_field, primary_key_value,
       gda_connection,
       error_message);
@@ -95,7 +95,7 @@ static bool get_field_result(const Glom::Document& document,
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
   //Connect to a Glom database
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -115,7 +115,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   //Some python code just to exercise our PyGlomRecord API:
   const Glib::ustring table_name = "products";
   const auto primary_key_field =
-    document.get_field_primary_key(table_name);
+    document->get_field_primary_key(table_name);
   if(!primary_key_field)
   {
     std::cerr << G_STRFUNC << ": Failure: primary_key_field is empty." << std::endl;
@@ -125,7 +125,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   const Gnome::Gda::Value primary_key_value(2);
 
   const Glom::type_map_fields field_values =
-    Glom::DbUtils::get_record_field_values(&document,
+    Glom::DbUtils::get_record_field_values(document,
       table_name,
       primary_key_field,
       primary_key_value);
diff --git a/tests/test_document_autosave.cc b/tests/test_document_autosave.cc
index e06e80a..5d22a44 100644
--- a/tests/test_document_autosave.cc
+++ b/tests/test_document_autosave.cc
@@ -68,43 +68,43 @@ int main()
 
   //Test manual saving:
   {
-    Glom::Document document;
-    document.set_allow_autosave(false);
-    document.set_file_uri(file_uri);
-    document.set_hosting_mode(Glom::Document::HostingMode::POSTGRES_CENTRAL);
-    document.set_database_title_original(test_title);
-    const auto saved = document.save();
+    auto document = std::make_shared<Glom::Document>();
+    document->set_allow_autosave(false);
+    document->set_file_uri(file_uri);
+    document->set_hosting_mode(Glom::Document::HostingMode::POSTGRES_CENTRAL);
+    document->set_database_title_original(test_title);
+    const auto saved = document->save();
     g_assert(saved);
   }
   {
-    Glom::Document document;
-    document.set_file_uri(file_uri);
+    auto document = std::make_shared<Glom::Document>();
+    document->set_file_uri(file_uri);
     int failure_code = 0;
-    const auto test = document.load(failure_code);
+    const auto test = document->load(failure_code);
     g_assert(test);
 
-    g_assert( document.get_database_title_original() == test_title );
+    g_assert( document->get_database_title_original() == test_title );
   }
 
   cleanup();
 
   //Test autosaving:
   {
-    Glom::Document document;
-    document.set_file_uri(file_uri);
-    document.set_hosting_mode(Glom::Document::HostingMode::POSTGRES_CENTRAL);
-    document.set_allow_autosave();
-    document.set_database_title_original(test_title);
-    g_assert( !document.get_modified() );
+    auto document = std::make_shared<Glom::Document>();
+    document->set_file_uri(file_uri);
+    document->set_hosting_mode(Glom::Document::HostingMode::POSTGRES_CENTRAL);
+    document->set_allow_autosave();
+    document->set_database_title_original(test_title);
+    g_assert( !document->get_modified() );
   }
   {
-    Glom::Document document;
-    document.set_file_uri(file_uri);
+    auto document = std::make_shared<Glom::Document>();
+    document->set_file_uri(file_uri);
     int failure_code = 0;
-    const auto test = document.load(failure_code);
+    const auto test = document->load(failure_code);
     g_assert(test);
 
-    g_assert( document.get_database_title_original() == test_title );
+    g_assert( document->get_database_title_original() == test_title );
   }
 
   cleanup();
diff --git a/tests/test_document_change.cc b/tests/test_document_change.cc
index 59e9437..511fe17 100644
--- a/tests/test_document_change.cc
+++ b/tests/test_document_change.cc
@@ -30,37 +30,37 @@ int main()
 {
   Glom::libglom_init();
 
-  Glom::Document document;
-  document.set_allow_autosave(false); //Avoid warnings about it having no URI.
+  auto document = std::make_shared<Glom::Document>();
+  document->set_allow_autosave(false); //Avoid warnings about it having no URI.
 
   //Test some simple get/set operations:
   const char* title = "Music Collection";
-  document.set_database_title_original(title);
-  g_assert(document.get_database_title_original() == title);
+  document->set_database_title_original(title);
+  g_assert(document->get_database_title_original() == title);
 
   const char* value = "someuser";
-  document.set_connection_user(value);
-  g_assert(document.get_connection_user() == value);
+  document->set_connection_user(value);
+  g_assert(document->get_connection_user() == value);
 
   value = "someserver";
-  document.set_connection_server(value);
-  g_assert(document.get_connection_server() == value);
+  document->set_connection_server(value);
+  g_assert(document->get_connection_server() == value);
 
   value = "somedb";
-  document.set_connection_database(value);
-  g_assert(document.get_connection_database() == value);
+  document->set_connection_database(value);
+  g_assert(document->get_connection_database() == value);
 
   const guint port = 12345;
-  document.set_connection_port(port);
-  g_assert(document.get_connection_port() == port);
+  document->set_connection_port(port);
+  g_assert(document->get_connection_port() == port);
 
   const bool try_other_ports = false;
-  document.set_connection_try_other_ports(try_other_ports);
-  g_assert(document.get_connection_try_other_ports() == try_other_ports);
+  document->set_connection_try_other_ports(try_other_ports);
+  g_assert(document->get_connection_try_other_ports() == try_other_ports);
 
   value = "somescriptcontents";
-  document.set_startup_script(value);
-  g_assert(document.get_startup_script() == value);
+  document->set_startup_script(value);
+  g_assert(document->get_startup_script() == value);
 
 
   const Glib::ustring table_name = "sometable";
@@ -70,14 +70,14 @@ int main()
   const Glib::ustring table_title = "sometabletitle";
   table_info->set_title_original(table_title);
   g_assert(table_info->get_title_original() == table_title);  
-  document.add_table(table_info);
+  document->add_table(table_info);
 
   const float x = 20.0f;
   const float y = 30.0f;
-  document.set_table_overview_position(table_name, x, y);
+  document->set_table_overview_position(table_name, x, y);
   float x_out = 0;
   float y_out = 0;
-  document.get_table_overview_position(table_name, x_out, y_out);
+  document->get_table_overview_position(table_name, x_out, y_out);
   g_assert(x == x_out);
   g_assert(y == y_out);
 
diff --git a/tests/test_document_load.cc b/tests/test_document_load.cc
index 918aabd..b9cf8bc 100644
--- a/tests/test_document_load.cc
+++ b/tests/test_document_load.cc
@@ -73,22 +73,22 @@ static bool get_group_named(const Glom::Document::type_list_groups& container, c
   return false;
 }
 
-static bool needs_navigation(Glom::Document& document, const Glib::ustring& table_name, const Glib::ustring& 
field_name)
+static bool needs_navigation(const std::shared_ptr<Glom::Document>& document, const Glib::ustring& 
table_name, const Glib::ustring& field_name)
 {
   auto layout_item = std::make_shared<Glom::LayoutItem_Field>();
   layout_item->set_name(field_name);
   layout_item->set_full_field_details(
-    document.get_field(table_name, field_name));
+    document->get_field(table_name, field_name));
 
   std::shared_ptr<Glom::Relationship> field_used_in_relationship_to_one;
   return Glom::DbUtils::layout_field_should_have_navigation(table_name, 
-    layout_item, &document, field_used_in_relationship_to_one);
+    layout_item, document, field_used_in_relationship_to_one);
 }
 
-static std::shared_ptr<const Glom::LayoutItem_Portal> get_portal_from_details_layout(const Glom::Document& 
document, const Glib::ustring& table_name, const Glib::ustring& relationship_name)
+static std::shared_ptr<const Glom::LayoutItem_Portal> get_portal_from_details_layout(const 
std::shared_ptr<Glom::Document>& document, const Glib::ustring& table_name, const Glib::ustring& 
relationship_name)
 {
   const auto groups = 
-    document.get_data_layout_groups("details", table_name);
+    document->get_data_layout_groups("details", table_name);
   if(groups.empty())
   {
     std::cerr << G_STRFUNC << ": groups is empty." << std::endl;
@@ -141,10 +141,10 @@ int main()
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -154,10 +154,10 @@ int main()
   }
 
   //Test some known details:
-  g_assert(document.get_is_example_file());
-  g_assert(document.get_database_title_original() == "Openismus Film Manager");
+  g_assert(document->get_is_example_file());
+  g_assert(document->get_database_title_original() == "Openismus Film Manager");
 
-  const auto table_names = document.get_table_names();
+  const auto table_names = document->get_table_names();
   g_assert(contains(table_names, "accommodation"));
   g_assert(contains(table_names, "cars"));
   g_assert(contains(table_names, "characters"));
@@ -167,31 +167,31 @@ int main()
   g_assert(contains(table_names, "scenes"));
   g_assert(!contains(table_names, "Scenes")); //The title, not the name.
 
-  auto table = document.get_table("scenes");
+  auto table = document->get_table("scenes");
   g_assert(table);
   g_assert( table->get_title_original() == "Scenes" );
   g_assert( table->get_title_singular_original() == "Scene" );
 
   //Test known fields of one table:
-  const auto fields = document.get_table_fields("scenes");
+  const auto fields = document->get_table_fields("scenes");
   g_assert(contains_named(fields, "scene_id"));
   g_assert(contains_named(fields, "comments"));
   g_assert(contains_named(fields, "description"));
   g_assert(contains_named(fields, "date"));
   g_assert(!contains_named(fields, "nosuchfield"));
 
-  const auto relationships = document.get_relationships("scenes");
+  const auto relationships = document->get_relationships("scenes");
   g_assert(contains_named(relationships, "location"));
   g_assert(contains_named(relationships, "scene_crew"));
   g_assert(contains_named(relationships, "scene_cast"));
 
   //Check some fields:
-  auto field = document.get_field("contacts", "contact_id");
+  auto field = document->get_field("contacts", "contact_id");
   g_assert(field);
   g_assert( field->get_title_original() == "Contact ID" );
   g_assert(field->get_glom_type() == Glom::Field::glom_field_type::NUMERIC);
   g_assert(field->get_auto_increment());
-  field = document.get_field("locations", "rent");
+  field = document->get_field("locations", "rent");
   g_assert(field);
   g_assert( field->get_title_original() == "Rent" );
   g_assert(field->get_glom_type() == Glom::Field::glom_field_type::NUMERIC);
@@ -199,7 +199,7 @@ int main()
   g_assert(!field->get_unique_key());
 
   //Check a relationship:
-  const auto relationship = document.get_relationship("characters", "contacts_actor");
+  const auto relationship = document->get_relationship("characters", "contacts_actor");
   g_assert(relationship);
   g_assert(relationship->get_from_field() == "contact_id");
   g_assert(relationship->get_to_table() == "contacts");
@@ -208,7 +208,7 @@ int main()
 
   //Check a layout:
   const Glom::Document::type_list_layout_groups groups = 
-    document.get_data_layout_groups("details", "scenes");
+    document->get_data_layout_groups("details", "scenes");
   g_assert(groups.size() == 3);
   const std::shared_ptr<const Glom::LayoutGroup> group =
     groups[1];
@@ -230,7 +230,7 @@ int main()
 
   
   //Check Field Formatting:
-  field = document.get_field("contacts", "name_title");  
+  field = document->get_field("contacts", "name_title");  
   g_assert(field);
   g_assert(field->get_glom_type() == Glom::Field::glom_field_type::TEXT);
   const Glom::Formatting& formatting = field->m_default_formatting;
@@ -254,11 +254,11 @@ int main()
   g_assert(field_on_layout->get_formatting_used() == formatting);
 
   //Test this utility method:
-  g_assert( document.get_data_layout_groups_have_any_fields("list", "cars") );
+  g_assert( document->get_data_layout_groups_have_any_fields("list", "cars") );
 
 
   //Test library modules:
-  const auto module_names = document.get_library_module_names();
+  const auto module_names = document->get_library_module_names();
   if(!module_names.empty()) //TODO: Test a document that actually has some?
   {
     std::cerr << G_STRFUNC << ": Failure: Unexpected library module names." << std::endl;
@@ -268,7 +268,7 @@ int main()
 
   //Test print layouts:  
   const std::vector<Glib::ustring> print_layout_names = 
-    document.get_print_layout_names("contacts");
+    document->get_print_layout_names("contacts");
   if(print_layout_names.size() != 1)
   {
     std::cerr << G_STRFUNC << ": Failure: Unexpected number of print layouts." << std::endl;
@@ -281,7 +281,7 @@ int main()
     return false;
   }
   
-  const auto print_layout = document.get_print_layout("contacts", "contact_details");
+  const auto print_layout = document->get_print_layout("contacts", "contact_details");
   if(!print_layout)
   {
     std::cerr << G_STRFUNC << ": Failure: Could not get an expected print layout." << std::endl;
@@ -302,7 +302,7 @@ int main()
 
 
   const std::vector<Glib::ustring> report_names = 
-    document.get_report_names("contacts");
+    document->get_report_names("contacts");
   if(report_names.size() != 2)
   {
     std::cerr << G_STRFUNC << ": Failure: Unexpected number of reports." << std::endl;
@@ -315,7 +315,7 @@ int main()
     return false;
   }
 
-  const auto report = document.get_report("contacts", "by_country_by_town");
+  const auto report = document->get_report("contacts", "by_country_by_town");
   if(!report)
   {
     std::cerr << G_STRFUNC << ": Failure: Could not get an expected report." << std::endl;
@@ -336,7 +336,7 @@ int main()
 
   
   //Test user groups:
-  Glom::Document::type_list_groups user_groups = document.get_groups();
+  Glom::Document::type_list_groups user_groups = document->get_groups();
   Glom::GroupInfo group_info_ignored;
   g_assert(get_group_named(user_groups, "glom_developer", group_info_ignored));
 
@@ -380,7 +380,7 @@ int main()
 
   Glib::ustring navigation_table_name;
   std::shared_ptr<const Glom::UsesRelationship> navigation_relationship;
-  portal->get_suitable_table_to_view_details(navigation_table_name, navigation_relationship, &document);
+  portal->get_suitable_table_to_view_details(navigation_table_name, navigation_relationship, document);
 
   if(navigation_table_name != "characters")
   {
diff --git a/tests/test_document_load_and_change.cc b/tests/test_document_load_and_change.cc
index 5a5437f..baf64d4 100644
--- a/tests/test_document_load_and_change.cc
+++ b/tests/test_document_load_and_change.cc
@@ -27,12 +27,12 @@
 
 #include <iostream>
 
-static bool field_is_on_a_layout(Glom::Document& document, const Glib::ustring& table_name, const 
Glib::ustring& field_name)
+static bool field_is_on_a_layout(const std::shared_ptr<Glom::Document>& document, const Glib::ustring& 
table_name, const Glib::ustring& field_name)
 {
   //Check that the field name is no longer used on a layout:
-  for(const auto& layout_table_name : document.get_table_names())
+  for(const auto& layout_table_name : document->get_table_names())
   {
-    for(const auto& group : document.get_data_layout_groups("details", layout_table_name))
+    for(const auto& group : document->get_data_layout_groups("details", layout_table_name))
     {
       if(group->has_field(layout_table_name, table_name, field_name))
       {
@@ -79,10 +79,10 @@ int main()
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -92,30 +92,30 @@ int main()
   }
 
   //Prevent these test changes from being saved back to the example file:
-  document.set_allow_autosave(false);
+  document->set_allow_autosave(false);
 
   //Change a field name throughout the document:
   const Glib::ustring table_name = "products";
   const Glib::ustring field_name_original = "product_id";
   const Glib::ustring field_name_new = "newfieldname";
-  document.change_field_name(table_name, field_name_original, field_name_new);
+  document->change_field_name(table_name, field_name_original, field_name_new);
 
   //Check that the original field name is not known to the document:
-  if(document.get_field(table_name, field_name_original))
+  if(document->get_field(table_name, field_name_original))
   {
     std::cerr << G_STRFUNC << ": Failure: The document should have forgotten about the original field name." 
<< std::endl;
     return false;
   }
 
   //Check that the new field name is known to the document:
-  if(!(document.get_field(table_name, field_name_new)))
+  if(!(document->get_field(table_name, field_name_new)))
   {
     std::cerr << G_STRFUNC << ": Failure: The document does not know about the new field name." << std::endl;
     return false;
   }
 
   //Check that the original field name is no longer used in the relationship:
-  auto relationship = document.get_relationship("invoice_lines", "products");
+  auto relationship = document->get_relationship("invoice_lines", "products");
   if(!relationship)
   {
     std::cerr << G_STRFUNC << ": Failure: The relationship could not be found in the document." << std::endl;
@@ -140,15 +140,15 @@ int main()
     const Glib::ustring table_name_invoices = "invoices";
     const Glib::ustring relationship_name_original = "contacts";
     const Glib::ustring relationship_name_new = "newrelationshipname";
-    document.change_relationship_name(table_name_invoices, 
+    document->change_relationship_name(table_name_invoices, 
       relationship_name_original, relationship_name_new);
-    if(document.get_relationship(table_name, relationship_name_original))
+    if(document->get_relationship(table_name, relationship_name_original))
     {
       std::cerr << G_STRFUNC << ": Failure: The original relationship name still exists." << std::endl;
       return false;
     }
 
-    if(!document.get_relationship(table_name, relationship_name_new))
+    if(!document->get_relationship(table_name, relationship_name_new))
     {
       std::cerr << G_STRFUNC << ": Failure: The new relationship name does not exist." << std::endl;
       return false;
@@ -166,7 +166,7 @@ int main()
   }
 
   //Remove a field from the whole document:
-  document.remove_field("publisher", "publisher_id");
+  document->remove_field("publisher", "publisher_id");
   if(field_is_on_a_layout(document, "publisher", "publisher_id"))
   {
     std::cerr << G_STRFUNC << ": Failure: The removed field name is still used on a layout." << std::endl;
@@ -174,8 +174,8 @@ int main()
   }
   
   //Remove a relationship:
-  document.remove_relationship(relationship);
-  relationship = document.get_relationship("invoice_lines", "products");
+  document->remove_relationship(relationship);
+  relationship = document->get_relationship("invoice_lines", "products");
   if(relationship)
   {
     std::cerr << G_STRFUNC << ": Failure: The removed relationship still exists." << std::endl;
@@ -184,14 +184,14 @@ int main()
   
   //Change a table name:
   const Glib::ustring table_renamed = "invoiceslinesrenamed";
-  document.change_table_name("invoice_lines", table_renamed);
-  if(document.get_table("invoice_lines"))
+  document->change_table_name("invoice_lines", table_renamed);
+  if(document->get_table("invoice_lines"))
   {
     std::cerr << G_STRFUNC << ": Failure: The renamed table still exists." << std::endl;
     return false;
   }
   
-  relationship = document.get_relationship("invoices", "invoice_lines");
+  relationship = document->get_relationship("invoices", "invoice_lines");
   if(!relationship)
   {
     std::cerr << G_STRFUNC << ": Failure: The expected relationship does not exist." << std::endl;
@@ -204,8 +204,8 @@ int main()
     return false;
   }
   
-  document.remove_table("products");
-  if(document.get_table("products"))
+  document->remove_table("products");
+  if(document->get_table("products"))
   {
     std::cerr << G_STRFUNC << ": Failure: The removed table still exists." << std::endl;
     return false;
@@ -214,16 +214,16 @@ int main()
  
   //Remove a print layout:
   auto print_layout = 
-    document.get_print_layout("contacts", "contact_details");
+    document->get_print_layout("contacts", "contact_details");
   if(!print_layout)
   {
     std::cerr << G_STRFUNC << ": Failure: Could not get an expected print layout." << std::endl;
     return false;
   }
   
-  document.remove_print_layout("contacts", "contact_details");
+  document->remove_print_layout("contacts", "contact_details");
   print_layout = 
-    document.get_print_layout("contacts", "contact_details");
+    document->get_print_layout("contacts", "contact_details");
   if(print_layout)
   {
     std::cerr << G_STRFUNC << ": Failure: The removed print layotu still exists." << std::endl;
@@ -231,13 +231,13 @@ int main()
   }
   
   //Test user groups:
-  Glom::Document::type_list_groups groups = document.get_groups();
+  Glom::Document::type_list_groups groups = document->get_groups();
   g_assert(groups_contain_named(groups, "glom_developer"));
   
   const Glib::ustring group_name = "accounts";
   g_assert(groups_contain_named(groups, group_name));
-  document.remove_group(group_name);
-  groups = document.get_groups();
+  document->remove_group(group_name);
+  groups = document->get_groups();
   g_assert(!groups_contain_named(groups, group_name));
   
   Glom::libglom_deinit();
diff --git a/tests/test_document_load_and_save.cc b/tests/test_document_load_and_save.cc
index fc59572..945c65e 100644
--- a/tests/test_document_load_and_save.cc
+++ b/tests/test_document_load_and_save.cc
@@ -91,10 +91,10 @@ int main(int argc, char* argv[])
   
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto loaded = document.load(failure_code);
+  const auto loaded = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!loaded)
@@ -104,12 +104,12 @@ int main(int argc, char* argv[])
   }
 
   // Save the document:
-  document.set_allow_autosave(false);
+  document->set_allow_autosave(false);
   const Glib::ustring temp_uri = 
     Glom::Utils::get_temp_file_uri("testglom_document", ".glom");
-  document.set_file_uri(temp_uri);
-  document.set_modified(); //TODO: Let save() succeed without this.
-  const auto saved = document.save();
+  document->set_file_uri(temp_uri);
+  document->set_modified(); //TODO: Let save() succeed without this.
+  const auto saved = document->save();
   if(!saved)
   {
     std::cerr << G_STRFUNC << ": Document::save() failed." << std::endl;
diff --git a/tests/test_document_load_image.cc b/tests/test_document_load_image.cc
index 8b7c99c..db1e1ea 100644
--- a/tests/test_document_load_image.cc
+++ b/tests/test_document_load_image.cc
@@ -52,10 +52,10 @@ int main()
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -65,12 +65,12 @@ int main()
   }
 
   //Test some known details:
-  g_assert(document.get_is_example_file());
-  g_assert(document.get_database_title_original() == "Project Manager Example");
+  g_assert(document->get_is_example_file());
+  g_assert(document->get_database_title_original() == "Project Manager Example");
 
   //Check a layout:
   const Glom::Document::type_list_layout_groups groups = 
-    document.get_data_layout_groups("details", "projects");
+    document->get_data_layout_groups("details", "projects");
   g_assert(groups.size() == 3);
   const std::shared_ptr<const Glom::LayoutGroup> group =
     groups[0];
diff --git a/tests/test_document_load_translations.cc b/tests/test_document_load_translations.cc
index ca1e485..73b53bf 100644
--- a/tests/test_document_load_translations.cc
+++ b/tests/test_document_load_translations.cc
@@ -72,9 +72,9 @@ bool contains_item_type(const Glom::Document::type_list_translatables& container
   );
 }
 
-static std::shared_ptr<const Glom::LayoutItem_Field> get_field_on_layout(const Glom::Document& document, 
const Glib::ustring& layout_table_name, const Glib::ustring& table_name, const Glib::ustring& field_name)
+static std::shared_ptr<const Glom::LayoutItem_Field> get_field_on_layout(const 
std::shared_ptr<Glom::Document>& document, const Glib::ustring& layout_table_name, const Glib::ustring& 
table_name, const Glib::ustring& field_name)
 {
-  for(const auto& group : document.get_data_layout_groups("details", layout_table_name))
+  for(const auto& group : document->get_data_layout_groups("details", layout_table_name))
   {
     if(!group)
       continue;
@@ -171,10 +171,10 @@ int main()
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -183,26 +183,26 @@ int main()
     return EXIT_FAILURE;
   }
 
-  const auto locales = document.get_translation_available_locales();
+  const auto locales = document->get_translation_available_locales();
   g_assert(locales.size() == 16);
   g_assert(contains(locales, "de"));
 
-  const auto table_names = document.get_table_names();
+  const auto table_names = document->get_table_names();
   g_assert(contains(table_names, "scenes"));
 
-  g_assert( document.get_table_title_original("scenes") == "Scenes" );
-  g_assert( document.get_table_title_singular_original("scenes") == "Scene" );
+  g_assert( document->get_table_title_original("scenes") == "Scenes" );
+  g_assert( document->get_table_title_singular_original("scenes") == "Scene" );
   
-  g_assert( document.get_table_title("scenes", locale_de) == "Szenen" );
-  g_assert( document.get_table_title_singular("scenes", locale_de) == "Szene" );
+  g_assert( document->get_table_title("scenes", locale_de) == "Szenen" );
+  g_assert( document->get_table_title_singular("scenes", locale_de) == "Szene" );
 
   //Check a field:
-  auto field = document.get_field("contacts", "contact_id");
+  auto field = document->get_field("contacts", "contact_id");
   g_assert(field);
   check_title(field, "Contact ID", "Kontaktkennung");
 
   //Check a field and its custom choices:
-  field = document.get_field("scenes", "day_or_night");
+  field = document->get_field("scenes", "day_or_night");
   g_assert(field);
   check_title(field, "Day/Night", "Tag/Nacht");
 
@@ -223,7 +223,7 @@ int main()
   g_assert( value->get_title_original() == "Day" );
 
   //Check a relationship:
-  const auto relationship = document.get_relationship("characters", "contacts_actor");
+  const auto relationship = document->get_relationship("characters", "contacts_actor");
   g_assert(relationship);
   check_title(relationship, "Actor", "Schauspieler");
 
@@ -248,12 +248,12 @@ int main()
   g_assert(field_on_layout->get_formatting_used_has_translatable_choices());
 
   //Check a print layout:
-  const auto print_layout = document.get_print_layout("contacts", "contact_details");
+  const auto print_layout = document->get_print_layout("contacts", "contact_details");
   g_assert(print_layout);
   check_title(print_layout, "Contact Details", "Kontakt Details" );
 
   //Check the whole list of translatable items:
-  Glom::Document::type_list_translatables list_layout_items = document.get_translatable_items();
+  Glom::Document::type_list_translatables list_layout_items = document->get_translatable_items();
   g_assert(!list_layout_items.empty());
   const bool contains_databasetitle =
     contains_item_type<Glom::DatabaseTitle>(list_layout_items);
diff --git a/tests/test_fake_connection.cc b/tests/test_fake_connection.cc
index 2c2c83f..4a88c7f 100644
--- a/tests/test_fake_connection.cc
+++ b/tests/test_fake_connection.cc
@@ -49,10 +49,10 @@ int main()
   }
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -66,16 +66,16 @@ int main()
 
   //Build a SQL query and get the string for it:
   const Gnome::Gda::Value value("Born To Run");
-  auto where_field = document.get_field("albums", "name");
+  auto where_field = document->get_field("albums", "name");
   const Gnome::Gda::SqlExpr where_clause = 
     Glom::Utils::build_simple_where_expression("albums", where_field, value);
   
   Glom::Utils::type_vecLayoutFields fieldsToGet;
-  auto field = document.get_field("albums", "album_id");
+  auto field = document->get_field("albums", "album_id");
   auto layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
-  field = document.get_field("albums", "name");
+  field = document->get_field("albums", "name");
   layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
diff --git a/tests/test_selfhosting_new_empty.cc b/tests/test_selfhosting_new_empty.cc
index 6e4d1b2..17d3fc2 100644
--- a/tests/test_selfhosting_new_empty.cc
+++ b/tests/test_selfhosting_new_empty.cc
@@ -27,7 +27,7 @@
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
   // Create the document:
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
 
   if(!(test_create_and_selfhost_new_database(document, hosting_mode, "test_db")))
   {
@@ -41,7 +41,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     Glom::SystemPrefs prefs;
     prefs.m_name = "test name";
     prefs.m_org_name = "test org name";
-    Glom::DbUtils::set_database_preferences(&document, prefs);
+    Glom::DbUtils::set_database_preferences(document, prefs);
   }
   catch(const Glom::ExceptionConnection& ex)
   {
diff --git a/tests/test_selfhosting_new_empty_change_sysprefs.cc 
b/tests/test_selfhosting_new_empty_change_sysprefs.cc
index 8e33d46..020d6e9 100644
--- a/tests/test_selfhosting_new_empty_change_sysprefs.cc
+++ b/tests/test_selfhosting_new_empty_change_sysprefs.cc
@@ -27,7 +27,7 @@
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
   // Create the document:
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
 
   if(!(test_create_and_selfhost_new_database(document, hosting_mode, "test_db")))
   {
@@ -46,10 +46,10 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     prefs_in.m_org_address_county = "test county";
     prefs_in.m_org_address_postcode = "test postcode";
     prefs_in.m_org_address_country = "test country";
-    Glom::DbUtils::set_database_preferences(&document, prefs_in);
+    Glom::DbUtils::set_database_preferences(document, prefs_in);
 
     const Glom::SystemPrefs prefs_out = 
-      Glom::DbUtils::get_database_preferences(&document);
+      Glom::DbUtils::get_database_preferences(document);
     if(prefs_out != prefs_in)
     {
       std::cerr << G_STRFUNC << ": The System Preferences read out were not the same as those written." << 
std::endl;
diff --git a/tests/test_selfhosting_new_empty_then_users.cc b/tests/test_selfhosting_new_empty_then_users.cc
index 12c33a3..1b4e58a 100644
--- a/tests/test_selfhosting_new_empty_then_users.cc
+++ b/tests/test_selfhosting_new_empty_then_users.cc
@@ -35,9 +35,9 @@ bool contains(const T_Container& container, const T_Value& name)
   return Glom::Utils::find_exists(container, name);
 }
 
-static bool test_add_group(const Glom::Document& document, const Glib::ustring& group)
+static bool test_add_group(const std::shared_ptr<Glom::Document>& document, const Glib::ustring& group)
 {
-  if(!Glom::DbUtils::add_group(&document, group))
+  if(!Glom::DbUtils::add_group(document, group))
   {
     std::cerr << G_STRFUNC << ": DbUtils::add_group() failed." << std::endl;
     return false;
@@ -61,10 +61,10 @@ static bool test_add_group(const Glom::Document& document, const Glib::ustring&
   return true;
 }
 
-static bool test_add_user(const Glom::Document& document, const Glib::ustring& user, const Glib::ustring& 
group)
+static bool test_add_user(const std::shared_ptr<Glom::Document>& document, const Glib::ustring& user, const 
Glib::ustring& group)
 {
   //Add an operator user, adding it to the group:
-  if(!Glom::DbUtils::add_user(&document, user, "somepassword", group))
+  if(!Glom::DbUtils::add_user(document, user, "somepassword", group))
   {
     std::cerr << G_STRFUNC << ": DbUtils::add_user() failed." << std::endl;
     test_selfhosting_cleanup();
@@ -122,7 +122,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   }
 
   //Create and self-host the document:
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
     if(!(test_create_and_selfhost_new_database(document, hosting_mode, "test_db")))
   {
     std::cerr << G_STRFUNC << ": test_create_and_selfhost_new_database() failed" << std::endl;
@@ -147,7 +147,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   //Add some tables, for the groups to have rights for:
   for(const auto& table_name : table_names)
   {
-    if(!Glom::DbUtils::create_table_with_default_fields(&document, table_name))
+    if(!Glom::DbUtils::create_table_with_default_fields(document, table_name))
     {
       std::cerr << G_STRFUNC << ": Failure: create_table_with_default_fields() failed." << std::endl;
       return false;
diff --git a/tests/test_selfhosting_new_from_example.cc b/tests/test_selfhosting_new_from_example.cc
index d604141..c7a266b 100644
--- a/tests/test_selfhosting_new_from_example.cc
+++ b/tests/test_selfhosting_new_from_example.cc
@@ -28,7 +28,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_music_collection.glom", document, hosting_mode);
   if(!recreated)
@@ -37,7 +37,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     return false;
   }
   
-  if(!test_example_musiccollection_data(&document))
+  if(!test_example_musiccollection_data(document))
   {
     std::cerr << G_STRFUNC << ": test_example_musiccollection_data() failed." << std::endl;
     return false;
@@ -58,7 +58,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   //and make it translatable:
   /* TODO: This is not stored in the examples. Should it be?
   const Glom::SystemPrefs prefs = 
-    Glom::DbUtils::get_database_preferences(&document);
+    Glom::DbUtils::get_database_preferences(document);
   g_return_val_if_fail(prefs.m_name == "Music Collection", false);
   g_return_val_if_fail(prefs.m_org_name == "SomeOrganization Incorporated", false);
   g_return_val_if_fail(prefs.m_org_address_street == "Some House", false);
diff --git a/tests/test_selfhosting_new_from_example_defaultvalues.cc 
b/tests/test_selfhosting_new_from_example_defaultvalues.cc
index 605df43..c69c376 100644
--- a/tests/test_selfhosting_new_from_example_defaultvalues.cc
+++ b/tests/test_selfhosting_new_from_example_defaultvalues.cc
@@ -28,7 +28,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -46,7 +46,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     return false;
   }
 
-  auto field = document.get_field(table_name, "count");
+  auto field = document->get_field(table_name, "count");
   if(!field)
   {
     std::cerr << G_STRFUNC << ": Failure: Could not get field." << std::endl;
@@ -76,7 +76,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     return false;
   }
 
-  field = document.get_field(table_name, "website");
+  field = document->get_field(table_name, "website");
   if(!field)
   {
     std::cerr << G_STRFUNC << ": Failure: Could not get field." << std::endl;
diff --git a/tests/test_selfhosting_new_from_example_float.cc 
b/tests/test_selfhosting_new_from_example_float.cc
index febc5aa..eb07b6f 100644
--- a/tests/test_selfhosting_new_from_example_float.cc
+++ b/tests/test_selfhosting_new_from_example_float.cc
@@ -32,7 +32,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -42,7 +42,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   }
   
   const Glib::ustring table_name = "products";
-  auto primary_key_field = document.get_field_primary_key(table_name);
+  auto primary_key_field = document->get_field_primary_key(table_name);
   if(!primary_key_field)
   {
     std::cerr << G_STRFUNC << ": Failure: primary_key_field is empty." << std::endl;
@@ -55,7 +55,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     Glom::Utils::build_simple_where_expression(table_name, primary_key_field, pk_value);
   
   Glom::Utils::type_vecLayoutFields fieldsToGet;
-  auto field = document.get_field(table_name, "price");
+  auto field = document->get_field(table_name, "price");
   auto layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
diff --git a/tests/test_selfhosting_new_from_example_operator.cc 
b/tests/test_selfhosting_new_from_example_operator.cc
index 05a3ed3..d6b6f1a 100644
--- a/tests/test_selfhosting_new_from_example_operator.cc
+++ b/tests/test_selfhosting_new_from_example_operator.cc
@@ -52,7 +52,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
 
   //Create and self-host the document:
   {
-    Glom::Document document;
+    auto document = std::make_shared<Glom::Document>();
     const bool recreated = 
       test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
     if(!recreated)
@@ -85,7 +85,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
       return false;
     }
 
-    if(!Glom::DbUtils::add_user(&document, operator_user, operator_password, operator_group_name))
+    if(!Glom::DbUtils::add_user(document, operator_user, operator_password, operator_group_name))
     {
       std::cerr << G_STRFUNC << ": DbUtils::add_user() failed." << std::endl;
       test_selfhosting_cleanup();
@@ -106,11 +106,11 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   
   //Self-host the document again, this time as operator:
   {
-    Glom::Document document;
-    document.set_allow_autosave(false); //To simplify things and to not depend implicitly on autosave.
-    document.set_file_uri(temp_file_uri);
+    auto document = std::make_shared<Glom::Document>();
+    document->set_allow_autosave(false); //To simplify things and to not depend implicitly on autosave.
+    document->set_file_uri(temp_file_uri);
     int failure_code = 0;
-    const auto test = document.load(failure_code);
+    const auto test = document->load(failure_code);
     //std::cout << "Document load result=" << test << std::endl;
     if(!test)
     {
diff --git a/tests/test_selfhosting_new_from_example_strangepath.cc 
b/tests/test_selfhosting_new_from_example_strangepath.cc
index 90f54a5..8115fe1 100644
--- a/tests/test_selfhosting_new_from_example_strangepath.cc
+++ b/tests/test_selfhosting_new_from_example_strangepath.cc
@@ -35,7 +35,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     return true;
   }
 
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   //Note: We avoid using a path that is longer than 107 characters to avoid a PostgreSQL error.
   //(107 == sizeof(struct sockaddr_un.sun_path) at least here). murrayc.
   //See http://lists.debian.org/debian-wb-team/2013/05/msg00015.html
@@ -50,7 +50,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     return false;
   }
   
-  if(!test_example_musiccollection_data(&document))
+  if(!test_example_musiccollection_data(document))
   {
     std::cerr << G_STRFUNC << ": test_example_musiccollection_data() failed." << std::endl;
     return false;
diff --git a/tests/test_selfhosting_new_then_alter_table.cc b/tests/test_selfhosting_new_then_alter_table.cc
index a48de33..7dba31b 100644
--- a/tests/test_selfhosting_new_then_alter_table.cc
+++ b/tests/test_selfhosting_new_then_alter_table.cc
@@ -32,7 +32,7 @@
 
 static bool do_test(Glom::Document::HostingMode hosting_mode, const Glib::ustring& first_table_name, const 
Glib::ustring& renamed_table_name)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -41,7 +41,7 @@ static bool do_test(Glom::Document::HostingMode hosting_mode, const Glib::ustrin
     return false;
   }
   
-  if(!Glom::DbUtils::create_table_with_default_fields(&document, first_table_name))
+  if(!Glom::DbUtils::create_table_with_default_fields(document, first_table_name))
   {
     std::cerr << G_STRFUNC << ": Failure: create_table_with_default_fields() failed." << std::endl;
     return false;
diff --git a/tests/test_selfhosting_new_then_backup_restore.cc 
b/tests/test_selfhosting_new_then_backup_restore.cc
index f63e06d..1352e5f 100644
--- a/tests/test_selfhosting_new_then_backup_restore.cc
+++ b/tests/test_selfhosting_new_then_backup_restore.cc
@@ -38,7 +38,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
 
   Glib::ustring backup_uri_tarball;
   {
-    Glom::Document document;
+    auto document = std::make_shared<Glom::Document>();
     const bool recreated = 
       test_create_and_selfhost_from_example("example_music_collection.glom", document, hosting_mode);
     if(!recreated)
@@ -48,7 +48,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     }
 
     const auto backup_uri = Glom::Utils::get_temp_directory_uri();
-    backup_uri_tarball = document.save_backup_file(
+    backup_uri_tarball = document->save_backup_file(
       backup_uri,
       sigc::ptr_fun(&on_backup_progress));
     if(backup_uri_tarball.empty())
@@ -76,7 +76,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     
     //Create a document from the backup:
     //std::cout << "debug: recreated_uri=" << recreated_uri << std::endl;
-    Glom::Document document;
+    auto document = std::make_shared<Glom::Document>();
     const bool recreated = 
       test_create_and_selfhost_from_data(backup_glom_file_contents, document, hosting_mode);
     if(!recreated)
@@ -88,7 +88,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
 
     //Check that the new file has the expected data:
     /* TODO: Find out why this test fails, though it seems to work fine in the UI:
-    if(!test_example_musiccollection_data(&document))
+    if(!test_example_musiccollection_data(document))
     {
       std::cerr << G_STRFUNC << ": test_example_musiccollection_data() failed." << std::endl;
       return false;
diff --git a/tests/test_selfhosting_new_then_change_columns.cc 
b/tests/test_selfhosting_new_then_change_columns.cc
index fa7d01a..8578807 100644
--- a/tests/test_selfhosting_new_then_change_columns.cc
+++ b/tests/test_selfhosting_new_then_change_columns.cc
@@ -34,7 +34,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -45,7 +45,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   
   const Glib::ustring table_name = "contacts";
   const Glib::ustring field_name_original = "date_of_birth";
-  auto field_original = document.get_field(table_name, field_name_original);
+  auto field_original = document->get_field(table_name, field_name_original);
   if(!field_original)
   {
     std::cerr << G_STRFUNC << ": Failure: Could not get field." << std::endl;
diff --git a/tests/test_selfhosting_new_then_choices.cc b/tests/test_selfhosting_new_then_choices.cc
index d40f369..40b3fdb 100644
--- a/tests/test_selfhosting_new_then_choices.cc
+++ b/tests/test_selfhosting_new_then_choices.cc
@@ -34,7 +34,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -54,7 +54,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   }
 
   const Glom::Utils::type_list_values_with_second values_with_second = 
-    Glom::Utils::get_choice_values_all(&document, field_with_choice);
+    Glom::Utils::get_choice_values_all(document, field_with_choice);
   if(values_with_second.size() != 3)
   {
     std::cerr << G_STRFUNC << ": Failure: There were an unexpected number of choices." << std::endl;
diff --git a/tests/test_selfhosting_new_then_get_privs.cc b/tests/test_selfhosting_new_then_get_privs.cc
index 176cc87..363cc63 100644
--- a/tests/test_selfhosting_new_then_get_privs.cc
+++ b/tests/test_selfhosting_new_then_get_privs.cc
@@ -26,7 +26,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
diff --git a/tests/test_selfhosting_new_then_image.cc b/tests/test_selfhosting_new_then_image.cc
index 21bfb2f..be6880e 100644
--- a/tests/test_selfhosting_new_then_image.cc
+++ b/tests/test_selfhosting_new_then_image.cc
@@ -34,7 +34,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -47,10 +47,10 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   //Where clause:
 
   const Glib::ustring table_name = "contacts";
-  const auto field = document.get_field(table_name, "picture");
+  const auto field = document->get_field(table_name, "picture");
 
   //Where clause:
-  const auto key_field = document.get_field(table_name, "contact_id");
+  const auto key_field = document->get_field(table_name, "contact_id");
   if(!key_field)
   {
     std::cerr << G_STRFUNC << ": Failure: Could not get key field." << std::endl;
diff --git a/tests/test_selfhosting_new_then_lookup.cc b/tests/test_selfhosting_new_then_lookup.cc
index 5a7b9d4..9942186 100644
--- a/tests/test_selfhosting_new_then_lookup.cc
+++ b/tests/test_selfhosting_new_then_lookup.cc
@@ -66,7 +66,7 @@ static bool contains_field(const Glom::Document::type_list_lookups& container, c
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -76,7 +76,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   }
   
   const Glib::ustring table_name = "invoice_lines";
-  auto primary_key_field = document.get_field_primary_key(table_name);
+  auto primary_key_field = document->get_field_primary_key(table_name);
   if(!primary_key_field)
   {
     std::cerr << G_STRFUNC << ": Failure: primary_key_field is empty." << std::endl;
@@ -85,7 +85,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
 
 
   // Get the fields whose values should be looked up when a field changes:
-  const auto lookups = document.get_lookup_fields(table_name, "product_id");
+  const auto lookups = document->get_lookup_fields(table_name, "product_id");
   if(lookups.size() != 3)
   {
     std::cerr << G_STRFUNC << ": Failure: Unexpected number of lookups: " << lookups.size() << std::endl;
@@ -177,8 +177,8 @@ static bool test(Glom::Document::HostingMode hosting_mode)
 
   //Lookup the value from the related record.
   const auto field_source = 
-    document.get_field(relationship->get_to_table(), field->get_lookup_field());
-  const auto value = Glom::DbUtils::get_lookup_value(&document, 
+    document->get_field(relationship->get_to_table(), field->get_lookup_field());
+  const auto value = Glom::DbUtils::get_lookup_value(document, 
     table_name, relationship, field_source, Gnome::Gda::Value(2));
 
   if(!test_check_numeric_value_type(hosting_mode, value))
diff --git a/tests/test_selfhosting_new_then_report.cc b/tests/test_selfhosting_new_then_report.cc
index 9d02aef..05abeb1 100644
--- a/tests/test_selfhosting_new_then_report.cc
+++ b/tests/test_selfhosting_new_then_report.cc
@@ -28,7 +28,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_music_collection.glom", document, hosting_mode);
   if(!recreated)
@@ -38,14 +38,14 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   }
 
   const auto report_temp = 
-    Glom::ReportBuilder::create_standard_list_report(&document, "albums");
+    Glom::ReportBuilder::create_standard_list_report(document, "albums");
 
   Glom::FoundSet found_set; //TODO: Test a where clause.
   found_set.m_table_name = "albums";
 
   const std::locale locale("en_US.UTF-8"); //Instead of just "" (current locale) so we get the same results 
each time.
   Glom::ReportBuilder report_builder(locale);
-  report_builder.set_document(&document);
+  report_builder.set_document(document);
   const Glib::ustring html = 
     report_builder.report_build(found_set, report_temp);
 
diff --git a/tests/test_selfhosting_new_then_report_summary.cc 
b/tests/test_selfhosting_new_then_report_summary.cc
index 69d94b1..131dfec 100644
--- a/tests/test_selfhosting_new_then_report_summary.cc
+++ b/tests/test_selfhosting_new_then_report_summary.cc
@@ -28,7 +28,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_example("example_smallbusiness.glom", document, hosting_mode);
   if(!recreated)
@@ -38,7 +38,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   }
 
   const auto report = 
-    document.get_report("invoices", "by_customer");
+    document->get_report("invoices", "by_customer");
   if(!report)
   {
     std::cerr << G_STRFUNC << ": The report could not be found." << std::endl;
@@ -50,7 +50,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
 
   const std::locale locale("en_US.UTF-8"); //Instead of just "" (current locale) so we know what numeric 
representations to expect and check for.
   Glom::ReportBuilder report_builder(locale);
-  report_builder.set_document(&document);
+  report_builder.set_document(document);
   const Glib::ustring html = 
     report_builder.report_build(found_set, report);
 
diff --git a/tests/test_selfhosting_non_numeric_primary_keys.cc 
b/tests/test_selfhosting_non_numeric_primary_keys.cc
index ec2cc55..6b523ab 100644
--- a/tests/test_selfhosting_non_numeric_primary_keys.cc
+++ b/tests/test_selfhosting_non_numeric_primary_keys.cc
@@ -28,7 +28,7 @@
 
 static bool test(Glom::Document::HostingMode hosting_mode)
 {
-  Glom::Document document;
+  auto document = std::make_shared<Glom::Document>();
   const bool recreated = 
     test_create_and_selfhost_from_test_example("test_example_music_collection_text_pk_fields.glom", 
document, hosting_mode);
   if(!recreated)
@@ -37,7 +37,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
     return false;
   }
   
-  if(!test_example_musiccollection_data(&document))
+  if(!test_example_musiccollection_data(document))
   {
     std::cerr << G_STRFUNC << ": test_example_musiccollection_data() failed." << std::endl;
     return false;
@@ -58,7 +58,7 @@ static bool test(Glom::Document::HostingMode hosting_mode)
   //and make it translatable:
   /* TODO: This is not stored in the examples. Should it be?
   const Glom::SystemPrefs prefs = 
-    Glom::DbUtils::get_database_preferences(&document);
+    Glom::DbUtils::get_database_preferences(document);
   g_return_val_if_fail(prefs.m_name == "Music Collection", false);
   g_return_val_if_fail(prefs.m_org_name == "SomeOrganization Incorporated", false);
   g_return_val_if_fail(prefs.m_org_address_street == "Some House", false);
diff --git a/tests/test_selfhosting_sqlinjection.cc b/tests/test_selfhosting_sqlinjection.cc
index 44db92b..a07c223 100644
--- a/tests/test_selfhosting_sqlinjection.cc
+++ b/tests/test_selfhosting_sqlinjection.cc
@@ -27,22 +27,22 @@
 #include <iostream>
 #include <cstdlib> //For EXIT_SUCCESS and EXIT_FAILURE
 
-Glom::Document document;
+auto document = std::make_shared<Glom::Document>();
 
 static bool check_get_extra_rows(const Glib::ustring& quote_char)
 {
   //Try to get more rows than intended:
   const Gnome::Gda::Value value("Born To Run" + quote_char + " OR " + quote_char + "x" + quote_char + "=" + 
quote_char + "x");
-  auto where_field = document.get_field("albums", "name");
+  auto where_field = document->get_field("albums", "name");
   const Gnome::Gda::SqlExpr where_clause = 
     Glom::Utils::build_simple_where_expression("albums", where_field, value);
   
   Glom::Utils::type_vecLayoutFields fieldsToGet;
-  auto field = document.get_field("albums", "album_id");
+  auto field = document->get_field("albums", "album_id");
   auto layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
-  field = document.get_field("albums", "name");
+  field = document->get_field("albums", "name");
   layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
@@ -66,16 +66,16 @@ static bool check_drop_table(const Glib::ustring& quote_char)
   //Try to drop the table in a second SQL statement:
   const Gnome::Gda::Value value("True Blue" + quote_char + "; DROP TABLE songs; --");
   auto where_field = 
-    document.get_field("albums", "name");
+    document->get_field("albums", "name");
   const Gnome::Gda::SqlExpr where_clause = 
     Glom::Utils::build_simple_where_expression("albums", where_field, value);
   
   Glom::Utils::type_vecLayoutFields fieldsToGet;
-  auto field = document.get_field("albums", "album_id");
+  auto field = document->get_field("albums", "album_id");
   auto layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
-  field = document.get_field("albums", "name");
+  field = document->get_field("albums", "name");
   layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
@@ -106,16 +106,16 @@ static bool check_avoid_quotes_and_drop_table_with_false_value_type()
   //by using a text value for a field whose type should not need quoting:
   const Gnome::Gda::Value value("1;DROP TABLE songs");
   auto where_field = 
-    document.get_field("albums", "album_id");
+    document->get_field("albums", "album_id");
   const Gnome::Gda::SqlExpr where_clause = 
     Glom::Utils::build_simple_where_expression("albums", where_field, value);
   
   Glom::Utils::type_vecLayoutFields fieldsToGet;
-  auto field = document.get_field("albums", "album_id");
+  auto field = document->get_field("albums", "album_id");
   auto layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
-  field = document.get_field("albums", "name");
+  field = document->get_field("albums", "name");
   layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
@@ -163,7 +163,7 @@ static bool check_avoid_quotes_and_drop_table_with_false_field_type()
 
   //Specify a field with incorrect type information:
   auto where_field = 
-    document.get_field("albums", "name");
+    document->get_field("albums", "name");
   where_field->set_glom_type(Glom::Field::glom_field_type::NUMERIC);
   //const GType gda_type = Glom::Field::get_gda_type_for_glom_type(Glom::TYPE_NUMERIC); 
 
@@ -171,11 +171,11 @@ static bool check_avoid_quotes_and_drop_table_with_false_field_type()
     Glom::Utils::build_simple_where_expression("albums", where_field, value);
  
   Glom::Utils::type_vecLayoutFields fieldsToGet;
-  auto field = document.get_field("albums", "album_id");
+  auto field = document->get_field("albums", "album_id");
   auto layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
-  field = document.get_field("albums", "name");
+  field = document->get_field("albums", "name");
   layoutitem = std::make_shared<Glom::LayoutItem_Field>();
   layoutitem->set_full_field_details(field);
   fieldsToGet.push_back(layoutitem);
diff --git a/tests/test_selfhosting_utils.cc b/tests/test_selfhosting_utils.cc
index 77983fd..7cbe874 100644
--- a/tests/test_selfhosting_utils.cc
+++ b/tests/test_selfhosting_utils.cc
@@ -149,12 +149,12 @@ void test_selfhosting_cleanup(bool delete_file)
   temp_file_uri.clear(); //Forget this too.
 }
 
-bool test_selfhost(Glom::Document& document, const Glib::ustring& user, const Glib::ustring& password)
+bool test_selfhost(const std::shared_ptr<Glom::Document>& document, const Glib::ustring& user, const 
Glib::ustring& password)
 {
   //TODO: Let this happen automatically on first connection?
   auto connection_pool = Glom::ConnectionPool::get_instance();
 
-  connection_pool->setup_from_document(&document);
+  connection_pool->setup_from_document(document);
 
   connection_pool->set_user(user);
   connection_pool->set_password(password);
@@ -171,7 +171,7 @@ bool test_selfhost(Glom::Document& document, const Glib::ustring& user, const Gl
   return true;
 }
 
-bool test_create_and_selfhost_new_empty(Glom::Document& document, Glom::Document::HostingMode hosting_mode, 
const std::string& subdirectory_path)
+bool test_create_and_selfhost_new_empty(const std::shared_ptr<Glom::Document>& document, 
Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path)
 {
   if( (hosting_mode != Glom::Document::HostingMode::POSTGRES_SELF) &&
     (hosting_mode != Glom::Document::HostingMode::MYSQL_SELF) &&
@@ -198,18 +198,18 @@ bool test_create_and_selfhost_new_empty(Glom::Document& document, Glom::Document
 
    //Save the example as a real file:
   temp_file_uri = Glib::filename_to_uri(temp_filepath);
-  document.set_allow_autosave(false); //To simplify things and to not depend implicitly on autosave.
-  document.set_file_uri(temp_file_uri);
+  document->set_allow_autosave(false); //To simplify things and to not depend implicitly on autosave.
+  document->set_file_uri(temp_file_uri);
 
-  document.set_hosting_mode(hosting_mode);
-  document.set_is_example_file(false);
-  document.set_network_shared(false);
-  const auto saved = document.save();
+  document->set_hosting_mode(hosting_mode);
+  document->set_is_example_file(false);
+  document->set_network_shared(false);
+  const auto saved = document->save();
   g_assert(saved);
 
   //Specify the backend and backend-specific details to be used by the connectionpool.
   auto connection_pool = Glom::ConnectionPool::get_instance();
-  connection_pool->setup_from_document(&document);
+  connection_pool->setup_from_document(document);
 
   //We must specify a default username and password:
   Glib::ustring password;
@@ -237,7 +237,7 @@ Glib::ustring test_get_temp_file_uri()
   return temp_file_uri;
 }
 
-bool test_create_and_selfhost_new_database(Glom::Document& document, Glom::Document::HostingMode 
hosting_mode, const Glib::ustring& database_name, const std::string& subdirectory_path)
+bool test_create_and_selfhost_new_database(const std::shared_ptr<Glom::Document>& document, 
Glom::Document::HostingMode hosting_mode, const Glib::ustring& database_name, const std::string& 
subdirectory_path)
 {
   if(!test_create_and_selfhost_new_empty(document, hosting_mode, subdirectory_path))
   {
@@ -253,7 +253,7 @@ bool test_create_and_selfhost_new_database(Glom::Document& document, Glom::Docum
   }
 
   //Create a database:
-  const auto created = Glom::DbUtils::create_database(&document, db_name,
+  const auto created = Glom::DbUtils::create_database(document, db_name,
     "test title", &on_db_creation_progress);
   if(!created)
   {
@@ -264,7 +264,7 @@ bool test_create_and_selfhost_new_database(Glom::Document& document, Glom::Docum
   return true;
 }
 
-static bool test_create_and_selfhost_from_example_full_path(const std::string& example_path, Glom::Document& 
document, Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path = std::string())
+static bool test_create_and_selfhost_from_example_full_path(const std::string& example_path, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode, const std::string& 
subdirectory_path = std::string())
 {
   Glib::ustring uri;
   try
@@ -280,7 +280,7 @@ static bool test_create_and_selfhost_from_example_full_path(const std::string& e
   return test_create_and_selfhost_from_uri(uri, document, hosting_mode, subdirectory_path);
 }
 
-bool test_create_and_selfhost_from_example(const std::string& example_filename, Glom::Document& document, 
Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path)
+bool test_create_and_selfhost_from_example(const std::string& example_filename, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode, const std::string& 
subdirectory_path)
 {
   Glib::ustring uri;
   
@@ -301,7 +301,7 @@ bool test_create_and_selfhost_from_example(const std::string& example_filename,
   return test_create_and_selfhost_from_example_full_path(path, document, hosting_mode, subdirectory_path);
 }
 
-bool test_create_and_selfhost_from_test_example(const std::string& example_filename, Glom::Document& 
document, Glom::Document::HostingMode hosting_mode)
+bool test_create_and_selfhost_from_test_example(const std::string& example_filename, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode)
 {
   Glib::ustring uri;
   
@@ -322,9 +322,9 @@ bool test_create_and_selfhost_from_test_example(const std::string& example_filen
   return test_create_and_selfhost_from_example_full_path(path, document, hosting_mode);
 }
 
-static bool after_load(Glom::Document& document, Glom::Document::HostingMode hosting_mode, const 
std::string& subdirectory_path)
+static bool after_load(const std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode 
hosting_mode, const std::string& subdirectory_path)
 {
-  if(!document.get_is_example_file() && !document.get_is_backup_file())
+  if(!document->get_is_example_file() && !document->get_is_backup_file())
   {
     std::cerr << G_STRFUNC << ": The document is not an example or a backup." << std::endl;
     return false;
@@ -336,14 +336,14 @@ static bool after_load(Glom::Document& document, Glom::Document::HostingMode hos
     return false;
   }
 
-  const auto recreated = Glom::DbUtils::recreate_database_from_document(&document, 
sigc::ptr_fun(&on_recreate_progress) );
+  const auto recreated = Glom::DbUtils::recreate_database_from_document(document, 
sigc::ptr_fun(&on_recreate_progress) );
   if(!recreated)
     test_selfhosting_cleanup();
 
   return recreated;
 }
 
-bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, Glom::Document& document, 
Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path)
+bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode, const std::string& 
subdirectory_path)
 {
   if( (hosting_mode != Glom::Document::HostingMode::POSTGRES_SELF) &&
     (hosting_mode != Glom::Document::HostingMode::MYSQL_SELF) &&
@@ -354,10 +354,10 @@ bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, Gl
   }
 
   // Load the document:
-  document.set_allow_autosave(false); //To simplify things and to not depend implicitly on autosave.
-  document.set_file_uri(example_file_uri);
+  document->set_allow_autosave(false); //To simplify things and to not depend implicitly on autosave.
+  document->set_file_uri(example_file_uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -369,7 +369,7 @@ bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, Gl
   return after_load(document, hosting_mode, subdirectory_path);
 }
 
-bool test_create_and_selfhost_from_data(const Glib::ustring& example_file_contents, Glom::Document& 
document, Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path)
+bool test_create_and_selfhost_from_data(const Glib::ustring& example_file_contents, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode, const std::string& 
subdirectory_path)
 {
   if( (hosting_mode != Glom::Document::HostingMode::POSTGRES_SELF) &&
     (hosting_mode != Glom::Document::HostingMode::MYSQL_SELF) &&
@@ -379,10 +379,10 @@ bool test_create_and_selfhost_from_data(const Glib::ustring& example_file_conten
     return false;
   }
 
-  document.set_allow_autosave(false); //To simplify things and to not depend implicitly on autosave.
+  document->set_allow_autosave(false); //To simplify things and to not depend implicitly on autosave.
 
   int failure_code = 0;
-  const auto test = document.load_from_data((const guchar*)example_file_contents.c_str(), 
example_file_contents.bytes(), failure_code);
+  const auto test = document->load_from_data((const guchar*)example_file_contents.c_str(), 
example_file_contents.bytes(), failure_code);
 
   if(!test)
   {
@@ -415,11 +415,11 @@ bool test_model_expected_size(const Glib::RefPtr<const Gnome::Gda::DataModel>& d
   return true;
 }
 
-bool test_table_exists(const Glib::ustring& table_name, const Glom::Document& document)
+bool test_table_exists(const Glib::ustring& table_name, const std::shared_ptr<Glom::Document>& document)
 {
   //Try to get more rows than intended:
   Glom::Utils::type_vecLayoutFields fieldsToGet;
-  auto field = document.get_field_primary_key(table_name); //To to get some field.
+  auto field = document->get_field_primary_key(table_name); //To to get some field.
   if(!field)
   {
     std::cerr << G_STRFUNC << "Failure: Could not get primary key for table=" << table_name << std::endl;
@@ -444,7 +444,7 @@ bool test_table_exists(const Glib::ustring& table_name, const Glom::Document& do
   return true;
 }
 
-static bool test_example_musiccollection_data_related(const Glom::Document* document, const 
Gnome::Gda::Value& album_id)
+static bool test_example_musiccollection_data_related(const std::shared_ptr<const Glom::Document>& document, 
const Gnome::Gda::Value& album_id)
 {
   if(!document)
   {
@@ -501,7 +501,7 @@ static bool test_example_musiccollection_data_related(const Glom::Document* docu
   return true;
 }
 
-bool test_example_musiccollection_data(const Glom::Document* document)
+bool test_example_musiccollection_data(const std::shared_ptr<const Glom::Document>& document)
 {
   if(!document)
   {
diff --git a/tests/test_selfhosting_utils.h b/tests/test_selfhosting_utils.h
index 221d1a2..1f7627c 100644
--- a/tests/test_selfhosting_utils.h
+++ b/tests/test_selfhosting_utils.h
@@ -31,7 +31,7 @@
  * @param hosting_mode Either HostingMode::POSTGRES_SELF or HostingMode::SQLITE
  * @param subdirectory_path: An additional directory path to use under the temporary directory that will be 
used to save the file.
  */
-bool test_create_and_selfhost_new_empty(Glom::Document& document, Glom::Document::HostingMode hosting_mode, 
const std::string& subdirectory_path = std::string());
+bool test_create_and_selfhost_new_empty(const std::shared_ptr<Glom::Document>& document, 
Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path = std::string());
 
 /** Create a .glom file from an example, with database data, and start a PostgreSQL server if necessary.
  *
@@ -40,7 +40,7 @@ bool test_create_and_selfhost_new_empty(Glom::Document& document, Glom::Document
  * @param database_name The name of the database to created.
  * @param subdirectory_path: An additional directory path to use under the temporary directory that will be 
used to save the file.
  */
-bool test_create_and_selfhost_new_database(Glom::Document& document, Glom::Document::HostingMode 
hosting_mode, const Glib::ustring& database_name,  const std::string& subdirectory_path = std::string());
+bool test_create_and_selfhost_new_database(const std::shared_ptr<Glom::Document>& document, 
Glom::Document::HostingMode hosting_mode, const Glib::ustring& database_name,  const std::string& 
subdirectory_path = std::string());
 
 /** Create a .glom file from an example, with database data, and start a PostgreSQL server if necessary.
  *
@@ -48,14 +48,14 @@ bool test_create_and_selfhost_new_database(Glom::Document& document, Glom::Docum
  * @param hosting_mode Either HostingMode::POSTGRES_SELF or HostingMode::SQLITE
  * @param subdirectory_path: An additional directory path to use under the temporary directory that will be 
used to save the file.
  */
-bool test_create_and_selfhost_from_example(const std::string& example_filename, Glom::Document& document, 
Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path = std::string());
+bool test_create_and_selfhost_from_example(const std::string& example_filename, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode, const std::string& 
subdirectory_path = std::string());
 
 /** Create a .glom file from a test example, with database data, and start a PostgreSQL server if necessary.
  *
  * @param example_filename The filename (not the full path) of the example .glom file.
  * @param hosting_mode Either HostingMode::POSTGRES_SELF or HostingMode::SQLITE
  */
-bool test_create_and_selfhost_from_test_example(const std::string& example_filename, Glom::Document& 
document, Glom::Document::HostingMode hosting_mode);
+bool test_create_and_selfhost_from_test_example(const std::string& example_filename, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode);
 
 
 /** Create a .glom file from an existing .glom example file with database data, and start a PostgreSQL 
server if necessary.
@@ -64,7 +64,7 @@ bool test_create_and_selfhost_from_test_example(const std::string& example_filen
  * @param hosting_mode Either HostingMode::POSTGRES_SELF or HostingMode::SQLITE
  * @param subdirectory_path: An additional directory path to use under the temporary directory that will be 
used to save the file.
  */
-bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, Glom::Document& document, 
Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path = std::string());
+bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode, const std::string& 
subdirectory_path = std::string());
 
 /** Create a .glom file from an existing .glom example file with database data, and start a PostgreSQL 
server if necessary.
  *
@@ -72,16 +72,16 @@ bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, Gl
  * @param hosting_mode Either HostingMode::POSTGRES_SELF or HostingMode::SQLITE
  * @param subdirectory_path: An additional directory path to use under the temporary directory that will be 
used to save the file.
  */
-bool test_create_and_selfhost_from_data(const Glib::ustring& example_file_contents, Glom::Document& 
document, Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path = std::string());
+bool test_create_and_selfhost_from_data(const Glib::ustring& example_file_contents, const 
std::shared_ptr<Glom::Document>& document, Glom::Document::HostingMode hosting_mode, const std::string& 
subdirectory_path = std::string());
 
 /** Start self-hosting of a .glom document.
  * @param document The document must already be saved to a file.
  */
-bool test_selfhost(Glom::Document& document, const Glib::ustring& user, const Glib::ustring& password);
+bool test_selfhost(const std::shared_ptr<Glom::Document>& document, const Glib::ustring& user, const 
Glib::ustring& password);
 
 
 bool test_model_expected_size(const Glib::RefPtr<const Gnome::Gda::DataModel>& data_model, guint 
columns_count, guint rows_count);
-bool test_table_exists(const Glib::ustring& table_name, const Glom::Document& document);
+bool test_table_exists(const Glib::ustring& table_name, const std::shared_ptr<Glom::Document>& document);
 
 /** Return the URI of the temporary .glom file created by the test_create_and_selfhost_*() methods.
  * This should only be used by some special tests.
@@ -93,7 +93,7 @@ Glib::ustring test_get_temp_file_uri();
  */
 void test_selfhosting_cleanup(bool delete_file = true);
 
-bool test_example_musiccollection_data(const Glom::Document* document);
+bool test_example_musiccollection_data(const std::shared_ptr<const Glom::Document>& document);
 
 typedef sigc::slot<bool, Glom::Document::HostingMode> SlotTest;
 
diff --git a/tests/test_utils.cc b/tests/test_utils.cc
index 48f99a3..869e878 100644
--- a/tests/test_utils.cc
+++ b/tests/test_utils.cc
@@ -23,9 +23,9 @@
 #include <glibmm/fileutils.h>
 #include <iostream>
 
-std::shared_ptr<const Glom::LayoutItem_Field> get_field_on_layout(const Glom::Document& document, const 
Glib::ustring& layout_table_name, const Glib::ustring& table_name, const Glib::ustring& field_name)
+std::shared_ptr<const Glom::LayoutItem_Field> get_field_on_layout(const std::shared_ptr<Glom::Document>& 
document, const Glib::ustring& layout_table_name, const Glib::ustring& table_name, const Glib::ustring& 
field_name)
 {
-  for(const auto& group : document.get_data_layout_groups("details", layout_table_name))
+  for(const auto& group : document->get_data_layout_groups("details", layout_table_name))
   {
     if(!group)
       continue;
diff --git a/tests/test_utils.h b/tests/test_utils.h
index 62085db..05c72e4 100644
--- a/tests/test_utils.h
+++ b/tests/test_utils.h
@@ -24,7 +24,7 @@
 #include <libglom/document/document.h>
 #include <string>
 
-std::shared_ptr<const Glom::LayoutItem_Field> get_field_on_layout(const Glom::Document& document, const 
Glib::ustring& layout_table_name, const Glib::ustring& table_name, const Glib::ustring& field_name);
+std::shared_ptr<const Glom::LayoutItem_Field> get_field_on_layout(const std::shared_ptr<Glom::Document>& 
document, const Glib::ustring& layout_table_name, const Glib::ustring& table_name, const Glib::ustring& 
field_name);
 
 Gnome::Gda::Value get_value_for_image();
 
diff --git a/tests/translations_po/test_document_export_po.cc 
b/tests/translations_po/test_document_export_po.cc
index 999a6f1..ff56764 100644
--- a/tests/translations_po/test_document_export_po.cc
+++ b/tests/translations_po/test_document_export_po.cc
@@ -88,10 +88,10 @@ int main()
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -111,7 +111,7 @@ int main()
 
   const Glib::ustring locale = "de";
   const bool success = 
-    Glom::write_translations_to_po_file(&document, po_file_uri, locale);
+    Glom::write_translations_to_po_file(document, po_file_uri, locale);
   if(!success)
   {
     std::cerr << G_STRFUNC << ": Glom::write_translations_to_po_file() failed." << std::endl;
diff --git a/tests/translations_po/test_document_import_po.cc 
b/tests/translations_po/test_document_import_po.cc
index 925ce8c..4bd916f 100644
--- a/tests/translations_po/test_document_import_po.cc
+++ b/tests/translations_po/test_document_import_po.cc
@@ -53,10 +53,10 @@ int main()
 
 
   // Load the document:
-  Glom::Document document;
-  document.set_file_uri(uri);
+  auto document = std::make_shared<Glom::Document>();
+  document->set_file_uri(uri);
   int failure_code = 0;
-  const auto test = document.load(failure_code);
+  const auto test = document->load(failure_code);
   //std::cout << "Document load result=" << test << std::endl;
 
   if(!test)
@@ -65,7 +65,7 @@ int main()
     return EXIT_FAILURE;
   }
 
-  document.set_allow_autosave(false); //Do not save changes back to the example file:
+  document->set_allow_autosave(false); //Do not save changes back to the example file:
   
   Glib::ustring po_file_uri;
   try
@@ -91,7 +91,7 @@ int main()
 
   const Glib::ustring locale = "de";
   const bool success = 
-    Glom::import_translations_from_po_file(&document, po_file_uri, locale);
+    Glom::import_translations_from_po_file(document, po_file_uri, locale);
   if(!success)
   {
     std::cerr << G_STRFUNC << ": Glom::import_translations_from_po_file() failed." << std::endl;
@@ -100,7 +100,7 @@ int main()
 
 
   //Check that some expected translated titles are now in the document:
-  auto table = document.get_table("scenes");
+  auto table = document->get_table("scenes");
   g_assert(table);
   g_assert( table->get_title_original() == "Scenes" ); //The original title should be unchanged:
 
@@ -111,7 +111,7 @@ int main()
     return EXIT_FAILURE;
   }
 
-  const auto report = document.get_report("crew", "crew_list");
+  const auto report = document->get_report("crew", "crew_list");
   g_assert(report);
   g_assert(report->get_title_original() == "Crew List"); //The original title should be unchanged:
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]