Changeset 266:b80521b41013 for src
- Timestamp:
- 07/01/12 17:13:55 (12 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- src/mlx
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/mlx/config.py
r264 r266 584 584 """Set the approach callouts for the given aircraft type.""" 585 585 if not approachCallouts==self._approachCallouts[aircraftType]: 586 print "Updating approach callouts"587 586 self._approachCallouts[aircraftType] = approachCallouts.clone() 588 587 self._modified = True -
src/mlx/gui/callouts.py
r264 r266 10 10 11 11 import os 12 import re 12 13 13 14 #------------------------------------------------------------------------------ … … 15 16 class ApproachCalloutsEditor(gtk.Dialog): 16 17 """The dialog to edit the approach callouts.""" 18 integerRE = re.compile("[0-9]+") 19 20 # A list of "usual" altitudes for callouts 21 _usualAltitudes = [10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 1000, 22 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000] 23 24 @staticmethod 25 def _getNextUsualAltitude(altitude, descending): 26 """Get the next altitude coming after the given one in the 27 given direction.""" 28 if descending: 29 previous = None 30 for alt in ApproachCalloutsEditor._usualAltitudes: 31 if alt>=altitude: return previous 32 previous = alt 33 else: 34 for alt in ApproachCalloutsEditor._usualAltitudes: 35 if alt>altitude: return alt 36 37 return None 38 17 39 def __init__(self, gui): 18 40 super(ApproachCalloutsEditor, self).__init__(WINDOW_TITLE_BASE + " - " + … … 27 49 self._approachCallouts = {} 28 50 self._currentAircraftType = const.aircraftTypes[0] 51 self._fileOpenDialog = None 29 52 30 53 contentArea = self.get_content_area() … … 60 83 61 84 contentArea.pack_start(typeBoxAlignment, False, False, 12) 62 # Until here, but notthat some texts are different85 # FIXME: common code until here, but note that some texts are different 63 86 64 87 fileBox = gtk.HBox() 65 66 # self._fileChooser = gtk.FileChooserWidget()67 # self._fileChooser.set_select_multiple(True)68 69 # filter = gtk.FileFilter()70 # filter.set_name(xstr("chklst_filter_audio"))71 # filter.add_pattern("*.wav")72 # filter.add_pattern("*.mp3")73 # self._fileChooser.add_filter(filter)74 75 # filter = gtk.FileFilter()76 # filter.set_name(xstr("file_filter_all"))77 # filter.add_pattern("*.*")78 # self._fileChooser.add_filter(filter)79 80 # self._fileChooser.connect("selection-changed",81 # self._fileChooserSelectionChanged)82 83 # fileBox.pack_start(self._fileChooser, True, True, 4)84 88 85 89 controlBox = gtk.VBox() … … 97 101 addAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.0, 98 102 xscale = 0.0, yscale = 0.0) 99 addAlignment.set_padding(padding_top = 64, padding_bottom = 0,103 addAlignment.set_padding(padding_top = 24, padding_bottom = 0, 100 104 padding_left = 0, padding_right = 0) 101 105 addAlignment.add(self._addButton) … … 110 114 removeAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.0, 111 115 xscale = 0.0, yscale = 0.0) 112 removeAlignment.set_padding(padding_top = 64, padding_bottom = 0,116 removeAlignment.set_padding(padding_top = 24, padding_bottom = 0, 113 117 padding_left = 0, padding_right = 0) 114 118 removeAlignment.add(self._removeButton) 115 119 controlBox.pack_start(removeAlignment, False, False, 0) 116 120 117 # self._moveUpButton = gtk.Button(xstr("chklst_moveUp"))118 # self._moveUpButton.set_use_underline(True)119 # self._moveUpButton.set_tooltip_text(xstr("chklst_moveUp_tooltip"))120 # self._moveUpButton.set_sensitive(False)121 # self._moveUpButton.connect("clicked", self._moveUpButtonClicked)122 123 # moveUpAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.0,124 # xscale = 0.0, yscale = 0.0)125 # moveUpAlignment.set_padding(padding_top = 16, padding_bottom = 0,126 # padding_left = 0, padding_right = 0)127 # moveUpAlignment.add(self._moveUpButton)128 # controlBox.pack_start(moveUpAlignment, False, False, 0)129 130 # self._moveDownButton = gtk.Button(xstr("chklst_moveDown"))131 # self._moveDownButton.set_use_underline(True)132 # self._moveDownButton.set_tooltip_text(xstr("chklst_moveDown_tooltip"))133 # self._moveDownButton.set_sensitive(False)134 # self._moveDownButton.connect("clicked", self._moveDownButtonClicked)135 136 # moveDownAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.0,137 # xscale = 0.0, yscale = 0.0)138 # moveDownAlignment.set_padding(padding_top = 4, padding_bottom = 0,139 # padding_left = 0, padding_right = 0)140 # moveDownAlignment.add(self._moveDownButton)141 # controlBox.pack_start(moveDownAlignment, False, False, 0)142 143 121 self._fileListModel = gtk.ListStore(int, str, str) 144 122 self._fileListModel.set_sort_column_id(0, SORT_DESCENDING) 123 124 self._addingFile = False 125 self._fileListModel.connect("row-inserted", self._fileAdded) 126 145 127 self._fileList = gtk.TreeView(model = self._fileListModel) 146 128 … … 173 155 self._fileList.set_tooltip_column(2) 174 156 self._fileList.set_reorderable(False) 175 self._fileList.set_size_request( 400, -1)157 self._fileList.set_size_request(300, -1) 176 158 selection = self._fileList.get_selection() 177 159 selection.set_mode(SELECTION_MULTIPLE) … … 182 164 contentArea.pack_start(fileBox, True, True, 4) 183 165 184 self.set_size_request( 500, 500)166 self.set_size_request(400, 300) 185 167 186 168 def run(self): … … 205 187 self._displayCurrentApproachCallouts() 206 188 207 # def _fileChooserSelectionChanged(self, fileChooser):208 # """Called when the selection of the given file chooser is changed."""209 # numFiles = 0210 # numSelected = 0211 # for path in fileChooser.get_filenames():212 # path = text2unicode(path)213 # numSelected += 1214 # if os.path.isfile(path): numFiles += 1215 216 # self._addButton.set_sensitive(numFiles>0 and numFiles==numSelected)217 218 189 def _addButtonClicked(self, button): 219 190 """Called when the Add button is clicked.""" 220 selection = self._fileList.get_selection() 221 (model, paths) = selection.get_selected_rows() 222 iters = [model.get_iter(path) for path in paths] 223 print paths, iters 224 self._fileListModel.append([1300, "1300.mp3", "1300.mp3"]) 225 191 dialog = self._getFileOpenDialog() 192 193 dialog.show_all() 194 result = dialog.run() 195 dialog.hide() 196 197 if result==RESPONSETYPE_OK: 198 filePath = dialog.get_filename() 199 baseName = os.path.basename(filePath) 200 altitude = self._getNewAltitude(baseName) 201 self._addingFile = True 202 self._fileListModel.append([altitude, baseName, filePath]) 203 self._addingFile = False 204 205 def _fileAdded(self, model, path, iter): 206 """Called when a file is added to the list of callouts. 207 208 Makes the treeview to edit the altitude in the given row.""" 209 if self._addingFile: 210 gobject.idle_add(self._fileList.set_cursor, 211 model.get_path(iter), 212 self._fileList.get_column(0), True) 213 self._fileList.grab_focus() 214 self.grab_focus() 215 226 216 def _removeButtonClicked(self, button): 227 217 """Called when the Remove button is clicked.""" … … 235 225 model.remove(i) 236 226 237 # def _moveUpButtonClicked(self, button):238 # """Called when the move up button is clicked."""239 # self._moveSelected(True)240 241 # def _moveDownButtonClicked(self, button):242 # """Called when the move down button is clicked."""243 # self._moveSelected(False)244 245 # def _moveSelected(self, up):246 # """Move the selected files up or down."""247 # selection = self._fileList.get_selection()248 # (model, paths) = selection.get_selected_rows()249 # indexes = [(path.get_indices() if pygobject else path)[0]250 # for path in paths]251 # indexes.sort()252 # if not up:253 # indexes.reverse()254 255 # for index in indexes:256 # fromIter = model.iter_nth_child(None, index)257 # toIter = model.iter_nth_child(None, index-1 if up else index + 1)258 # if up:259 # model.move_before(fromIter, toIter)260 # else:261 # model.move_after(fromIter, toIter)262 263 # self._moveUpButton.set_sensitive(indexes[0]>1 if up else True)264 # numRows = model.iter_n_children(None)265 # self._moveDownButton.set_sensitive(True if up else266 # indexes[0]<(numRows-2))267 268 227 def _fileListSelectionChanged(self, selection): 269 228 """Called when the selection in the file list changes.""" … … 284 243 editedIter = model.get_iter_from_string(path) 285 244 editedPath = model.get_path(editedIter) 286 iter = model.get_iter_first() 287 while iter is not None and newAltitude is not None: 288 path = model.get_path(iter) 289 if editedPath!=path and newAltitude==model[path][0]: 290 dialog = gtk.MessageDialog(parent = self, 291 type = MESSAGETYPE_QUESTION, 292 message_format = 293 xstr("callouts_altitude_clash")) 294 dialog.format_secondary_markup(xstr("callouts_altitude_clash_sec")) 295 dialog.add_button(xstr("button_no"), RESPONSETYPE_NO) 296 dialog.add_button(xstr("button_yes"), RESPONSETYPE_YES) 297 dialog.set_title(WINDOW_TITLE_BASE) 298 299 result = dialog.run() 300 dialog.hide() 301 302 if result==RESPONSETYPE_NO: 303 newAltitude = None 304 iter = model.iter_next(iter) 245 if self._hasAltitude(newAltitude, ignorePath = editedPath): 246 dialog = gtk.MessageDialog(parent = self, 247 type = MESSAGETYPE_QUESTION, 248 message_format = 249 xstr("callouts_altitude_clash")) 250 dialog.format_secondary_markup(xstr("callouts_altitude_clash_sec")) 251 dialog.add_button(xstr("button_no"), RESPONSETYPE_NO) 252 dialog.add_button(xstr("button_yes"), RESPONSETYPE_YES) 253 dialog.set_title(WINDOW_TITLE_BASE) 254 255 result = dialog.run() 256 dialog.hide() 257 258 if result==RESPONSETYPE_NO: 259 newAltitude = None 305 260 306 261 if newAltitude is not None: 307 self._fileListModel[editedPath][0] = newAltitude262 model[editedPath][0] = newAltitude 308 263 309 264 def _saveApproachCallouts(self): … … 335 290 for (altitude, path) in approachCallouts: 336 291 self._fileListModel.append([altitude, os.path.basename(path), path]) 292 293 def _getFileOpenDialog(self): 294 """Get the dialog to open a file. 295 296 If it does not exist yet, it will be created.""" 297 if self._fileOpenDialog is None: 298 dialog = gtk.FileChooserDialog(title = WINDOW_TITLE_BASE + " - " + 299 xstr("callouts_open_title"), 300 action = FILE_CHOOSER_ACTION_OPEN, 301 buttons = (gtk.STOCK_CANCEL, 302 RESPONSETYPE_CANCEL, 303 gtk.STOCK_OK, RESPONSETYPE_OK), 304 parent = self) 305 dialog.set_modal(True) 306 dialog.set_do_overwrite_confirmation(True) 307 308 # FIXME: create the filters in one location and use them 309 # from there 310 filter = gtk.FileFilter() 311 filter.set_name(xstr("file_filter_audio")) 312 filter.add_pattern("*.wav") 313 filter.add_pattern("*.mp3") 314 dialog.add_filter(filter) 315 316 filter = gtk.FileFilter() 317 filter.set_name(xstr("file_filter_all")) 318 filter.add_pattern("*.*") 319 dialog.add_filter(filter) 320 321 self._fileOpenDialog = dialog 322 323 return self._fileOpenDialog 324 325 def _getNewAltitude(self, baseName): 326 """Get a new, unique altitude for the audio file with the given 327 base name. 328 329 First the given file name is searched for suitable 330 numbers. Otherwise the smallest altitude in the model is 331 considered, and, depending on the actual ordering of the 332 table, a suitable smaller or greater value is found. It is 333 ensured that the number is unique, unless all numbers are 334 taken. 335 336 If there is no entry in the table yet, 2500 is returned if the 337 table is sorted descending, 10 otherwise.""" 338 altitude = self._getNewAltitudeFromFileName(baseName) 339 if altitude is not None: return altitude 340 341 descending = self._fileList.get_column(0).get_sort_order()==SORT_DESCENDING 342 model = self._fileListModel 343 numEntries = model.iter_n_children(None) 344 if numEntries==0: 345 return 2500 if descending else 10 346 else: 347 lastIter = model.iter_nth_child(None, numEntries-1) 348 lastValue = model.get_value(lastIter, 0) 349 350 altitude = self._getNextValidUsualAltitude(lastValue, descending) 351 if altitude is None: 352 altitude = self._getNextValidUsualAltitude(lastValue, 353 not descending) 354 355 if altitude is None: 356 for altitude in range(0 if descending else 4999, 357 4999 if descending else 0, 358 1 if descending else -1): 359 if not self._hasAltitude(altitude): break 360 361 return altitude 362 363 def _getNewAltitudeFromFileName(self, baseName): 364 """Get a new altitude value from the given file name. 365 366 The name is traversed for numbers. If a number is less than 367 5000 and there is no such altitude yet in the table, it is 368 checked if it is divisible by 100 or 1000, and if so, it gets 369 a score of 2. If it is divisible by 10, the score will be 1, 370 otherwise 0. The first highest scoring number is returned, if 371 there are any at all, otherwise None.""" 372 candidateAltitude = None 373 candidateScore = None 374 375 (baseName, _) = os.path.splitext(baseName) 376 numbers = ApproachCalloutsEditor.integerRE.findall(baseName) 377 for number in numbers: 378 value = int(number) 379 if value<5000 and not self._hasAltitude(value): 380 score = 2 if (value%100)==0 or (value%1000)==0 \ 381 else 1 if (value%10)==0 else 0 382 if candidateAltitude is None or score>candidateScore: 383 candidateAltitude = value 384 candidateScore = score 385 386 return candidateAltitude 387 388 def _hasAltitude(self, altitude, ignorePath = None): 389 """Determine if the model already contains the given altitude 390 or not. 391 392 ignorePath is a path in the model to ignore.""" 393 model = self._fileListModel 394 iter = model.get_iter_first() 395 while iter is not None: 396 path = model.get_path(iter) 397 if path!=ignorePath and altitude==model[path][0]: 398 return True 399 iter = model.iter_next(iter) 400 401 return False 402 403 def _getNextValidUsualAltitude(self, startValue, descending): 404 """Get the next valid usual altitude.""" 405 value = startValue 406 while value is not None and self._hasAltitude(value): 407 value = \ 408 ApproachCalloutsEditor._getNextUsualAltitude(value, 409 descending) 410 411 return value 337 412 338 413 #------------------------------------------------------------------------------ -
src/mlx/gui/checklist.py
r264 r266 66 66 67 67 filter = gtk.FileFilter() 68 filter.set_name(xstr(" chklst_filter_audio"))68 filter.set_name(xstr("file_filter_audio")) 69 69 filter.add_pattern("*.wav") 70 70 filter.add_pattern("*.mp3") -
src/mlx/i18n.py
r264 r266 163 163 self.add("file_filter_all", "All files") 164 164 self.add("file_filter_pireps", "PIREP files") 165 self.add("file_filter_audio", "Audio files") 165 166 166 167 self.add("button_ok", "_OK") … … 778 779 self.add("chklst_moveDown_tooltip", 779 780 "Move down the selected file(s) in the checklist.") 780 self.add("chklst_filter_audio", "Audio files")781 781 self.add("chklst_header", "Checklist files") 782 782 … … 1034 1034 self.add("file_filter_all", "Összes fájl") 1035 1035 self.add("file_filter_pireps", "PIREP fájlok") 1036 self.add("file_filter_audio", "Audio fájlok") 1036 1037 1037 1038 self.add("button_ok", "_OK") … … 1573 1574 self.add("chklst_moveDown_tooltip", 1574 1575 "Az ellenőrzőlistából kijelölt fájl(ok) eggyel lejjebb mozgatása.") 1575 self.add("chklst_filter_audio", "Audio fájlok")1576 1576 self.add("chklst_header", "Ellenőrzőlista fájljai") 1577 1577
Note:
See TracChangeset
for help on using the changeset viewer.