The following commit has been merged in the master branch:
commit 5655b46a99d4b91f21a68f237b9eb5c00ec42d11
Author: Andrei Zavada <[email protected]>
Date:   Sun Apr 7 18:58:24 2013 +0300

    subject sorting in main window

diff --git a/data/mw.glade b/data/mw.glade
index f475474..830bc3c 100644
--- a/data/mw.glade
+++ b/data/mw.glade
@@ -1,6 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkAdjustment" id="jArtifDampFactor">
+    <property name="upper">1</property>
+    <property name="value">0.94999999999999996</property>
+    <property name="step_increment">0.01</property>
+    <property name="page_increment">0.10000000000000001</property>
+  </object>
   <object class="GtkMenu" id="iiSubjectTimeline">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -81,12 +87,6 @@
     <property name="can_focus">False</property>
     <property name="icon_name">reload</property>
   </object>
-  <object class="GtkAdjustment" id="jArtifDampFactor">
-    <property name="upper">1</property>
-    <property name="value">0.94999999999999996</property>
-    <property name="step_increment">0.01</property>
-    <property name="page_increment">0.10000000000000001</property>
-  </object>
   <object class="GtkAdjustment" id="jBandAlphaFrom">
     <property name="lower">6</property>
     <property name="upper">10</property>
@@ -711,6 +711,83 @@ rm */*/*/.*.{psd,mc,swu}</property>
                                       </object>
                                     </child>
                                     <child>
+                                      <object class="GtkMenuItem" 
id="menuitem4">
+                                        <property 
name="visible">True</property>
+                                        <property 
name="can_focus">False</property>
+                                        <property name="label" 
translatable="yes">Subject _order</property>
+                                        <property 
name="use_underline">True</property>
+                                        <child type="submenu">
+                                          <object class="GtkMenu" id="menu2">
+                                            <property 
name="visible">True</property>
+                                            <property 
name="can_focus">False</property>
+                                            <child>
+                                              <object class="GtkRadioMenuItem" 
id="iExpSubjectSortName">
+                                                <property 
name="visible">True</property>
+                                                <property 
name="can_focus">False</property>
+                                                <property name="label" 
translatable="yes">_Name</property>
+                                                <property 
name="use_underline">True</property>
+                                                <property 
name="active">True</property>
+                                                <property 
name="draw_as_radio">True</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="GtkRadioMenuItem" 
id="iExpSubjectSortAge">
+                                                <property 
name="visible">True</property>
+                                                <property 
name="can_focus">False</property>
+                                                <property name="label" 
translatable="yes">_Age</property>
+                                                <property 
name="use_underline">True</property>
+                                                <property 
name="draw_as_radio">True</property>
+                                                <property 
name="group">iExpSubjectSortName</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="GtkRadioMenuItem" 
id="iExpSubjectSortAdmissionDate">
+                                                <property 
name="visible">True</property>
+                                                <property 
name="can_focus">False</property>
+                                                <property name="label" 
translatable="yes">Ad_mission date</property>
+                                                <property 
name="use_underline">True</property>
+                                                <property 
name="draw_as_radio">True</property>
+                                                <property 
name="group">iExpSubjectSortName</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="GtkRadioMenuItem" 
id="iExpSubjectSortAvgPower">
+                                                <property 
name="visible">True</property>
+                                                <property 
name="can_focus">False</property>
+                                                <property name="label" 
translatable="yes">Average _profile power</property>
+                                                <property 
name="use_underline">True</property>
+                                                <property 
name="draw_as_radio">True</property>
+                                                <property 
name="group">iExpSubjectSortName</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object 
class="GtkSeparatorMenuItem" id="menuitem5">
+                                                <property 
name="visible">True</property>
+                                                <property 
name="can_focus">False</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="GtkCheckMenuItem" 
id="iExpSubjectSortAscending">
+                                                <property 
name="visible">True</property>
+                                                <property 
name="can_focus">False</property>
+                                                <property name="label" 
translatable="yes">A_scending</property>
+                                                <property 
name="use_underline">True</property>
+                                                <property 
name="active">True</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="GtkCheckMenuItem" 
id="iExpSubjectSortSegregate">
+                                                <property 
name="visible">True</property>
+                                                <property 
name="can_focus">False</property>
+                                                <property name="label" 
translatable="yes">S_egregate by gender</property>
+                                                <property 
name="use_underline">True</property>
+                                              </object>
+                                            </child>
+                                          </object>
+                                        </child>
+                                      </object>
+                                    </child>
+                                    <child>
                                       <object class="GtkMenuItem" 
