mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-18 09:14:01 -04:00
feat(clipboard): add a copy-as-text action for entries with a text alternates
- New Entries captured from a mixed image+text offer keep the image as the primary mime i.e. bitmap - Copy Text context-menu item on atlernates Closes #2849
This commit is contained in:
@@ -205,6 +205,8 @@ func handleCopyEntry(conn *models.Conn, req models.Request, m *Manager) {
|
||||
return
|
||||
}
|
||||
|
||||
textOnly := params.BoolOpt(req.Params, "textOnly", false) && entry.AltMimeType != ""
|
||||
|
||||
if entry.AltMimeType == "" {
|
||||
filePath := m.EntryToFile(entry)
|
||||
if filePath != "" {
|
||||
@@ -220,8 +222,15 @@ func handleCopyEntry(conn *models.Conn, req models.Request, m *Manager) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := m.SetClipboardEntry(entry); err != nil {
|
||||
models.RespondError(conn, req.ID, err.Error())
|
||||
var setErr error
|
||||
switch {
|
||||
case textOnly:
|
||||
setErr = m.SetClipboard(entry.AltData, entry.AltMimeType)
|
||||
default:
|
||||
setErr = m.SetClipboardEntry(entry)
|
||||
}
|
||||
if setErr != nil {
|
||||
models.RespondError(conn, req.ID, setErr.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ Item {
|
||||
|
||||
readonly property bool hasPinnedDuplicate: !!entry && !entry.pinned && ClipboardService.getPinnedEntryByHash(entry.hash) !== null
|
||||
readonly property bool canEditEntry: !!entry && !(entry.isImage ?? false)
|
||||
readonly property bool hasTextAlternative: !!entry && (entry.altMimeType ?? "") !== ""
|
||||
readonly property string pinText: entry?.pinned || hasPinnedDuplicate ? I18n.tr("Unpin") : I18n.tr("Pin")
|
||||
readonly property string pinIcon: entry?.pinned || hasPinnedDuplicate ? "keep_off" : "push_pin"
|
||||
|
||||
@@ -48,6 +49,15 @@ Item {
|
||||
}
|
||||
];
|
||||
|
||||
if (hasTextAlternative) {
|
||||
items.splice(1, 0, {
|
||||
type: "item",
|
||||
icon: "text_fields",
|
||||
text: I18n.tr("Copy Text"),
|
||||
action: copyEntryAsText
|
||||
});
|
||||
}
|
||||
|
||||
if (canEditEntry) {
|
||||
items.push({
|
||||
type: "item",
|
||||
@@ -180,6 +190,13 @@ Item {
|
||||
hide();
|
||||
}
|
||||
|
||||
function copyEntryAsText() {
|
||||
if (!entry || !hasTextAlternative)
|
||||
return;
|
||||
modal?.copyEntryAsText(entry);
|
||||
hide();
|
||||
}
|
||||
|
||||
function togglePin() {
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
@@ -108,6 +108,10 @@ FocusScope {
|
||||
ClipboardService.copyEntry(entry, () => root.requestClose(false));
|
||||
}
|
||||
|
||||
function copyEntryAsText(entry) {
|
||||
ClipboardService.copyEntry(entry, () => root.requestClose(false), true);
|
||||
}
|
||||
|
||||
function selectedEntry() {
|
||||
const entries = activeTab === "saved" ? pinnedEntries : unpinnedEntries;
|
||||
if (!entries || entries.length === 0 || selectedIndex < 0 || selectedIndex >= entries.length)
|
||||
|
||||
@@ -202,15 +202,17 @@ Singleton {
|
||||
unpinnedEntries = [];
|
||||
}
|
||||
|
||||
function copyEntry(entry, closeCallback) {
|
||||
function copyEntry(entry, closeCallback, textOnly) {
|
||||
const asText = textOnly === true;
|
||||
DMSService.sendRequest("clipboard.copyEntry", {
|
||||
"id": entry.id
|
||||
"id": entry.id,
|
||||
"textOnly": asText
|
||||
}, function (response) {
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to copy entry"));
|
||||
return;
|
||||
}
|
||||
ToastService.showInfo(entry.isImage ? I18n.tr("Image copied to clipboard") : I18n.tr("Copied to clipboard"));
|
||||
ToastService.showInfo(entry.isImage && !asText ? I18n.tr("Image copied to clipboard") : I18n.tr("Copied to clipboard"));
|
||||
historyCopied();
|
||||
if (closeCallback) {
|
||||
closeCallback();
|
||||
|
||||
Reference in New Issue
Block a user