diff --git a/apps/file_manager/ui.cpp b/apps/file_manager/ui.cpp index d6caf99..6af6740 100644 --- a/apps/file_manager/ui.cpp +++ b/apps/file_manager/ui.cpp @@ -823,6 +823,20 @@ int ListCallback(EsElement *element, EsMessage *message) { ListItemCreated(element, message->createItem.index, false); } else if (message->type == ES_MSG_LIST_VIEW_CONTEXT_MENU) { EsMenu *menu = EsMenuCreate(element, ES_MENU_AT_CURSOR); + EsOpenDocumentInformation information; + ListEntry *entry = &instance->listContents[message->selectItem.index]; + String path = instance->folder->itemHandler->getPathForChild(instance->folder, entry->entry); + EsOpenDocumentQueryInformation(STRING(path), &information); + StringDestroy(&path); + + if (information.isOpen) { + char buffer[256]; + size_t bytes = EsStringFormat(buffer, sizeof(buffer), interfaceString_FileManagerFileOpenIn, + (size_t) information.applicationNameBytes, (const char *) information.applicationName); + EsMenuAddItem(menu, ES_MENU_ITEM_HEADER, buffer, bytes); + EsMenuAddSeparator(menu); + } + EsMenuAddCommand(menu, ES_FLAGS_DEFAULT, INTERFACE_STRING(CommonClipboardCut), EsCommandByID(instance, ES_COMMAND_CUT)); EsMenuAddCommand(menu, ES_FLAGS_DEFAULT, INTERFACE_STRING(CommonClipboardCopy), EsCommandByID(instance, ES_COMMAND_COPY)); EsMenuAddSeparator(menu); diff --git a/desktop/api.cpp b/desktop/api.cpp index aff859c..ab831d3 100644 --- a/desktop/api.cpp +++ b/desktop/api.cpp @@ -51,15 +51,16 @@ struct EnumString { const char *cName; int value; }; #define DESKTOP_MSG_RUN_TEMPORARY_APPLICATION (7) #define DESKTOP_MSG_REQUEST_SHUTDOWN (8) #define DESKTOP_MSG_START_APPLICATION (9) -#define DESKTOP_MSG_CREATE_CLIPBOARD_FILE (10) -#define DESKTOP_MSG_CLIPBOARD_PUT (11) -#define DESKTOP_MSG_CLIPBOARD_GET (12) -#define DESKTOP_MSG_SYSTEM_CONFIGURATION_GET (13) -#define DESKTOP_MSG_FILE_TYPES_GET (14) -#define DESKTOP_MSG_START_USER_TASK (16) -#define DESKTOP_MSG_SET_PROGRESS (17) -#define DESKTOP_MSG_RENAME (18) -#define DESKTOP_MSG_SET_MODIFIED (19) +#define DESKTOP_MSG_CREATE_CLIPBOARD_FILE (10) +#define DESKTOP_MSG_CLIPBOARD_PUT (11) +#define DESKTOP_MSG_CLIPBOARD_GET (12) +#define DESKTOP_MSG_SYSTEM_CONFIGURATION_GET (13) +#define DESKTOP_MSG_FILE_TYPES_GET (14) +#define DESKTOP_MSG_START_USER_TASK (16) +#define DESKTOP_MSG_SET_PROGRESS (17) +#define DESKTOP_MSG_RENAME (18) +#define DESKTOP_MSG_SET_MODIFIED (19) +#define DESKTOP_MSG_QUERY_OPEN_DOCUMENT (20) struct EsFileStore { #define FILE_STORE_HANDLE (1) @@ -620,6 +621,19 @@ void _EsPathAnnouncePathMoved(const char *oldPath, ptrdiff_t oldPathBytes, const } } +void EsOpenDocumentQueryInformation(const char *path, ptrdiff_t pathBytes, EsOpenDocumentInformation *information) { + if (pathBytes == -1) pathBytes = EsCStringLength(path); + char *buffer = (char *) EsHeapAllocate(pathBytes + 1, false); + + if (buffer) { + buffer[0] = DESKTOP_MSG_QUERY_OPEN_DOCUMENT; + EsMemoryCopy(buffer + 1, path, pathBytes); + EsBuffer response = { .out = (uint8_t *) information, .bytes = sizeof(EsOpenDocumentInformation) }; + MessageDesktop(buffer, pathBytes + 1, ES_INVALID_HANDLE, &response); + EsHeapFree(buffer); + } +} + void EsApplicationRunTemporary(EsInstance *instance, const char *path, ptrdiff_t pathBytes) { if (pathBytes == -1) pathBytes = EsCStringLength(path); char *buffer = (char *) EsHeapAllocate(pathBytes + 1, false); diff --git a/desktop/desktop.cpp b/desktop/desktop.cpp index 366e06f..682f447 100644 --- a/desktop/desktop.cpp +++ b/desktop/desktop.cpp @@ -2691,6 +2691,42 @@ void DesktopSyscall(EsMessage *message, uint8_t *buffer, EsBuffer *pipe) { desktop.allOngoingUserTasks.Add(instance); TaskBarTasksButtonUpdate(); + } else if (buffer[0] == DESKTOP_MSG_QUERY_OPEN_DOCUMENT) { + InstalledApplication *application = ApplicationFindByPID(message->desktop.processID); + + if (application && (application->permissions & APPLICATION_PERMISSION_ALL_FILES)) { + EsObjectID id = 0; + + for (uintptr_t i = 0; i < desktop.openDocuments.Count(); i++) { + OpenDocument *document = &desktop.openDocuments[i]; + + if (0 == EsStringCompare(document->path, document->pathBytes, (char *) buffer + 1, message->desktop.bytes - 1)) { + id = document->id; + break; + } + } + + EsOpenDocumentInformation information; + EsMemoryZero(&information, sizeof(information)); + + if (id) { + information.isOpen = true; + + for (uintptr_t i = 0; i < desktop.allApplicationInstances.Length(); i++) { + ApplicationInstance *instance = desktop.allApplicationInstances[i]; + + if (instance->documentID == id) { + information.isModified = instance->tab && (instance->tab->closeButton->customStyleState & THEME_STATE_CHECKED); + information.applicationNameBytes = MinimumInteger(EsCStringLength(instance->application->cName), + sizeof(information.applicationName)); + EsMemoryCopy(information.applicationName, instance->application->cName, information.applicationNameBytes); + break; + } + } + } + + EsBufferWrite(pipe, &information, sizeof(information)); + } } else if (!instance) { // ------------------------------------------------- // | Messages below here require a valid instance. | diff --git a/desktop/gui.cpp b/desktop/gui.cpp index 6011758..fda0654 100644 --- a/desktop/gui.cpp +++ b/desktop/gui.cpp @@ -4171,10 +4171,6 @@ void EsMenuAddItem(EsMenu *menu, uint64_t flags, const char *label, ptrdiff_t la }; button->menuItemContext = context; - - if (flags & ES_MENU_ITEM_CHECKED) { - EsButtonSetCheck(button, ES_CHECK_CHECKED); - } } void EsMenuAddCommand(EsMenu *menu, uint64_t flags, const char *label, ptrdiff_t labelBytes, EsCommand *command) { diff --git a/desktop/os.header b/desktop/os.header index 30c26e4..7e70edf 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -504,7 +504,7 @@ define ES_BUTTON_CHECKBOX (1 << 10) define ES_BUTTON_RADIOBOX (1 << 11) define ES_BUTTON_CANCEL (1 << 12) define ES_BUTTON_PUSH (1 << 13) -define ES_MENU_ITEM_CHECKED (1 << 14) +define ES_MENU_ITEM_CHECKED (ES_CHECK_CHECKED) define ES_COLOR_WELL_HAS_OPACITY (1 << 0) @@ -1896,6 +1896,12 @@ struct EsBlockDeviceInformation { char model[64]; }; +struct EsOpenDocumentInformation { + bool isOpen, isModified; + uint8_t applicationNameBytes; + char applicationName[128]; +}; + // Function pointer types. function_pointer void EsThreadEntryCallback(EsGeneric argument); @@ -1980,10 +1986,11 @@ function bool EsFileStoreAppend(EsFileStore *file, const void *data, size_t data function EsFileOffsetDifference EsFileStoreGetSize(EsFileStore *file); // Returns -1 on error. function void *EsFileStoreMap(EsFileStore *file, size_t *fileSize, uint32_t flags); -// Requires permission_all_files. +// These calls require permission_all_files. function bool EsMountPointGetVolumeInformation(const char *prefix, size_t prefixBytes, EsVolumeInformation *information); // Returns false if the mount point does not exist. function void EsMountPointEnumerate(EsMountPointEnumerationCallback callback, EsGeneric context); function void _EsPathAnnouncePathMoved(STRING oldPath, STRING newPath); +function void EsOpenDocumentQueryInformation(STRING filePath, EsOpenDocumentInformation *information); function void EsDeviceEnumerate(EsDeviceEnumerationCallback callback, EsGeneric context); function EsError EsDeviceControl(EsHandle handle, EsDeviceControlType type, void *dp, void *dq); diff --git a/shared/strings.cpp b/shared/strings.cpp index ba2970e..12da177 100644 --- a/shared/strings.cpp +++ b/shared/strings.cpp @@ -306,6 +306,7 @@ DEFINE_INTERFACE_STRING(FileManagerMoveTask, "Moving" ELLIPSIS); DEFINE_INTERFACE_STRING(FileManagerGoBack, "Go back"); DEFINE_INTERFACE_STRING(FileManagerGoForwards, "Go forwards"); DEFINE_INTERFACE_STRING(FileManagerGoUp, "Go to containing folder"); +DEFINE_INTERFACE_STRING(FileManagerFileOpenIn, "File is open in " OPEN_SPEECH "%s" CLOSE_SPEECH); // 2048. diff --git a/util/api_table.ini b/util/api_table.ini index 2390b5a..1d29573 100644 --- a/util/api_table.ini +++ b/util/api_table.ini @@ -475,3 +475,4 @@ EsCRTatod=473 EsCRTatof=474 EsCRTstrtod=475 EsCRTstrtof=476 +EsOpenDocumentQueryInformation=477