[fractal] attach: use common filechooser widget to attach file



commit 8afbc5cd15776da03c4de125ef4b3635ac7eaa4e
Author: Julian Sparber <julian sparber net>
Date:   Fri Dec 28 16:53:09 2018 +0100

    attach: use common filechooser widget to attach file

 fractal-gtk/src/actions/global.rs           | 16 ++++++++
 fractal-gtk/src/app/connect/attach.rs       | 12 ------
 fractal-gtk/src/app/connect/mod.rs          |  2 -
 fractal-gtk/src/appop/attach.rs             | 15 +++-----
 fractal-gtk/src/appop/message.rs            | 57 +++++++----------------------
 fractal-gtk/src/widgets/file_dialog.rs      |  2 +-
 fractal-gtk/src/widgets/sourceview_entry.rs |  1 +
 7 files changed, 37 insertions(+), 68 deletions(-)
---
diff --git a/fractal-gtk/src/actions/global.rs b/fractal-gtk/src/actions/global.rs
index 3236fb91..f6c5570e 100644
--- a/fractal-gtk/src/actions/global.rs
+++ b/fractal-gtk/src/actions/global.rs
@@ -5,6 +5,8 @@ use std::rc::Rc;
 use std::sync::{Arc, Mutex};
 
 use crate::appop::AppOp;
+use crate::i18n::i18n;
+use crate::widgets::FileDialog::open;
 use crate::App;
 use fractal_api::types::Message;
 use gio::prelude::*;
