source: src/mlx/gui/checklist.py@ 282:568be726e4bc

Last change on this file since 282:568be726e4bc was 280:4d2a277c703b, checked in by István Váradi <ivaradi@…>, 12 years ago

Added a popup menu to the callouts editor's file list

File size: 14.6 KB
Line 
1# Module for editing checklists
2
3#------------------------------------------------------------------------------
4
5from common import *
6
7from mlx.i18n import xstr
8import mlx.const as const
9import mlx.config as config
10
11import os
12
13#------------------------------------------------------------------------------
14
15class ChecklistEditor(gtk.Dialog):
16 """The dialog to edit the checklists."""
17 def __init__(self, gui):
18 super(ChecklistEditor, self).__init__(WINDOW_TITLE_BASE + " - " +
19 xstr("chklst_title"),
20 gui.mainWindow,
21 DIALOG_MODAL)
22
23 self.add_button(xstr("button_cancel"), RESPONSETYPE_REJECT)
24 self.add_button(xstr("button_ok"), RESPONSETYPE_ACCEPT)
25
26 self._gui = gui
27 self._checklists = {}
28 self._currentAircraftType = const.aircraftTypes[0]
29
30 contentArea = self.get_content_area()
31
32 typeBox = gtk.HBox()
33
34 label = gtk.Label(xstr("chklst_aircraftType"))
35 label.set_use_underline(True)
36
37 typeBox.pack_start(label, False, False, 4)
38
39 self._aircraftTypeModel = gtk.ListStore(str, int)
40 for type in const.aircraftTypes:
41 name = aircraftNames[type] if type in aircraftNames \
42 else "Aircraft type #%d" % (type,)
43 self._aircraftTypeModel.append([name, type])
44 self._aircraftType = gtk.ComboBox(model = self._aircraftTypeModel)
45 renderer = gtk.CellRendererText()
46 self._aircraftType.pack_start(renderer, True)
47 self._aircraftType.add_attribute(renderer, "text", 0)
48 self._aircraftType.set_tooltip_text(xstr("chklst_aircraftType_tooltip"))
49 self._aircraftType.set_active(0)
50 self._aircraftType.connect("changed", self._aircraftTypeChanged)
51 label.set_mnemonic_widget(self._aircraftType)
52
53 typeBox.pack_start(self._aircraftType, True, True, 4)
54
55 typeBoxAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
56 xscale = 0.0, yscale = 0.0)
57 typeBoxAlignment.set_size_request(400, -1)
58 typeBoxAlignment.add(typeBox)
59
60 contentArea.pack_start(typeBoxAlignment, False, False, 12)
61
62 fileBox = gtk.HBox()
63
64 self._fileChooser = gtk.FileChooserWidget()
65 self._fileChooser.set_select_multiple(True)
66
67 filter = gtk.FileFilter()
68 filter.set_name(xstr("file_filter_audio"))
69 filter.add_pattern("*.wav")
70 filter.add_pattern("*.mp3")
71 self._fileChooser.add_filter(filter)
72
73 filter = gtk.FileFilter()
74 filter.set_name(xstr("file_filter_all"))
75 filter.add_pattern("*.*")
76 self._fileChooser.add_filter(filter)
77
78 self._fileChooser.connect("selection-changed",
79 self._fileChooserSelectionChanged)
80
81 fileBox.pack_start(self._fileChooser, True, True, 4)
82
83 controlBox = gtk.VBox()
84 controlAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
85 xscale = 0.0, yscale = 0.0)
86 controlAlignment.set_padding(padding_top = 0, padding_bottom = 0,
87 padding_left = 32, padding_right = 32)
88 controlAlignment.add(controlBox)
89 fileBox.pack_start(controlAlignment, False, False, 0)
90
91 self._addButton = gtk.Button(xstr("chklst_add"))
92 self._addButton.set_use_underline(True)
93 self._addButton.set_tooltip_text(xstr("chklst_add_tooltip"))
94 self._addButton.connect("clicked", self._addButtonClicked)
95 addAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.0,
96 xscale = 0.0, yscale = 0.0)
97 addAlignment.set_padding(padding_top = 64, padding_bottom = 0,
98 padding_left = 0, padding_right = 0)
99 addAlignment.add(self._addButton)
100 controlBox.pack_start(addAlignment, False, False, 0)
101
102 self._removeButton = gtk.Button(xstr("chklst_remove"))
103 self._removeButton.set_use_underline(True)
104 self._removeButton.set_tooltip_text(xstr("chklst_remove_tooltip"))
105 self._removeButton.set_sensitive(False)
106 self._removeButton.connect("clicked", self._removeButtonClicked)
107
108 removeAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.0,
109 xscale = 0.0, yscale = 0.0)
110 removeAlignment.set_padding(padding_top = 64, padding_bottom = 0,
111 padding_left = 0, padding_right = 0)
112 removeAlignment.add(self._removeButton)
113 controlBox.pack_start(removeAlignment, False, False, 0)
114
115 self._moveUpButton = gtk.Button(xstr("chklst_moveUp"))
116 self._moveUpButton.set_use_underline(True)
117 self._moveUpButton.set_tooltip_text(xstr("chklst_moveUp_tooltip"))
118 self._moveUpButton.set_sensitive(False)
119 self._moveUpButton.connect("clicked", self._moveUpButtonClicked)
120
121 moveUpAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.0,
122 xscale = 0.0, yscale = 0.0)
123 moveUpAlignment.set_padding(padding_top = 16, padding_bottom = 0,
124 padding_left = 0, padding_right = 0)
125 moveUpAlignment.add(self._moveUpButton)
126 controlBox.pack_start(moveUpAlignment, False, False, 0)
127
128 self._moveDownButton = gtk.Button(xstr("chklst_moveDown"))
129 self._moveDownButton.set_use_underline(True)
130 self._moveDownButton.set_tooltip_text(xstr("chklst_moveDown_tooltip"))
131 self._moveDownButton.set_sensitive(False)
132 self._moveDownButton.connect("clicked", self._moveDownButtonClicked)
133
134 moveDownAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.0,
135 xscale = 0.0, yscale = 0.0)
136 moveDownAlignment.set_padding(padding_top = 4, padding_bottom = 0,
137 padding_left = 0, padding_right = 0)
138 moveDownAlignment.add(self._moveDownButton)
139 controlBox.pack_start(moveDownAlignment, False, False, 0)
140
141 self._fileListModel = gtk.ListStore(str, str)
142 self._fileList = gtk.TreeView(model = self._fileListModel)
143 self._fileList.connect("button-press-event",
144 self._fileListButtonPressed)
145 column = gtk.TreeViewColumn(xstr("chklst_header"),
146 gtk.CellRendererText(), text = 0)
147 column.set_expand(True)
148 column.set_clickable(False)
149 column.set_reorderable(False)
150 self._fileList.append_column(column)
151 self._fileList.set_tooltip_column(1)
152 self._fileList.set_reorderable(True)
153 self._fileListPopupMenu = None
154 selection = self._fileList.get_selection()
155 selection.set_mode(SELECTION_MULTIPLE)
156 selection.connect("changed", self._fileListSelectionChanged)
157
158 self._buildFileListPopupMenu()
159
160 scrolledWindow = gtk.ScrolledWindow()
161 scrolledWindow.add(self._fileList)
162 scrolledWindow.set_size_request(200, -1)
163 scrolledWindow.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
164 scrolledWindow.set_shadow_type(SHADOW_IN)
165
166 fileBox.pack_start(scrolledWindow, False, False, 4)
167
168 contentArea.pack_start(fileBox, True, True, 4)
169
170 self.set_size_request(900, 500)
171
172 def run(self):
173 """Run the checklist editor dialog."""
174 self._checklists = {}
175 self._displayCurrentChecklist()
176 self.show_all()
177 response = super(ChecklistEditor, self).run()
178 self.hide()
179
180 if response==RESPONSETYPE_ACCEPT:
181 self._saveChecklist()
182 config = self._gui.config
183 for (aircraftType, checklist) in self._checklists.iteritems():
184 config.setChecklist(aircraftType, checklist)
185 config.save()
186
187 def _aircraftTypeChanged(self, comboBox):
188 """Called when the aircraft's type has changed."""
189 self._saveChecklist()
190 self._displayCurrentChecklist()
191
192 def _fileChooserSelectionChanged(self, fileChooser):
193 """Called when the selection of the given file chooser is changed."""
194 numFiles = 0
195 numSelected = 0
196 for path in fileChooser.get_filenames():
197 path = text2unicode(path)
198 numSelected += 1
199 if os.path.isfile(path): numFiles += 1
200
201 self._addButton.set_sensitive(numFiles>0 and numFiles==numSelected)
202
203 def _addButtonClicked(self, button):
204 """Called when the Add button is clicked."""
205 for path in self._fileChooser.get_filenames():
206 path = text2unicode(path)
207 self._fileListModel.append([os.path.basename(path),
208 path])
209 self._fileChooser.unselect_all()
210
211 def _removeButtonClicked(self, button):
212 """Called when the Remove button is clicked."""
213 self._removeSelected()
214
215 def _removeSelected(self):
216 """Remove the currently selected files."""
217 selection = self._fileList.get_selection()
218 (model, paths) = selection.get_selected_rows()
219
220 iters = [model.get_iter(path) for path in paths]
221
222 for i in iters:
223 if i is not None:
224 model.remove(i)
225
226 def _moveUpButtonClicked(self, button):
227 """Called when the move up button is clicked."""
228 self._moveSelected(True)
229
230 def _moveDownButtonClicked(self, button):
231 """Called when the move down button is clicked."""
232 self._moveSelected(False)
233
234 def _moveSelected(self, up):
235 """Move the selected files up or down."""
236 selection = self._fileList.get_selection()
237 (model, paths) = selection.get_selected_rows()
238 indexes = [(path.get_indices() if pygobject else path)[0]
239 for path in paths]
240 indexes.sort()
241 if not up:
242 indexes.reverse()
243
244 for index in indexes:
245 fromIter = model.iter_nth_child(None, index)
246 toIter = model.iter_nth_child(None, index-1 if up else index + 1)
247 if up:
248 model.move_before(fromIter, toIter)
249 else:
250 model.move_after(fromIter, toIter)
251
252 self._moveUpButton.set_sensitive(indexes[0]>1 if up else True)
253 numRows = model.iter_n_children(None)
254 self._moveDownButton.set_sensitive(True if up else
255 indexes[0]<(numRows-2))
256
257 def _fileListSelectionChanged(self, selection):
258 """Called when the selection in the file list changes."""
259 anySelected = selection.count_selected_rows()>0
260 self._removeButton.set_sensitive(anySelected)
261 self._popupRemoveItem.set_sensitive(anySelected)
262
263 if anySelected:
264 (model, paths) = selection.get_selected_rows()
265 minIndex = None
266 maxIndex = None
267 for path in paths:
268 [index] = path.get_indices() if pygobject else path
269 if minIndex is None or index<minIndex: minIndex = index
270 if maxIndex is None or index>maxIndex: maxIndex = index
271
272 self._moveUpButton.set_sensitive(minIndex>0)
273 self._popupMoveUpItem.set_sensitive(minIndex>0)
274
275 numRows = model.iter_n_children(None)
276 self._moveDownButton.set_sensitive(maxIndex<(numRows-1))
277 self._popupMoveDownItem.set_sensitive(maxIndex<(numRows-1))
278 else:
279 self._moveUpButton.set_sensitive(False)
280 self._popupMoveUpItem.set_sensitive(False)
281 self._moveDownButton.set_sensitive(False)
282 self._popupMoveDownItem.set_sensitive(False)
283
284 def _getAircraftType(self):
285 """Get the currently selected aircraft type."""
286 index = self._aircraftType.get_active()
287 return self._aircraftTypeModel[index][1]
288
289 def _saveChecklist(self):
290 """Save the currently displayed checklist for the previously displayed
291 aircraft type."""
292 fileList = []
293 model = self._fileListModel
294 iter = model.get_iter_first()
295 while iter is not None:
296 path = model.get(iter, 1)[0]
297 fileList.append(path)
298 iter = model.iter_next(iter)
299
300 self._checklists[self._currentAircraftType] = config.Checklist(fileList)
301
302 def _displayCurrentChecklist(self):
303 """Display the checklist for the currently selected aircraft type."""
304 aircraftType = self._getAircraftType()
305 self._currentAircraftType = aircraftType
306 if aircraftType not in self._checklists:
307 self._checklists[aircraftType] = \
308 self._gui.config.getChecklist(aircraftType).clone()
309 checklist = self._checklists[aircraftType]
310
311 self._fileListModel.clear()
312 for path in checklist:
313 self._fileListModel.append([os.path.basename(path), path])
314
315 def _fileListButtonPressed(self, widget, event):
316 """Called when a mouse button is pressed on the file list."""
317 if event.type!=EVENT_BUTTON_PRESS or event.button!=3:
318 return
319
320 menu = self._fileListPopupMenu
321 if pygobject:
322 menu.popup(None, None, None, None, event.button, event.time)
323 else:
324 menu.popup(None, None, None, event.button, event.time)
325
326 def _buildFileListPopupMenu(self):
327 """Build the file list popup menu."""
328 menu = gtk.Menu()
329
330 menuItem = gtk.MenuItem()
331 menuItem.set_label(xstr("chklst_remove"))
332 menuItem.set_use_underline(True)
333 menuItem.connect("activate", self._popupRemove)
334 menuItem.show()
335 self._popupRemoveItem = menuItem
336
337 menu.append(menuItem)
338
339 menuItem = gtk.MenuItem()
340 menuItem.set_label(xstr("chklst_moveUp"))
341 menuItem.set_use_underline(True)
342 menuItem.connect("activate", self._popupMoveUp)
343 menuItem.show()
344 self._popupMoveUpItem = menuItem
345
346 menu.append(menuItem)
347
348 menuItem = gtk.MenuItem()
349 menuItem.set_label(xstr("chklst_moveDown"))
350 menuItem.set_use_underline(True)
351 menuItem.connect("activate", self._popupMoveDown)
352 menuItem.show()
353 self._popupMoveDownItem = menuItem
354
355 menu.append(menuItem)
356
357 self._fileListPopupMenu = menu
358
359 def _popupRemove(self, menuItem):
360 """Remove the currently selected menu items."""
361 self._removeSelected()
362
363 def _popupMoveUp(self, menuItem):
364 """Move up the currently selected menu items."""
365 self._moveSelected(True)
366
367 def _popupMoveDown(self, menuItem):
368 """Move down the currently selected menu items."""
369 self._moveSelected(False)
370
371#------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.