basic file cut and paste

This commit is contained in:
nakst 2021-09-01 17:48:52 +01:00
parent fdc4da053b
commit 6c106d1a1f
12 changed files with 153 additions and 55 deletions

View File

@ -62,7 +62,7 @@ void CommandRename(Instance *instance, EsElement *, EsCommand *) {
size_t oldPathBytes; size_t oldPathBytes;
char *oldPath = EsStringAllocateAndFormat(&oldPathBytes, "%s%s", STRFMT(instance->folder->path), STRFMT(task->string2)); char *oldPath = EsStringAllocateAndFormat(&oldPathBytes, "%s%s", STRFMT(instance->folder->path), STRFMT(task->string2));
FolderPathMoved(instance, { .text = oldPath, .bytes = oldPathBytes }, { .text = newPath, .bytes = newPathBytes }); FolderPathMoved(instance, { .text = oldPath, .bytes = oldPathBytes }, { .text = newPath, .bytes = newPathBytes }, true);
EsDirectoryChild information = {}; EsDirectoryChild information = {};
EsPathQueryInformation(newPath, newPathBytes, &information); EsPathQueryInformation(newPath, newPathBytes, &information);
@ -119,7 +119,7 @@ void CommandNewFolder(Instance *instance, EsElement *, EsCommand *) {
}); });
} }
void CommandCopy(Instance *instance, EsElement *, EsCommand *) { void CommandCopyOrCut(Instance *instance, uint32_t flags) {
// TODO If copying a single file, copy the data of the file (as well as its path), // TODO If copying a single file, copy the data of the file (as well as its path),
// so that document can be pasted into other applications. // so that document can be pasted into other applications.
@ -141,10 +141,14 @@ void CommandCopy(Instance *instance, EsElement *, EsCommand *) {
EsBufferFlushToFileStore(&buffer); EsBufferFlushToFileStore(&buffer);
EsPoint point = EsListViewGetAnnouncementPointForSelection(instance->list); EsPoint point = EsListViewGetAnnouncementPointForSelection(instance->list);
EsError error = EsClipboardCloseAndAdd(ES_CLIPBOARD_PRIMARY, ES_CLIPBOARD_FORMAT_PATH_LIST, buffer.fileStore); EsError error = EsClipboardCloseAndAdd(ES_CLIPBOARD_PRIMARY, ES_CLIPBOARD_FORMAT_PATH_LIST, buffer.fileStore, flags);
if (error == ES_SUCCESS) { if (error == ES_SUCCESS) {
if (flags & ES_CLIPBOARD_ADD_LAZY_CUT) {
EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementCut));
} else {
EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementCopied)); EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementCopied));
}
} else if (error == ES_ERROR_INSUFFICIENT_RESOURCES || error == ES_ERROR_DRIVE_FULL) { } else if (error == ES_ERROR_INSUFFICIENT_RESOURCES || error == ES_ERROR_DRIVE_FULL) {
EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementCopyErrorResources)); EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementCopyErrorResources));
} else { } else {
@ -152,15 +156,30 @@ void CommandCopy(Instance *instance, EsElement *, EsCommand *) {
} }
} }
EsError CommandPasteFile(String source, String destinationBase, void **copyBuffer, String *_destination = nullptr) { void CommandCut(Instance *instance, EsElement *, EsCommand *) {
CommandCopyOrCut(instance, ES_CLIPBOARD_ADD_LAZY_CUT);
}
void CommandCopy(Instance *instance, EsElement *, EsCommand *) {
CommandCopyOrCut(instance, ES_FLAGS_DEFAULT);
}
EsError CommandPasteFile(String source, String destinationBase, void **copyBuffer, bool move, String *_destination) {
if (PathHasPrefix(destinationBase, source)) { if (PathHasPrefix(destinationBase, source)) {
return ES_ERROR_TARGET_WITHIN_SOURCE; return ES_ERROR_TARGET_WITHIN_SOURCE;
} }
String name = PathGetName(source); String name = PathGetName(source);
String destination = StringAllocateAndFormat("%s%z%s", STRFMT(destinationBase), PathHasTrailingSlash(destinationBase) ? "" : "/", STRFMT(name)); String destination = StringAllocateAndFormat("%s%z%s", STRFMT(destinationBase), PathHasTrailingSlash(destinationBase) ? "" : "/", STRFMT(name));
EsError error;
if (StringEquals(PathGetParent(source), destinationBase)) { if (StringEquals(PathGetParent(source), destinationBase)) {
if (move) {
// Move with the source and destination folders identical; meaningless.
error = ES_SUCCESS;
goto done;
}
destination.allocated += 32; destination.allocated += 32;
destination.text = (char *) EsHeapReallocate(destination.text, destination.allocated, false); destination.text = (char *) EsHeapReallocate(destination.text, destination.allocated, false);
size_t bytes = EsPathFindUniqueName(destination.text, destination.bytes, destination.allocated); size_t bytes = EsPathFindUniqueName(destination.text, destination.bytes, destination.allocated);
@ -174,8 +193,18 @@ EsError CommandPasteFile(String source, String destinationBase, void **copyBuffe
} }
} }
EsPrint("Copying %s -> %s...\n", STRFMT(source), STRFMT(destination)); EsPrint("%z %s -> %s...\n", move ? "Moving" : "Copying", STRFMT(source), STRFMT(destination));
EsError error = EsFileCopy(STRING(source), STRING(destination), copyBuffer);
if (move) {
error = EsPathMove(STRING(source), STRING(destination), ES_FLAGS_DEFAULT);
if (error == ES_ERROR_VOLUME_MISMATCH) {
// TODO Delete the files after all copies complete successfully.
error = EsFileCopy(STRING(source), STRING(destination), copyBuffer);
}
} else {
error = EsFileCopy(STRING(source), STRING(destination), copyBuffer);
}
if (error == ES_ERROR_INCORRECT_NODE_TYPE) { if (error == ES_ERROR_INCORRECT_NODE_TYPE) {
EsDirectoryChild *buffer; EsDirectoryChild *buffer;
@ -190,7 +219,7 @@ EsError CommandPasteFile(String source, String destinationBase, void **copyBuffe
for (intptr_t i = 0; i < childCount && error == ES_SUCCESS; i++) { for (intptr_t i = 0; i < childCount && error == ES_SUCCESS; i++) {
String childSourcePath = StringAllocateAndFormat("%s%z%s", STRFMT(source), String childSourcePath = StringAllocateAndFormat("%s%z%s", STRFMT(source),
PathHasTrailingSlash(source) ? "" : "/", buffer[i].nameBytes, buffer[i].name); PathHasTrailingSlash(source) ? "" : "/", buffer[i].nameBytes, buffer[i].name);
error = CommandPasteFile(childSourcePath, destination, copyBuffer); error = CommandPasteFile(childSourcePath, destination, copyBuffer, move, nullptr);
StringDestroy(&childSourcePath); StringDestroy(&childSourcePath);
} }
} }
@ -200,9 +229,15 @@ EsError CommandPasteFile(String source, String destinationBase, void **copyBuffe
} }
if (error == ES_SUCCESS) { if (error == ES_SUCCESS) {
if (move) {
FolderFileUpdatedAtPath(source, nullptr);
}
FolderFileUpdatedAtPath(destination, nullptr); FolderFileUpdatedAtPath(destination, nullptr);
} }
done:;
if (_destination && error == ES_SUCCESS) { if (_destination && error == ES_SUCCESS) {
*_destination = destination; *_destination = destination;
} else { } else {
@ -212,6 +247,10 @@ EsError CommandPasteFile(String source, String destinationBase, void **copyBuffe
return error; return error;
} }
struct PasteOperation {
String source, destination;
};
void CommandPaste(Instance *instance, EsElement *, EsCommand *) { void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
if (EsClipboardHasFormat(ES_CLIPBOARD_PRIMARY, ES_CLIPBOARD_FORMAT_PATH_LIST)) { if (EsClipboardHasFormat(ES_CLIPBOARD_PRIMARY, ES_CLIPBOARD_FORMAT_PATH_LIST)) {
// TODO Background task. // TODO Background task.
@ -223,9 +262,14 @@ void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
void *copyBuffer = nullptr; void *copyBuffer = nullptr;
size_t bytes; size_t bytes;
char *pathList = EsClipboardReadText(ES_CLIPBOARD_PRIMARY, &bytes); uint32_t flags;
char *pathList = EsClipboardReadText(ES_CLIPBOARD_PRIMARY, &bytes, &flags);
Array<String> itemsToSelect = {}; bool move = flags & ES_CLIPBOARD_ADD_LAZY_CUT;
String destinationBase = StringDuplicate(instance->folder->path);
Array<PasteOperation> pasteOperations = {};
bool success = true;
if (pathList) { if (pathList) {
const char *position = pathList; const char *position = pathList;
@ -237,13 +281,12 @@ void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
String source = StringFromLiteralWithSize(position, newline - position); String source = StringFromLiteralWithSize(position, newline - position);
String destination; String destination;
if (ES_SUCCESS != CommandPasteFile(source, instance->folder->path, &copyBuffer, &destination)) { if (ES_SUCCESS != CommandPasteFile(source, destinationBase, &copyBuffer, move, &destination)) {
goto encounteredError; goto encounteredError;
} }
String destinationItem = StringDuplicate(PathGetName(destination)); PasteOperation operation = { .source = StringDuplicate(source), .destination = destination };
itemsToSelect.Add(destinationItem); pasteOperations.Add(operation);
StringDestroy(&destination);
position += source.bytes + 1; position += source.bytes + 1;
bytes -= source.bytes + 1; bytes -= source.bytes + 1;
@ -252,25 +295,47 @@ void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
encounteredError:; encounteredError:;
EsPoint point = EsListViewGetAnnouncementPointForSelection(instance->list); EsPoint point = EsListViewGetAnnouncementPointForSelection(instance->list);
EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementPasteErrorOther)); EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementPasteErrorOther));
success = false;
} }
size_t pathSectionCount = PathCountSections(instance->folder->path); size_t pathSectionCount = PathCountSections(destinationBase);
for (uintptr_t i = 0; i < pathSectionCount - 1; i++) { for (uintptr_t i = 0; i < pathSectionCount; i++) {
String parent = PathGetParent(instance->folder->path, i + 1); String parent = PathGetParent(destinationBase, i + 1);
FolderFileUpdatedAtPath(parent, nullptr); FolderFileUpdatedAtPath(parent, nullptr);
} }
EsListViewSelectNone(instance->list); if (pasteOperations.Length()) {
size_t pathSectionCount = PathCountSections(pasteOperations[0].source);
for (uintptr_t i = 0; i < itemsToSelect.Length(); i++) { for (uintptr_t i = 0; i < pathSectionCount; i++) {
InstanceSelectByName(instance, itemsToSelect[i], true, i == itemsToSelect.Length() - 1); String parent = PathGetParent(pasteOperations[0].source, i + 1);
StringDestroy(&itemsToSelect[i]); FolderFileUpdatedAtPath(parent, nullptr);
}
}
if (success) {
EsListViewSelectNone(instance->list);
}
for (uintptr_t i = 0; i < pasteOperations.Length(); i++) {
if (success) {
InstanceSelectByName(instance, PathGetName(pasteOperations[i].destination), true, i == pasteOperations.Length() - 1);
if (move) {
// TODO We must do this regardless of whether the instance has been destroyed during the operation.
FolderPathMoved(instance, pasteOperations[i].source, pasteOperations[i].destination, i == pasteOperations.Length() - 1);
}
}
StringDestroy(&pasteOperations[i].source);
StringDestroy(&pasteOperations[i].destination);
} }
EsHeapFree(pathList); EsHeapFree(pathList);
EsHeapFree(copyBuffer); EsHeapFree(copyBuffer);
itemsToSelect.Free(); StringDestroy(&destinationBase);
pasteOperations.Free();
} else { } else {
// TODO Paste the data into a new file. // TODO Paste the data into a new file.
} }

