glom r1487 - in trunk: . glom



Author: arminb
Date: Sun Mar 30 15:16:29 2008
New Revision: 1487
URL: http://svn.gnome.org/viewvc/glom?rev=1487&view=rev

Log:
2008-03-30  Armin Burgmeier  <armin openismus com>

	* glom/glom.glade:
	* glom/dialog_existing_or_new.h:
	* glom/dialog_existing_or_new.cc:
	* glom/Makefile.am: Redesigned initial dialog, as described in
	http://www.murrayc.com/blog/permalink/2007/11/29/gloms-initial-dialog.

	* glom/application.h:
	* glom/application.cc: Actually use it.


Added:
   trunk/glom/dialog_existing_or_new.cc
   trunk/glom/dialog_existing_or_new.h
Modified:
   trunk/ChangeLog
   trunk/glom/Makefile.am
   trunk/glom/application.cc
   trunk/glom/application.h
   trunk/glom/glom.glade

Modified: trunk/glom/Makefile.am
==============================================================================
--- trunk/glom/Makefile.am	(original)
+++ trunk/glom/Makefile.am	Sun Mar 30 15:16:29 2008
@@ -39,6 +39,7 @@
                combobox_fields.h combobox_fields.cc \
                combobox_relationship.h combobox_relationship.cc \
                dialog_connection.h dialog_connection.cc \
+	       dialog_existing_or_new.h dialog_existing_or_new.cc \
                dialog_invalid_data.h dialog_invalid_data.cc \
                filechooser_export.h filechooser_export.cc \
                box_reports.h box_reports.cc \

Modified: trunk/glom/application.cc
==============================================================================
--- trunk/glom/application.cc	(original)
+++ trunk/glom/application.cc	Sun Mar 30 15:16:29 2008
@@ -19,6 +19,7 @@
  */
 
 #include "application.h"
+#include "dialog_existing_or_new.h"
 
 #include <glom/libglom/dialog_progress_creating.h>
 
@@ -1161,116 +1162,52 @@
     return false;
 #endif
 
-  Gtk::Dialog* dialog = 0;
-  refXml->get_widget("dialog_existing_or_new", dialog);
+  Dialog_ExistingOrNew* dialog_raw = 0;
+  refXml->get_widget_derived("dialog_existing_or_new", dialog_raw);
+  std::auto_ptr<Dialog_ExistingOrNew> dialog(dialog_raw);
   dialog->set_transient_for(*this);
 
-  Gtk::RecentChooserWidget* recent_chooser = NULL;
-  refXml->get_widget("existing_or_new_recentchooser", recent_chooser);
+  dialog->signal_new().connect(sigc::mem_fun(*this, &App_Glom::on_existing_or_new_new));
+  dialog->signal_open_from_uri().connect(sigc::mem_fun(*this, &App_Glom::on_existing_or_new_open_from_uri));
+  dialog->signal_open_from_remote().connect(sigc::mem_fun(*this, &App_Glom::on_existing_or_new_open_from_remote));
 
-  Gtk::RecentFilter filter;
-  filter.add_mime_type("application/x-glom");
-  recent_chooser->set_filter(filter);
-
-  /* Don't show files that don't exist anymore: */
-  recent_chooser->set_show_not_found(FALSE);
-
-  Gtk::Frame* recent_frame = NULL;
-  refXml->get_widget("existing_or_new_recentchooser_frame", recent_frame);
-
-  // Hide the recent chooser when they are not any recently used files
-  if(recent_chooser->get_items().empty()) recent_frame->hide();
-  recent_chooser->signal_item_activated().connect(sigc::bind(sigc::mem_fun(*dialog, &Gtk::Dialog::response), 1)); // Open
-
-#ifdef GLOM_ENABLE_CLIENT_ONLY
-  // Don't offer the user the chance to create a new document, because without
-  // developer mode he couldn't do anything useful with it, anyway.
-  Gtk::Button* new_button;
-  refXml->get_widget("existing_or_new_button_new", new_button);
-  new_button->hide();
-
-  refXml->get_widget("existing_or_new_button_example", new_button);
-  new_button->hide();
-
-  // Show another label that does not ask whether one wants to create a new
-  // document because that is not possible in client only mode
-  // TODO: Add another text, or simply hide the label?
-  Gtk::Label* label = 0;
-  refXml->get_widget("existing_or_new_label", label);
-  label->set_markup(_("<span weight='bold' size='larger'>Open existing document</span>\n"));
-#endif // GLOM_ENABLE_CLIENT_ONLY
-
-#ifdef GLOM_ENABLE_MAEMO
-  // Set dialog title to not show <unnamed> (default on maemo for empty title)
-  // Strip terminating newline.
-  dialog->set_title(label->get_text().substr(0, label->get_text().length()-1)); //TODO: Make this more robust.
-  label->hide();
-
-  // Stop the dialog from being too wide:
-  recent_chooser->set_size_request(500, -1);
-#endif
-
-  const int response_id = dialog->run();
-  Glib::ustring selected_uri = recent_chooser->get_current_uri();
-
-  delete dialog;
-  dialog = 0;
-
-  if(response_id == 1) //Open
+  bool ask_again = true;
+  while(ask_again)
   {
-    // When a recent document was selected, open that one instead.
-    if(selected_uri.empty())
-      on_menu_file_open();
-    else
-      open_document(selected_uri);
+    const int response_id = dialog->run();
+    dialog->hide();
 
-    //Check that a document was opened:
-    Document_Glom* document = dynamic_cast<Document_Glom*>(get_document());
-    if(document->get_file_uri().empty() && !(document->get_opened_from_browse()))
+    if(response_id == Gtk::RESPONSE_ACCEPT)
     {
-      //Ask again:
-      return offer_new_or_existing();
+      //Check that a document was opened:
+      Document_Glom* document = dynamic_cast<Document_Glom*>(get_document());
+      if(!document->get_file_uri().empty() || (document->get_opened_from_browse()))
+        ask_again = false;
     }
-  }
-#ifndef GLOM_ENABLE_CLIENT_ONLY
-  else if(response_id == 3) //Open Example
-  {
-    //Based on on_menu_file_open();
-
-    //Display File Open dialog and respond to choice:
-
-    //Bring document window to front, to make it clear which document is being changed:
-    ui_bring_to_front();
-
-    //Ask user to choose file to open:
-    //Create a URI (prefixed by file://) for this path).
-    //Previous versions of gnome-vfs could handle this without file://,
-    //but that stopped working at some point around Ubuntu Hardy. murrayc.
-    //g_warning("GLOM_EXAMPLES_DIR=%s", GLOM_EXAMPLES_DIR);
-    Glib::ustring examples_uri;
-    try
+    else if((response_id == Gtk::RESPONSE_CANCEL)  || (response_id == Gtk::RESPONSE_DELETE_EVENT))
     {
-      examples_uri = Glib::filename_to_uri(GLOM_EXAMPLES_DIR);
+      return false; //close the window to close the application, because they need to choose a new or existing document.
     }
-    catch(const Glib::Error& ex)
+    else
     {
-      std::cerr << "Glom: Error converting examples path to a URI: " << ex.what() << std::endl;
+      //Do nothing. TODO: Do something?
     }
-    
-    Glib::ustring file_uri = ui_file_select_open(examples_uri);
-    if(!file_uri.empty())
-      open_document(file_uri);
+  }
 