@@ -85,6 +87,8 @@ pub fn new(app: &gtk::Application, op: &Arc<Mutex<AppOp>>) {
     let directory = SimpleAction::new("directory", None);
     //TODO: use roomid as value
     let room_settings = SimpleAction::new("open-room-settings", None);
+    // TODO: send file should be a room_history action
+    let send_file = SimpleAction::new("send-file", None);
 
     app.add_action(&settings);
     app.add_action(&account);
@@ -107,6 +111,8 @@ pub fn new(app: &gtk::Application, op: &Arc<Mutex<AppOp>>) {
     app.add_action(&media_viewer);
     app.add_action(&account);
 
+    app.add_action(&send_file);
+
     // When activated, shuts down the application
     let app_weak = app.downgrade();
     quit.connect_activate(move |_action, _parameter| {
@@ -207,6 +213,16 @@ pub fn new(app: &gtk::Application, op: &Arc<Mutex<AppOp>>) {
         }
     });
 
+    let app_weak = app.downgrade();
+    send_file.connect_activate(move |_, _| {
+        let app = upgrade_weak!(app_weak);
+        if let Some(window) = app.get_active_window() {
+            if let Some(path) = open(&window, i18n("Select a file").as_str()) {
+                APPOP!(attach_message, (path));
+            }
+        }
+    });
+
     /* Add Keybindings to actions */
     app.set_accels_for_action("app.quit", &["<Ctrl>Q"]);
     app.set_accels_for_action("app.back", &["Escape"]);
diff --git a/fractal-gtk/src/app/connect/mod.rs b/fractal-gtk/src/app/connect/mod.rs
index fcea064f..c37f95e7 100644
--- a/fractal-gtk/src/app/connect/mod.rs
+++ b/fractal-gtk/src/app/connect/mod.rs
@@ -1,5 +1,4 @@
 mod account;
-mod attach;
 mod autocomplete;
 mod direct;
 mod directory;
@@ -21,7 +20,6 @@ impl App {
         self.connect_login_view();
 
         self.connect_send();
-        self.connect_attach();
         self.connect_markdown();
         self.connect_autocomplete();
 
diff --git a/fractal-gtk/src/appop/attach.rs b/fractal-gtk/src/appop/attach.rs
index b5c44279..f8235405 100644
--- a/fractal-gtk/src/appop/attach.rs
+++ b/fractal-gtk/src/appop/attach.rs
@@ -6,7 +6,6 @@ use std::io::prelude::*;
 use std::path::PathBuf;
 use std::sync::{Arc, Mutex};
 
-use failure::err_msg;
 use failure::Error;
 
 use gdk;
@@ -73,8 +72,8 @@ impl AppOp {
                 }));
                 /* FIXME: make this a action */
                 okbtn.connect_clicked(clone!(pixb, dialog => move |_| {
-                    if let Ok(file) = store_pixbuf(&pixb) {
-                        APPOP!(attach_message, (file))
+                    if let Ok(path) = store_pixbuf(&pixb) {
+                        APPOP!(attach_message, (path))
                     }
                     dialog.destroy();
                 }));
@@ -85,19 +84,15 @@ impl AppOp {
     }
 }
 
-fn store_pixbuf(pixb: &Pixbuf) -> Result<String, Error> {
+fn store_pixbuf(pixb: &Pixbuf) -> Result<PathBuf, Error> {
     let data = get_pixbuf_data(pixb)?;
     let mut path = glib::get_tmp_dir().unwrap_or(PathBuf::from("/tmp"));
     path.push("fractal-pasted-image");
-    let file = path
-        .into_os_string()
-        .into_string()
-        .map_err(|_| err_msg("bad string"))?;
-    let mut f = File::create(file.clone())?;
+    let mut f = File::create(&path)?;
     f.write_all(&data)?;
     f.sync_data()?;
 
-    Ok(file)
+    Ok(path)
 }
 
 /// This function receives the appop mutex to avoid lock the interface
diff --git a/fractal-gtk/src/appop/message.rs b/fractal-gtk/src/appop/message.rs
index 80083c38..65872d5a 100644
--- a/fractal-gtk/src/appop/message.rs
+++ b/fractal-gtk/src/appop/message.rs
@@ -5,7 +5,7 @@ use gtk::prelude::*;
 use lazy_static::lazy_static;
 use std::collections::HashMap;
 use std::fs;
-use std::path::Path;
+use std::path::PathBuf;
 use tree_magic;
 
 use crate::appop::room::Force;
@@ -243,12 +243,10 @@ impl AppOp {
         self.dequeue_message();
     }
 
-    pub fn attach_message(&mut self, file: String) -> Message {
+    pub fn attach_message(&mut self, path: PathBuf) -> Option<()> {
         let now = Local::now();
-        let room = self.active_room.clone();
-        let f = file.clone();
-        let p: &Path = Path::new(&f);
-        let mime = tree_magic::from_filepath(p);
+        let room = self.active_room.clone()?;
+        let mime = tree_magic::from_filepath(&path);
         let mtype = match mime.as_ref() {
             "image/gif" => "m.image",
             "image/png" => "m.image",
@@ -256,21 +254,23 @@ impl AppOp {
             "image/jpg" => "m.image",
             _ => "m.file",
         };
-        let body = String::from(file.split("/").last().unwrap_or(&file));
+        let body = path.file_name().and_then(|s| s.to_str());
+        let path_string = path.to_str()?.to_string();
 
         let info = match mtype {
-            "m.image" => get_image_media_info(&file, mime.as_ref()),
+            "m.image" => get_image_media_info(&path_string, mime.as_ref()),
             _ => None,
         };
 
+        // TODO: write constructor for Message
         let mut m = Message {
-            sender: self.uid.clone().unwrap_or_default(),
+            sender: self.uid.clone()?,
             mtype: mtype.to_string(),
-            body: body,
-            room: room.unwrap_or_default(),
+            body: body?.to_string(),
+            room,
             date: now,
             thumb: None,
-            url: Some(file),
+            url: Some(path_string),
             id: None,
             formatted_body: None,
             format: None,
@@ -282,10 +282,10 @@ impl AppOp {
         };
 
         m.id = Some(m.get_txn_id());
-        self.add_tmp_room_message(m.clone());
+        self.add_tmp_room_message(m);
         self.dequeue_message();
 
-        m
+        Some(())
     }
 
     /// This method is called when a tmp message with an attach is sent correctly
@@ -300,35 +300,6 @@ impl AppOp {
         self.add_tmp_room_message(msg);
     }
 
-    pub fn attach_file(&mut self) {
-        let window: gtk::ApplicationWindow = self
-            .ui
-            .builder
-            .get_object("main_window")
-            .expect("Can't find main_window in ui file.");
-
-        let file_chooser = gtk::FileChooserNative::new(
-            None,
-            Some(&window),
-            gtk::FileChooserAction::Open,
-            None,
-            None,
-        );
-
-        // Running in a *thread* to free self lock
-        // FIXME don't use idle_add
-        gtk::idle_add(move || {
-            let result = file_chooser.run();
-            if gtk::ResponseType::from(result) == gtk::ResponseType::Accept {
-                if let Some(fname) = file_chooser.get_filename() {
-                    let f = String::from(fname.to_str().unwrap_or_default());
-                    APPOP!(attach_message, (f));
-                }
-            }
-            gtk::Continue(false)
-        });
-    }
-
     /* TODO: find a better name for this function */
     pub fn show_room_messages(&mut self, newmsgs: Vec<Message>) -> Option<()> {
         let mut msgs = vec![];
diff --git a/fractal-gtk/src/widgets/file_dialog.rs b/fractal-gtk/src/widgets/file_dialog.rs
index bf14209b..11f178da 100644
--- a/fractal-gtk/src/widgets/file_dialog.rs
+++ b/fractal-gtk/src/widgets/file_dialog.rs
@@ -1,7 +1,7 @@
+use crate::i18n::i18n;
 use gtk;
 use gtk::prelude::*;
 use gtk::ResponseType;
-use i18n::i18n;
 use std::path::PathBuf;
 
 pub fn save(parent: &gtk::Window, title: &str) -> Option<PathBuf> {
diff --git a/fractal-gtk/src/widgets/sourceview_entry.rs b/fractal-gtk/src/widgets/sourceview_entry.rs
index e8796c27..0a0060b9 100644
--- a/fractal-gtk/src/widgets/sourceview_entry.rs
+++ b/fractal-gtk/src/widgets/sourceview_entry.rs
@@ -35,6 +35,7 @@ impl Default for SVEntry {
         attach.set_image(&attach_img);
         attach.set_valign(gtk::Align::End);
         attach.set_receives_default(true);
+        attach.set_action_name("app.send-file");
         // TODO: there was an a11y object in the xml
         /*
         <object class="AtkObject" id="attach_button-atkobject">


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]