[gtkmm-documentation] Added Gtk::Application example.



commit 448b91f0f0b7d1ea25872d1c83be353d02193d12
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Mar 4 12:20:35 2011 +0100

    	Added Gtk::Application example.
    
    	* examples/Makefile.am:
    	* examples/book/application/: Added an example of Gtk::Application, opening
    	text files and doing some command-line parsing.
    
    	There is still a warning at the end which we should deal with:
    	(example:17496): Gtk-CRITICAL **: gtk_main_quit: assertion `main_loops != NULL' failed

 ChangeLog                                       |   11 +++
 examples/Makefile.am                            |    2 +
 examples/book/application/exampleapplication.cc |   82 ++++++++++++++++++++---
 examples/book/application/exampleapplication.h  |    7 +-
 examples/book/application/examplewindow.cc      |   25 +++++--
 examples/book/application/examplewindow.h       |   12 +++-
 examples/book/application/main.cc               |   10 +---
 7 files changed, 118 insertions(+), 31 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index bb95ccc..dfad185 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-03-04  Murray Cumming  <murrayc murrayc com>
+
+	Added Gtk::Application example.
+
+	* examples/Makefile.am:
+	* examples/book/application/: Added an example of Gtk::Application, opening 
+	text files and doing some command-line parsing.
+	
+	There is still a warning at the end which we should deal with:
+	(example:17496): Gtk-CRITICAL **: gtk_main_quit: assertion `main_loops != NULL' failed
+	
 2011-02-22  Murray Cumming  <murrayc murrayc com>
 
 	Code-style changes.
diff --git a/examples/Makefile.am b/examples/Makefile.am
index bd1836e..9383470 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -131,6 +131,8 @@ dist_noinst_DATA =				\
 book_application_example_SOURCES =		\
 	book/application/exampleapplication.cc	\
 	book/application/exampleapplication.h	\
+	book/application/exampleoptiongroup.cc	\
+	book/application/exampleoptiongroup.h	\
 	book/application/examplewindow.cc	\
 	book/application/examplewindow.h	\
 	book/application/main.cc
diff --git a/examples/book/application/exampleapplication.cc b/examples/book/application/exampleapplication.cc
index 62fa783..530da7c 100644
--- a/examples/book/application/exampleapplication.cc
+++ b/examples/book/application/exampleapplication.cc
@@ -16,32 +16,37 @@
 
 #include "exampleapplication.h"
 #include "examplewindow.h"
+#include "exampleoptiongroup.h"
 #include <iostream>
 
-ExampleApplication::ExampleApplication(const Glib::ustring& application_id, Gio::ApplicationFlags flags)
-: Gtk::Application(application_id, flags)
+ExampleApplication::ExampleApplication()
+: Gtk::Application("org.gtkmm.examples.application",
+    Gio::ApplicationFlags(Gio::APPLICATION_HANDLES_OPEN | Gio::APPLICATION_HANDLES_COMMAND_LINE))
 {
 }
 
-Glib::RefPtr<ExampleApplication> ExampleApplication::create(const Glib::ustring& application_id, 
-  Gio::ApplicationFlags flags)
+Glib::RefPtr<ExampleApplication> ExampleApplication::create()
 {
-  return Glib::RefPtr<ExampleApplication>( new ExampleApplication(application_id, flags) );
+  return Glib::RefPtr<ExampleApplication>( new ExampleApplication() );
 }
 
 void ExampleApplication::create_window(const Glib::RefPtr<Gio::File>& file)
 {
-  Gtk::Window* window = new ExampleWindow(file);
+  ExampleWindow* window = new ExampleWindow();
   
   //Make sure that the application runs for as long this window is still open:
-  add_window(*window); 
+  add_window(*window);
   
   //Delete the window when it is hidden.
   //That's enough for this simple example.
   window->signal_hide().connect(sigc::bind<Gtk::Window*>(sigc::mem_fun(*this,
     &ExampleApplication::on_window_hide), window));
-
+  
   window->show();
+  
+  const bool loaded = window->load_file(file);
+  if(!loaded)
+    std::cerr << "This file could not be loaded: " << file->get_path() << std::endl;
 }
 
 void ExampleApplication::on_window_hide(Gtk::Window* window)
@@ -51,6 +56,7 @@ void ExampleApplication::on_window_hide(Gtk::Window* window)
 
 void ExampleApplication::on_activate()
 {
+  std::cout << "debug1: " << G_STRFUNC << std::endl;
   // The application has been started, so let's show a window.
   // A real application might want to reuse this "empty" window in on_open(),
   // when asked to open a file, if no changes have been made yet.
@@ -65,8 +71,66 @@ void ExampleApplication::on_open(const Gio::Application::type_vec_files& files,
   std::cout << "debug: files.size()=" << files.size() << std::endl;
   for(guint i = 0; i < files.size(); i++)
   {
-    create_window(files[i]);
+    Glib::RefPtr<Gio::File> file = files[0];
+    if(!file)
+    {
+      std::cerr << G_STRFUNC << ": file is null." << std::endl;
+    }
+    else
+      create_window(file);
   }
   
   Application::on_open(files, hint);
 }
+
+int ExampleApplication::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine>& command_line)
+{
+  //Parse command-line arguments that were passed either to the main (first) instance 
+  //or to subsequent instances.
+  //Note that this parsing is happening in the main (not remote) instance.
+  int argc = 0;
+  char** argv =	command_line->get_arguments(argc);
+  
+  Glib::OptionContext context;
+  ExampleOptionGroup group;
+  context.set_main_group(group);
+  
+  try
+  {
+    context.parse(argc, argv);
+  }
+  catch(const Glib::Error& ex)
+  {
+    std::cerr << "Exception parsing command-line: " << ex.what() << std::endl;
+    std::cerr << context.get_help() << std::endl;
+    return EXIT_FAILURE;
+  }
+  
+  // The GOption documentation says that options without names will be returned 
+  // to the application as "rest arguments", meaning they will be left in the argv.
+  std::string filepath;
+  if(argc > 1)
+  {
+    const char* pch = argv[1];
+    if(pch)
+      filepath = pch;
+  }
+  
+  if(filepath.empty())
+  {
+    std::cerr << "No filepath was provided." << std::endl;
+    std::cerr << context.get_help() << std::endl;
+    return EXIT_FAILURE;
+  }
+
+  std::cout << "debug: parsed values: " << std::endl <<
+    "  foo = " << group.m_arg_foo << std::endl << 
+    "  goo = " << group.m_arg_goo << std::endl <<
+    "  filepath = " << filepath << std::endl;
+
+  Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(filepath);
+  open(file);
+
+  //The local instance will eventually exit with this status code:
+  return EXIT_SUCCESS;
+}
diff --git a/examples/book/application/exampleapplication.h b/examples/book/application/exampleapplication.h
index cdea1e6..c968e02 100644
--- a/examples/book/application/exampleapplication.h
+++ b/examples/book/application/exampleapplication.h
@@ -22,18 +22,17 @@
 class ExampleApplication: public Gtk::Application
 {
 protected:
-  explicit ExampleApplication(const Glib::ustring& application_id, 
-    Gio::ApplicationFlags flags = Gio::APPLICATION_FLAGS_NONE);
+  ExampleApplication();
 
 public:
-  static Glib::RefPtr<ExampleApplication> create(const Glib::ustring& application_id, 
-    Gio::ApplicationFlags flags = Gio::APPLICATION_FLAGS_NONE);
+  static Glib::RefPtr<ExampleApplication> create();
     
 protected:
   //Overrides of default signal handlers:
   virtual void on_activate();
   virtual void on_open(const Gio::Application::type_vec_files& files,
     const Glib::ustring& hint);
+  virtual int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine>& command_line);
 
 private:
   void create_window(const Glib::RefPtr<Gio::File>& file = Glib::RefPtr<Gio::File>());
