diff --git a/package.json b/package.json
index 94c7215ba..94e757ba8 100644
--- a/package.json
+++ b/package.json
@@ -1028,13 +1028,13 @@
},
{
"command": "code-for-ibmi.launchTerminalPicker",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Launch Terminal Picker",
"category": "IBM i"
},
{
"command": "code-for-ibmi.goToFile",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Go to File...",
"category": "IBM i",
"icon": "$(go-to-file)"
@@ -1162,7 +1162,7 @@
},
{
"command": "code-for-ibmi.runAction",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Run Action...",
"category": "IBM i",
"icon": "$(file-binary)"
@@ -1259,28 +1259,28 @@
},
{
"command": "code-for-ibmi.createMember",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "New Member...",
"category": "IBM i",
"icon": "$(new-file)"
},
{
"command": "code-for-ibmi.copyMember",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Copy...",
"category": "IBM i",
"icon": "$(files)"
},
{
"command": "code-for-ibmi.updateMemberText",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Change Description...",
"category": "IBM i",
"icon": "$(symbol-file)"
},
{
"command": "code-for-ibmi.renameQSYS",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Rename...",
"category": "IBM i",
"icon": "$(files)"
@@ -1293,7 +1293,7 @@
},
{
"command": "code-for-ibmi.uploadAndReplaceMemberAsFile",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Upload and Replace...",
"category": "IBM i"
},
@@ -1325,7 +1325,7 @@
},
{
"command": "code-for-ibmi.deleteIFS",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Delete...",
"category": "IBM i"
},
@@ -1337,14 +1337,14 @@
},
{
"command": "code-for-ibmi.moveIFS",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Rename/Move...",
"category": "IBM i",
"icon": "$(files)"
},
{
"command": "code-for-ibmi.copyIFS",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Copy...",
"category": "IBM i",
"icon": "$(files)"
@@ -1358,21 +1358,21 @@
},
{
"command": "code-for-ibmi.createDirectory",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "New Directory...",
"category": "IBM i",
"icon": "$(new-folder)"
},
{
"command": "code-for-ibmi.createStreamfile",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "New File...",
"category": "IBM i",
"icon": "$(new-file)"
},
{
"command": "code-for-ibmi.uploadStreamfile",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Upload...",
"category": "IBM i",
"icon": "$(cloud-upload)"
@@ -1382,11 +1382,11 @@
"title": "Deploy Workspace",
"category": "IBM i",
"icon": "$(cloud-upload)",
- "enablement": "code-for-ibmi:connected && workspaceFolderCount >= 1"
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly && workspaceFolderCount >= 1"
},
{
"command": "code-for-ibmi.setDeployLocation",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Set Deploy Workspace Location",
"category": "IBM i",
"icon": "$(cloud-upload)"
@@ -1476,7 +1476,7 @@
},
{
"command": "code-for-ibmi.objectBrowser.delete",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Delete...",
"category": "IBM i",
"icon": "$(remove)"
@@ -1537,35 +1537,35 @@
},
{
"command": "code-for-ibmi.createSourceFile",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "New Source File...",
"category": "IBM i",
"icon": "$(new-file)"
},
{
"command": "code-for-ibmi.createLibrary",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "New Library...",
"category": "IBM i",
"icon": "$(file-directory-create)"
},
{
"command": "code-for-ibmi.changeObjectDesc",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Change Description...",
"category": "IBM i",
"icon": "$(symbol-file)"
},
{
"command": "code-for-ibmi.copyObject",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Copy...",
"category": "IBM i",
"icon": "$(symbol-file)"
},
{
"command": "code-for-ibmi.moveObject",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Move...",
"category": "IBM i",
"icon": "$(symbol-file)"
@@ -1599,6 +1599,7 @@
},
{
"command": "code-for-ibmi.openTerminalHere",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"title": "Open Terminal Here",
"category": "IBM i"
},
@@ -1616,7 +1617,7 @@
{
"command": "code-for-ibmi.edit",
"title": "Edit",
- "enablement": "code-for-ibmi:connected",
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly",
"category": "IBM i"
},
{
@@ -1692,7 +1693,7 @@
"title": "Reset keyboard",
"category": "IBM i",
"icon": "$(keyboard)",
- "enablement": "code-for-ibmi:connected"
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly"
},
{
"command": "code-for-ibmi.testing.connectWithFixture",
@@ -1706,7 +1707,7 @@
"title": "Generate binder source",
"category": "IBM i",
"icon": "$(plus)",
- "enablement": "code-for-ibmi:connected"
+ "enablement": "code-for-ibmi:connected && !code-for-ibmi:isReadonly"
}
],
"keybindings": [
@@ -1719,7 +1720,7 @@
"command": "code-for-ibmi.launchDeploy",
"key": "ctrl+shift+e",
"mac": "cmd+shift+e",
- "when": "workspaceFolderCount >= 1 && code-for-ibmi:connected"
+ "when": "workspaceFolderCount >= 1 && code-for-ibmi:connected && !code-for-ibmi:isReadonly"
},
{
"command": "code-for-ibmi.goToFile",
diff --git a/schemas/settings.json b/schemas/settings.json
index 965fd6277..9c0c35f64 100644
--- a/schemas/settings.json
+++ b/schemas/settings.json
@@ -7,7 +7,7 @@
"readOnlyMode": {
"type": "boolean",
"default": false,
- "description": "Always open source members and IFS files in read-only mode."
+ "description": "Always open source members and IFS files in read-only mode. Content on the server can not be changed."
},
"tempLibrary": {
"type": "string",
diff --git a/src/filesystems/ifsFs.ts b/src/filesystems/ifsFs.ts
index 0f25736e5..7efeec8d2 100644
--- a/src/filesystems/ifsFs.ts
+++ b/src/filesystems/ifsFs.ts
@@ -70,6 +70,10 @@ export class IFSFS implements vscode.FileSystemProvider {
const path = uri.path;
const connection = instance.getConnection();
if (connection) {
+ const readonly = connection.getConfig().readOnlyMode;
+ if (readonly) {
+ throw new FileSystemError("Connection is in readonly mode");
+ }
const contentApi = connection.getContent();
if (!content.length) { //Coming from "Save as"
this.savedAsFiles.add(path);
diff --git a/src/filesystems/local/deployment.ts b/src/filesystems/local/deployment.ts
index 1a01606ea..ea2e8ef9d 100644
--- a/src/filesystems/local/deployment.ts
+++ b/src/filesystems/local/deployment.ts
@@ -56,8 +56,12 @@ export namespace Deployment {
const storage = instance.getStorage();
if (workspaces && connection && storage) {
- if (workspaces.length > 0) {
+ const config = connection.getConfig();
+
+ if (workspaces.length > 0 && !config.readOnlyMode) {
button.show();
+ } else {
+ button.hide();
}
const existingPaths = storage.getDeployment();
diff --git a/src/instantiate.ts b/src/instantiate.ts
index d21254abc..e0f61ceae 100644
--- a/src/instantiate.ts
+++ b/src/instantiate.ts
@@ -105,12 +105,12 @@ async function updateConnectedBar() {
if (connection) {
const config = connection.getConfig();
connectedBarItem.text = `$(${config.readOnlyMode ? "lock" : "settings-gear"}) ${config.name}`;
-
+ const terminalMenuItem = config.readOnlyMode ? `` : `[$(terminal) Terminals](command:code-for-ibmi.launchTerminalPicker)`;
const debugRunning = await isDebugEngineRunning();
connectedBarItem.tooltip = new vscode.MarkdownString([
`[$(settings-gear) Settings](command:code-for-ibmi.showAdditionalSettings)`,
`[$(file-binary) Actions](command:code-for-ibmi.showActionsMaintenance)`,
- `[$(terminal) Terminals](command:code-for-ibmi.launchTerminalPicker)`,
+ terminalMenuItem,
debugPTFInstalled(connection) ?
`[$(${debugRunning ? "bug" : "debug"}) Debugger ${((await getDebugServiceDetails(connection)).version)} (${debugRunning ? "on" : "off"})](command:ibmiDebugBrowser.focus)`
:
@@ -129,6 +129,8 @@ async function onConnected() {
updateConnectedBar();
+ vscode.commands.executeCommand(`setContext`, `code-for-ibmi:isReadonly`, config?.readOnlyMode);
+
// Enable the profile view if profiles exist.
vscode.commands.executeCommand(`setContext`, `code-for-ibmi:hasProfiles`, (config?.connectionProfiles || []).length > 0);
}
@@ -154,4 +156,3 @@ async function onDisconnected() {
connectedBarItem,
].forEach(barItem => barItem.hide())
}
-
diff --git a/src/webviews/settings/index.ts b/src/webviews/settings/index.ts
index f5974bfca..889b1fec9 100644
--- a/src/webviews/settings/index.ts
+++ b/src/webviews/settings/index.ts
@@ -68,7 +68,7 @@ export class SettingsUI {
if (serverConfig && serverConfig.codefori) {
for (const field of currentSection.fields) {
if (!field.id) continue;
-
+
if (serverConfig.codefori[field.id] !== undefined) {
field.readonly = true;
}
@@ -76,7 +76,7 @@ export class SettingsUI {
}
}
- const restartFields = [`showDescInLibList`, `tempDir`, `debugCertDirectory`];
+ const restartFields = [`readOnlyMode`, `showDescInLibList`, `tempDir`, `debugCertDirectory`];
let restart = false;
const featuresTab = new Section();
@@ -88,6 +88,8 @@ export class SettingsUI {
}
featuresTab
+ .addCheckbox(`readOnlyMode`, `Read only mode`, `When enabled, content on the server can not be changed. Requires restart when changed.`, config.readOnlyMode)
+ .addHorizontalRule()
.addCheckbox(`quickConnect`, `Quick Connect`, `When enabled, server settings from previous connection will be used, resulting in much quicker connection. If server settings are changed, right-click the connection in Connection Browser and select Connect and Reload Server Settings
to refresh the cache.`, config.quickConnect)
.addCheckbox(`showDescInLibList`, `Show description of libraries in User Library List view`, `When enabled, library text and attribute will be shown in User Library List. It is recommended to also enable SQL for this.`, config.showDescInLibList)
.addCheckbox(`showHiddenFiles`, `Show hidden files and directories in IFS browser.`, `When disabled, hidden files and directories (i.e. names starting with '.') will not be shown in the IFS browser, except for special config files.`, config.showHiddenFiles)
@@ -154,7 +156,6 @@ export class SettingsUI {
}
], `Set your Default Deployment Method. This is used when deploying from the local workspace to the server.`)
.addHorizontalRule()
- .addCheckbox(`readOnlyMode`, `Read only mode`, `When enabled, source members and IFS files will always be opened in read-only mode.`, config.readOnlyMode)
.addInput(`protectedPaths`, `Protected paths`, `A comma separated list of libraries and/or IFS directories whose members will always be opened in read-only mode. (Example: QGPL, /home/QSECOFR, MYLIB, /QIBM
)`, { default: config.protectedPaths.join(`, `) });
setFieldsReadOnly(sourceTab);
@@ -204,7 +205,7 @@ export class SettingsUI {
.set("Debug port", config.debugPort);
debugServiceConfig.set("SEP debug port", config.debugSepPort)
-
+
debuggerTab.addParagraph(`
${label}
: ${value}*PROD
) libraries.`, config.debugUpdateProductionFiles)
@@ -338,7 +339,7 @@ export class SettingsUI {
}
}
- if (restartFields.some(item => data[item] && data[item] !== config[item])) {
+ if (restartFields.some(item => data[item] !== config[item])) {
restart = true;
}
@@ -395,7 +396,7 @@ export class SettingsUI {
.addPassword(`password`, `${vscode.l10n.t(`Password`)}${storedPassword ? ` (${vscode.l10n.t(`stored`)})` : ``}`, vscode.l10n.t("Only provide a password if you want to update an existing one or set a new one."))
.addFile(`privateKeyPath`, `${vscode.l10n.t(`Private Key`)}${privateKeyPath ? ` (${vscode.l10n.t(`Private Key`)}: ${privateKeyPath})` : ``}`, privateKeyWarning + vscode.l10n.t("Only provide a private key if you want to update from the existing one or set one.") + '