-    //Check that a document was opened:
-    Document_Glom* document = dynamic_cast<Document_Glom*>(get_document());
-    if(document->get_file_uri().empty())
-    {
-      //Ask again:
-      return offer_new_or_existing();
-    }
+  return true;
+}
+
+void App_Glom::on_existing_or_new_new(const std::string& template_uri)
+{
+  if(!template_uri.empty())
+  {
+    // New from template
+    open_document(template_uri);
   }
-  else if(response_id == 2) //New
+  else
   {
+    // New empty document
+
     //Each document must have a location, so ask the user for one.
     //This will use an extended save dialog that also asks for the database title and some hosting details:
     Glib::ustring db_title;
@@ -1297,93 +1234,70 @@
       document->set_connection_try_other_ports(!m_ui_save_extra_newdb_selfhosted);
 
       //Each new document must have an associated new database,
-      //so ask the user for the name of one to create:
-      
+      //so choose a name
 
-      bool keep_asking = true;
-      while(keep_asking)
+      //Create a database name based on the title.
+      //The user will (almost) never see this anyway but it's nicer than using a random number:
+      Glib::ustring db_name = Utils::create_name_from_title(db_title);
+
+      //Prefix glom_ to the database name, so it's more obvious
+      //for the system administrator.
+      //This database name should never be user-visible again, either prefixed or not prefixed.
+      db_name = "glom_" + db_name;
+
+      //Connect to the server and choose a variation of this db_name that does not exist yet:
+      document->set_connection_database(db_name);
+      document->set_connection_is_self_hosted(self_hosted);
+           
+#ifndef GLOM_ENABLE_CLIENT_ONLY
+     //Tell the connection pool about the document:
+     ConnectionPool* connection_pool = ConnectionPool::get_instance();
+     if(connection_pool)
+       connection_pool->set_get_document_func( sigc::mem_fun(*this, &App_Glom::on_connection_pool_get_document) );
+#endif
+
+      const bool connected = m_pFrame->connection_request_password_and_choose_new_database_name();
+      if(!connected)
+      {
+        // Unset URI so that the offer_new_or_existing does not disappear
+        // so the user can make a different choice about what document to open.
+        // TODO: Show some error message?
+        document->set_file_uri("");
+      }
+      else
       {
-        //Create a database name based on the title.
-        //The user will (almost) never see this anyway but it's nicer than using a random number:
-        Glib::ustring db_name = Utils::create_name_from_title(db_title);
-
-        //Prefix glom_ to the database name, so it's more obvious
-        //for the system administrator.
-        //This database name should never be user-visible again, either prefixed or not prefixed.
-        db_name = "glom_" + db_name;
-
-        if(!db_name.empty()) //The dialog and prefix prevent this anyway.
+        const bool db_created = m_pFrame->create_database(document->get_connection_database(), db_title, false /* do not request password */);
+        if(db_created)
         {
-          //Connect to the server and choose a variation of this db_name that does not exist yet:
-          document->set_connection_database(db_name);
-          document->set_connection_is_self_hosted(self_hosted);
-               
-#ifndef GLOM_ENABLE_CLIENT_ONLY
-         //Tell the connection pool about the document:
-         ConnectionPool* connection_pool = ConnectionPool::get_instance();
-         if(connection_pool)
-           connection_pool->set_get_document_func( sigc::mem_fun(*this, &App_Glom::on_connection_pool_get_document) );
-#endif
-
-          const bool connected = m_pFrame->connection_request_password_and_choose_new_database_name();
-          if(!connected)
-            return false;
-
-          const bool db_created = m_pFrame->create_database(document->get_connection_database(), db_title, false /* do not request password */);
-          if(db_created)
-          {
-            keep_asking = false;
-
-            //document->set_connection_database(db_name); //Select the database that was just created.
-
-            /*
-            ConnectionPool* connection_pool = ConnectionPool::get_instance();
-            if(connection_pool)
-            {
-              connection_pool->set_database(db_name); //The rest has been set while creating the database.
-            }
-            */
-
-            const Glib::ustring database_name_used = document->get_connection_database();
-            ConnectionPool::get_instance()->set_database(database_name_used);
-            document->set_database_title(db_title);
-            m_pFrame->set_databases_selected(database_name_used);
-          }
-          else
-          {
-            //Ask again:
-            return offer_new_or_existing();
-          }
+          const Glib::ustring database_name_used = document->get_connection_database();
+          ConnectionPool::get_instance()->set_database(database_name_used);
+          document->set_database_title(db_title);
+          m_pFrame->set_databases_selected(database_name_used);
         }
         else
         {
-           g_warning(" App_Glom::offer_new_or_existing(): db_name is empty.");
-           //And ask again, by going back to the start of the while() loop.
+          // Unset URI so that the offer_new_or_existing does not disappear
+          // so the user can make a different choice about what document to open.
+          // TODO: Show some error message?
+          document->set_file_uri("");
         }
-
-      } /* while() */
-
-      return true; //File successfully created.
-
-    }
-    else
-    {
-      //Ask again:
-      return offer_new_or_existing();
+      }
     }
   }
-#endif // !GLOM_ENABLE_CLIENT_ONLY
-  else if((response_id == Gtk::RESPONSE_CANCEL)  || (response_id == Gtk::RESPONSE_DELETE_EVENT))
-  {
-    return false; //close the window to close the application, because they need to choose a new or existing document.
-  }
-  else
-  {
-    //Do nothing. TODO: Do something?
-  }
+}
 
-  return true;
+void App_Glom::on_existing_or_new_open_from_uri(const std::string& document_uri)
+{
+  open_document(document_uri);
+}
+
+#ifndef G_OS_WIN32
+void App_Glom::on_existing_or_new_open_from_remote(EpcServiceInfo* info, const Glib::ustring& service_name)
+{
+  open_browsed_document(info, service_name);
 }
+#endif
+
 void App_Glom::set_mode_data()
 {
   m_action_mode_data->activate();

Modified: trunk/glom/application.h
==============================================================================
--- trunk/glom/application.h	(original)
+++ trunk/glom/application.h	Sun Mar 30 15:16:29 2008
@@ -98,6 +98,13 @@
 
   bool offer_new_or_existing();
 
+  void on_existing_or_new_new(const std::string& template_uri);
+  void on_existing_or_new_open_from_uri(const std::string& document_uri);
+
+#ifndef G_OS_WIN32
+  void on_existing_or_new_open_from_remote(EpcServiceInfo* info, const Glib::ustring& service_name);
+#endif
+
   void on_menu_help_contents();
 #ifndef GLOM_ENABLE_CLIENT_ONLY
   void on_menu_userlevel_developer();

Added: trunk/glom/dialog_existing_or_new.cc
==============================================================================
--- (empty file)
+++ trunk/glom/dialog_existing_or_new.cc	Sun Mar 30 15:16:29 2008
@@ -0,0 +1,498 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2004 Murray Cumming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "dialog_existing_or_new.h"
+
+#include <libxml++/parsers/saxparser.h>
+
+#include <glibmm/i18n.h>
+#include <giomm/contenttype.h>
+#include <gtkmm/recentmanager.h>
+#include <gtkmm/filechooserdialog.h>
+#include <gtkmm/stock.h>
+
+#ifdef G_OS_WIN32
+# include <glib/gwin32.h>
+#else
+# include <libepc/service-type.h>
+#endif
+
+#include <iostream>
+
+namespace
+{
+
+// Reads the title of an example from the first few characters of the XML
+class Parser: public xmlpp::SaxParser
+{
+public:
+  Parser() {}
+
+  Glib::ustring get_example_title(const std::string& beginning)
+  {
+    parse_chunk(beginning);
+    return m_title;
+  }
+
+protected:
+  virtual void on_start_element(const Glib::ustring& name, const AttributeList& attributes)
+  {
+    if(m_title.empty()) // Already found name? Wait for parse_chunk() call to return.
+    {
+      if(name == "glom_document")
+      {
+        for(AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++ iter)
+        {
+          if(iter->name == "database_title")
+          {
+            m_title = iter->value;
+            // TODO: We should stop parsing here somehow, but I don't
+            // think we can throw an exception through the C library back
+            // to get_example_name, and there does not seem to be API to
+            // stop parsing.
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  Glib::ustring m_title;
+};
+
+}
+
+namespace Glom
+{
+
+Dialog_ExistingOrNew::Dialog_ExistingOrNew(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade)
+: Gtk::Dialog(cobject)
+{
+  refGlade->get_widget("existing_or_new_existing_treeview", m_existing_view);
+  refGlade->get_widget("existing_or_new_new_treeview", m_new_view);
+
+  if(!m_existing_view || !m_new_view)
+    throw std::runtime_error("Glade file does not contain treeviews for ExistingOrNew dialog");
+
+  m_existing_model = Gtk::TreeStore::create(m_existing_columns);
+  m_existing_model->set_sort_column(m_existing_columns.m_col_time, Gtk::SORT_DESCENDING);
+  m_existing_view->set_model(m_existing_model);
+
+  m_new_model = Gtk::TreeStore::create(m_new_columns);
+  m_new_view->set_model(m_new_model);
+
+  m_existing_column_title.set_expand(true);
+  m_existing_column_title.pack_start(m_existing_icon_renderer, false);
+  m_existing_column_title.pack_start(m_existing_title_renderer, true);
+  m_existing_column_title.set_cell_data_func(m_existing_icon_renderer, sigc::mem_fun(*this, &Dialog_ExistingOrNew::existing_icon_data_func));
+  m_existing_column_title.add_attribute(m_existing_title_renderer, "text", m_existing_columns.m_col_title.index());
+  m_existing_view->append_column(m_existing_column_title);
+
+  m_existing_column_button.pack_end(m_existing_button_renderer, false);
+  m_existing_column_button.add_attribute(m_existing_button_renderer, "text", m_existing_columns.m_col_button_text.index());
+  m_existing_view->append_column(m_existing_column_button);
+
+  m_new_column_title.set_expand(true);
+  m_new_column_title.pack_start(m_new_icon_renderer, false);
+  m_new_column_title.pack_start(m_new_title_renderer, true);
+  m_new_column_title.set_cell_data_func(m_new_icon_renderer, sigc::mem_fun(*this, &Dialog_ExistingOrNew::new_icon_data_func));
+  m_new_column_title.add_attribute(m_new_title_renderer, "text", m_new_columns.m_col_title.index());
+  m_new_view->append_column(m_new_column_title);
+
+  m_new_column_button.pack_end(m_new_button_renderer, false);
+  m_new_column_button.add_attribute(m_new_button_renderer, "text", m_new_columns.m_col_button_text.index());
+  m_new_view->append_column(m_new_column_button);
+
+  m_existing_view->set_headers_visible(false);
+  m_existing_view->signal_row_activated().connect(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_existing_row_activated));
+  m_existing_button_renderer.signal_clicked().connect(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_existing_button_clicked));
+  m_new_view->set_headers_visible(false);
+  m_new_view->signal_row_activated().connect(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_new_row_activated));
+  m_new_button_renderer.signal_clicked().connect(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_new_button_clicked));
+
+  m_iter_existing_recent = m_existing_model->append();
+  (*m_iter_existing_recent)[m_existing_columns.m_col_title] = _("Recently Opened");
+  
+  m_iter_existing_network = m_existing_model->append();
+  (*m_iter_existing_network)[m_existing_columns.m_col_title] = _("Local Network");
+
+  m_iter_existing_other = m_existing_model->append();
+  (*m_iter_existing_other)[m_existing_columns.m_col_title] = _("Other");
+  (*m_iter_existing_other)[m_existing_columns.m_col_button_text] = _("Select Fileâ");
+  
+  m_iter_new_empty = m_new_model->append();
+  (*m_iter_new_empty)[m_new_columns.m_col_title] = _("New Empty Document");
+  (*m_iter_new_empty)[m_new_columns.m_col_button_text] = _("Create");
+
+  m_iter_new_template = m_new_model->append();
+  (*m_iter_new_template)[m_new_columns.m_col_title] = _("New From Template");
+
+  // Load example files
+#ifdef G_OS_WIN32
+  gchar* dir = g_win32_get_package_installation_subdirectory(NULL, NULL, "share/doc/examples");
+  std::string path(dir);
+  g_free(dir);
+#else
+  const char* path = GLOM_EXAMPLES_DIR;
+#endif
+
+  m_examples_dir = Gio::File::create_for_path(path);
+
+  try
+  {
+    m_examples_dir->enumerate_children_async(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_enumerate_children),
+                                             G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE","G_FILE_ATTRIBUTE_STANDARD_NAME);
+    // TODO: Monitor example directory for new/removed files?
+  }
+  catch(const Glib::Exception& ex)
+  {
+    std::cerr << "Could not enumerate examples: " << ex.what() << std::endl;
+  }
+
+  // Browse local network
+#ifndef G_OS_WIN32
+  gchar* service_type = epc_service_type_new(EPC_PROTOCOL_HTTPS, "glom");
+  m_service_monitor = epc_service_monitor_new_for_types(NULL, service_type, NULL);
+  g_signal_connect(m_service_monitor, "service-found", G_CALLBACK(on_service_found_static), this);
+  g_signal_connect(m_service_monitor, "service-removed", G_CALLBACK(on_service_removed_static), this);
+  g_free(service_type);
+#endif
+
+  // Add recently used files
+  Gtk::RecentManager::ListHandle_RecentInfos infos = Gtk::RecentManager::get_default()->get_items();
+  for(Gtk::RecentManager::ListHandle_RecentInfos::const_iterator iter = infos.begin(); iter != infos.end(); ++ iter)
+  {
+    Glib::RefPtr<Gtk::RecentInfo> info = *iter;
+    if(info->get_mime_type() == "application/x-glom")
+    {
+      Gtk::TreeIter iter = m_existing_model->append(m_iter_existing_recent->children());
+      (*iter)[m_existing_columns.m_col_title] = info->get_display_name();
+      (*iter)[m_existing_columns.m_col_time] = info->get_modified();
+      (*iter)[m_existing_columns.m_col_button_text] = _("Open");
+      (*iter)[m_existing_columns.m_col_recent_info] = new Glib::RefPtr<Gtk::RecentInfo>(info);
+    }
+  }
+}
+
+Dialog_ExistingOrNew::~Dialog_ExistingOrNew()
+{
+  if(m_service_monitor)
+  {
+    g_object_unref(m_service_monitor);
+    m_service_monitor = NULL;
+  }
+
+#ifndef G_OS_WIN32
+  // Release the service infos in the treestore
+  {
+    const Gtk::TreeNodeChildren& children = m_iter_existing_network->children();
+    for(Gtk::TreeIter iter = children.begin(); iter != children.end(); ++ iter)
+      epc_service_info_unref((*iter)[m_existing_columns.m_col_service_info]);
+  }
+#endif
+
+  // Release the recent infos (see comment in the header for why these
+  // have to be dynamically allocated)
+  {
+    const Gtk::TreeNodeChildren& children = m_iter_existing_recent->children();
+    for(Gtk::TreeIter iter = children.begin(); iter != children.end(); ++ iter)
+    {
+      Glib::RefPtr<Gtk::RecentInfo>* info = (*iter)[m_existing_columns.m_col_recent_info];
+      delete info;
+    }
+  }
+}
+
+void Dialog_ExistingOrNew::existing_icon_data_func(Gtk::CellRenderer* renderer, const Gtk::TreeIter& iter)
+{
+  Gtk::CellRendererPixbuf* pixbuf_renderer = dynamic_cast<Gtk::CellRendererPixbuf*>(renderer);
+  if(!pixbuf_renderer) throw std::logic_error("Renderer not a pixbuf renderer in existing_icon_data_func");
+
+  pixbuf_renderer->property_stock_size() = Gtk::ICON_SIZE_BUTTON;
+  pixbuf_renderer->property_stock_id() = "";
+  pixbuf_renderer->property_pixbuf() = Glib::RefPtr<Gdk::Pixbuf>();
+      
+  if(iter == m_iter_existing_recent)
+    pixbuf_renderer->property_stock_id() = Gtk::Stock::INDEX.id; // TODO: More meaningful icon?
+  else if(iter == m_iter_existing_network)
+    pixbuf_renderer->property_stock_id() = Gtk::Stock::NETWORK.id;
+  else if(iter == m_iter_existing_other)
+    pixbuf_renderer->property_stock_id() = Gtk::Stock::OPEN.id;
+  else
+  {
+    if(m_existing_model->is_ancestor(m_iter_existing_recent, iter))
+    {
+      //Glib::RefPtr<Gtk::RecentInfo>* info = (*iter)[m_existing_columns.m_col_recent_info];
+      //pixbuf_renderer->property_pixbuf() = (*info)->get_icon(Gtk::ICON_SIZE_BUTTON);
+      pixbuf_renderer->set_property("icon-name", Glib::ustring("glom"));
+    }
+    else if(m_existing_model->is_ancestor(m_iter_existing_network, iter))
+    {
+      //pixbuf_renderer->property_stock_id() = Gtk::Stock::CONNECT.id;
+      pixbuf_renderer->set_property("icon-name", Glib::ustring("glom"));
+    }
+    else
+    {
+      throw std::logic_error("Unexpected iterator in existing_icon_data_func");
+    }
+  }
+}
+
+void Dialog_ExistingOrNew::new_icon_data_func(Gtk::CellRenderer* renderer, const Gtk::TreeIter& iter)
+{
+  Gtk::CellRendererPixbuf* pixbuf_renderer = dynamic_cast<Gtk::CellRendererPixbuf*>(renderer);
+  if(!pixbuf_renderer) throw std::logic_error("Renderer not a pixbuf renderer in new_icon_data_func");
+
+  pixbuf_renderer->property_stock_size() = Gtk::ICON_SIZE_BUTTON;
+  pixbuf_renderer->property_stock_id() = "";
+  pixbuf_renderer->property_pixbuf() = Glib::RefPtr<Gdk::Pixbuf>();
+      
+  if(iter == m_iter_new_empty)
+    pixbuf_renderer->property_stock_id() = Gtk::Stock::NEW.id;
+  else if(iter == m_iter_new_template)
+    pixbuf_renderer->property_stock_id() = Gtk::Stock::EDIT.id; // TODO: More meaningful icon?
+  else
+  {
+    if(m_new_model->is_ancestor(m_iter_new_template, iter))
+    {
+      pixbuf_renderer->set_property("icon-name", Glib::ustring("glom"));
+    }
+    else
+    {
+      throw std::logic_error("Unexpected iterator in new_icon_data_func");
+    }
+  }
+}
+
+void Dialog_ExistingOrNew::on_enumerate_children(const Glib::RefPtr<Gio::AsyncResult>& res)
+{
+  try
+  {
+    m_examples_enumerator = m_examples_dir->enumerate_children_finish(res);
+    m_examples_enumerator->next_files_async(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_next_files));
+  }
+  catch(const Glib::Exception& ex)
+  {
+    std::cerr << "Could not enumerate examples: " << ex.what() << std::endl;
+    
+    m_examples_enumerator.reset();
+    m_examples_dir.reset();
+  }
+}
+
+void Dialog_ExistingOrNew::on_next_files(const Glib::RefPtr<Gio::AsyncResult>& res)
+{
+  try
+  {
+    const Glib::ListHandle<Glib::RefPtr<Gio::FileInfo> >& list = m_examples_enumerator->next_files_finish(res);
+    if (list.empty())
+    {
+      // Done
+      m_examples_dir.reset();
+      m_examples_enumerator.reset();
+    }
+    else
+    {
+      // Load file
+      Glib::RefPtr<Gio::FileInfo> info = *list.begin();
+      Glib::ustring content_type = info->get_attribute_string(G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
+      Glib::ustring mime_type = Gio::content_type_get_mime_type(content_type);
+
+      if(mime_type == "application/x-glom")
+      {
+        m_current_example = Gio::File::create_for_path(Glib::build_filename(m_examples_dir->get_path(), info->get_name()));
+        m_current_example->read_async(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_read));
+      }
+      else
+      {
+        // File is not a glom file, continue with next
+        m_examples_enumerator->next_files_async(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_next_files));
+      }
+    }
+  }
+  catch(const Glib::Exception& ex)
+  {
+    std::cerr << "Could not enumerate examples: " << ex.what() << std::endl;
+
+    m_examples_dir.reset();
+    m_examples_enumerator.reset();
+  }
+}
+
+void Dialog_ExistingOrNew::on_read(const Glib::RefPtr<Gio::AsyncResult>& res)
+{
+  try
+  {
+    m_current_stream = m_current_example->read_finish(res);
+    m_current_buffer.reset(new buffer);
+    m_current_stream->read_async(m_current_buffer->buf, buffer::SIZE, sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_stream_read));
+  }
+  catch(const Glib::Exception& exception)
+  {
+    // Could not read this file, read next
+    m_examples_enumerator->next_files_async(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_next_files));
+
+    m_current_example.reset();
+    m_current_stream.reset();
+    m_current_buffer.reset();
+  }
+}
+
+void Dialog_ExistingOrNew::on_stream_read(const Glib::RefPtr<Gio::AsyncResult>& res)
+{
+  try
+  {
+    gssize size_read = m_current_stream->read_finish(res);
+    std::string data(m_current_buffer->buf, size_read);
+    // TODO: Check that data is valid UTF-8, the last character might be truncated
+
+    Parser parser;
+    Glib::ustring title = parser.get_example_title(data);
+
+    if(title.empty())
+    {
+      // TODO: Read more data from this file?
+    }
+    else
+    {
+      // Add to list
+      Gtk::TreeIter iter = m_new_model->append(m_iter_new_template->children());
+      (*iter)[m_new_columns.m_col_title] = title;
+      (*iter)[m_new_columns.m_col_button_text] = _("Create");
+      (*iter)[m_new_columns.m_col_template_uri] = m_current_example->get_uri();
+    }
+  }
+  catch(const Glib::Exception& ex)
+  {
+    std::cerr << "Could not read " << m_current_example->get_path() << ": " << ex.what() << std::endl;
+  }
+
+  // Done with this, read next file
+  m_current_example.reset();
+  m_current_stream.reset();
+  m_current_buffer.reset();
+
+  m_examples_enumerator->next_files_async(sigc::mem_fun(*this, &Dialog_ExistingOrNew::on_next_files));
+}
+
+#ifndef G_OS_WIN32
+void Dialog_ExistingOrNew::on_service_found(const Glib::ustring& name, EpcServiceInfo* info)
+{
+  gchar* title = g_strdup_printf(_("%s on %s (via %s)"), name.c_str(), epc_service_info_get_host(info), epc_service_info_get_interface(info));
+  Gtk::TreeIter iter = m_existing_model->prepend(m_iter_existing_network->children());
+  (*iter)[m_existing_columns.m_col_title] = title;
+  (*iter)[m_existing_columns.m_col_button_text] = _("Open");
+  (*iter)[m_existing_columns.m_col_time] = std::time(NULL); /* sort more recently discovered items above */
+  (*iter)[m_existing_columns.m_col_service_name] = name;
+  (*iter)[m_existing_columns.m_col_service_info] = info;
+
+  epc_service_info_ref(info);
+  g_free(title);
+}
+
+void Dialog_ExistingOrNew::on_service_removed(const Glib::ustring& name, const Glib::ustring& type)
+{
+  // Find the entry with the given name
+  const Gtk::TreeNodeChildren& children = m_iter_existing_network->children();
+  for(Gtk::TreeIter iter = children.begin(); iter != children.end(); ++ iter)
+  {
+    if((*iter)[m_existing_columns.m_col_service_name] == name)
+    {
+      // Remove from store
+      epc_service_info_unref((*iter)[m_existing_columns.m_col_service_info]);
+      m_existing_model->erase(iter);
+      break;
+    }
+  }
+}
+#endif // !G_OS_WIN32
+
+void Dialog_ExistingOrNew::on_existing_row_activated(const Gtk::TreePath& path, Gtk::TreeViewColumn* column)
+{
+  existing_activated(m_existing_model->get_iter(path));
+}
+
+void Dialog_ExistingOrNew::on_existing_button_clicked(const Gtk::TreePath& path)
+{
+  existing_activated(m_existing_model->get_iter(path));
+}
+
+void Dialog_ExistingOrNew::on_new_row_activated(const Gtk::TreePath& path, Gtk::TreeViewColumn* column)
+{
+  new_activated(m_new_model->get_iter(path));
+}
+
+void Dialog_ExistingOrNew::on_new_button_clicked(const Gtk::TreePath& path)
+{
+  new_activated(m_new_model->get_iter(path));
+}
+
+void Dialog_ExistingOrNew::existing_activated(const Gtk::TreeIter& iter)
+{
+  if(iter == m_iter_existing_other)
+  {
+    Gtk::FileChooserDialog dialog(*this, "Choose a glom file to open");
+    Gtk::FileFilter filter;
+    filter.add_mime_type("application/x-glom");
+    filter.set_name("Glom files");
+    dialog.add_filter(filter);
+
+    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+    dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
+    //dialog.set_default_response(Gtk::RESPONSE_ACCEPT);
+
+    if(dialog.run() == Gtk::RESPONSE_ACCEPT)
+    {
+      dialog.hide();
+      m_signal_open_from_uri.emit(dialog.get_uri());
+      response(Gtk::RESPONSE_ACCEPT);
+    }
+  }
+  else if(m_existing_model->is_ancestor(m_iter_existing_recent, iter))
+  {
+    Glib::RefPtr<Gtk::RecentInfo>* info = (*iter)[m_existing_columns.m_col_recent_info];
+    m_signal_open_from_uri.emit((*info)->get_uri());
+    response(Gtk::RESPONSE_ACCEPT);
+  }
+  else if(m_existing_model->is_ancestor(m_iter_existing_network, iter))
+  {
+#ifndef G_OS_WIN32
+    m_signal_open_from_remote.emit((*iter)[m_existing_columns.m_col_service_info], (*iter)[m_existing_columns.m_col_service_name]);
+    response(Gtk::RESPONSE_ACCEPT);
+#endif
+  }
+}
+
+void Dialog_ExistingOrNew::new_activated(const Gtk::TreeIter& iter)
+{
+  if(iter == m_iter_new_empty)
+  {
+    m_signal_new.emit(std::string());
+    response(Gtk::RESPONSE_ACCEPT);
+  }
+  else if(m_new_model->is_ancestor(m_iter_new_template, iter))
+  {
+    m_signal_new.emit((*iter)[m_new_columns.m_col_template_uri]);
+    response(Gtk::RESPONSE_ACCEPT);
+  }
+}
+
+} //namespace Glom

Added: trunk/glom/dialog_existing_or_new.h
==============================================================================
--- (empty file)
+++ trunk/glom/dialog_existing_or_new.h	Sun Mar 30 15:16:29 2008
@@ -0,0 +1,185 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2004 Murray Cumming
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLOM_DIALOG_EXISTING_OR_NEW_H
+#define GLOM_DIALOG_EXISTING_OR_NEW_H
+
+#ifndef G_OS_WIN32
+# include <libepc/service-monitor.h>
+#endif
+
+#include <memory>
+#include <giomm/asyncresult.h>
+#include <giomm/file.h>
+#include <giomm/fileenumerator.h>
+#include <giomm/inputstream.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/recentinfo.h>
+#include <libglademm/xml.h>
+#include <glom/utility_widgets/db_adddel/cellrenderer_buttontext.h>
+
+namespace Glom
+{
+
+class Dialog_ExistingOrNew
+  : public Gtk::Dialog
+{
+  typedef sigc::signal<void, const std::string&> SignalNew;
+  typedef sigc::signal<void, const std::string&> SignalOpenFromUri;
+#ifndef G_OS_WIN32
+  typedef sigc::signal<void, EpcServiceInfo*, const Glib::ustring&> SignalOpenFromRemote;
+#endif
+
+public:
+  Dialog_ExistingOrNew(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& refGlade);
+  virtual ~Dialog_ExistingOrNew();
+
+  SignalNew signal_new() const { return m_signal_new; }
+  SignalOpenFromUri signal_open_from_uri() const { return m_signal_open_from_uri; }
+
+#ifndef G_OS_WIN32
+  SignalOpenFromRemote signal_open_from_remote() const { return m_signal_open_from_remote; }
+#endif
+
+protected:
+  void existing_icon_data_func(Gtk::CellRenderer* renderer, const Gtk::TreeIter& iter);
+  void new_icon_data_func(Gtk::CellRenderer* renderer, const Gtk::TreeIter& iter);
+
+  void on_enumerate_children(const Glib::RefPtr<Gio::AsyncResult>& res);
+  void on_next_files(const Glib::RefPtr<Gio::AsyncResult>& res);
+  void on_read(const Glib::RefPtr<Gio::AsyncResult>& res);
+  void on_stream_read(const Glib::RefPtr<Gio::AsyncResult>& res);
+
+#ifndef G_OS_WIN32
+  static void on_service_found_static(EpcServiceMonitor* monitor, gchar* name, EpcServiceInfo* info, gpointer user_data) { static_cast<Dialog_ExistingOrNew*>(user_data)->on_service_found(name, info); }
+  static void on_service_removed_static(EpcServiceMonitor* monitor, gchar* name, gchar* type, gpointer user_data) { static_cast<Dialog_ExistingOrNew*>(user_data)->on_service_removed(name, type); }
+
+  void on_service_found(const Glib::ustring& name, EpcServiceInfo* info);
+  void on_service_removed(const Glib::ustring& name, const Glib::ustring& type);
+#endif
+
+  void on_existing_row_activated(const Gtk::TreePath& path, Gtk::TreeViewColumn* column);
+  void on_existing_button_clicked(const Gtk::TreePath& path);
+  void on_new_row_activated(const Gtk::TreePath& path, Gtk::TreeViewColumn* column);
+  void on_new_button_clicked(const Gtk::TreePath& path);
+
+  void existing_activated(const Gtk::TreeIter& iter);
+  void new_activated(const Gtk::TreeIter& iter);
+
+  class ExistingModelColumns : public Gtk::TreeModel::ColumnRecord
+  {
+  public:
+
+    ExistingModelColumns()
+    {
+      add(m_col_title);
+      add(m_col_button_text); 
+      add(m_col_time);
+
+#ifndef G_OS_WIN32
+      add(m_col_service_name);
+      add(m_col_service_info);
+#endif
+
+      add(m_col_recent_info);
+    }
+
+    Gtk::TreeModelColumn<Glib::ustring> m_col_title;
+    Gtk::TreeModelColumn<Glib::ustring> m_col_button_text;
+    Gtk::TreeModelColumn<std::time_t> m_col_time; // Sort criteria
+
+#ifndef G_OS_WIN32
+    // For service discovery:
+    Gtk::TreeModelColumn<Glib::ustring> m_col_service_name;
+    Gtk::TreeModelColumn<EpcServiceInfo*> m_col_service_info;
+#endif
+
+    // For recently used resources:
+    // TODO: We can't use Glib::RefPtr<Gtk::RecentInfo> directly here, due to
+    // bug #. Therefore, the refptrs are dynamically allocated and explicitely
+    // freed in the destructor.
+    Gtk::TreeModelColumn<Glib::RefPtr<Gtk::RecentInfo>*> m_col_recent_info;
+  };
+  
+  class NewModelColumns : public Gtk::TreeModel::ColumnRecord
+  {
+  public:
+
+    NewModelColumns()
+    { add(m_col_title); add(m_col_button_text); add(m_col_template_uri); }
+
+    Gtk::TreeModelColumn<Glib::ustring> m_col_title;
+    Gtk::TreeModelColumn<Glib::ustring> m_col_button_text;
+    Gtk::TreeModelColumn<std::string> m_col_template_uri;
+  };
+
+  ExistingModelColumns m_existing_columns;
+  Glib::RefPtr<Gtk::TreeStore> m_existing_model;
+  Gtk::TreeView* m_existing_view;
+
+  NewModelColumns m_new_columns;
+  Gtk::TreeView* m_new_view;
+  Glib::RefPtr<Gtk::TreeStore> m_new_model;
+
+  Gtk::TreeViewColumn m_existing_column_title;
+  Gtk::TreeViewColumn m_existing_column_button;
+  Gtk::CellRendererPixbuf m_existing_icon_renderer;
+  Gtk::CellRendererText m_existing_title_renderer;
+  GlomCellRenderer_ButtonText m_existing_button_renderer;
+
+  Gtk::TreeViewColumn m_new_column_title;
+  Gtk::TreeViewColumn m_new_column_button;
+  Gtk::CellRendererPixbuf m_new_icon_renderer;
+  Gtk::CellRendererText m_new_title_renderer;
+  GlomCellRenderer_ButtonText m_new_button_renderer;
+
+  Gtk::TreeIter m_iter_existing_recent;
+  Gtk::TreeIter m_iter_existing_network;
+  Gtk::TreeIter m_iter_existing_other;
+
+  Gtk::TreeIter m_iter_new_empty;
+  Gtk::TreeIter m_iter_new_template;
+  
+  Glib::RefPtr<Gio::File> m_examples_dir;
+  Glib::RefPtr<Gio::FileEnumerator> m_examples_enumerator;
+  Glib::RefPtr<Gio::File> m_current_example;
+  Glib::RefPtr<Gio::InputStream> m_current_stream;
+
+  struct buffer { static const guint SIZE = 1024; char buf[SIZE]; };
+  std::auto_ptr<buffer> m_current_buffer;
+
+#ifndef G_OS_WIN32
+  EpcServiceMonitor* m_service_monitor;
+#endif
+
+  SignalNew m_signal_new;
+  SignalOpenFromUri m_signal_open_from_uri;
+
+#ifndef G_OS_WIN32
+  SignalOpenFromRemote m_signal_open_from_remote;
+#endif
+};
+
+} //namespace Glom
+
+#endif //GLOM_DIALOG_DATABASE_PREFERENCES_H
+

