Explorar el Código

handle empty File or FileList params

Alexander Rose hace 5 años
padre
commit
c7f6041aa4

+ 4 - 0
src/apps/viewer/extensions/cellpack/model.ts

@@ -345,6 +345,10 @@ async function loadPackings(plugin: PluginContext, runtime: RuntimeContext, stat
             .apply(StateTransforms.Data.Download, { url, isBinary: false, label: params.source.params }, { state: { isGhost: true } })
     } else {
         const file = params.source.params
+        if (file === null) {
+            plugin.log.error('No file selected')
+            return
+        }
         cellPackJson = state.build().toRoot()
             .apply(StateTransforms.Data.ReadFile, { file, isBinary: false, label: file.name }, { state: { isGhost: true } })
     }

+ 5 - 3
src/apps/viewer/extensions/cellpack/state.ts

@@ -70,9 +70,11 @@ const StructureFromCellpack = PluginStateTransform.BuiltIn({
         return Task.create('Structure from CellPack', async ctx => {
             const packing = a.data.packings[params.packing]
             const ingredientFiles: IngredientFiles = {}
-            for (let i = 0, il = params.ingredientFiles.length; i < il; ++i) {
-                const file = params.ingredientFiles.item(i)
-                if (file) ingredientFiles[file.name] = file
+            if (params.ingredientFiles !== null) {
+                for (let i = 0, il = params.ingredientFiles.length; i < il; ++i) {
+                    const file = params.ingredientFiles.item(i)
+                    if (file) ingredientFiles[file.name] = file
+                }
             }
             const structure = await createStructureFromCellPack(packing, params.baseUrl, ingredientFiles).runInContext(ctx)
             return new PSO.Molecule.Structure(structure, { label: packing.name })

+ 1 - 0
src/mol-model-props/rcsb/validation-report.ts

@@ -111,6 +111,7 @@ namespace ValidationReport {
     }
 
     export async function open(ctx: CustomProperty.Context, model: Model, props: FileSourceProps): Promise<ValidationReport> {
+        if (props.input === null) throw new Error('No file given')
         const xml = await readFromFile(props.input, 'xml').runInContext(ctx.runtime)
         return fromXml(xml, model)
     }

+ 5 - 3
src/mol-plugin-state/actions/data-format.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -132,14 +132,16 @@ export const OpenFiles = StateAction.build({
     }
 })(({ params, state }, plugin: PluginContext) => Task.create('Open Files', async taskCtx => {
     await state.transaction(async () => {
+        if (params.files === null) {
+            plugin.log.error('No file(s) selected')
+            return
+        }
         for (let i = 0, il = params.files.length; i < il; ++i) {
             try {
                 const file = params.files[i]
                 const info = getFileInfo(file)
                 const isBinary = plugin.dataFormat.registry.binaryExtensions.has(info.ext)
                 const { data } = await plugin.builders.data.readFile({ file, isBinary });
-                // const data = state.build().toRoot().apply(StateTransforms.Data.ReadFile, { file, isBinary });
-                // const dataStateObject = await state.updateTree(data).runInContext(taskCtx);
                 const provider = params.format === 'auto'
                     ? plugin.dataFormat.registry.auto(info, data.cell?.obj!)
                     : plugin.dataFormat.registry.get(params.format)

+ 1 - 1
src/mol-plugin-state/builder/data.ts

@@ -34,7 +34,7 @@ export class DataBuilder {
 
     async readFile(params: StateTransformer.Params<ReadFile>, options?: Partial<StateTransform.Options>) {
         const data = this.dataState.build().toRoot().apply(ReadFile, params, options);
-        const fileInfo = getFileInfo(params.file);
+        const fileInfo = getFileInfo(params.file || '');
         await this.plugin.updateDataState(data, { revertOnError: true });
         return { data: data.selector, fileInfo };
     }

+ 8 - 4
src/mol-plugin-state/transforms/data.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -11,7 +11,7 @@ import { Task } from '../../mol-task';
 import { CIF } from '../../mol-io/reader/cif'
 import { PluginContext } from '../../mol-plugin/context';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
-import { StateTransformer } from '../../mol-state';
+import { StateTransformer, StateObject } from '../../mol-state';
 import { readFromFile, ajaxGetMany } from '../../mol-util/data-source';
 import * as CCP4 from '../../mol-io/reader/ccp4/parser'
 import * as DSN6 from '../../mol-io/reader/dsn6/parser'
@@ -143,8 +143,12 @@ const ReadFile = PluginStateTransform.BuiltIn({
         isBinary: PD.Optional(PD.Boolean(false, { description: 'If true, open file as as binary (string otherwise)' }))
     }
 })({
-    apply({ params: p }) {
+    apply({ params: p }, plugin: PluginContext) {
         return Task.create('Open File', async ctx => {
+            if (p.file === null) {
+                plugin.log.error('No file(s) selected')
+                return StateObject.Null;
+            }
             const data = await readFromFile(p.file, p.isBinary ? 'binary' : 'string').runInContext(ctx);
             return p.isBinary
                 ? new SO.Data.Binary(data as Uint8Array, { label: p.label ? p.label : p.file.name })
@@ -153,7 +157,7 @@ const ReadFile = PluginStateTransform.BuiltIn({
     },
     update({ oldParams, newParams, b }) {
         if (oldParams.label !== newParams.label) {
-            (b.label as string) = newParams.label || oldParams.file.name;
+            (b.label as string) = newParams.label || oldParams.file?.name || '';
             return StateTransformer.UpdateResult.Updated;
         }
         return StateTransformer.UpdateResult.Unchanged;

+ 4 - 4
src/mol-util/param-definition.ts

@@ -147,22 +147,22 @@ export namespace ParamDefinition {
         return setInfo<Mat4>({ type: 'mat4', defaultValue }, info)
     }
 
-    export interface FileParam extends Base<File> {
+    export interface FileParam extends Base<File | null> {
         type: 'file'
         accept?: string
     }
     export function File(info?: Info & { accept?: string, multiple?: boolean }): FileParam {
-        const ret = setInfo<FileParam>({ type: 'file', defaultValue: void 0 as any }, info);
+        const ret = setInfo<FileParam>({ type: 'file', defaultValue: null }, info);
         if (info?.accept) ret.accept = info.accept;
         return ret;
     }
 
-    export interface FileListParam extends Base<FileList> {
+    export interface FileListParam extends Base<FileList | null> {
         type: 'file-list'
         accept?: string
     }
     export function FileList(info?: Info & { accept?: string, multiple?: boolean }): FileListParam {
-        const ret = setInfo<FileListParam>({ type: 'file-list', defaultValue: void 0 as any }, info);
+        const ret = setInfo<FileListParam>({ type: 'file-list', defaultValue: null }, info);
         if (info?.accept) ret.accept = info.accept;
         return ret;
     }