wip
This commit is contained in:
@@ -3073,6 +3073,8 @@ impl ContextEditor {
|
||||
let selection = editor.selections.newest::<usize>(cx);
|
||||
let mut copied_text = String::new();
|
||||
let mut spanned_messages = 0;
|
||||
let mut clipboard_entries: Vec<ClipboardEntry> = Vec::new();
|
||||
|
||||
for message in context.messages(cx) {
|
||||
if message.offset_range.start >= selection.range().end {
|
||||
break;
|
||||
@@ -3090,8 +3092,16 @@ impl ContextEditor {
|
||||
}
|
||||
}
|
||||
|
||||
for image_anchor in context.image_anchors(cx) {
|
||||
if let Some((render_image, _)) = context.get_image(image_anchor.image_id) {
|
||||
//
|
||||
} else {
|
||||
log::error!("Assistant panel context had an image id of {:?} but there was no associated images entry stored for that id. This should never happen!", image_anchor.image_id);
|
||||
}
|
||||
}
|
||||
|
||||
if spanned_messages > 1 {
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(copied_text));
|
||||
cx.write_to_clipboard(ClipboardItem::new(clipboard_entries));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3155,11 +3165,13 @@ impl ContextEditor {
|
||||
let new_blocks = self
|
||||
.context
|
||||
.read(cx)
|
||||
.images(cx)
|
||||
.filter_map(|image| {
|
||||
.image_anchors(cx)
|
||||
.filter_map(|image_anchor| {
|
||||
const MAX_HEIGHT_IN_LINES: u32 = 8;
|
||||
let anchor = buffer.anchor_in_excerpt(excerpt_id, image.anchor).unwrap();
|
||||
let image = image.render_image.clone();
|
||||
let anchor = buffer
|
||||
.anchor_in_excerpt(excerpt_id, image_anchor.anchor)
|
||||
.unwrap();
|
||||
let image = image_anchor.render_image.clone();
|
||||
anchor.is_valid(&buffer).then(|| BlockProperties {
|
||||
position: anchor,
|
||||
height: MAX_HEIGHT_IN_LINES,
|
||||
|
||||
@@ -1906,10 +1906,20 @@ impl Context {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn images<'a>(&'a self, _cx: &'a AppContext) -> impl 'a + Iterator<Item = ImageAnchor> {
|
||||
pub fn image_anchors<'a>(
|
||||
&'a self,
|
||||
_cx: &'a AppContext,
|
||||
) -> impl 'a + Iterator<Item = ImageAnchor> {
|
||||
self.image_anchors.iter().cloned()
|
||||
}
|
||||
|
||||
pub fn get_image(
|
||||
&self,
|
||||
image_id: u64,
|
||||
) -> Option<&(Arc<RenderImage>, Shared<Task<Option<LanguageModelImage>>>)> {
|
||||
self.images.get(&image_id)
|
||||
}
|
||||
|
||||
pub fn split_message(
|
||||
&mut self,
|
||||
range: Range<usize>,
|
||||
|
||||
@@ -26,7 +26,7 @@ use crate::{
|
||||
RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, Scene, SharedString, Size,
|
||||
SvgSize, Task, TaskLabel, WindowContext, DEFAULT_WINDOW_SIZE,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_task::Runnable;
|
||||
use futures::channel::oneshot;
|
||||
use image::codecs::gif::GifDecoder;
|
||||
@@ -987,6 +987,11 @@ pub enum ClipboardEntry {
|
||||
}
|
||||
|
||||
impl ClipboardItem {
|
||||
/// Create a new ClipboardItem with the given entries
|
||||
pub fn new(entries: Vec<ClipboardEntry>) -> Self {
|
||||
Self { entries }
|
||||
}
|
||||
|
||||
/// Create a new ClipboardItem::String with no associated metadata
|
||||
pub fn new_string(text: String) -> Self {
|
||||
Self {
|
||||
@@ -1083,6 +1088,39 @@ impl Image {
|
||||
ImageSource::Image(self).use_data(cx)
|
||||
}
|
||||
|
||||
/// Convert an `ImageData` object to a clipboard image in PNG format.
|
||||
pub fn from_image_data(render_image: &RenderImage) -> Result<Self> {
|
||||
// hardcode frame index 0; we don't currently support copying animated GIFs
|
||||
if let Some(input_bytes) = render_image.as_bytes(0) {
|
||||
let rgba_bytes = {
|
||||
let mut buf = input_bytes.to_vec();
|
||||
|
||||
// Convert from BGRA to RGBA.
|
||||
for pixel in buf.chunks_exact_mut(4) {
|
||||
pixel.swap(0, 2);
|
||||
}
|
||||
|
||||
buf
|
||||
};
|
||||
|
||||
let mut output_bytes = Vec::with_capacity(rgba_bytes.len());
|
||||
let image_buffer = RgbaIma
|
||||
let cursor = Cursor::new(output_bytes);
|
||||
image::DynamicImage::ImageRgba8(rgba_bytes)
|
||||
.write_to(&mut cursor, image::ImageOutputFormat::Png)?;
|
||||
|
||||
Ok(Self {
|
||||
format: ImageFormat::Png,
|
||||
bytes: cursor.into_inner(),
|
||||
id: rand::random(),
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"RenderImage did not have a frame 0, which should never happen."
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the clipboard image to an `ImageData` object.
|
||||
pub fn to_image_data(&self, cx: &AppContext) -> Result<Arc<RenderImage>> {
|
||||
fn frames_for_image(
|
||||
|
||||
@@ -921,6 +921,74 @@ impl Platform for MacPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
// write some images and text to the clip
|
||||
// let image1 = ns_image(&bytes).unwrap();
|
||||
// let image2 = ns_image(&bytes).unwrap();
|
||||
let image1 = NSImage::initWithPasteboard_(nil, pasteboard);
|
||||
let image2 = NSImage::initWithPasteboard_(nil, pasteboard);
|
||||
// let attributed_string = text_and_images([image1, image2]);
|
||||
// text_and_images([NSImage::initWithPasteboard_(, pasteboard), ns_image(&bytes).unwrap()]);
|
||||
let attributed_string = {
|
||||
use cocoa::appkit::NSImage;
|
||||
|
||||
let image: id = msg_send![class!(NSImage), alloc];
|
||||
NSImage::initWithContentsOfFile_(
|
||||
image,
|
||||
NSString::alloc(nil).init_str("/Users/rtfeldman/Downloads/test.jpeg"),
|
||||
);
|
||||
let size = image.size();
|
||||
|
||||
let string = NSString::alloc(nil).init_str("Test String");
|
||||
let attr_string =
|
||||
NSMutableAttributedString::alloc(nil).init_attributed_string(string);
|
||||
let hello_string = NSString::alloc(nil).init_str("Hello World");
|
||||
let hello_attr_string =
|
||||
NSAttributedString::alloc(nil).init_attributed_string(hello_string);
|
||||
attr_string.appendAttributedString_(hello_attr_string);
|
||||
|
||||
let attachment = NSTextAttachment::alloc(nil);
|
||||
let _: () = msg_send![attachment, setImage: image];
|
||||
let image_attr_string = msg_send![class!(NSAttributedString), attributedStringWithAttachment: attachment];
|
||||
attr_string.appendAttributedString_(image_attr_string);
|
||||
|
||||
let another_string = NSString::alloc(nil).init_str("Another String");
|
||||
let another_attr_string =
|
||||
NSAttributedString::alloc(nil).init_attributed_string(another_string);
|
||||
attr_string.appendAttributedString_(another_attr_string);
|
||||
|
||||
attr_string
|
||||
};
|
||||
|
||||
pasteboard.clearContents();
|
||||
|
||||
let rtfd_data = attributed_string.RTFDFromRange_documentAttributes_(
|
||||
NSRange::new(0, msg_send![attributed_string, length]),
|
||||
nil,
|
||||
);
|
||||
if rtfd_data != nil {
|
||||
pasteboard.setData_forType(rtfd_data, NSPasteboardTypeRTFD);
|
||||
}
|
||||
|
||||
// let rtf_data = attributed_string.RTFFromRange_documentAttributes_(
|
||||
// NSRange::new(0, attributed_string.length()),
|
||||
// nil,
|
||||
// );
|
||||
// if rtf_data != nil {
|
||||
// pasteboard.setData_forType(rtf_data, NSPasteboardTypeRTF);
|
||||
// }
|
||||
|
||||
// let plain_text = attributed_string.string();
|
||||
// pasteboard.setString_forType(plain_text, NSPasteboardTypeString);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
buf.appendAttributedString_(to_append);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user