RecentChooser
| Chapter 21. Recently Used Documents |

## RecentChooser

`RecentChooser` is an interface that can be implemented by widgets displaying the list of recently used files. gtkmm provides four built-in implementations for choosing recent files: `RecentChooserWidget`, `RecentChooserDialog`, `RecentChooserMenu`, and `RecentAction`.

`RecentChooserWidget` is a simple widget for displaying a list of recently used files. `RecentChooserWidget` is the basic building block for `RecentChooserDialog`, but you can embed it into your user interface if you want to.

`RecentChooserMenu` and `RecentAction` allow you to list recently used files as a menu.

### Simple RecentChooserDialog example

Shown below is a simple example of how to use the `RecentChooserDialog` and the `RecentAction` classes in a program. This simple program has a menubar with a Recent Files Dialog menu item. When you select this menu item, a dialog pops up showing the list of recently used files.

| Note
If this is the first time you're using a program that uses the Recent Files framework, the dialog may be empty at first. Otherwise it should show the list of recently used documents registered by other applications.

After selecting the Recent Files Dialog menu item, you should see something similar to the following window.

Source Code

File: `examplewindow.h` (For use with gtkmm 3, not gtkmm 2)

    #ifndef GTKMM_EXAMPLEWINDOW_H
    #define GTKMM_EXAMPLEWINDOW_H

    #include <gtkmm.h>

    class ExampleWindow : public Gtk::Window
    {
    public:
      ExampleWindow();
      virtual ~ExampleWindow();

    protected:
      //Signal handlers:
      void on_menu_file_recent_files_item();
      void on_menu_file_recent_files_dialog();
      void on_menu_file_quit();
      void on_menu_file_new();

      //Child widgets:
      Gtk::Box m_Box;

      Glib::RefPtr<Gtk::UIManager> m_refUIManager;
      Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup;
      Glib::RefPtr<Gtk::RecentAction> m_refRecentAction;

      Glib::RefPtr<Gtk::RecentManager> m_refRecentManager;
    };

    #endif //GTKMM_EXAMPLEWINDOW_H

File: `examplewindow.cc` (For use with gtkmm 3, not gtkmm 2)

    #include "examplewindow.h"
    #include <gtkmm/stock.h>
    #include <iostream>

    ExampleWindow::ExampleWindow()
    : m_Box(Gtk::ORIENTATION_VERTICAL),
      m_refRecentManager(Gtk::RecentManager::get_default())
    {
      set_title("recent files example");
      set_default_size(200, 200);

      //We can put a MenuBar at the top of the box and other stuff below it.
      add(m_Box);

      //Create actions for menus and toolbars:
      m_refActionGroup = Gtk::ActionGroup::create();

      //File menu:
      m_refActionGroup->add( Gtk::Action::create("FileMenu", "_File") );
      m_refActionGroup->add( Gtk::Action::create("FileNew", Gtk::Stock::NEW),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_file_new));

      //A recent-files submenu:
      m_refRecentAction = Gtk::RecentAction::create("FileRecentFiles", "_Recent Files");
      m_refActionGroup->add(m_refRecentAction);
      //Connect to RecentChooser's item_activated signal
      //instead of Action's activate signal:
      m_refRecentAction->signal_item_activated().connect(
        sigc::mem_fun(*this, &ExampleWindow::on_menu_file_recent_files_item) );

      //A menu item to open the recent-files dialog:
      m_refActionGroup->add( Gtk::Action::create("FileRecentDialog", "Recent Files _Dialog"),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_file_recent_files_dialog) );

      m_refActionGroup->add( Gtk::Action::create("FileQuit", Gtk::Stock::QUIT),
        sigc::mem_fun(*this, &ExampleWindow::on_menu_file_quit) );

      m_refUIManager = Gtk::UIManager::create();
      m_refUIManager->insert_action_group(m_refActionGroup);

      add_accel_group(m_refUIManager->get_accel_group());

      //Layout the actions in a menubar and toolbar:
      Glib::ustring ui_info =
            "<ui>"
            "  <menubar name='MenuBar'>"
            "    <menu action='FileMenu'>"
            "      <menuitem action='FileNew'/>"
            "      <menuitem action='FileRecentFiles'/>"
            "      <menuitem action='FileRecentDialog'/>"
            "      <separator/>"
            "      <menuitem action='FileQuit'/>"
            "    </menu>"
            "  </menubar>"
            "  <toolbar  name='ToolBar'>"
            "    <toolitem action='FileNew'/>"
            "    <toolitem action='FileQuit'/>"
            "  </toolbar>"
            "</ui>";

      try
      {
        m_refUIManager->add_ui_from_string(ui_info);
      }
      catch(const Glib::Error& ex)
      {
        std::cerr << "building menus failed: " <<  ex.what();
      }

      //Get the menubar and toolbar widgets, and add them to a container widget:
      Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar");
      if(pMenubar)
        m_Box.pack_start(*pMenubar, Gtk::PACK_SHRINK);

      Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar");
      if(pToolbar)
        m_Box.pack_start(*pToolbar, Gtk::PACK_SHRINK);

      show_all_children();
    }

    ExampleWindow::~ExampleWindow()
    {
    }

    void ExampleWindow::on_menu_file_new()
    {
      std::cout << " New File" << std::endl;
    }

    void ExampleWindow::on_menu_file_quit()
    {
      hide(); //Closes the main window to stop the app->run().
    }

    void ExampleWindow::on_menu_file_recent_files_item()
    {
      std::cout << "URI selected = " << m_refRecentAction->get_current_uri() << std::endl;
    }

    void ExampleWindow::on_menu_file_recent_files_dialog()
    {
      Gtk::RecentChooserDialog dialog(*this, "Recent Files", m_refRecentManager);
      dialog.add_button("Select File", Gtk::RESPONSE_OK);
      dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);

      const int response = dialog.run();
      dialog.hide();
      if(response == Gtk::RESPONSE_OK)
      {
        std::cout << "URI selected = " << dialog.get_current_uri() << std::endl;
      }
    }

File: `main.cc` (For use with gtkmm 3, not gtkmm 2)

    #include "examplewindow.h"
    #include <gtkmm/application.h>

    int main(int argc, char *argv[])
    {
      Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

      ExampleWindow window;

      //Shows the window and returns when it is closed.
      return app->run(window);
    }

The constructor for `ExampleWindow` creates the menu using `UIManager` (see Chapter 12, Menus and Toolbars for more information). It then adds the menu and the toolbar to the window.

### Filtering Recent Files

For any of the `RecentChooser` classes, if you don't wish to display all of the items in the list of recent files, you can filter the list to show only those that you want. You can filter the list with the help of the `RecentFilter` class. This class allows you to filter recent files by their name (`add_pattern()`), their mime type (`add_mime_type()`), the application that registered them (`add_application()`), or by a custom filter function (`add_custom()`). It also provides the ability to filter based on how long ago the file was modified and which groups it belongs to.

After you've created and set up the filter to match only the items you want, you can apply a filter to a chooser widget with the `RecentChooser::add_filter()` function.

Chapter 21. Recently Used Documents |  | Chapter 22. Plugs and Sockets