From 3234087dc98cd966b0e82d5a48d0df16b5d9caa0 Mon Sep 17 00:00:00 2001
From: Chris Pavlina <pavlina.chris@gmail.com>
Date: Thu, 30 Mar 2017 21:46:48 -0400
Subject: [PATCH] Move wxDataViewCtrl manipulators out of
 dialog_choose_component.cpp

Fixes: lp:1677925
* https://bugs.launchpad.net/kicad/+bug/1677925
---
 common/CMakeLists.txt                        |   1 +
 common/wxdataviewctrl_helpers.cpp            | 119 +++++++++++++++++++
 eeschema/dialogs/dialog_choose_component.cpp | 105 +---------------
 include/wxdataviewctrl_helpers.h             |  67 +++++++++++
 4 files changed, 188 insertions(+), 104 deletions(-)
 create mode 100644 common/wxdataviewctrl_helpers.cpp
 create mode 100644 include/wxdataviewctrl_helpers.h

diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index ad1cd5dee4..e119d4b7e9 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -284,6 +284,7 @@ set( COMMON_SRCS
     wildcards_and_files_ext.cpp
     worksheet.cpp
     wxwineda.cpp
+    wxdataviewctrl_helpers.cpp
     wx_unit_binder.cpp
     wx_status_popup.cpp
     xnode.cpp
diff --git a/common/wxdataviewctrl_helpers.cpp b/common/wxdataviewctrl_helpers.cpp
new file mode 100644
index 0000000000..5e1ed258cf
--- /dev/null
+++ b/common/wxdataviewctrl_helpers.cpp
@@ -0,0 +1,119 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <wx/dataview.h>
+#include <wxdataviewctrl_helpers.h>
+
+wxDataViewItem GetPrevItem( wxDataViewCtrl const& aView, wxDataViewItem const& aItem )
+{
+    auto prevItem = GetPrevSibling( aView, aItem );
+
+    if( !prevItem.IsOk() )
+    {
+        prevItem = aView.GetModel()->GetParent( aItem );
+    }
+    else if( aView.IsExpanded( prevItem ) )
+    {
+        wxDataViewItemArray children;
+        aView.GetModel()->GetChildren( prevItem, children );
+        prevItem = children[children.size() - 1];
+    }
+
+    return prevItem;
+}
+
+
+wxDataViewItem GetNextItem( wxDataViewCtrl const& aView, wxDataViewItem const& aItem )
+{
+    wxDataViewItem nextItem;
+
+    if( !aItem.IsOk() )
+    {
+        // No selection. Select the first.
+        wxDataViewItemArray children;
+        aView.GetModel()->GetChildren( aItem, children );
+        return children[0];
+    }
+
+    if( aView.IsExpanded( aItem ) )
+    {
+        wxDataViewItemArray children;
+        aView.GetModel()->GetChildren( aItem, children );
+        nextItem = children[0];
+    }
+    else
+    {
+        // Walk up levels until we find one that has a next sibling.
+        for( wxDataViewItem walk = aItem; walk.IsOk(); walk = aView.GetModel()->GetParent( walk ) )
+        {
+            nextItem = GetNextSibling( aView, walk );
+
+            if( nextItem.IsOk() )
+                break;
+        }
+    }
+
+    return nextItem;
+}
+
+
+wxDataViewItem GetPrevSibling( wxDataViewCtrl const& aView, wxDataViewItem const& aItem )
+{
+    wxDataViewItemArray siblings;
+    wxDataViewItem      invalid;
+    wxDataViewItem      parent = aView.GetModel()->GetParent( aItem );
+
+    aView.GetModel()->GetChildren( parent, siblings );
+
+    for( size_t i = 0; i < siblings.size(); ++i )
+    {
+        if( siblings[i] == aItem )
+        {
+            if( i == 0 )
+                return invalid;
+            else
+                return siblings[i - 1];
+        }
+    }
+
+    return invalid;
+}
+
+
+wxDataViewItem GetNextSibling( wxDataViewCtrl const& aView, wxDataViewItem const& aItem )
+{
+    wxDataViewItemArray siblings;
+    wxDataViewItem      invalid;
+    wxDataViewItem      parent = aView.GetModel()->GetParent( aItem );
+
+    aView.GetModel()->GetChildren( parent, siblings );
+
+    for( size_t i = 0; i < siblings.size(); ++i )
+    {
+        if( siblings[i] == aItem )
+        {
+            if( i == siblings.size() - 1 )
+                return invalid;
+            else
+                return siblings[i + 1];
+        }
+    }
+
+    return invalid;
+}
diff --git a/eeschema/dialogs/dialog_choose_component.cpp b/eeschema/dialogs/dialog_choose_component.cpp
index 7940a2cbd9..b219d249b7 100644
--- a/eeschema/dialogs/dialog_choose_component.cpp
+++ b/eeschema/dialogs/dialog_choose_component.cpp
@@ -50,12 +50,8 @@
 #include <template_fieldnames.h>
 #include <widgets/footprint_preview_widget.h>
 #include <widgets/footprint_select_widget.h>
+#include <wxdataviewctrl_helpers.h>
 
-// Tree navigation helpers.
-static wxDataViewItem GetPrevItem( const wxDataViewCtrl& ctrl, const wxDataViewItem& item );
-static wxDataViewItem GetNextItem( const wxDataViewCtrl& ctrl, const wxDataViewItem& item );
-static wxDataViewItem GetPrevSibling( const wxDataViewCtrl& ctrl, const wxDataViewItem& item );
-static wxDataViewItem GetNextSibling( const wxDataViewCtrl& ctrl, const wxDataViewItem& item );
 
 FOOTPRINT_ASYNC_LOADER          DIALOG_CHOOSE_COMPONENT::m_fp_loader;
 std::unique_ptr<FOOTPRINT_LIST> DIALOG_CHOOSE_COMPONENT::m_fp_list;
@@ -526,102 +522,3 @@ void DIALOG_CHOOSE_COMPONENT::HandleItemSelection()
             m_tree_ctrl->Expand( sel );
     }
 }
