Dialogs

For the open and save dialog, we'll use the same functions as in the previous chapter:

use std::path::PathBuf;

use gtk::{FileChooserAction, FileChooserDialog, FileFilter};
use gtk_sys::{GTK_RESPONSE_ACCEPT, GTK_RESPONSE_CANCEL};

const RESPONSE_ACCEPT: i32 = GTK_RESPONSE_ACCEPT as i32;
const RESPONSE_CANCEL: i32 = GTK_RESPONSE_CANCEL as i32;

fn show_open_dialog(parent: &Window) -> Option<PathBuf> {
    let mut file = None;
    let dialog = FileChooserDialog::new(Some("Select an MP3 audio file"), 
Some(parent), FileChooserAction::Open); let mp3_filter = FileFilter::new(); mp3_filter.add_mime_type("audio/mp3"); mp3_filter.set_name("MP3 audio file"); dialog.add_filter(&mp3_filter); let m3u_filter = FileFilter::new(); m3u_filter.add_mime_type("audio/x-mpegurl"); m3u_filter.set_name("M3U playlist file"); dialog.add_filter(&m3u_filter); dialog.add_button("Cancel", RESPONSE_CANCEL); dialog.add_button("Accept", RESPONSE_ACCEPT); let result = dialog.run(); if result == RESPONSE_ACCEPT { file = dialog.get_filename(); } dialog.destroy(); file } fn show_save_dialog(parent: &Window) -> Option<PathBuf> { let mut file = None; let dialog = FileChooserDialog::new(Some("Choose a destination M3U playlist
file"
), Some(parent), FileChooserAction::Save); let filter = FileFilter::new(); filter.add_mime_type("audio/x-mpegurl"); filter.set_name("M3U playlist file"); dialog.set_do_overwrite_confirmation(true); dialog.add_filter(&filter); dialog.add_button("Cancel", RESPONSE_CANCEL); dialog.add_button("Save", RESPONSE_ACCEPT); let result = dialog.run(); if result == RESPONSE_ACCEPT { file = dialog.get_filename(); } dialog.destroy(); file }

But this time, we'll put the code for the open action in a method on the App widget:

use gtk::{ButtonsType, DialogFlags, MessageDialog, MessageType};

impl App {
    fn open(&self) {
        let file = show_open_dialog(&self.window);
        if let Some(file) = file {
            let ext = file.extension().map(|ext| 
ext.to_str().unwrap().to_string()); if let Some(ext) = ext { match ext.as_str() { "mp3" => (), "m3u" => (), extension => { let dialog =
MessageDialog::new(Some(&self.window),
DialogFlags::empty(), MessageType::Error, ButtonsType::Ok, &format!("Cannot open file
with extension . {}"
, extension)); dialog.run(); dialog.destroy(); }, } } } } }

We can then call these functions in the update() method:

fn update(&mut self, event: Msg) {
    match event {
        Open => self.open(),
        PlayPause =>  (),
        Quit => gtk::main_quit(),
        Save => show_save_dialog(&self.window),
        Stop => (),
    }
}

Let's manage some of the other actions.