mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-10 18:31:10 -06:00
refactor(ui): simplify image and page context menus
Share click handling, set crop mode in the image menu, remove duplicate export and inactive editor entries, and format shortcuts for the platform. Add a selection constructor for callers. Co-Authored-By: Codex GPT-6.1 <noreply@openai.com>
This commit is contained in:
co-authored by
Codex GPT-6.1
parent
3c394bb860
commit
91f94ec26a
+50
-111
@@ -182,21 +182,7 @@ impl ImageObb {
|
||||
let v_axis = (c / h_v, d / h_v);
|
||||
let is_rotated = b.abs() > 1e-4 || c.abs() > 1e-4;
|
||||
|
||||
Self {
|
||||
s00,
|
||||
s10,
|
||||
s11,
|
||||
s01,
|
||||
s_bc,
|
||||
s_rc,
|
||||
s_tc,
|
||||
s_lc,
|
||||
s_rot,
|
||||
screen_center,
|
||||
u_axis,
|
||||
v_axis,
|
||||
is_rotated,
|
||||
}
|
||||
Self { s00, s10, s11, s01, s_bc, s_rc, s_tc, s_lc, s_rot, screen_center, u_axis, v_axis, is_rotated }
|
||||
}
|
||||
|
||||
pub fn from_image(im: &pdfcraft_engine::PageImage, xf: &PageXform, info: &DocInfo, page: usize) -> Self {
|
||||
@@ -731,8 +717,8 @@ pub enum ViewAction {
|
||||
/// Default page right-click menu actions.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub(crate) enum PageMenuAction {
|
||||
RotateCCW(usize),
|
||||
RotateCW(usize),
|
||||
RotateCCW,
|
||||
RotateCW,
|
||||
Print,
|
||||
SelectTool,
|
||||
HandTool,
|
||||
@@ -740,7 +726,7 @@ pub(crate) enum PageMenuAction {
|
||||
Copy,
|
||||
Paste(usize, [f64; 2]),
|
||||
AddComment(usize, [f64; 2]),
|
||||
AddBookmark(usize),
|
||||
AddBookmark,
|
||||
TakeSnapshot,
|
||||
EditPdf,
|
||||
AddText,
|
||||
@@ -763,100 +749,66 @@ pub(crate) struct PageMenuPerms {
|
||||
}
|
||||
|
||||
pub(crate) fn default_page_context_menu(ui: &mut egui::Ui, page: usize, at: [f64; 2], perms: PageMenuPerms, action: &mut Option<PageMenuAction>) {
|
||||
use PageMenuAction as A;
|
||||
// Takes `choice` when `entry` was clicked, and closes the menu.
|
||||
let mut pick = |entry: egui::Response, ui: &mut egui::Ui, choice: PageMenuAction| {
|
||||
if entry.clicked() {
|
||||
*action = Some(choice);
|
||||
ui.close();
|
||||
}
|
||||
};
|
||||
let icon = |ui: &mut egui::Ui, name: &str, tip: &str| crate::icons::button(ui, name, 24.0, false, tip);
|
||||
// Top horizontal icon bar: Rotate CCW, Print, Select tool, Hand tool, Marquee Zoom
|
||||
ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 4.0;
|
||||
if crate::icons::button(ui, "rotate-ccw", 24.0, false, tl!("Rotate view counterclockwise")).clicked() {
|
||||
*action = Some(PageMenuAction::RotateCCW(page));
|
||||
ui.close();
|
||||
}
|
||||
ui.add_enabled_ui(perms.can_print, |ui| {
|
||||
if crate::icons::button(ui, "printer", 24.0, false, tl!("Print")).clicked() {
|
||||
*action = Some(PageMenuAction::Print);
|
||||
ui.close();
|
||||
}
|
||||
});
|
||||
if crate::icons::button(ui, "mouse-pointer-2", 24.0, false, tl!("Select Tool")).clicked() {
|
||||
*action = Some(PageMenuAction::SelectTool);
|
||||
ui.close();
|
||||
}
|
||||
if crate::icons::button(ui, "hand", 24.0, false, tl!("Hand Tool")).clicked() {
|
||||
*action = Some(PageMenuAction::HandTool);
|
||||
ui.close();
|
||||
}
|
||||
if crate::icons::button(ui, "zoom-in", 24.0, false, tl!("Marquee Zoom")).clicked() {
|
||||
*action = Some(PageMenuAction::MarqueeZoom);
|
||||
ui.close();
|
||||
}
|
||||
pick(icon(ui, "rotate-ccw", tl!("Rotate view counterclockwise")), ui, A::RotateCCW);
|
||||
ui.add_enabled_ui(perms.can_print, |ui| pick(icon(ui, "printer", tl!("Print")), ui, A::Print));
|
||||
pick(icon(ui, "mouse-pointer-2", tl!("Select Tool")), ui, A::SelectTool);
|
||||
pick(icon(ui, "hand", tl!("Hand Tool")), ui, A::HandTool);
|
||||
pick(icon(ui, "zoom-in", tl!("Marquee Zoom")), ui, A::MarqueeZoom);
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.add_enabled(perms.can_copy, egui::Button::new(tl!("Copy")).shortcut_text("Ctrl+C")).clicked() {
|
||||
*action = Some(PageMenuAction::Copy);
|
||||
ui.close();
|
||||
}
|
||||
if ui.add_enabled(perms.can_paste, egui::Button::new(tl!("Paste")).shortcut_text("Ctrl+V")).clicked() {
|
||||
*action = Some(PageMenuAction::Paste(page, at));
|
||||
ui.close();
|
||||
}
|
||||
pick(
|
||||
ui.add_enabled(
|
||||
perms.can_copy,
|
||||
egui::Button::new(tl!("Copy")).shortcut_text(crate::commands::shortcut_label(ui.ctx(), crate::commands::COPY)),
|
||||
),
|
||||
ui,
|
||||
A::Copy,
|
||||
);
|
||||
pick(
|
||||
ui.add_enabled(
|
||||
perms.can_paste,
|
||||
egui::Button::new(tl!("Paste")).shortcut_text(crate::commands::shortcut_label(ui.ctx(), pdfcraft_engine::commands::Shortcut::cmd("V"))),
|
||||
),
|
||||
ui,
|
||||
A::Paste(page, at),
|
||||
);
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.add_enabled(perms.can_annotate, egui::Button::new(tl!("Add comment"))).clicked() {
|
||||
*action = Some(PageMenuAction::AddComment(page, at));
|
||||
ui.close();
|
||||
}
|
||||
if perms.has_annotations && ui.add_enabled(perms.can_modify, egui::Button::new(tl!("Flatten comments"))).clicked() {
|
||||
*action = Some(PageMenuAction::FlattenComments);
|
||||
ui.close();
|
||||
}
|
||||
if ui.add_enabled(perms.can_assemble, egui::Button::new(tl!("Add bookmark"))).clicked() {
|
||||
*action = Some(PageMenuAction::AddBookmark(page));
|
||||
ui.close();
|
||||
}
|
||||
if ui.add_enabled(perms.can_copy, egui::Button::new(tl!("Take a snapshot"))).clicked() {
|
||||
*action = Some(PageMenuAction::TakeSnapshot);
|
||||
ui.close();
|
||||
pick(ui.add_enabled(perms.can_annotate, egui::Button::new(tl!("Add comment"))), ui, A::AddComment(page, at));
|
||||
if perms.has_annotations {
|
||||
pick(ui.add_enabled(perms.can_modify, egui::Button::new(tl!("Flatten comments"))), ui, A::FlattenComments);
|
||||
}
|
||||
pick(ui.add_enabled(perms.can_assemble, egui::Button::new(tl!("Add bookmark"))), ui, A::AddBookmark);
|
||||
pick(ui.add_enabled(perms.can_copy, egui::Button::new(tl!("Take a snapshot"))), ui, A::TakeSnapshot);
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.add_enabled(perms.can_modify, egui::Button::new(egui::RichText::new(tl!("Edit this PDF")).strong())).clicked() {
|
||||
*action = Some(PageMenuAction::EditPdf);
|
||||
ui.close();
|
||||
}
|
||||
if ui.add_enabled(perms.can_modify, egui::Button::new(tl!("Add text"))).clicked() {
|
||||
*action = Some(PageMenuAction::AddText);
|
||||
ui.close();
|
||||
}
|
||||
if ui.add_enabled(perms.can_modify, egui::Button::new(tl!("Add image"))).clicked() {
|
||||
*action = Some(PageMenuAction::AddImage);
|
||||
ui.close();
|
||||
}
|
||||
if ui.add_enabled(perms.can_assemble, egui::Button::new(tl!("Delete page"))).clicked() {
|
||||
*action = Some(PageMenuAction::DeletePage(page));
|
||||
ui.close();
|
||||
}
|
||||
if ui.add_enabled(perms.can_copy, egui::Button::new(tl!("Export this PDF"))).clicked() {
|
||||
*action = Some(PageMenuAction::ExportPdf);
|
||||
ui.close();
|
||||
}
|
||||
pick(ui.add_enabled(perms.can_modify, egui::Button::new(egui::RichText::new(tl!("Edit this PDF")).strong())), ui, A::EditPdf);
|
||||
pick(ui.add_enabled(perms.can_modify, egui::Button::new(tl!("Add text"))), ui, A::AddText);
|
||||
pick(ui.add_enabled(perms.can_modify, egui::Button::new(tl!("Add image"))), ui, A::AddImage);
|
||||
pick(ui.add_enabled(perms.can_assemble, egui::Button::new(tl!("Delete page"))), ui, A::DeletePage(page));
|
||||
pick(ui.add_enabled(perms.can_copy, egui::Button::new(tl!("Export this PDF"))), ui, A::ExportPdf);
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.button(tl!("Find text or tools")).clicked() {
|
||||
*action = Some(PageMenuAction::Find);
|
||||
ui.close();
|
||||
}
|
||||
if ui.button(tl!("Rotate view clockwise")).clicked() {
|
||||
*action = Some(PageMenuAction::RotateCW(page));
|
||||
ui.close();
|
||||
}
|
||||
if ui.button(tl!("Document properties…")).clicked() {
|
||||
*action = Some(PageMenuAction::DocProperties);
|
||||
ui.close();
|
||||
}
|
||||
pick(ui.button(tl!("Find text or tools")), ui, A::Find);
|
||||
pick(ui.button(tl!("Rotate view clockwise")), ui, A::RotateCW);
|
||||
pick(ui.button(tl!("Document properties…")), ui, A::DocProperties);
|
||||
}
|
||||
|
||||
impl DocView {
|
||||
@@ -3951,17 +3903,6 @@ fn apply_frame_requests(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui,
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(crate::edit_text_ui::ImageAction::Crop) => {
|
||||
let doc_id = app.views[index].id;
|
||||
if let Some(s) = app.views[index].image_selection.as_mut()
|
||||
&& let Some(d) = app.session.get(doc_id)
|
||||
{
|
||||
let images = d.page_images(s.page);
|
||||
if let Some(im) = images.get(s.index) {
|
||||
s.crop = Some(crate::edit_text_ui::CropMode::new(im.visible_rect.unwrap_or(im.rect)));
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
match page_action {
|
||||
@@ -3980,12 +3921,10 @@ fn apply_frame_requests(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui,
|
||||
Some(PageMenuAction::Paste(page, at)) => {
|
||||
app.paste_image_at(page, at);
|
||||
}
|
||||
Some(PageMenuAction::RotateCCW(page)) => {
|
||||
let _ = page;
|
||||
Some(PageMenuAction::RotateCCW) => {
|
||||
app.views[index].rotate_view(false);
|
||||
}
|
||||
Some(PageMenuAction::RotateCW(page)) => {
|
||||
let _ = page;
|
||||
Some(PageMenuAction::RotateCW) => {
|
||||
app.views[index].rotate_view(true);
|
||||
}
|
||||
Some(PageMenuAction::Print) => {
|
||||
@@ -4008,7 +3947,7 @@ fn apply_frame_requests(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui,
|
||||
app.views[index].comments.selected = None;
|
||||
app.views[index].pending_edit = Some(pdfcraft_engine::Edit::Flatten { comments: true, fields: false });
|
||||
}
|
||||
Some(PageMenuAction::AddBookmark(_page)) => {
|
||||
Some(PageMenuAction::AddBookmark) => {
|
||||
app.bookmark_action(crate::panels::BmAction::New);
|
||||
}
|
||||
Some(PageMenuAction::TakeSnapshot) => {
|
||||
|
||||
@@ -92,6 +92,11 @@ pub struct ImageSelection {
|
||||
}
|
||||
|
||||
impl ImageSelection {
|
||||
/// Select a page image without an active gesture.
|
||||
pub fn at(page: usize, index: usize) -> Self {
|
||||
Self { page, index, drag: None, crop: None, crop_mode: false, crop_rect: None, turning: false, settled: None }
|
||||
}
|
||||
|
||||
/// Cancel an in-progress text, rotation or crop drag and restore the crop it was previewing.
|
||||
pub(crate) fn cancel_pointer_gesture(&mut self) {
|
||||
self.drag = None;
|
||||
@@ -489,7 +494,6 @@ pub enum ImageAction {
|
||||
Paste(usize, Option<[f64; 2]>),
|
||||
DrawFreehand,
|
||||
AddComment(usize, usize),
|
||||
Crop,
|
||||
}
|
||||
|
||||
/// Where the rotate knob sits, and the edge point its stem starts from: above the middle of the
|
||||
@@ -1051,8 +1055,7 @@ pub(crate) fn image_input(cx: &ImageCx<'_>, images: &[pdfcraft_engine::PageImage
|
||||
_ => (resp.clicked() || resp.secondary_clicked()).then_some(hit),
|
||||
};
|
||||
if let Some(index) = clicked {
|
||||
view.image_selection =
|
||||
Some(ImageSelection { page, index, drag: None, crop: None, crop_mode: false, crop_rect: None, turning: false, settled: None });
|
||||
view.image_selection = Some(ImageSelection::at(page, index));
|
||||
}
|
||||
if resp.secondary_clicked() {
|
||||
ui.ctx().data_mut(|d| d.insert_persisted(menu_key, true));
|
||||
@@ -1076,133 +1079,114 @@ pub(crate) fn image_context_menu(
|
||||
use pdfcraft_engine::ImageEdit as E;
|
||||
let raster = !img.is_form;
|
||||
|
||||
let close = |ui: &mut egui::Ui| {
|
||||
ui.ctx().data_mut(|d| d.insert_persisted(image_menu_id(), false));
|
||||
egui::Popup::close_all(ui.ctx());
|
||||
ui.close();
|
||||
// Whether `entry` was clicked; a click closes the menu.
|
||||
let picked = |ui: &mut egui::Ui, entry: egui::Response| {
|
||||
let clicked = entry.clicked();
|
||||
if clicked {
|
||||
ui.ctx().data_mut(|d| d.insert_persisted(image_menu_id(), false));
|
||||
egui::Popup::close_all(ui.ctx());
|
||||
ui.close();
|
||||
}
|
||||
clicked
|
||||
};
|
||||
let item = |ui: &mut egui::Ui, enabled: bool, label: &str| {
|
||||
let entry = ui.add_enabled(enabled, egui::Button::new(label));
|
||||
picked(ui, entry)
|
||||
};
|
||||
let edit = |change| Some(Edit::EditPageImage { page, index: hit, change });
|
||||
|
||||
// Top horizontal icon bar: Comment, Crop, Rotate CCW, Rotate CW
|
||||
ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 4.0;
|
||||
if crate::icons::button(ui, "message-square", 24.0, false, tl!("Add a sticky note here")).clicked() {
|
||||
let icon = |ui: &mut egui::Ui, name: &str, tip: &str| {
|
||||
let entry = crate::icons::button(ui, name, 24.0, false, tip);
|
||||
picked(ui, entry)
|
||||
};
|
||||
if icon(ui, "message-square", tl!("Add a sticky note here")) {
|
||||
*action = Some(ImageAction::AddComment(page, hit));
|
||||
close(ui);
|
||||
}
|
||||
if raster && crate::icons::button(ui, "crop", 24.0, false, tl!("Crop")).clicked() {
|
||||
*action = Some(ImageAction::Crop);
|
||||
if let Some(s) = view.image_selection.as_mut() {
|
||||
let rect = img.visible_rect.unwrap_or(img.rect);
|
||||
s.crop = Some(CropMode::new(rect));
|
||||
}
|
||||
close(ui);
|
||||
if raster
|
||||
&& icon(ui, "crop", tl!("Crop"))
|
||||
&& let Some(s) = view.image_selection.as_mut()
|
||||
{
|
||||
s.crop = Some(CropMode::new(img.visible_rect.unwrap_or(img.rect)));
|
||||
}
|
||||
if crate::icons::button(ui, "rotate-ccw", 24.0, false, tl!("Rotate Counterclockwise")).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Rotate(3) });
|
||||
close(ui);
|
||||
if icon(ui, "rotate-ccw", tl!("Rotate Counterclockwise")) {
|
||||
view.pending_edit = edit(E::Rotate(3));
|
||||
}
|
||||
if crate::icons::button(ui, "rotate-cw", 24.0, false, tl!("Rotate Clockwise")).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Rotate(1) });
|
||||
close(ui);
|
||||
if icon(ui, "rotate-cw", tl!("Rotate Clockwise")) {
|
||||
view.pending_edit = edit(E::Rotate(1));
|
||||
}
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.button(tl!("Cut Image")).clicked() {
|
||||
if item(ui, true, tl!("Cut Image")) {
|
||||
*action = Some(ImageAction::Cut(page, hit));
|
||||
close(ui);
|
||||
}
|
||||
if ui.button(tl!("Copy Image")).clicked() {
|
||||
if item(ui, true, tl!("Copy Image")) {
|
||||
*action = Some(ImageAction::Copy(page, hit));
|
||||
close(ui);
|
||||
}
|
||||
if ui.add_enabled(can_paste, egui::Button::new(tl!("Paste"))).clicked() {
|
||||
if item(ui, can_paste, tl!("Paste")) {
|
||||
*action = Some(ImageAction::Paste(page, at));
|
||||
close(ui);
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
let is_cropped = img.visible_rect.is_some() && img.visible_rect != Some(img.rect);
|
||||
if raster && ui.add_enabled(is_cropped, egui::Button::new(tl!("Remove crop"))).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::RemoveCrop });
|
||||
close(ui);
|
||||
if raster && item(ui, is_cropped, tl!("Remove crop")) {
|
||||
view.pending_edit = edit(E::RemoveCrop);
|
||||
}
|
||||
|
||||
if ui.button(tl!("Flip horizontal")).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Flip { horizontal: true } });
|
||||
close(ui);
|
||||
if item(ui, true, tl!("Flip horizontal")) {
|
||||
view.pending_edit = edit(E::Flip { horizontal: true });
|
||||
}
|
||||
if ui.button(tl!("Flip vertical")).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Flip { horizontal: false } });
|
||||
close(ui);
|
||||
if item(ui, true, tl!("Flip vertical")) {
|
||||
view.pending_edit = edit(E::Flip { horizontal: false });
|
||||
}
|
||||
|
||||
ui.menu_button(tl!("Arrange image"), |ui| {
|
||||
if ui.button(tl!("Bring to front")).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Arrange(pdfcraft_engine::ArrangeOrder::BringToFront) });
|
||||
close(ui);
|
||||
}
|
||||
if ui.button(tl!("Send to back")).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Arrange(pdfcraft_engine::ArrangeOrder::SendToBack) });
|
||||
close(ui);
|
||||
}
|
||||
if ui.button(tl!("Bring forward")).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Arrange(pdfcraft_engine::ArrangeOrder::BringForward) });
|
||||
close(ui);
|
||||
}
|
||||
if ui.button(tl!("Send backward")).clicked() {
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Arrange(pdfcraft_engine::ArrangeOrder::SendBackward) });
|
||||
close(ui);
|
||||
use pdfcraft_engine::ArrangeOrder as A;
|
||||
for (order, label) in [
|
||||
(A::BringToFront, tl!("Bring to front")),
|
||||
(A::SendToBack, tl!("Send to back")),
|
||||
(A::BringForward, tl!("Bring forward")),
|
||||
(A::SendBackward, tl!("Send backward")),
|
||||
] {
|
||||
if item(ui, true, label) {
|
||||
view.pending_edit = edit(E::Arrange(order));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if ui.add_enabled(raster, egui::Button::new(tl!("Replace image"))).clicked() {
|
||||
if item(ui, raster, tl!("Replace image")) {
|
||||
*action = Some(ImageAction::Replace(page, hit));
|
||||
close(ui);
|
||||
}
|
||||
if ui.add_enabled(raster, egui::Button::new(tl!("Save Image As…"))).clicked() {
|
||||
if item(ui, raster, tl!("Save Image As…")) {
|
||||
*action = Some(ImageAction::Save(page, hit));
|
||||
close(ui);
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.button(tl!("Draw freehand")).clicked() {
|
||||
if item(ui, true, tl!("Draw freehand")) {
|
||||
*action = Some(ImageAction::DrawFreehand);
|
||||
close(ui);
|
||||
}
|
||||
if ui.button(tl!("Redact Image")).clicked() {
|
||||
if item(ui, true, tl!("Redact Image")) {
|
||||
*action = Some(ImageAction::Redact(page, hit));
|
||||
close(ui);
|
||||
}
|
||||
if ui.add_enabled(raster, egui::Button::new(tl!("Export image"))).clicked() {
|
||||
*action = Some(ImageAction::Save(page, hit));
|
||||
close(ui);
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.button(tl!("Create Link…")).clicked() {
|
||||
if item(ui, true, tl!("Create Link…")) {
|
||||
*action = Some(ImageAction::Link(page, hit));
|
||||
close(ui);
|
||||
}
|
||||
|
||||
ui.menu_button(tl!("Edit image using"), |ui| {
|
||||
ui.add_enabled(false, egui::Button::new(tl!("Default image editor")));
|
||||
});
|
||||
|
||||
if ui.button(tl!("Recognize Text…")).clicked() {
|
||||
if item(ui, true, tl!("Recognize Text…")) {
|
||||
*action = Some(ImageAction::Recognize(page));
|
||||
close(ui);
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.button(tl!("Delete")).clicked() {
|
||||
if item(ui, true, tl!("Delete")) {
|
||||
view.image_selection = None;
|
||||
view.pending_edit = Some(Edit::EditPageImage { page, index: hit, change: E::Delete });
|
||||
close(ui);
|
||||
view.pending_edit = edit(E::Delete);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4616,9 +4616,7 @@ fn image_right_click_context_menu_items_and_actions() {
|
||||
"Replace image",
|
||||
"Draw freehand",
|
||||
"Redact Image",
|
||||
"Export image",
|
||||
"Create Link",
|
||||
"Edit image using",
|
||||
"Recognize Text",
|
||||
] {
|
||||
h.get_by_label_contains(item);
|
||||
|
||||
Reference in New Issue
Block a user