!7 DynTable > RecentlyDeletedModules { S moduleID; JComponent visualize() { JComponent c = super.visualize(); tablePopupMenuItemsThreaded(table, "Restore module", voidfunc(int row) { restore(row) }); ret northAndCenter( withLabel("Module ID:", jLiveValueTextField_bothWays(dm_fieldLiveValue('moduleID))), c); } L calc() { if (empty(moduleID)) null; ret reversed(map(scanLog_iterator(deletedModulesLogFile(moduleID)), func(S structure) { O mod = safeUnstructure(structure); // old layout: // "c DynamicModule(_className=\"main$TextArea\", created=1529499892012L, frameRect=Rect(h=66, w=130, x=618, y=339), id=384L, moduleID=\"#1016122\", on=t, visible=t)" // new layout: // "hm{deleted=123L, module := c DynamicModule(...)}" long deleted = 0; if (mod instanceof Map) { deleted = toLong(mod/Map.get("deleted")); mod = mod/Map.get("module"); } S className = dynShortName(mod); if (eq(className, "DynamicModule")) className = shortenClassName(getString(mod, '_className)); ret litorderedmap( "Module ID" := joinNempties("/", getString(mod, 'moduleID), className), //"Created" := formatLocalDateWithMinutes(getOptLong(mod, 'created)), "Deleted" := formatLocalDateWithMinutes(deleted), "Data Size" := toK(l(structure)) + " K", "[hidden] md5" := md5(structure)); })); } void restore(int row) { Map map = get(data, row); if (map == null) ret; S md5 = (S) map.get("[hidden] md5"); for (S structure : scanLog_iterator(deletedModulesLogFile(moduleID))) { if (!eq(md5(structure), md5)) continue; print("Found row"); if (structure instanceof Map) structure = getString((Map) structure, 'module); callCreator('restoreModule, structure); } } }