Modified: trunk/glom/glom.glade
==============================================================================
--- trunk/glom/glom.glade	(original)
+++ trunk/glom/glom.glade	Sun Mar 30 15:16:29 2008
@@ -193,6 +193,8 @@
     </child>
   </widget>
   <widget class="GtkDialog" id="dialog_existing_or_new">
+    <property name="default_width">480</property>
+    <property name="default_height">320</property>
     <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
     <child internal-child="vbox">
       <widget class="GtkVBox" id="dialog-vbox1">
@@ -219,25 +221,24 @@
               <widget class="GtkVBox" id="vbox4">
                 <property name="visible">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="spacing">12</property>
                 <child>
                   <widget class="GtkLabel" id="existing_or_new_label">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="xalign">0</property>
                     <property name="yalign">0</property>
-                    <property name="label" translatable="yes">&lt;span weight="bold" size="larger"&gt;Open existing document, or create new document&lt;/span&gt;
-
-Would you like to open an existing document, to connect to an existing database?
-
-Or would you like to create a new document, to design a new database?
-</property>
+                    <property name="label" translatable="yes">&lt;span weight="bold" size="larger"&gt;Please open an existing document or create new document&lt;/span&gt;</property>
                     <property name="use_markup">True</property>
                     <property name="wrap">True</property>
                     <property name="selectable">True</property>
                   </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                  </packing>
                 </child>
                 <child>
