3 from gi.repository
import Gtk
as gtk, Pango
4 from gi.repository
import GObject
as gobject
5 from gi.repository
import GdkPixbuf
as pixbuf
10 from datetime
import datetime
11 from dateutil
import tz
20 last_filechooser_location =
None
23 WAV_FILE_FILTER =
None
24 TRS_FILE_FILTER =
None
25 ALL_FILE_FILTER =
None
26 CSV_FILE_FILTER =
None
27 TRS_CSV_FILE_FILTER =
None
30 DB_DT_OUTPUT_FMT =
'%Y-%m-%d %H:%M:%S'
32 DT_DISPLAY_FMT =
'%b %d, %Y %I:%M %p'
36 BUTTON_ICONS = Enum.from_dict({
37 'CREATE':
'icons/open_icon_library-standard/icons/png/%s/actions/document-new-8.png',
38 'OPEN':
'icons/open_icon_library-standard/icons/png/%s/actions/document-open-8.png',
39 'ADD':
'icons/open_icon_library-standard/icons/png/%s/actions/list-add-5.png',
40 'EDIT':
'icons/open_icon_library-standard/icons/png/%s/actions/edit.png',
41 'REMOVE':
'icons/open_icon_library-standard/icons/png/%s/actions/list-remove-5.png',
42 'DELETE':
'icons/open_icon_library-standard/icons/png/%s/actions/edit-delete-3.png',
43 'RUN':
'icons/open_icon_library-standard/icons/png/%s/actions/system-run-2.png',
44 'CLOSE':
'icons/open_icon_library-standard/icons/png/%s/actions/application-exit-4.png',
45 'EXIT':
'icons/open_icon_library-standard/icons/png/%s/actions/application-exit.png',
46 'EXPAND':
'icons/open_icon_library-standard/icons/png/%s/actions/edit-add-3.png',
47 'COLLAPSE':
'icons/open_icon_library-standard/icons/png/%s/actions/edit-remove-2.png',
48 'REFRESH':
'icons/open_icon_library-standard/icons/png/%s/actions/view-refresh-6.png',
49 'PLAY':
'icons/open_icon_library-standard/icons/png/%s/apps/exaile-2.png',
50 'FLAG':
'icons/open_icon_library-standard/icons/png/%s/actions/flag.png',
51 'EXPORT':
'icons/open_icon_library-standard/icons/png/%s/actions/document-export.png',
52 'SPLIT':
'icons/open_icon_library-standard/icons/png/%s/actions/edit-copy-9.png',
53 'MERGE':
'icons/open_icon_library-standard/icons/png/%s/actions/edit-text-frame-update.png',
54 'CLEAR':
'icons/open_icon_library-standard/icons/png/%s/actions/edit-clear-2.png',
55 'FILTER':
'icons/open_icon_library-standard/icons/png/%s/actions/filter.png',
56 'PRAAT':
'icons/open_icon_library-standard/icons/png/%s/apps/praat.png',
57 'SAVE':
'icons/open_icon_library-standard/icons/png/%s/actions/document-save-as-6.png',
58 'UPDATE':
'icons/open_icon_library-standard/icons/png/%s/apps/system-software-update-4.png',
59 'VOLUME_OFF':
'icons/open_icon_library-standard/icons/png/%s/status/volume-0.png',
60 'VOLUME_ON':
'icons/open_icon_library-standard/icons/png/%s/status/audio-volume-high-5.png',
65 BUTTON_ICON_SIZES = Enum.from_dict({
81 gtk.Settings.get_default().set_long_property(
'gtk-button-images',
True,
'main')
83 gtk.Window.set_default_icon_list([pixbuf.Pixbuf.new_from_file(app_icon_filename)])
91 font = widget.get_style_context().get_font(gtk.StateFlags.NORMAL)
92 font.set_size(pt_size * Pango.SCALE)
94 font.set_weight(Pango.Weight.BOLD)
95 widget.override_font(font)
103 return img_path % (icon_size_dir)
113 button = gtk.Button(label)
115 full_path = UIUtils.get_icon_path(img_path, icon_size_dir)
116 img.set_from_file(full_path)
117 button.set_image(img)
126 dialog = gtk.MessageDialog(buttons=gtk.ButtonsType.YES_NO,
127 type=gtk.MessageType.INFO,
129 response = dialog.run()
132 return response == gtk.ResponseType.YES
139 default_msg =
'Please select a row.'
140 UIUtils.show_message_dialog(default_msg
or alt_msg)
147 default_msg =
'Please make sure that all options have been filled out.'
148 UIUtils.show_message_dialog(default_msg
or alt_msg)
157 dialog = gtk.MessageDialog(buttons=gtk.ButtonsType.OK,
158 message_format=message,
177 entry_box = gtk.HBox()
178 entry_box.pack_start(gtk.Alignment(xalign=0.25, yalign=0),
False,
False, 0)
181 entry_box.pack_start(label,
False,
False, 0)
183 hours_adj = gtk.Adjustment(value=0, lower=0, upper=1000, step_incr=1, page_incr=5)
184 hours_spinner = gtk.SpinButton()
185 hours_spinner.set_adjustment(hours_adj)
186 hours_spinner.set_value(hours)
187 entry_box.pack_start(hours_spinner,
False,
False, 0)
188 entry_box.pack_start(gtk.Label(
':'),
False,
False, 0)
190 mins_adj = gtk.Adjustment(value=0, lower=0, upper=59, step_incr=1, page_incr=5)
191 mins_spinner = gtk.SpinButton()
192 mins_spinner.set_adjustment(mins_adj)
193 mins_spinner.set_value(mins)
194 entry_box.pack_start(mins_spinner,
False,
False, 0)
195 entry_box.pack_start(gtk.Label(
':'),
False,
False, 0)
197 secs_adj = gtk.Adjustment(value=0, lower=0, upper=59, step_incr=1, page_incr=5)
198 secs_spinner = gtk.SpinButton()
199 secs_spinner.set_adjustment(secs_adj)
200 secs_spinner.set_value(secs)
201 entry_box.pack_start(secs_spinner,
False,
False, 0)
202 entry_box.pack_start(gtk.Alignment(xalign=0.25, yalign=0),
False,
False, 0)
204 return entry_box, hours_spinner, mins_spinner, secs_spinner
210 return datetime.now().strftime(UIUtils.DT_DISPLAY_FMT)
217 return datetime.strptime(timestamp, UIUtils.DB_DT_OUTPUT_FMT).strftime(UIUtils.DT_DISPLAY_FMT)
221 from_zone = tz.tzutc()
222 to_zone = tz.tzlocal()
225 utc = datetime.strptime(utc_timestamp, UIUtils.DB_DT_OUTPUT_FMT)
229 utc = utc.replace(tzinfo=from_zone)
232 local = utc.astimezone(to_zone)
234 return local.strftime(UIUtils.DT_DISPLAY_FMT)
242 file_filter = gtk.FileFilter()
243 file_filter.set_name(title)
244 map(file_filter.add_pattern, patterns)
263 model = gtk.ListStore(*types)
264 map(model.append, zip(labels, vals))
266 combobox = gtk.ComboBox(model=model)
267 renderer = gtk.CellRendererText()
268 combobox.pack_start(renderer,
True,
False, 0)
269 combobox.add_attribute(renderer,
'text', 0)
270 combobox.set_active(0)
283 list_store = gtk.ListStore(gobject.TYPE_STRING,
286 for i
in range(len(labels)):
287 list_store.append([labels[i], vals[i]])
304 list_store = UIUtils.build_simple_liststore(labels, vals, val_type)
305 treeview = gtk.TreeView(list_store)
306 treeview.get_selection().set_mode(gtk.SelectionMode.MULTIPLE)
308 col = gtk.TreeViewColumn(header_text, gtk.CellRendererText(), text=0)
309 treeview.append_column(col)
310 col.set_sizing(gtk.TreeViewColumnSizing.AUTOSIZE)
312 col = gtk.TreeViewColumn(
'ID', gtk.CellRendererText(), text=1)
313 col.set_visible(
False)
314 col.set_sizing(gtk.TreeViewColumnSizing.AUTOSIZE)
315 treeview.append_column(col)
329 list_store = gtk.ListStore(gobject.TYPE_STRING,
332 group_keys_enum = DBConstants.COMBO_OPTIONS[group_id]
333 for i
in range(int(
not include_empty_option), len(group_keys_enum)):
334 group_option_key = group_keys_enum[i]
335 option = DBConstants.COMBOS[group_id][group_option_key]
336 if not option.hidden:
337 list_store.append([option.disp_desc, option.db_id])
348 return 90 + (len(col_name) / 15) * 50
358 list_store = UIUtils.build_options_liststore(group_id, include_empty_option)
360 combobox = gtk.ComboBox(model=list_store)
361 renderer = gtk.CellRendererText()
362 combobox.pack_start(renderer,
True,
False, 0)
363 combobox.add_attribute(renderer,
'text', 0)
365 combobox.set_active(active_index)
377 combo = UIUtils.build_options_combo(DBConstants.COMBO_GROUPS.COMMON_REGEXS)
378 combo.connect(
'changed', UIUtils._fill_entry, entry)
388 opt_id = combo.get_model()[combo.get_active()][1]
394 rows = db.select(
'common_regexs',
'regex'.split(),
'combo_option_id=?', [opt_id])
397 highlight_start = regex.find(
'<')
398 highlight_end = regex.find(
'>')
400 entry.set_text(regex.replace(
'<',
'<').replace(
'>',
'>'))
403 if highlight_start > -1
and highlight_end > -1:
404 entry.select_region(highlight_start, highlight_end)
420 def browse_file(title, entry, filters=[], auto_fill_entry=None, auto_fill_file_extension='wav'):
421 filename = UIUtils.open_file(title, filters, save_last_location=
True)
423 entry.set_text(filename)
424 search_name = filename[:-3] + auto_fill_file_extension
428 if auto_fill_entry
and auto_fill_entry.get_text() ==
'':
429 if os.path.exists(search_name):
430 auto_fill_entry.set_text(search_name)
432 parent_dir = os.path.abspath( os.path.dirname(filename) + os.path.sep + os.path.pardir)
433 search_name = parent_dir + os.path.sep + os.path.basename(search_name)
434 if os.path.exists(search_name):
435 auto_fill_entry.set_text(search_name)
436 except Exception
as e:
437 print 'Unable to find matching %s file: %s' % (auto_fill_file_extension, e)
448 foldername = UIUtils.open_folder(title, filters, save_last_location=
True)
450 entry.set_text(foldername)
460 def open_file(title='Open File', filters=[], save_last_location=False, cur_location=None):
462 filters = [UIUtils.ALL_FILE_FILTER]
463 filename, open_now = UIUtils.show_file_dialog(title, filters, gtk.FileChooserAction.OPEN, gtk.STOCK_OPEN, save_last_location=save_last_location, cur_location=cur_location)
476 def open_folder(title='Select Folder', filters=[], save_last_location=False, cur_location=None):
478 filters = [UIUtils.ALL_FILE_FILTER]
479 foldername, open_now = UIUtils.show_file_dialog(title, filters, gtk.FileChooserAction.SELECT_FOLDER, gtk.STOCK_OPEN, save_last_location=save_last_location, cur_location=cur_location)
491 def save_file(title='Save File', filters=[], open_now_opt=False, save_last_location=False, cur_location=None):
493 filters = [UIUtils.ALL_FILE_FILTER]
494 return UIUtils.show_file_dialog(title, filters, gtk.FileChooserAction.SAVE, gtk.STOCK_SAVE, open_now_opt, save_last_location=save_last_location, cur_location=cur_location)
507 def show_entry_dialog(msg, entry_title, default_text='', validate_regex=r'^.+$', invalid_msg='Please enter a value.'):
508 dialog = gtk.MessageDialog(buttons=gtk.ButtonsType.OK_CANCEL,
510 type=gtk.MessageType.QUESTION)
512 message_area = dialog.get_message_area()
516 entry_label = gtk.Label(entry_title)
518 entry.set_text(default_text)
519 invalid_label = gtk.Label(
'')
522 hbox.pack_start(entry_label,
False,
False, 0)
523 hbox.pack_start(entry,
False,
False, 0)
524 vbox.pack_start(hbox,
False,
False, 0)
525 vbox.pack_start(invalid_label,
False,
False, 0)
527 message_area.pack_end(vbox,
False,
False, 0)
532 while text ==
None and dialog.run() == gtk.ResponseType.OK:
533 entry_input = entry.get_text()
534 if re.match(validate_regex, entry_input):
537 invalid_label.set_markup(
'<span foreground="red">%s</span>' % (invalid_msg))
560 dialog = gtk.FileChooserDialog(title=title,
562 buttons=(gtk.STOCK_CANCEL, gtk.ResponseType.CANCEL, confirm_button_stock, gtk.ResponseType.OK))
563 dialog.set_default_response(gtk.ResponseType.OK)
564 if save_last_location
and UIUtils.last_filechooser_location:
565 dialog.set_current_folder(UIUtils.last_filechooser_location)
567 for cur_filter
in filters:
568 dialog.add_filter(cur_filter)
571 content_area = dialog.get_content_area()
573 for button
in checkbuttons:
574 align = gtk.Alignment(xalign=1.0, yalign=1.0)
576 vbox.pack_start(align,
False,
False, 0)
578 content_area.pack_end(vbox,
False,
False, 0)
581 response = dialog.run()
582 if response == gtk.ResponseType.OK:
583 filename = dialog.get_filename()
584 for button
in checkbuttons:
585 check_results.append(button.get_active())
589 if save_last_location
and filename:
590 UIUtils.last_filechooser_location = os.path.dirname(filename)
592 return filename, check_results
608 def show_file_dialog(title, filters, action, confirm_button_stock, open_now_opt=False, save_last_location=False, cur_location=None):
610 open_now_checkbox =
None
613 dialog = gtk.FileChooserDialog(title=title,
615 buttons=(gtk.STOCK_CANCEL, gtk.ResponseType.CANCEL, confirm_button_stock, gtk.ResponseType.OK))
616 dialog.set_default_response(gtk.ResponseType.OK)
618 dialog.set_current_folder(cur_location)
619 elif save_last_location
and UIUtils.last_filechooser_location:
620 dialog.set_current_folder(UIUtils.last_filechooser_location)
622 map(
lambda f: dialog.add_filter(f), filters)
626 content_area = dialog.get_content_area()
627 open_now_checkbox = gtk.CheckButton(
'Open Immediately')
628 open_now_checkbox.set_active(
True)
629 align = gtk.Alignment(xalign=1.0, yalign=1.0)
630 align.add(open_now_checkbox)
631 content_area.pack_end(align,
False,
False, 0)
632 open_now_checkbox.show()
635 response = dialog.run()
636 if response == gtk.ResponseType.OK:
637 filename = dialog.get_filename()
639 open_now = open_now_checkbox.get_active()
643 if save_last_location
and filename:
644 UIUtils.last_filechooser_location = os.path.dirname(filename)
646 return filename, open_now
654 UIUtils.WAV_FILE_FILTER = UIUtils.build_file_filter(
'WAV Files', [
'*.wav'])
655 UIUtils.TRS_FILE_FILTER = UIUtils.build_file_filter(
'TRS Files', [
'*.trs'])
656 UIUtils.ALL_FILE_FILTER = UIUtils.build_file_filter(
'All Files', [
'*'])
657 UIUtils.CSV_FILE_FILTER = UIUtils.build_file_filter(
'CSV Files', [
'*.csv'])
658 UIUtils.TRS_CSV_FILE_FILTER = UIUtils.build_file_filter(
'TRS/CSV Files', [
'*.trs',
'*.csv'])