diff --git a/.gitignore b/.gitignore index 0ca13cda..77c73061 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ deploy /bin +*~ + + diff --git a/README.md b/README.md index 897eeb06..386f64fa 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Cyclist is a visual interface companion for the Cyclus project. It provides an i ### Dependencies: | package | version | download | ------- | ------- | -------- -| Java | 8.0 | https://jdk8.java.net/download.html +| Java | 8.0_25 | http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html | JavaFX | 8.0 | (JavaFX is part of Java 8) | Ant | 1.9+ | http://ant.apache.org/bindownload.cgi diff --git a/build.xml b/build.xml index 29a3adba..14799d7e 100644 --- a/build.xml +++ b/build.xml @@ -5,6 +5,7 @@ + @@ -35,7 +36,7 @@ - + @@ -45,7 +46,7 @@ - + @@ -126,6 +127,7 @@ + @@ -160,7 +162,6 @@ - @@ -168,12 +169,6 @@ - - - - - - @@ -212,7 +207,7 @@ - + @@ -224,6 +219,7 @@ + + + diff --git a/cyclist/.classpath b/cyclist/.classpath index a91821f3..f4206804 100644 --- a/cyclist/.classpath +++ b/cyclist/.classpath @@ -5,16 +5,16 @@ - - - + - + + + diff --git a/cyclist/.classpath.orig b/cyclist/.classpath.orig index b27ba589..bd8ee54a 100644 --- a/cyclist/.classpath.orig +++ b/cyclist/.classpath.orig @@ -5,20 +5,19 @@ - - - - - -<<<<<<< HEAD + + + - +<<<<<<< HEAD ======= ->>>>>>> upstream/master + + +>>>>>>> d1089b11dcdf5ed055565977412869ee90c1a44b diff --git a/cyclist/.classpath~ b/cyclist/.classpath~ deleted file mode 100644 index ae6dc9ff..00000000 --- a/cyclist/.classpath~ +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/cyclist/cyclus.sqlite b/cyclist/cyclus.sqlite deleted file mode 100644 index 1b9a0e4b..00000000 Binary files a/cyclist/cyclus.sqlite and /dev/null differ diff --git a/cyclist/default-metadata.json b/cyclist/default-metadata.json deleted file mode 100644 index 5edb40ef..00000000 --- a/cyclist/default-metadata.json +++ /dev/null @@ -1,713 +0,0 @@ -{ - "annotations": { - ":agents:KFacility": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader" - ], - "doc": "A facility designed for integration tests that both provides and consumes commodities. It changes its request and offer amounts based on a power law with respect to time.", - "entity": "facility", - "name": "cyclus::KFacility", - "parents": ["cyclus::Facility"], - "vars": { - "current_capacity": { - "default": 0, - "doc": "number of output commodity units that can be supplied at the current time step (infinite capacity can be represented by a very large number", - "index": 5, - "tooltip": "current output capacity", - "type": "double" - }, - "in_capacity": { - "doc": "number of commodity units that can be taken at each time step (infinite capacity can be represented by a very large number", - "index": 3, - "tooltip": "input commodity capacity", - "type": "double" - }, - "in_commod": { - "doc": "commodity that the k-facility consumes", - "index": 0, - "schematype": "token", - "tooltip": "input commodity", - "type": "std::string", - "uitype": "incommodity" - }, - "inventory": { - "capacity": "max_inv_size", - "index": 7, - "type": "cyclus::toolkit::ResourceBuff" - }, - "k_factor_in": { - "doc": "conversion factor that governs the behavior of the k-facility's input commodity capacity", - "index": 8, - "tooltip": "input k-factor", - "type": "double" - }, - "k_factor_out": { - "doc": "conversion factor that governs the behavior of the k-facility's output commodity capacity", - "index": 9, - "tooltip": "output k-factor", - "type": "double" - }, - "max_inv_size": { - "default": 1.000000000000000e+299, - "doc": "total maximum inventory size of the k-facility", - "index": 6, - "tooltip": "k-facility maximum inventory size", - "type": "double" - }, - "out_capacity": { - "doc": "number of commodity units that can be supplied at each time step (infinite capacity can be represented by a very large number", - "index": 4, - "tooltip": "output commodity capacity", - "type": "double" - }, - "out_commod": { - "doc": "commodity that the k-facility supplies", - "index": 1, - "schematype": "token", - "tooltip": "output commodity", - "type": "std::string", - "uitype": "outcommodity" - }, - "recipe_name": { - "doc": "recipe name for the k-facility's in-commodity", - "index": 2, - "schematype": "token", - "shape": [50], - "tooltip": "in-commodity recipe name", - "type": "std::string", - "uitype": "recipe" - } - } - }, - ":agents:NullInst": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Ider", - "cyclus::Institution", - "cyclus::StateWrangler", - "cyclus::TimeListener" - ], - "doc": "An instition that owns facilities in the simulation but exhibits null behavior. No parameters are given when using the null institution.", - "entity": "institution", - "name": "cyclus::NullInst", - "parents": ["cyclus::Institution"], - "vars": {} - }, - ":agents:NullRegion": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Ider", - "cyclus::Region", - "cyclus::StateWrangler", - "cyclus::TimeListener" - ], - "doc": "A region that owns the simulation's institutions but exhibits null behavior. No parameters are given when using the null region.", - "entity": "region", - "name": "cyclus::NullRegion", - "parents": ["cyclus::Region"], - "vars": {} - }, - ":agents:Predator": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader" - ], - "doc": "A facility that represents predators in the Lotka-Volterra integration tests", - "entity": "facility", - "name": "cyclus::Predator", - "parents": ["cyclus::Facility"], - "vars": { - "age": { - "default": 0, - "doc": "age of predator at beginning of simulation", - "index": 7, - "tooltip": "predator age", - "type": "int" - }, - "birth_and_death": { - "default": 0, - "doc": "whether or not simultaneous birth and and death are allowed (i.e., can a facility give birth and die in the same time step?)", - "index": 11, - "tooltip": "simultaneous birth and death?", - "type": "bool" - }, - "commod": { - "doc": "commodity that the predator supplies", - "index": 0, - "schematype": "token", - "tooltip": "predator commodity", - "type": "std::string", - "uitype": "outcommodity" - }, - "consumed": { - "default": 0, - "doc": "how many units of prey consumed per time step", - "index": 12, - "tooltip": "prey consumed", - "type": "double" - }, - "dead": { - "default": 0, - "doc": "flag for whether predator is currently dead", - "index": 9, - "tooltip": "dead?", - "type": "bool" - }, - "full": { - "default": 1, - "doc": "how many units of prey a predator consumes until it is satisfied", - "index": 2, - "tooltip": "feast size", - "type": "double" - }, - "hunt_cap": { - "default": 1, - "doc": "how many units of prey a predator can catch during a hunt", - "index": 3, - "tooltip": "hunting yield", - "type": "double" - }, - "hunt_factor": { - "default": 0, - "doc": "whether or not to base hunting success on relative predator/prey populations", - "index": 10, - "tooltip": "hunting success factor", - "type": "bool" - }, - "hunt_freq": { - "default": 1, - "doc": "how often a predator needs to hunt", - "index": 4, - "tooltip": "hunting frequency", - "type": "int" - }, - "lifespan": { - "default": 1, - "doc": "how long a predator lives", - "index": 8, - "tooltip": "predator lifespan", - "type": "int" - }, - "nchildren": { - "default": 1, - "doc": "number of predator children born at each birthing instance", - "index": 6, - "tooltip": "number of children", - "type": "double" - }, - "prey": { - "doc": "prey that the predator hunts", - "index": 1, - "schematype": "token", - "tooltip": "predator's prey", - "type": "std::string", - "uitype": "incommodity" - }, - "success": { - "default": 1, - "doc": "fraction of hunting success on a scale from 0 to 1", - "index": 5, - "tooltip": "hunting success fraction", - "type": "double" - } - } - }, - ":agents:Prey": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader" - ], - "doc": "A facility that represents prey in the Lotka-Volterra integration tests", - "entity": "facility", - "name": "cyclus::Prey", - "parents": ["cyclus::Facility"], - "vars": { - "age": { - "default": 0, - "doc": "age of prey at start of simulation", - "index": 3, - "tooltip": "prey age", - "type": "int" - }, - "birth_and_death": { - "default": 1, - "doc": "whether or not simultaneous birth and and death are allowed (i.e., can a facility give birth and die in the same time step?)", - "index": 5, - "tooltip": "simultaneous birth and death?", - "type": "bool" - }, - "birth_freq": { - "default": 1, - "doc": "number of time steps between birth of children", - "index": 1, - "tooltip": "birth frequency", - "type": "int" - }, - "commod": { - "index": 0, - "schematype": "token", - "type": "std::string", - "uitype": "outcommodity" - }, - "dead": { - "default": 0, - "doc": "flag for whether prey is currently dead", - "index": 4, - "tooltip": "dead?", - "type": "bool" - }, - "nchildren": { - "default": 1, - "doc": "number of children born at each birthing instance", - "index": 2, - "tooltip": "number of children", - "type": "int" - } - } - }, - ":agents:Sink": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader" - ], - "doc": "A minimum implementation sink facility that accepts specified amounts of commodities from other agents", - "entity": "facility", - "name": "cyclus::Sink", - "parents": ["cyclus::Facility"], - "vars": { - "capacity": { - "doc": "capacity the sink facility can accept at each time step", - "index": 1, - "tooltip": "sink capacity", - "type": "double" - }, - "in_commods": { - "doc": "commodities that the sink facility accepts", - "index": 0, - "schematype": "token", - "tooltip": "input commodities for the sink", - "type": ["std::vector", "std::string"], - "uitype": "incommodity" - }, - "inventory": { - "capacity": "max_inv_size", - "index": 3, - "type": "cyclus::toolkit::ResourceBuff" - }, - "max_inv_size": { - "default": 1.000000000000000e+299, - "doc": "total maximum inventory size of sink facility", - "index": 2, - "tooltip": "sink maximum inventory size", - "type": "double" - } - } - }, - ":agents:Source": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader" - ], - "doc": "A minimum implementation source facility that provides a commodity with a given capacity", - "entity": "facility", - "name": "cyclus::Source", - "parents": ["cyclus::Facility"], - "vars": { - "capacity": { - "doc": "amount of commodity that can be supplied at each time step", - "index": 2, - "tooltip": "source capacity", - "type": "double" - }, - "commod": { - "doc": "commodity that the source facility supplies", - "index": 0, - "schematype": "token", - "tooltip": "source commodity", - "type": "std::string", - "uitype": "outcommodity" - }, - "recipe_name": { - "doc": "recipe name for source facility's commodity", - "index": 1, - "schematype": "token", - "tooltip": "commodity recipe name", - "type": "std::string", - "uitype": "recipe" - } - } - }, - ":cycaless:BatchReactor": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader", - "cyclus::toolkit::AgentManaged", - "cyclus::toolkit::CommodityProducer" - ], - "doc": "A reactor facility that has three storage areas that hold batches of materials: reserves, core, and storage. It can manage multiple input-output commodity pairs.", - "entity": "facility", - "name": "cycaless::BatchReactor", - "niche": "reactor", - "parents": ["cyclus::Facility", "cyclus::toolkit::CommodityProducer"], - "vars": { - "crctx_": { - "alias": "fuel", - "doc": "in-out commodity and fuel recipe mappings", - "index": 0, - "type": ["std::vector", "CommodityRecipeContext"], - "uitype": ["oneormore", "incommodity", "recipe", "outcommodity", "recipe"] - }, - "fuel": "crctx_" - } - }, - ":cycaless:DeployInst": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Ider", - "cyclus::Institution", - "cyclus::StateWrangler", - "cyclus::TimeListener" - ], - "doc": "An institution that owns, operates, and deploys facilities manually defined in the input file.", - "entity": "institution", - "name": "cycamore::DeployInst", - "parents": ["cyclus::Institution"], - "vars": { - "build_sched_": { - "alias": "buildorder", - "doc": "list of times to build specific facilities", - "index": 0, - "type": ["std::map", "int", ["std::vector", "std::string"]], - "uitype": ["oneormore", "prototype", "null", "null"] - }, - "buildorder": "build_sched_" - } - }, - ":cycamore:BatchReactor": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader", - "cyclus::toolkit::AgentManaged", - "cyclus::toolkit::CommodityProducer" - ], - "doc": "A reactor facility that has three storage areas that hold batches of materials: reserves, core, and storage. It can manage multiple input-output commodity pairs.", - "entity": "facility", - "name": "cycamore::BatchReactor", - "parents": ["cyclus::Facility", "cyclus::toolkit::CommodityProducer"], - "vars": {} - }, - ":cycamore:DeployInst": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Ider", - "cyclus::Institution", - "cyclus::StateWrangler", - "cyclus::TimeListener" - ], - "doc": "An institution that owns, operates, and deploys facilities manually defined in the input file.", - "entity": "institution", - "name": "cycamore::DeployInst", - "parents": ["cyclus::Institution"], - "vars": {} - }, - ":cycamore:EnrichmentFacility": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader" - ], - "doc": "An enrichment facility that intakes a commodity (usually natural uranium) and supplies a user-specified enriched product based on SWU capacity", - "entity": "facility", - "name": "cycamore::EnrichmentFacility", - "niche": "enrichment", - "parents": ["cyclus::Facility"], - "vars": { - "current_swu_capacity": { - "derived_init": "current_swu_capacity = swu_capacity;", - "index": 7, - "type": "double" - }, - "feed_assay": { - "derived_init": "cyclus::Material::Ptr feed = cyclus::Material::CreateUntracked(0, context()->GetRecipe(in_recipe)); feed_assay = cyclus::toolkit::UraniumAssay(feed);", - "doc": "feed assay for the enrichment process", - "index": 8, - "tooltip": "feed assay", - "type": "double" - }, - "in_commod": { - "doc": "commodity that the enrichment facility accepts", - "index": 0, - "tooltip": "input commodity", - "type": "std::string", - "uitype": "incommodity" - }, - "in_recipe": { - "doc": "recipe for enrichment facility's input commodity", - "index": 2, - "tooltip": "input commodity recipe", - "type": "std::string", - "uitype": "recipe" - }, - "initial_reserves": { - "default": 0, - "doc": "amount of natural uranium stored at the enrichment facility at the beginning of the simulation", - "index": 6, - "tooltip": "initial uranium reserves", - "type": "double" - }, - "inventory": { - "capacity": "max_inv_size", - "index": 9, - "type": "cyclus::toolkit::ResourceBuff" - }, - "max_inv_size": { - "default": 1.000000000000000e+299, - "doc": "maximum inventory capacity of natural uranium in the enrichment facility", - "index": 5, - "tooltip": "maximum inventory size", - "type": "double" - }, - "out_commod": { - "doc": "commodity that the enrichment facility supplies", - "index": 1, - "tooltip": "output commodity", - "type": "std::string", - "uitype": "outcommodity" - }, - "swu_capacity": { - "default": 1.000000000000000e+299, - "doc": "separative work unit (SWU) capcity of enrichment facility", - "index": 4, - "tooltip": "SWU capacity", - "type": "double" - }, - "tails_assay": { - "default": 0.030, - "doc": "tails assay from the enrichment process", - "index": 3, - "tooltip": "tails assay", - "type": "double" - } - } - }, - ":cycamore:GrowthRegion": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Ider", - "cyclus::Region", - "cyclus::StateWrangler", - "cyclus::TimeListener" - ], - "doc": "A region that governs a scenario in which there is growth in demand for a commodity. ", - "entity": "region", - "name": "cycamore::GrowthRegion", - "parents": ["cyclus::Region"], - "vars": { - "commodity_name": { - "doc": "name of the commodity experiencing a growth in demand", - "index": 0, - "tooltip": "commodity in demand", - "type": "std::string", - "uitype": "commodity" - }, - "demand_params": { - "doc": "parameters that define the behavior of the demand type function", - "index": 2, - "tooltip": "demand parameters", - "type": ["std::vector", "std::string"] - }, - "demand_times": { - "doc": "vector describing the length of times regarding the piecewise demand type", - "index": 3, - "tooltip": "demand times", - "type": ["std::vector", "int"] - }, - "demand_types": { - "doc": "mathematical description of demand growth (i.e., linear, exponential, piecewise)", - "index": 1, - "tooltip": "demand type", - "type": ["std::vector", "std::string"] - } - } - }, - ":cycamore:ManagerInst": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Ider", - "cyclus::Institution", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::toolkit::AgentManaged", - "cyclus::toolkit::Builder", - "cyclus::toolkit::CommodityProducerManager" - ], - "doc": "An institution that owns and operates a manually entered list of facilities in the input file", - "entity": "institution", - "name": "cycamore::ManagerInst", - "parents": [ - "cyclus::Institution", - "cyclus::toolkit::Builder", - "cyclus::toolkit::CommodityProducerManager" - ], - "vars": { - "prototypes": { - "doc": "a facility to be managed by the institution", - "index": 0, - "tooltip": "facility prototypes", - "type": ["std::vector", "std::string"], - "uitype": "prototype" - } - } - }, - ":cycamore:Sink": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader" - ], - "doc": "A sink facility that accepts specified amounts of commodities from other agents", - "entity": "facility", - "name": "cycamore::Sink", - "parents": ["cyclus::Facility"], - "vars": { - "capacity": { - "default": 1.000000000000000e+299, - "doc": "capacity the sink facility can accept at each time step", - "index": 1, - "tooltip": "sink capacity", - "type": "double" - }, - "in_commods": { - "doc": "commodities that the sink facility accepts", - "index": 0, - "tooltip": "input commodities", - "type": ["std::vector", "std::string"], - "uitype": ["oneormore", "incommodity"] - }, - "inventory": { - "capacity": "max_inv_size", - "index": 3, - "type": "cyclus::toolkit::ResourceBuff" - }, - "max_inv_size": { - "default": 1.000000000000000e+299, - "doc": "total maximum inventory size of sink facility", - "index": 2, - "tooltip": "sink maximum inventory size", - "type": "double" - } - } - }, - ":cycamore:Source": { - "all_parents": [ - "cyclus::Agent", - "cyclus::Facility", - "cyclus::Ider", - "cyclus::StateWrangler", - "cyclus::TimeListener", - "cyclus::Trader", - "cyclus::toolkit::AgentManaged", - "cyclus::toolkit::CommodityProducer" - ], - "doc": "A source facility that provides a commodity with a given capacity", - "entity": "facility", - "name": "cycamore::Source", - "parents": ["cyclus::Facility", "cyclus::toolkit::CommodityProducer"], - "vars": { - "capacity": { - "default": 1.000000000000000e+299, - "doc": "amount of commodity that can be supplied at each time step", - "index": 2, - "tooltip": "source capacity", - "type": "double" - }, - "current_capacity": {"derived_init": "current_capacity = capacity;", "index": 3, "type": "double"}, - "out_commod": { - "doc": "output commodity that the source facility supplies", - "index": 0, - "tooltip": "source output commodity", - "type": "std::string", - "uitype": "outcommodity" - }, - "recipe_name": { - "doc": "recipe name for source facility's commodity", - "index": 1, - "tooltip": "commodity recipe name", - "type": "std::string", - "uitype": "recipe" - } - } - } - }, - "schema": { - ":agents:KFacility": "\n\n \n\n\n \n\n\n \n\n\n \n\n\n \n\n\n \n \n \n\n\n \n \n \n\n\n \n\n\n \n\n\n", - ":agents:NullInst": "", - ":agents:NullRegion": "", - ":agents:Predator": "\n\n \n\n\n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n", - ":agents:Prey": "\n\n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n", - ":agents:Sink": "\n\n \n \n \n \n \n\n\n \n\n\n \n \n \n\n\n", - ":agents:Source": "\n\n \n\n\n \n\n\n \n\n\n", - ":cycaless:BatchReactor": " \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", - ":cycaless:DeployInst": " \n \n \n \n \n \n \n \n \n \n \n \n \n", - ":cycamore:BatchReactor": " \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", - ":cycamore:DeployInst": " \n \n \n \n \n \n \n \n \n \n \n \n \n", - ":cycamore:EnrichmentFacility": "\n\n \n\n\n \n\n\n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n", - ":cycamore:GrowthRegion": "\n\n \n\n\n \n \n \n \n \n\n\n \n \n \n \n \n\n\n \n \n \n \n \n\n\n", - ":cycamore:ManagerInst": "\n\n \n \n \n \n \n\n\n", - ":cycamore:Sink": "\n\n \n \n \n \n \n\n\n \n \n \n\n\n \n \n \n\n\n", - ":cycamore:Source": "\n\n \n\n\n \n\n\n \n \n \n\n\n" - }, - "specs": [ - ":agents:KFacility", - ":agents:NullInst", - ":agents:NullRegion", - ":agents:Predator", - ":agents:Prey", - ":agents:Sink", - ":agents:Source", - ":cycaless:BatchReactor", - ":cycaless:DeployInst", - ":cycamore:BatchReactor", - ":cycamore:DeployInst", - ":cycamore:EnrichmentFacility", - ":cycamore:GrowthRegion", - ":cycamore:ManagerInst", - ":cycamore:Sink", - ":cycamore:Source" - ] -} diff --git a/cyclist/externalApps/cycpost-darwin-386 b/cyclist/externalApps/cycpost-darwin-386 index b51c076a..a61db23d 100644 Binary files a/cyclist/externalApps/cycpost-darwin-386 and b/cyclist/externalApps/cycpost-darwin-386 differ diff --git a/cyclist/externalApps/cycpost-darwin-amd64 b/cyclist/externalApps/cycpost-darwin-amd64 index ac94dcf4..22e5d32c 100755 Binary files a/cyclist/externalApps/cycpost-darwin-amd64 and b/cyclist/externalApps/cycpost-darwin-amd64 differ diff --git a/cyclist/externalApps/cycpost-linux-386 b/cyclist/externalApps/cycpost-linux-386 index 3e7af471..1173f7f6 100644 Binary files a/cyclist/externalApps/cycpost-linux-386 and b/cyclist/externalApps/cycpost-linux-386 differ diff --git a/cyclist/externalApps/cycpost-linux-amd64 b/cyclist/externalApps/cycpost-linux-amd64 index bad6a378..1a7f694e 100755 Binary files a/cyclist/externalApps/cycpost-linux-amd64 and b/cyclist/externalApps/cycpost-linux-amd64 differ diff --git a/cyclist/externalApps/cycpost-linux-arm b/cyclist/externalApps/cycpost-linux-arm index 54e48d11..6dcc8879 100644 Binary files a/cyclist/externalApps/cycpost-linux-arm and b/cyclist/externalApps/cycpost-linux-arm differ diff --git a/cyclist/externalApps/cycpost-windows-386.exe b/cyclist/externalApps/cycpost-windows-386.exe index 72e3a8bd..495cf0f6 100644 Binary files a/cyclist/externalApps/cycpost-windows-386.exe and b/cyclist/externalApps/cycpost-windows-386.exe differ diff --git a/cyclist/externalApps/cycpost-windows-amd64.exe b/cyclist/externalApps/cycpost-windows-amd64.exe index c53fa720..6e0cb168 100644 Binary files a/cyclist/externalApps/cycpost-windows-amd64.exe and b/cyclist/externalApps/cycpost-windows-amd64.exe differ diff --git a/cyclist/lib/json-simple-1.1.1.jar b/cyclist/lib/json-simple-1.1.1.jar new file mode 100644 index 00000000..66347a6c Binary files /dev/null and b/cyclist/lib/json-simple-1.1.1.jar differ diff --git a/cyclist/lib/sqlite-jdbc-3.8.10.1.jar b/cyclist/lib/sqlite-jdbc-3.8.10.1.jar new file mode 100644 index 00000000..971a81f3 Binary files /dev/null and b/cyclist/lib/sqlite-jdbc-3.8.10.1.jar differ diff --git a/cyclist/lib/sqlite-jdbc-3.8.7.jar b/cyclist/lib/sqlite-jdbc-3.8.7.jar new file mode 100644 index 00000000..22acadde Binary files /dev/null and b/cyclist/lib/sqlite-jdbc-3.8.7.jar differ diff --git a/cyclist/skinImages/reactorSC2.jpg b/cyclist/skinImages/reactorSC2.jpg deleted file mode 100644 index 0a9129a3..00000000 Binary files a/cyclist/skinImages/reactorSC2.jpg and /dev/null differ diff --git a/cyclist/skinImages/sourceFacSC2.jpg b/cyclist/skinImages/sourceFacSC2.jpg deleted file mode 100644 index 13c563c7..00000000 Binary files a/cyclist/skinImages/sourceFacSC2.jpg and /dev/null differ diff --git a/cyclist/src/edu/utah/sci/cyclist/Cyclist.java b/cyclist/src/edu/utah/sci/cyclist/Cyclist.java index 9e65334e..bc03fc88 100755 --- a/cyclist/src/edu/utah/sci/cyclist/Cyclist.java +++ b/cyclist/src/edu/utah/sci/cyclist/Cyclist.java @@ -31,6 +31,7 @@ import edu.utah.sci.cyclist.core.ui.MainScreen; import javafx.application.Application; import javafx.scene.Scene; +import javafx.scene.image.Image; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.stage.Stage; @@ -62,6 +63,7 @@ public void start(Stage primaryStage) throws Exception { primaryStage.setTitle(TITLE); primaryStage.setScene(scene); + primaryStage.getIcons().add(new Image(Cyclist.class.getResourceAsStream("assets/cyclist.png"))); MainScreen root = new MainScreen(primaryStage); diff --git a/cyclist/src/edu/utah/sci/cyclist/ToolsLibrary.java b/cyclist/src/edu/utah/sci/cyclist/ToolsLibrary.java index 62d445d5..31bea0c2 100644 --- a/cyclist/src/edu/utah/sci/cyclist/ToolsLibrary.java +++ b/cyclist/src/edu/utah/sci/cyclist/ToolsLibrary.java @@ -22,69 +22,118 @@ *******************************************************************************/ package edu.utah.sci.cyclist; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import edu.utah.sci.cyclist.core.tools.SimpleToolFactory; import edu.utah.sci.cyclist.core.tools.Tool; import edu.utah.sci.cyclist.core.tools.ToolFactory; import edu.utah.sci.cyclist.core.util.AwesomeIcon; import edu.utexas.cycic.tools.CycicToolFactory; -import edu.utexas.cycic.tools.FacilitySorterToolFactory; -import edu.utexas.cycic.tools.InstitutionViewToolFactory; +import edu.utexas.cycic.tools.InstitutionCorralViewToolFactory; +//import edu.utexas.cycic.tools.InstitutionCorralViewToolFactory; import edu.utexas.cycic.tools.RecipeFormToolFactory; import edu.utexas.cycic.tools.RegionCorralViewToolFactory; -import edu.utexas.cycic.tools.SimulationInfoToolFactory; -import edu.utexas.cycic.tools.TimelineDisplayToolFactory; public class ToolsLibrary { - - public static final ToolFactory[] factories = { - new SimpleToolFactory("edu.utah.sci.cyclist.core", - "Table", AwesomeIcon.LIST_ALT, - "ui.views.SimpleTableView", - "presenter.TablePresenter"), - - new SimpleToolFactory("edu.utah.sci.cyclist.core", - "Plot", AwesomeIcon.BAR_CHART_ALT, - "ui.views.ChartView", - "presenter.ChartPresenter"), - - new SimpleToolFactory("edu.utah.sci.cyclist.neup", - "Flow", AwesomeIcon.RANDOM, - "ui.views.flow.FlowView", - "presenter.NEUPPresenter"), - - new SimpleToolFactory("edu.utah.sci.cyclist.neup", - "Inventory", AwesomeIcon.BOOK, - "ui.views.inventory.InventoryView", - "presenter.NEUPPresenter"), - - new SimpleToolFactory("edu.utah.sci.cyclist.core", - "Workspace", AwesomeIcon.DESKTOP, - "ui.views.Workspace", - "presenter.WorkspacePresenter") - }; - - public static final ToolFactory[] inputFactories = { - new CycicToolFactory(), - new InstitutionViewToolFactory(), - new RecipeFormToolFactory(), - new RegionCorralViewToolFactory(), - //new TimelineDisplayToolFactory() - }; + public static final String VIS_TOOL = "vis_tool"; + public static final String SCENARIO_TOOL = "scenario_tool"; + + private static List factories = new ArrayList<>(); + + public static void register(ToolFactory... list) { + for (ToolFactory factory : list) + factories.add(factory); + } + - public static ToolFactory findFactory(String name) { - for (int i=0; i f.getToolName().equals(name)) + .findFirst() + .get(); + } + + public static List getFactoriesOfType(String type) { + return factories + .stream() + .filter(f -> f.getToolType().equals(type)) + .collect(Collectors.toList()); + } + + public static List getFactoriesOfType(String type, boolean level) { + return factories + .stream() + .filter(f -> f.getToolType().equals(type)) + .filter(f -> f.isUserLevel() == level) + .collect(Collectors.toList()); } public static Tool createTool(String name) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Tool tool = null; - ToolFactory factory = findFactory(name); + ToolFactory factory = getFactory(name); if (factory != null) tool = factory.create(); return tool; } + + static { + register( + new SimpleToolFactory("edu.utah.sci.cyclist.core", + "Table", VIS_TOOL, true, AwesomeIcon.LIST_ALT, + "ui.views.SimpleTableView", + "presenter.TablePresenter"), + + new SimpleToolFactory("edu.utah.sci.cyclist.core", + "Plot", VIS_TOOL, true, AwesomeIcon.BAR_CHART_ALT, + "ui.views.ChartView", + "presenter.ChartPresenter"), + + new SimpleToolFactory("edu.utah.sci.cyclist.neup", + "Flow", VIS_TOOL, true, AwesomeIcon.RANDOM, + "ui.views.flow.FlowView", + "presenter.NEUPPresenter"), + + new SimpleToolFactory("edu.utah.sci.cyclist.neup", + "Inventory", VIS_TOOL, true, AwesomeIcon.BOOK, + "ui.views.inventory.InventoryView", + "presenter.NEUPPresenter"), + + new SimpleToolFactory("edu.utah.sci.cyclist.core", + "Workspace", VIS_TOOL, true, AwesomeIcon.DESKTOP, + "ui.views.VisWorkspace", + "presenter.VisWorkspacePresenter") + ); + + register( + new SimpleToolFactory("edu.utexas.cycic", + "Cycic", SCENARIO_TOOL, false, AwesomeIcon.EYE, + "Cycic", + "presenter.CycicPresenter" + ), + new SimpleToolFactory("edu.utexas.cycic", + "Institution Corral", SCENARIO_TOOL, true, AwesomeIcon.GLOBE, + "InstitutionCorralView", + "presenter.InstitutionCorralViewPresenter" + ), + new SimpleToolFactory("edu.utexas.cycic", + "Recipe Builder", SCENARIO_TOOL, true, AwesomeIcon.SORT_ALPHA_DESC, + "RecipeForm", + "presenter.RecipeFormPresenter" + ), + new SimpleToolFactory("edu.utexas.cycic", + "Region Corral", SCENARIO_TOOL, true, AwesomeIcon.GLOBE, + "RegionCorralView", + "presenter.RegionCorralViewPresenter" + ) +// new CycicToolFactory(), +// new InstitutionCorralViewToolFactory(), +// new RecipeFormToolFactory(), +// new RegionCorralViewToolFactory() + ); + } + } diff --git a/cyclist/src/edu/utah/sci/cyclist/assets/cyclist.png b/cyclist/src/edu/utah/sci/cyclist/assets/cyclist.png new file mode 100644 index 00000000..d433b849 Binary files /dev/null and b/cyclist/src/edu/utah/sci/cyclist/assets/cyclist.png differ diff --git a/cyclist/src/edu/utah/sci/cyclist/assets/default-metadata.json b/cyclist/src/edu/utah/sci/cyclist/assets/default-metadata.json new file mode 100644 index 00000000..7f91dcdf --- /dev/null +++ b/cyclist/src/edu/utah/sci/cyclist/assets/default-metadata.json @@ -0,0 +1,1377 @@ +{ + "annotations": { + ":agents:KFacility": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": "A facility designed for integration tests that both provides and consumes commodities. It changes its request and offer amounts based on a power law with respect to time.", + "entity": "facility", + "name": "cyclus::KFacility", + "parents": ["cyclus::Facility"], + "vars": { + "current_capacity": { + "alias": "current_capacity", + "default": 0, + "doc": "number of output commodity units that can be supplied at the current time step (infinite capacity can be represented by a very large number )", + "index": 5, + "tooltip": "current output capacity", + "type": "double", + "uilabel": "Current Capacity" + }, + "in_capacity": { + "alias": "in_capacity", + "doc": "number of commodity units that can be taken at each timestep (infinite capacity can be represented by a very large number)", + "index": 3, + "tooltip": "input commodity capacity", + "type": "double", + "uilabel": "Incoming Throughput" + }, + "in_commod": { + "alias": "in_commod", + "doc": "commodity that the k-facility consumes", + "index": 0, + "schematype": "token", + "tooltip": "input commodity", + "type": "std::string", + "uilabel": "Input Commodity", + "uitype": "incommodity" + }, + "inventory": { + "alias": "inventory", + "capacity": "max_inv_size", + "index": 7, + "tooltip": "inventory", + "type": "cyclus::toolkit::ResourceBuff", + "uilabel": "inventory" + }, + "k_factor_in": { + "alias": "k_factor_in", + "doc": "conversion factor that governs the behavior of the k-facility's input commodity capacity", + "index": 8, + "tooltip": "input k-factor", + "type": "double", + "uilabel": "Input K-Factor" + }, + "k_factor_out": { + "alias": "k_factor_out", + "doc": "conversion factor that governs the behavior of the k-facility's output commodity capacity", + "index": 9, + "tooltip": "output k-factor", + "type": "double", + "uilabel": "Output K-Factor" + }, + "max_inv_size": { + "alias": "max_inv_size", + "default": 1.000000000000000e+299, + "doc": "total maximum inventory size of the k-facility", + "index": 6, + "tooltip": "k-facility maximum inventory size", + "type": "double", + "uilabel": "Maximum Inventory" + }, + "out_capacity": { + "alias": "out_capacity", + "doc": "number of commodity units that can be supplied at each timestep (infinite capacity can be represented by a very large number)", + "index": 4, + "tooltip": "output commodity capacity", + "type": "double", + "uilabel": "Outgoing Throughput" + }, + "out_commod": { + "alias": "out_commod", + "doc": "commodity that the k-facility supplies", + "index": 2, + "schematype": "token", + "tooltip": "output commodity", + "type": "std::string", + "uilabel": "Output Commodity", + "uitype": "outcommodity" + }, + "recipe_name": { + "alias": "recipe_name", + "doc": "recipe name for the k-facility's in-commodity", + "index": 1, + "schematype": "token", + "shape": [50], + "tooltip": "in-commodity recipe name", + "type": "std::string", + "uilabel": "Input Recipe", + "uitype": "recipe" + } + } + }, + ":agents:NullInst": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Ider", + "cyclus::Institution", + "cyclus::StateWrangler", + "cyclus::TimeListener" + ], + "doc": "An instition that owns facilities in the simulation but exhibits null behavior. No parameters are given when using the null institution.", + "entity": "institution", + "name": "cyclus::NullInst", + "parents": ["cyclus::Institution"], + "vars": {} + }, + ":agents:NullRegion": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Ider", + "cyclus::Region", + "cyclus::StateWrangler", + "cyclus::TimeListener" + ], + "doc": "A region that owns the simulation's institutions but exhibits null behavior. No parameters are given when using the null region.", + "entity": "region", + "name": "cyclus::NullRegion", + "parents": ["cyclus::Region"], + "vars": {} + }, + ":agents:Predator": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": "A facility that represents predators in the Lotka-Volterra integration tests", + "entity": "facility", + "name": "cyclus::Predator", + "parents": ["cyclus::Facility"], + "vars": { + "age": { + "alias": "age", + "default": 0, + "doc": "age of predator at beginning of simulation", + "index": 8, + "tooltip": "predator age", + "type": "int", + "uilabel": "Predator Age" + }, + "birth_and_death": { + "alias": "birth_and_death", + "default": 0, + "doc": "whether or not simultaneous birth and death are allowed (i.e., can a facility give birth and die in the same time step?)", + "index": 12, + "tooltip": "simultaneous birth and death?", + "type": "bool", + "uilabel": "Simultaneous Birth and Death?" + }, + "commod": { + "alias": "commod", + "doc": "commodity that the predator supplies", + "index": 0, + "schematype": "token", + "tooltip": "predator commodity", + "type": "std::string", + "uilabel": "Predator Commodity", + "uitype": "outcommodity" + }, + "consumed": { + "alias": "consumed", + "default": 0, + "doc": "how many units of prey consumed per time step", + "index": 6, + "tooltip": "prey consumed", + "type": "double", + "uilabel": "Prey Consumed" + }, + "dead": { + "alias": "dead", + "default": 0, + "doc": "flag for whether predator is currently dead", + "index": 10, + "tooltip": "dead?", + "type": "bool", + "uilabel": "Predator Dead?" + }, + "full": { + "alias": "full", + "default": 1, + "doc": "how many units of prey a predator consumes until it is satisfied", + "index": 2, + "tooltip": "feast size", + "type": "double", + "uilabel": "Feast Size" + }, + "hunt_cap": { + "alias": "hunt_cap", + "default": 1, + "doc": "how many units of prey a predator can catch during a hunt", + "index": 4, + "tooltip": "hunting yield", + "type": "double", + "uilabel": "Hunting Yield" + }, + "hunt_factor": { + "alias": "hunt_factor", + "default": 0, + "doc": "whether or not to base hunting success on relative predator/prey populations", + "index": 7, + "tooltip": "hunting success factor", + "type": "bool", + "uilabel": "Hunting Success Factor" + }, + "hunt_freq": { + "alias": "hunt_freq", + "default": 1, + "doc": "how often a predator needs to hunt", + "index": 3, + "tooltip": "hunting frequency", + "type": "int", + "uilabel": "Hunting Frequency" + }, + "lifespan": { + "alias": "lifespan", + "default": 1, + "doc": "how long a predator lives", + "index": 9, + "tooltip": "predator lifespan", + "type": "int", + "uilabel": "Predator Lifespan" + }, + "nchildren": { + "alias": "nchildren", + "default": 1, + "doc": "number of predator children born at each birthing instance", + "index": 11, + "tooltip": "number of children", + "type": "double", + "uilabel": "Number Predator Children" + }, + "prey": { + "alias": "prey", + "doc": "prey that the predator hunts", + "index": 1, + "schematype": "token", + "tooltip": "predator's prey", + "type": "std::string", + "uilabel": "Prey Commodity", + "uitype": "incommodity" + }, + "success": { + "alias": "success", + "default": 1, + "doc": "fraction of hunting success on a scale from 0 to 1", + "index": 5, + "tooltip": "hunting success fraction", + "type": "double", + "uilabel": "Hunting Success Fraction" + } + } + }, + ":agents:Prey": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": "A facility that represents prey in the Lotka-Volterra integration tests", + "entity": "facility", + "name": "cyclus::Prey", + "parents": ["cyclus::Facility"], + "vars": { + "age": { + "alias": "age", + "default": 0, + "doc": "age of prey at start of simulation", + "index": 1, + "tooltip": "prey age", + "type": "int", + "uilabel": "Prey Age" + }, + "birth_and_death": { + "alias": "birth_and_death", + "default": 1, + "doc": "whether or not simultaneous birth and death are allowed (i.e., can a facility give birth and die in the same time step?)", + "index": 5, + "tooltip": "simultaneous birth and death?", + "type": "bool", + "uilabel": "Simultaneous Birth and Death?" + }, + "birth_freq": { + "alias": "birth_freq", + "default": 1, + "doc": "number of time steps between birth of children", + "index": 4, + "tooltip": "birth frequency", + "type": "int", + "uilabel": "Birth Frequency" + }, + "commod": { + "alias": "commod", + "index": 0, + "schematype": "token", + "tooltip": "commod", + "type": "std::string", + "uilabel": "Prey Commodity", + "uitype": "outcommodity" + }, + "dead": { + "alias": "dead", + "default": 0, + "doc": "flag for whether prey is currently dead", + "index": 2, + "tooltip": "dead?", + "type": "bool", + "uilabel": "Dead?" + }, + "nchildren": { + "alias": "nchildren", + "default": 1, + "doc": "number of children born at each birthing instance", + "index": 3, + "tooltip": "number of children", + "type": "int", + "uilabel": "Number of Children" + } + } + }, + ":agents:Sink": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": "A minimum implementation sink facility that accepts specified amounts of commodities from other agents", + "entity": "facility", + "name": "cyclus::Sink", + "parents": ["cyclus::Facility"], + "vars": { + "capacity": { + "alias": "capacity", + "doc": "capacity the sink facility can accept at each time step", + "index": 3, + "tooltip": "sink capacity", + "type": "double", + "uilabel": "Maximum Throughput" + }, + "in_commods": { + "alias": ["in_commods", "val"], + "doc": "commodities that the sink facility accepts ", + "index": 0, + "tooltip": ["input commodities for the sink", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["List of Input Commodities", ""], + "uitype": ["oneormore", "incommodity"] + }, + "inventory": { + "alias": "inventory", + "capacity": "max_inv_size", + "index": 4, + "tooltip": "inventory", + "type": "cyclus::toolkit::ResourceBuff", + "uilabel": "inventory" + }, + "max_inv_size": { + "alias": "max_inv_size", + "default": 1.000000000000000e+299, + "doc": "total maximum inventory size of sink facility", + "index": 2, + "tooltip": "sink maximum inventory size", + "type": "double", + "uilabel": "Maximum Inventory" + }, + "recipe_name": { + "alias": "recipe_name", + "default": "", + "doc": "Name of recipe to request.If empty, sink requests material no particular composition.", + "index": 1, + "tooltip": "input/request recipe name", + "type": "std::string", + "uilabel": "Input Recipe", + "uitype": "recipe" + } + } + }, + ":agents:Source": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": "A minimum implementation source facility that provides a commodity with a given capacity", + "entity": "facility", + "name": "cyclus::Source", + "parents": ["cyclus::Facility"], + "vars": { + "capacity": { + "alias": "capacity", + "doc": "amount of commodity that can be supplied at each time step", + "index": 2, + "tooltip": "source capacity", + "type": "double", + "uilabel": "Maximum Throughput" + }, + "commod": { + "alias": "commod", + "doc": "commodity that the source facility supplies", + "index": 0, + "schematype": "token", + "tooltip": "source commodity", + "type": "std::string", + "uilabel": "Commodity", + "uitype": "outcommodity" + }, + "recipe_name": { + "alias": "recipe_name", + "default": "", + "doc": "Recipe name for source facility's commodity.If empty, source supplies material with requested compositions.", + "index": 1, + "schematype": "token", + "tooltip": "commodity recipe name", + "type": "std::string", + "uilabel": "Recipe", + "uitype": "recipe" + } + } + }, + ":cycamore:DeployInst": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Ider", + "cyclus::Institution", + "cyclus::StateWrangler", + "cyclus::TimeListener" + ], + "doc": "Builds and manages agents (facilities) according to a manually specified deployment schedule. Deployed agents are automatically decommissioned at the end of their lifetime. The user specifies a list of prototypes for each and corresponding build times, number to build, and (optionally) lifetimes. The same prototype can be specified multiple times with any combination of the same or different build times, build number, and lifetimes. ", + "entity": "institution", + "name": "cycamore::DeployInst", + "parents": ["cyclus::Institution"], + "vars": { + "build_times": { + "alias": ["build_times", "val"], + "doc": "Time step on which to deploy agents given in prototype list (same order).", + "index": 1, + "tooltip": ["build_times", ""], + "type": ["std::vector", "int"], + "uilabel": ["Deployment times", ""] + }, + "lifetimes": { + "alias": ["lifetimes", "val"], + "default": [], + "doc": "Lifetimes for each prototype in prototype list (same order). These lifetimes override the lifetimes in the original prototype definition. If unspecified, lifetimes from the original prototype definitions are used. Although a new prototype is created in the Prototypes table for each lifetime with the suffix '_life_[lifetime]', all deployed agents themselves will have the same original prototype name (and so will the Agents tables).", + "index": 3, + "tooltip": ["lifetimes", ""], + "type": ["std::vector", "int"], + "uilabel": ["Lifetimes", ""] + }, + "n_build": { + "alias": ["n_build", "val"], + "doc": "Number of each prototype given in prototype list that should be deployed (same order).", + "index": 2, + "tooltip": ["n_build", ""], + "type": ["std::vector", "int"], + "uilabel": ["Number to deploy", ""] + }, + "prototypes": { + "alias": ["prototypes", "val"], + "doc": "Ordered list of prototypes to build.", + "index": 0, + "tooltip": ["prototypes", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Prototypes to deploy", ""], + "uitype": ["oneormore", "prototype"] + } + } + }, + ":cycamore:Enrichment": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": "The Enrichment facility is a simple agent that enriches natural uranium in a Cyclus simulation. It does not explicitly compute the physical enrichment process, rather it calculates the SWU required to convert an source uranium recipe (i.e. natural uranium) into a requested enriched recipe (i.e. 4% enriched uranium), given the natural uranium inventory constraint and its SWU capacity constraint.\n\nThe Enrichment facility requests an input commodity and associated recipe whose quantity is its remaining inventory capacity. All facilities trading the same input commodity (even with different recipes) will offer materials for trade. The Enrichment facility accepts any input materials with enrichments less than its tails assay, as long as some U235 is present, and preference increases with U235 content. If no U235 is present in the offered material, the trade preference is set to -1 and the material is not accepted. Any material components other than U235 and U238 are sent directly to the tails buffer.\n\nThe Enrichment facility will bid on any request for its output commodity up to the maximum allowed enrichment (if not specified, default is 100%) It bids on either the request quantity, or the maximum quanity allowed by its SWU constraint or natural uranium inventory, whichever is lower. If multiple output commodities with different enrichment levels are requested and the facility does not have the SWU or quantity capacity to meet all requests, the requests are fully, then partially filled in unspecified but repeatable order.\n\nAccumulated tails inventory is offered for trading as a specifiable output commodity.", + "entity": "facility", + "name": "cycamore::Enrichment", + "niche": "enrichment facility", + "parents": ["cyclus::Facility"], + "vars": { + "feed_commod": { + "alias": "feed_commod", + "doc": "feed commodity that the enrichment facility accepts", + "index": 0, + "tooltip": "feed commodity", + "type": "std::string", + "uilabel": "Feed Commodity", + "uitype": "incommodity" + }, + "feed_recipe": { + "alias": "feed_recipe", + "doc": "recipe for enrichment facility feed commodity", + "index": 1, + "tooltip": "feed recipe", + "type": "std::string", + "uilabel": "Feed Recipe", + "uitype": "recipe" + }, + "initial_feed": { + "alias": "initial_feed", + "default": 0, + "doc": "amount of natural uranium stored at the enrichment facility at the beginning of the simulation (kg)", + "index": 5, + "tooltip": "initial uranium reserves (kg)", + "type": "double", + "uilabel": "Initial Feed Inventory" + }, + "inventory": { + "capacity": "max_feed_inventory", + "index": 10, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + }, + "max_enrich": { + "alias": "max_enrich", + "default": 1.0, + "doc": "maximum allowed weight fraction of U235 in product", + "index": 7, + "schema": " 0 1 ", + "tooltip": "maximum allowed enrichment fraction", + "type": "double", + "uilabel": "Maximum Allowed Enrichment" + }, + "max_feed_inventory": { + "alias": "max_feed_inventory", + "default": 1.000000000000000e+299, + "doc": "maximum total inventory of natural uranium in the enrichment facility (kg)", + "index": 6, + "tooltip": "max inventory of feed material (kg)", + "type": "double", + "uilabel": "Maximum Feed Inventory" + }, + "order_prefs": { + "alias": "order_prefs", + "default": 1, + "doc": "turn on preference ordering for input material so that EF chooses higher U235 content first", + "index": 8, + "tooltip": "Rank Material Requests by U235 Content", + "type": "bool", + "uilabel": "Prefer feed with higher U235 content", + "userlevel": 10 + }, + "product_commod": { + "alias": "product_commod", + "doc": "product commodity that the enrichment facility generates", + "index": 2, + "tooltip": "product commodity", + "type": "std::string", + "uilabel": "Product Commodity", + "uitype": "outcommodity" + }, + "swu_capacity": { + "alias": "swu_capacity", + "default": 1.000000000000000e+299, + "doc": "separative work unit (SWU) capacity of enrichment facility (kgSWU/timestep) ", + "index": 9, + "tooltip": "SWU capacity (kgSWU/month)", + "type": "double", + "uilabel": "SWU Capacity" + }, + "tails": {"index": 11, "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"]}, + "tails_assay": { + "alias": "tails_assay", + "default": 0.0030, + "doc": "tails assay from the enrichment process", + "index": 4, + "tooltip": "tails assay", + "type": "double", + "uilabel": "Tails Assay" + }, + "tails_commod": { + "alias": "tails_commod", + "doc": "tails commodity supplied by enrichment facility", + "index": 3, + "tooltip": "tails commodity", + "type": "std::string", + "uilabel": "Tails Commodity", + "uitype": "outcommodity" + } + } + }, + ":cycamore:FuelFab": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": "FuelFab takes in 2 streams of material and mixes them in ratios in order to supply material that matches some neutronics properties of reqeusted material. It uses an equivalence type method [1] inspired by a similar approach in the COSI fuel cycle simulator.\n\nThe FuelFab has 3 input inventories: fissile stream, filler stream, and an optional top-up inventory. All materials received into each inventory are always combined into a single material (i.e. a single fissile material, a single filler material, etc.). The input streams and requested fuel composition are each assigned weights based on summing:\n\n N * (p_i - p_U238) / (p_Pu239 - p_U238)\n\nfor each nuclide where:\n\n - p = nu*sigma_f - sigma_a for the nuclide\n - p_U238 is p for pure U238\n - p_Pu239 is p for pure Pu239\n - N is the nuclide's atom fraction\n - nu is the average # neutrons per fission\n - sigma_f is the microscopic fission cross-section\n - sigma_a is the microscopic neutron absorption cross-section\n\nThe cross sections are from the simple cross section library in PyNE. They can be set to either a thermal or fast neutron spectrum. A linear interpolation is performed using the weights of the fissile, filler, and target streams. The interpolation is used to compute a mixing ratio of the input streams that matches the target weight. In the event that the target weight is higher than the fissile stream weight, the FuelFab will attempt to use the top-up and fissile input streams together instead of the fissile and filler streams. All supplied material will always have the same weight as the requested material.\n\nThe supplying of mixed material is constrained by available inventory quantities and a per time step throughput limit. Requests for fuel material larger than the throughput can never be met. Fissile inventory can be requested/received via one or more commodities. The DRE request preference for each of these commodities can also optionally be specified. By default, the top-up inventory size is zero, and it is not used for mixing. \n\n[1] Baker, A. R., and R. W. Ross. \"Comparison of the value of plutonium and uranium isotopes in fast reactors.\" Proceedings of the Conference on Breeding. Economics, and Safety in Large Fast Power Reactors. 1963.", + "entity": "facility", + "name": "cycamore::FuelFab", + "niche": "fabrication", + "parents": ["cyclus::Facility"], + "vars": { + "fill": { + "capacity": "fill_size", + "index": 4, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + }, + "fill_commod_prefs": { + "alias": ["fill_commod_prefs", "val"], + "default": [], + "doc": "Filler stream commodity request preferences for each of the given filler commodities (same order). If unspecified, default is to use 1.0 for all preferences.", + "index": 1, + "tooltip": ["fill_commod_prefs", ""], + "type": ["std::vector", "double"], + "uilabel": ["Filler Stream Preferences", ""] + }, + "fill_commods": { + "alias": ["fill_commods", "val"], + "doc": "Ordered list of commodities on which to requesting filler stream material.", + "index": 0, + "tooltip": ["fill_commods", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Filler Stream Commodities", ""], + "uitype": ["oneormore", "incommodity"] + }, + "fill_recipe": { + "alias": "fill_recipe", + "doc": "Name of recipe to be used in filler material stream requests.", + "index": 2, + "tooltip": "fill_recipe", + "type": "std::string", + "uilabel": "Filler Stream Recipe", + "uitype": "recipe" + }, + "fill_size": { + "alias": "fill_size", + "doc": "Size of filler material stream inventory.", + "index": 3, + "tooltip": "fill_size", + "type": "double", + "uilabel": "Filler Stream Inventory Capacity", + "units": "kg" + }, + "fiss": { + "capacity": "fiss_size", + "index": 9, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + }, + "fiss_commod_prefs": { + "alias": ["fiss_commod_prefs", "val"], + "default": [], + "doc": "Fissile stream commodity request preferences for each of the given fissile commodities (same order). If unspecified, default is to use 1.0 for all preferences.", + "index": 6, + "tooltip": ["fiss_commod_prefs", ""], + "type": ["std::vector", "double"], + "uilabel": ["Fissile Stream Preferences", ""] + }, + "fiss_commods": { + "alias": ["fiss_commods", "val"], + "doc": "Ordered list of commodities on which to requesting fissile stream material.", + "index": 5, + "tooltip": ["fiss_commods", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Fissile Stream Commodities", ""], + "uitype": ["oneormore", "incommodity"] + }, + "fiss_recipe": { + "alias": "fiss_recipe", + "default": "", + "doc": "Name for recipe to be used in fissile stream requests. Empty string results in use of an empty dummy recipe.", + "index": 7, + "tooltip": "fiss_recipe", + "type": "std::string", + "uilabel": "Fissile Stream Recipe", + "uitype": "recipe" + }, + "fiss_size": { + "alias": "fiss_size", + "doc": "Size of fissile material stream inventory.", + "index": 8, + "tooltip": "fiss_size", + "type": "double", + "uilabel": "Fissile Stream Inventory Capacity", + "units": "kg" + }, + "outcommod": { + "alias": "outcommod", + "doc": "Commodity on which to offer/supply mixed fuel material.", + "index": 15, + "tooltip": "outcommod", + "type": "std::string", + "uilabel": "Output Commodity", + "uitype": "outcommodity" + }, + "spectrum": { + "alias": "spectrum", + "categorical": ["fission_spectrum_ave", "thermal"], + "doc": "The type of cross-sections to use for composition property calculation. Use 'fission_spectrum_ave' for fast reactor compositions or 'thermal' for thermal reactors.", + "index": 17, + "tooltip": "spectrum", + "type": "std::string", + "uilabel": "Spectrum type" + }, + "throughput": { + "alias": "throughput", + "doc": "Maximum number of kg of fuel material that can be supplied per time step.", + "index": 16, + "tooltip": "throughput", + "type": "double", + "uilabel": "Maximum Throughput", + "units": "kg" + }, + "topup": { + "capacity": "topup_size", + "index": 14, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + }, + "topup_commod": { + "alias": "topup_commod", + "default": "", + "doc": "Commodity on which to request material for top-up stream. This MUST be set if 'topup_size > 0'.", + "index": 10, + "tooltip": "topup_commod", + "type": "std::string", + "uilabel": "Top-up Stream Commodity", + "uitype": "incommodity" + }, + "topup_pref": { + "alias": "topup_pref", + "default": 0, + "doc": "Top-up material stream request preference.", + "index": 11, + "tooltip": "topup_pref", + "type": "double", + "uilabel": "Top-up Stream Preference" + }, + "topup_recipe": { + "alias": "topup_recipe", + "default": "", + "doc": "Name of recipe to be used in top-up material stream requests. This MUST be set if 'topup_size > 0'.", + "index": 12, + "tooltip": "topup_recipe", + "type": "std::string", + "uilabel": "Top-up Stream Recipe", + "uitype": "recipe" + }, + "topup_size": { + "alias": "topup_size", + "default": 0, + "doc": "Size of top-up material stream inventory.", + "index": 13, + "tooltip": "topup_size", + "type": "double", + "uilabel": "Top-up Stream Inventory Capacity", + "units": "kg" + } + } + }, + ":cycamore:GrowthRegion": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Ider", + "cyclus::Region", + "cyclus::StateWrangler", + "cyclus::TimeListener" + ], + "doc": "A region that governs a scenario in which there is growth in demand for a commodity. ", + "entity": "region", + "name": "cycamore::GrowthRegion", + "parents": ["cyclus::Region"], + "vars": { + "commodity_demand": { + "alias": [ + ["growth", "item"], + "commod", + ["piecewise_function", ["piece", "start", ["function", "type", "params"]]] + ], + "doc": "Nameplate capacity demand functions.\n\nEach demand type must be for a commodity for which capacity can be built (e.g., 'power' from cycamore::Reactors). Any archetype that implements the cyclus::toolkit::CommodityProducer interface can interact with the GrowthRegion in the manner.\n\nDemand functions are defined as piecewise functions. Each piece must be provided a starting time and function description. Each function description is comprised of a function type and associated parameters. \n\n * Start times are inclusive. For a start time :math:`t_0`, the demand function is evaluated on :math:`[t_0, \\infty)`.\n\n * Supported function types are based on the `cyclus::toolkit::BasicFunctionFactory types `_. \n\n * The type name is the lower-case name of the function (e.g., 'linear', 'exponential', etc.).\n\n * The parameters associated with each function type can be found on their respective documentation pages.", + "index": 0, + "tooltip": [["commodity_demand", ""], "", ["", ["", "", ["", "", ""]]]], + "type": [ + "std::map", + "std::string", + [ + "std::vector", + ["std::pair", "int", ["std::pair", "std::string", "std::string"]] + ] + ], + "uilabel": [["Growth Demand Curves", ""], "", ["", ["", "", ["", "", ""]]]], + "uitype": [ + "oneormore", + "string", + ["oneormore", ["pair", "int", ["pair", "string", "string"]]] + ] + }, + "growth": "commodity_demand" + } + }, + ":cycamore:ManagerInst": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Ider", + "cyclus::Institution", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::toolkit::AgentManaged", + "cyclus::toolkit::Builder", + "cyclus::toolkit::CommodityProducerManager" + ], + "doc": "An institution that owns and operates a manually entered list of facilities in the input file", + "entity": "institution", + "name": "cycamore::ManagerInst", + "parents": [ + "cyclus::Institution", + "cyclus::toolkit::Builder", + "cyclus::toolkit::CommodityProducerManager" + ], + "vars": { + "prototypes": { + "alias": ["prototypes", "val"], + "doc": "A set of facility prototypes that this institution can build. All prototypes in this list must be based on an archetype that implements the cyclus::toolkit::CommodityProducer interface", + "index": 0, + "tooltip": ["producer facility prototypes", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Producer Prototype List", ""], + "uitype": ["oneormore", "prototype"] + } + } + }, + ":cycamore:Reactor": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader", + "cyclus::toolkit::AgentManaged", + "cyclus::toolkit::CommodityProducer" + ], + "doc": "Reactor is a simple, general reactor based on static compositional transformations to model fuel burnup. The user specifies a set of input fuels and corresponding burnt compositions that fuel is transformed to when it is discharged from the core. No incremental transmutation takes place. Rather, at the end of an operational cycle, the batch being discharged from the core is instantaneously transmuted from its original fresh fuel composition into its spent fuel form.\n\nEach fuel is identified by a specific input commodity and has an associated input recipe (nuclide composition), output recipe, output commidity, and preference. The preference identifies which input fuels are preferred when requesting. Changes in these preferences can be specified as a function of time using the pref_change variables. Changes in the input-output recipe compositions can also be specified as a function of time using the recipe_change variables.\n\nThe reactor treats fuel as individual assemblies that are never split, combined or otherwise treated in any non-discrete way. Fuel is requested in full-or-nothing assembly sized quanta. If real-world assembly modeling is unnecessary, parameters can be adjusted (e.g. n_assem_core, assem_size, n_assem_batch). At the end of every cycle, a full batch is discharged from the core consisting of n_assem_batch assemblies of assem_size kg. The reactor also has a specifiable refueling time period following the end of each cycle at the end of which it will resume operation on the next cycle *if* it has enough fuel for a full core; otherwise it waits until it has enough fresh fuel assemblies.\n\nIn addition to its core, the reactor has an on-hand fresh fuel inventory and a spent fuel inventory whose capacities are specified by n_assem_fresh and n_assem_spent respectively. Each time step the reactor will attempt to acquire enough fresh fuel to fill its fresh fuel inventory (and its core if the core isn't currently full). If the fresh fuel inventory has zero capacity, fuel will be ordered just-in-time after the end of each operational cycle before the next begins. If the spent fuel inventory becomes full, the reactor will halt operation at the end of the next cycle until there is more room. Each time step, the reactor will try to trade away as much of its spent fuel inventory as possible.\n\nWhen the reactor reaches the end of its lifetime, it will discharge all material from its core and trade away all its spent fuel as quickly as possible. Full decommissioning will be delayed until all spent fuel is gone. If the reactor has a full core when it is decommissioned (i.e. is mid-cycle) when the reactor is decommissioned, half (rounded up to nearest int) of its assemblies are transmuted to their respective burnt compositions.", + "entity": "facility", + "name": "cycamore::Reactor", + "niche": "reactor", + "parents": ["cyclus::Facility", "cyclus::toolkit::CommodityProducer"], + "vars": { + "assem_size": { + "alias": "assem_size", + "doc": "Mass (kg) of a single assembly.", + "index": 9, + "tooltip": "assem_size", + "type": "double", + "uilabel": "Assembly Mass", + "units": "kg" + }, + "core": { + "capacity": "n_assem_core * assem_size", + "index": 23, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + }, + "cycle_step": { + "alias": "cycle_step", + "default": 0, + "doc": "Number of time steps since the start of the last cycle. Only set this if you know what you are doing", + "index": 16, + "tooltip": "cycle_step", + "type": "int", + "uilabel": "Time Since Start of Last Cycle", + "units": "time steps" + }, + "cycle_time": { + "alias": "cycle_time", + "doc": "The duration of a full operational cycle (excluding refueling time) in time steps.", + "index": 14, + "tooltip": "cycle_time", + "type": "int", + "uilabel": "Cycle Length", + "units": "time steps" + }, + "discharged": { + "alias": "discharged", + "default": 0, + "doc": "This should NEVER be set manually", + "index": 25, + "internal": true, + "tooltip": "discharged", + "type": "bool", + "uilabel": "discharged" + }, + "fresh": { + "capacity": "n_assem_fresh * assem_size", + "index": 22, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + }, + "fuel_incommods": { + "alias": ["fuel_incommods", "val"], + "doc": "Ordered list of input commodities on which to requesting fuel.", + "index": 0, + "tooltip": ["fuel_incommods", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Fresh Fuel Commodity List", ""], + "uitype": ["oneormore", "incommodity"] + }, + "fuel_inrecipes": { + "alias": ["fuel_inrecipes", "val"], + "doc": "Fresh fuel recipes to request for each of the given fuel input commodities (same order).", + "index": 1, + "tooltip": ["fuel_inrecipes", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Fresh Fuel Recipe List", ""], + "uitype": ["oneormore", "recipe"] + }, + "fuel_outcommods": { + "alias": ["fuel_outcommods", "val"], + "doc": "Output commodities on which to offer spent fuel originally received as each particular input commodity (same order).", + "index": 3, + "tooltip": ["fuel_outcommods", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Spent Fuel Commodity List", ""], + "uitype": ["oneormore", "outcommodity"] + }, + "fuel_outrecipes": { + "alias": ["fuel_outrecipes", "val"], + "doc": "Spent fuel recipes corresponding to the given fuel input commodities (same order). Fuel received via a particular input commodity is transmuted to the recipe specified here after being burned during a cycle.", + "index": 4, + "tooltip": ["fuel_outrecipes", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Spent Fuel Recipe List", ""], + "uitype": ["oneormore", "recipe"] + }, + "fuel_prefs": { + "alias": ["fuel_prefs", "val"], + "default": [], + "doc": "The preference for each type of fresh fuel requested corresponding to each input commodity (same order). If no preferences are specified, zero is used for all fuel requests (default).", + "index": 2, + "tooltip": ["fuel_prefs", ""], + "type": ["std::vector", "double"], + "uilabel": ["Fresh Fuel Preference List", ""] + }, + "n_assem_batch": { + "alias": "n_assem_batch", + "doc": "Number of assemblies that constitute a single batch. This is the number of assemblies discharged from the core fully burned each cycle.Batch size is equivalent to ``n_assem_batch / n_assem_core``.", + "index": 10, + "tooltip": "n_assem_batch", + "type": "int", + "uilabel": "Number of Assemblies per Batch" + }, + "n_assem_core": { + "alias": "n_assem_core", + "doc": "Number of assemblies that constitute a full core.", + "index": 11, + "tooltip": "n_assem_core", + "type": "int", + "uilabel": "Number of Assemblies in Core" + }, + "n_assem_fresh": { + "alias": "n_assem_fresh", + "default": 0, + "doc": "Number of fresh fuel assemblies to keep on-hand if possible.", + "index": 12, + "tooltip": "n_assem_fresh", + "type": "int", + "uilabel": "Minimum Fresh Fuel Inventory", + "units": "assemblies" + }, + "n_assem_spent": { + "alias": "n_assem_spent", + "default": 1000000000, + "doc": "Number of spent fuel assemblies that can be stored on-site before reactor operation stalls.", + "index": 13, + "tooltip": "n_assem_spent", + "type": "int", + "uilabel": "Maximum Spent Fuel Inventory", + "units": "assemblies" + }, + "power_cap": { + "alias": "power_cap", + "default": 0, + "doc": "Amount of electrical power the facility produces when operating normally.", + "index": 17, + "tooltip": "power_cap", + "type": "double", + "uilabel": "Nominal Reactor Power", + "units": "MWe" + }, + "power_name": { + "alias": "power_name", + "default": "power", + "doc": "The name of the 'power' commodity used in conjunction with a deployment curve.", + "index": 18, + "tooltip": "power_name", + "type": "std::string", + "uilabel": "Power Commodity Name" + }, + "pref_change_commods": { + "alias": ["pref_change_commods", "val"], + "default": [], + "doc": "The input commodity for a particular fuel preference change. Same order as and direct correspondence to the specified preference change times.", + "index": 20, + "tooltip": ["pref_change_commods", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Commodity for Changed Fresh Fuel Preference", ""], + "uitype": ["oneormore", "incommodity"] + }, + "pref_change_times": { + "alias": ["pref_change_times", "val"], + "default": [], + "doc": "A time step on which to change the request preference for a particular fresh fuel type.", + "index": 19, + "tooltip": ["pref_change_times", ""], + "type": ["std::vector", "int"], + "uilabel": ["Time to Change Fresh Fuel Preference", ""] + }, + "pref_change_values": { + "alias": ["pref_change_values", "val"], + "default": [], + "doc": "The new/changed request preference for a particular fresh fuel. Same order as and direct correspondence to the specified preference change times.", + "index": 21, + "tooltip": ["pref_change_values", ""], + "type": ["std::vector", "double"], + "uilabel": ["Changed Fresh Fuel Preference", ""] + }, + "recipe_change_commods": { + "alias": ["recipe_change_commods", "val"], + "default": [], + "doc": "The input commodity indicating fresh fuel for which recipes will be changed. Same order as and direct correspondence to the specified recipe change times.", + "index": 6, + "tooltip": ["recipe_change_commods", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Commodity for Changed Fresh/Spent Fuel Recipe", ""], + "uitype": ["oneormore", "incommodity"] + }, + "recipe_change_in": { + "alias": ["recipe_change_in", "val"], + "default": [], + "doc": "The new input recipe to use for this recipe change. Same order as and direct correspondence to the specified recipe change times.", + "index": 7, + "tooltip": ["recipe_change_in", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["New Recipe for Fresh Fuel", ""], + "uitype": ["oneormore", "recipe"] + }, + "recipe_change_out": { + "alias": ["recipe_change_out", "val"], + "default": [], + "doc": "The new output recipe to use for this recipe change. Same order as and direct correspondence to the specified recipe change times.", + "index": 8, + "tooltip": ["recipe_change_out", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["New Recipe for Spent Fuel", ""], + "uitype": ["oneormore", "recipe"] + }, + "recipe_change_times": { + "alias": ["recipe_change_times", "val"], + "default": [], + "doc": "A time step on which to change the input-output recipe pair for a requested fresh fuel.", + "index": 5, + "tooltip": ["recipe_change_times", ""], + "type": ["std::vector", "int"], + "uilabel": ["Time to Change Fresh/Spent Fuel Recipe", ""] + }, + "refuel_time": { + "alias": "refuel_time", + "doc": "The duration of a full refueling period - the minimum time between the end of a cycle and the start of the next cycle.", + "index": 15, + "tooltip": "refuel_time", + "type": "int", + "uilabel": "Refueling Outage Duration", + "units": "time steps" + }, + "res_indexes": { + "alias": [["res_indexes", "item"], "key", "val"], + "default": {}, + "doc": "This should NEVER be set manually", + "index": 26, + "internal": true, + "tooltip": [["res_indexes", ""], "", ""], + "type": ["std::map", "int", "int"], + "uilabel": [["res_indexes", ""], "", ""] + }, + "spent": { + "capacity": "n_assem_spent * assem_size", + "index": 24, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + } + } + }, + ":cycamore:Separations": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": "Separations processes feed material into one or more streams containing specific elements and/or nuclides. It uses mass-based efficiencies.\n\nUser defined separations streams are specified as groups of component-efficiency pairs where 'component' means either a particular element or a particular nuclide. Each component's paired efficiency represents the mass fraction of that component in the feed that is separated into that stream. The efficiencies of a particular component across all streams must sum up to less than or equal to one. If less than one, the remainining material is sent to a waste inventory and (potentially) traded away from there.\n\nThe facility receives material into a feed inventory that it processes with a specified throughput each time step. Each output stream has a corresponding output inventory size/limit. If the facility is unable to reduce its stocks by trading and hits this limit for any of its output streams, further processing/separations of feed material will halt until room is again available in the output streams.", + "entity": "facility", + "name": "cycamore::Separations", + "niche": "separations", + "parents": ["cyclus::Facility"], + "vars": { + "feed": { + "capacity": "feedbuf_size", + "index": 4, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + }, + "feed_commod_prefs": { + "alias": ["feed_commod_prefs", "val"], + "default": [], + "doc": "Feed commodity request preferences for each of the given feed commodities (same order). If unspecified, default is to use zero for all preferences.", + "index": 1, + "tooltip": ["feed_commod_prefs", ""], + "type": ["std::vector", "double"], + "uilabel": ["Feed Commodity Preference List", ""] + }, + "feed_commods": { + "alias": ["feed_commods", "val"], + "doc": "Ordered list of commodities on which to request feed material to separate. Order only matters for matching up with feed commodity preferences if specified.", + "index": 0, + "tooltip": ["feed_commods", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["Feed Commodity List", ""], + "uitype": ["oneormore", "incommodity"] + }, + "feed_recipe": { + "alias": "feed_recipe", + "default": "", + "doc": "Name for recipe to be used in feed requests. Empty string results in use of a dummy recipe.", + "index": 2, + "tooltip": "feed_recipe", + "type": "std::string", + "uilabel": "Feed Commodity Recipe List", + "uitype": "recipe" + }, + "feedbuf_size": { + "alias": "feedbuf_size", + "doc": "Maximum amount of feed material to keep on hand.", + "index": 3, + "tooltip": "feedbuf_size", + "type": "double", + "uilabel": "Maximum Feed Inventory", + "units": "kg" + }, + "leftover": { + "capacity": "leftoverbuf_size", + "index": 8, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Material"] + }, + "leftover_commod": { + "alias": "leftover_commod", + "default": "default-waste-stream", + "doc": "Commodity on which to trade the leftover separated material stream. This MUST NOT be the same as any commodity used to define the other separations streams.", + "index": 6, + "tooltip": "leftover_commod", + "type": "std::string", + "uilabel": "Leftover Commodity", + "uitype": "outcommodity" + }, + "leftoverbuf_size": { + "alias": "leftoverbuf_size", + "default": 1.000000000000000e+299, + "doc": "Maximum amount of leftover separated material (not included in any other stream) that can be stored. If full, the facility halts operation until space becomes available.", + "index": 7, + "tooltip": "leftoverbuf_size", + "type": "double", + "uilabel": "Maximum Leftover Inventory", + "units": "kg" + }, + "streams": "streams_", + "streams_": { + "alias": [ + ["streams", "item"], + "commod", + ["info", "buf_size", [["efficiencies", "item"], "comp", "eff"]] + ], + "doc": "Output streams for separations. Each stream must have a unique name identifying the commodity on which its material is traded, a max buffer capacity in kg (neg values indicate infinite size), and a set of component efficiencies. 'comp' is a component to be separated into the stream (e.g. U, Pu, etc.) and 'eff' is the mass fraction of the component that is separated from the feed into this output stream. If any stream buffer is full, the facility halts operation until space becomes available. The sum total of all component efficiencies across streams must be less than or equal to 1 (e.g. sum of U efficiencies for all streams must be <= 1).", + "index": 9, + "tooltip": [["streams_", ""], "", ["", "", [["", ""], "", ""]]], + "type": [ + "std::map", + "std::string", + ["std::pair", "double", ["std::map", "int", "double"]] + ], + "uilabel": [["Separations Streams and Efficiencies", ""], "", ["", "", [["", ""], "", ""]]], + "uitype": [ + "oneormore", + "outcommodity", + ["pair", "double", ["oneormore", "nuclide", "double"]] + ] + }, + "throughput": { + "alias": "throughput", + "doc": "Maximum quantity of feed material that can be processed per time step.", + "index": 5, + "tooltip": "throughput", + "type": "double", + "uilabel": "Maximum Separations Throughput", + "units": "kg" + } + } + }, + ":cycamore:Sink": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader" + ], + "doc": " A sink facility that accepts materials and products with a fixed\n throughput (per time step) capacity and a lifetime capacity defined by\n a total inventory size. The inventory size and throughput capacity\n both default to infinite. If a recipe is provided, it will request\n material with that recipe. Requests are made for any number of\n specified commodities.\n", + "entity": "facility", + "name": "cycamore::Sink", + "parents": ["cyclus::Facility"], + "vars": { + "capacity": { + "alias": "capacity", + "default": 1.000000000000000e+299, + "doc": "capacity the sink facility can accept at each time step", + "index": 3, + "tooltip": "sink capacity", + "type": "double", + "uilabel": "Maximum Throughput" + }, + "in_commods": { + "alias": ["in_commods", "val"], + "doc": "commodities that the sink facility accepts", + "index": 0, + "tooltip": ["input commodities", ""], + "type": ["std::vector", "std::string"], + "uilabel": ["List of Input Commodities", ""], + "uitype": ["oneormore", "incommodity"] + }, + "inventory": { + "capacity": "max_inv_size", + "index": 4, + "type": ["cyclus::toolkit::ResBuf", "cyclus::Resource"] + }, + "max_inv_size": { + "alias": "max_inv_size", + "default": 1.000000000000000e+299, + "doc": "total maximum inventory size of sink facility", + "index": 2, + "tooltip": "sink maximum inventory size", + "type": "double", + "uilabel": "Maximum Inventory" + }, + "recipe_name": { + "alias": "recipe_name", + "default": "", + "doc": "name of recipe to use for material requests, where the default (empty string) is to accept everything", + "index": 1, + "tooltip": "requested composition", + "type": "std::string", + "uilabel": "Input Recipe", + "uitype": "recipe" + } + } + }, + ":cycamore:Source": { + "all_parents": [ + "cyclus::Agent", + "cyclus::Facility", + "cyclus::Ider", + "cyclus::StateWrangler", + "cyclus::TimeListener", + "cyclus::Trader", + "cyclus::toolkit::AgentManaged", + "cyclus::toolkit::CommodityProducer" + ], + "doc": "This facility acts as a source of material with a fixed throughput (per\ntime step) capacity and a lifetime capacity defined by a total inventory\nsize. It offers its material as a single commodity. If a composition\nrecipe is specified, it provides that single material composition to\nrequesters. If unspecified, the source provides materials with the exact\nrequested compositions. The inventory size and throughput both default to\ninfinite. Supplies material results in corresponding decrease in\ninventory, and when the inventory size reaches zero, the source can provide\nno more material.\n", + "entity": "facility", + "name": "cycamore::Source", + "parents": ["cyclus::Facility", "cyclus::toolkit::CommodityProducer"], + "vars": { + "inventory_size": { + "alias": "inventory_size", + "default": 1.000000000000000e+299, + "doc": "Total amount of material this source has remaining. Every trade decreases this value by the supplied material quantity. When it reaches zero, the source cannot provide any more material.", + "index": 2, + "tooltip": "inventory_size", + "type": "double", + "uilabel": "Initial Inventory", + "units": "kg" + }, + "outcommod": { + "alias": "outcommod", + "doc": "Output commodity on which the source offers material.", + "index": 0, + "tooltip": "source output commodity", + "type": "std::string", + "uilabel": "Output Commodity", + "uitype": "outcommodity" + }, + "outrecipe": { + "alias": "outrecipe", + "default": "", + "doc": "Name of composition recipe that this source provides regardless of requested composition. If empty, source creates and provides whatever compositions are requested.", + "index": 1, + "tooltip": "name of material recipe to provide", + "type": "std::string", + "uilabel": "Output Recipe", + "uitype": "recipe" + }, + "throughput": { + "alias": "throughput", + "default": 1.000000000000000e+299, + "doc": "amount of commodity that can be supplied at each time step", + "index": 3, + "tooltip": "per time step throughput", + "type": "double", + "uilabel": "Maximum Throughput", + "units": "kg/(time step)" + } + } + } + }, + "schema": { + ":agents:KFacility": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":agents:NullInst": "", + ":agents:NullRegion": "", + ":agents:Predator": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":agents:Prey": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":agents:Sink": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":agents:Source": "\n \n \n \n \n \n \n \n \n \n \n \n\n", + ":cycamore:DeployInst": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":cycamore:Enrichment": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 0\n 1\n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":cycamore:FuelFab": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":cycamore:GrowthRegion": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":cycamore:ManagerInst": "\n \n \n \n \n \n \n \n\n", + ":cycamore:Reactor": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":cycamore:Separations": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":cycamore:Sink": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + ":cycamore:Source": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "specs": [ + ":agents:KFacility", + ":agents:NullInst", + ":agents:NullRegion", + ":agents:Predator", + ":agents:Prey", + ":agents:Sink", + ":agents:Source", + ":cycamore:DeployInst", + ":cycamore:Enrichment", + ":cycamore:FuelFab", + ":cycamore:GrowthRegion", + ":cycamore:ManagerInst", + ":cycamore:Reactor", + ":cycamore:Separations", + ":cycamore:Sink", + ":cycamore:Source" + ] +} diff --git a/cyclist/src/edu/utah/sci/cyclist/assets/process_sqlite.sql b/cyclist/src/edu/utah/sci/cyclist/assets/process_sqlite.sql new file mode 100644 index 00000000..a0b658d4 --- /dev/null +++ b/cyclist/src/edu/utah/sci/cyclist/assets/process_sqlite.sql @@ -0,0 +1,80 @@ +-- VERSION: 1.0 + +-- Cyclist info +CREATE table if not exists Cyclist ( + Version TEXT primary key, + Date Date); + +-- Ensure Agents compatibility +UPDATE Agents set ExitTime = EnterTime+(select Duration from Info where Agents.SimId=Info.SimId ) + WHERE ExitTime is null and Lifetime = -1; + +UPDATE Agents set ExitTime=(EnterTime+Lifetime) where ExitTime is null and Lifetime != -1; + +-- Create Facilities +create table if not exists Facilities ( + SimID BLOB, + AgentId INTEGER, + Spec TEXT, + Prototype TEXT, + InstitutionId INTEGER, + RegionId INTEGER, + EnterTime INTEGER, + ExitTime INTEGER, + Lifetime INTEGER); + +REPLACE into Facilities(SimID,AgentId,Spec,Prototype,InstitutionId,RegionId,EnterTime,ExitTime,Lifetime) + select f.SimId, f.AgentId, f.Spec, f.Prototype, i.AgentId, + cast(-1 as INTEGER), f.EnterTime, f.ExitTime, f.Lifetime from Agents as f, Agents as i + where f.Kind = 'Facility' and i.Kind = 'Inst' and f.ParentId = i.AgentId and f.SimId = i.SimId; + +CREATE INDEX if not exists Facilities_idx on Facilities (SimId ASC, AgentId ASC); + +-- Inventory +CREATE table if not exists QuantityInventoryBase as + SELECT inv.SimId as SimId, tl.Time AS Time,cmp.NucId AS NucId,ag.AgentID as AgentID, + cast(SUM(inv.Quantity*cmp.MassFrac) as REAL) AS Quantity + FROM + Timelist AS tl + INNER JOIN Inventories AS inv ON inv.StartTime <= tl.Time AND inv.EndTime > tl.Time + INNER JOIN Agents AS ag ON ag.AgentId = inv.AgentId + INNER JOIN Compositions AS cmp ON cmp.QualId = inv.QualId + WHERE + inv.SimId = cmp.SimId AND inv.SimId = ag.SimId and tl.SimId=inv.SimId + GROUP BY inv.SimId, tl.Time, cmp.NucId, ag.AgentID; + +CREATE INDEX IF NOT EXISTS QuantityInventoryBase_idx ON QuantityInventoryBase (simid,agentid,time,nucid,quantity); + +CREATE view if not exists QuantityInventory as + SELECT base.SimID as SimID, Time, Quantity, NucId, base.AgentId as AgentId, Kind, Spec, Prototype + FROM + QuantityInventoryBase as base, Agents ag + WHERE + base.SimID = ag.SimID + AND base.AgentId = ag.AgentId; + +-- Transacted +CREATE table if not exists QuantityTransactedBase as + SELECT res.SimId as SimId, tr.Time AS Time,cmp.NucId AS NucId, ag.AgentID as AgentID, + cast(SUM(cmp.MassFrac * res.Quantity) AS REAL) AS Quantity + FROM + Resources AS res + INNER JOIN Transactions AS tr ON tr.ResourceId = res.ResourceId + INNER JOIN Agents AS ag ON ag.AgentId = tr.SenderID + INNER JOIN Compositions AS cmp ON cmp.QualId = res.QualId + WHERE + tr.SimId = res.SimId AND ag.SimId = tr.SimId and cmp.SimId=res.SimId + GROUP BY res.SimId, cmp.NucId, tr.Time, ag.AgentID + ORDER BY tr.Time ASC; + +CREATE INDEX IF NOT EXISTS QuantityTransactedBase_idx ON QuantityTransactedBase (simid,agentid,time,nucid,quantity); ; + +CREATE view if not exists QuantityTransacted as + SELECT base.SimID as SimID, Time, Quantity, NucId, base.AgentId as AgentId, Kind, Spec, Prototype + FROM + QuantityTransactedBase as base, Agents ag + WHERE + base.SimID = ag.SimID + AND base.AgentId = ag.AgentId; + + diff --git a/cyclist/skinImages/fuelcycle_abr.png b/cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_abr.png similarity index 100% rename from cyclist/skinImages/fuelcycle_abr.png rename to cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_abr.png diff --git a/cyclist/skinImages/fuelcycle_enr.png b/cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_enr.png similarity index 100% rename from cyclist/skinImages/fuelcycle_enr.png rename to cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_enr.png diff --git a/cyclist/skinImages/fuelcycle_fab.png b/cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_fab.png similarity index 100% rename from cyclist/skinImages/fuelcycle_fab.png rename to cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_fab.png diff --git a/cyclist/skinImages/fuelcycle_geo.png b/cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_geo.png similarity index 100% rename from cyclist/skinImages/fuelcycle_geo.png rename to cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_geo.png diff --git a/cyclist/skinImages/fuelcycle_mine.png b/cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_mine.png similarity index 100% rename from cyclist/skinImages/fuelcycle_mine.png rename to cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_mine.png diff --git a/cyclist/skinImages/fuelcycle_rxtr.png b/cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_rxtr.png similarity index 100% rename from cyclist/skinImages/fuelcycle_rxtr.png rename to cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_rxtr.png diff --git a/cyclist/skinImages/fuelcycle_sep.png b/cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_sep.png similarity index 100% rename from cyclist/skinImages/fuelcycle_sep.png rename to cyclist/src/edu/utah/sci/cyclist/assets/skinImages/fuelcycle_sep.png diff --git a/cyclist/skinImages/reactor.png b/cyclist/src/edu/utah/sci/cyclist/assets/skinImages/reactor.png similarity index 100% rename from cyclist/skinImages/reactor.png rename to cyclist/src/edu/utah/sci/cyclist/assets/skinImages/reactor.png diff --git a/cyclist/src/edu/utah/sci/cyclist/core/controller/CyclistController.java b/cyclist/src/edu/utah/sci/cyclist/core/controller/CyclistController.java index 0e89cd33..ecc2a91a 100755 --- a/cyclist/src/edu/utah/sci/cyclist/core/controller/CyclistController.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/controller/CyclistController.java @@ -29,6 +29,9 @@ import java.io.InputStream; import java.io.PrintWriter; import java.io.Reader; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -45,8 +48,8 @@ import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.control.MenuItem; +import javafx.scene.control.Tab; import javafx.stage.DirectoryChooser; -import javafx.stage.FileChooser; import javafx.stage.Stage; import javafx.stage.WindowEvent; @@ -60,6 +63,7 @@ import edu.utah.sci.cyclist.core.model.CyclistDatasource; import edu.utah.sci.cyclist.core.model.Field; import edu.utah.sci.cyclist.core.model.Model; +import edu.utah.sci.cyclist.core.model.Perspective; import edu.utah.sci.cyclist.core.model.Preferences; import edu.utah.sci.cyclist.core.model.Simulation; import edu.utah.sci.cyclist.core.model.Table; @@ -68,21 +72,19 @@ import edu.utah.sci.cyclist.core.presenter.SchemaPresenter; import edu.utah.sci.cyclist.core.presenter.SimulationPresenter; import edu.utah.sci.cyclist.core.presenter.ToolsPresenter; -import edu.utah.sci.cyclist.core.presenter.WorkspacePresenter; +import edu.utah.sci.cyclist.core.presenter.VisWorkspacePresenter; import edu.utah.sci.cyclist.core.services.CyclusService; import edu.utah.sci.cyclist.core.tools.ToolFactory; import edu.utah.sci.cyclist.core.ui.MainScreen; +import edu.utah.sci.cyclist.core.ui.components.ViewBase; import edu.utah.sci.cyclist.core.ui.panels.JobsPanel; -import edu.utah.sci.cyclist.core.ui.views.Workspace; +import edu.utah.sci.cyclist.core.ui.views.VisWorkspace; import edu.utah.sci.cyclist.core.ui.wizards.DatatableWizard; -import edu.utah.sci.cyclist.core.ui.wizards.ManageRemoteServersWizard; import edu.utah.sci.cyclist.core.ui.wizards.PreferencesWizard; -import edu.utah.sci.cyclist.core.ui.wizards.RemoteServerWizard; import edu.utah.sci.cyclist.core.ui.wizards.SaveWsWizard; import edu.utah.sci.cyclist.core.ui.wizards.SimulationWizard; import edu.utah.sci.cyclist.core.ui.wizards.SqliteLoaderWizard; import edu.utah.sci.cyclist.core.util.LoadSqlite; -import edu.utah.sci.cyclist.core.util.StreamUtils; public class CyclistController { @@ -91,14 +93,20 @@ public class CyclistController { private final EventBus _eventBus; private MainScreen _screen; - public static WorkspacePresenter _presenter; + public static VisWorkspacePresenter _presenter; private Model _model = new Model(); private String SAVE_FILE = "workspace-config.xml"; - private WorkDirectoryController _workDirectoryController; + private SessionController _sessionController; private Boolean _dirtyFlag = false; public static CyclusService _cyclusService; - private static final String SIMULATIONS_TABLES_FILE = "assets/SimulationTablesDef.xml"; + private static final String SIMULATIONS_TABLES_FILE = "SimulationTablesDef.xml"; + + private Perspective _perspectives[] = { + new Perspective(0, "Scenario Builder", ToolsLibrary.SCENARIO_TOOL, Arrays.asList("Builder", "Jobs")), + new Perspective(1, "Data Exploration", ToolsLibrary.VIS_TOOL, Arrays.asList("Simulations", "Tables", "Fields", "Filters", "Jobs")) + }; + private Perspective _currentPerspective = null; /** * Constructor @@ -118,20 +126,20 @@ public void invalidated(Observable observable) { // TODO: fix this hack. We need a better way of passing around the list of datasources LoadSqlite.setSources(_model.getSources()); - _workDirectoryController = new WorkDirectoryController(); + _sessionController = new SessionController(); // If the save directory does not exist, create it - File saveDir = new File(WorkDirectoryController.CYCLIST_DIR); + File saveDir = new File(SessionController.CYCLIST_DIR); if (!saveDir.exists()) saveDir.mkdir(); - File defaultWs = new File(WorkDirectoryController.DEFAULT_WORKSPACE); + File defaultWs = new File(SessionController.DEFAULT_WORKSPACE); if (!defaultWs.exists()) defaultWs.mkdir(); - if (_workDirectoryController.initGeneralConfigFile()) + if (_sessionController.initGeneralConfigFile()) { - _workDirectoryController.restoreGeneralConfigFile(); + _sessionController.restoreGeneralConfigFile(); } } @@ -153,6 +161,17 @@ public void setScreen(final MainScreen screen) { ds.setTables(_model.getTables()); ds.setPanel(screen.getDatasourcesPanel()); + screen.getDatasourcesPanel().setTableActions(Arrays.asList("Plot"), + action -> { + try { + _presenter + .addTool(ToolsLibrary.getFactory(action.v1).create()) + .addTable(action.v2); + } catch (Exception e) { + log.error("internal error: ",e); + } + }); + // Schema panel SchemaPresenter sp = new SchemaPresenter(_eventBus); sp.setPanel(screen.getFieldsPanel()); @@ -176,24 +195,72 @@ public void call(List list) { // ToolsLibrary panel ToolsPresenter tp = new ToolsPresenter(_eventBus); tp.setPanel(screen.getToolsPanel()); - tp.setFactories(Arrays.asList(ToolsLibrary.factories)); + tp.setFactories(ToolsLibrary.getFactoriesOfType(ToolsLibrary.VIS_TOOL, true)); // InputLibrary panel InputPresenter ip = new InputPresenter(_eventBus); ip.setPanel(screen.getInputPanel()); - ip.setFactories(Arrays.asList(ToolsLibrary.inputFactories)); + ip.setFactories(ToolsLibrary.getFactoriesOfType(ToolsLibrary.SCENARIO_TOOL, true)); - // set up the main workspace - Workspace workspace = new Workspace(true); -// workspace.setWorkDirPath(getLastChosenWorkDirectory()); - screen.setWorkspace(workspace); + // Builder perspectives + + for (Perspective p : _perspectives) { + ViewBase workspace = new VisWorkspace(true); + p.presenter = new VisWorkspacePresenter(_eventBus); + p.presenter.setView(workspace); + + Tab tab = new Tab(); + tab.setText(p.name); + tab.setClosable(false); + tab.setContent(workspace); + screen.getTabPane().getTabs().add(tab); + +// + } - _presenter = new WorkspacePresenter(_eventBus); - _presenter.setView(workspace); + screen.getTabPane().getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue o, Number prev, Number id) { + perspectiveChanged(id.intValue()); + + } + }); - // do something? - //selectWorkspace(); restore(); + + selectPerspective(_currentPerspective.id); + if (_currentPerspective.id == 0) + perspectiveChanged(_currentPerspective.id); + } + + private void selectPerspective(int id) { + _screen.getTabPane().getSelectionModel().select(id); + } + + private void perspectiveChanged(int id) { + if (_currentPerspective != null && _currentPerspective.id != id) { + _currentPerspective.setToolsPositions(_screen.getToolsPositions()); + _presenter.getWorkspace().getConsole().setActive(false); + } + + _currentPerspective = _perspectives[id]; + if (!_currentPerspective.initialized) { + _currentPerspective.init(); + if (id == 0) { + try { + if (!_perspectives[0].presenter.hasTool("Cycic")) { + ToolFactory factory = ToolsLibrary.getFactory("Cycic"); + _perspectives[0].presenter.addTool(factory.create(), 0, 0); + } + } catch (Exception e) { + log.error("Can create scenario builder"); + } + } + } + _presenter = _currentPerspective.presenter; + _presenter.getWorkspace().getConsole().setActive(true); + _screen.showPanels(_currentPerspective.tools, _currentPerspective.toolsPositions); + _screen.selectTools( _currentPerspective.type); } /** @@ -202,31 +269,24 @@ public void call(List list) { */ public void selectWorkspace() { - if(_workDirectoryController == null){ + if(_sessionController == null){ return; } - ObservableList selection = _screen.selectWorkspace(_workDirectoryController.getWorkDirectories(), - _workDirectoryController.getLastChosenIndex()); + ObservableList selection = _screen.selectWorkspace(_sessionController.getWorkDirectories(), + _sessionController.getLastChosenIndex()); selection.addListener(new ListChangeListener(){ @Override public void onChanged(Change list ){ - if(_workDirectoryController != null){ - if(_workDirectoryController.handleWorkDirectoriesListChangedEvent(list)){ + if(_sessionController != null){ + if(_sessionController.handleWorkDirectoriesListChangedEvent(list)){ restore(); //Set all the views to match the new tables. ObservableList emptyList = FXCollections.observableArrayList(); _screen.getFieldsPanel().setFields(emptyList); - -// //Set the workspace to display the new path at the title. -// Workspace workspace = _screen.getWorkspace(); -// if(workspace != null){ -// workspace.setWorkDirPath(getLastChosenWorkDirectory()); -// } - } } @@ -292,7 +352,6 @@ public void onChanged(ListChangeListener.Change newList) { Simulation sim = simulation.clone(); Simulation existingSim = _model.simExists(simulation); if(existingSim==null){ -// _model.getSimulations().add(sim); newSimulations.add(sim); _dirtyFlag = true; }else if(!existingSim.getAlias().equals(simulation.getAlias())){ @@ -338,7 +397,6 @@ public void onChanged(ListChangeListener.Change newList) { Simulation existingSim = _model.simExists(simulation); if(existingSim == null){ newSimulations.add(sim); -// _model.getSimulations().add(sim); _dirtyFlag = true; }else if(!existingSim.getAlias().equals(simulation.getAlias())){ existingSim.setAlias(simulation.getAlias()); @@ -358,80 +416,80 @@ public void onChanged(ListChangeListener.Change newList) { } }); - _screen.onRun().set(new EventHandler() { - @Override - public void handle(ActionEvent event) { - String server = ""; - if(event.getSource() instanceof MenuItem){ - server = (String) ((MenuItem)event.getSource()).getUserData(); - if(server.isEmpty()){ - server = Preferences.getInstance().getDefaultServer(); - } - } - FileChooser chooser = new FileChooser(); - chooser.getExtensionFilters().add( new FileChooser.ExtensionFilter("Cyclus files (*.xml)", "*.xml") ); - File file = chooser.showOpenDialog(Cyclist.cyclistStage); - if (file != null) { - _cyclusService.submit(file, server); - } - } - }); - - _screen.onManage().set(new EventHandler() { - @Override - public void handle(ActionEvent event) { - ManageRemoteServersWizard wizard = new ManageRemoteServersWizard(_model.getRemoteServersList()); - ObservableList deletedServers = wizard.show(_screen.getParent().getScene().getWindow()); - deletedServers.addListener(new ListChangeListener() { - @Override - public void onChanged(ListChangeListener.Change listChange) { - List items = new ArrayList(); - for(String server:listChange.getList()){ - _model.getRemoteServersList().remove(server); - for(MenuItem item : _screen.getRemoteServers()){ - if(item.getText().equals(server)){ - items.add(item); - } - } - } - for(MenuItem item : items){ - _screen.getRemoteServers().remove(item); - } - } - }); - - } - }); - - _screen.onRunOnOther().set(new EventHandler() { - @Override - public void handle(ActionEvent event) { - RemoteServerWizard wizard = new RemoteServerWizard(); - ObjectProperty selection = wizard.show(_screen.getParent().getScene().getWindow()); - selection.addListener(new ChangeListener(){ - @Override - public void changed(ObservableValue arg0, String oldVal,String newVal) { - if(!newVal.isEmpty()){ - if(_model.addNewRemoteServer(newVal)){ - MenuItem item = new MenuItem(newVal); - _screen.getRemoteServers().add(item); - _dirtyFlag = true; - item.fire(); - }else{ - //Item already exists - for(MenuItem menuItem :_screen.getRemoteServers()){ - if(menuItem.getText().equals(newVal)){ - menuItem.fire(); - break; - } - } - } - - } - } - }); - } - }); +// _screen.onRun().set(new EventHandler() { +// @Override +// public void handle(ActionEvent event) { +// String server = ""; +// if(event.getSource() instanceof MenuItem){ +// server = (String) ((MenuItem)event.getSource()).getUserData(); +// if(server.isEmpty()){ +// server = Preferences.getInstance().getDefaultServer(); +// } +// } +// FileChooser chooser = new FileChooser(); +// chooser.getExtensionFilters().add( new FileChooser.ExtensionFilter("Cyclus files (*.xml)", "*.xml") ); +// File file = chooser.showOpenDialog(Cyclist.cyclistStage); +// if (file != null) { +// _cyclusService.submit(file, server); +// } +// } +// }); + +// _screen.onManage().set(new EventHandler() { +// @Override +// public void handle(ActionEvent event) { +// ManageRemoteServersWizard wizard = new ManageRemoteServersWizard(_model.getRemoteServersList()); +// ObservableList deletedServers = wizard.show(_screen.getParent().getScene().getWindow()); +// deletedServers.addListener(new ListChangeListener() { +// @Override +// public void onChanged(ListChangeListener.Change listChange) { +// List items = new ArrayList(); +// for(String server:listChange.getList()){ +// _model.getRemoteServersList().remove(server); +// for(MenuItem item : _screen.getRemoteServers()){ +// if(item.getText().equals(server)){ +// items.add(item); +// } +// } +// } +// for(MenuItem item : items){ +// _screen.getRemoteServers().remove(item); +// } +// } +// }); +// +// } +// }); + +// _screen.onRunOnOther().set(new EventHandler() { +// @Override +// public void handle(ActionEvent event) { +// RemoteServerWizard wizard = new RemoteServerWizard(); +// ObjectProperty selection = wizard.show(_screen.getParent().getScene().getWindow()); +// selection.addListener(new ChangeListener(){ +// @Override +// public void changed(ObservableValue arg0, String oldVal,String newVal) { +// if(!newVal.isEmpty()){ +// if(_model.addNewRemoteServer(newVal)){ +// MenuItem item = new MenuItem(newVal); +// _screen.getRemoteServers().add(item); +// _dirtyFlag = true; +// item.fire(); +// }else{ +// //Item already exists +// for(MenuItem menuItem :_screen.getRemoteServers()){ +// if(menuItem.getText().equals(newVal)){ +// menuItem.fire(); +// break; +// } +// } +// } +// +// } +// } +// }); +// } +// }); _screen.onSelectWorkspace().set(new EventHandler(){ @@ -439,8 +497,11 @@ public void changed(ObservableValue arg0, String oldVal,String public void handle(ActionEvent arg0) { //If need to save the current workspace data - ask the user whether to save it or not - - if(_dirtyFlag || _presenter.getDirtyFlag()){ + boolean dirty = _dirtyFlag; + for (Perspective p : _perspectives) { + dirty |= p.presenter.getDirtyFlag(); + } + if (dirty) { SaveWsWizard wizard = new SaveWsWizard(); ObjectProperty selection = wizard.show(_screen.getParent().getScene().getWindow()); selection.addListener(new ChangeListener(){ @@ -476,7 +537,7 @@ public void handle(ActionEvent event) { File dir = new File(getLastChosenWorkDirectory()); String parent=""; if(!dir.exists()){ - parent = WorkDirectoryController.DEFAULT_WORKSPACE; + parent = SessionController.DEFAULT_WORKSPACE; }else{ parent = dir.getParent(); } @@ -487,7 +548,7 @@ public void handle(ActionEvent event) { if (file != null) { saveAs(file.getAbsolutePath()); //Display the new directory in the work directories dialog. - _workDirectoryController.addNewDir(file.getAbsolutePath()); + _sessionController.addNewDir(file.getAbsolutePath()); } } }); @@ -563,42 +624,43 @@ public void handle(WindowEvent event) { quit(); } }); - ; + EventHandler viewAction = new EventHandler() { @Override public void handle(ActionEvent event) { MenuItem item = (MenuItem) event.getSource(); - for (ToolFactory factory : ToolsLibrary.factories) { - if (factory.getToolName().equals(item.getText())) { - try { - _presenter.addTool(factory.create()); - } catch (Exception e) { - e.printStackTrace(); - } - } + try { + ToolFactory factory = ToolsLibrary.getFactory(item.getText()); + _presenter.addTool(factory.create()); + } catch (Exception e) { + log.error("Internal error: Can't find tool "+item.getText()); } } }; - for (MenuItem item : _screen.getViewMenu().getItems()) { + for (MenuItem item : _screen.getToolsMenu().getItems()) { item.setOnAction(viewAction); } _model.getSimulations().addListener(new ListChangeListener() { @Override public void onChanged(ListChangeListener.Change listChange) { - while (listChange.next()) { - for(Simulation sim : listChange.getRemoved()){ - _presenter.removeSimulation(sim); - _model.markSimALiasAsRemoved(sim); - } - boolean select = true; - for(Simulation sim : listChange.getAddedSubList()){ - _model.addNewSimALias(sim,""); - //If there are a few simulations added at the same time - select only the first. - _presenter.addFirstSelectedSimulation(sim,select); - if(select){ - select = false; + if (_presenter instanceof VisWorkspacePresenter) { + VisWorkspacePresenter p = (VisWorkspacePresenter) _presenter; + + while (listChange.next()) { + for(Simulation sim : listChange.getRemoved()){ + p.removeSimulation(sim); + _model.markSimALiasAsRemoved(sim); + } + boolean select = true; + for(Simulation sim : listChange.getAddedSubList()){ + _model.addNewSimALias(sim,""); + //If there are a few simulations added at the same time - select only the first. + p.addFirstSelectedSimulation(sim,select); + if(select){ + select = false; + } } } } @@ -609,7 +671,14 @@ public void onChanged(ListChangeListener.Change listChange private void quit() { - if(_dirtyFlag || _presenter.getDirtyFlag()){ + _currentPerspective.setToolsPositions(_screen.getToolsPositions()); + + boolean dirty = _dirtyFlag || Preferences.getInstance().isDirty(); + for (Perspective p : _perspectives) { + dirty |= p.presenter.getDirtyFlag(); + } + + if(dirty){ SaveWsWizard wizard = new SaveWsWizard(); ObjectProperty selection = wizard.show(_screen.getParent().getScene().getWindow()); selection.addListener(new ChangeListener(){ @@ -632,6 +701,8 @@ private void save() { private void saveAs(String workdir) { + _currentPerspective.setToolsPositions(_screen.getToolsPositions()); + IMemento child; File saveDir = new File(workdir); if (!saveDir.exists()) @@ -679,11 +750,15 @@ private void saveAs(String workdir) { Preferences.getInstance().save(memento.createChild("Preferences")); //Save the remote servers - saveRemoteServers(memento); +// saveRemoteServers(memento); _cyclusService.save(memento.createChild("Jobs")); - _presenter.save(memento.createChild("workspace")); + IMemento perspectives_memento = memento.createChild("Perspectives"); + perspectives_memento.putInteger("current", _currentPerspective.id); + for (Perspective p : _perspectives) { + p.save(perspectives_memento.createChild("Perspective")); + } //First save the main workspace IMemento mainWs = memento.createChild("main-window"); @@ -703,7 +778,7 @@ private void saveAs(String workdir) { private void restore() { - String currDirectory = _workDirectoryController.getWorkDirectories().get(_workDirectoryController.getLastChosenIndex()); + String currDirectory = _sessionController.getWorkDirectories().get(_sessionController.getLastChosenIndex()); // Check if the save file exists File saveFile = new File(currDirectory+"/"+SAVE_FILE); @@ -712,9 +787,11 @@ private void restore() { clearModel(); //Clears the main workspace. - _presenter.clearWorkspace(); + for(Perspective p : _perspectives) { + p.presenter.clearWorkspace(); + } - _screen.getRemoteServers().clear(); +// _screen.getRemoteServers().clear(); Context ctx = new Context(); readSimulationsTables(ctx); @@ -777,8 +854,8 @@ private void restore() { //Read the preferences. Preferences.getInstance().restore(memento.getChild("Preferences")); - //Read the remote servers - restoreRemoteServers(memento); +// //Read the remote servers +// restoreRemoteServers(memento); _cyclusService.restore(memento.getChild("Jobs")); @@ -789,20 +866,38 @@ private void restore() { restoreMainScreen(mainWs.getChild("geom")); _screen.restore(mainWs, ctx); - IMemento toolsRoot = memento.getChild("workspace"); - if(toolsRoot != null){ - _presenter.restore(toolsRoot, ctx); + + IMemento p_memento = memento.getChild("Perspectives"); + if (p_memento != null) { + for (IMemento child : p_memento.getChildren("Perspective")) { + Perspective p = _perspectives[child.getInteger("id")]; + p.restore(child, ctx); + } + + int i = 0; + try { + i = p_memento.getInteger("current"); + } catch(Exception e) { + // ignore + } + _currentPerspective= _perspectives[i]; + } else { + _currentPerspective= _perspectives[0]; + if (memento.getChild("workspace") != null) { + _perspectives[0].restore(memento, ctx); + } } } catch (Exception e) { log.error("Error during restore: "+e.getMessage()); - e.printStackTrace(); } } catch (FileNotFoundException e) { log.error("Error during restore: "+e.getMessage()); - e.printStackTrace(); } } + + if (_currentPerspective == null) + _currentPerspective = _perspectives[0]; } /* @@ -812,23 +907,25 @@ private void restore() { */ private void readSimulationsTables(Context ctx){ try { - InputStream in = Cyclist.class.getResourceAsStream(SIMULATIONS_TABLES_FILE); - File simulationsFile = StreamUtils.stream2file(in); - if(simulationsFile.exists()){ - Reader reader = new FileReader(simulationsFile); - XMLMemento memento = XMLMemento.createReadRoot(reader); - - // Restore tables - for(IMemento node: memento.getChildren("Table")){ - Table table = new Table(); - table.restoreSimulated(node, ctx); - table.setLocalDatafile(getLastChosenWorkDirectory()); - _model.getSimulationsTablesDef().add(table); - _model.getTables().add(table); - } + Path path = FileSystems.getDefault().getPath(SessionController.CYCLIST_DIR, SIMULATIONS_TABLES_FILE); + if (!Files.exists(path)) { + InputStream in = Cyclist.class.getResourceAsStream("assets/"+SIMULATIONS_TABLES_FILE); + Files.copy(in, path); + } + File simulationsFile = path.toFile(); + Reader reader = new FileReader(simulationsFile); + XMLMemento memento = XMLMemento.createReadRoot(reader); + + // Restore tables + for(IMemento node: memento.getChildren("Table")){ + Table table = new Table(); + table.restoreSimulated(node, ctx); + table.setLocalDatafile(getLastChosenWorkDirectory()); + _model.getSimulationsTablesDef().add(table); + _model.getTables().add(table); } } catch (Exception e) { - log.info("Exception " + e.getMessage()); + log.error(e.getMessage()); } } @@ -837,10 +934,10 @@ private void readSimulationsTables(Context ctx){ * If not available - return the default work directory */ private String getLastChosenWorkDirectory(){ - if(_workDirectoryController == null){ - return WorkDirectoryController.CYCLIST_DIR; + if(_sessionController == null){ + return SessionController.CYCLIST_DIR; } - return _workDirectoryController.getWorkDirectories().get(_workDirectoryController.getLastChosenIndex()); + return _sessionController.getWorkDirectories().get(_sessionController.getLastChosenIndex()); } /* @@ -880,40 +977,40 @@ private void clearModel(){ _model.getTables().clear(); _model.getSimulations().clear(); _model.setSelectedDatasource(null); - _model.getRemoteServersList().clear(); +// _model.getRemoteServersList().clear(); } /* * Saves the list of remote servers from the model. * @param IMemento memento */ - private void saveRemoteServers(IMemento memento){ - IMemento remotes = memento.createChild("remote-servers"); - for(String remote : _model.getRemoteServersList()){ - IMemento server = remotes.createChild("Server"); - server.putString("address", remote); - } - } +// private void saveRemoteServers(IMemento memento){ +// IMemento remotes = memento.createChild("remote-servers"); +// for(String remote : _model.getRemoteServersList()){ +// IMemento server = remotes.createChild("Server"); +// server.putString("address", remote); +// } +// } /* * Restores the list of remote servers. * Adds the list to the model and creates corresponding menu items in the main screen menu. * @param IMemento memento. */ - private void restoreRemoteServers(IMemento memento){ - IMemento remotesTitle = memento.getChild("remote-servers"); - if(remotesTitle != null){ - IMemento[] servers = remotesTitle.getChildren("Server"); - if(servers != null){ - for(IMemento server : servers){ - String address = server.getString("address"); - _model.addNewRemoteServer(address); - MenuItem item = new MenuItem(address); - _screen.getRemoteServers().add(item); - } - } - } - } +// private void restoreRemoteServers(IMemento memento){ +// IMemento remotesTitle = memento.getChild("remote-servers"); +// if(remotesTitle != null){ +// IMemento[] servers = remotesTitle.getChildren("Server"); +// if(servers != null){ +// for(IMemento server : servers){ +// String address = server.getString("address"); +// _model.addNewRemoteServer(address); +// MenuItem item = new MenuItem(address); +// _screen.getRemoteServers().add(item); +// } +// } +// } +// } diff --git a/cyclist/src/edu/utah/sci/cyclist/core/controller/CyclistController.java.orig b/cyclist/src/edu/utah/sci/cyclist/core/controller/CyclistController.java.orig deleted file mode 100755 index 1a1c7693..00000000 --- a/cyclist/src/edu/utah/sci/cyclist/core/controller/CyclistController.java.orig +++ /dev/null @@ -1,621 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 SCI Institute, University of Utah. - * All rights reserved. - * - * License for the specific language governing rights and limitations under Permission - * is hereby granted, free of charge, to any person obtaining a copy of this software and - * associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: The above copyright notice - * and this permission notice shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR - * A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Contributors: - * Yarden Livnat - *******************************************************************************/ -package edu.utah.sci.cyclist.core.controller; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.util.Arrays; -import java.util.List; - -import org.apache.log4j.Logger; - -import javafx.beans.property.ObjectProperty; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.scene.control.MenuItem; -import javafx.stage.Stage; -import javafx.stage.WindowEvent; -import edu.utah.sci.cyclist.Cyclist; -import edu.utah.sci.cyclist.ToolsLibrary; -import edu.utah.sci.cyclist.core.event.notification.EventBus; -import edu.utah.sci.cyclist.core.model.CyclistDatasource; -import edu.utah.sci.cyclist.core.model.Field; -import edu.utah.sci.cyclist.core.model.Model; -import edu.utah.sci.cyclist.core.model.Simulation; -import edu.utah.sci.cyclist.core.model.Table; -import edu.utah.sci.cyclist.core.presenter.DatasourcesPresenter; -import edu.utah.sci.cyclist.core.presenter.SchemaPresenter; -import edu.utah.sci.cyclist.core.presenter.SimulationPresenter; -import edu.utah.sci.cyclist.core.presenter.ToolsPresenter; -import edu.utah.sci.cyclist.core.presenter.WorkspacePresenter; -import edu.utah.sci.cyclist.core.tools.ToolFactory; -import edu.utah.sci.cyclist.core.ui.MainScreen; -import edu.utah.sci.cyclist.core.ui.components.SQLitePage; -import edu.utah.sci.cyclist.core.ui.views.Workspace; -import edu.utah.sci.cyclist.core.ui.wizards.DatatableWizard; -import edu.utah.sci.cyclist.core.ui.wizards.SaveWsWizard; -import edu.utah.sci.cyclist.core.ui.wizards.SimulationWizard; -//import edu.utexas.cycic.tools.FormBuilderTool; -//import edu.utexas.cycic.tools.FormBuilderToolFactory; -import edu.utah.sci.cyclist.core.util.StreamUtils; - - -public class CyclistController { - - private final EventBus _eventBus; - private MainScreen _screen; - public static WorkspacePresenter _presenter; - private Model _model = new Model(); - //private String SAVE_DIR = System.getProperty("user.dir") + "/.cyclist/"; - private String SAVE_FILE = "save.xml"; - private WorkDirectoryController _workDirectoryController; - private Boolean _dirtyFlag = false; - - private static final String SIMULATIONS_TABLES_FILE = "assets/SimulationTablesDef.xml"; - - /** - * Constructor - * - * @param eventBus - */ - public CyclistController(EventBus eventBus) { - this._eventBus = eventBus; - - _workDirectoryController = new WorkDirectoryController(); - - // If the save directory does not exist, create it - File saveDir = new File(WorkDirectoryController.SAVE_DIR); - if (!saveDir.exists()) - saveDir.mkdir(); - - - if(_workDirectoryController.initGeneralConfigFile()) - { - _workDirectoryController.restoreGeneralConfigFile(); - } - -// load(); - } - - /** - * initialize the main screen - * @param screen - */ - public void setScreen(final MainScreen screen) { - this._screen = screen; - addActions(); - - /* - * wire panels - */ - - // Tables panel - DatasourcesPresenter ds = new DatasourcesPresenter(_eventBus); - ds.setSources(_model.getSources()); - ds.setTables(_model.getTables()); - ds.setPanel(screen.getDatasourcesPanel()); - - // Schema panel - SchemaPresenter sp = new SchemaPresenter(_eventBus); - sp.setPanel(screen.getFieldsPanel()); - - //Simulation panel - SimulationPresenter sip = new SimulationPresenter(_eventBus); - sip.setSimIds(_model.getSimulations()); - sip.setSimPanel(screen.getSimulationPanel()); - - - // ToolsLibrary panel - ToolsPresenter tp = new ToolsPresenter(_eventBus); - tp.setPanel(screen.getToolsPanel()); - tp.setFactories(Arrays.asList(ToolsLibrary.factories)); - - // set up the main workspace - Workspace workspace = new Workspace(true); -// workspace.setWorkDirPath(getLastChosenWorkDirectory()); - screen.setWorkspace(workspace); - - _presenter = new WorkspacePresenter(_eventBus); - _presenter.setView(workspace); - - // do something? - //selectWorkspace(); - load(); - } - - /** - * selectWorkspace - * - */ - public void selectWorkspace() { - - if(_workDirectoryController == null){ - return; - } - - ObservableList selection = _screen.selectWorkspace(_workDirectoryController.getWorkDirectories(), - _workDirectoryController.getLastChosenIndex()); - - selection.addListener(new ListChangeListener(){ - - @Override - public void onChanged(Change list ){ - if(_workDirectoryController != null){ - if(_workDirectoryController.handleWorkDirectoriesListChangedEvent(list)){ - load(); - - //Set all the views to match the new tables. - ObservableList emptyList = FXCollections.observableArrayList(); - _screen.getFieldsPanel().setFields(emptyList); - -// //Set the workspace to display the new path at the title. -// Workspace workspace = _screen.getWorkSpace(); -// if(workspace != null){ -// workspace.setWorkDirPath(getLastChosenWorkDirectory()); -// } - - } - } - - } - }); - - } - - private void addActions() { - - _screen.onAddDatasource().set(new EventHandler() { - - @Override - public void handle(ActionEvent event) { - final DatatableWizard wizard = new DatatableWizard(); - wizard.setItems(_model.getSources()); - if(_model.getSelectedDatasource() != null){ - wizard.setSelectedSource(_model.getSelectedDatasource()); - } - String currDirectory = getLastChosenWorkDirectory(); - wizard.setWorkDir(currDirectory); - ObjectProperty selection = wizard.show(_screen.getWindow()); - - // wizard.getDataSources() - - selection.addListener(new ChangeListener
() { - @Override - public void changed(ObservableValue arg0, Table oldVal, Table newVal) { - if(newVal != null) - { - Table tbl = new Table(newVal); - _model.getTables().add(tbl); - _model.setSelectedDatasource(wizard.getSelectedSource()); - _dirtyFlag = true; - } - } - }); - - } - }); - - _screen.onAddSimulation().set(new EventHandler() { - @Override - public void handle(ActionEvent event) { - final SimulationWizard wizard = new SimulationWizard(); - - wizard.setItems(_model.getSources()); - if(_model.getSelectedDatasource() != null){ - wizard.setSelectedSource(_model.getSelectedDatasource()); - } - String currDirectory = getLastChosenWorkDirectory(); - wizard.setWorkDir(currDirectory); - ObservableList selection = wizard.show(_screen.getWindow()); - - - selection.addListener(new ListChangeListener() { - @Override - public void onChanged(ListChangeListener.Change newList) { - if(newList != null) - { - for(Simulation simulation:newList.getList()){ - if(!_model.simExists(simulation)){ - Simulation sim = simulation.clone(); - _model.getSimulations().add(sim); - _dirtyFlag = true; - } - } - _model.setSelectedDatasource(wizard.getSelectedSource()); - } - } - }); - } - }); - - _screen.onSelectWorkspace().set(new EventHandler(){ - - @Override - public void handle(ActionEvent arg0) { - - //If need to save the current workspace data - ask the user whether to save it or not - - if(_dirtyFlag || _presenter.getDirtyFlag()){ - SaveWsWizard wizard = new SaveWsWizard(); - ObjectProperty selection = wizard.show(_screen.getParent().getScene().getWindow()); - selection.addListener(new ChangeListener(){ - @Override - public void changed(ObservableValue arg0, Boolean oldVal,Boolean newVal) { - if(newVal){ - save(); - } - selectWorkspace(); - } - }); - }else{ - selectWorkspace(); - } - } - }); - - _screen.onSave().set(new EventHandler() { - - @Override - public void handle(ActionEvent event) { - save(); - } - }); - - _screen.onQuit().set(new EventHandler() { - - @Override - public void handle(ActionEvent event) { - quit(); - } - }); - - _screen.editDataSourceProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue arg0, Boolean oldVal, Boolean newVal) { - if(newVal){ - _dirtyFlag = true; - _screen.editDataSourceProperty().setValue(false); - } - } - }); - - _screen.editSimulationProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue arg0, Boolean oldVal, Boolean newVal) { - if(newVal){ - _dirtyFlag = true; - _screen.editSimulationProperty().setValue(false); - } - } - }); - - _screen.selectSimulationProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue arg0, Simulation oldVal, Simulation newVal) { - - //Meanwhile - all the tables are the same for all the simulation - so load them once, - //when the first simulation is selected. In the future - can compare between old and new simulations - //and each time a different simulation is selected - change the tables accordingly. - - if(oldVal==null && newVal!=null){ - readSimulationsTables(); - _presenter.addFirstSelectedSimulation(newVal); - } - _model.setLastSelectedSimulation(newVal); - _dirtyFlag = true; - } - }); - - _screen.onSystemClose().set(new EventHandler() { - - @Override - public void handle(WindowEvent event) { - event.consume(); - quit(); - } - }); - - EventHandler viewAction = new EventHandler() { - @Override - public void handle(ActionEvent event) { - MenuItem item = (MenuItem) event.getSource(); - for (ToolFactory factory : ToolsLibrary.factories) { - if (factory.getToolName().equals(item.getText())) { - try { - _presenter.addTool(factory.create()); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - }; - - for (MenuItem item : _screen.getViewMenu().getItems()) { - item.setOnAction(viewAction); - } - -<<<<<<< HEAD:cnome/src/edu/utah/sci/cyclist/core/controller/CyclistController.java - -======= - _model.getSimulations().addListener(new ListChangeListener() { - @Override - public void onChanged(ListChangeListener.Change listChange) { - while (listChange.next()) { - for(Simulation sim : listChange.getRemoved()){ - _presenter.removeSimulation(sim); - } - } - } - }); ->>>>>>> 313e1b8a6c1057077a2424cccb9da60e0ddd447b:cyclist/src/edu/utah/sci/cyclist/core/controller/CyclistController.java - - } - - private void quit() { - // TODO: check is we need to save - if(_dirtyFlag || _presenter.getDirtyFlag()){ - SaveWsWizard wizard = new SaveWsWizard(); - ObjectProperty selection = wizard.show(_screen.getParent().getScene().getWindow()); - selection.addListener(new ChangeListener(){ - @Override - public void changed(ObservableValue arg0, Boolean oldVal,Boolean newVal) { - if(newVal){ - save(); - } - System.exit(0); - } - }); - }else{ - System.exit(0); - } - } - - private void save() { - - String currDirectory = getLastChosenWorkDirectory(); - - // If the save directory does not exist, create it - File saveDir = new File(currDirectory); - if (!saveDir.exists()) - saveDir.mkdir(); - - // The save file - File saveFile = new File(currDirectory+"/"+SAVE_FILE); - - // Create the root memento - XMLMemento memento = XMLMemento.createWriteRoot("root"); - - // Save the data sources - for(CyclistDatasource source: _model.getSources()){ - source.save(memento.createChild("CyclistDatasource")); - } - - // Save the data tables - // Saves only tables added by the user (not loaded by the simulation configuration file). - for(Table table: _model.getTables()){ - if(!table.getIsStandardSimulation()){ - table.save(memento.createChild("Table")); - } - } - - //Save the last selected simulation - if(_model.getLastSelectedSimulation() != null && _model.getSimulations().size() >0){ - IMemento selectedSim = memento.createChild("LastSelectedSimulation"); - selectedSim.putString("simulation-id", _model.getLastSelectedSimulation().getSimulationId().toString()); - } - //Save the Simulations - for(Simulation simulation: _model.getSimulations()){ - simulation.save(memento.createChild("Simulation")); - } - - _presenter.save(memento.createChild("Tools")); - - //First save the main workspace - IMemento mainWs = memento.createChild("mainWorkSpace"); - saveMainScreen(mainWs); - - - try { - memento.save(new PrintWriter(saveFile)); - _dirtyFlag = false; - - } catch (IOException e) { - e.printStackTrace(); - } - - } - - // Load saved properties - private void load() { - - String currDirectory = _workDirectoryController.getWorkDirectories().get(_workDirectoryController.getLastChosenIndex()); - - // Check if the save file exists - File saveFile = new File(currDirectory+"/"+SAVE_FILE); - - //Clear the previous data - clearModel(); - - // If we have a save file, read it in - if(saveFile.exists()){ - - Reader reader; - try { - reader = new FileReader(saveFile); - try { - // Create the root memento - XMLMemento memento = XMLMemento.createReadRoot(reader); - - // Read in the data sources - IMemento[] sources = memento.getChildren("CyclistDatasource"); - for(IMemento source: sources){ - CyclistDatasource datasource = new CyclistDatasource(); - datasource.restore(source); - _model.getSources().add(datasource); - } - - // Read in the tables - IMemento[] tables = memento.getChildren("Table"); - //System.out.println("tables " + tables.length); - for(IMemento table: tables){ - Table tbl = new Table(); - tbl.restore(table, _model.getSources()); - tbl.setLocalDatafile(getLastChosenWorkDirectory()); - _model.getTables().add(tbl); - } - - //Read the simulations - IMemento[] simulations = memento.getChildren("Simulation"); - for(IMemento simulation:simulations){ - Simulation sim = new Simulation(); - sim.restore(simulation,_model.getSources()); - _model.getSimulations().add(sim); - } - - //Find if there is last selected simulation - IMemento lastSimulation = memento.getChild("LastSelectedSimulation"); - String lastSimulationId = ""; - if(lastSimulation != null){ - lastSimulationId = lastSimulation.getString("simulation-id"); - } - _screen.getSimulationPanel().selectSimulation(lastSimulationId); - - _dirtyFlag = false; - - //Read the main workspace - IMemento mainWs = memento.getChild("mainWorkSpace"); - loadMainScreen(mainWs); - - IMemento toolsRoot = memento.getChild("Tools"); - if(toolsRoot != null){ - _presenter.restore(toolsRoot,_model); - } - - - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } catch (FileNotFoundException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - } - //readSimulationsTables(); - } - - /* - * Reads the configuration file which defines the tables required for simulation. - * The tables are loaded with a null database property. - * The tables are added to the model tables list. - */ - private void readSimulationsTables(){ - Logger log = Logger.getLogger(SQLitePage.class); - try { - InputStream in = Cyclist.class.getResourceAsStream(SIMULATIONS_TABLES_FILE); - File simulationsFile = StreamUtils.stream2file(in); - if(simulationsFile.exists()){ - Reader reader = new FileReader(simulationsFile); - // Create the root memento - XMLMemento memento = XMLMemento.createReadRoot(reader); - - // Read in the data sources - IMemento[] tables = memento.getChildren("Table"); - for(IMemento table:tables){ - - Table tbl = new Table(); - tbl.restoreSimulated(table); - tbl.setLocalDatafile(getLastChosenWorkDirectory()); - _model.getSimulationsTablesDef().add(tbl); - _model.getTables().add(tbl); - } - } - } catch (Exception e) { - log.info("Exception " + e.getMessage()); - e.printStackTrace(); - } - } - - /* - * Gets the path of the last chosen work directory. - * If not available - return the default work directory - */ - private String getLastChosenWorkDirectory(){ - if(_workDirectoryController == null){ - return WorkDirectoryController.SAVE_DIR; - } - return _workDirectoryController.getWorkDirectories().get(_workDirectoryController.getLastChosenIndex()); - } - - /* - * Saves the data of the main window: size and location - * @param IMemento mainWs - */ - private void saveMainScreen(IMemento mainWs){ - Stage stage = (Stage)_screen.getParent().getScene().getWindow(); - mainWs.putString("x", Double.toString(stage.getX())); - mainWs.putString("y", Double.toString(stage.getY())); - mainWs.putString("width", Double.toString(stage.getWidth())); - mainWs.putString("height", Double.toString(stage.getHeight())); - } - - /* - * Restores the data of the main window:size and location. - * @param IMemento mainWs - */ - private void loadMainScreen(IMemento mainWs){ - double width = Double.parseDouble(mainWs.getString("width")); - double height = Double.parseDouble(mainWs.getString("height")); - double x = Double.parseDouble(mainWs.getString("x")); - double y = Double.parseDouble(mainWs.getString("y")); - Stage stage = (Stage)_screen.getParent().getScene().getWindow(); - stage.setWidth(width); - stage.setHeight(height); - stage.setX(x); - stage.setY(y); - } - - /* - * Clears the model from an old data. - */ - private void clearModel(){ - _model.getSources().clear(); - _model.getTables().clear(); - _model.getSimulations().clear(); - _model.setSelectedDatasource(null); - } - - - -} diff --git a/cyclist/src/edu/utah/sci/cyclist/core/controller/WorkDirectoryController.java b/cyclist/src/edu/utah/sci/cyclist/core/controller/SessionController.java similarity index 99% rename from cyclist/src/edu/utah/sci/cyclist/core/controller/WorkDirectoryController.java rename to cyclist/src/edu/utah/sci/cyclist/core/controller/SessionController.java index a345ad06..032f5c87 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/controller/WorkDirectoryController.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/controller/SessionController.java @@ -11,7 +11,7 @@ import javafx.collections.ListChangeListener.Change; import edu.utah.sci.cyclist.core.model.WorkDirectory; -public class WorkDirectoryController { +public class SessionController { public static final String CYCLIST_DIR = System.getProperty("user.home").replace("\\", "/") + "/.cyclist/"; private static final String CONFIG_FILE = CYCLIST_DIR+"config.xml"; diff --git a/cyclist/src/edu/utah/sci/cyclist/core/model/CyclistDatasource.java b/cyclist/src/edu/utah/sci/cyclist/core/model/CyclistDatasource.java index d926f785..636da1a5 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/model/CyclistDatasource.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/model/CyclistDatasource.java @@ -217,14 +217,14 @@ public Connection getConnection(String username, String password) throws SQLExce public void releaseConnection() { if (isSQLite()) { if (_currentThread != Thread.currentThread()) { - log.warn("SQLite: wrong thread close connection: ignored"); + log.debug("SQLite: wrong thread close connection: ignored"); return; } try { _SQLiteConnection.close(); _SQLiteConnection = null; } catch (SQLException e) { - log.warn("Error while closing sqlite connection: ",e); + log.debug("Error while closing sqlite connection: ",e); e.printStackTrace(); } _SQLiteSemaphore.release(); diff --git a/cyclist/src/edu/utah/sci/cyclist/core/model/Field.java b/cyclist/src/edu/utah/sci/cyclist/core/model/Field.java index b8773c22..f789993a 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/model/Field.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/model/Field.java @@ -253,7 +253,7 @@ public void restore(IMemento memento, Context ctx) { _name = memento.getString("name"); if (_id == null) _id = _name; ctx.put(_id, this); - System.out.println("restore "+_name); +// System.out.println("restore "+_name); IMemento dataMemento = memento.getChild("datatype"); DataType.Role role = dataMemento.getString("role")!= "" ? DataType.Role.valueOf(dataMemento.getString("role")) : null; @@ -273,8 +273,11 @@ public void restore(IMemento memento, Context ctx) { for(IMemento entry:entries) { String key = entry.getString("key"); String cls = entry.getString("class"); - - if((String.class.toString().equals(cls))){ + + if (cls == null) { + set(key, cls); + } + else if((String.class.toString().equals(cls))){ String value = entry.getTextData(); set(key, value); } diff --git a/cyclist/src/edu/utah/sci/cyclist/core/model/Perspective.java b/cyclist/src/edu/utah/sci/cyclist/core/model/Perspective.java new file mode 100644 index 00000000..931453f0 --- /dev/null +++ b/cyclist/src/edu/utah/sci/cyclist/core/model/Perspective.java @@ -0,0 +1,77 @@ +package edu.utah.sci.cyclist.core.model; + +import java.util.Arrays; +import java.util.List; + +import edu.utah.sci.cyclist.core.controller.IMemento; +import edu.utah.sci.cyclist.core.presenter.VisWorkspacePresenter; +import edu.utah.sci.cyclist.core.ui.views.VisWorkspace; + +public class Perspective { + public String name; + public String type; + public List tools; + public VisWorkspace workspace; + public VisWorkspacePresenter presenter; + public Boolean initialized = false; + public int id; + public double[] toolsPositions = new double[0]; + private IMemento _memento = null; + private Context _ctx = null; + + public Perspective(int id, String name, String type, List tools) { + this.id = id; + this.name = name; + this.type = type; + this.tools = tools; + } + + public void init() { + if (_memento != null) { + presenter.restore(_memento.getChild("workspace"), _ctx); + } + initialized = true; + } + + public void setToolsPositions(double[] pos) { + boolean changed = pos.length != toolsPositions.length; + if (!changed) { + int n = Math.min(pos.length, toolsPositions.length); + for (int i=0; i _servers = FXCollections.observableArrayList(); + private String _cyclus = "cyclus"; + + private Preferences() { + _servers.addListener(new InvalidationListener() { + @Override + public void invalidated(Observable arg0) { + _dirty = true; + } + }); + _servers.addAll("local", CLOUDIUS_URL); + } public static Preferences getInstance() { return _instance; } @@ -23,13 +43,73 @@ public void setDefaultServer(String defaultServer){ _defaultServer = defaultServer; } + public ObservableList servers() { + return _servers; + } + + public int getCurrentServerIndex() { + return _currentServer; + } + + public void setCurrentServerIndex(int value) { + _currentServer = value; + _dirty = true; + } + + public String getCyclusPath() { + return _cyclus; + } + + public void setCyclusPath(String path) { + _cyclus = path; + _dirty = true; + } + + public boolean isDirty() { + return _dirty; + } + public void save(IMemento memento){ IMemento defaultServer = memento.createChild("defaultServer"); defaultServer.putString("value", _defaultServer); + + IMemento m = memento.createChild("servers"); + m.putInteger("current", _currentServer); + for (String server : _servers) { + if (server != "") + m.createChild("server").putTextData(server); + } + + memento.createChild("cyclus").putString("path", _cyclus); + + _dirty = false; } public void restore(IMemento memento){ if (memento == null) return; + + boolean prev = _dirty; _defaultServer = memento.getChild("defaultServer").getString("value"); + + _servers.clear(); + IMemento s = memento.getChild("servers"); + if (s == null) { + _servers.addAll(LOCAL_SERVER, CLOUDIUS_URL); + _currentServer = 0; + } else { + _currentServer = s.getInteger("current"); + for (IMemento m : s.getChildren("server")) { + // TEMPORARY fix + String server = m.getTextData(); + if ("local".equals(server.toLowerCase())) server = LOCAL_SERVER; + _servers.add(server); + } + } + + IMemento c = memento.getChild("cyclus"); + if (c != null) { + _cyclus = c.getString("path"); + } + _dirty = prev; } } diff --git a/cyclist/src/edu/utah/sci/cyclist/core/model/Schema.java b/cyclist/src/edu/utah/sci/cyclist/core/model/Schema.java index b7181eee..3da3fa75 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/model/Schema.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/model/Schema.java @@ -66,6 +66,14 @@ public Field getField(String name) { return null; } + public Field getField(String name, Boolean casesensetive) { + if (casesensetive) return getField(name); + name = name.toLowerCase(); + for (Field field : _fields) + if (field.getName().toLowerCase().equals(name)) + return field; + return null; + } public void addField(Field field) { field.setTable(_table); _fields.add(field); diff --git a/cyclist/src/edu/utah/sci/cyclist/core/model/Table.java b/cyclist/src/edu/utah/sci/cyclist/core/model/Table.java index 1e25b0a6..99d16471 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/model/Table.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/model/Table.java @@ -49,7 +49,7 @@ import org.apache.log4j.Logger; import edu.utah.sci.cyclist.core.controller.IMemento; -import edu.utah.sci.cyclist.core.controller.WorkDirectoryController; +import edu.utah.sci.cyclist.core.controller.SessionController; import edu.utah.sci.cyclist.core.controller.XMLMemento; import edu.utah.sci.cyclist.core.util.DataFactory; import edu.utah.sci.cyclist.core.util.QueryBuilder; @@ -392,11 +392,15 @@ public List getFields() { public Field getField(int index) { return _schema.getField(index); } - + public Field getField(String name) { return _schema.getField(name); } + public Field getField(String name, Boolean casesensitive) { + return _schema.getField(name, casesensitive); + } + public void setFieldSelected(int index, boolean selected){ _schema.getField(index).setSelectedProperty(selected); } @@ -535,7 +539,7 @@ public String getSaveDir(){ * */ private void writeFieldValuesToFile(String fieldName, String fieldType, String role ,CyclistDatasource ds, List values){ if(_saveDir == ""){ - _saveDir = WorkDirectoryController.DEFAULT_WORKSPACE; + _saveDir = SessionController.DEFAULT_WORKSPACE; } File defaultDir = new File(_saveDir); if(!defaultDir.exists()){ @@ -699,7 +703,7 @@ private List readFieldValuesFromFile(String fieldName, CyclistDatasource List values = new ArrayList<>(); if(_saveDir == ""){ - _saveDir = WorkDirectoryController.DEFAULT_WORKSPACE; + _saveDir = SessionController.DEFAULT_WORKSPACE; } // If the save file does not exist - return an empty list. diff --git a/cyclist/src/edu/utah/sci/cyclist/core/presenter/ChartPresenter.java b/cyclist/src/edu/utah/sci/cyclist/core/presenter/ChartPresenter.java index f9c8e1c5..fb432ba9 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/presenter/ChartPresenter.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/presenter/ChartPresenter.java @@ -76,6 +76,13 @@ public void removeSimulationData(){ getView().removeSimulationData(); } + /** + * @parm Table + */ + public void addTable(Table table) { + getView().addTable(table, false, true); + } + /** * setView * @param view diff --git a/cyclist/src/edu/utah/sci/cyclist/core/presenter/Presenter.java b/cyclist/src/edu/utah/sci/cyclist/core/presenter/Presenter.java index b00eebba..f1ae032c 100755 --- a/cyclist/src/edu/utah/sci/cyclist/core/presenter/Presenter.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/presenter/Presenter.java @@ -24,13 +24,14 @@ import edu.utah.sci.cyclist.core.event.notification.CyclistNotification; import edu.utah.sci.cyclist.core.event.notification.EventBus; +import edu.utah.sci.cyclist.core.model.Table; public abstract interface Presenter { String getId(); EventBus getEventBus(); + void addTable(Table table); // void setView(final View view); -// View getView(); // // void setRemoteTables(List list); // void addTable(Table table, boolean remote, boolean active, boolean remoteActive); diff --git a/cyclist/src/edu/utah/sci/cyclist/core/presenter/PresenterBase.java b/cyclist/src/edu/utah/sci/cyclist/core/presenter/PresenterBase.java index 178be52c..3aa13c6d 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/presenter/PresenterBase.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/presenter/PresenterBase.java @@ -3,6 +3,7 @@ import edu.utah.sci.cyclist.core.event.notification.CyclistNotification; import edu.utah.sci.cyclist.core.event.notification.CyclistNotificationHandler; import edu.utah.sci.cyclist.core.event.notification.EventBus; +import edu.utah.sci.cyclist.core.model.Table; public class PresenterBase implements Presenter { private static int _idCounter = 0; @@ -15,6 +16,10 @@ public PresenterBase(EventBus bus) { _eventBus = bus; } + @Override + public void addTable(Table table) { + } + @Override public String getId() { return _id; diff --git a/cyclist/src/edu/utah/sci/cyclist/core/presenter/WorkspacePresenter.java b/cyclist/src/edu/utah/sci/cyclist/core/presenter/VisWorkspacePresenter.java similarity index 96% rename from cyclist/src/edu/utah/sci/cyclist/core/presenter/WorkspacePresenter.java rename to cyclist/src/edu/utah/sci/cyclist/core/presenter/VisWorkspacePresenter.java index 01efe506..6c076f05 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/presenter/WorkspacePresenter.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/presenter/VisWorkspacePresenter.java @@ -54,30 +54,30 @@ import edu.utah.sci.cyclist.core.ui.components.CyclistViewBase; import edu.utah.sci.cyclist.core.ui.components.ViewBase; import edu.utah.sci.cyclist.core.ui.views.FilterPanel; -import edu.utah.sci.cyclist.core.ui.views.Workspace; +import edu.utah.sci.cyclist.core.ui.views.VisWorkspace; -public class WorkspacePresenter extends CyclistViewPresenter { +public class VisWorkspacePresenter extends CyclistViewPresenter { private List _presenters = new ArrayList<>(); private List _filterPresenters = new ArrayList<>(); ObservableList _tools = FXCollections.observableArrayList(); private EventBus _localBus; - public WorkspacePresenter(EventBus bus/*, Model model*/) { + public VisWorkspacePresenter(EventBus bus/*, Model model*/) { super(bus); build(); _localBus = /*getWorkspace().isToplevel() ? getEventBus() : */ new SimpleEventBus(); addListeners(); } - public Workspace getWorkspace() { - return (Workspace) getView(); + public VisWorkspace getWorkspace() { + return (VisWorkspace) getView(); } public void setView(View view) { super.setView(view); - if (view instanceof Workspace) { + if (view instanceof VisWorkspace) { _tools.addListener(new ListChangeListener(){ @Override @@ -87,7 +87,7 @@ public void onChanged(ListChangeListener.Change newList) { }); - Workspace workspace = getWorkspace(); + VisWorkspace workspace = getWorkspace(); if (getWorkspace().isToplevel()) @@ -203,8 +203,8 @@ public void call(Simulation simulation) { /* * addTool */ - public void addTool(Tool tool) { - addTool(tool, 100, 100); + public Presenter addTool(Tool tool) { + return addTool(tool, 100, 100); } @Override @@ -284,7 +284,7 @@ public void removeSimulation(Simulation sim){ broadcast(getLocalEventBus(), new CyclistSimulationNotification(CyclistNotifications.SIMULATION_REMOVE, sim)); } - private Presenter addTool(Tool tool, double x, double y) { + public Presenter addTool(Tool tool, double x, double y) { ViewBase view = (ViewBase) tool.getView(); ViewPresenter presenter = tool.getPresenter(getLocalEventBus()); @@ -293,6 +293,14 @@ private Presenter addTool(Tool tool, double x, double y) { return addTool(view, presenter, x, y); } + public boolean hasTool(String name) { + for(Tool tool : _tools) { + if (tool.getName().equals(name)) + return true; + } + return false; + } + private Presenter addTool(ViewBase view, ViewPresenter presenter, double x, double y) { view.setLayoutX(x); view.setLayoutY(y); @@ -635,8 +643,8 @@ private void removeOldViews(){ for (ViewPresenter presenter : presenters) { removeView(presenter.getId()); //If the presenter itself is a workspace - clear it's contents as well. - if(presenter instanceof WorkspacePresenter){ - ((WorkspacePresenter) presenter).clearWorkspace(); + if(presenter instanceof VisWorkspacePresenter){ + ((VisWorkspacePresenter) presenter).clearWorkspace(); } } } diff --git a/cyclist/src/edu/utah/sci/cyclist/core/services/CyclusService.java b/cyclist/src/edu/utah/sci/cyclist/core/services/CyclusService.java index 0a594228..2511ebc1 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/services/CyclusService.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/services/CyclusService.java @@ -122,7 +122,7 @@ public void restore(IMemento memento) { } } - private void _submit(String path, Request request, String serverUrl) { + private CyclusJob _submit(String path, Request request, String serverUrl) { CyclusJob job = new CyclusJob(path,serverUrl); try { @@ -134,31 +134,41 @@ private void _submit(String path, Request request, String serverUrl) { _jobs.add(job); poll(job); } catch (ClientProtocolException e) { - log.error("Submit job communication error: "+ e.getMessage()); + String msg = e.getMessage() != null ? ": "+e.getMessage() : ""; + log.error("Submit job communication error "+ msg); + job.setStatus(Status.FAILED); } catch (IOException e) { - log.error("submit job IO error: "+ e.getMessage()); + String msg = e.getMessage() != null ? ": "+e.getMessage() : ""; + log.error("submit job IO error"+msg); + job.setStatus(Status.FAILED); } + return job; } - public void submit(File file, String serverUrl) { + public CyclusJob submit(File file, String serverUrl) { String path = file.getAbsolutePath(); Request request = Request.Post(serverUrl + SUBMIT_PATH) .bodyFile(file, ContentType.DEFAULT_TEXT); - this._submit(path, request,serverUrl); + return this._submit(path, request,serverUrl); } - public void submit(String file) { - // file is a string of XML here that represents an input file, - // rather than a file path - String serverUrl = Preferences.CLOUDIUS_URL; + public CyclusJob submit(String cmd) { + return submit(cmd, Preferences.CLOUDIUS_URL); + } + + public CyclusJob submit(String cmd, String url) { + // cmd is a string of XML String path = "cycic.xml"; - Request request = Request.Post(serverUrl+ SUBMIT_PATH) - .bodyString(file, ContentType.DEFAULT_TEXT); - this._submit(path, request,serverUrl); + Request request = Request.Post(url+ SUBMIT_PATH) + .bodyString(cmd, ContentType.DEFAULT_TEXT); + return this._submit(path, request,url); } - public void submitCmd(String cmd, String... args) { - String serverUrl = Preferences.CLOUDIUS_URL; + public CyclusJob submitCmd(String cmd, String... args) { + return submitCmdToRemote(Preferences.CLOUDIUS_URL, cmd, args); + } + + public CyclusJob submitCmdToRemote(String url, String cmd, String... args) { String name = "cmd"; String uid = UUID.randomUUID().toString().replace("-", ""); String reqJSON = "{\"Id\": \"" + uid + "\", \"Cmd\": [\"" + cmd + "\""; @@ -166,9 +176,9 @@ public void submitCmd(String cmd, String... args) { reqJSON += ", \"" + arg + "\""; } reqJSON += "]}"; - Request request = Request.Post(serverUrl+SUBMIT_JOB_PATH) + Request request = Request.Post(url+SUBMIT_JOB_PATH) .bodyString(reqJSON, ContentType.APPLICATION_JSON); - this._submit(name, request,serverUrl); + return this._submit(name, request,url); } private void poll(final CyclusJob job) { diff --git a/cyclist/src/edu/utah/sci/cyclist/core/tools/GenericTool.java b/cyclist/src/edu/utah/sci/cyclist/core/tools/GenericTool.java index 33429af2..935904b1 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/tools/GenericTool.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/tools/GenericTool.java @@ -33,6 +33,11 @@ public String getName() { return _name; } + @Override + public boolean isUserLevel() { + return true; + } + @Override public View getView() { if (_view == null) { diff --git a/cyclist/src/edu/utah/sci/cyclist/core/tools/GenericToolFactory.java b/cyclist/src/edu/utah/sci/cyclist/core/tools/GenericToolFactory.java deleted file mode 100644 index 4220a092..00000000 --- a/cyclist/src/edu/utah/sci/cyclist/core/tools/GenericToolFactory.java +++ /dev/null @@ -1,31 +0,0 @@ -package edu.utah.sci.cyclist.core.tools; - -import edu.utah.sci.cyclist.core.util.AwesomeIcon; - -public class GenericToolFactory implements ToolFactory { - - private Class cls; - private String name; - private AwesomeIcon iconName; - - public GenericToolFactory(Class cls, String name, AwesomeIcon iconName) { - this.cls = cls; - this.name = name; - this.iconName = iconName; - } - @Override - public String getToolName() { - return name; - } - - @Override - public AwesomeIcon getIcon() { - return iconName; - } - - @Override - public Tool create() throws InstantiationException, IllegalAccessException { - return cls.newInstance(); - } - -} diff --git a/cyclist/src/edu/utah/sci/cyclist/core/tools/SimpleToolFactory.java b/cyclist/src/edu/utah/sci/cyclist/core/tools/SimpleToolFactory.java index 7188d898..07e58f1e 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/tools/SimpleToolFactory.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/tools/SimpleToolFactory.java @@ -6,13 +6,17 @@ public class SimpleToolFactory implements ToolFactory { private String _id; private String _name; + private String _type; + private boolean _userlevel; private AwesomeIcon _iconName; private String _viewClass; private String _presenterClass; - public SimpleToolFactory(String pkg, String name, AwesomeIcon iconName, String viewClass, String presenterClass) { + public SimpleToolFactory(String pkg, String name, String type, Boolean userlevel, AwesomeIcon iconName, String viewClass, String presenterClass) { _id = pkg+"."+name; _name = name; + _type = type; + _userlevel = userlevel; _iconName = iconName; _viewClass = pkg+"."+viewClass; _presenterClass = pkg+"."+presenterClass; @@ -23,6 +27,16 @@ public String getToolName() { return _name; } + @Override + public String getToolType() { + return _type; + } + + @Override + public boolean isUserLevel() { + return _userlevel; + } + @Override public AwesomeIcon getIcon() { return _iconName; diff --git a/cyclist/src/edu/utah/sci/cyclist/core/tools/Tool.java b/cyclist/src/edu/utah/sci/cyclist/core/tools/Tool.java index 3828ec6a..a0018eb9 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/tools/Tool.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/tools/Tool.java @@ -30,6 +30,7 @@ public interface Tool { String getId(); String getName(); + boolean isUserLevel(); View getView(); ViewPresenter getPresenter(EventBus bus); } diff --git a/cyclist/src/edu/utah/sci/cyclist/core/tools/ToolFactory.java b/cyclist/src/edu/utah/sci/cyclist/core/tools/ToolFactory.java index 11e89c04..e6c9dda4 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/tools/ToolFactory.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/tools/ToolFactory.java @@ -4,6 +4,8 @@ public interface ToolFactory { String getToolName(); + String getToolType(); + boolean isUserLevel(); AwesomeIcon getIcon(); Tool create() throws InstantiationException, IllegalAccessException, ClassNotFoundException; diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/MainScreen.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/MainScreen.java index fb2f0e70..7a55e315 100755 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/MainScreen.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/MainScreen.java @@ -22,13 +22,13 @@ *******************************************************************************/ package edu.utah.sci.cyclist.core.ui; -import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import javafx.application.Platform; import javafx.beans.property.ObjectProperty; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; @@ -39,9 +39,9 @@ import javafx.scene.control.MenuItem; import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.SplitPane; +import javafx.scene.control.TabPane; import javafx.scene.input.KeyCombination; import javafx.scene.layout.Priority; -import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.stage.Window; @@ -58,8 +58,8 @@ import edu.utah.sci.cyclist.core.ui.panels.SchemaPanel; import edu.utah.sci.cyclist.core.ui.panels.SimulationsPanel; import edu.utah.sci.cyclist.core.ui.panels.TablesPanel; +import edu.utah.sci.cyclist.core.ui.panels.TitledPanel; import edu.utah.sci.cyclist.core.ui.panels.ToolsPanel; -import edu.utah.sci.cyclist.core.ui.views.Workspace; import edu.utah.sci.cyclist.core.ui.wizards.WorkspaceWizard; import edu.utah.sci.cyclist.core.util.AwesomeIcon; import edu.utah.sci.cyclist.core.util.GlyphRegistry; @@ -73,14 +73,15 @@ public class MainScreen extends VBox implements Resource { private SchemaPanel _fieldsPanel; private ToolsPanel _toolsPanel; private InputPanel _inputPanel; - private StackPane _workspacePane; + private TabPane _tabsPane; private SimulationsPanel _simulationPanel; private JobsPanel _jobsPanel; + private Map _panels = new HashMap<>(); private Menu _perspectiveMenu; - private Menu _viewMenu; - private Menu _inputMenu; - private Menu _runMenu; + private Menu _toolsMenu; +// private Menu _inputMenu; +// private Menu _runMenu; private ObjectProperty> _stageCloseProperty; @@ -109,9 +110,26 @@ public ObservableList selectWorkspace(ObservableList list, int c return wizard.show(getScene().getWindow()); } + public TabPane getTabPane() { + return _tabsPane; + } - public void setWorkspace(Workspace workspace) { - _workspacePane.getChildren().add(workspace); + public void showPanels(List list, double[] pos) { + _toolsPane.getItems().clear(); + for (String name : list) { + TitledPanel panel = _panels.get(name); + if (panel != null) + _toolsPane.getItems().add(panel); + else + System.out.println("MainScreen error: unknow panel ["+name+"]"); + } + + Platform.runLater(new Runnable() { + @Override + public void run() { + _toolsPane.setDividerPositions(pos); + } + }); } public TablesPanel getDatasourcesPanel() { @@ -138,27 +156,24 @@ public JobsPanel getJobsPanel() { return _jobsPanel; } - public Workspace getWorkspace(){ - for(Object obj : _workspacePane.getChildren()){ - if (obj.getClass() == Workspace.class) { - return (Workspace)obj; - } - } - return null; - } - private double TOOLS_WIDTH = 120; private void build(Stage stage){ - getStyleClass().add("main-screen"); - double[] div = {0.1, 0.4, 0.7, 0.8, 0.95, 0.97}; - + getStyleClass().add("main-screen"); double [] mainDividers = {TOOLS_WIDTH/600.0}; this.setPrefWidth(600); this.setPrefHeight(400); this.setPadding(new Insets(0)); this.setSpacing(0); + + _panels.put("Builder", _inputPanel = new InputPanel()); + _panels.put("Simulations", _simulationPanel = new SimulationsPanel()); + _panels.put("Tables", _datasourcesPanel = new TablesPanel()); + _panels.put("Fields", _fieldsPanel = new SchemaPanel("Fields")); + _panels.put("Tools", _toolsPanel = new ToolsPanel()); + _panels.put("Jobs", _jobsPanel = new JobsPanel()); + _panels.put("Filters", new FiltersListPanel()); _sp = new SplitPane(); _sp.setOrientation(Orientation.HORIZONTAL); @@ -169,20 +184,10 @@ private void build(Stage stage){ _toolsPane.setPrefWidth(USE_COMPUTED_SIZE); _toolsPane.setPrefHeight(USE_COMPUTED_SIZE); _toolsPane.setOrientation(Orientation.VERTICAL); - _toolsPane.getItems().addAll( - _simulationPanel = new SimulationsPanel(), - _datasourcesPanel = new TablesPanel(), - _fieldsPanel = new SchemaPanel("Fields"), - _toolsPanel = new ToolsPanel(), - _inputPanel = new InputPanel(), - _jobsPanel = new JobsPanel(), - /*_filtersPanel = */new FiltersListPanel() - ); - _toolsPane.setDividerPositions(div); _sp.getItems().addAll( _toolsPane, - _workspacePane = new StackPane()); + _tabsPane = new TabPane()); this.getChildren().addAll( createMenuBar(stage), @@ -194,46 +199,46 @@ private void build(Stage stage){ SplitPane.setResizableWithParent(_toolsPane, false); _stageCloseProperty = stage.onCloseRequestProperty(); - _remoteServers = FXCollections.observableArrayList(); - _remoteServers.addListener(new ListChangeListener() { - @Override - public void onChanged(ListChangeListener.Change change) { - List newServers = new ArrayList(); - List deletedServers = new ArrayList(); - while (change.next()) { - for (MenuItem item : change.getRemoved()) { - deletedServers.add(item); - } - for (MenuItem item : change.getAddedSubList()) { - item.setUserData(item.getText()); - item.onActionProperty().set(_runMenuItem.getOnAction()); - newServers.add(item); - } - updateRunOnMenu(newServers,deletedServers); - } - } - }); +// _remoteServers = FXCollections.observableArrayList(); +// _remoteServers.addListener(new ListChangeListener() { +// @Override +// public void onChanged(ListChangeListener.Change change) { +// List newServers = new ArrayList(); +// List deletedServers = new ArrayList(); +// while (change.next()) { +// for (MenuItem item : change.getRemoved()) { +// deletedServers.add(item); +// } +// for (MenuItem item : change.getAddedSubList()) { +// item.setUserData(item.getText()); +// item.onActionProperty().set(_runMenuItem.getOnAction()); +// newServers.add(item); +// } +// updateRunOnMenu(newServers,deletedServers); +// } +// } +// }); } /* * Menus & Actions */ - public Menu getViewMenu() { - return _viewMenu; + public Menu getToolsMenu() { + return _toolsMenu; } - public Menu getInputMenu() { - return _inputMenu; - } +// public Menu getInputMenu() { +// return _inputMenu; +// } public Menu getPerspectiveMenu() { return _perspectiveMenu; } - public Menu getRunMenu() { - return _runMenu; - } +// public Menu getRunMenu() { +// return _runMenu; +// } private MenuItem _datasourceMenuItem; private MenuItem _workspaceMenuItem; @@ -242,12 +247,12 @@ public Menu getRunMenu() { private MenuItem _saveAsMenuItem; private MenuItem _simulationMenuItem; private MenuItem _sqliteLoaderMenuItem; - private MenuItem _runMenuItem; - private MenuItem _manageMenuItem; - private Menu _runOnMenu; - private MenuItem _runOnOtherItem; +// private MenuItem _runMenuItem; +// private MenuItem _manageMenuItem; +// private Menu _runOnMenu; +// private MenuItem _runOnOtherItem; private MenuItem _preferencesMenuItem; - private ObservableList _remoteServers; +// private ObservableList _remoteServers; public ObjectProperty> onAddDatasource() { return _datasourceMenuItem.onActionProperty(); @@ -276,17 +281,17 @@ public ObjectProperty> onQuit() { return _quitMenuItem.onActionProperty(); } - public ObjectProperty> onRun() { - return _runMenuItem.onActionProperty(); - } +// public ObjectProperty> onRun() { +// return _runMenuItem.onActionProperty(); +// } - public ObjectProperty> onManage() { - return _manageMenuItem.onActionProperty(); - } - - public ObjectProperty> onRunOnOther() { - return _runOnOtherItem.onActionProperty(); - } +// public ObjectProperty> onManage() { +// return _manageMenuItem.onActionProperty(); +// } +// +// public ObjectProperty> onRunOnOther() { +// return _runOnOtherItem.onActionProperty(); +// } public ObjectProperty editDataSourceProperty() { return _datasourcesPanel.editTableProperty(); @@ -296,9 +301,9 @@ public ObjectProperty> onSetPreferences() { return _preferencesMenuItem.onActionProperty(); } - public ObservableList getRemoteServers(){ - return _remoteServers; - } +// public ObservableList getRemoteServers(){ +// return _remoteServers; +// } /** @@ -325,22 +330,29 @@ public ObjectProperty> onSystemClose(){ return _stageCloseProperty; } + public double[] getToolsPositions() { + return _toolsPane.getDividerPositions(); + } + + public double[] getSplitPositions() { + return _sp.getDividerPositions(); + } + public void save(IMemento memento) { memento.createChild("sp-pos").putString("values", Arrays.toString(_sp.getDividerPositions())); - memento.createChild("tools-pos").putString("values", Arrays.toString(_toolsPane.getDividerPositions())); } public void restore(IMemento memento, Context ctx) { -// final double [] pos = parseArray(memento.getChild("sp-pos").getString("values")); -// final double [] pos1 = parseArray(memento.getChild("tools-pos").getString("values")); -// -// Platform.runLater(new Runnable() { -// @Override -// public void run() { -// _sp.setDividerPositions(pos); -// _toolsPane.setDividerPositions(pos1); -// } -// }); + if (memento.getChild("sp-pos") != null) { + final double [] pos = parseArray(memento.getChild("sp-pos").getString("values")); + + Platform.runLater(new Runnable() { + @Override + public void run() { + _sp.setDividerPositions(pos); + } + }); + } } private double[] parseArray(String str) { @@ -357,13 +369,11 @@ private MenuBar createMenuBar(Stage stage) { Menu fileMenu = createFileMenu(); Menu dataMenu = createDataMenu(); - _viewMenu = createViewMenu(); - _inputMenu = createInputMenu(); - _runMenu = createRunMenu(); -// Menu panelMenu = createPanelMenu(); -// _perspectiveMenu = createPerspectiveMenu(); + _toolsMenu = createToolsMenu(); +// _inputMenu = createInputMenu(); +// _runMenu = createRunMenu(); - menubar.getMenus().addAll(fileMenu, dataMenu, _viewMenu, _inputMenu, _runMenu /*, _perspectiveMenu*/); + menubar.getMenus().addAll(fileMenu, dataMenu, _toolsMenu /*, _inputMenu , _runMenu*/); return menubar; } @@ -409,46 +419,61 @@ private Menu createDataMenu() { return dataMenu; } - private Menu createViewMenu() { - Menu menu = new Menu("Views"); + private Menu createToolsMenu() { + Menu menu = new Menu("Tools"); - for (final ToolFactory factory : ToolsLibrary.factories) { + for (final ToolFactory factory : ToolsLibrary.getFactoriesOfType(ToolsLibrary.SCENARIO_TOOL)) { + if (factory.isUserLevel()) { + MenuItem item = new MenuItem(factory.getToolName(), GlyphRegistry.get(factory.getIcon())); + item.getProperties().put("type", ToolsLibrary.SCENARIO_TOOL); + menu.getItems().add(item); + } + } + + for (final ToolFactory factory : ToolsLibrary.getFactoriesOfType(ToolsLibrary.VIS_TOOL)) { MenuItem item = new MenuItem(factory.getToolName(), GlyphRegistry.get(factory.getIcon())); + item.getProperties().put("type", ToolsLibrary.VIS_TOOL); menu.getItems().add(item); } return menu; } - private Menu createInputMenu() { - Menu menu = new Menu("Input"); - - for (final ToolFactory factory : ToolsLibrary.inputFactories) { - MenuItem item = new MenuItem(factory.getToolName(), GlyphRegistry.get(factory.getIcon())); - menu.getItems().add(item); - } - - return menu; + public void selectTools(String type) { + for (MenuItem item : _toolsMenu.getItems()) { + item.setDisable(item.getProperties().get("type") != type); + } } + +// private Menu createInputMenu() { +// Menu menu = new Menu("Scenario Builder"); +// +// for (final ToolFactory factory : ToolsLibrary.getFactoriesOfType(ToolsLibrary.SCENARIO_TOOL)) { +// MenuItem item = new MenuItem(factory.getToolName(), GlyphRegistry.get(factory.getIcon())); +// menu.getItems().add(item); +// } +// +// return menu; +// } - private Menu createRunMenu() { - Menu menu= new Menu("Run"); - _runMenuItem = new MenuItem("Submit file"/*, GlyphRegistry.get(AwesomeIcon.EXCHANGE))*/); - _runMenuItem.setAccelerator(KeyCombination.keyCombination("Meta+R")); - //Let the controller retrieve the current default server each time the menu item is selected. - _runMenuItem.setUserData(""); - - _runOnMenu = new Menu("Run on"); - _runOnOtherItem = new MenuItem("other..."); - - _runOnMenu.getItems().add(_runOnOtherItem); - - _manageMenuItem = new MenuItem("Manage list"); - - menu.getItems().addAll(_runMenuItem,_runOnMenu,_manageMenuItem); - - return menu; - } +// private Menu createRunMenu() { +// Menu menu= new Menu("Run"); +// _runMenuItem = new MenuItem("Submit file"/*, GlyphRegistry.get(AwesomeIcon.EXCHANGE))*/); +// _runMenuItem.setAccelerator(KeyCombination.keyCombination("Meta+R")); +// //Let the controller retrieve the current default server each time the menu item is selected. +// _runMenuItem.setUserData(""); +// +// _runOnMenu = new Menu("Run on"); +// _runOnOtherItem = new MenuItem("other..."); +// +// _runOnMenu.getItems().add(_runOnOtherItem); +// +// _manageMenuItem = new MenuItem("Manage list"); +// +// menu.getItems().addAll(_runMenuItem,_runOnMenu,_manageMenuItem); +// +// return menu; +// } /* * Updates the remote servers menu after the list of remote addresses has changed. @@ -458,43 +483,33 @@ private Menu createRunMenu() { * @param List deletedServers - list of addresses to remove. * */ - private void updateRunOnMenu(List newServers, List deletedServers){ - - List deleted = new ArrayList(); - //First deleted old items - for(MenuItem item : deletedServers){ - for(MenuItem menuItem :_runOnMenu.getItems()){ - if(menuItem.getText() != null && menuItem.getText().equals(item.getText())){ - deleted.add(menuItem); - } - } - } - - for(MenuItem menuItem : deleted){ - _runOnMenu.getItems().remove(menuItem); - } - - //If only the separator and "other" where left - if(_runOnMenu.getItems().size()==2 && _runOnMenu.getItems().get(0) instanceof SeparatorMenuItem){ - _runOnMenu.getItems().remove(0); - } - - //If only "other" menu item exists - add a separator - if(_runOnMenu.getItems().size()==1 && newServers.size()>0 ){ - _runOnMenu.getItems().add(0,new SeparatorMenuItem()); - } - if(newServers.size()>0){ - _runOnMenu.getItems().addAll(0, newServers); - } - } - - private Menu createPerspectiveMenu() { - Menu menu = new Menu("Perspectives"); - - MenuItem cycic = new MenuItem("Design"); - MenuItem cyclist = new MenuItem("Analysis"); - - menu.getItems().addAll(cycic, cyclist); - return menu; - } +// private void updateRunOnMenu(List newServers, List deletedServers){ +// +// List deleted = new ArrayList(); +// //First deleted old items +// for(MenuItem item : deletedServers){ +// for(MenuItem menuItem :_runOnMenu.getItems()){ +// if(menuItem.getText() != null && menuItem.getText().equals(item.getText())){ +// deleted.add(menuItem); +// } +// } +// } +// +// for(MenuItem menuItem : deleted){ +// _runOnMenu.getItems().remove(menuItem); +// } +// +// //If only the separator and "other" where left +// if(_runOnMenu.getItems().size()==2 && _runOnMenu.getItems().get(0) instanceof SeparatorMenuItem){ +// _runOnMenu.getItems().remove(0); +// } +// +// //If only "other" menu item exists - add a separator +// if(_runOnMenu.getItems().size()==1 && newServers.size()>0 ){ +// _runOnMenu.getItems().add(0,new SeparatorMenuItem()); +// } +// if(newServers.size()>0){ +// _runOnMenu.getItems().addAll(0, newServers); +// } +// } } diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/components/Console.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/components/Console.java index 6c60f559..b0f6e824 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/components/Console.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/components/Console.java @@ -1,38 +1,80 @@ package edu.utah.sci.cyclist.core.ui.components; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; + import javafx.application.Platform; import javafx.scene.control.ScrollPane; -import javafx.scene.control.TextArea; +import javafx.scene.paint.Color; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; +import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; import org.apache.log4j.Appender; import org.apache.log4j.Layout; +import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.spi.ErrorHandler; import org.apache.log4j.spi.Filter; import org.apache.log4j.spi.LoggingEvent; public class Console extends ScrollPane { - private TextArea _text; - private String _current; - + private TextFlow _textFlow; + private Map _colors = new HashMap<>(); + private Map _prefix = new HashMap<>(); + private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[hh:mm]"); + private Font regular = Font.getDefault(); + private Font bold = Font.font(regular.getFamily(), FontWeight.BOLD, regular.getSize()); + + private boolean active = true; + public Console() { super(); build(); init(); } + public void setActive(boolean value) { + active = value; + } + + // TODO: upgrade to Log4j2.x private void init() { Logger.getRootLogger().addAppender(new CyclistAppender()); + + _colors.put(Level.FATAL, Color.RED); + _colors.put(Level.ERROR, Color.RED); + _colors.put(Level.WARN, Color.BLACK); + _colors.put(Level.INFO, Color.BLACK); + _colors.put(Level.DEBUG, Color.BLUE); + _colors.put(Level.TRACE, Color.GRAY); + _colors.put(Level.ALL, Color.GRAY); + + _prefix.put(Level.FATAL, "FATAL: "); + _prefix.put(Level.ERROR, "Error: "); + _prefix.put(Level.WARN, "Warning: "); + _prefix.put(Level.INFO, ""); + _prefix.put(Level.DEBUG, ""); + _prefix.put(Level.TRACE, ""); + _prefix.put(Level.ALL, ""); } - + private void build() { getStyleClass().add("console"); setFitToWidth(true); setFitToHeight(true); setPrefSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE); - _text = new TextArea(); - setContent(_text); + _textFlow = new TextFlow(); + setContent(_textFlow); + } + + private Color color(Level level) { + Color c = _colors.get(level); + return c != null ? c : _colors.get(Level.ALL); } class CyclistAppender implements Appender { @@ -57,16 +99,32 @@ public void close() { } @Override - public void doAppend(LoggingEvent event) { - StringBuilder builder = new StringBuilder(); - _current = builder.append(_current).append(event.getMessage()).append("\n").toString(); - Platform.runLater(new Runnable() { - @Override - public void run() { - _text.setText(_current); - _text.end(); - } - }); + public void doAppend(LoggingEvent e) { + if (!active) return; + + StringBuilder builder = new StringBuilder() + .append(" [") + .append(LocalTime.now().format(formatter)) + .append("] ") + .append(_prefix.get(e.getLevel())) + .append(": ") + .append(e.getMessage()) + .append("\n"); + + Text text = new Text(builder.toString()); + text.setFill(color(e.getLevel())); + text.setFont(e.getLevel() == Level.WARN ? bold : regular); + + _textFlow.getChildren().add(text); + + final Console self = Console.this; + Platform.runLater(new Runnable() { + @Override + public void run() { + self.setVvalue(1); + } + }); + } @Override diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/components/CyclistNumberAxis.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/components/CyclistNumberAxis.java index e1ac9123..e01e8f30 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/components/CyclistNumberAxis.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/components/CyclistNumberAxis.java @@ -398,6 +398,7 @@ private Dimension2D measureTickMarkSize(Number value, double rotation, int range double maxReqTickGap = 0; double last = 0; count = 0; + for (double major = minRounded; major <= maxRounded; major += tickUnitRounded, count ++) { double size = (vertical) ? measureTickMarkSize((Double)major, getTickLabelRotation(), rangeIndex).getHeight() : measureTickMarkSize((Double)major, getTickLabelRotation(), rangeIndex).getWidth(); @@ -406,6 +407,10 @@ private Dimension2D measureTickMarkSize(Number value, double rotation, int range } else { maxReqTickGap = Math.max(maxReqTickGap, last + 6 + (size/2) ); } + if (minRounded == maxRounded) { + maxReqTickGap = Math.max(maxReqTickGap, last + 6 + (size/2) ); + break; + } } reqLength = (count-1) * maxReqTickGap; tickUnit = tickUnitRounded; diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/components/DropArea.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/components/DropArea.java index c43c3390..035d9990 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/components/DropArea.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/components/DropArea.java @@ -122,11 +122,23 @@ public void updatePreOccupiedField(List fields){ _preOccupiedFields.addAll(fields); } + private boolean compatible() { + Field field = getLocalClipboard().get(DnD.FIELD_FORMAT, Field.class); + if (field == null + || (_acceptedRoles == AcceptedRoles.DIMENSION && (field.getRole() != Role.DIMENSION && field.getRole() != Role.INT_TIME)) + || isPreOccupiedField(field) + || (getFields().size() > 0 && _policy == Policy.MULTIPLE && field.getRole() != getFields().get(0).getRole())) + { + return false; + } + return true; + } + /** * @name setDragAndDropModes * @param sourcesTransferModes - Maps for each possible source the accepted drag and drop transfer modes. */ - public void setDragAndDropModes( Map, TransferMode[]> sourcesTransferModes){ + public void setDragAndDropModes( Map, TransferMode[]> sourcesTransferModes) { _sourcesTransferModes = sourcesTransferModes; } @@ -160,7 +172,7 @@ public void handle(DragEvent event) { //predefined accepted transfer modes. if(getLocalClipboard().hasContent(DnD.DnD_SOURCE_FORMAT)){ Class key = getLocalClipboard().getType(DnD.DnD_SOURCE_FORMAT); - if(key != null && _sourcesTransferModes!= null && _sourcesTransferModes.containsKey(key) ){ + if(key != null && _sourcesTransferModes!= null && _sourcesTransferModes.containsKey(key) && compatible()) { event.acceptTransferModes(_sourcesTransferModes.get(key)); } } @@ -194,19 +206,25 @@ public void handle(DragEvent event) { } //} if (field != null) { - if(_acceptedRoles == AcceptedRoles.DIMENSION && field.getRole() != Role.DIMENSION){ + if(_acceptedRoles == AcceptedRoles.DIMENSION && (field.getRole() != Role.DIMENSION && field.getRole() != Role.INT_TIME)){ log.warn("Cannot add non-discrete field to this drop area"); - } else if(isPreOccupiedField(field, event)){ + status = false; + } else if(isPreOccupiedField(field)) { log.warn("Field already exists in another drop area"); + status = false; }else if (getFields().size() == 0) { getFields().add(field); + status = true; } else if(_policy == Policy.SINGLE){ getFields().set(0, field); + status = true; + } else if (field.getRole() != getFields().get(0).getRole()) { + log.warn("Field is incompatible with existing fields"); + status = false; } else { getFields().add(field); - } - - status = true; + status = true; + } } event.setDropCompleted(status); @@ -215,6 +233,7 @@ public void handle(DragEvent event) { }); + tableProperty().addListener(new InvalidationListener() { @Override @@ -347,7 +366,7 @@ private DnD.LocalClipboard getLocalClipboard() { * Returns: Boolean. Returns true if the field already exists in another drop area, false if not. * Description: Checks if the specified field is already used by other drop areas. */ - private Boolean isPreOccupiedField(Field testedField, DragEvent event){ + private Boolean isPreOccupiedField(Field testedField){ //Check if the field was dragged from another drop area. //If it came from another drop area - if the transfer mode is "Move" the source drop area is going to remove the field anyway at the end of the drag and drop. diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/components/ViewBase.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/components/ViewBase.java index 4929cce0..2c65113d 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/components/ViewBase.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/components/ViewBase.java @@ -77,7 +77,8 @@ public enum Edge { TOP, BOTTOM, LEFT, RIGHT, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, B private boolean _toplevel; private boolean _maximized = false; private final Resize resize = new Resize(); - + private boolean _closeable = true; + private boolean _enableDragging = true; // Actions @@ -185,6 +186,16 @@ public void setMaximized(boolean value) { } } + public void setCloseable(boolean value) { + if (_closeable == value) return; + _closeable = value; + _closeButton.setVisible(value); + _closeButton.setManaged(value); + } + + public boolean isCloseable() { + return _closeable; + } /* * Max/min button */ @@ -292,7 +303,16 @@ public void restore(IMemento memento, Context ctx) { } protected void enableDragging(Boolean value) { + if (_enableDragging == value) return; _enableDragging = value; + if (value) { + setHeaderListeners(); + } else { + _header.setOnMousePressed(null); + _header.setOnMouseClicked(null); + _header.setOnMouseDragged(null); + setOnMouseClicked(null); + } } protected boolean isDragginEnabled() { diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/panels/InputPanel.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/panels/InputPanel.java index fa1314ab..9fb9aea6 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/panels/InputPanel.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/panels/InputPanel.java @@ -43,14 +43,14 @@ public class InputPanel extends TitledPanel { public static final String ID = "input-panel"; - public static final String TITLE = "Input"; + public static final String TITLE = "Views"; public ImageView dragView = new ImageView(); public Pane root; public InputPanel() { - super(TITLE, GlyphRegistry.get(AwesomeIcon.SHARE)); + super(TITLE, GlyphRegistry.get(AwesomeIcon.EDIT)); } public void setToolFactories(List factories) { diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/panels/TablesPanel.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/panels/TablesPanel.java index 950ce5fd..5e2696d0 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/panels/TablesPanel.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/panels/TablesPanel.java @@ -25,6 +25,10 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; + +import org.mo.closure.v1.Closure; import javafx.beans.InvalidationListener; import javafx.beans.Observable; @@ -43,6 +47,7 @@ import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; import javafx.scene.control.MenuItem; +import javafx.scene.control.SeparatorMenuItem; import javafx.scene.input.ClipboardContent; import javafx.scene.input.Dragboard; import javafx.scene.input.MouseButton; @@ -52,7 +57,9 @@ import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.FontPosture; +import edu.utah.sci.cyclist.core.event.Pair; import edu.utah.sci.cyclist.core.event.dnd.DnD; +import edu.utah.sci.cyclist.core.model.Simulation; import edu.utah.sci.cyclist.core.model.Table; import edu.utah.sci.cyclist.core.ui.wizards.TableEditorWizard; import edu.utah.sci.cyclist.core.util.AwesomeIcon; @@ -70,9 +77,12 @@ public class TablesPanel extends TitledPanel { private ObservableList
_items; private ObjectProperty
_tableProperty = new SimpleObjectProperty<>(); private Entry _selected = null; - private ObjectProperty _editTableProperty = new SimpleObjectProperty<>(); + private ObjectProperty _editTableProperty = new SimpleObjectProperty<>(); private ContextMenu _menu = new ContextMenu(); private Entry _selectedForEdit = null; + private Consumer> _actionOnTable; + + private InvalidationListener _listener = new InvalidationListener() { @Override @@ -127,6 +137,22 @@ public void setEditTable(Boolean value) { _editTableProperty.set(value); } + public void setTableActions(List actions, Consumer> callback) { + _actionOnTable = callback; + int pos = 0; + for (String name: actions) { + MenuItem item = new MenuItem(name); + item.setOnAction(new EventHandler() { + public void handle(ActionEvent e) { + _actionOnTable.accept(new Pair(name, _selectedForEdit.table)); + } + }); + _menu.getItems().add(pos++, item); + } + + _menu.getItems().add(pos, new SeparatorMenuItem()); + } + private void resetContent() { VBox vbox = (VBox) getContent(); vbox.getChildren().clear(); @@ -258,22 +284,23 @@ private List
sortRealAndSimulatedTables(){ * Creates a menu to edit or delete a table. */ private void createMenu(){ + MenuItem deleteTable = new MenuItem("Delete Table"); deleteTable.setOnAction(new EventHandler() { - public void handle(ActionEvent e) { - removeTable(_selectedForEdit); - setEditTable(true); - _selectedForEdit = null; - } + public void handle(ActionEvent e) { + removeTable(_selectedForEdit); + setEditTable(true); + _selectedForEdit = null; + } }); _menu.getItems().add(deleteTable); MenuItem editTable = new MenuItem("Edit Table"); editTable.setOnAction(new EventHandler() { - public void handle(ActionEvent e) { - editTable(_selectedForEdit); - _selectedForEdit = null; - } + public void handle(ActionEvent e) { + editTable(_selectedForEdit); + _selectedForEdit = null; + } }); _menu.getItems().add(editTable); } diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/views/BaseWorkspace.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/views/BaseWorkspace.java new file mode 100644 index 00000000..7828ca6c --- /dev/null +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/views/BaseWorkspace.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * Copyright (c) 2013 SCI Institute, University of Utah. + * All rights reserved. + * + * License for the specific language governing rights and limitations under Permission + * is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: The above copyright notice + * and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR + * A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Contributors: + * Yarden Livnat + *******************************************************************************/ +package edu.utah.sci.cyclist.core.ui.views; + +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.geometry.Bounds; +import javafx.geometry.Insets; +import javafx.geometry.Orientation; +import javafx.geometry.Point2D; +import javafx.scene.control.SplitPane; +import javafx.scene.input.TransferMode; +import javafx.scene.layout.Pane; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.mo.closure.v1.Closure; + +import edu.utah.sci.cyclist.ToolsLibrary; +import edu.utah.sci.cyclist.core.event.dnd.DnD; +import edu.utah.sci.cyclist.core.event.ui.CyclistDropEvent; +import edu.utah.sci.cyclist.core.model.Table; +import edu.utah.sci.cyclist.core.tools.Tool; +import edu.utah.sci.cyclist.core.ui.CyclistView; +import edu.utah.sci.cyclist.core.ui.View; +import edu.utah.sci.cyclist.core.ui.components.Console; +import edu.utah.sci.cyclist.core.ui.components.CyclistViewBase; +import edu.utah.sci.cyclist.core.ui.components.InfinitPane; +import edu.utah.sci.cyclist.core.ui.components.ViewBase; + +public class BaseWorkspace extends ViewBase { + public static final String WORKSPACE_ID = "base-workspace"; + + static final Logger log = LogManager.getLogger(BaseWorkspace.class.getName()); + + private Pane _pane; + + private ViewBase _maximizedView = null; + + private Closure.V3 _onToolDrop = null; + private Closure.V4 _onShowTable = null; + + public void setOnToolDrop(Closure.V3 action) { + _onToolDrop = action; + } + + public void setOnShowTable(Closure.V4 action) { + _onShowTable = action; + } + + // -- Properties + + // OnToolDrop + private ObjectProperty> _propertyOnToolDrop = new SimpleObjectProperty>(); + + public final ObjectProperty> onToolDropPropery() { + return _propertyOnToolDrop; + } + + public final void setOnToolDrop(EventHandler eventHandler) { + _propertyOnToolDrop.set(eventHandler); + } + + public final EventHandler getOnToolDrop() { + return _propertyOnToolDrop.get(); + } + + /** + * Constructor + */ + + public BaseWorkspace() { + this(false); + } + + public BaseWorkspace(boolean toplevel) { + super(toplevel); + build(toplevel); + enableDragging(!toplevel); + } + + private void build(boolean toplevel) { + getStyleClass().add("workspace"); + setTitle("Workspace"); + setPadding(new Insets(5, 10, 5, 10)); + + InfinitPane ipane = new InfinitPane(); + _pane = ipane.getPane(); + _pane.getStyleClass().add("workspace-pane"); + + Console console = new Console(); + + // arrange console bellow the infinite workspace + SplitPane sp1 = new SplitPane(); + sp1.setOrientation(Orientation.VERTICAL); + sp1.setDividerPosition(0, 0.9); + sp1.getItems().addAll(ipane, console); + + SplitPane.setResizableWithParent(ipane, true); + SplitPane.setResizableWithParent(console, false);; + + SplitPane.setResizableWithParent(ipane, true); + setContent(sp1, !toplevel); + + /* + * set up listeners + */ + + _pane.widthProperty().addListener(e->{ + if (_maximizedView != null) { + _maximizedView.setPrefWidth(_pane.getWidth()); + } + }); + + _pane.heightProperty().addListener(e->{ + if (_maximizedView != null) { + _maximizedView.setPrefHeight(_pane.getHeight()); + } + }); + + setOnDragOver(event->{ + if (event.getTarget() == _pane) { + DnD.LocalClipboard clipboard = getLocalClipboard(); + if (clipboard.hasContent(DnD.TOOL_FORMAT) || clipboard.hasContent(DnD.TABLE_FORMAT)) + { + event.acceptTransferModes(TransferMode.COPY); + event.consume(); + } else if (clipboard.hasContent(DnD.FIELD_FORMAT)) { + event.acceptTransferModes(TransferMode.MOVE); + event.consume(); + } + } + }); + + setOnDragDropped(event->{ + boolean accept = false; + DnD.LocalClipboard clipboard = getLocalClipboard(); + if (event.getGestureSource() != this) { + if ( clipboard.hasContent(DnD.TOOL_FORMAT)) { + Tool tool = clipboard.get(DnD.TOOL_FORMAT, Tool.class); + if (_onToolDrop != null) { + Point2D p = _pane.sceneToLocal(event.getSceneX(), event.getSceneY()); + _onToolDrop.call(tool, p.getX(), p.getY()); + if(getOnToolDrop() != null){ + getOnToolDrop().handle(new CyclistDropEvent(CyclistDropEvent.DROP, tool, null, p.getX(),p.getY())); + } + } + accept = true; + } else if (clipboard.hasContent(DnD.TABLE_FORMAT)) { + Table table = clipboard.get(DnD.TABLE_FORMAT, Table.class); + Tool tool; + try { + tool = ToolsLibrary.createTool("Table"); + if (_onShowTable != null) { + Point2D p = _pane.sceneToLocal(event.getSceneX(), event.getSceneY()); + _onShowTable.call(tool, table, p.getX(), p.getY()); + if(getOnToolDrop() != null){ + getOnToolDrop().handle(new CyclistDropEvent(CyclistDropEvent.DROP_DATASOURCE, tool, table, p.getX(), p.getY())); + } + accept = true; + } + } catch (Exception e) { + log.error("Can not create a TableView", e); + } + + } +// else if (clipboard.hasContent(DnD.FIELD_FORMAT)) { +// // HACK: accept but don't do anything. +// // This allows fields to be remove from other places without causing the DnD to fail +// status = true; +// } + } + if (accept) { + event.setDropCompleted(accept); + event.consume(); + } + }); + } + + @Override + public void setTitle(String title) { + super.setTitle(title); + } + + public void selectView(View view) { + ViewBase node = (ViewBase) view; + node.toFront(); + } + /** + * add a new view to the workspace + * @param view + */ + public void addView(final ViewBase view) { + _pane.getChildren().add(view); + + view.setOnSelect(new EventHandler() { + @Override + public void handle(ActionEvent event) { + view.toFront(); + } + }); + + view.setOnMinmax(new EventHandler() { + @Override + public void handle(ActionEvent event) { + if (view.isMaximized()) { + view.setLayoutX(_viewPos.x); + view.setLayoutY(_viewPos.y); + view.setPrefSize(_viewPos.width, _viewPos.height); + + view.setMaximized(false); + _maximizedView = null; + } else { + _viewPos.x = view.getLayoutX(); + _viewPos.y = view.getLayoutY(); + _viewPos.width = view.getWidth(); + _viewPos.height = view.getHeight(); + + view.setLayoutX(0); + view.setLayoutY(0); + Bounds b = _pane.getLayoutBounds(); + view.setPrefSize(b.getWidth(), b.getHeight()); + + view.toFront(); + + view.setMaximized(true); + _maximizedView = view; + + view.select(); + } + } + }); + } + + + /** + * will be called by the workspace presenter + * @param view + */ + public void removeView(ViewBase view) { + view.setOnSelect(null); + _pane.getChildren().remove(view); + if(getOnToolDrop() != null){ + getOnToolDrop().handle(new CyclistDropEvent(CyclistDropEvent.REMOVE, view)); + } + } + + private ViewPos _viewPos = new ViewPos(); +} + +class ViewPos { + public double x; + public double y; + public double width; + public double height; +} \ No newline at end of file diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/views/ChartView.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/views/ChartView.java index a2ee320c..757fe56a 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/views/ChartView.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/views/ChartView.java @@ -6,10 +6,14 @@ import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import javafx.beans.InvalidationListener; import javafx.beans.Observable; @@ -65,6 +69,7 @@ import edu.utah.sci.cyclist.Cyclist; import edu.utah.sci.cyclist.core.controller.IMemento; +import edu.utah.sci.cyclist.core.event.Pair; import edu.utah.sci.cyclist.core.event.dnd.DnD; import edu.utah.sci.cyclist.core.event.ui.FilterEvent; import edu.utah.sci.cyclist.core.model.Context; @@ -94,11 +99,14 @@ public class ChartView extends CyclistViewBase { public static final String TITLE = "Plot"; static Logger log = Logger.getLogger(ChartView.class); + public static Double CYCLUS_INFINITY = 1e50; + enum ViewType { CROSS_TAB, BAR, LINE, SCATTER_PLOT, GANTT, NA } enum MarkType { TEXT, BAR, LINE, SHAPE, GANTT, NA } - + public static double CYCLIST_MAX_VALUE = 1e90; + private boolean _active = true; private TableProxy _tableProxy = null; @@ -118,7 +126,7 @@ enum MarkType { TEXT, BAR, LINE, SHAPE, GANTT, NA } private ObservableList _indicators = FXCollections.observableArrayList(); private Map _lineIndicators = new HashMap<>(); private List _distanceIndicators = new ArrayList<>(); - + private Set _seriesWithInfinity = new HashSet(); private Closure.V0 _onDuplicate = null; private Spec _currentSpec = null; @@ -127,6 +135,8 @@ enum MarkType { TEXT, BAR, LINE, SHAPE, GANTT, NA } private DropArea _xArea; private DropArea _yArea; private DropArea _lodArea; + private Text _warningText = new Text(); + private Text _warningLabel = new Text("Warning"); private ObjectProperty
_currentTableProperty = new SimpleObjectProperty<>(); @@ -474,29 +484,22 @@ private boolean compatible(AxisSpec spec, AxisSpec current) { @SuppressWarnings("unchecked") private void assignData(List list, Spec spec) { log.debug("chart data has "+list.size()+" rows"); + _seriesWithInfinity.clear(); if (list.size() == 0) { log.debug("no data"); getChart().getData().clear(); _currentSpec = spec; + checkForInfinities(null); return; } - - log.debug("data has "+list.size()+" rows"); -// if (list.size() > 5000) { -// log.warn("Too many data points (>5000). Ignored"); -// return; -// } - + + Map>> dataMap = split(list, spec); - int c = _currentSpec.seriesMap.size(); - int r = 0; - int n = 0; // remove current series that are not part of the new data for (MultiKey key : _currentSpec.seriesMap.keySet()) { if (!dataMap.containsKey(key)) { getChart().getData().remove(_currentSpec.seriesMap.get(key)); - r++; } } @@ -508,17 +511,40 @@ private void assignData(List list, Spec spec) { series = new XYChart.Series(); series.setName(createLabel(key)); add.add(series); - n++; } ObservableList> data = dataMap.get(key); series.setData(data); spec.seriesMap.put(key, series); } spec.dataMap = dataMap; - log.debug(" p: "+c+" r:"+r+" n:"+n); getChart().getData().addAll(add); getChart().setLegendVisible(spec.seriesMap.size() > 1); _currentSpec = spec; + + checkForInfinities(dataMap.keySet()); + + } + + private void checkForInfinities(Collection keys ) { + String s = ""; + if (keys != null) { + for (MultiKey bad : _seriesWithInfinity) { + if (keys.contains(bad)) { + s += createLabel(bad) + " "; + } + } + } + + if (s.equals("")) { + _warningLabel.setVisible(false); + _warningText.setText(""); + } + else { + s = s.equals(" ") ? "Infinity values removed" : + ("Infinity values removed from: "+s); + _warningText.setText(s); + _warningLabel.setVisible(true); + } } private String createLabel(MultiKey key) { @@ -560,21 +586,29 @@ private Map>> split(List> series = map.get(key); if (series == null) { series = FXCollections.observableArrayList(); map.put(key, series); } - series.add(pt); + + if (pt == null) { + _seriesWithInfinity.add(key); + } else { + series.add(pt); + } } } } return map; } + private XYChart.Data createPoint(Object x, Object y, Classification cx, Classification cy) { x = convert(x, cx); y = convert(y, cy); + if (x == null || y == null) return null; XYChart.Data pt = new XYChart.Data(x, y); return pt; } @@ -600,13 +634,13 @@ private Object convert(Object v, Classification c) { case Qi: case Qd: if (v instanceof Number) { - // ignore + if (v instanceof Double && ((Double) v) > CYCLUS_INFINITY) return null; } else if (v instanceof CyclistData) { v = ((CyclistData)v).toNumber(); } else { // Data can not be visualize // Don't throw an exception - return 0; + v = 0; } } return v; @@ -746,7 +780,7 @@ private void setChart(XYChart chart, Spec spec) { _currentSpec = spec != null? spec : new Spec(); setChart(chart); } else { - Text text = new Text("Unsupported fields combination"); + Text text = new Text("No data"); _stackPane.getChildren().add(0, text); _currentSpec = new Spec(); } @@ -1220,6 +1254,10 @@ private Node createControl() { _xArea = createControlArea(grid, "X", 0, 0, 1, DropArea.Policy.SINGLE, DropArea.AcceptedRoles.ALL); _yArea = createControlArea(grid, "Y", 1, 0, 1, DropArea.Policy.MULTIPLE, DropArea.AcceptedRoles.ALL); _lodArea = createControlArea(grid, "Group by", 0, 2, 2, DropArea.Policy.MULTIPLE, DropArea.AcceptedRoles.DIMENSION); + + _warningLabel.setVisible(false); + grid.add(_warningLabel, 2, 1); + grid.add(_warningText, 3, 1); return grid; } @@ -1264,8 +1302,8 @@ public void invalidated(Observable o) { Filter filter = (Filter) o; // LOD filters only show/hide data. No need to fetch new data // TODO: is this true only for classification == C? Seems to be true for any field that is not range - if(isInLodArea(filter.getField()) && filter.getField().getClassification() == Classification.C ) { - invalidateLODFilters(filter); + if(_currentSpec != null && isInLodArea(filter.getField()) && filter.getField().getClassification() == Classification.C ) { +// invalidateLODFilters(filter); filter.setValid(true); reassignData(filter); } else { @@ -1381,10 +1419,10 @@ private void reassignData(Filter filter) { for (MultiKey multikey : _currentSpec.seriesMap.keySet()) { Object keyValue = multikey.getKey(idx); if (!filter.getSelectedValues().contains(keyValue)) { - // remove keys.add(multikey); } } + for (MultiKey multikey : keys) { getChart().getData().remove(_currentSpec.seriesMap.get(multikey)); _currentSpec.seriesMap.remove(multikey); @@ -1392,15 +1430,19 @@ private void reassignData(Filter filter) { keys.clear(); // add series - for (MultiKey multikey : _currentSpec.dataMap.keySet()) { - Object keyValue = multikey.getKey(idx); - if (filter.getSelectedValues().contains(keyValue) - && !_currentSpec.seriesMap.containsKey(multikey)) { + + keys = new ArrayList<>(_currentSpec.dataMap.keySet()); + for (Pair p : getLODFilters()) { + Iterator i = keys.iterator(); + while (i.hasNext()) { + MultiKey key = i.next(); + Object keyValue = key.getKey(p.v1+2); + if (!p.v2.getSelectedValues().contains(keyValue) + || _currentSpec.seriesMap.containsKey(key)) { - // add - keys.add(multikey); + i.remove(); } - } + } } for (MultiKey multikey : keys) { @@ -1412,9 +1454,36 @@ private void reassignData(Filter filter) { } getChart().setLegendVisible(_currentSpec.seriesMap.size() > 1); + checkForInfinities(_currentSpec.seriesMap.keySet()); + } + + private List> getLODFilters() { + List> list = new ArrayList<>(); + int idx = -1; + for (FieldInfo info : _currentSpec.lod) { + idx++; + boolean found = false; + String name = info.field.getName(); + for (Filter f : filters()) { + if (f.getField().getName().equals(name)) { + list.add(new Pair(idx, f)); + found = true; + break; + } + } + if (!found) { + for (Filter f : remoteFilters()) { + if (f.getField().getName().equals(name)) { + list.add(new Pair(idx, f)); + found = true; + break; + } + } + } + } + return list; } - /*Name: setAreaFiltersListeners * This method handles fields which are connected to a filter * If the field SQL function has changed the filter has to be changed accordingly @@ -1537,4 +1606,4 @@ public FieldInfo(Field field, int index) { } } -} \ No newline at end of file +} diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/views/SimpleTableView.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/views/SimpleTableView.java index 2e8b0d44..6f409a18 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/views/SimpleTableView.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/views/SimpleTableView.java @@ -257,7 +257,7 @@ public void selectTable(Table table, boolean active) { if (active) { _currentTable = table; - _simField = table.getField(SIMULATION_FIELD_NAME); + _simField = table.getField(SIMULATION_FIELD_NAME, false); Simulation sim = getCurrentSimulation(); if(sim != null){ _simFilter = new ValueFilter(_simField, sim.getSimulationId()); diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/views/Workspace.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/views/VisWorkspace.java similarity index 91% rename from cyclist/src/edu/utah/sci/cyclist/core/ui/views/Workspace.java rename to cyclist/src/edu/utah/sci/cyclist/core/ui/views/VisWorkspace.java index 38b50bb9..23d356b0 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/views/Workspace.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/views/VisWorkspace.java @@ -57,12 +57,13 @@ import edu.utah.sci.cyclist.core.ui.components.WorkspacePanelArea; import edu.utah.sci.cyclist.core.ui.panels.TitledPanel; -public class Workspace extends CyclistViewBase implements CyclistView { +public class VisWorkspace extends CyclistViewBase implements CyclistView { public static final String WORKSPACE_ID = "workspace"; - static final Logger log = LogManager.getLogger(Workspace.class.getName()); + static final Logger log = LogManager.getLogger(VisWorkspace.class.getName()); private Pane _pane; + private Console _console; private WorkspacePanelArea _filtersPane; ScrollBar _wb; @@ -84,6 +85,10 @@ public void setOnShowTable(Closure.V4 action) { _onShowTable = action; } + public Console getConsole() { + return _console; + } + // -- Properties // OnToolDrop @@ -105,11 +110,11 @@ public final EventHandler getOnToolDrop() { * Constructor */ - public Workspace() { + public VisWorkspace() { this(false); } - public Workspace(boolean toplevel) { + public VisWorkspace(boolean toplevel) { super(toplevel); build(toplevel); enableDragging(!toplevel); @@ -124,16 +129,16 @@ private void build(boolean toplevel) { _pane = ipane.getPane(); _pane.getStyleClass().add("workspace-pane"); - Console console = new Console(); + _console = new Console(); // arrange console bellow the infinite workspace SplitPane sp1 = new SplitPane(); sp1.setOrientation(Orientation.VERTICAL); sp1.setDividerPosition(0, 0.9); - sp1.getItems().addAll(ipane, console); + sp1.getItems().addAll(ipane, _console); SplitPane.setResizableWithParent(ipane, true); - SplitPane.setResizableWithParent(console, false); + SplitPane.setResizableWithParent(_console, false); // arrange filters to the right _filtersPane = new WorkspacePanelArea(); @@ -174,17 +179,19 @@ private void build(boolean toplevel) { }); setOnDragOver(event->{ - if (event.getTarget() == _pane) { +// if (event.getTarget() == _pane) { DnD.LocalClipboard clipboard = getLocalClipboard(); - if (clipboard.hasContent(DnD.TOOL_FORMAT) || clipboard.hasContent(DnD.TABLE_FORMAT)) - { - event.acceptTransferModes(TransferMode.COPY); - event.consume(); - } else if (clipboard.hasContent(DnD.FIELD_FORMAT)) { - event.acceptTransferModes(TransferMode.MOVE); - event.consume(); + if (clipboard != null) { + if (clipboard.hasContent(DnD.TOOL_FORMAT) || clipboard.hasContent(DnD.TABLE_FORMAT)) + { + event.acceptTransferModes(TransferMode.COPY); + event.consume(); + } else if (clipboard.hasContent(DnD.FIELD_FORMAT)) { + event.acceptTransferModes(TransferMode.MOVE); + event.consume(); + } } - } +// } }); setOnDragDropped(event->{ @@ -363,9 +370,9 @@ private void updateFilters() { private ViewPos _viewPos = new ViewPos(); } -class ViewPos { - public double x; - public double y; - public double width; - public double height; -} \ No newline at end of file +//class ViewPos { +// public double x; +// public double y; +// public double width; +// public double height; +//} \ No newline at end of file diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/DatatableWizard.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/DatatableWizard.java index f56bec2c..321dcb7f 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/DatatableWizard.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/DatatableWizard.java @@ -55,7 +55,7 @@ import javafx.stage.Stage; import javafx.stage.Window; import edu.utah.sci.cyclist.Cyclist; -import edu.utah.sci.cyclist.core.controller.WorkDirectoryController; +import edu.utah.sci.cyclist.core.controller.SessionController; import edu.utah.sci.cyclist.core.model.CyclistDatasource; import edu.utah.sci.cyclist.core.model.Table; import edu.utah.sci.cyclist.core.ui.components.DatasourceSelector; @@ -84,7 +84,7 @@ public class DatatableWizard extends TilePane { private CyclistDatasource _current; private ObjectProperty
_selection = new SimpleObjectProperty<>(); private DatasourceSelector _selector; - private String _workDir = WorkDirectoryController.CYCLIST_DIR; + private String _workDir = SessionController.CYCLIST_DIR; private UpdateDbDialog _updateDialog; private ObjectProperty _dsIsValid = new SimpleObjectProperty<>(); private TextArea _statusText; diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/SaveWsWizard.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/SaveWsWizard.java index 5f177e7c..daae9cd0 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/SaveWsWizard.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/SaveWsWizard.java @@ -8,6 +8,7 @@ import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; +import javafx.scene.input.KeyCode; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.text.Font; @@ -55,7 +56,7 @@ private Scene createScene(final Stage dialog) { vbox.setSpacing(10); vbox.setAlignment(Pos.CENTER); - Text text = new Text("WorkSpace has been modified. Save changed? "); + Text text = new Text("Workspace has been modified. Save changed? "); text.setFont(new Font(12)); HBox hbox = new HBox(); @@ -65,12 +66,14 @@ private Scene createScene(final Stage dialog) { hbox.setMinWidth(300); Button yes = new Button("Yes"); +// yes.setDefaultButton(true); yes.setMinWidth(50); yes.setAlignment(Pos.CENTER); Button no = new Button("No"); no.setMinWidth(50); no.setAlignment(Pos.CENTER); Button cancel = new Button("Cancel"); + cancel.setCancelButton(true); cancel.setMinWidth(50); cancel.setAlignment(Pos.CENTER); hbox.getChildren().addAll(yes,no,cancel); @@ -80,6 +83,8 @@ public void handle(ActionEvent arg0) { _dialog.hide(); }; }); + cancel.setOnKeyPressed((ke)-> { if (ke.getCode() == KeyCode.ENTER) { cancel.fire(); } } ); + yes.setOnAction(new EventHandler() { @Override public void handle(ActionEvent arg0) { @@ -87,6 +92,8 @@ public void handle(ActionEvent arg0) { _dialog.hide(); }; }); + yes.setOnKeyPressed((ke)-> {if (ke.getCode() == KeyCode.ENTER) yes.fire(); } ); + no.setOnAction(new EventHandler() { @Override public void handle(ActionEvent arg0) { @@ -94,6 +101,7 @@ public void handle(ActionEvent arg0) { _dialog.hide(); }; }); + no.setOnKeyPressed((ke)-> { if (ke.getCode() == KeyCode.ENTER) no.fire(); } ); vbox.getChildren().addAll(text,hbox); diff --git a/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/WorkspaceWizard.java b/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/WorkspaceWizard.java index 19343a56..2e6b5a8a 100755 --- a/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/WorkspaceWizard.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/ui/wizards/WorkspaceWizard.java @@ -48,7 +48,7 @@ import javax.swing.JOptionPane; import edu.utah.sci.cyclist.Cyclist; -import edu.utah.sci.cyclist.core.controller.WorkDirectoryController; +import edu.utah.sci.cyclist.core.controller.SessionController; public class WorkspaceWizard extends VBox { @@ -125,7 +125,7 @@ public void handle(ActionEvent event) { if(dir.isDirectory()){ String parent= dir.getParent(); if(parent.isEmpty()){ - parent = WorkDirectoryController.DEFAULT_WORKSPACE; + parent = SessionController.DEFAULT_WORKSPACE; } File parentDir = new File(parent); if(parentDir != null){ diff --git a/cyclist/src/edu/utah/sci/cyclist/core/util/QueryBuilder.java b/cyclist/src/edu/utah/sci/cyclist/core/util/QueryBuilder.java index cf179762..a954b26c 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/util/QueryBuilder.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/util/QueryBuilder.java @@ -126,7 +126,7 @@ public String toString() { builder.append(SQL.getFunction(field.getString(FieldProperties.AGGREGATION_FUNC)).format(field.getName())); } - append(builder, first, _grouping); + first = append(builder, first, _grouping); if (first) { // no projection -> use '*' diff --git a/cyclist/src/edu/utah/sci/cyclist/core/util/SimulationTablesPostProcessor.java b/cyclist/src/edu/utah/sci/cyclist/core/util/SimulationTablesPostProcessor.java index c67a2c4d..6b6be06b 100644 --- a/cyclist/src/edu/utah/sci/cyclist/core/util/SimulationTablesPostProcessor.java +++ b/cyclist/src/edu/utah/sci/cyclist/core/util/SimulationTablesPostProcessor.java @@ -49,6 +49,7 @@ public class SimulationTablesPostProcessor { "EnterTime INTEGER,"+ "ExitTime INTEGER,"+ "Lifetime INTEGER)"; + private static final String FACILITIES_TABLE_UPDATE = "replace into Facilities(SimID,AgentId,Spec,Prototype,InstitutionId,RegionId,EnterTime,ExitTime,Lifetime) "+ "select f.SimId, f.AgentId, f.Spec, f.Prototype, i.AgentId, " + "cast(-1 as INTEGER), f.EnterTime, f.ExitTime, f.Lifetime from Agents as f, Agents as i " + @@ -69,7 +70,8 @@ public class SimulationTablesPostProcessor { + " INNER JOIN Compositions AS cmp ON cmp.QualId = inv.QualId " + " WHERE " + " inv.SimId = cmp.SimId AND inv.SimId = ag.SimId and tl.SimId=inv.SimId " - + " GROUP BY inv.SimId, tl.Time, cmp.NucId, ag.AgentID;"; + + " GROUP BY inv.SimId, tl.Time, cmp.NucId, ag.AgentID; " + + "CREATE INDEX IF NOT EXISTS QuantityInventoryBase_idx ON QuantityInventoryBase (simid,agentid,time,nucid,quantity)"; private static final String QUANTITY_INVENTORY_VIEW_CREATE = "CREATE view if not exists QuantityInventory as " @@ -92,7 +94,9 @@ public class SimulationTablesPostProcessor { + " WHERE " + " tr.SimId = res.SimId AND ag.SimId = tr.SimId and cmp.SimId=res.SimId " + " GROUP BY res.SimId, cmp.NucId, tr.Time, ag.AgentID" - + " ORDER BY tr.Time ASC;"; + + " ORDER BY tr.Time ASC;" + + " CREATE INDEX IF NOT EXISTS QuantityTransactedBase_idx ON QuantityTransactedBase (simid,agentid,time,nucid,quantity); "; + private static final String QUANTITY_TRANSACTED_VIEW_CREATE = "CREATE view if not exists QuantityTransacted as " @@ -105,16 +109,20 @@ public class SimulationTablesPostProcessor { private QueryOperation[] UpdateTablesRunningOrderTbl = { - new QueryOperation("Fix \"Agents\" table phase #1",FIX_AGENTS_TABLE_PHASE1), - new QueryOperation("Fix \"Agents\" table phase #2",FIX_AGENTS_TABLE_PHASE2), - new QueryOperation("Create \"Facilitites\" table",FACILITIES_TABLE_CREATE), - new QueryOperation("Update \"Facilitites\" table",FACILITIES_TABLE_UPDATE), - new QueryOperation("Create \"Facilitites\" index",FACILITIES_TABLE_INDEX), - new QueryOperation("Create base table \"QuantityInventoryBase\"",QUANTITY_INVENTORY_BASE_CREATE), - new QueryOperation("Create view \"QuantityInventory\"",QUANTITY_INVENTORY_VIEW_CREATE), - new QueryOperation("Create base table \"QuantityTransactedBase\"",QUANTITY_TRANSACTED_BASE_CREATE), - new QueryOperation("Create view \"QuantityTransacted\"",QUANTITY_TRANSACTED_VIEW_CREATE), - new QueryOperation("Create table \"UpdatedIndication\"",UPDATED_INDICATION_TABLE_CREATE) + new QueryOperation("Fix Agents table phase #1",FIX_AGENTS_TABLE_PHASE1), + new QueryOperation("Fix Agents table phase #2",FIX_AGENTS_TABLE_PHASE2), + + new QueryOperation("Create Facilitites table",FACILITIES_TABLE_CREATE), + new QueryOperation("Update Facilitites table",FACILITIES_TABLE_UPDATE), + new QueryOperation("Create Facilitites index",FACILITIES_TABLE_INDEX), + + new QueryOperation("Create base table QuantityInventoryBase",QUANTITY_INVENTORY_BASE_CREATE), + new QueryOperation("Create view QuantityInventory",QUANTITY_INVENTORY_VIEW_CREATE), + + new QueryOperation("Create base table QuantityTransactedBase",QUANTITY_TRANSACTED_BASE_CREATE), + new QueryOperation("Create view QuantityTransacted",QUANTITY_TRANSACTED_VIEW_CREATE), + + new QueryOperation("Create table UpdatedIndication",UPDATED_INDICATION_TABLE_CREATE) }; private static final Map applicationsMap; @@ -410,7 +418,7 @@ private Boolean createAdditionalTables(CyclistDatasource ds){ } return true; } catch (SQLException e) { - log.warn("Create additional table failed"); + log.warn("Create additional table failed:", e); return false; }finally{ try { diff --git a/cyclist/src/edu/utah/sci/cyclist/neup/ui/views/inventory/InventoryChart.java b/cyclist/src/edu/utah/sci/cyclist/neup/ui/views/inventory/InventoryChart.java index 24b40d17..16c21e2b 100644 --- a/cyclist/src/edu/utah/sci/cyclist/neup/ui/views/inventory/InventoryChart.java +++ b/cyclist/src/edu/utah/sci/cyclist/neup/ui/views/inventory/InventoryChart.java @@ -312,7 +312,10 @@ private void updateSeries(XYChart.Series series, Collection value : values) { double v = value.v2/_scale; if (first) { - prev = v; + if (value.v1 > 0) + list.add(new XYChart.Data(value.v1-1, 0)); + else + prev = v; first = false; } list.add(new XYChart.Data(value.v1, v-prev)); diff --git a/cyclist/src/edu/utexas/cycic/Clones.java b/cyclist/src/edu/utexas/cycic/Clones.java index e269855c..34811a6c 100644 --- a/cyclist/src/edu/utexas/cycic/Clones.java +++ b/cyclist/src/edu/utexas/cycic/Clones.java @@ -67,7 +67,7 @@ static void addClone(String name, final facilityNode parent, Boolean parentChild clone.rgbColor.set(0, (int)(clone.rgbColor.get(0)*VisFunctions.colorMultiplierTest(clone.rgbColor.get(0)))); clone.rgbColor.set(1, (int)(clone.rgbColor.get(1)*VisFunctions.colorMultiplierTest(clone.rgbColor.get(1)))); clone.rgbColor.set(2, (int)(clone.rgbColor.get(2)*VisFunctions.colorMultiplierTest(clone.rgbColor.get(2)))); - clone.setFill(Color.rgb(clone.rgbColor.get(0), clone.rgbColor.get(1), clone.rgbColor.get(2))); + clone.setFill(VisFunctions.pastelize(Color.rgb(clone.rgbColor.get(0), clone.rgbColor.get(1), clone.rgbColor.get(2)))); // Setting font color for visibility // if(VisFunctions.colorTest(clone.rgbColor) == true){ @@ -87,18 +87,14 @@ static void addClone(String name, final facilityNode parent, Boolean parentChild // Adding the facility menu // final Menu menu1 = new Menu((String) clone.name); - MenuItem facForm = new MenuItem("Facility Form"); + MenuItem facForm = new MenuItem("Configure"); MenuItem delete = new MenuItem("Delete"); delete.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ removeClone(cloneNode, parent); } }); - menu1.getItems().addAll(facForm, delete); - clone.menu.getMenus().add(menu1); - clone.menu.setLayoutX(clone.getCenterX()); - clone.menu.setLayoutY(clone.getCenterY()); - clone.menu.setVisible(false); + clone.menu.getItems().addAll(facForm, delete); // Adding circle.text to be shown in the CYCIC pane. clone.text.setText(name.toString()); clone.text.setLayoutX(clone.getCenterX()-clone.getRadius()*0.6); @@ -129,7 +125,7 @@ public void handle(MouseEvent event){ Dragboard db = clone.startDragAndDrop(TransferMode.COPY); ClipboardContent content = new ClipboardContent(); - content.put( DnD.TOOL_FORMAT, "Facility Form"); + content.put( DnD.TOOL_FORMAT, "Configure"); db.setContent(content); // DnDIcon.getInstance().show(icon, title); @@ -168,8 +164,7 @@ public void handle(MouseEvent event){ if(clone.getCenterX() >= Cycic.pane.getLayoutBounds().getMaxX()-clone.getRadius()){ clone.setCenterX(Cycic.pane.getLayoutBounds().getMaxX()-clone.getRadius()); } - clone.menu.setLayoutX(clone.getCenterX()); - clone.menu.setLayoutY(clone.getCenterY()); + clone.text.setLayoutX(clone.getCenterX()-clone.getRadius()*0.6); clone.text.setLayoutY(clone.getCenterY()); parentChild.line.setEndX(clone.getCenterX()); @@ -189,7 +184,7 @@ public void handle(MouseEvent event){ @Override public void handle(MouseEvent event){ if(event.getButton().equals(MouseButton.SECONDARY)){ - clone.menu.setVisible(true); + clone.menu.show(clone, event.getX(), event.getY()); } if(event.getButton().equals(MouseButton.PRIMARY)){ for(int i = 0; i < Cycic.pane.getChildren().size(); i++){ @@ -211,7 +206,6 @@ public void handle(MouseEvent event){ int childIndex = parent.cycicCircle.childrenList.size(); if(parentChildShow == true){ Cycic.pane.getChildren().add(parent.cycicCircle.childrenList.get(childIndex-1)); - Cycic.pane.getChildren().add(parent.cycicCircle.childrenList.get(childIndex-1).menu); Cycic.pane.getChildren().add(parent.cycicCircle.childrenList.get(childIndex-1).text); Cycic.pane.getChildren().add(parentChild.line); parentChild.line.toBack(); @@ -240,6 +234,6 @@ static void removeClone(facilityNode child, facilityNode parent){ parent.facilityClones.remove(i); } } - VisFunctions.marketHide(); + VisFunctions.redrawPane(); } } diff --git a/cyclist/src/edu/utexas/cycic/ConnectorLine.java b/cyclist/src/edu/utexas/cycic/ConnectorLine.java index 0876c98f..69ae5b63 100644 --- a/cyclist/src/edu/utexas/cycic/ConnectorLine.java +++ b/cyclist/src/edu/utexas/cycic/ConnectorLine.java @@ -1,32 +1,45 @@ package edu.utexas.cycic; +import javafx.scene.paint.Color; import javafx.scene.shape.Line; +import javafx.scene.text.Font; import javafx.scene.text.Text; public class ConnectorLine extends Line { + { + setStroke(Color.BLACK); + } Line right = new Line(){ { setStrokeWidth(2); + setStroke(Color.BLACK); } }; Line left = new Line(){ { setStrokeWidth(2); + setStroke(Color.BLACK); } }; Line right1 = new Line(){ { setStrokeWidth(2); + setStroke(Color.BLACK); } }; Line left1 = new Line(){ { setStrokeWidth(2); + setStroke(Color.BLACK); + } + }; + Text text = new Text(){ + { + setFill(Color.BLACK); + setFont(new Font(20)); } }; - - Text text = new Text(); public void updatePosition(){ double x1 = getEndX(); double y1 = getEndY(); @@ -59,7 +72,20 @@ public void updatePosition(){ left.setEndY((y1 + (y2-y1)*0.71)+5.0*(x2-x1)/Math.sqrt(Math.pow((y2-y1), 2)+Math.pow(x2-x1, 2))); text.setX(x1 + (x2-x1)*0.55+10.0*(y2-y1)/Math.sqrt(Math.pow((y2-y1), 2)+Math.pow(x2-x1, 2))); - text.setY(y1 + (y2-y1)*0.55-10.0*(x2-x1)/Math.sqrt(Math.pow((y2-y1), 2)+Math.pow(x2-x1, 2))); + text.setY(y1 + (y2-y1)*0.55+10.0*(x2-x1)/Math.sqrt(Math.pow((y2-y1), 2)+Math.pow(x2-x1, 2))); + } + public void updateColor(Color color){ + this.setStroke(color); + right1.setStroke(color); + right.setStroke(color); + left1.setStroke(color); + left.setStroke(color); + text.setFill(color); + } + public void hideText(){ + Cycic.pane.getChildren().remove(text); + } + public void showText(){ + Cycic.pane.getChildren().add(text); } - } diff --git a/cyclist/src/edu/utexas/cycic/CycICDnD.java b/cyclist/src/edu/utexas/cycic/CycICDnD.java new file mode 100644 index 00000000..d54dfbf2 --- /dev/null +++ b/cyclist/src/edu/utexas/cycic/CycICDnD.java @@ -0,0 +1,8 @@ +package edu.utexas.cycic; + +import javafx.scene.input.DataFormat; + +public class CycICDnD { + + public static final DataFormat UNASSOC_FAC = new DataFormat("cyclist.dnd.unassocFac"); +} diff --git a/cyclist/src/edu/utexas/cycic/Cycic.java b/cyclist/src/edu/utexas/cycic/Cycic.java index d5653417..ff8aed85 100644 --- a/cyclist/src/edu/utexas/cycic/Cycic.java +++ b/cyclist/src/edu/utexas/cycic/Cycic.java @@ -1,8 +1,5 @@ package edu.utexas.cycic; -import java.io.FileReader; -import java.io.Reader; -import java.io.StringReader; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -11,46 +8,40 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; -import java.util.regex.Pattern; +import java.util.List; +import java.util.Optional; -import org.apache.log4j.Logger; - -import edu.utah.sci.cyclist.Cyclist; -import edu.utah.sci.cyclist.core.Resources1; -import edu.utah.sci.cyclist.core.event.dnd.DnD; -import edu.utah.sci.cyclist.core.ui.components.ViewBase; -import edu.utah.sci.cyclist.core.util.AwesomeIcon; -import edu.utah.sci.cyclist.core.util.GlyphRegistry; -import edu.utah.sci.cyclist.core.controller.CyclistController; -import edu.utah.sci.cyclist.core.model.CyclusJob; -import edu.utah.sci.cyclist.core.model.CyclusJob.Status; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; import javafx.embed.swing.SwingFXUtils; import javafx.event.ActionEvent; import javafx.event.EventHandler; - -import javax.imageio.ImageIO; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonReader; -import javax.json.JsonString; - +import javafx.geometry.HPos; import javafx.geometry.Insets; import javafx.scene.SnapshotParameters; import javafx.scene.control.Button; +import javafx.scene.control.ButtonBar.ButtonData; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ColorPicker; import javafx.scene.control.ComboBox; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.Dialog; import javafx.scene.control.Label; +import javafx.scene.control.Menu; +import javafx.scene.control.MenuItem; +import javafx.scene.control.RadioButton; import javafx.scene.control.ScrollPane; +import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; -import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleGroup; import javafx.scene.control.Tooltip; import javafx.scene.image.WritableImage; import javafx.scene.input.ClipboardContent; import javafx.scene.input.DragEvent; import javafx.scene.input.Dragboard; +import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; import javafx.scene.input.TransferMode; import javafx.scene.layout.GridPane; @@ -59,12 +50,29 @@ import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.text.Font; -import javafx.scene.text.TextAlignment; import javafx.stage.FileChooser; import javafx.stage.Window; +import javax.imageio.ImageIO; + +import org.apache.log4j.Logger; + +import edu.utah.sci.cyclist.Cyclist; +import edu.utah.sci.cyclist.core.controller.CyclistController; +import edu.utah.sci.cyclist.core.event.dnd.DnD; +import edu.utah.sci.cyclist.core.event.dnd.DnD.LocalClipboard; +import edu.utah.sci.cyclist.core.event.notification.CyclistNotification; +import edu.utah.sci.cyclist.core.model.CyclusJob; +import edu.utah.sci.cyclist.core.model.CyclusJob.Status; +import edu.utah.sci.cyclist.core.model.Preferences; +import edu.utah.sci.cyclist.core.ui.components.ViewBase; +import edu.utah.sci.cyclist.core.util.AwesomeIcon; +import edu.utah.sci.cyclist.core.util.GlyphRegistry; +import edu.utexas.cycic.presenter.CycicPresenter; + public class Cycic extends ViewBase{ static Logger log = Logger.getLogger(Cycic.class); + /** * Function for building the CYCIC Pane and GridPane of this view. */ @@ -80,6 +88,9 @@ public Cycic(){ } init(); } + /** + * + */ public static final String TITLE = "Cycic"; static Pane pane = new Pane(); Pane nodesPane = new Pane(); @@ -87,13 +98,19 @@ public Cycic(){ static DataArrays workingScenario; static boolean marketHideBool = true; static Window window; - ComboBox skins = new ComboBox(); static ToggleGroup opSwitch = new ToggleGroup(); - static ToggleButton localToggle = new ToggleButton("Local"); - static ToggleButton remoteToggle = new ToggleButton("Remote"); static CyclusJob _remoteDashA; private static Object monitor = new Object(); + static String currentSkin = "Default Skin"; + static String currentServer = ""; + static TextField duration = VisFunctions.numberField(); + static ComboBox startMonth = new ComboBox(); + static TextField startYear = VisFunctions.numberField(); + static TextArea description = new TextArea(); + static ComboBox decay = new ComboBox(); + static TextField simHandle = new TextField(); + /** * */ @@ -184,22 +201,131 @@ public void handle(ActionEvent e){ } }; + + private void updateLinkColor(){ + ColorPicker cP = new ColorPicker(); + cP.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + for(nodeLink node: DataArrays.Links){ + node.line.updateColor(cP.getValue()); + } + } + }); + Dialog dg = new Dialog(); + ButtonType loginButtonType = new ButtonType("Ok", ButtonData.OK_DONE); + dg.getDialogPane().setContent(cP); + dg.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL); + dg.setResizable(true); + dg.show(); + + } + private void updateBgColor(){ + ColorPicker cP = new ColorPicker(); + cP.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + String background = "-fx-background-color: #"; + background += cP.getValue().toString().substring(2, 8); + pane.setStyle(background); + } + }); + Dialog dg = new Dialog(); + ButtonType loginButtonType = new ButtonType("Ok", ButtonData.OK_DONE); + dg.getDialogPane().setContent(cP); + dg.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL); + dg.setResizable(true); + dg.show(); + + } + + private void setSkin() { + + if(currentSkin.equalsIgnoreCase("Default Skin")){ + for(int j = 0; j < DataArrays.FacilityNodes.size(); j++){ + DataArrays.FacilityNodes.get(j).cycicCircle.image.setVisible(false); + DataArrays.FacilityNodes.get(j).cycicCircle.setOpacity(100); + } + } else { + for(int i = 0; i < DataArrays.visualizationSkins.size(); i++){ + skinSet skin = DataArrays.visualizationSkins.get(i); + if(skin.name.equalsIgnoreCase(currentSkin)){ + for(int j = 0; j < DataArrays.FacilityNodes.size(); j++){ + DataArrays.FacilityNodes.get(j).cycicCircle.image.setImage(skin.images.getOrDefault(DataArrays.FacilityNodes.get(j).niche, skin.images.get("facility"))); + DataArrays.FacilityNodes.get(j).cycicCircle.image.setVisible(true); + DataArrays.FacilityNodes.get(j).cycicCircle.setOpacity(0); + } + } + } + } + + } + /** * Initiates the Pane and GridPane. */ private void init(){ - Resources1 resource = new Resources1(); - File file = new File(resource.getCurrentPath()); - String path = "/" + file.getParent(); - try { - defaultJsonReader(path); - log.info("Meta data loaded for default archetypes. If you wish to add others, please use the DISCOVER ARCHETYPES button. Thanks!"); - } catch (IOException e1) { - log.warn("Could not read default meta data. Please use DISCOVER ARCHETYPES button. Thanks!"); + + setCloseable(false); + enableDragging(false); + DataArrays.cycicInitLoader(); + + final ContextMenu paneMenu = new ContextMenu(); + MenuItem linkColor = new MenuItem("Change Link Color..."); + linkColor.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + updateLinkColor(); + } + }); + MenuItem bgColor = new MenuItem("Change Background Color..."); + bgColor.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + updateBgColor(); + } + }); + + Menu skinMenu = new Menu("Change skin"); + MenuItem defSkin = new MenuItem("Default Skin"); + defSkin.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + currentSkin = "Default Skin"; + setSkin(); + } + }); + skinMenu.getItems().add(defSkin); + for(int i = 0; i < DataArrays.visualizationSkins.size(); i++){ + final String skinName = DataArrays.visualizationSkins.get(i).name; + if (skinName.equals("DSARR")) { + currentSkin = skinName; + } + MenuItem item = new MenuItem(skinName); + item.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + currentSkin = skinName; + setSkin(); + } + }); + skinMenu.getItems().add(item); } + + + MenuItem imageExport = new MenuItem("Save fuel cycle diagram"); + imageExport.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + export(); + } + }); + + paneMenu.getItems().addAll(linkColor,bgColor,skinMenu,new SeparatorMenuItem(), imageExport); + + pane.setOnMouseClicked(new EventHandler(){ + public void handle(MouseEvent e){ + if(e.getButton().equals(MouseButton.SECONDARY)){ + paneMenu.show(pane,e.getScreenX(),e.getScreenY()); + } + } + }); pane.setOnDragOver(new EventHandler (){ public void handle(DragEvent event){ - event.acceptTransferModes(TransferMode.ANY); + event.acceptTransferModes(TransferMode.COPY); } }); pane.setOnDragDropped(new EventHandler(){ @@ -212,24 +338,26 @@ public void handle(DragEvent event){ if(DataArrays.simFacilities.get(i).facilityName.equalsIgnoreCase(facility.facilityType)){ facility.facilityStructure = DataArrays.simFacilities.get(i).facStruct; facility.niche = DataArrays.simFacilities.get(i).niche; + facility.doc = DataArrays.simFacilities.get(i).doc; facility.archetype = DataArrays.simFacilities.get(i).facilityArch; } } event.consume(); facility.name = ""; + facility.facLifetime = ""; facility.cycicCircle = CycicCircles.addNode((String)facility.name, facility); facility.cycicCircle.setCenterX(event.getX()); facility.cycicCircle.setCenterY(event.getY()); - facility.cycicCircle.text.setLayoutX(event.getX()-facility.cycicCircle.getRadius()*0.7); - facility.cycicCircle.text.setLayoutY(event.getY()-facility.cycicCircle.getRadius()*0.6); - facility.cycicCircle.menu.setLayoutX(event.getX()); - facility.cycicCircle.menu.setLayoutY(event.getY()); + VisFunctions.placeTextOnCircle(facility.cycicCircle, "middle"); + for(int i = 0; i < DataArrays.visualizationSkins.size(); i++){ - if(DataArrays.visualizationSkins.get(i).name.equalsIgnoreCase(skins.getValue())){ - facility.cycicCircle.image.setImage(DataArrays.visualizationSkins.get(i).images.get(facility.niche)); + if(DataArrays.visualizationSkins.get(i).name.equalsIgnoreCase(currentSkin)){ + facility.cycicCircle.image.setImage(DataArrays.visualizationSkins.get(i).images.getOrDefault(facility.niche,DataArrays.visualizationSkins.get(i).images.get("facility"))); facility.cycicCircle.image.setVisible(true); facility.cycicCircle.setOpacity(0); + facility.cycicCircle.setRadius(DataArrays.visualizationSkins.get(i).radius); + VisFunctions.placeTextOnCircle(facility.cycicCircle, DataArrays.visualizationSkins.get(i).textPlacement); } } facility.cycicCircle.image.setLayoutX(facility.cycicCircle.getCenterX()-60); @@ -237,6 +365,8 @@ public void handle(DragEvent event){ facility.sorterCircle = SorterCircles.addNode((String)facility.name, facility, facility); FormBuilderFunctions.formArrayBuilder(facility.facilityStructure, facility.facilityData); + } else { + event.consume(); } } }); @@ -249,10 +379,11 @@ public void handle(MouseEvent e){ VBox cycicBox = new VBox(); cycicBox.autosize(); - Cycic.pane.autosize(); - Cycic.pane.setId("cycicPane"); - Cycic.pane.setPrefSize(1000, 600); - Cycic.pane.setStyle("-fx-background-color: white;"); + + pane.autosize(); + pane.setId("cycicPane"); + pane.setPrefSize(1000, 600); + pane.setStyle("-fx-background-color: white;"); // Temp Toolbar // final GridPane grid = new GridPane(); @@ -291,17 +422,41 @@ public void handle(ActionEvent event){ if (structureCB.getValue() == null){ return; } - facilityNode tempNode = new facilityNode(); - tempNode.facilityType = structureCB.getValue(); + facilityNode facility = new facilityNode(); + facility.facilityType = structureCB.getValue(); + facility.facilityType.trim(); + addArcheToBar(facility.facilityType); for (int i = 0; i < DataArrays.simFacilities.size(); i++){ - if (DataArrays.simFacilities.get(i).facilityName == structureCB.getValue()){ - tempNode.facilityStructure = DataArrays.simFacilities.get(i).facStruct; - } + if(DataArrays.simFacilities.get(i).facilityName.equalsIgnoreCase(facility.facilityType)){ + facility.facilityStructure = DataArrays.simFacilities.get(i).facStruct; + facility.niche = DataArrays.simFacilities.get(i).niche; + facility.doc = DataArrays.simFacilities.get(i).doc; + facility.archetype = DataArrays.simFacilities.get(i).facilityArch; + } } - tempNode.name = facNameField.getText(); - tempNode.cycicCircle = CycicCircles.addNode((String)tempNode.name, tempNode); - tempNode.sorterCircle = SorterCircles.addNode((String)tempNode.name, tempNode, tempNode); - FormBuilderFunctions.formArrayBuilder(tempNode.facilityStructure, tempNode.facilityData); + event.consume(); + facility.name = facNameField.getText(); + facility.facLifetime = ""; + facility.cycicCircle = CycicCircles.addNode((String)facility.name, facility); + facility.cycicCircle.setCenterX(80); + facility.cycicCircle.setCenterY(80); + VisFunctions.placeTextOnCircle(facility.cycicCircle, "middle"); + + + for(int i = 0; i < DataArrays.visualizationSkins.size(); i++){ + if(DataArrays.visualizationSkins.get(i).name.equalsIgnoreCase(currentSkin)){ + facility.cycicCircle.image.setImage(DataArrays.visualizationSkins.get(i).images.getOrDefault(facility.niche,DataArrays.visualizationSkins.get(i).images.get("facility"))); + facility.cycicCircle.image.setVisible(true); + facility.cycicCircle.setOpacity(0); + facility.cycicCircle.setRadius(DataArrays.visualizationSkins.get(i).radius); + VisFunctions.placeTextOnCircle(facility.cycicCircle, DataArrays.visualizationSkins.get(i).textPlacement); + } + } + facility.cycicCircle.image.setLayoutX(facility.cycicCircle.getCenterX()-60); + facility.cycicCircle.image.setLayoutY(facility.cycicCircle.getCenterY()-60); + + facility.sorterCircle = SorterCircles.addNode((String)facility.name, facility, facility); + FormBuilderFunctions.formArrayBuilder(facility.facilityStructure, facility.facilityData); } }); grid.add(submit1, 4, 0); @@ -310,59 +465,16 @@ public void handle(ActionEvent event){ scroll.setMinHeight(120); scroll.setContent(nodesPane); - skins.getItems().add("Default Skin"); - skins.setValue("Default Skin"); - DataArrays.visualizationSkins.add(XMLReader.loadSkin(path)); - for(int i = 0; i < DataArrays.visualizationSkins.size(); i++){ - skins.getItems().add(DataArrays.visualizationSkins.get(i).name); - } - skins.setOnAction(new EventHandler(){ - public void handle(ActionEvent e){ - if(skins.getValue().equalsIgnoreCase("Default Skin")){ - for(int j = 0; j < DataArrays.FacilityNodes.size(); j++){ - DataArrays.FacilityNodes.get(j).cycicCircle.image.setVisible(false); - DataArrays.FacilityNodes.get(j).cycicCircle.setOpacity(100); - } - } else { - for(int i = 0; i < DataArrays.visualizationSkins.size(); i++){ - skinSet skin = DataArrays.visualizationSkins.get(i); - if(skin.name.equalsIgnoreCase(skins.getValue())){ - for(int j = 0; j < DataArrays.FacilityNodes.size(); j++){ - DataArrays.FacilityNodes.get(j).cycicCircle.image.setImage(skin.images.getOrDefault(DataArrays.FacilityNodes.get(j).niche, skin.images.get("facility"))); - DataArrays.FacilityNodes.get(j).cycicCircle.image.setVisible(true); - DataArrays.FacilityNodes.get(j).cycicCircle.setOpacity(0); - } - } - } - } - } - }); - grid.add(new Label("Node Skins"){ - { - setTooltip(new Tooltip("Use this drop down to select the skin set to use for your nodes.")); - setFont(new Font("Time", 14)); - } - }, 0, 1); - grid.add(skins, 1, 1); - - Button imageButton = new Button("Save fuel cycle diagram"); - imageButton.setOnAction(new EventHandler(){ - public void handle(ActionEvent e){ - export(); - } - }); - grid.add(imageButton, 2, 1); - opSwitch.getToggles().addAll(localToggle, remoteToggle); - try { - Process readproc = Runtime.getRuntime().exec("cyclus -V"); - BufferedReader schema = new BufferedReader(new InputStreamReader(readproc.getInputStream())); - localToggle.setSelected(true); - } catch (RuntimeException | IOException e) { - localToggle.setSelected(false); - remoteToggle.setSelected(true); - }; - grid.add(localToggle, 7, 0); - grid.add(remoteToggle, 8, 0); +// opSwitch.getToggles().clear(); +// opSwitch.getToggles().addAll(localToggle, remoteToggle); +// try { +// Process readproc = Runtime.getRuntime().exec("cyclus -V"); +// new BufferedReader(new InputStreamReader(readproc.getInputStream())); +// localToggle.setSelected(true); +// } catch (RuntimeException | IOException e) { +// localToggle.setSelected(false); +// remoteToggle.setSelected(true); +// }; cycicBox.getChildren().addAll(grid, scroll, pane); @@ -380,91 +492,13 @@ public void handle(ActionEvent e){ + "-fx-border-color: black"); } }; - //ScrollPane commodScroll = new ScrollPane(); - //commodScroll.setContent(commodBox); + sideView.getChildren().addAll(simDetailBox, archetypeGrid, commodBox); mainView.getChildren().addAll(sideView, cycicBox); setContent(mainView); } - /** - * - */ - public void retrieveSchema(String rawMetadata) { - // rawMetadata is a JSON string. - Reader metaReader = new StringReader(rawMetadata); - JsonReader metaJsonReader = Json.createReader(metaReader); - JsonObject metadata = metaJsonReader.readObject(); - metaJsonReader.close(); - JsonObject schemas = metadata.getJsonObject("schema"); - JsonObject annotations = metadata.getJsonObject("annotations"); - - String string; - DataArrays.simFacilities.clear(); - DataArrays.simRegions.clear(); - DataArrays.simInstitutions.clear(); - for(javax.json.JsonString specVal : metadata.getJsonArray("specs").getValuesAs(JsonString.class)){ - String spec = specVal.getString(); - boolean test = true; - for(int j = 0; j < XMLReader.blackList.size(); j++){ - if(spec.equalsIgnoreCase(XMLReader.blackList.get(j))){ - test = false; - } - } - if(test == false){ - continue; - } - String schema = schemas.getString(spec); - String pattern1 = ""; - Pattern p = Pattern.compile(pattern1, Pattern.DOTALL); - schema = p.matcher(schema).replaceAll(""); - if(schema.length() > 12){ - if(!schema.substring(0, 12).equals("")){ - schema = "" + schema + ""; - } - } - JsonObject anno = annotations.getJsonObject(spec); - switch(anno.getString("entity")){ - case "facility": - facilityStructure node = new facilityStructure(); - node.facAnnotations = anno.toString(); - node.facilityArch = spec; - node.niche = anno.getString("niche", "facility"); - node.facStruct = XMLReader.annotationReader(anno.toString(), - XMLReader.readSchema(schema)); - node.facilityName = spec.replace(":", " "); - DataArrays.simFacilities.add(node); - log.info("Adding archetype "+spec); - break; - case "region": - log.info("Adding archetype "+spec); - regionStructure rNode = new regionStructure(); - rNode.regionAnnotations = anno.toString(); - rNode.regionArch = spec; - rNode.regionStruct = XMLReader.annotationReader(anno.toString(), - XMLReader.readSchema(schema)); - rNode.regionName = spec.replace(":", " "); - DataArrays.simRegions.add(rNode); - break; - case "institution": - log.info("Adding archetype "+spec); - institutionStructure iNode = new institutionStructure(); - iNode.institArch = spec; - iNode.institAnnotations = anno.toString(); - iNode.institStruct = XMLReader.annotationReader(anno.toString(), - XMLReader.readSchema(schema)); - iNode.institName = spec.replace(":", " "); - DataArrays.simInstitutions.add(iNode); - break; - default: - log.error(spec+" is not of the 'facility', 'region' or 'institution' type. " - + "Please check the entity value in the archetype annotation."); - break; - }; - } - log.info("Schema discovery complete"); - } /** * @@ -475,21 +509,22 @@ public void retrieveSchema(String rawMetadata) { public void buildDnDCircle(FacilityCircle circle, int i, String name){ circle.setRadius(40); circle.setStroke(Color.BLACK); - circle.setFill(Color.web("#CF5300")); + circle.rgbColor=VisFunctions.stringToColor(name); + circle.setFill(VisFunctions.pastelize(Color.rgb(circle.rgbColor.get(0),circle.rgbColor.get(1),circle.rgbColor.get(2)))); circle.setCenterX(45+(i*90)); circle.setCenterY(50); - circle.text.setText(name); - circle.text.setWrapText(true); - circle.text.setMaxWidth(60); - circle.text.setLayoutX(circle.getCenterX()-circle.getRadius()*0.7); - circle.text.setLayoutY(circle.getCenterY()-circle.getRadius()*0.6); - circle.text.setTextAlignment(TextAlignment.CENTER); - circle.text.setMouseTransparent(true); + circle.text.setText(name.split(" ")[2] + " (" + name.split(" ")[1] + ")"); + VisFunctions.placeTextOnCircle(circle, "middle"); circle.setOnDragDetected(new EventHandler(){ public void handle(MouseEvent e){ Dragboard db = circle.startDragAndDrop(TransferMode.COPY); ClipboardContent content = new ClipboardContent(); - content.put(DnD.VALUE_FORMAT, circle.text.getText()); + content.put(DnD.VALUE_FORMAT, name); + SnapshotParameters snapParams = new SnapshotParameters(); + snapParams.setFill(Color.TRANSPARENT); + + content.putImage(circle.snapshot(snapParams, null)); + db.setContent(content); e.consume(); } @@ -527,7 +562,22 @@ public void changed(ObservableValue observable, String oldValu removeCommod.setGraphic(GlyphRegistry.get(AwesomeIcon.TRASH_ALT, "10px")); removeCommod.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ + String commod = Cycic.workingScenario.CommoditiesList.get(index).name.getText(); Cycic.workingScenario.CommoditiesList.remove(index); + for(facilityNode facility: DataArrays.FacilityNodes){ + for(int i =0; i < facility.cycicCircle.incommods.size(); i++){ + if(facility.cycicCircle.incommods.get(i) == commod){ + facility.cycicCircle.incommods.remove(i); + } + } + for(int i =0; i < facility.cycicCircle.outcommods.size(); i++){ + if(facility.cycicCircle.outcommods.get(i) == commod){ + facility.cycicCircle.outcommods.remove(i); + } + } + commodListRm(facility.facilityStructure, facility.facilityData, commod); + } + VisFunctions.redrawPane(); buildCommodPane(); } }); @@ -555,15 +605,12 @@ public void changed(ObservableValue observable, String oldValu } HashMap months = new HashMap(); - ArrayList monthList = new ArrayList(); + static ArrayList monthList = new ArrayList(); /** * Quick hack to convert months into their integer values. * i.e. January = 0, Feb = 1, etc... */ public void months(){ - - Cycic.workingScenario.simulationData.startMonth = "0"; - monthList.add("January"); monthList.add("February"); monthList.add("March"); @@ -590,12 +637,15 @@ public void months(){ months.put("November", "11"); months.put("December", "12"); } + + /** + * + */ public void details(){ Label simDets = new Label("Simulation Details"); simDets.setTooltip(new Tooltip("The top level details of the simulation.")); simDets.setFont(new Font("Times", 16)); - simInfo.add(simDets, 0, 0); - TextField duration = VisFunctions.numberField(); + simInfo.add(simDets, 0, 0, 2, 1); duration.setMaxWidth(150); duration.setPromptText("Length of Simulation"); duration.setText(Cycic.workingScenario.simulationData.duration); @@ -605,26 +655,23 @@ public void changed(ObservableValue observable, String oldValu Cycic.workingScenario.simulationData.duration = newValue; } }); - simInfo.add(new Label("Duration (Months)"), 0, 1); - simInfo.add(duration, 1, 1); + simInfo.add(new Label("Duration (Months)"), 0, 1, 2, 1); + simInfo.add(duration, 2, 1); - - final ComboBox startMonth = new ComboBox(); - startMonth.setValue(months.get(Cycic.workingScenario.simulationData.startMonth)); for(int i = 0; i < 12; i++ ){ startMonth.getItems().add(monthList.get(i)); } Cycic.workingScenario.simulationData.startMonth = "1"; - startMonth.setValue(monthList.get(Integer.parseInt(Cycic.workingScenario.simulationData.startMonth))); + startMonth.setValue(monthList.get(Integer.parseInt(Cycic.workingScenario.simulationData.startMonth)-1)); startMonth.valueProperty().addListener(new ChangeListener(){ public void changed(ObservableValue observable, String oldValue, String newValue){ Cycic.workingScenario.simulationData.startMonth = months.get(newValue); } }); startMonth.setPromptText("Select Month"); - simInfo.add(new Label("Start Month"), 0, 2); - simInfo.add(startMonth, 1, 2); - TextField startYear = VisFunctions.numberField(); + simInfo.add(new Label("Start Month"), 0, 2, 2, 1); + simInfo.add(startMonth, 2, 2); + startYear.setText(Cycic.workingScenario.simulationData.startYear); Cycic.workingScenario.simulationData.startYear = "0"; startYear.textProperty().addListener(new ChangeListener(){ @@ -634,86 +681,194 @@ public void changed(ObservableValue observable, String oldValu }); startYear.setPromptText("Starting Year"); startYear.setMaxWidth(150); - simInfo.add(new Label("Start Year"), 0, 3); - simInfo.add(startYear, 1, 3); + simInfo.add(new Label("Start Year"), 0, 3, 2, 1); + simInfo.add(startYear, 2, 3); - TextArea description = new TextArea(); - description.setMaxSize(250, 50); - description.setWrapText(true); - description.textProperty().addListener(new ChangeListener(){ + decay.getItems().addAll("manual", "never"); + decay.setValue("Never"); + Cycic.workingScenario.simulationData.decay = "never"; + decay.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + Cycic.workingScenario.simulationData.decay = decay.getValue(); + } + }); + simInfo.add(new Label("Decay"), 0, 4); + simInfo.add(decay, 2, 4); + + simHandle.setPromptText("Optional Simulation Name"); + simHandle.textProperty().addListener(new ChangeListener(){ public void changed(ObservableValue observable, String oldValue, String newValue){ - Cycic.workingScenario.simulationData.description = newValue; + Cycic.workingScenario.simulationData.simHandle = newValue; } }); - simInfo.add(new Label("Description"), 0, 4); - simInfo.add(description, 1, 4); + simInfo.add(new Label("Simulation Handle"), 0, 5, 2, 1); + simInfo.add(simHandle, 2, 5); - TextArea notes = new TextArea(); - notes.setMaxSize(250, 50); - notes.setWrapText(true); - notes.textProperty().addListener(new ChangeListener(){ + description.setMaxSize(250, 50); + description.setWrapText(true); + description.textProperty().addListener(new ChangeListener(){ public void changed(ObservableValue observable, String oldValue, String newValue){ Cycic.workingScenario.simulationData.notes = newValue; } }); - simInfo.add(new Label("Notes"), 0, 5); - simInfo.add(notes, 1, 5); + simInfo.add(new Label("Description"), 0, 6, 2, 1); + simInfo.add(description, 2, 6); // Prints the Cyclus input associated with this simulator. - Button output = new Button("Generate Cyclus Input"); + Button output = new Button("Generate"); output.setOnAction(new EventHandler(){ public void handle(ActionEvent event){ - if(OutPut.inputTest()){ - FileChooser fileChooser = new FileChooser(); - //Set extension filter - FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("XML files (*.xml)", "*.xml"); - fileChooser.getExtensionFilters().add(extFilter); - fileChooser.setTitle("Please save as Cyclus input file."); - fileChooser.setInitialFileName("*.xml"); - //Show save file dialog - File file = fileChooser.showSaveDialog(window); - OutPut.output(file); - } + OutPut.CheckInjection(); + if(OutPut.inputTest()){ + FileChooser fileChooser = new FileChooser(); + //Set extension filter + FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("XML files (*.xml)", "*.xml"); + fileChooser.getExtensionFilters().add(extFilter); + fileChooser.setTitle("Save Cyclus input file"); + fileChooser.setInitialFileName("*.xml"); + //Show save file dialog + File file = fileChooser.showSaveDialog(window); + OutPut.output(file); + } + } + }); + simInfo.add(output, 0, 7, 2, 1); + + Button load = new Button("Load"); + load.setOnAction(new EventHandler(){ + public void handle(ActionEvent e){ + FileChooser fileChooser = new FileChooser(); + //Set extension filter + FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("XML files (*.xml)", "*.xml"); + fileChooser.getExtensionFilters().add(extFilter); + fileChooser.setTitle("Select input file to load."); + fileChooser.setInitialFileName("*.xml"); + //Show save file dialog + File file = fileChooser.showOpenDialog(window); + OutPut.loadFile(file); } }); - simInfo.add(output, 0, 6); + simInfo.add(load, 2, 7); - Button runCyclus = new Button("Run Cyclus!"); + Button runCyclus = new Button("Execute"); + simInfo.add(runCyclus, 0, 8, 1, 1); + + + final List serversList = FXCollections.observableArrayList(Preferences.getInstance().servers()); + serversList.add(0, "-- add new --"); + ComboBox serverBox = new ComboBox<>(); + serverBox.getItems().addAll(serversList); + serverBox.setVisibleRowCount(Math.min(6, serverBox.getItems().size())); + + int currentIndex = Preferences.getInstance().getCurrentServerIndex()+1; + currentServer = serversList.get(currentIndex); + + serverBox.setPromptText("server"); + serverBox.setEditable(true); + serverBox.getSelectionModel().select(currentIndex); + + serverBox.valueProperty().addListener( + (ov, from, to)-> { + int idx = serverBox.getSelectionModel().getSelectedIndex(); + if (idx-1 != Preferences.getInstance().getCurrentServerIndex()) { + Preferences.getInstance().setCurrentServerIndex(idx-1); + } else if (Preferences.LOCAL_SERVER.equals(from)) { + serverBox.getSelectionModel().select(idx); + } else if ("".equals(to)) { + serverBox.getItems().remove(from); + Preferences.getInstance().servers().remove(from); + + } else if (serverBox.getItems().indexOf(to) == -1) { + serverBox.getItems().add(to); + Preferences.getInstance().servers().add(to); + Preferences.getInstance().setCurrentServerIndex(serverBox.getItems().size()-2); + serverBox.setVisibleRowCount(Math.min(6, serverBox.getItems().size())); + } + currentServer = serverBox.getValue(); + }); + + Label serverLabel = new Label("Server:"); + GridPane.setHalignment(serverLabel, HPos.RIGHT); + simInfo.add(serverLabel, 1, 8, 1, 1); + simInfo.add(serverBox, 2, 8); + runCyclus.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ - if(!OutPut.inputTest()){ - log.info("Cyclus Input Not Well Formed!"); - return; // safety dance + OutPut.CheckInjection(); + if(!OutPut.inputTest()){ + log.error("Cyclus Input Not Well Formed!"); + return; // safety dance + } + String server = serverBox.getValue(); + if (Preferences.LOCAL_SERVER.equals(server)) { + // local execution + String tempHash = Integer.toString(OutPut.xmlStringGen().hashCode()); + String prefix = "cycic" + tempHash; + String infile = prefix + ".xml"; + String outfile = prefix + ".sqlite"; + try { + File temp = new File(infile); + log.trace("Writing file " + temp.getName()); + log.trace("lines:\n" + OutPut.xmlStringGen()); + OutPut.output(temp); + // BufferedWriter output = new BufferedWriter(new FileWriter(temp)); + // output.write(OutPut.xmlStringGen()); + // output.close(); + Process p = Runtime.getRuntime().exec(Preferences.getInstance().getCyclusPath()+" -o " + outfile + " " + infile); + p.waitFor(); + String line = null; + BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); + while ((line = input.readLine()) != null) { + log.info(line); + } + input.close(); + input = new BufferedReader(new InputStreamReader(p.getErrorStream())); + while ((line = input.readLine()) != null) { + log.warn(line); + } + input.close(); + log.info("Cyclus run complete"); + } catch (Exception e1) { + // e1.printStackTrace(); + log.error(e1.getMessage()); } - if (localToggle.isSelected()) { - // local execution - String tempHash = Integer.toString(OutPut.xmlStringGen().hashCode()); - String cycicTemp = "cycic"+tempHash; - try { - File temp = File.createTempFile(cycicTemp, ".xml"); - FileWriter fileOutput = new FileWriter(temp); - BufferedWriter buffOut = new BufferedWriter(fileOutput); - Process p = Runtime.getRuntime().exec("cyclus -o "+cycicTemp +".sqlite "+cycicTemp); - p.waitFor(); - String line = null; - BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); - while ((line = input.readLine()) != null) { - log.info(line); - } - input.close(); - log.info("Cyclus run complete"); - } catch (Exception e1) { - e1.printStackTrace(); - } - } else { - // remote execution - String cycicXml = OutPut.xmlStringGen(); - CyclistController._cyclusService.submit(cycicXml); - } + } else { + // remote execution + String cycicXml = OutPut.xmlStringGen(); + CyclistController._cyclusService.submit(cycicXml, server); + } } - });; - simInfo.add(runCyclus, 1,6); + });; + + } + + + public void addArcheToBar(String archeType){ + + for(int i = 0; i < DataArrays.simFacilities.size(); i++){ + if(DataArrays.simFacilities.get(i).facilityName.equalsIgnoreCase(archeType)){ + if(DataArrays.simFacilities.get(i).loaded == true){ + return; + } + facilityStructure test = DataArrays.simFacilities.get(i); + try { + test.loaded = true; + FacilityCircle circle = new FacilityCircle(); + int pos = 0; + for(int k = 0; k < DataArrays.simFacilities.size(); k++){ + if(DataArrays.simFacilities.get(k).loaded == true){ + pos+=1; + } + } + buildDnDCircle(circle, pos-1, test.facilityName); + nodesPane.getChildren().addAll(circle, circle.text); + } catch (Exception eq) { + + } + } + } + } public void createArchetypeBar(GridPane grid){ @@ -731,30 +886,7 @@ public void handle(MouseEvent e){ }); archetypes.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ - for(int i = 0; i < DataArrays.simFacilities.size(); i++){ - if(DataArrays.simFacilities.get(i).facilityName.equalsIgnoreCase(archetypes.getValue())){ - if(DataArrays.simFacilities.get(i).loaded == true){ - return; - } - facilityStructure test = DataArrays.simFacilities.get(i); - String string; - StringBuilder sb = new StringBuilder(); - try { - test.loaded = true; - FacilityCircle circle = new FacilityCircle(); - int pos = 0; - for(int k = 0; k < DataArrays.simFacilities.size(); k++){ - if(DataArrays.simFacilities.get(k).loaded == true){ - pos+=1; - } - } - buildDnDCircle(circle, pos-1, test.facilityName); - nodesPane.getChildren().addAll(circle,circle.text); - } catch (Exception eq) { - - } - } - } + addArcheToBar(archetypes.getValue()); } }); @@ -762,34 +894,39 @@ public void handle(ActionEvent e){ cyclusDashM.setTooltip(new Tooltip("Use this button to search for all local Cyclus modules.")); cyclusDashM.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ - if (localToggle.isSelected()) { + if (Preferences.LOCAL_SERVER.equals(currentServer)) { // Local metadata collection try { - Process readproc = Runtime.getRuntime().exec("cyclus -m"); + Process readproc = Runtime.getRuntime().exec(Preferences.getInstance().getCyclusPath()+" -m"); BufferedReader metaBuf = new BufferedReader(new InputStreamReader(readproc.getInputStream())); String line=null; String metadata = new String(); while ((line = metaBuf.readLine()) != null) {metadata += line;} metaBuf.close(); - retrieveSchema(metadata); + DataArrays.retrieveSchema(metadata); } catch (IOException ex) { - // TODO Auto-generated catch block - ex.printStackTrace(); + log.error(ex.getMessage()); +// ex.printStackTrace(); } } else { // Remote metadata collection - CyclistController._cyclusService.submitCmd("cyclus", "-m"); - _remoteDashA = CyclistController._cyclusService.latestJob(); - _remoteDashA.statusProperty() - .addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, - Status oldValue, Status newValue) { - if (newValue == Status.READY) { - retrieveSchema(_remoteDashA.getStdout()); - } - } - }); + _remoteDashA = CyclistController._cyclusService.submitCmdToRemote(currentServer, "cyclus", "-m"); +// _remoteDashA = CyclistController._cyclusService.latestJob(); + CyclusJob job = _remoteDashA; + if (_remoteDashA.getStatus() == Status.FAILED) { + // TODO: an error msg was already sent to the console. Do we want to pop up an error msg? + } else { + _remoteDashA.statusProperty() + .addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, + Status oldValue, Status newValue) { + if (newValue == Status.READY) { + DataArrays.retrieveSchema(_remoteDashA.getStdout()); + } + } + }); + } } } }); @@ -813,21 +950,34 @@ private void export() { log.error("Error writing image to file: "+e.getMessage()); } } else { + log.error("File did not generate correctly."); System.out.println("File did not generate correctly."); } } - private void defaultJsonReader(String path) throws IOException{ - BufferedReader reader = new BufferedReader( new FileReader (path + "/default-metadata.json")); - String line = null; - StringBuilder stringBuilder = new StringBuilder(); - String ls = System.getProperty("line.separator"); - - while( ( line = reader.readLine() ) != null ) { - stringBuilder.append( line ); - stringBuilder.append( ls ); - } - reader.close(); - retrieveSchema(stringBuilder.toString()); + public static void commodListRm(ArrayList facArray, ArrayList dataArray, String commod){ + if(facArray.get(0) instanceof ArrayList){ + for(int i = 0; i < facArray.size(); i++){ + commodListRm((ArrayList) facArray.get(i), (ArrayList) dataArray.get(i), commod); + } + } else if(facArray.get(1) instanceof ArrayList){ + for(int i = 0; i < dataArray.size(); i++){ + commodListRm((ArrayList) facArray.get(1), (ArrayList) dataArray.get(i), commod); + } + } else { + switch ((String) facArray.get(2).toString().toLowerCase()){ + case "incommodity": + if(dataArray.get(0).toString().equalsIgnoreCase(commod)){ + dataArray.set(0, ""); + } + break; + case "outcommodity": + if(dataArray.get(0).toString().equalsIgnoreCase(commod)){ + dataArray.set(0, ""); + } + break; + } + } } -} \ No newline at end of file + +} diff --git a/cyclist/src/edu/utexas/cycic/CycicCircles.java b/cyclist/src/edu/utexas/cycic/CycicCircles.java index 448407cf..bbd1f12c 100644 --- a/cyclist/src/edu/utexas/cycic/CycicCircles.java +++ b/cyclist/src/edu/utexas/cycic/CycicCircles.java @@ -1,38 +1,27 @@ package edu.utexas.cycic; -import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; import edu.utah.sci.cyclist.core.controller.CyclistController; -import edu.utah.sci.cyclist.core.event.dnd.DnD; -import edu.utah.sci.cyclist.core.event.notification.EventBus; -import edu.utah.sci.cyclist.core.presenter.WorkspacePresenter; -import edu.utah.sci.cyclist.core.tools.Tool; -import edu.utah.sci.cyclist.core.ui.MainScreen; -import edu.utah.sci.cyclist.core.ui.View; -import edu.utah.sci.cyclist.core.ui.components.ViewBase; -import edu.utah.sci.cyclist.core.ui.views.Workspace; import edu.utexas.cycic.tools.FormBuilderTool; -import edu.utexas.cycic.tools.FormBuilderToolFactory; +import edu.utexas.cycic.FormBuilder; import javafx.event.ActionEvent; import javafx.event.EventHandler; -import javafx.geometry.VPos; -import javafx.scene.control.CustomMenuItem; -import javafx.scene.control.Label; +import javafx.scene.control.Alert; +import javafx.scene.control.ChoiceDialog; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; -import javafx.scene.control.Tooltip; -import javafx.scene.image.Image; -import javafx.scene.input.ClipboardContent; -import javafx.scene.input.Dragboard; +import javafx.scene.control.TextInputDialog; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; -import javafx.scene.input.TransferMode; import javafx.scene.paint.Color; -import javafx.scene.shape.Circle; +import javafx.scene.shape.Line; import javafx.scene.shape.Shape; import javafx.scene.text.Font; -import javafx.scene.text.Text; import javafx.scene.text.TextAlignment; +import javafx.stage.Window; /** * The class used to build a new Prototype Facility node. @@ -45,6 +34,10 @@ public class CycicCircles{ protected static double mousex; protected static double x; protected static double y; + protected static int defRadius = 45; + protected static int mouseOverRadius = 52; + + static Window window; /** * Function to build a prototype facility node. This node will contain @@ -55,7 +48,7 @@ public class CycicCircles{ static FacilityCircle addNode(String name, final facilityNode parent) { final FacilityCircle circle = parent.cycicCircle; - circle.setRadius(45); + circle.setRadius(defRadius); circle.setCenterX(60); circle.setCenterY(60); circle.type = "Parent"; @@ -65,27 +58,15 @@ static FacilityCircle addNode(String name, final facilityNode parent) { circle.text.setText(name); circle.tooltip.setText(name); circle.text.setTooltip(circle.tooltip); - circle.text.setWrapText(true); - circle.text.setLayoutX(circle.getCenterX()-circle.getRadius()*0.6); - circle.text.setLayoutY(circle.getCenterY()-circle.getRadius()*0.6); - circle.text.setTextAlignment(TextAlignment.CENTER); - circle.text.setMaxWidth(circle.getRadius()*1.4); - circle.text.setMouseTransparent(true); - circle.text.setFont(new Font("ComicSans", 14)); - circle.text.setMaxHeight(circle.getRadius()*1.2); - - - + // Setting the circle color // circle.setStroke(Color.BLACK); circle.rgbColor=VisFunctions.stringToColor(parent.facilityType); - circle.setFill(Color.rgb(circle.rgbColor.get(0), circle.rgbColor.get(1), circle.rgbColor.get(2), 0.9)); - // Setting font color for visibility // - if(VisFunctions.colorTest(circle.rgbColor) == true){ - circle.text.setTextFill(Color.BLACK); - }else{ - circle.text.setTextFill(Color.WHITE); - } + circle.setFill(VisFunctions.pastelize(Color.rgb(circle.rgbColor.get(0), circle.rgbColor.get(1), circle.rgbColor.get(2), 0.9))); + + // Place text after color to get font color right // + VisFunctions.placeTextOnCircle(circle, "bottom"); + for(int i = 0; i < Cycic.pane.getChildren().size(); i++){ if(Cycic.pane.getChildren().get(i).getId() == "cycicNode"){ ((Shape) Cycic.pane.getChildren().get(i)).setStroke(Color.BLACK); @@ -97,55 +78,74 @@ static FacilityCircle addNode(String name, final facilityNode parent) { circle.setStroke(Color.DARKGRAY); // Adding the menu and it's menu items. - final Menu menu1 = new Menu("Options"); - MenuItem facForm = new MenuItem("Facility Form"); + MenuItem facForm = new MenuItem("Configure"); EventHandler circleAction = new EventHandler() { @Override public void handle(ActionEvent event) { try{ CyclistController._presenter.addTool(new FormBuilderTool()); - circle.menu.setVisible(false); } catch (Exception e) { e.printStackTrace(); } } }; facForm.setOnAction(circleAction); - + + MenuItem helpDialog = new MenuItem("Facility Documentation"); + helpDialog.setOnAction(new EventHandler() { + public void handle(ActionEvent e){ + FormBuilder.showHelpDialog(parent.doc); + } + }); + circle.image.setLayoutX(circle.getCenterX()-60); + circle.image.setLayoutY(circle.getCenterY()-60); MenuItem delete = new MenuItem("Delete"); delete.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ deleteNode(parent); - circle.menu.setVisible(false); } }); - final Menu clonesList = new Menu("Children"); - - /*CustomMenuItem cloneNode = new CustomMenuItem(new Label("Add Child")); - cloneNode.setHideOnClick(false); - cloneNode.setOnAction(new EventHandler(){ + MenuItem changeNiche = new MenuItem("Change Niche"); + changeNiche.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ - Clones.addClone("", parent, parent.cycicCircle.childrenShow); + /** TODO CHANGE NICHE OF CIRCLE */ + Object[] skinList = null; + for(int i = 0; i < CycicScenarios.workingCycicScenario.visualizationSkins.size(); i++){ + if(CycicScenarios.workingCycicScenario.visualizationSkins.get(i).name.equals(Cycic.currentSkin)){ + skinSet skin = CycicScenarios.workingCycicScenario.visualizationSkins.get(i); + skinList = skin.images.keySet().toArray(); + } + } + ChoiceDialog dg = new ChoiceDialog(circle.niche, skinList); + dg.setResizable(true); + dg.setContentText("New Niche: "); + Optional result = dg.showAndWait(); + if (result.isPresent()){ + parent.niche = result.get(); + for(int i = 0; i < DataArrays.visualizationSkins.size(); i++){ + if(DataArrays.visualizationSkins.get(i).name.equalsIgnoreCase(Cycic.currentSkin)){ + circle.image.setImage(DataArrays.visualizationSkins.get(i).images.getOrDefault(parent.niche,DataArrays.visualizationSkins.get(i).images.get("facility"))); + circle.image.setVisible(true); + circle.setOpacity(0); + circle.setRadius(DataArrays.visualizationSkins.get(i).radius); + VisFunctions.placeTextOnCircle(circle, DataArrays.visualizationSkins.get(i).textPlacement); + } + } + } } }); - clonesList.getItems().add(cloneNode);*/ - - circle.image.setLayoutX(circle.getCenterX()-60); - circle.image.setLayoutY(circle.getCenterY()-60); - - + MenuItem showImage = new MenuItem("Show Image"); showImage.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ circle.image.setVisible(true); circle.image.toBack(); circle.setOpacity(0); - circle.menu.setVisible(false); } }); @@ -153,15 +153,10 @@ public void handle(ActionEvent e){ hideImage.setOnAction(new EventHandler(){ public void handle(ActionEvent e){ circle.image.setVisible(false); - circle.setOpacity(100); - circle.menu.setVisible(false); } + circle.setOpacity(100); } }); - menu1.getItems().addAll(facForm, clonesList, delete, showImage, hideImage); - circle.menu.getMenus().add(menu1); - circle.menu.setLayoutX(circle.getCenterX()); - circle.menu.setLayoutY(circle.getCenterY()); - circle.menu.setVisible(false); + circle.menu.getItems().addAll(facForm, helpDialog, changeNiche, delete, showImage, hideImage); // Piece of test code for changing the look of the facility circles. //circle.image.setImage(new Image("reactor.png")); @@ -190,66 +185,72 @@ public void handle(MouseEvent event){ // To allow the facilityCircle to be moved through the pane and setting bounding regions. circle.onMouseDraggedProperty().set(new EventHandler(){ - @Override public void handle(MouseEvent event){ - circle.setCenterX(mousex+x); - circle.setCenterY(mousey+y); - - if(circle.getCenterX() <= Cycic.pane.getLayoutBounds().getMinX()+circle.getRadius()){ - circle.setCenterX(Cycic.pane.getLayoutBounds().getMinX()+circle.getRadius()); - } - if(circle.getCenterY() <= Cycic.pane.getLayoutBounds().getMinY()+circle.getRadius()){ - circle.setCenterY(Cycic.pane.getLayoutBounds().getMinY()+circle.getRadius()); - } - if(circle.getCenterY() >= Cycic.pane.getLayoutBounds().getMaxY()-circle.getRadius()){ - circle.setCenterY(Cycic.pane.getLayoutBounds().getMaxY()-circle.getRadius()); - } - if(circle.getCenterX() >= Cycic.pane.getLayoutBounds().getMaxX()-circle.getRadius()){ - circle.setCenterX(Cycic.pane.getLayoutBounds().getMaxX()-circle.getRadius()); - } - - circle.menu.setLayoutX(circle.getCenterX()); - circle.menu.setLayoutY(circle.getCenterY()); - - circle.image.setLayoutX(circle.getCenterX()-60); - circle.image.setLayoutY(circle.getCenterY()-50); - - circle.text.setLayoutX(circle.getCenterX()-circle.getRadius()*0.6); - circle.text.setLayoutY(circle.getCenterY()-circle.getRadius()*0.6); - - for(int i = 0; i < CycicScenarios.workingCycicScenario.Links.size(); i++){ - if(CycicScenarios.workingCycicScenario.Links.get(i).source == circle){ - CycicScenarios.workingCycicScenario.Links.get(i).line.setStartX(circle.getCenterX()); - CycicScenarios.workingCycicScenario.Links.get(i).line.setStartY(circle.getCenterY()); - CycicScenarios.workingCycicScenario.Links.get(i).line.updatePosition(); + Line line = new Line(); + if(event.isShiftDown() == true){ + Cycic.pane.getChildren().add(line); + line.setEndX(event.getX()); + line.setEndY(event.getY()); + line.setStartX(circle.getCenterX()); + line.setStartY(circle.getCenterY()); + } else { + circle.setCenterX(mousex+x); + circle.setCenterY(mousey+y); + + if(circle.getCenterX() <= Cycic.pane.getLayoutBounds().getMinX()+circle.getRadius()){ + circle.setCenterX(Cycic.pane.getLayoutBounds().getMinX()+circle.getRadius()); } - if(CycicScenarios.workingCycicScenario.Links.get(i).target == circle){ - CycicScenarios.workingCycicScenario.Links.get(i).line.setEndX(circle.getCenterX()); - CycicScenarios.workingCycicScenario.Links.get(i).line.setEndY(circle.getCenterY()); - CycicScenarios.workingCycicScenario.Links.get(i).line.updatePosition(); + if(circle.getCenterY() <= Cycic.pane.getLayoutBounds().getMinY()+circle.getRadius()){ + circle.setCenterY(Cycic.pane.getLayoutBounds().getMinY()+circle.getRadius()); } - } - for(int i = 0; i < circle.childrenLinks.size(); i++){ - circle.childrenLinks.get(i).line.setStartX(circle.getCenterX()); - circle.childrenLinks.get(i).line.setStartY(circle.getCenterY()); - circle.childrenList.get(i).setCenterX(mousex-circle.childrenDeltaX.get(i)+x); - circle.childrenList.get(i).setCenterY(mousey-circle.childrenDeltaY.get(i)+y); - circle.childrenLinks.get(i).line.setEndX(circle.childrenList.get(i).getCenterX()); - circle.childrenLinks.get(i).line.setEndY(circle.childrenList.get(i).getCenterY()); - circle.childrenList.get(i).menu.setLayoutX(circle.childrenList.get(i).getCenterX()); - circle.childrenList.get(i).menu.setLayoutY(circle.childrenList.get(i).getCenterY()); - circle.childrenList.get(i).text.setLayoutX(circle.childrenList.get(i).getCenterX()-circle.childrenList.get(i).getRadius()*0.6); - circle.childrenList.get(i).text.setLayoutY(circle.childrenList.get(i).getCenterY()-circle.childrenList.get(i).getRadius()*0.6); - for(int ii = 0; ii < CycicScenarios.workingCycicScenario.Links.size(); ii++){ - if(circle.childrenList.get(i) == CycicScenarios.workingCycicScenario.Links.get(ii).source){ - CycicScenarios.workingCycicScenario.Links.get(ii).line.setStartX(circle.childrenList.get(i).getCenterX()); - CycicScenarios.workingCycicScenario.Links.get(ii).line.setStartY(circle.childrenList.get(i).getCenterY()); - CycicScenarios.workingCycicScenario.Links.get(ii).line.updatePosition(); + if(circle.getCenterY() >= Cycic.pane.getLayoutBounds().getMaxY()-circle.getRadius()){ + circle.setCenterY(Cycic.pane.getLayoutBounds().getMaxY()-circle.getRadius()); + } + if(circle.getCenterX() >= Cycic.pane.getLayoutBounds().getMaxX()-circle.getRadius()){ + circle.setCenterX(Cycic.pane.getLayoutBounds().getMaxX()-circle.getRadius()); + } + + + circle.image.setLayoutX(circle.getCenterX()-60); + circle.image.setLayoutY(circle.getCenterY()-50); + + VisFunctions.placeTextOnCircle(circle, "bottom"); + + for(int i = 0; i < CycicScenarios.workingCycicScenario.Links.size(); i++){ + if(CycicScenarios.workingCycicScenario.Links.get(i).source == circle){ + CycicScenarios.workingCycicScenario.Links.get(i).line.setStartX(circle.getCenterX()); + CycicScenarios.workingCycicScenario.Links.get(i).line.setStartY(circle.getCenterY()); + CycicScenarios.workingCycicScenario.Links.get(i).line.updatePosition(); + } + if(CycicScenarios.workingCycicScenario.Links.get(i).target == circle){ + CycicScenarios.workingCycicScenario.Links.get(i).line.setEndX(circle.getCenterX()); + CycicScenarios.workingCycicScenario.Links.get(i).line.setEndY(circle.getCenterY()); + CycicScenarios.workingCycicScenario.Links.get(i).line.updatePosition(); + } + } + for(int i = 0; i < circle.childrenLinks.size(); i++){ + circle.childrenLinks.get(i).line.setStartX(circle.getCenterX()); + circle.childrenLinks.get(i).line.setStartY(circle.getCenterY()); + circle.childrenList.get(i).setCenterX(mousex-circle.childrenDeltaX.get(i)+x); + circle.childrenList.get(i).setCenterY(mousey-circle.childrenDeltaY.get(i)+y); + circle.childrenLinks.get(i).line.setEndX(circle.childrenList.get(i).getCenterX()); + circle.childrenLinks.get(i).line.setEndY(circle.childrenList.get(i).getCenterY()); + VisFunctions.placeTextOnCircle(circle.childrenList.get(i), "bottom"); + for(int ii = 0; ii < CycicScenarios.workingCycicScenario.Links.size(); ii++){ + if(circle.childrenList.get(i) == CycicScenarios.workingCycicScenario.Links.get(ii).source){ + CycicScenarios.workingCycicScenario.Links.get(ii).line.setStartX(circle.childrenList.get(i).getCenterX()); + CycicScenarios.workingCycicScenario.Links.get(ii).line.setStartY(circle.childrenList.get(i).getCenterY()); + CycicScenarios.workingCycicScenario.Links.get(ii).line.updatePosition(); + } } } + mousex = event.getX(); + mousey = event.getY(); } - mousex = event.getX(); - mousey = event.getY(); + event.consume(); + /*if(event.isConsumed()){ + Cycic.pane.getChildren().remove(line); + }*/ } }); // Double click functionality to show/hide children. As well as a bloom feature to show which node is selected. @@ -257,7 +258,8 @@ public void handle(MouseEvent event){ @Override public void handle(MouseEvent event){ if(event.getButton().equals(MouseButton.SECONDARY)){ - circle.menu.setVisible(true); + circle.menu.show(circle, event.getScreenX(), event.getScreenY()); + event.consume(); } if(event.isAltDown() && event.isControlDown()){ @@ -278,28 +280,48 @@ public void handle(MouseEvent event){ } }); - Cycic.workingScenario.FacilityNodes.add(parent); + CycicScenarios.workingCycicScenario.FacilityNodes.add(parent); // Code for allow a shift + (drag and drop) to start a new facility form for this facilityCircle. - circle.setOnDragDetected(new EventHandler(){ + /*circle.setOnDragDetected(new EventHandler(){ @Override public void handle(MouseEvent event){ if(event.isShiftDown() == true){ - DnD.LocalClipboard clipboard = DnD.getInstance().createLocalClipboard(); + System.out.print("YAY"); + /*DnD.LocalClipboard clipboard = DnD.getInstance().createLocalClipboard(); clipboard.put(DnD.TOOL_FORMAT, Tool.class, new FormBuilderTool()); Dragboard db = circle.startDragAndDrop(TransferMode.COPY); + //Dragboard db = circle.startDragAndDrop(TransferMode.NONE); ClipboardContent content = new ClipboardContent(); - content.put(DnD.TOOL_FORMAT, "Facility Form"); + content.put(DnD.TOOL_FORMAT, "Configure"); db.setContent(content); + Line line = new Line(); + Cycic.pane.getChildren().add(line); + line.setEndX(event.getX()); + line.setEndY(event.getY()); + line.setStartX(circle.getCenterX()); + line.setStartY(circle.getCenterY()); event.consume(); + Cycic.pane.getChildren().remove(line); } } + });*/ + + circle.setOnMouseEntered(new EventHandler(){ + public void handle(MouseEvent e){ + circle.setRadius(mouseOverRadius); + } + }); + + circle.setOnMouseExited(new EventHandler(){ + public void handle(MouseEvent e){ + circle.setRadius(defRadius); + } }); // Adding facilityCircle to the pane. Cycic.pane.getChildren().add(circle); - Cycic.pane.getChildren().add(circle.menu); Cycic.pane.getChildren().add(circle.text); Cycic.pane.getChildren().add(circle.image); circle.image.toBack(); @@ -334,7 +356,7 @@ static void deleteNode(facilityNode node){ CycicScenarios.workingCycicScenario.FacilityNodes.get(i).cycicCircle.childrenList.get(ii).parentIndex = i; } } - VisFunctions.marketHide(); + VisFunctions.redrawPane(); } -} \ No newline at end of file +} diff --git a/cyclist/src/edu/utexas/cycic/CycicNotifications.java b/cyclist/src/edu/utexas/cycic/CycicNotifications.java index b08ed38c..5e274f02 100644 --- a/cyclist/src/edu/utexas/cycic/CycicNotifications.java +++ b/cyclist/src/edu/utexas/cycic/CycicNotifications.java @@ -3,5 +3,6 @@ public class CycicNotifications { public static final String NEW_INSTIT = "new_instit"; + public static final String FORM_REDRAW = "form_redraw"; } diff --git a/cyclist/src/edu/utexas/cycic/DataArrays.java b/cyclist/src/edu/utexas/cycic/DataArrays.java index 0d877b0f..3e45489a 100644 --- a/cyclist/src/edu/utexas/cycic/DataArrays.java +++ b/cyclist/src/edu/utexas/cycic/DataArrays.java @@ -1,12 +1,35 @@ package edu.utexas.cycic; +import java.io.File; +import java.io.FileReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.io.BufferedReader; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonReader; +import javax.json.JsonString; + import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; import javafx.scene.control.Label; import javafx.scene.image.Image; import javafx.scene.shape.Line; +import edu.utah.sci.cyclist.Cyclist; +import edu.utah.sci.cyclist.core.Resources1; + /** * This class contains all of the data structures used for CYCIC. @@ -14,6 +37,8 @@ * */ public class DataArrays{ + static Logger log = Logger.getLogger(DataArrays.class); + static ArrayList FacilityNodes = new ArrayList(); static ArrayList