View File

@ -211,6 +211,7 @@ NamespaceHandler namespaceHandlers[] = {
{ {
.type = NAMESPACE_HANDLER_FILE_SYSTEM, .type = NAMESPACE_HANDLER_FILE_SYSTEM,
.rootContainerHandlerType = NAMESPACE_HANDLER_DRIVES_PAGE, .rootContainerHandlerType = NAMESPACE_HANDLER_DRIVES_PAGE,
.canCut = true,
.canCopy = true, .canCopy = true,
.canPaste = true, .canPaste = true,
.handlesPath = FSDirHandlesPath, .handlesPath = FSDirHandlesPath,
@ -426,29 +427,6 @@ void FolderAddEntryAndUpdateInstances(Folder *folder, const char *name, size_t n
} }
} }
void FolderFileUpdatedAtPath(String path, Instance *instance) {
path = PathRemoveTrailingSlash(path);
String file = PathGetName(path);
String folder = PathGetParent(path);
EsDirectoryChild information = {};
if (EsPathQueryInformation(STRING(path), &information)) {
for (uintptr_t i = 0; i < loadedFolders.Length(); i++) {
if (loadedFolders[i]->itemHandler->type != NAMESPACE_HANDLER_FILE_SYSTEM) continue;
if (EsStringCompareRaw(STRING(loadedFolders[i]->path), STRING(folder))) continue;
EsMutexAcquire(&loadedFolders[i]->modifyEntriesMutex);
if (loadedFolders[i]->doneInitialEnumeration) {
FolderAddEntryAndUpdateInstances(loadedFolders[i], file.text, file.bytes, &information, instance);
}
EsMutexRelease(&loadedFolders[i]->modifyEntriesMutex);
}
}
}
uint64_t FolderRemoveEntryAndUpdateInstances(Folder *folder, const char *name, size_t nameBytes) { uint64_t FolderRemoveEntryAndUpdateInstances(Folder *folder, const char *name, size_t nameBytes) {
FolderEntry *entry = (FolderEntry *) HashTableGetLong(&folder->entries, name, nameBytes); FolderEntry *entry = (FolderEntry *) HashTableGetLong(&folder->entries, name, nameBytes);
uint64_t id = 0; uint64_t id = 0;
@ -466,7 +444,32 @@ uint64_t FolderRemoveEntryAndUpdateInstances(Folder *folder, const char *name, s
return id; return id;
} }
void FolderPathMoved(Instance *instance, String oldPath, String newPath) { void FolderFileUpdatedAtPath(String path, Instance *instance) {
path = PathRemoveTrailingSlash(path);
String file = PathGetName(path);
String folder = PathGetParent(path);
EsDirectoryChild information = {};
bool add = EsPathQueryInformation(STRING(path), &information);
for (uintptr_t i = 0; i < loadedFolders.Length(); i++) {
if (loadedFolders[i]->itemHandler->type != NAMESPACE_HANDLER_FILE_SYSTEM) continue;
if (EsStringCompareRaw(STRING(loadedFolders[i]->path), STRING(folder))) continue;
EsMutexAcquire(&loadedFolders[i]->modifyEntriesMutex);
if (loadedFolders[i]->doneInitialEnumeration) {
if (add) {
FolderAddEntryAndUpdateInstances(loadedFolders[i], file.text, file.bytes, &information, instance);
} else {
FolderRemoveEntryAndUpdateInstances(loadedFolders[i], file.text, file.bytes);
}
}
EsMutexRelease(&loadedFolders[i]->modifyEntriesMutex);
}
}
void FolderPathMoved(Instance *instance, String oldPath, String newPath, bool saveConfiguration) {
_EsPathAnnouncePathMoved(instance, STRING(oldPath), STRING(newPath)); _EsPathAnnouncePathMoved(instance, STRING(oldPath), STRING(newPath));
for (uintptr_t i = 0; i < loadedFolders.Length(); i++) { for (uintptr_t i = 0; i < loadedFolders.Length(); i++) {
@ -523,7 +526,9 @@ void FolderPathMoved(Instance *instance, String oldPath, String newPath) {
"%s%s", STRFMT(newPath), STRFMT(after)); "%s%s", STRFMT(newPath), STRFMT(after));
} }
if (saveConfiguration) {
ConfigurationSave(); ConfigurationSave();
}
} }
void FolderAttachInstance(Instance *instance, String path, bool recurse) { void FolderAttachInstance(Instance *instance, String path, bool recurse) {

View File

@ -182,7 +182,7 @@ struct NamespaceHandler {
uint8_t type; uint8_t type;
uint8_t rootContainerHandlerType; uint8_t rootContainerHandlerType;
bool canCopy, canPaste; bool canCut, canCopy, canPaste;
bool (*handlesPath)(String path); bool (*handlesPath)(String path);

View File

@ -175,8 +175,11 @@ void InstanceUpdateItemSelectionCountCommands(Instance *instance) {
EsCommandSetEnabled(command, enabled); \ EsCommandSetEnabled(command, enabled); \
EsCommandSetCallback(command, callback); } while(0) EsCommandSetCallback(command, callback); } while(0)
if (EsElementIsFocused(instance->list)) {
COMMAND_SET(ES_COMMAND_CUT, CommandCut, instance->selectedItemCount >= 1 && instance->folder->itemHandler->canCut && !instance->folder->readOnly);
COMMAND_SET(ES_COMMAND_COPY, CommandCopy, instance->selectedItemCount >= 1 && instance->folder->itemHandler->canCopy); COMMAND_SET(ES_COMMAND_COPY, CommandCopy, instance->selectedItemCount >= 1 && instance->folder->itemHandler->canCopy);
COMMAND_SET(ES_COMMAND_PASTE, CommandPaste, instance->folder->itemHandler->canPaste && EsClipboardHasData(ES_CLIPBOARD_PRIMARY) && !instance->folder->readOnly); COMMAND_SET(ES_COMMAND_PASTE, CommandPaste, instance->folder->itemHandler->canPaste && EsClipboardHasData(ES_CLIPBOARD_PRIMARY) && !instance->folder->readOnly);
}
} }
int InstanceCompareFolderEntries(FolderEntry *left, FolderEntry *right, uint16_t sortColumn) { int InstanceCompareFolderEntries(FolderEntry *left, FolderEntry *right, uint16_t sortColumn) {
@ -703,7 +706,9 @@ int ListCallback(EsElement *element, EsMessage *message) {
InstanceUpdateItemSelectionCountCommands(instance); InstanceUpdateItemSelectionCountCommands(instance);
return 0; return 0;
} else if (message->type == ES_MSG_FOCUSED_END) { } else if (message->type == ES_MSG_FOCUSED_END) {
EsCommandSetCallback(EsCommandByID(instance, ES_COMMAND_CUT), nullptr);
EsCommandSetCallback(EsCommandByID(instance, ES_COMMAND_COPY), nullptr); EsCommandSetCallback(EsCommandByID(instance, ES_COMMAND_COPY), nullptr);
EsCommandSetCallback(EsCommandByID(instance, ES_COMMAND_PASTE), nullptr);
return 0; return 0;
} else if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT) { } else if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT) {
int column = message->getContent.column, index = message->getContent.index; int column = message->getContent.column, index = message->getContent.index;

View File

@ -5408,6 +5408,10 @@ void UIMaybeRemoveFocusedElement(EsWindow *window) {
} }
} }
bool EsElementIsFocused(EsElement *element) {
return element->window->focused == element;
}
void EsElementFocus(EsElement *element, uint32_t flags) { void EsElementFocus(EsElement *element, uint32_t flags) {
EsMessageMutexCheck(); EsMessageMutexCheck();

View File

@ -483,6 +483,7 @@ struct EsListView : EsElement {
} }
void Populate() { void Populate() {
#if 0
EsPrint("--- Before Populate() ---\n"); EsPrint("--- Before Populate() ---\n");
EsPrint("Scroll: %i\n", (int) (scroll.position[1] - currentStyle->insets.t)); EsPrint("Scroll: %i\n", (int) (scroll.position[1] - currentStyle->insets.t));
@ -498,6 +499,7 @@ struct EsListView : EsElement {
} }
EsPrint("------\n"); EsPrint("------\n");
#endif
// TODO Keep one item before and after the viewport, so tab traversal on custom elements works. // TODO Keep one item before and after the viewport, so tab traversal on custom elements works.
// TODO Always keep an item if it has FOCUS_WITHIN. // TODO Always keep an item if it has FOCUS_WITHIN.
@ -2507,7 +2509,8 @@ void EsListViewSetMaximumItemsPerBand(EsListView *view, int maximumItemsPerBand)
} }
EsPoint EsListViewGetAnnouncementPointForSelection(EsListView *view) { EsPoint EsListViewGetAnnouncementPointForSelection(EsListView *view) {
EsRectangle bounding = EsElementGetWindowBounds(view); EsRectangle viewWindowBounds = EsElementGetWindowBounds(view);
EsRectangle bounding = viewWindowBounds;
bool first = true; bool first = true;
for (uintptr_t i = 0; i < view->visibleItems.Length(); i++) { for (uintptr_t i = 0; i < view->visibleItems.Length(); i++) {
@ -2518,5 +2521,6 @@ EsPoint EsListViewGetAnnouncementPointForSelection(EsListView *view) {
first = false; first = false;
} }
bounding = EsRectangleIntersection(bounding, viewWindowBounds);
return ES_POINT((bounding.l + bounding.r) / 2, (bounding.t + bounding.b) / 2); return ES_POINT((bounding.l + bounding.r) / 2, (bounding.t + bounding.b) / 2);
} }

View File

@ -729,6 +729,8 @@ define ES_VOLUME_READ_ONLY (1 << 0)
define ES_PATH_MOVE_ALLOW_COPY_AND_DELETE (1 << 0) // Copy and delete the file if a direct move is not possible. define ES_PATH_MOVE_ALLOW_COPY_AND_DELETE (1 << 0) // Copy and delete the file if a direct move is not possible.
define ES_CLIPBOARD_ADD_LAZY_CUT (1 << 0) // Only perform the deletion after pasting; often implemented as a move.
include desktop/icons.header include desktop/icons.header
enum EsFatalError { enum EsFatalError {
@ -2230,9 +2232,9 @@ function int EsCRTvsnprintf(char *buffer, size_t bufferSize, const char *format,
function EsError EsClipboardAddText(EsClipboard clipboard, STRING text = BLANK_STRING); function EsError EsClipboardAddText(EsClipboard clipboard, STRING text = BLANK_STRING);
function bool EsClipboardHasFormat(EsClipboard clipboard, EsClipboardFormat format); function bool EsClipboardHasFormat(EsClipboard clipboard, EsClipboardFormat format);
function bool EsClipboardHasData(EsClipboard clipboard); function bool EsClipboardHasData(EsClipboard clipboard);
function char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes); // Free with EsHeapFree. function char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes, uint32_t *flags = nullptr); // Free with EsHeapFree.
function EsFileStore *EsClipboardOpen(EsClipboard clipboard); // Open the clipboard for writing. function EsFileStore *EsClipboardOpen(EsClipboard clipboard); // Open the clipboard for writing.
function EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format, EsFileStore *fileStore); function EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format, EsFileStore *fileStore, uint32_t flags = ES_FLAGS_DEFAULT);
function void EsUndoClear(EsUndoManager *manager); function void EsUndoClear(EsUndoManager *manager);
function void EsUndoContinueGroup(EsUndoManager *manager); function void EsUndoContinueGroup(EsUndoManager *manager);
@ -2277,6 +2279,7 @@ function EsMessage *EsMessageReceive();
function void EsElementDraw(EsElement *element, EsPainter *painter); // Actually draw an element onto a painter. function void EsElementDraw(EsElement *element, EsPainter *painter); // Actually draw an element onto a painter.
function void EsElementFocus(EsElement *element, uint32_t flags = ES_FLAGS_DEFAULT); function void EsElementFocus(EsElement *element, uint32_t flags = ES_FLAGS_DEFAULT);
function bool EsElementIsFocused(EsElement *element);
function void EsElementSetDisabled(EsElement *element, bool disabled = true); function void EsElementSetDisabled(EsElement *element, bool disabled = true);
function void EsElementSetHidden(EsElement *element, bool hidden = true); function void EsElementSetHidden(EsElement *element, bool hidden = true);
function void EsElementSetCallback(EsElement *element, EsUICallbackFunction callback); function void EsElementSetCallback(EsElement *element, EsUICallbackFunction callback);

View File

@ -502,6 +502,10 @@ EsError EsPathMove(const char *oldPath, ptrdiff_t oldPathBytes, const char *newP
if (oldPathBytes == -1) oldPathBytes = EsCStringLength(oldPath); if (oldPathBytes == -1) oldPathBytes = EsCStringLength(oldPath);
if (newPathBytes == -1) newPathBytes = EsCStringLength(newPath); if (newPathBytes == -1) newPathBytes = EsCStringLength(newPath);
if (newPathBytes && newPath[newPathBytes - 1] == '/') {
newPathBytes--;
}
_EsNodeInformation node = {}; _EsNodeInformation node = {};
_EsNodeInformation directory = {}; _EsNodeInformation directory = {};
EsError error; EsError error;
@ -756,6 +760,7 @@ struct ClipboardInformation {
uint8_t desktopMessageTag; uint8_t desktopMessageTag;
intptr_t error; intptr_t error;
EsClipboardFormat format; EsClipboardFormat format;
uint32_t flags;
}; };
EsFileStore *EsClipboardOpen(EsClipboard clipboard) { EsFileStore *EsClipboardOpen(EsClipboard clipboard) {
@ -773,7 +778,7 @@ EsFileStore *EsClipboardOpen(EsClipboard clipboard) {
return fileStore; return fileStore;
} }
EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format, EsFileStore *fileStore) { EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format, EsFileStore *fileStore, uint32_t flags) {
(void) clipboard; (void) clipboard;
EsError error = fileStore->error; EsError error = fileStore->error;
@ -782,6 +787,7 @@ EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format,
information.desktopMessageTag = DESKTOP_MSG_CLIPBOARD_PUT; information.desktopMessageTag = DESKTOP_MSG_CLIPBOARD_PUT;
information.error = error; information.error = error;
information.format = format; information.format = format;
information.flags = flags;
MessageDesktop(&information, sizeof(information)); MessageDesktop(&information, sizeof(information));
} }
@ -828,7 +834,7 @@ bool EsClipboardHasData(EsClipboard clipboard) {
return information.error == ES_SUCCESS && information.format != ES_CLIPBOARD_FORMAT_INVALID; return information.error == ES_SUCCESS && information.format != ES_CLIPBOARD_FORMAT_INVALID;
} }
char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes) { char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes, uint32_t *flags) {
(void) clipboard; (void) clipboard;
char *result = nullptr; char *result = nullptr;
@ -841,6 +847,10 @@ char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes) {
if (file) { if (file) {
if (information.format == ES_CLIPBOARD_FORMAT_TEXT || information.format == ES_CLIPBOARD_FORMAT_PATH_LIST) { if (information.format == ES_CLIPBOARD_FORMAT_TEXT || information.format == ES_CLIPBOARD_FORMAT_PATH_LIST) {
result = (char *) EsFileReadAllFromHandle(file, bytes); result = (char *) EsFileReadAllFromHandle(file, bytes);
if (flags) {
*flags = information.flags;
}
} }
EsHandleClose(file); EsHandleClose(file);

Binary file not shown.

Binary file not shown.

View File

@ -60,6 +60,7 @@ DEFINE_INTERFACE_STRING(CommonListViewTypeTiles, "Tiles");
DEFINE_INTERFACE_STRING(CommonListViewTypeDetails, "Details"); DEFINE_INTERFACE_STRING(CommonListViewTypeDetails, "Details");
DEFINE_INTERFACE_STRING(CommonAnnouncementCopied, "Copied"); DEFINE_INTERFACE_STRING(CommonAnnouncementCopied, "Copied");
DEFINE_INTERFACE_STRING(CommonAnnouncementCut, "Cut");
DEFINE_INTERFACE_STRING(CommonAnnouncementTextCopied, "Text copied"); DEFINE_INTERFACE_STRING(CommonAnnouncementTextCopied, "Text copied");
DEFINE_INTERFACE_STRING(CommonAnnouncementCopyErrorResources, "There's not enough space to copy this"); DEFINE_INTERFACE_STRING(CommonAnnouncementCopyErrorResources, "There's not enough space to copy this");
DEFINE_INTERFACE_STRING(CommonAnnouncementCopyErrorOther, "Could not copy"); DEFINE_INTERFACE_STRING(CommonAnnouncementCopyErrorOther, "Could not copy");

View File

@ -431,3 +431,4 @@ EsClipboardHasFormat=429
EsClipboardHasData=430 EsClipboardHasData=430
EsFileCopy=431 EsFileCopy=431
EsListViewSelectNone=432 EsListViewSelectNone=432
EsElementIsFocused=433