id="iiExpGlobalOperations">
                                         <property 
name="visible">True</property>
                                         <property 
name="can_focus">False</property>
diff --git a/src/ui/mw/construct.cc b/src/ui/mw/construct.cc
index f5e6f67..72d2658 100644
--- a/src/ui/mw/construct.cc
+++ b/src/ui/mw/construct.cc
@@ -96,6 +96,12 @@ SExpDesignUIWidgets ()
             !AGH_GBGETOBJ (GtkMenuItem,        iExpRefresh) ||
             !AGH_GBGETOBJ (GtkMenuItem,        iExpPurgeComputed) ||
             !AGH_GBGETOBJ (GtkMenuItem,        iExpAnnotations) ||
+            !AGH_GBGETOBJ (GtkRadioMenuItem,   iExpSubjectSortName) ||
+            !AGH_GBGETOBJ (GtkRadioMenuItem,   iExpSubjectSortAge) ||
+            !AGH_GBGETOBJ (GtkRadioMenuItem,   iExpSubjectSortAdmissionDate) ||
+            !AGH_GBGETOBJ (GtkRadioMenuItem,   iExpSubjectSortAvgPower) ||
+            !AGH_GBGETOBJ (GtkCheckMenuItem,   iExpSubjectSortAscending) ||
+            !AGH_GBGETOBJ (GtkCheckMenuItem,   iExpSubjectSortSegregate) ||
             !AGH_GBGETOBJ (GtkMenuItem,        
iExpBasicSADetectUltradianCycles) ||
             !AGH_GBGETOBJ (GtkMenuItem,        iiExpGlobalOperations) ||
             !AGH_GBGETOBJ (GtkMenuItem,        iExpGloballyDetectArtifacts) ||
@@ -122,6 +128,13 @@ SExpDesignUIWidgets ()
        G_CONNECT_1 (iHelpAbout, activate);
        G_CONNECT_1 (iHelpUsage, activate);
 
+       for ( auto& w : {iExpSubjectSortName, iExpSubjectSortAge, 
iExpSubjectSortAdmissionDate, iExpSubjectSortAvgPower} )
+               g_signal_connect( w, "toggled",
+                                 (GCallback)iExpSubjectSortAny_toggled_cb,
+                                 this);
+       G_CONNECT_1 (iExpSubjectSortAscending, toggled);
+       G_CONNECT_1 (iExpSubjectSortSegregate, toggled);
+
      // --------- tabs
        if ( !AGH_GBGETOBJ (GtkNotebook,        tTaskSelector) ||
             !AGH_GBGETOBJ (GtkNotebook,        tDesign) ||
diff --git a/src/ui/mw/mainmenu_cb.cc b/src/ui/mw/mainmenu_cb.cc
index 425bc66..8c71a54 100644
--- a/src/ui/mw/mainmenu_cb.cc
+++ b/src/ui/mw/mainmenu_cb.cc
@@ -34,6 +34,58 @@ iExpPurgeComputed_activate_cb( GtkMenuItem*, gpointer 
userdata)
 }
 
 