-                  <widget class="GtkFrame" id="existing_or_new_recentchooser_frame">
+                  <widget class="GtkFrame" id="existing_or_new_existing_frame">
                     <property name="visible">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                     <property name="label_xalign">0</property>
@@ -246,15 +247,25 @@
                       <widget class="GtkAlignment" id="alignment3">
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="top_padding">6</property>
                         <property name="left_padding">12</property>
                         <child>
-                          <widget class="GtkRecentChooserWidget" id="existing_or_new_recentchooser">
+                          <widget class="GtkScrolledWindow" id="scrolledwindow2">
                             <property name="visible">True</property>
+                            <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                            <property name="show_not_found">True</property>
-                            <property name="show_tips">True</property>
-                            <property name="sort_type">GTK_RECENT_SORT_MRU</property>
-                            <property name="limit">15</property>
+                            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                            <property name="shadow_type">GTK_SHADOW_IN</property>
+                            <child>
+                              <widget class="GtkTreeView" id="existing_or_new_existing_treeview">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="headers_clickable">True</property>
+                                <property name="search_column">0</property>
+                              </widget>
+                            </child>
                           </widget>
                         </child>
                       </widget>
@@ -263,7 +274,7 @@
                       <widget class="GtkLabel" id="label6">
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Recently Opened Files:&lt;/b&gt;</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Open Existing Document&lt;/b&gt;</property>
                         <property name="use_markup">True</property>
                       </widget>
                       <packing>
