mirror of https://gitlab.com/nakst/essence
basic file cut and paste
This commit is contained in:
parent
fdc4da053b
commit
6c106d1a1f
|
@ -62,7 +62,7 @@ void CommandRename(Instance *instance, EsElement *, EsCommand *) {
|
|||
size_t oldPathBytes;
|
||||
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 = {};
|
||||
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),
|
||||
// so that document can be pasted into other applications.
|
||||
|
||||
|
@ -141,10 +141,14 @@ void CommandCopy(Instance *instance, EsElement *, EsCommand *) {
|
|||
EsBufferFlushToFileStore(&buffer);
|
||||
|
||||
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) {
|
||||
EsAnnouncementShow(instance->window, ES_FLAGS_DEFAULT, point.x, point.y, INTERFACE_STRING(CommonAnnouncementCopied));
|
||||
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));
|
||||
}
|
||||
} 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));
|
||||
} 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)) {
|
||||
return ES_ERROR_TARGET_WITHIN_SOURCE;
|
||||
}
|
||||
|
||||
String name = PathGetName(source);
|
||||
String destination = StringAllocateAndFormat("%s%z%s", STRFMT(destinationBase), PathHasTrailingSlash(destinationBase) ? "" : "/", STRFMT(name));
|
||||
EsError error;
|
||||
|
||||
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.text = (char *) EsHeapReallocate(destination.text, destination.allocated, false);
|
||||
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));
|
||||
EsError error = EsFileCopy(STRING(source), STRING(destination), copyBuffer);
|
||||
EsPrint("%z %s -> %s...\n", move ? "Moving" : "Copying", STRFMT(source), STRFMT(destination));
|
||||
|
||||
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) {
|
||||
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++) {
|
||||
String childSourcePath = StringAllocateAndFormat("%s%z%s", STRFMT(source),
|
||||
PathHasTrailingSlash(source) ? "" : "/", buffer[i].nameBytes, buffer[i].name);
|
||||
error = CommandPasteFile(childSourcePath, destination, copyBuffer);
|
||||
error = CommandPasteFile(childSourcePath, destination, copyBuffer, move, nullptr);
|
||||
StringDestroy(&childSourcePath);
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +229,15 @@ EsError CommandPasteFile(String source, String destinationBase, void **copyBuffe
|
|||
}
|
||||
|
||||
if (error == ES_SUCCESS) {
|
||||
if (move) {
|
||||
FolderFileUpdatedAtPath(source, nullptr);
|
||||
}
|
||||
|
||||
FolderFileUpdatedAtPath(destination, nullptr);
|
||||
}
|
||||
|
||||
done:;
|
||||
|
||||
if (_destination && error == ES_SUCCESS) {
|
||||
*_destination = destination;
|
||||
} else {
|
||||
|
@ -212,6 +247,10 @@ EsError CommandPasteFile(String source, String destinationBase, void **copyBuffe
|
|||
return error;
|
||||
}
|
||||
|
||||
struct PasteOperation {
|
||||
String source, destination;
|
||||
};
|
||||
|
||||
void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
|
||||
if (EsClipboardHasFormat(ES_CLIPBOARD_PRIMARY, ES_CLIPBOARD_FORMAT_PATH_LIST)) {
|
||||
// TODO Background task.
|
||||
|
@ -223,9 +262,14 @@ void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
|
|||
void *copyBuffer = nullptr;
|
||||
|
||||
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) {
|
||||
const char *position = pathList;
|
||||
|
@ -237,13 +281,12 @@ void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
|
|||
String source = StringFromLiteralWithSize(position, newline - position);
|
||||
String destination;
|
||||
|
||||
if (ES_SUCCESS != CommandPasteFile(source, instance->folder->path, ©Buffer, &destination)) {
|
||||
if (ES_SUCCESS != CommandPasteFile(source, destinationBase, ©Buffer, move, &destination)) {
|
||||
goto encounteredError;
|
||||
}
|
||||
|
||||
String destinationItem = StringDuplicate(PathGetName(destination));
|
||||
itemsToSelect.Add(destinationItem);
|
||||
StringDestroy(&destination);
|
||||
PasteOperation operation = { .source = StringDuplicate(source), .destination = destination };
|
||||
pasteOperations.Add(operation);
|
||||
|
||||
position += source.bytes + 1;
|
||||
bytes -= source.bytes + 1;
|
||||
|
@ -252,25 +295,47 @@ void CommandPaste(Instance *instance, EsElement *, EsCommand *) {
|
|||
encounteredError:;
|
||||
EsPoint point = EsListViewGetAnnouncementPointForSelection(instance->list);
|
||||
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++) {
|
||||
String parent = PathGetParent(instance->folder->path, i + 1);
|
||||
for (uintptr_t i = 0; i < pathSectionCount; i++) {
|
||||
String parent = PathGetParent(destinationBase, i + 1);
|
||||
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++) {
|
||||
InstanceSelectByName(instance, itemsToSelect[i], true, i == itemsToSelect.Length() - 1);
|
||||
StringDestroy(&itemsToSelect[i]);
|
||||
for (uintptr_t i = 0; i < pathSectionCount; i++) {
|
||||
String parent = PathGetParent(pasteOperations[0].source, i + 1);
|
||||
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(copyBuffer);
|
||||
itemsToSelect.Free();
|
||||
StringDestroy(&destinationBase);
|
||||
pasteOperations.Free();
|
||||
} else {
|
||||
// TODO Paste the data into a new file.
|
||||
}
|
||||
|
|
|
@ -211,6 +211,7 @@ NamespaceHandler namespaceHandlers[] = {
|
|||
{
|
||||
.type = NAMESPACE_HANDLER_FILE_SYSTEM,
|
||||
.rootContainerHandlerType = NAMESPACE_HANDLER_DRIVES_PAGE,
|
||||
.canCut = true,
|
||||
.canCopy = true,
|
||||
.canPaste = true,
|
||||
.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) {
|
||||
FolderEntry *entry = (FolderEntry *) HashTableGetLong(&folder->entries, name, nameBytes);
|
||||
uint64_t id = 0;
|
||||
|
@ -466,7 +444,32 @@ uint64_t FolderRemoveEntryAndUpdateInstances(Folder *folder, const char *name, s
|
|||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
ConfigurationSave();
|
||||
if (saveConfiguration) {
|
||||
ConfigurationSave();
|
||||
}
|
||||
}
|
||||
|
||||
void FolderAttachInstance(Instance *instance, String path, bool recurse) {
|
||||
|
|
|
@ -182,7 +182,7 @@ struct NamespaceHandler {
|
|||
uint8_t type;
|
||||
uint8_t rootContainerHandlerType;
|
||||
|
||||
bool canCopy, canPaste;
|
||||
bool canCut, canCopy, canPaste;
|
||||
|
||||
bool (*handlesPath)(String path);
|
||||
|
||||
|
|
|
@ -175,8 +175,11 @@ void InstanceUpdateItemSelectionCountCommands(Instance *instance) {
|
|||
EsCommandSetEnabled(command, enabled); \
|
||||
EsCommandSetCallback(command, callback); } while(0)
|
||||
|
||||
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);
|
||||
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_PASTE, CommandPaste, instance->folder->itemHandler->canPaste && EsClipboardHasData(ES_CLIPBOARD_PRIMARY) && !instance->folder->readOnly);
|
||||
}
|
||||
}
|
||||
|
||||
int InstanceCompareFolderEntries(FolderEntry *left, FolderEntry *right, uint16_t sortColumn) {
|
||||
|
@ -703,7 +706,9 @@ int ListCallback(EsElement *element, EsMessage *message) {
|
|||
InstanceUpdateItemSelectionCountCommands(instance);
|
||||
return 0;
|
||||
} 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_PASTE), nullptr);
|
||||
return 0;
|
||||
} else if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT) {
|
||||
int column = message->getContent.column, index = message->getContent.index;
|
||||
|
|
|
@ -5408,6 +5408,10 @@ void UIMaybeRemoveFocusedElement(EsWindow *window) {
|
|||
}
|
||||
}
|
||||
|
||||
bool EsElementIsFocused(EsElement *element) {
|
||||
return element->window->focused == element;
|
||||
}
|
||||
|
||||
void EsElementFocus(EsElement *element, uint32_t flags) {
|
||||
EsMessageMutexCheck();
|
||||
|
||||
|
|
|
@ -483,6 +483,7 @@ struct EsListView : EsElement {
|
|||
}
|
||||
|
||||
void Populate() {
|
||||
#if 0
|
||||
EsPrint("--- Before Populate() ---\n");
|
||||
EsPrint("Scroll: %i\n", (int) (scroll.position[1] - currentStyle->insets.t));
|
||||
|
||||
|
@ -498,6 +499,7 @@ struct EsListView : EsElement {
|
|||
}
|
||||
|
||||
EsPrint("------\n");
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
|
@ -2507,7 +2509,8 @@ void EsListViewSetMaximumItemsPerBand(EsListView *view, int maximumItemsPerBand)
|
|||
}
|
||||
|
||||
EsPoint EsListViewGetAnnouncementPointForSelection(EsListView *view) {
|
||||
EsRectangle bounding = EsElementGetWindowBounds(view);
|
||||
EsRectangle viewWindowBounds = EsElementGetWindowBounds(view);
|
||||
EsRectangle bounding = viewWindowBounds;
|
||||
bool first = true;
|
||||
|
||||
for (uintptr_t i = 0; i < view->visibleItems.Length(); i++) {
|
||||
|
@ -2518,5 +2521,6 @@ EsPoint EsListViewGetAnnouncementPointForSelection(EsListView *view) {
|
|||
first = false;
|
||||
}
|
||||
|
||||
bounding = EsRectangleIntersection(bounding, viewWindowBounds);
|
||||
return ES_POINT((bounding.l + bounding.r) / 2, (bounding.t + bounding.b) / 2);
|
||||
}
|
||||
|
|
|
@ -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_CLIPBOARD_ADD_LAZY_CUT (1 << 0) // Only perform the deletion after pasting; often implemented as a move.
|
||||
|
||||
include desktop/icons.header
|
||||
|
||||
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 bool EsClipboardHasFormat(EsClipboard clipboard, EsClipboardFormat format);
|
||||
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 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 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 EsElementFocus(EsElement *element, uint32_t flags = ES_FLAGS_DEFAULT);
|
||||
function bool EsElementIsFocused(EsElement *element);
|
||||
function void EsElementSetDisabled(EsElement *element, bool disabled = true);
|
||||
function void EsElementSetHidden(EsElement *element, bool hidden = true);
|
||||
function void EsElementSetCallback(EsElement *element, EsUICallbackFunction callback);
|
||||
|
|
|
@ -502,6 +502,10 @@ EsError EsPathMove(const char *oldPath, ptrdiff_t oldPathBytes, const char *newP
|
|||
if (oldPathBytes == -1) oldPathBytes = EsCStringLength(oldPath);
|
||||
if (newPathBytes == -1) newPathBytes = EsCStringLength(newPath);
|
||||
|
||||
if (newPathBytes && newPath[newPathBytes - 1] == '/') {
|
||||
newPathBytes--;
|
||||
}
|
||||
|
||||
_EsNodeInformation node = {};
|
||||
_EsNodeInformation directory = {};
|
||||
EsError error;
|
||||
|
@ -756,6 +760,7 @@ struct ClipboardInformation {
|
|||
uint8_t desktopMessageTag;
|
||||
intptr_t error;
|
||||
EsClipboardFormat format;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
EsFileStore *EsClipboardOpen(EsClipboard clipboard) {
|
||||
|
@ -773,7 +778,7 @@ EsFileStore *EsClipboardOpen(EsClipboard clipboard) {
|
|||
return fileStore;
|
||||
}
|
||||
|
||||
EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format, EsFileStore *fileStore) {
|
||||
EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format, EsFileStore *fileStore, uint32_t flags) {
|
||||
(void) clipboard;
|
||||
EsError error = fileStore->error;
|
||||
|
||||
|
@ -782,6 +787,7 @@ EsError EsClipboardCloseAndAdd(EsClipboard clipboard, EsClipboardFormat format,
|
|||
information.desktopMessageTag = DESKTOP_MSG_CLIPBOARD_PUT;
|
||||
information.error = error;
|
||||
information.format = format;
|
||||
information.flags = flags;
|
||||
MessageDesktop(&information, sizeof(information));
|
||||
}
|
||||
|
||||
|
@ -828,7 +834,7 @@ bool EsClipboardHasData(EsClipboard clipboard) {
|
|||
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;
|
||||
|
||||
char *result = nullptr;
|
||||
|
@ -841,6 +847,10 @@ char *EsClipboardReadText(EsClipboard clipboard, size_t *bytes) {
|
|||
if (file) {
|
||||
if (information.format == ES_CLIPBOARD_FORMAT_TEXT || information.format == ES_CLIPBOARD_FORMAT_PATH_LIST) {
|
||||
result = (char *) EsFileReadAllFromHandle(file, bytes);
|
||||
|
||||
if (flags) {
|
||||
*flags = information.flags;
|
||||
}
|
||||
}
|
||||
|
||||
EsHandleClose(file);
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -60,6 +60,7 @@ DEFINE_INTERFACE_STRING(CommonListViewTypeTiles, "Tiles");
|
|||
DEFINE_INTERFACE_STRING(CommonListViewTypeDetails, "Details");
|
||||
|
||||
DEFINE_INTERFACE_STRING(CommonAnnouncementCopied, "Copied");
|
||||
DEFINE_INTERFACE_STRING(CommonAnnouncementCut, "Cut");
|
||||
DEFINE_INTERFACE_STRING(CommonAnnouncementTextCopied, "Text copied");
|
||||
DEFINE_INTERFACE_STRING(CommonAnnouncementCopyErrorResources, "There's not enough space to copy this");
|
||||
DEFINE_INTERFACE_STRING(CommonAnnouncementCopyErrorOther, "Could not copy");
|
||||
|
|
|
@ -431,3 +431,4 @@ EsClipboardHasFormat=429
|
|||
EsClipboardHasData=430
|
||||
EsFileCopy=431
|
||||
EsListViewSelectNone=432
|
||||
EsElementIsFocused=433
|
||||
|
|
Loading…
Reference in New Issue