+
+void
+iExpSubjectSortAny_toggled_cb( GtkCheckMenuItem* mi, gpointer userdata)
+{
+       auto& ED = *(SExpDesignUI*)userdata;
+       if ( ED.suppress_redraw )
+               return;
+
+       // only set ON
+       if ( gtk_check_menu_item_get_active( mi) == FALSE )
+               return;
+
+       if      ( mi == (GtkCheckMenuItem*)ED.iExpSubjectSortName )
+               ED.sort_by = SExpDesignUI::TSubjectSortBy::name;
+       else if ( mi == (GtkCheckMenuItem*)ED.iExpSubjectSortAge )
+               ED.sort_by = SExpDesignUI::TSubjectSortBy::age;
+       else if ( mi == (GtkCheckMenuItem*)ED.iExpSubjectSortAdmissionDate )
+               ED.sort_by = SExpDesignUI::TSubjectSortBy::admission_date;
+       else if ( mi == (GtkCheckMenuItem*)ED.iExpSubjectSortAvgPower )
+               ED.sort_by = SExpDesignUI::TSubjectSortBy::avg_profile_power;
+
+       ED.populate_1();
+}
+
+
+void
+iExpSubjectSortAscending_toggled_cb( GtkCheckMenuItem*, gpointer userdata)
+{
+       auto& ED = *(SExpDesignUI*)userdata;
+       if ( ED.suppress_redraw )
+               return;
+
+       ED.sort_ascending = !ED.sort_ascending;
+       ED.populate_1();
+}
+
+void
+iExpSubjectSortSegregate_toggled_cb( GtkCheckMenuItem*, gpointer userdata)
+{
+       auto& ED = *(SExpDesignUI*)userdata;
+       if ( ED.suppress_redraw )
+               return;
+
+       ED.sort_segregate = !ED.sort_segregate;
+       ED.populate_1();
+}
+
+
+
+
+
+
 void
 iExpAnnotations_activate_cb( GtkMenuItem*, gpointer userdata)
 {
diff --git a/src/ui/mw/measurements_cb.cc b/src/ui/mw/measurements_cb.cc
index 288fca9..e12aa99 100644
--- a/src/ui/mw/measurements_cb.cc
+++ b/src/ui/mw/measurements_cb.cc
@@ -157,7 +157,8 @@ iSubjectTimelineSubjectInfo_activate_cb( GtkMenuItem*, 
gpointer userdata)
 {
        auto& ED = *(SExpDesignUI*)userdata;
        ED.update_subject_details_interactively( ED.using_subject->csubject);
-       gtk_widget_queue_draw( (GtkWidget*)ED.using_subject->da);
+       ED.populate_1(); // trigger sort
+       //gtk_widget_queue_draw( (GtkWidget*)ED.using_subject->da);
 }
 
 
diff --git a/src/ui/mw/mw.cc b/src/ui/mw/mw.cc
index 5af78bd..7135f10 100644
--- a/src/ui/mw/mw.cc
+++ b/src/ui/mw/mw.cc
@@ -165,6 +165,9 @@ SExpDesignUI (aghui::SSessionChooser *parent,
        smooth_profile (1),
        timeline_height (80),
        timeline_pph (30),
+       sort_by (TSubjectSortBy::name),
+       sort_ascending (true),
+       sort_segregate (false),
        browse_command ("thunar"),
        config_keys_s ({
                confval::SValidator<string>("WindowGeometry.Main",              
&_geometry_placeholder),
@@ -174,6 +177,9 @@ SExpDesignUI (aghui::SSessionChooser *parent,
        }),
        config_keys_d ({
                confval::SValidator<int>("Common.OnlyPlainAnnotations",         
(int*)&only_plain_global_annotations,           
confval::SValidator<int>::SVFRangeIn ( 0,   1)),
+               confval::SValidator<int>("Common.Sort.By",                      
(int*)&sort_by,                                 
confval::SValidator<int>::SVFRangeIn ( 0,   3)),
+               confval::SValidator<int>("Common.Sort.Ascending",               
(int*)&sort_ascending,                          
confval::SValidator<int>::SVFRangeIn ( 0,   1)),
+               confval::SValidator<int>("Common.Sort.Segregate",               
(int*)&sort_segregate,                          
confval::SValidator<int>::SVFRangeIn ( 0,   1)),
                confval::SValidator<int>("Measurements.DisplayProfileType",     
(int*)&display_profile_type,                    
confval::SValidator<int>::SVFRangeIn ( 0,   3)),
                confval::SValidator<int>("Measurements.SmoothSide",             
(int*)&smooth_profile,                          
confval::SValidator<int>::SVFRangeIn ( 1,  20)),
                confval::SValidator<int>("Measurements.TimelineHeight",         
(int*)&timeline_height,                         
confval::SValidator<int>::SVFRangeIn (10, 600)),
@@ -194,6 +200,7 @@ SExpDesignUI (aghui::SSessionChooser *parent,
        })
 {
        nodestroy_by_cb = true;
+       suppress_redraw = true;
 
        set_wMainWindow_interactive( false);
        set_controls_for_empty_experiment( true, false);
@@ -288,7 +295,18 @@ SExpDesignUI (aghui::SSessionChooser *parent,
 
        populate( true);
 
+       // set check and radio menuitems in global menu
+       switch ( sort_by ) {
+       case TSubjectSortBy::name:              gtk_check_menu_item_set_active( 
(GtkCheckMenuItem*)iExpSubjectSortName,         TRUE); break;
+       case TSubjectSortBy::age:               gtk_check_menu_item_set_active( 
(GtkCheckMenuItem*)iExpSubjectSortAge,          TRUE); break;
+       case TSubjectSortBy::admission_date:    gtk_check_menu_item_set_active( 
(GtkCheckMenuItem*)iExpSubjectSortAdmissionDate,TRUE); break;
+       case TSubjectSortBy::avg_profile_power: gtk_check_menu_item_set_active( 
(GtkCheckMenuItem*)iExpSubjectSortAvgPower,     TRUE); break;
+       }
+       gtk_check_menu_item_set_active( iExpSubjectSortAscending, 
sort_ascending);
+       gtk_check_menu_item_set_active( iExpSubjectSortSegregate, 
sort_segregate);
+
        set_wMainWindow_interactive( true, false);
+       suppress_redraw = false;
 }
 
 void
diff --git a/src/ui/mw/mw.hh b/src/ui/mw/mw.hh
index f1becb8..3191769 100644
--- a/src/ui/mw/mw.hh
+++ b/src/ui/mw/mw.hh
@@ -79,7 +79,8 @@ class SExpDesignUI
 
                bool get_episode_from_timeline_click( unsigned along);  // 
possibly sets episode_focused
 
-               time_t  tl_start;
+               time_t  tl_start,
+                       admission_date;
 
                time_t timeline_start() const   { return _p._p.timeline_start; }
                time_t timeline_end() const     { return _p._p.timeline_end; }
@@ -95,6 +96,9 @@ class SExpDesignUI
                SSubjectPresentation (agh::CSubject&, SGroupPresentation& 
parent);
               ~SSubjectPresentation ();
 
+               // sort
+               bool operator<( const SSubjectPresentation& rv) const;
+
                GtkWidget
                        *da;
        };
@@ -287,6 +291,15 @@ class SExpDesignUI
                _aghdd_placeholder,
                _aghtt_placeholder;
 
+       enum TSubjectSortBy {
+               name, age, admission_date,
+               avg_profile_power
+       };
+       TSubjectSortBy sort_by;
+       bool    sort_ascending,
+               sort_segregate;
+       void sort_subjects();
+
        size_t  timeline_pph_saved,
                timeline_height_saved;
        int     pagesize_item_saved,
diff --git a/src/ui/mw/mw_cb.hh b/src/ui/mw/mw_cb.hh
index 38228de..5b0f735 100644
--- a/src/ui/mw/mw_cb.hh
+++ b/src/ui/mw/mw_cb.hh
@@ -26,6 +26,9 @@ gboolean wMainWindow_configure_event_cb( GtkWidget*, 
GdkEventConfigure*, gpointe
 void iExpRefresh_activate_cb( GtkMenuItem*, gpointer);
 void iExpPurgeComputed_activate_cb( GtkMenuItem*, gpointer);
 void iExpAnnotations_activate_cb( GtkMenuItem*, gpointer);
+void iExpSubjectSortAny_toggled_cb( GtkCheckMenuItem*, gpointer);
+void iExpSubjectSortAscending_toggled_cb( GtkCheckMenuItem*, gpointer);
+void iExpSubjectSortSegregate_toggled_cb( GtkCheckMenuItem*, gpointer);
 void iExpBasicSADetectUltradianCycles_activate_cb( GtkMenuItem*, gpointer);
 void iExpGloballyDetectArtifacts_activate_cb( GtkMenuItem*, gpointer);
 void iExpGloballySetFilters_activate_cb( GtkMenuItem*, gpointer);
diff --git a/src/ui/mw/populate.cc b/src/ui/mw/populate.cc
index f7b90da..033e0c4 100644
--- a/src/ui/mw/populate.cc
+++ b/src/ui/mw/populate.cc
@@ -395,7 +395,8 @@ populate_1()
                SGroupPresentation& Gp = groups.back();
                for ( auto &J : Gi->second ) {
                        Gp.emplace_back( J, Gp);
-                       const SSubjectPresentation& j = Gp.back();
+                       SSubjectPresentation& j = Gp.back(); // not const 
because admission_date is set right here:
+                       j.admission_date = (time_t)0;
                        if ( j.cprofile && J.have_session(*_AghDi) ) {
                                auto& ee = J.measurements[*_AghDi].episodes;
                                if ( not ee.empty() ) {
@@ -404,6 +405,8 @@ populate_1()
                                                earliest_start = 
ee.front().start_rel;
                                        if ( latest_end == (time_t)-1 || 
latest_end < ee.back().end_rel )
                                                latest_end = ee.back().end_rel;
+
+                                       j.admission_date = 
ee.front().start_time();
                                } else
                                        fprintf( stderr, 
"SExpDesignUI::populate_1(): session \"%s\", channel \"%s\" for subject \"%s\" 
is empty\n",
                                                 AghD(), AghT(), 
J.short_name.c_str());
@@ -411,6 +414,8 @@ populate_1()
                }
        }
 
+       sort_subjects();
+
        timeline_start = earliest_start;
        timeline_end   = latest_end;
        timeline_width = (timeline_end - timeline_start) / 3600 * timeline_pph;
@@ -556,6 +561,56 @@ populate_1()
 }
 
 
+void
+aghui::SExpDesignUI::
+sort_subjects()
+{
+       for ( auto Gi = groups.begin(); Gi != groups.end(); ++Gi )
+               Gi->sort();
+}
+
+
+bool
+aghui::SExpDesignUI::SSubjectPresentation::
+operator<( const SSubjectPresentation& rv) const
+{
+       if ( _p._p.sort_segregate and csubject.gender != rv.csubject.gender )
+               return csubject.gender < rv.csubject.gender;
+
+       bool    result = false,
+               unsure = true; // avoid swapping if result == false
+       switch ( _p._p.sort_by ) {
+       case TSubjectSortBy::name:
+               result = csubject.short_name <  rv.csubject.short_name;
+               unsure = csubject.short_name == rv.csubject.short_name;
+               break;
+       case TSubjectSortBy::age:
+               result = csubject.age <  rv.csubject.age;
+               unsure = csubject.age == rv.csubject.age;
+               break;
+       case TSubjectSortBy::admission_date:
+               result = tl_start <  rv.tl_start;
+               unsure = tl_start == rv.tl_start;
+               break;
+       case TSubjectSortBy::avg_profile_power:
+               if ( cprofile and rv.cprofile ) {
+                       result = cprofile->metric_avg() < 
rv.cprofile->metric_avg();
+                       unsure = false;
+               } else {
+                       result = false;
+                       unsure = false;
+               }
+               break;
+       }
+
+       if ( unsure )
+               return false;
+       if ( _p._p.sort_ascending )
+               result = !result;
+
+       return result;
+}
+
 // Local Variables:
 // Mode: c++
 // indent-tabs-mode: 8
diff --git a/src/ui/mw/widgets.hh b/src/ui/mw/widgets.hh
index 37856d8..c02e655 100644
--- a/src/ui/mw/widgets.hh
+++ b/src/ui/mw/widgets.hh
@@ -93,7 +93,8 @@ struct SExpDesignUIWidgets {
       // 1. Measurements
        GtkMenuItem
                *iiMainMenu,
-               *iExpRefresh, *iExpPurgeComputed, *iExpAnnotations, *iExpClose, 
*iExpQuit,
+               *iExpRefresh, *iExpPurgeComputed, *iExpAnnotations,
+               *iExpClose, *iExpQuit,
                *iExpBasicSADetectUltradianCycles,
                *iiExpGlobalOperations,
                *iExpGloballyDetectArtifacts,
@@ -101,6 +102,15 @@ struct SExpDesignUIWidgets {
                *iMontageSetDefaults,
                *iHelpAbout,
                *iHelpUsage;
+       GtkRadioMenuItem
+               *iExpSubjectSortName,
+               *iExpSubjectSortAge,
+               *iExpSubjectSortAdmissionDate,
+               *iExpSubjectSortAvgPower;
+       GtkCheckMenuItem
+               *iExpSubjectSortAscending,
+               *iExpSubjectSortSegregate;
+
 
        // profile mode & parameters
        GtkBox  *cMsmtTopArea,

-- 
Sleep experiment manager

_______________________________________________
debian-med-commit mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit

Reply via email to