99from traitsui .ui_editors .data_frame_editor import DataFrameEditor
1010
1111# Local imports
12- from . .model .image_folder import FILENAME_COL , ImageFolder , NUM_FACE_COL
12+ from pycasa .model .image_folder import FILENAME_COL , ImageFolder , NUM_FACE_COL
1313
1414
1515DISPLAYED_COLUMNS = [FILENAME_COL , NUM_FACE_COL ] + [
1919 'ISOSpeedRatings' , 'SceneType'
2020]
2121
22+ YEAR_KEY = "__year__"
23+
24+ DATETIME_COL = "DateTime"
25+
26+ MAKE_COL = 'Make'
27+
2228
2329class ImageFolderView (ModelView ):
2430 """ ModelView for an image folder object.
@@ -30,6 +36,10 @@ class ImageFolderView(ModelView):
3036 # Filters widgets
3137 view_filter_controls = Bool
3238
39+ # Copy of the model's data, with filtering columns added if missing
40+ all_data = Instance (pd .DataFrame )
41+
42+ # Filtered dataframe based on filtering widgets
3343 filtered_data = Instance (pd .DataFrame )
3444
3545 year_mask = Instance (pd .Series )
@@ -44,7 +54,7 @@ class ImageFolderView(ModelView):
4454
4555 def traits_view (self ):
4656 view = View (
47- Item ("model.path " , style = "readonly" , show_label = False ),
57+ Item ("model.directory " , style = "readonly" , show_label = False ),
4858 HGroup (
4959 Spring (),
5060 Item ("view_filter_controls" ),
@@ -73,7 +83,6 @@ def traits_view(self):
7383 enabled_when = "len(model.data) > 0" ),
7484 Spring (),
7585 ),
76- resizable = True , height = 800
7786 )
7887 return view
7988
@@ -82,22 +91,22 @@ def traits_view(self):
8291 @observe ("scan" )
8392 def scan_for_faces (self , event ):
8493 self .model .compute_num_faces ()
94+ self .all_data .update (self .model .data )
8595
8696 @observe ("selected_years" )
8797 def update_years (self , event ):
88- self .year_mask = self .model . data [ 'Year' ].isin (self .selected_years )
98+ self .year_mask = self .all_data [ YEAR_KEY ].isin (self .selected_years )
8999
90100 @observe ("selected_make" )
91101 def update_make (self , event ):
92102 if self .selected_make == "All" :
93- self .make_mask = pd .Series (np .ones (len (self .model .data ),
94- dtype = bool ))
103+ self .make_mask = pd .Series ([True ] * len (self .model .data ))
95104 else :
96- self .make_mask = self .model . data [ 'Make' ] == self .selected_make
105+ self .make_mask = self .all_data [ MAKE_COL ] == self .selected_make
97106
98- @observe ("year_mask, make_mask" )
107+ @observe ("year_mask, make_mask, all_data " )
99108 def update_filtered_data (self , event ):
100- self .filtered_data = self .model . data [self .year_mask & self .make_mask ]
109+ self .filtered_data = self .all_data [self .year_mask & self .make_mask ]
101110
102111 # Initialization methods --------------------------------------------------
103112
@@ -107,15 +116,27 @@ def _make_mask_default(self):
107116 def _year_mask_default (self ):
108117 return pd .Series (np .ones (len (self .model .data ), dtype = bool ))
109118
110- def _filtered_data_default (self ):
111- return self .model .data
119+ def _all_data_default (self ):
120+ # Enrich metadata with missing fields: date time, make
121+ data = self .model .data .copy ()
122+
123+ if DATETIME_COL not in data .columns :
124+ data [DATETIME_COL ] = np .nan
125+
126+ if MAKE_COL not in data .columns :
127+ data [MAKE_COL ] = np .nan
112128
113- def _all_years_default (self ):
114129 def parse_year (x ):
115130 return x .split (":" )[0 ] if isinstance (x , str ) else "unknown"
131+ data [YEAR_KEY ] = data [DATETIME_COL ].apply (parse_year )
132+
133+ return data
116134
117- self .model .data ['Year' ] = self .model .data ['DateTime' ].apply (parse_year )
118- return sorted (self .model .data ['Year' ].unique ().tolist ())
135+ def _filtered_data_default (self ):
136+ return self .all_data
137+
138+ def _all_years_default (self ):
139+ return sorted (self .all_data [YEAR_KEY ].unique ().tolist ())
119140
120141
121142if __name__ == '__main__' :
0 commit comments