diff --git a/examples/book/application/examplewindow.cc b/examples/book/application/examplewindow.cc
index 01d81c1..3434d5d 100644
--- a/examples/book/application/examplewindow.cc
+++ b/examples/book/application/examplewindow.cc
@@ -18,15 +18,18 @@
 
 #include "examplewindow.h"
 
-ExampleWindow::ExampleWindow(const Glib::RefPtr<Gio::File>& file)
+ExampleWindow::ExampleWindow()
 {
   set_title("Gio::Application example");
 
-  add(scrolled);
-  scrolled.add(view);
+  add(m_scrolledwindow);
+  m_scrolledwindow.add(m_view);
+}
 
+bool ExampleWindow::load_file(const Glib::RefPtr<Gio::File>& file)
+{    
   if(!file)
-    return;
+    return false;
 
   try
   {
@@ -38,7 +41,7 @@ ExampleWindow::ExampleWindow(const Glib::RefPtr<Gio::File>& file)
       if(contents && length)
       {
         const Glib::ustring text(contents);
-        Glib::RefPtr<Gtk::TextBuffer> buffer = view.get_buffer();
+        Glib::RefPtr<Gtk::TextBuffer> buffer = m_view.get_buffer();
         buffer->set_text(text);
       }
       g_free(contents);
@@ -46,8 +49,18 @@ ExampleWindow::ExampleWindow(const Glib::RefPtr<Gio::File>& file)
   }
   catch (const Glib::Error& ex)
   {
-    std::cerr << ex.what() << std::endl;
+    std::cerr << G_STRFUNC << ": exception while opening file: " << file->get_uri() <<  std::endl <<
+      "  exception: " << ex.what() << std::endl;
+    
+    //Tell the application that this window can no longer be useful to 
+    //this application, so it can forget about it. The instance might then exit 
+    //if this is its last open window.
+    //Note that we must be careful that the caller only calls this method _after_ 
+    //calling show(), or this would be useless: 
+    hide();
+    return false;
   }
 
   show_all_children();
+  return true;
 }
diff --git a/examples/book/application/examplewindow.h b/examples/book/application/examplewindow.h
index 4f6cf92..80fc00f 100644
--- a/examples/book/application/examplewindow.h
+++ b/examples/book/application/examplewindow.h
@@ -22,11 +22,17 @@
 class ExampleWindow: public Gtk::Window
 {
 public:
-  explicit ExampleWindow(const Glib::RefPtr<Gio::File>& file);
+
+  //We do not take the file as a constructor parameter,
+  //so we can separate window creation and hiding of the window
+  //when loading fails.
+  explicit ExampleWindow();
+  
+  bool load_file(const Glib::RefPtr<Gio::File>& file);
 
 private:
-  Gtk::ScrolledWindow scrolled;
-  Gtk::TextView view;
+  Gtk::ScrolledWindow m_scrolledwindow;
+  Gtk::TextView m_view;
 };
 
 #endif /* GTKMM_EXAMPLEWINDOW_H */
diff --git a/examples/book/application/main.cc b/examples/book/application/main.cc
index d5770d6..05fdad7 100644
--- a/examples/book/application/main.cc
+++ b/examples/book/application/main.cc
@@ -19,20 +19,12 @@
 
 #include "exampleapplication.h"
 
-void on_open(const Gio::Application::type_vec_files& /* files */, 
-  const Glib::ustring& /* hint */)
-{
-  std::cout << "open signal received" << std::endl;
-}
-
 int main(int argc, char *argv[])
 {
   Gtk::Main kit(argc, argv); //TODO: Make this unnecessary: Put it in Gtk::Application.
 
   Glib::RefPtr<ExampleApplication> application = 
-    ExampleApplication::create("org.gtkmm.examples.application",
-      Gio::APPLICATION_HANDLES_OPEN);
-  application->signal_open().connect( sigc::ptr_fun(on_open) );
+    ExampleApplication::create();
 
   // Start the application, showing the initial window, 
   // and opening extra windows for any files that it is asked to open,



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