-
-
-static wxDataViewItem GetPrevItem( const wxDataViewCtrl& tree, const wxDataViewItem& item )
-{
-    auto prevItem = GetPrevSibling( tree, item );
-
-    if( !prevItem.IsOk() )
-    {
-        prevItem = tree.GetModel()->GetParent( item );
-    }
-    else if( tree.IsExpanded( prevItem ) )
-    {
-        wxDataViewItemArray children;
-        tree.GetModel()->GetChildren( prevItem, children );
-        prevItem = children[children.size() - 1];
-    }
-
-    return prevItem;
-}
-
-
-static wxDataViewItem GetNextItem( const wxDataViewCtrl& tree, const wxDataViewItem& item )
-{
-    wxDataViewItem nextItem;
-
-    if( !item.IsOk() )
-    {
-        // No selection. Select the first.
-        wxDataViewItemArray children;
-        tree.GetModel()->GetChildren( item, children );
-        return children[0];
-    }
-
-    if( tree.IsExpanded( item ) )
-    {
-        wxDataViewItemArray children;
-        tree.GetModel()->GetChildren( item, children );
-        nextItem = children[0];
-    }
-    else
-    {
-        // Walk up levels until we find one that has a next sibling.
-        for( wxDataViewItem walk = item; walk.IsOk(); walk = tree.GetModel()->GetParent( walk ) )
-        {
-            nextItem = GetNextSibling( tree, walk );
-
-            if( nextItem.IsOk() )
-                break;
-        }
-    }
-
-    return nextItem;
-}
-
-
-static wxDataViewItem GetPrevSibling( const wxDataViewCtrl& tree, const wxDataViewItem& item )
-{
-    wxDataViewItemArray siblings;
-    wxDataViewItem      invalid;
-    wxDataViewItem      parent = tree.GetModel()->GetParent( item );
-
-    tree.GetModel()->GetChildren( parent, siblings );
-
-    for( size_t i = 0; i < siblings.size(); ++i )
-    {
-        if( siblings[i] == item )
-        {
-            if( i == 0 )
-                return invalid;
-            else
-                return siblings[i - 1];
-        }
-    }
-
-    return invalid;
-}
-
-
-static wxDataViewItem GetNextSibling( const wxDataViewCtrl& tree, const wxDataViewItem& item )
-{
-    wxDataViewItemArray siblings;
-    wxDataViewItem      invalid;
-    wxDataViewItem      parent = tree.GetModel()->GetParent( item );
-
-    tree.GetModel()->GetChildren( parent, siblings );
-
-    for( size_t i = 0; i < siblings.size(); ++i )
-    {
-        if( siblings[i] == item )
-        {
-            if( i == siblings.size() - 1 )
-                return invalid;
-            else
-                return siblings[i + 1];
-        }
-    }
-
-    return invalid;
-}
diff --git a/include/wxdataviewctrl_helpers.h b/include/wxdataviewctrl_helpers.h
new file mode 100644
index 0000000000..ce7fc3dabf
--- /dev/null
+++ b/include/wxdataviewctrl_helpers.h
@@ -0,0 +1,67 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * wxDataViewCtrl helper functions. These are functions that should be methods
+ * of wxDataViewCtrl, but aren't.
+ */
+
+#ifndef WXDATAVIEWCTRL_HELPERS_H
+#define WXDATAVIEWCTRL_HELPERS_H
+
+#include <wx/dataview.h>
+
+/**
+ * Get the previous item in list order.
+ *
+ * @param aView - a wxDataViewCtrl with valid model
+ * @param aItem - a valid item in the model
+ * @return the item before aItem, or an invalid item if aItem is at the top.
+ */
+wxDataViewItem GetPrevItem( wxDataViewCtrl const& aView, wxDataViewItem const& aItem );
+
+/**
+ * Get the next item in list order.
+ *
+ * @param aView - a wxDataViewCtrl with valid model
+ * @param aItem - a valid item in the model
+ * @return the item after aItem, or an invalid item if aItem is at the bottom.
+ */
+wxDataViewItem GetNextItem( wxDataViewCtrl const& aView, wxDataViewItem const& aItem );
+
+/**
+ * Get the previous sibling of an item.
+ *
+ * @param aView - awxDataViewCtrl with valid model
+ * @param aItem - a valid item in the model
+ * @return the sibling before aItem, or an invalid item if aItem has no siblings before it.
+ */
+wxDataViewItem GetPrevSibling( wxDataViewCtrl const& aView, wxDataViewItem const& aItem );
+
+/**
+ * Get the next sibling of an item.
+ *
+ * @param aView - awxDataViewCtrl with valid model
+ * @param aItem - a valid item in the model
+ * @return the sibling after aItem, or an invalid item if aItem has no siblings after it.
+ */
+wxDataViewItem GetNextSibling( wxDataViewCtrl const& aView, wxDataViewItem const& aItem );
+
+#endif // WXDATAVIEWCTRL_HELPERS_H