@@ -275,102 +286,77 @@
                     <property name="position">1</property>
                   </packing>
                 </child>
-              </widget>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <widget class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="layout_style">GTK_BUTTONBOX_END</property>
-            <child>
-              <widget class="GtkButton" id="cancelbutton1">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="label">gtk-cancel</property>
-                <property name="use_stock">True</property>
-                <property name="response_id">-6</property>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkButton" id="existing_or_new_button_new">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="label">gtk-new</property>
-                <property name="use_stock">True</property>
-                <property name="response_id">2</property>
-              </widget>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkButton" id="existing_or_new_button_example">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
-                <property name="response_id">3</property>
                 <child>
-                  <widget class="GtkAlignment" id="alignment71">
+                  <widget class="GtkFrame" id="existing_or_new_new_frame">
                     <property name="visible">True</property>
-                    <property name="xscale">0</property>
-                    <property name="yscale">0</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">GTK_SHADOW_NONE</property>
                     <child>
-                      <widget class="GtkHBox" id="hbox82">
+                      <widget class="GtkAlignment" id="alignment1">
                         <property name="visible">True</property>
-                        <property name="spacing">2</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="top_padding">6</property>
+                        <property name="left_padding">12</property>
                         <child>
-                          <widget class="GtkImage" id="image32">
+                          <widget class="GtkScrolledWindow" id="scrolledwindow3">
                             <property name="visible">True</property>
