Changes:
1) Added export all with quotes 2) added delete exports 3) export dir is created if not exists on saving file
This commit is contained in:
parent
9c3d4a4c0f
commit
43d3a63c7f
|
|
@ -72,6 +72,12 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bichannel"
|
||||||
|
version = "0.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4bdf5473d36d166934ddefbedab84ad123ba887d2dd16eb2e1a036c484c213b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit_field"
|
name = "bit_field"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
|
|
@ -879,6 +885,7 @@ dependencies = [
|
||||||
name = "post_maker"
|
name = "post_maker"
|
||||||
version = "0.4.0-alpha.5"
|
version = "0.4.0-alpha.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bichannel",
|
||||||
"clap",
|
"clap",
|
||||||
"dirs",
|
"dirs",
|
||||||
"fltk",
|
"fltk",
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,4 @@ infer = "0.7.0"
|
||||||
textwrap = "0.14"
|
textwrap = "0.14"
|
||||||
webbrowser = "0.5"
|
webbrowser = "0.5"
|
||||||
mozjpeg = "0.9.2"
|
mozjpeg = "0.9.2"
|
||||||
|
bichannel = "0.0.4"
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ impl ConfigPicker {
|
||||||
let top_padding_btn = Frame::default();
|
let top_padding_btn = Frame::default();
|
||||||
let mut panel_flex = Flex::default().row();
|
let mut panel_flex = Flex::default().row();
|
||||||
Frame::default();
|
Frame::default();
|
||||||
let apply_btn = Button::default().with_label("apply");
|
let apply_btn = Button::default().with_label("Apply");
|
||||||
Frame::default();
|
Frame::default();
|
||||||
panel_flex.set_size(&apply_btn, 100);
|
panel_flex.set_size(&apply_btn, 100);
|
||||||
panel_flex.end();
|
panel_flex.end();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,223 @@
|
||||||
|
/*
|
||||||
|
This file is part of Post Maker.
|
||||||
|
Post Maker is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
Post Maker is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Post Maker. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Picker to pick config if multiple configs are present or defalut config is not present
|
||||||
|
use crate::{
|
||||||
|
dialog, globals,
|
||||||
|
result_ext::ResultExt,
|
||||||
|
utils::{self, ImageContainer, ImageInfo, ImageProperties, ImagePropertiesFile},
|
||||||
|
};
|
||||||
|
use bichannel::Channel;
|
||||||
|
use fltk::{
|
||||||
|
app::{self},
|
||||||
|
button::Button,
|
||||||
|
enums,
|
||||||
|
frame::Frame,
|
||||||
|
group::Flex,
|
||||||
|
image::SvgImage,
|
||||||
|
misc::Progress,
|
||||||
|
prelude::*,
|
||||||
|
window::Window,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) struct ExportAllWindow {
|
||||||
|
pub(crate) win: Window,
|
||||||
|
pub(crate) progress: Progress,
|
||||||
|
pub(crate) image_name: Frame,
|
||||||
|
pub(crate) close_btn: Button,
|
||||||
|
pub(crate) images_list: Arc<RwLock<Vec<ImageInfo>>>,
|
||||||
|
pub(crate) channel: Arc<RwLock<Option<Channel<ThreadMessage, ThreadMessage>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExportAllWindow {
|
||||||
|
pub(crate) fn new(images_list: Arc<RwLock<Vec<ImageInfo>>>) -> Self {
|
||||||
|
let mut win = Window::new(0, 0, 500, 130, "Export All").center_screen();
|
||||||
|
win.set_icon(Some(
|
||||||
|
SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(),
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut main_flex = Flex::default().size_of_parent().column();
|
||||||
|
|
||||||
|
//label
|
||||||
|
let mut panel_flex = Flex::default().row();
|
||||||
|
panel_flex.set_size(&Frame::default(), 1);
|
||||||
|
Frame::default()
|
||||||
|
.with_label("Exporting all with quotes")
|
||||||
|
.with_align(enums::Align::Left | enums::Align::Inside);
|
||||||
|
panel_flex.end();
|
||||||
|
main_flex.set_size(&panel_flex, 25);
|
||||||
|
|
||||||
|
//image name
|
||||||
|
let mut panel_flex = Flex::default().row();
|
||||||
|
panel_flex.set_size(&Frame::default(), 1);
|
||||||
|
let image_name = Frame::default()
|
||||||
|
.with_label("")
|
||||||
|
.with_align(enums::Align::Left | enums::Align::Inside);
|
||||||
|
panel_flex.end();
|
||||||
|
main_flex.set_size(&panel_flex, 25);
|
||||||
|
|
||||||
|
// progress bar
|
||||||
|
let mut panel_flex = Flex::default().row();
|
||||||
|
Frame::default();
|
||||||
|
let mut progress = Progress::default().with_label("Exporting...");
|
||||||
|
progress.set_maximum(1.0);
|
||||||
|
progress.set_value(0.0);
|
||||||
|
Frame::default();
|
||||||
|
panel_flex.set_size(&progress, 490);
|
||||||
|
panel_flex.end();
|
||||||
|
main_flex.set_size(&panel_flex, 30);
|
||||||
|
|
||||||
|
//close button
|
||||||
|
let mut panel_flex = Flex::default().row();
|
||||||
|
Frame::default();
|
||||||
|
let close_btn = Button::default().with_label("Cancel");
|
||||||
|
panel_flex.set_size(&Frame::default(), 1);
|
||||||
|
panel_flex.set_size(&close_btn, 100);
|
||||||
|
panel_flex.end();
|
||||||
|
main_flex.set_size(&panel_flex, 30);
|
||||||
|
|
||||||
|
main_flex.end();
|
||||||
|
|
||||||
|
win.end();
|
||||||
|
win.make_resizable(true);
|
||||||
|
|
||||||
|
let mut config_picker = Self {
|
||||||
|
win,
|
||||||
|
progress,
|
||||||
|
image_name,
|
||||||
|
close_btn,
|
||||||
|
images_list,
|
||||||
|
channel: Arc::new(RwLock::new(None)),
|
||||||
|
};
|
||||||
|
config_picker.event();
|
||||||
|
|
||||||
|
config_picker
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn export(&mut self) {
|
||||||
|
self.image_name.set_label("");
|
||||||
|
self.progress.set_label("Exporting...");
|
||||||
|
self.progress.set_maximum(1.0);
|
||||||
|
self.progress.set_value(0.0);
|
||||||
|
self.win.show();
|
||||||
|
let (left, right) = bichannel::channel();
|
||||||
|
*rw_write!(self.channel) = Some(left);
|
||||||
|
spawn_export_thread(self, right);
|
||||||
|
while self.win.shown() {
|
||||||
|
if let Some(channel) = &*rw_read!(self.channel) {
|
||||||
|
if let Ok(msg) = channel.try_recv() {
|
||||||
|
match msg {
|
||||||
|
ThreadMessage::HideWindow => self.win.hide(),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app::wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set callbacks of elements
|
||||||
|
fn event(&mut self) {
|
||||||
|
let channel = Arc::clone(&self.channel);
|
||||||
|
// Close Button
|
||||||
|
self.close_btn.set_callback(move |_| {
|
||||||
|
if dialog::choice_default("Are you sure?", "Yes", "No") == 0 {
|
||||||
|
if let Some(c) = &*rw_read!(channel) {
|
||||||
|
c.send(ThreadMessage::Stop).error_log("Failed to stop task");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let channel = Arc::clone(&self.channel);
|
||||||
|
// Window Close
|
||||||
|
self.win.set_callback(move |_| {
|
||||||
|
if dialog::choice_default("Are you sure?", "Yes", "No") == 0 {
|
||||||
|
if let Some(c) = &*rw_read!(channel) {
|
||||||
|
c.send(ThreadMessage::Stop).error_log("Failed to stop task");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) enum ThreadMessage {
|
||||||
|
Stop,
|
||||||
|
HideWindow,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_export_thread(
|
||||||
|
export_all: &mut ExportAllWindow,
|
||||||
|
channel: Channel<ThreadMessage, ThreadMessage>,
|
||||||
|
) {
|
||||||
|
let mut win = export_all.win.clone();
|
||||||
|
let mut progress = export_all.progress.clone();
|
||||||
|
let mut image_name = export_all.image_name.clone();
|
||||||
|
let images_list = Arc::clone(&export_all.images_list);
|
||||||
|
|
||||||
|
thread::spawn(move || {
|
||||||
|
let total = rw_read!(images_list).len();
|
||||||
|
progress.set_maximum(total as f64);
|
||||||
|
progress.set_value(0.0);
|
||||||
|
for (idx, image) in (*rw_read!(images_list)).iter().enumerate() {
|
||||||
|
image_name.set_label(
|
||||||
|
image
|
||||||
|
.path
|
||||||
|
.file_name()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or_default(),
|
||||||
|
);
|
||||||
|
let properties = Arc::new(RwLock::new(ImageProperties::default()));
|
||||||
|
let container = ImageContainer::new(image, properties);
|
||||||
|
let properties_file = utils::get_properties_path(image);
|
||||||
|
let read = match File::open(&properties_file) {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
let read = match serde_json::from_reader::<File, ImagePropertiesFile>(read) {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
rw_write!(container.properties).merge(read, "", "");
|
||||||
|
|
||||||
|
if rw_read!(container.properties).quote.trim().len() == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
container.save();
|
||||||
|
|
||||||
|
progress.set_value(idx as f64 + 1.0);
|
||||||
|
progress.set_label(&format!("[{}/{}]", idx + 1, total));
|
||||||
|
win.redraw();
|
||||||
|
app::awake();
|
||||||
|
|
||||||
|
if let Ok(msg) = channel.try_recv() {
|
||||||
|
match msg {
|
||||||
|
ThreadMessage::Stop => break,
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image_name.set_label("Done");
|
||||||
|
channel
|
||||||
|
.send(ThreadMessage::HideWindow)
|
||||||
|
.error_log("Failed to close window");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,7 @@ mod config_window;
|
||||||
mod crop_window;
|
mod crop_window;
|
||||||
mod dialog;
|
mod dialog;
|
||||||
mod draw_thread;
|
mod draw_thread;
|
||||||
|
mod export_all_window;
|
||||||
mod globals;
|
mod globals;
|
||||||
mod main_window;
|
mod main_window;
|
||||||
mod result_ext;
|
mod result_ext;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ use crate::{
|
||||||
crop_window::CropWindow,
|
crop_window::CropWindow,
|
||||||
dialog,
|
dialog,
|
||||||
draw_thread::*,
|
draw_thread::*,
|
||||||
|
export_all_window::ExportAllWindow,
|
||||||
globals,
|
globals,
|
||||||
result_ext::ResultExt,
|
result_ext::ResultExt,
|
||||||
utils::{self, ImageInfo, ImageProperties, ImageType},
|
utils::{self, ImageInfo, ImageProperties, ImageType},
|
||||||
|
|
@ -422,13 +423,6 @@ impl MainWindow {
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let expost_dir = path.join("export");
|
|
||||||
if !expost_dir.exists() {
|
|
||||||
if let Err(e) = fs::create_dir(expost_dir) {
|
|
||||||
Result::<(), _>::Err(e).warn_log("Failed to create export folder!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
win.set_label(&format!(
|
win.set_label(&format!(
|
||||||
"{} - Post Maker",
|
"{} - Post Maker",
|
||||||
path.file_name()
|
path.file_name()
|
||||||
|
|
@ -462,6 +456,46 @@ impl MainWindow {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut export_all = ExportAllWindow::new(Arc::clone(&self.images_list));
|
||||||
|
let mut win = self.win.clone();
|
||||||
|
self.menubar.add(
|
||||||
|
"&Actions/Export All with Quotes...\t",
|
||||||
|
Shortcut::None,
|
||||||
|
menu::MenuFlag::Normal,
|
||||||
|
move |_| {
|
||||||
|
win.deactivate();
|
||||||
|
|
||||||
|
export_all.export();
|
||||||
|
win.activate();
|
||||||
|
win.redraw();
|
||||||
|
fltk::app::awake();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let properties = Arc::clone(&self.properties);
|
||||||
|
let mut win = self.win.clone();
|
||||||
|
self.menubar.add(
|
||||||
|
"&Actions/Delete Exports...\t",
|
||||||
|
Shortcut::None,
|
||||||
|
menu::MenuFlag::Normal,
|
||||||
|
move |_| {
|
||||||
|
win.deactivate();
|
||||||
|
if dialog::choice_default("Do you want to remove exports?", "Yes", "No") == 0 {
|
||||||
|
let props = rw_read!(properties);
|
||||||
|
if let Some(prop) = &props.image_info {
|
||||||
|
let export = prop.path.parent().unwrap().join("export");
|
||||||
|
if export.exists() {
|
||||||
|
fs::remove_dir_all(&export)
|
||||||
|
.warn_log("Failed to remove export directory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
win.activate();
|
||||||
|
win.redraw();
|
||||||
|
fltk::app::awake();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let mut config_window = ConfigWindow::new();
|
let mut config_window = ConfigWindow::new();
|
||||||
let sender = self.sender.clone();
|
let sender = self.sender.clone();
|
||||||
let mut image = self.page.image.clone();
|
let mut image = self.page.image.clone();
|
||||||
|
|
|
||||||
11
src/utils.rs
11
src/utils.rs
|
|
@ -756,13 +756,12 @@ pub(crate) fn get_export_image_path(image_info: &ImageInfo) -> PathBuf {
|
||||||
export_format.as_extension()
|
export_format.as_extension()
|
||||||
);
|
);
|
||||||
|
|
||||||
let export = image_info
|
let expost_dir = image_info.path.parent().unwrap().join("export");
|
||||||
.path
|
if !expost_dir.exists() {
|
||||||
.parent()
|
fs::create_dir(&expost_dir).expect_log("Failed to create export folder!");
|
||||||
.unwrap()
|
}
|
||||||
.join("export")
|
|
||||||
.join(&image_name);
|
|
||||||
|
|
||||||
|
let export = expost_dir.join(&image_name);
|
||||||
export
|
export
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue