add code to disable AppNap on OS X/MacOS
[ardour.git] / gtk2_ardour / option_editor.cc
index 56cb4ca1d790b960292a04a9f2b1c2c72bf1df07..9809b0516546ac750a65294d52bb6886056a645f 100644 (file)
@@ -1,19 +1,19 @@
 /*
-    Copyright (C) 2001-2009 Paul Davis
+  Copyright (C) 2001-2009 Paul Davis
 
-    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 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.
+  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 */
 #include <algorithm>
@@ -36,7 +36,7 @@
 #include "option_editor.h"
 #include "public_editor.h"
 #include "utils.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace Gtk;
@@ -470,7 +470,7 @@ OptionEditorPage::OptionEditorPage (Gtk::Notebook& n, std::string const & t)
  *  @param o Configuration to edit.
  *  @param t Title for the dialog.
  */
-OptionEditor::OptionEditor (PBD::Configuration* c, std::string const & t)
+OptionEditor::OptionEditor (PBD::Configuration* c)
        : _config (c)
        , option_tree (TreeStore::create (option_columns))
        , option_treeview (option_tree)
@@ -485,6 +485,7 @@ OptionEditor::OptionEditor (PBD::Configuration* c, std::string const & t)
        option_treeview.set_enable_search(true);
        option_treeview.set_search_column(0);
        option_treeview.set_name ("OptionsTreeView");
+       option_treeview.set_headers_visible (false);
 
        option_treeview.get_selection()->set_mode (Gtk::SELECTION_SINGLE);
        option_treeview.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &OptionEditor::treeview_row_selected));
@@ -532,101 +533,66 @@ OptionEditor::treeview_row_selected ()
        }
 }
 
-void
-OptionEditor::add_path_to_treeview (std::string const & pn, Gtk::Widget& widget)
+TreeModel::iterator
+OptionEditor::find_path_in_treemodel (std::string const & pn, bool create_missing)
 {
-       option_treeview.set_model (Glib::RefPtr<TreeStore>());
-
-       if (pn.find ('/') == std::string::npos) {
-               /* new top level item in tree */
-
-               TreeModel::iterator new_row = option_tree->append ();
-               TreeModel::Row row = *new_row;
-               row[option_columns.name] = pn;
-               row[option_columns.widget] = &widget;
-
-       } else {
-
-               /* find parent */
-
-               /* split page name, which is actually a path, into each
-                * component
-                */
+       /* split page name, which is actually a path, into each component */
 
-               std::vector<std::string> components;
-               split (pn, components, '/');
+       std::vector<std::string> components;
+       split (pn, components, '/');
 
-               /* start with top level children */
+       /* start with top level children */
 
-               typedef Gtk::TreeModel::Children type_children; //minimise code length.
-               type_children children = option_tree->children();
+       TreeModel::Children children = option_tree->children();
+       TreeModel::iterator iter;
 
-               /* foreach path component ... */
+       /* foreach path component ... */
 
-               for (std::vector<std::string>::const_iterator s = components.begin(); s != components.end(); ++s) {
+       for (std::vector<std::string>::const_iterator s = components.begin(); s != components.end(); ++s) {
 
-                       bool component_found = false;
-
-                       type_children::iterator iter;
-
-                       /* look through the children at this level */
-
-                       for (iter = children.begin(); iter != children.end(); ++iter) {
-                               Gtk::TreeModel::Row row = *iter;
-
-                               std::string row_name = row[option_columns.name];
-                               if (row_name == (*s)) {
-
-                                       /* found it */
-
-                                       component_found = true;
-
-                                       /* reset children to point to
-                                        * the children of this row
-                                        */
-
-                                       children = row.children();
-                                       break;
-                               }
+               for (iter = children.begin(); iter != children.end(); ++iter) {
+                       TreeModel::Row row = *iter;
+                       const std::string row_name = row[option_columns.name];
+                       if (row_name == (*s)) {
+                               break;
                        }
+               }
 
-                       if (!component_found) {
-
-                               /* missing component. If it is the last
-                                * one, append a real page. Otherwise
-                                * just put an entry in the tree model
-                                * since it is a navigational/sorting
-                                * component.
-                                */
-
-                               TreeModel::iterator new_row = option_tree->append (children);
-                               TreeModel::Row row = *new_row;
+               if (iter == children.end()) {
+                       /* the current component is missing; bail out or create it */
+                       if (!create_missing) {
+                               return option_tree->get_iter(TreeModel::Path(""));
+                       } else {
+                               iter = option_tree->append (children);
+                               TreeModel::Row row = *iter;
                                row[option_columns.name] = *s;
+                               row[option_columns.widget] = 0;
+                       }
+               }
 
-                               ++s;
+               /* from now on, iter points to a valid row, either the one we found or a new one */
+               /* set children to the row's children to continue searching */
+               children = (*iter)->children ();
 
-                               if (s == components.end()) {
-                                       row[option_columns.widget] = &widget;
-                               } else {
-                                       row[option_columns.widget] = 0;
-                               }
+       }
 
-                               children = row.children ();
+       return iter;
+}
 
-                       } else {
+void
+OptionEditor::add_path_to_treeview (std::string const & pn, Gtk::Widget& widget)
+{
+       option_treeview.set_model (Glib::RefPtr<TreeStore>());
 
-                               /* component found, just move on to the
-                                * next one. children has already been
-                                * reset appropriately.
-                                */
+       TreeModel::iterator row_iter = find_path_in_treemodel(pn, true);
 
-                               ++s;
-                       }
-               }
+       assert(row_iter);
 
-       }
+       TreeModel::Row row = *row_iter;
+       row[option_columns.widget] = &widget;
 
        option_treeview.set_model (option_tree);
+       option_treeview.expand_all ();
 }
 
 /** Add a component to a given page.
@@ -670,15 +636,12 @@ OptionEditor::add_page (std::string const & pn, Gtk::Widget& w)
 void
 OptionEditor::set_current_page (string const & p)
 {
-       int i = 0;
-       while (i < _notebook.get_n_pages ()) {
-               if (_notebook.get_tab_label_text (*_notebook.get_nth_page (i)) == p) {
-                       _notebook.set_current_page (i);
-                       return;
-               }
+       TreeModel::iterator row_iter = find_path_in_treemodel(p);
 
-               ++i;
+       if (row_iter) {
+               option_treeview.get_selection()->select(row_iter);
        }
+
 }
 
 
@@ -716,7 +679,7 @@ DirectoryOption::selection_changed ()
 /*--------------------------*/
 
 OptionEditorContainer::OptionEditorContainer (PBD::Configuration* c, string const& str)
-       : OptionEditor (c, str)
+       : OptionEditor (c)
 {
        set_border_width (4);
        hpacker.pack_start (treeview(), false, false);
@@ -728,7 +691,8 @@ OptionEditorContainer::OptionEditorContainer (PBD::Configuration* c, string cons
 }
 
 OptionEditorWindow::OptionEditorWindow (PBD::Configuration* c, string const& str)
-       : OptionEditor (c, str)
+       : OptionEditor (c)
+       , ArdourWindow (str)
 {
        container.set_border_width (4);
        hpacker.pack_start (treeview(), false, false);