-                            <property name="stock">gtk-new</property>
+                            <property name="can_focus">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                            <property name="shadow_type">GTK_SHADOW_IN</property>
+                            <child>
+                              <widget class="GtkTreeView" id="existing_or_new_new_treeview">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="headers_clickable">True</property>
+                              </widget>
+                            </child>
                           </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkLabel" id="label207">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">New From Example</property>
-                            <property name="use_underline">True</property>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">1</property>
-                          </packing>
                         </child>
                       </widget>
                     </child>
+                    <child>
+                      <widget class="GtkLabel" id="label1">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Create New Document&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                      <packing>
+                        <property name="type">label_item</property>
+                      </packing>
+                    </child>
                   </widget>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
                 </child>
               </widget>
               <packing>
-                <property name="position">2</property>
+                <property name="position">1</property>
               </packing>
             </child>
+          </widget>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
             <child>
-              <widget class="GtkButton" id="button_open">
+              <widget class="GtkButton" id="cancelbutton1">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
-                <property name="label">gtk-open</property>
+                <property name="label">gtk-close</property>
                 <property name="use_stock">True</property>
-                <property name="response_id">1</property>
+                <property name="response_id">-6</property>
               </widget>
-              <packing>
-                <property name="position">3</property>
-              </packing>
             </child>
           </widget>
           <packing>
@@ -449,128 +435,125 @@
                     <property name="column_spacing">6</property>
                     <property name="row_spacing">6</property>
                     <child>
-                      <widget class="GtkLabel" id="label_database">
+                      <widget class="GtkEntry" id="entry_host">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
+                        <property name="can_focus">True</property>
                       </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                        <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label68">
+                      <widget class="GtkLabel" id="label64">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Database</property>
+                        <property name="label" translatable="yes">_Host</property>
+                        <property name="use_underline">True</property>
                         <property name="justify">GTK_JUSTIFY_RIGHT</property>
+                        <property name="mnemonic_widget">entry_host</property>
+                        <accessibility>
+                          <atkrelation target="entry_host" type="label-for"/>
+                        </accessibility>
                       </widget>
                       <packing>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label65">
+                      <widget class="GtkLabel" id="label66">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
-                        <property name="label" translatable="yes">_User</property>
+                        <property name="label" translatable="yes">_Password</property>
                         <property name="use_underline">True</property>
                         <property name="justify">GTK_JUSTIFY_RIGHT</property>
-                        <property name="mnemonic_widget">entry_user</property>
+                        <property name="mnemonic_widget">entry_password</property>
                         <accessibility>
-                          <atkrelation target="entry_user" type="label-for"/>
+                          <atkrelation target="entry_password" type="label-for"/>
                         </accessibility>
                       </widget>
                       <packing>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkEntry" id="entry_user">
+                      <widget class="GtkEntry" id="entry_password">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="invisible_char">*</property>
+                        <property name="has_focus">True</property>
+                        <property name="visibility">False</property>
+                        <property name="activates_default">True</property>
                       </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkEntry" id="entry_password">
+                      <widget class="GtkEntry" id="entry_user">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="has_focus">True</property>
-                        <property name="visibility">False</property>
-                        <property name="invisible_char">*</property>
-                        <property name="activates_default">True</property>
                       </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label66">
+                      <widget class="GtkLabel" id="label65">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
-                        <property name="label" translatable="yes">_Password</property>
+                        <property name="label" translatable="yes">_User</property>
                         <property name="use_underline">True</property>
                         <property name="justify">GTK_JUSTIFY_RIGHT</property>
-                        <property name="mnemonic_widget">entry_password</property>
+                        <property name="mnemonic_widget">entry_user</property>
                         <accessibility>
-                          <atkrelation target="entry_password" type="label-for"/>
+                          <atkrelation target="entry_user" type="label-for"/>
                         </accessibility>
                       </widget>
                       <packing>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label64">
+                      <widget class="GtkLabel" id="label68">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
-                        <property name="label" translatable="yes">_Host</property>
-                        <property name="use_underline">True</property>
+                        <property name="label" translatable="yes">Database</property>
                         <property name="justify">GTK_JUSTIFY_RIGHT</property>
-                        <property name="mnemonic_widget">entry_host</property>
-                        <accessibility>
-                          <atkrelation target="entry_host" type="label-for"/>
-                        </accessibility>
                       </widget>
                       <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkEntry" id="entry_host">
+                      <widget class="GtkLabel" id="label_database">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="invisible_char">*</property>
+                        <property name="xalign">0</property>
                       </widget>
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
                     </child>
@@ -930,7 +913,6 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="has_focus">True</property>
-                                <property name="invisible_char">*</property>
                                 <property name="activates_default">True</property>
                               </widget>
                               <packing>
@@ -1141,7 +1123,6 @@
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="has_focus">True</property>
-                    <property name="invisible_char">*</property>
                   </widget>
                   <packing>
                     <property name="position">1</property>
@@ -1249,9 +1230,12 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkLabel" id="label_records_count">
+                      <widget class="GtkButton" id="button_find_all">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes">0</property>
+                        <property name="can_focus">True</property>
+                        <property name="label" translatable="yes">Find All</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
@@ -1261,12 +1245,9 @@
                       </packing>
                     </child>
                     <child>
-                      <widget class="GtkButton" id="button_find_all">
+                      <widget class="GtkLabel" id="label_records_count">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="label" translatable="yes">Find All</property>
-                        <property name="use_underline">True</property>
-                        <property name="response_id">0</property>
+                        <property name="label" translatable="yes">0</property>
                       </widget>
                       <packing>
                         <property name="expand">False</property>



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