@theia/workspace
Version:
Theia - Workspace Extension
207 lines • 9.04 kB
JavaScript
;
// *****************************************************************************
// Copyright (C) 2017 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkspaceDeleteHandler = void 0;
const tslib_1 = require("tslib");
const inversify_1 = require("@theia/core/shared/inversify");
const uri_1 = require("@theia/core/lib/common/uri");
const browser_1 = require("@theia/core/lib/browser");
const workspace_service_1 = require("./workspace-service");
const workspace_utils_1 = require("./workspace-utils");
const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
const filesystem_preferences_1 = require("@theia/filesystem/lib/common/filesystem-preferences");
const nls_1 = require("@theia/core/lib/common/nls");
let WorkspaceDeleteHandler = class WorkspaceDeleteHandler {
/**
* Determine if the command is visible.
*
* @param uris URIs of selected resources.
* @returns `true` if the command is visible.
*/
isVisible(uris) {
return !!uris.length && !this.workspaceUtils.containsRootDirectory(uris);
}
/**
* Determine if the command is enabled.
*
* @param uris URIs of selected resources.
* @returns `true` if the command is enabled.
*/
isEnabled(uris) {
return !!uris.length && !this.workspaceUtils.containsRootDirectory(uris);
}
/**
* Execute the command.
*
* @param uris URIs of selected resources.
*/
async execute(uris) {
const distinctUris = uri_1.default.getDistinctParents(uris);
const resolved = {
recursive: true,
useTrash: this.fsPreferences['files.enableTrash'] && distinctUris[0] && this.fileService.hasCapability(distinctUris[0], 4096 /* FileSystemProviderCapabilities.Trash */)
};
if (await this.confirm(distinctUris, resolved)) {
await Promise.all(distinctUris.map(uri => this.delete(uri, resolved)));
}
}
/**
* Display dialog to confirm deletion.
*
* @param uris URIs of selected resources.
*/
confirm(uris, options) {
let title = uris.length === 1 ? nls_1.nls.localizeByDefault('File') : nls_1.nls.localizeByDefault('Files');
if (options.useTrash) {
title = nls_1.nls.localize('theia/workspace/trashTitle', 'Move {0} to Trash', title);
}
else {
title = nls_1.nls.localizeByDefault('Delete {0}', title);
}
return new browser_1.ConfirmDialog({
title,
msg: this.getConfirmMessage(uris)
}).open();
}
/**
* Get the dialog confirmation message for deletion.
*
* @param uris URIs of selected resources.
*/
getConfirmMessage(uris) {
const dirty = this.getDirty(uris);
if (dirty.length) {
if (dirty.length === 1) {
return nls_1.nls.localize('theia/workspace/confirmMessage.dirtySingle', 'Do you really want to delete {0} with unsaved changes?', dirty[0].path.base);
}
return nls_1.nls.localize('theia/workspace/confirmMessage.dirtyMultiple', 'Do you really want to delete {0} files with unsaved changes?', dirty.length);
}
if (uris.length === 1) {
return nls_1.nls.localize('theia/workspace/confirmMessage.uriSingle', 'Do you really want to delete {0}?', uris[0].path.base);
}
if (uris.length > 10) {
return nls_1.nls.localize('theia/workspace/confirmMessage.uriMultiple', 'Do you really want to delete all the {0} selected files?', uris.length);
}
const messageContainer = document.createElement('div');
messageContainer.textContent = nls_1.nls.localize('theia/workspace/confirmMessage.delete', 'Do you really want to delete the following files?');
const list = document.createElement('ul');
list.style.listStyleType = 'none';
for (const uri of uris) {
const listItem = document.createElement('li');
listItem.textContent = uri.path.base;
list.appendChild(listItem);
}
messageContainer.appendChild(list);
return messageContainer;
}
/**
* Get which URI are presently dirty.
*
* @param uris URIs of selected resources.
* @returns An array of dirty URI.
*/
getDirty(uris) {
const dirty = new Map();
const widgets = browser_1.NavigatableWidget.getAffected(browser_1.SaveableWidget.getDirty(this.shell.widgets), uris);
for (const [resourceUri] of widgets) {
dirty.set(resourceUri.toString(), resourceUri);
}
return [...dirty.values()];
}
/**
* Perform deletion of a given URI.
*
* @param uri URI of selected resource.
* @param options deletion options.
*/
async delete(uri, options) {
try {
await Promise.all([
this.closeWithoutSaving(uri),
options.useTrash ? this.moveFileToTrash(uri, options) : this.deleteFilePermanently(uri, options)
]);
}
catch (e) {
console.error(e);
}
}
async deleteFilePermanently(uri, options) {
this.fileService.delete(uri, { ...options, useTrash: false });
}
async moveFileToTrash(uri, options) {
try {
await this.fileService.delete(uri, { ...options, useTrash: true });
}
catch (error) {
console.error('Error deleting with trash:', error);
if (await this.confirmDeletePermanently(uri)) {
return this.deleteFilePermanently(uri, options);
}
}
}
/**
* Display dialog to confirm the permanent deletion of a file.
*
* @param uri URI of selected resource.
*/
async confirmDeletePermanently(uri) {
const title = nls_1.nls.localize('theia/workspace/confirmDeletePermanently.title', 'Error deleting file');
const msg = document.createElement('div');
const question = document.createElement('p');
question.textContent = nls_1.nls.localize('theia/workspace/confirmDeletePermanently.description', 'Failed to delete "{0}" using the Trash. Do you want to permanently delete instead?', uri.path.base);
msg.append(question);
const info = document.createElement('p');
info.textContent = nls_1.nls.localize('theia/workspace/confirmDeletePermanently.solution', 'You can disable the use of Trash in the preferences.');
msg.append(info);
const response = await new browser_1.ConfirmDialog({ title, msg }).open();
return response || false;
}
/**
* Close widget without saving changes.
*
* @param uri URI of a selected resource.
*/
async closeWithoutSaving(uri) {
const toClose = [...browser_1.NavigatableWidget.getAffected(this.shell.widgets, uri)].map(([, widget]) => widget);
await this.shell.closeMany(toClose, { save: false });
}
};
exports.WorkspaceDeleteHandler = WorkspaceDeleteHandler;
tslib_1.__decorate([
(0, inversify_1.inject)(file_service_1.FileService),
tslib_1.__metadata("design:type", file_service_1.FileService)
], WorkspaceDeleteHandler.prototype, "fileService", void 0);
tslib_1.__decorate([
(0, inversify_1.inject)(browser_1.ApplicationShell),
tslib_1.__metadata("design:type", browser_1.ApplicationShell)
], WorkspaceDeleteHandler.prototype, "shell", void 0);
tslib_1.__decorate([
(0, inversify_1.inject)(workspace_utils_1.WorkspaceUtils),
tslib_1.__metadata("design:type", workspace_utils_1.WorkspaceUtils)
], WorkspaceDeleteHandler.prototype, "workspaceUtils", void 0);
tslib_1.__decorate([
(0, inversify_1.inject)(workspace_service_1.WorkspaceService),
tslib_1.__metadata("design:type", workspace_service_1.WorkspaceService)
], WorkspaceDeleteHandler.prototype, "workspaceService", void 0);
tslib_1.__decorate([
(0, inversify_1.inject)(filesystem_preferences_1.FileSystemPreferences),
tslib_1.__metadata("design:type", Object)
], WorkspaceDeleteHandler.prototype, "fsPreferences", void 0);
exports.WorkspaceDeleteHandler = WorkspaceDeleteHandler = tslib_1.__decorate([
(0, inversify_1.injectable)()
], WorkspaceDeleteHandler);
//# sourceMappingURL=workspace-delete-handler.js.map