Parse pastes
This commit is contained in:
parent
3ab5597fc3
commit
a2560db6ba
2 changed files with 84 additions and 10 deletions
|
|
@ -1,23 +1,29 @@
|
|||
// Copyright 2024 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use cosmic::iced::clipboard::mime::AsMimeTypes;
|
||||
use std::{borrow::Cow, path::Path};
|
||||
use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
error::Error,
|
||||
path::{Path, PathBuf},
|
||||
str,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum ClipboardKind {
|
||||
Copy,
|
||||
Cut,
|
||||
}
|
||||
|
||||
pub struct ClipboardContents {
|
||||
pub struct ClipboardCopy {
|
||||
pub available: Cow<'static, [String]>,
|
||||
pub text_plain: Cow<'static, [u8]>,
|
||||
pub text_uri_list: Cow<'static, [u8]>,
|
||||
pub x_special_gnome_copied_files: Cow<'static, [u8]>,
|
||||
}
|
||||
|
||||
impl ClipboardContents {
|
||||
impl ClipboardCopy {
|
||||
pub fn new<P: AsRef<Path>>(kind: ClipboardKind, paths: &[P]) -> Self {
|
||||
let available = vec![
|
||||
"text/plain".to_string(),
|
||||
|
|
@ -80,7 +86,7 @@ impl ClipboardContents {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsMimeTypes for ClipboardContents {
|
||||
impl AsMimeTypes for ClipboardCopy {
|
||||
fn available(&self) -> Cow<'static, [String]> {
|
||||
self.available.clone()
|
||||
}
|
||||
|
|
@ -94,3 +100,60 @@ impl AsMimeTypes for ClipboardContents {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ClipboardPaste {
|
||||
pub kind: ClipboardKind,
|
||||
pub paths: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl AllowedMimeTypes for ClipboardPaste {
|
||||
fn allowed() -> Cow<'static, [String]> {
|
||||
Cow::from(vec![
|
||||
"x-special/gnome-copied-files".to_string(),
|
||||
"text/uri-list".to_string(),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(Vec<u8>, String)> for ClipboardPaste {
|
||||
type Error = Box<dyn Error>;
|
||||
fn try_from(value: (Vec<u8>, String)) -> Result<Self, Self::Error> {
|
||||
let (data, mime) = value;
|
||||
// Assume the kind is Copy if not provided by the mime type
|
||||
let mut kind = ClipboardKind::Copy;
|
||||
let mut paths = Vec::new();
|
||||
match mime.as_str() {
|
||||
"text/uri-list" => {
|
||||
let text = str::from_utf8(&data)?;
|
||||
for line in text.lines() {
|
||||
let url = Url::parse(line)?;
|
||||
match url.to_file_path() {
|
||||
Ok(path) => paths.push(path),
|
||||
Err(()) => Err(format!("invalid file URL {:?}", url))?,
|
||||
}
|
||||
}
|
||||
}
|
||||
"x-special/gnome-copied-files" => {
|
||||
let text = str::from_utf8(&data)?;
|
||||
for (i, line) in text.lines().enumerate() {
|
||||
if i == 0 {
|
||||
kind = match line {
|
||||
"copy" => ClipboardKind::Copy,
|
||||
"cut" => ClipboardKind::Cut,
|
||||
_ => Err(format!("unsupported clipboard operation {:?}", line))?,
|
||||
};
|
||||
} else {
|
||||
let url = Url::parse(line)?;
|
||||
match url.to_file_path() {
|
||||
Ok(path) => paths.push(path),
|
||||
Err(()) => Err(format!("invalid file URL {:?}", url))?,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => Err(format!("unsupported mime type {:?}", mime))?,
|
||||
}
|
||||
Ok(Self { kind, paths })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue