From bc3433fcf2f0a452453365372d590e73173a731c Mon Sep 17 00:00:00 2001 From: David Capello Date: Sat, 15 Feb 2025 11:50:23 -0300 Subject: [PATCH] Add new ui::TranslationDelegate to translate Entry popup items Parts of this commit are from #4968 and will be useful to reuse in the multiline TextEdit widget. Co-authored-by: Christian Kaiser --- data/strings/en.ini | 8 +++++++- src/app/util/clipboard.cpp | 12 +++++++++++- src/app/util/clipboard.h | 1 + src/ui/clipboard_delegate.h | 2 ++ src/ui/entry.cpp | 35 +++++++++++++++++++++++++++-------- src/ui/system.cpp | 2 +- src/ui/system.h | 11 ++++++++--- src/ui/translation_delegate.h | 29 +++++++++++++++++++++++++++++ src/ui/ui.h | 3 ++- 9 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 src/ui/translation_delegate.h diff --git a/data/strings/en.ini b/data/strings/en.ini index 85c217b17..5a0ab6201 100644 --- a/data/strings/en.ini +++ b/data/strings/en.ini @@ -1,5 +1,5 @@ # Aseprite -# Copyright (C) 2018-2024 Igara Studio S.A. +# Copyright (C) 2018-2025 Igara Studio S.A. # Copyright (C) 2016-2018 David Capello # # This work is licensed under the Creative Commons Attribution 4.0 @@ -813,6 +813,12 @@ opacity = Opacity: tolerance = Tolerance: show_more = Show more... +[general_text] +copy = &Copy +cut = Cu&t +paste = &Paste +select_all = Select &All + [gif_options] title = GIF Options general_options = General Options: diff --git a/src/app/util/clipboard.cpp b/src/app/util/clipboard.cpp index 014a9c2ac..92026df1d 100644 --- a/src/app/util/clipboard.cpp +++ b/src/app/util/clipboard.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2019-2024 Igara Studio S.A. +// Copyright (C) 2019-2025 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This program is distributed under the terms of @@ -198,6 +198,16 @@ bool Clipboard::getClipboardText(std::string& text) } } +bool Clipboard::hasClipboardText() +{ + if (use_native_clipboard()) { + return clip::has(clip::text_format()); + } + else { + return !m_data->text.empty(); + } +} + void Clipboard::setData(Image* image, Mask* mask, Palette* palette, diff --git a/src/app/util/clipboard.h b/src/app/util/clipboard.h index e95b655f6..5b36b1b3a 100644 --- a/src/app/util/clipboard.h +++ b/src/app/util/clipboard.h @@ -89,6 +89,7 @@ public: // ui::ClipboardDelegate impl void setClipboardText(const std::string& text) override; bool getClipboardText(std::string& text) override; + bool hasClipboardText() override; bool setNativeBitmap(const doc::Image* image, const doc::Mask* mask, diff --git a/src/ui/clipboard_delegate.h b/src/ui/clipboard_delegate.h index 02b06545e..c769bcb6f 100644 --- a/src/ui/clipboard_delegate.h +++ b/src/ui/clipboard_delegate.h @@ -1,4 +1,5 @@ // Aseprite UI Library +// Copyright (C) 2025 Igara Studio S.A. // Copyright (C) 2018 David Capello // // This file is released under the terms of the MIT license. @@ -17,6 +18,7 @@ public: virtual ~ClipboardDelegate() {} virtual void setClipboardText(const std::string& text) = 0; virtual bool getClipboardText(std::string& text) = 0; + virtual bool hasClipboardText() = 0; }; } // namespace ui diff --git a/src/ui/entry.cpp b/src/ui/entry.cpp index c8fd920e1..0fd5a3259 100644 --- a/src/ui/entry.cpp +++ b/src/ui/entry.cpp @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2018-2024 Igara Studio S.A. +// Copyright (C) 2018-2025 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This file is released under the terms of the MIT license. @@ -15,6 +15,7 @@ #include "os/system.h" #include "text/draw_text.h" #include "text/font.h" +#include "ui/clipboard_delegate.h" #include "ui/display.h" #include "ui/menu.h" #include "ui/message.h" @@ -23,6 +24,7 @@ #include "ui/system.h" #include "ui/theme.h" #include "ui/timer.h" +#include "ui/translation_delegate.h" #include "ui/widget.h" #include @@ -872,20 +874,37 @@ bool Entry::isPosInSelection(int pos) void Entry::showEditPopupMenu(const gfx::Point& pt) { Menu menu; - MenuItem cut("Cut"); - MenuItem copy("Copy"); - MenuItem paste("Paste"); + + auto* clipboard = UISystem::instance()->clipboardDelegate(); + if (!clipboard) + return; + + auto* translate = UISystem::instance()->translationDelegate(); + ASSERT(translate); // We provide UISystem as default translation delegate + if (!translate) + return; + + MenuItem cut(translate->cut()); + MenuItem copy(translate->copy()); + MenuItem paste(translate->paste()); + MenuItem selectAll(translate->selectAll()); menu.addChild(&cut); menu.addChild(©); menu.addChild(&paste); + menu.addChild(new MenuSeparator); + menu.addChild(&selectAll); + + for (auto* item : menu.children()) + item->processMnemonicFromText(); + cut.Click.connect([this] { executeCmd(EntryCmd::Cut, 0, false); }); copy.Click.connect([this] { executeCmd(EntryCmd::Copy, 0, false); }); paste.Click.connect([this] { executeCmd(EntryCmd::Paste, 0, false); }); + selectAll.Click.connect([this] { executeCmd(EntryCmd::SelectAll, 0, false); }); - if (isReadOnly()) { - cut.setEnabled(false); - paste.setEnabled(false); - } + copy.setEnabled(m_select >= 0); + cut.setEnabled(m_select >= 0 && !isReadOnly()); + paste.setEnabled(clipboard->hasClipboardText() && !isReadOnly()); menu.showPopup(pt, display()); } diff --git a/src/ui/system.cpp b/src/ui/system.cpp index b8782d892..009f46064 100644 --- a/src/ui/system.cpp +++ b/src/ui/system.cpp @@ -153,7 +153,7 @@ UISystem* UISystem::instance() return g_instance; } -UISystem::UISystem() : m_clipboardDelegate(nullptr) +UISystem::UISystem() : m_clipboardDelegate(nullptr), m_translationDelegate(this) { ASSERT(!g_instance); g_instance = this; diff --git a/src/ui/system.h b/src/ui/system.h index 8175acef6..5ccb287a7 100644 --- a/src/ui/system.h +++ b/src/ui/system.h @@ -12,6 +12,7 @@ #include "gfx/fwd.h" #include "ui/base.h" #include "ui/cursor_type.h" +#include "ui/translation_delegate.h" #include #include @@ -23,18 +24,22 @@ class Cursor; class Display; class Widget; -class UISystem { +class UISystem : public TranslationDelegate { public: static UISystem* instance(); UISystem(); ~UISystem(); + ClipboardDelegate* clipboardDelegate() const { return m_clipboardDelegate; } + TranslationDelegate* translationDelegate() const { return m_translationDelegate; } + void setClipboardDelegate(ClipboardDelegate* delegate) { m_clipboardDelegate = delegate; } - ClipboardDelegate* clipboardDelegate() { return m_clipboardDelegate; } + void setTranslationDelegate(TranslationDelegate* delegate) { m_translationDelegate = delegate; } private: - ClipboardDelegate* m_clipboardDelegate; + ClipboardDelegate* m_clipboardDelegate = nullptr; + TranslationDelegate* m_translationDelegate = nullptr; }; void set_multiple_displays(bool multi); diff --git a/src/ui/translation_delegate.h b/src/ui/translation_delegate.h new file mode 100644 index 000000000..8fc783170 --- /dev/null +++ b/src/ui/translation_delegate.h @@ -0,0 +1,29 @@ +// Aseprite UI Library +// Copyright (C) 2025 Igara Studio S.A. +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef UI_TRANSLATION_DELEGATE_H_INCLUDED +#define UI_TRANSLATION_DELEGATE_H_INCLUDED +#pragma once + +#include + +namespace ui { + +// Translates strings displayed in the ui-lib widgets. +class TranslationDelegate { +public: + virtual ~TranslationDelegate() {} + + // ui::Entry popup + virtual std::string copy() { return "&Copy"; } + virtual std::string cut() { return "Cu&t"; } + virtual std::string paste() { return "&Paste"; } + virtual std::string selectAll() { return "Select &All"; } +}; + +} // namespace ui + +#endif diff --git a/src/ui/ui.h b/src/ui/ui.h index ecdd5f0b2..14b298459 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2019-2024 Igara Studio S.A. +// Copyright (C) 2019-2025 Igara Studio S.A. // Copyright (C) 2001-2018 David Capello // // This file is released under the terms of the MIT license. @@ -66,6 +66,7 @@ #include "ui/theme.h" #include "ui/timer.h" #include "ui/tooltips.h" +#include "ui/translation_delegate.h" #include "ui/view.h" #include "ui/viewport.h" #include "ui/widget.h"