From 27f56a61a02cfcc343086a06a26c52b4b300c39d Mon Sep 17 00:00:00 2001 From: Holden Davis <59069546+holden-davis-uca@users.noreply.github.com> Date: Tue, 1 Mar 2022 21:01:58 -0600 Subject: [PATCH] Added elementary file browser tab in messages pane --- .metadata/.log | 488 ++++++ .../com.genuitec.eclipse.devstyle/recent.json | 2 +- .../myeclipse-usage.properties | 60 +- .../color-definitions-fix.css | 249 ++- .metadata/.plugins/org.eclipse.cdt.core/.log | 1 + .../org.eclipse.cdt.make.core/specs.c | 1 + .../org.eclipse.cdt.make.core/specs.cpp | 1 + .../0/f026ae1bd399001c1d8ae14b8d89d874 | 505 ++++++ .../12/207261105e87001c1c94b070776e38c3 | 754 -------- .../18/407f2aecd399001c1d8ae14b8d89d874 | 508 ++++++ .../23/006ec962d399001c1d8ae14b8d89d874 | 5 + .../26/b00745585d87001c1c94b070776e38c3 | 750 -------- .../2a/40100ae95a87001c12a89c1e3bf7e9be | 738 -------- .../2b/400c26a0d399001c1d8ae14b8d89d874 | 508 ++++++ .../2b/404dc76cd499001c1d8ae14b8d89d874 | 508 ++++++ .../2d/807aa58cf486001c1970df1b0fc2e419 | 755 -------- .../2e/00a37e6d6284001c1eb5866612b6e642 | 470 ----- .../33/10e4bb225d87001c1c94b070776e38c3 | 747 -------- .../35/60041bb2f486001c1970df1b0fc2e419 | 755 -------- .../39/702945305d87001c1c94b070776e38c3 | 747 -------- .../3d/e08bfdbb6284001c1eb5866612b6e642 | 470 ----- .../43/00064cbb5e87001c1c94b070776e38c3 | 754 -------- .../5/00dc7daaf486001c1970df1b0fc2e419 | 755 -------- .../5/b0d20351f486001c1970df1b0fc2e419 | 755 -------- .../51/80f203c36284001c1eb5866612b6e642 | 470 ----- .../53/f0a289f5d399001c1d8ae14b8d89d874 | 508 ++++++ .../56/805e0b5c5d87001c1c94b070776e38c3 | 750 -------- .../57/102a3eb95d87001c1c94b070776e38c3 | 753 -------- .../58/802681bef486001c1970df1b0fc2e419 | 755 -------- .../58/90c8190ed499001c1d8ae14b8d89d874 | 508 ++++++ .../5a/70336e9df486001c1970df1b0fc2e419 | 755 -------- .../5a/f01ddfd9d399001c1d8ae14b8d89d874 | 508 ++++++ .../5d/b0b2f1415d87001c1c94b070776e38c3 | 748 -------- .../66/10dc06426284001c1eb5866612b6e642 | 467 ----- .../66/6097dca85d87001c1c94b070776e38c3 | 753 -------- .../67/20b24081d499001c1d8ae14b8d89d874 | 508 ++++++ .../6c/e033fbe35a87001c12a89c1e3bf7e9be | 738 -------- .../6d/b06ad4c25a87001c12a89c1e3bf7e9be | 733 -------- .../70/1081c502d399001c1d8ae14b8d89d874 | 501 ++++++ .../72/d0bb465af486001c1970df1b0fc2e419 | 755 -------- .../74/100cb78e5a87001c12a89c1e3bf7e9be | 733 -------- .../75/20d8d5396284001c1eb5866612b6e642 | 464 ----- .../77/403771de5e87001c1c94b070776e38c3 | 754 -------- .../78/c0850554d399001c1d8ae14b8d89d874 | 0 .../7b/b082de556284001c1eb5866612b6e642 | 468 ----- .../80/90b75b00d499001c1d8ae14b8d89d874 | 508 ++++++ .../81/8077f51c5d87001c1c94b070776e38c3 | 746 -------- .../85/508e05d0f486001c1970df1b0fc2e419 | 755 -------- .../85/e0da54d5d399001c1d8ae14b8d89d874 | 508 ++++++ .../92/90f353525b87001c12a89c1e3bf7e9be | 743 -------- .../92/f07cbadf5a87001c12a89c1e3bf7e9be | 737 -------- .../97/703d08035e87001c1c94b070776e38c3 | 753 -------- .../97/c02619345b87001c12a89c1e3bf7e9be | 740 -------- .../99/f0d49d13d499001c1d8ae14b8d89d874 | 508 ++++++ .../9e/905659c75a87001c12a89c1e3bf7e9be | 737 -------- .../a2/10e23b1b6784001c1510d797f7689ac2 | 118 -- .../a3/b0509f115b87001c12a89c1e3bf7e9be | 739 -------- .../a4/30551484f486001c1970df1b0fc2e419 | 755 -------- .../a4/5048b339d499001c1d8ae14b8d89d874 | 508 ++++++ .../a4/d0cad140d499001c1d8ae14b8d89d874 | 508 ++++++ .../a7/0059552dd399001c1d8ae14b8d89d874 | 508 ++++++ .../ab/6026bcad5d87001c1c94b070776e38c3 | 753 -------- .../ab/70d9257bd399001c1d8ae14b8d89d874 | 122 ++ .../ac/20f0d68fd399001c1d8ae14b8d89d874 | 507 ++++++ .../ac/a0269b1f5e87001c1c94b070776e38c3 | 754 -------- .../b/005180265b87001c12a89c1e3bf7e9be | 740 -------- .../b0/70ee67c95e87001c1c94b070776e38c3 | 754 -------- .../b2/7012a02a5b87001c12a89c1e3bf7e9be | 741 -------- .../b3/a03c2467d399001c1d8ae14b8d89d874 | 122 ++ .../b7/807c50265d87001c1c94b070776e38c3 | 747 -------- .../b7/d0e55bc86284001c1eb5866612b6e642 | 470 ----- .../c4/2079bf565d87001c1c94b070776e38c3 | 748 -------- .../c9/80a396fff386001c1970df1b0fc2e419 | 754 -------- .../cd/f0f755e9d299001c1d8ae14b8d89d874 | 501 ++++++ .../d/20bfe3e45a87001c12a89c1e3bf7e9be | 738 -------- .../d7/808763a35d87001c1c94b070776e38c3 | 752 -------- .../d8/40b800515e87001c1c94b070776e38c3 | 754 -------- .../de/6032030a5e87001c1c94b070776e38c3 | 754 -------- .../e1/705441bcd399001c1d8ae14b8d89d874 | 508 ++++++ .../e2/40c2644d5d87001c1c94b070776e38c3 | 748 -------- .../e3/a0fddc3c6284001c1eb5866612b6e642 | 465 ----- .../e4/503c6fd96284001c1eb5866612b6e642 | 470 ----- .../e4/e0b0f6d0d399001c1d8ae14b8d89d874 | 508 ++++++ .../e7/30b7fc8b5e84001c1413be1fff78b6c5 | 10 - .../e9/10096c165d87001c1c94b070776e38c3 | 745 -------- .../ec/50fce65d5d87001c1c94b070776e38c3 | 752 -------- .../ed/70890dd86284001c1eb5866612b6e642 | 470 ----- .../ef/b01bbc0d5e87001c1c94b070776e38c3 | 754 -------- .../f1/f0f92644f486001c1970df1b0fc2e419 | 754 -------- .../f5/20e359e25e87001c1c94b070776e38c3 | 754 -------- .../fd/c0e111035b87001c12a89c1e3bf7e9be | 739 -------- .../ff/3009bde0f486001c1970df1b0fc2e419 | 755 -------- .../source/.indexes/af/history.index | Bin 70 -> 0 bytes .../source/.indexes/d5/7d/history.index | Bin 1516 -> 619 bytes .../source/.indexes/d5/history.index | Bin 60 -> 0 bytes .../.projects/source/.markers | Bin 455241 -> 458955 bytes .../source/org.eclipse.jdt.core/state.dat | Bin 201160 -> 202334 bytes .../29f1b599e14df99a511fd2afcc83fc53fbf0b145 | 974 +++++------ .../3af9e2743710c60c846aa60276509696a3b79be9 | 67 + .../408e8f56744f6f24b5f11afb51ee2d6953157f1e | 45 + .../issues/index.pb | 6 +- .../.root/.indexes/properties.index | Bin 151 -> 151 bytes .../.root/{13.tree => 14.tree} | Bin 83670 -> 83852 bytes .../.safetable/org.eclipse.core.resources | Bin 1009 -> 1416 bytes .../org.eclipse.papyrus.infra.emf.1 | 2 + .../com.genuitec.eclipse.theming.ui.prefs | 4 +- .../org.eclipse.cdt.debug.core.prefs | 2 + .../.settings/org.eclipse.cdt.make.ui.prefs | 8 - .../.settings/org.eclipse.cdt.ui.prefs | 145 +- .../.settings/org.eclipse.debug.core.prefs | 4 + .../org.eclipse.launchbar.core.prefs | 7 + .../.settings/org.eclipse.ui.ide.prefs | 2 +- .../.settings/org.eclipse.ui.workbench.prefs | 3 + .../.settings/org.eclipse.wst.json.ui.prefs | 10 + .../org.eclipse.debug.ui/dialog_settings.xml | 8 + .../org.eclipse.e4.workbench/workbench.xmi | 1552 ++++++++++++++++- .../org.eclipse.jdt.core/1865797976.index | Bin 3432342 -> 3432552 bytes .../org.eclipse.jdt.core/2538701421.index | Bin 533701 -> 534973 bytes .../org.eclipse.jdt.core/savedIndexNames.txt | 2 +- .../QualifiedTypeNameHistory.xml | 4 +- .../org.eclipse.jdt.ui/dialog_settings.xml | 7 + .../0.log | 1 + .../dialog_settings.xml | 3 + .../dialog_settings.xml | 3 + .../dialog_settings.xml | 3 + .../dialog_settings.xml | 3 + .../dialog_settings.xml | 3 + .../dialog_settings.xml | 3 + .../dialog_settings.xml | 3 + .../dialog_settings.xml | 3 + .../dialog_settings.xml | 3 + .../.cache/clean-cache.properties | 2 +- .../SavedExternalPluginList.txt | 1068 +++++++++++- .../org.eclipse.xtext.builder/builder.state | Bin 0 -> 15 bytes .metadata/version.ini | 2 +- Mars-UCA.jar | Bin 4196255 -> 4201437 bytes README.md | 1 + source/mars/venus/FileTree$1.class | Bin 0 -> 1340 bytes source/mars/venus/FileTree.class | Bin 0 -> 3214 bytes source/mars/venus/FileTree.java | 123 ++ source/mars/venus/MessagesPane$1.class | Bin 816 -> 816 bytes source/mars/venus/MessagesPane$2.class | Bin 3042 -> 3042 bytes source/mars/venus/MessagesPane$3.class | Bin 811 -> 811 bytes source/mars/venus/MessagesPane$4.class | Bin 1280 -> 1280 bytes .../mars/venus/MessagesPane$Asker$1$1.class | Bin 1918 -> 1918 bytes .../mars/venus/MessagesPane$Asker$1$2.class | Bin 1523 -> 1523 bytes source/mars/venus/MessagesPane$Asker$1.class | Bin 1355 -> 1355 bytes source/mars/venus/MessagesPane$Asker$2.class | Bin 1664 -> 1664 bytes source/mars/venus/MessagesPane$Asker$3.class | Bin 838 -> 838 bytes source/mars/venus/MessagesPane$Asker$4.class | Bin 1612 -> 1612 bytes source/mars/venus/MessagesPane$Asker.class | Bin 3530 -> 3530 bytes source/mars/venus/MessagesPane.class | Bin 7779 -> 7957 bytes source/mars/venus/MessagesPane.java | 13 +- 153 files changed, 14033 insertions(+), 42985 deletions(-) create mode 100644 .metadata/.plugins/org.eclipse.cdt.core/.log create mode 100644 .metadata/.plugins/org.eclipse.cdt.make.core/specs.c create mode 100644 .metadata/.plugins/org.eclipse.cdt.make.core/specs.cpp create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/0/f026ae1bd399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/12/207261105e87001c1c94b070776e38c3 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/18/407f2aecd399001c1d8ae14b8d89d874 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/23/006ec962d399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/26/b00745585d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2a/40100ae95a87001c12a89c1e3bf7e9be create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2b/400c26a0d399001c1d8ae14b8d89d874 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2b/404dc76cd499001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2d/807aa58cf486001c1970df1b0fc2e419 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/2e/00a37e6d6284001c1eb5866612b6e642 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/33/10e4bb225d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/35/60041bb2f486001c1970df1b0fc2e419 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/39/702945305d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/3d/e08bfdbb6284001c1eb5866612b6e642 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/43/00064cbb5e87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5/00dc7daaf486001c1970df1b0fc2e419 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5/b0d20351f486001c1970df1b0fc2e419 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/51/80f203c36284001c1eb5866612b6e642 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/53/f0a289f5d399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/56/805e0b5c5d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/57/102a3eb95d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/58/802681bef486001c1970df1b0fc2e419 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/58/90c8190ed499001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5a/70336e9df486001c1970df1b0fc2e419 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5a/f01ddfd9d399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/5d/b0b2f1415d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/66/10dc06426284001c1eb5866612b6e642 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/66/6097dca85d87001c1c94b070776e38c3 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/67/20b24081d499001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6c/e033fbe35a87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/6d/b06ad4c25a87001c12a89c1e3bf7e9be create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/70/1081c502d399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/72/d0bb465af486001c1970df1b0fc2e419 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/74/100cb78e5a87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/75/20d8d5396284001c1eb5866612b6e642 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/77/403771de5e87001c1c94b070776e38c3 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/78/c0850554d399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/7b/b082de556284001c1eb5866612b6e642 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/80/90b75b00d499001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/81/8077f51c5d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/508e05d0f486001c1970df1b0fc2e419 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/85/e0da54d5d399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/92/90f353525b87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/92/f07cbadf5a87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/97/703d08035e87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/97/c02619345b87001c12a89c1e3bf7e9be create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/99/f0d49d13d499001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/9e/905659c75a87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a2/10e23b1b6784001c1510d797f7689ac2 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a3/b0509f115b87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a4/30551484f486001c1970df1b0fc2e419 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a4/5048b339d499001c1d8ae14b8d89d874 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a4/d0cad140d499001c1d8ae14b8d89d874 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/a7/0059552dd399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ab/6026bcad5d87001c1c94b070776e38c3 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ab/70d9257bd399001c1d8ae14b8d89d874 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ac/20f0d68fd399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ac/a0269b1f5e87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b/005180265b87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b0/70ee67c95e87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b2/7012a02a5b87001c12a89c1e3bf7e9be create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b3/a03c2467d399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b7/807c50265d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/b7/d0e55bc86284001c1eb5866612b6e642 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c4/2079bf565d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/c9/80a396fff386001c1970df1b0fc2e419 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/cd/f0f755e9d299001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d/20bfe3e45a87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d7/808763a35d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/d8/40b800515e87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/de/6032030a5e87001c1c94b070776e38c3 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e1/705441bcd399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e2/40c2644d5d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e3/a0fddc3c6284001c1eb5866612b6e642 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e4/503c6fd96284001c1eb5866612b6e642 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e4/e0b0f6d0d399001c1d8ae14b8d89d874 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e7/30b7fc8b5e84001c1413be1fff78b6c5 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/e9/10096c165d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ec/50fce65d5d87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ed/70890dd86284001c1eb5866612b6e642 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ef/b01bbc0d5e87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f1/f0f92644f486001c1970df1b0fc2e419 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/f5/20e359e25e87001c1c94b070776e38c3 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/fd/c0e111035b87001c12a89c1e3bf7e9be delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.history/ff/3009bde0f486001c1970df1b0fc2e419 delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/source/.indexes/af/history.index delete mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/source/.indexes/d5/history.index create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/source/org.sonarlint.eclipse.core/issues/3/a/3af9e2743710c60c846aa60276509696a3b79be9 create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.projects/source/org.sonarlint.eclipse.core/issues/4/0/408e8f56744f6f24b5f11afb51ee2d6953157f1e rename .metadata/.plugins/org.eclipse.core.resources/.root/{13.tree => 14.tree} (82%) create mode 100644 .metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.papyrus.infra.emf.1 create mode 100644 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.debug.core.prefs delete mode 100644 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.make.ui.prefs create mode 100644 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.core.prefs create mode 100644 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.launchbar.core.prefs create mode 100644 .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.json.ui.prefs create mode 100644 .metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.collaborationuse.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.common.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.connectionpointreference.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.message.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.parameter.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.property.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.state.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.stereotypeproperty.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.papyrus.uml.textedit.transition.xtext.ui/dialog_settings.xml create mode 100644 .metadata/.plugins/org.eclipse.xtext.builder/builder.state create mode 100644 source/mars/venus/FileTree$1.class create mode 100644 source/mars/venus/FileTree.class create mode 100644 source/mars/venus/FileTree.java diff --git a/.metadata/.log b/.metadata/.log index fa4272e..11cc0fd 100644 --- a/.metadata/.log +++ b/.metadata/.log @@ -698,3 +698,491 @@ user global configuration and to define the default location to store repositori not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and EGit might behave differently since they see different configuration options. This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. +!SESSION 2022-03-01 20:45:32.499 ----------------------------------------------- +eclipse.buildId=4.22.0.I20211124-1800 +java.version=17.0.2 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US +Framework arguments: -product org.eclipse.epp.package.java.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.java.product + +!ENTRY org.eclipse.jface 2 0 2022-03-01 20:45:37.782 +!MESSAGE Keybinding conflicts occurred. They may interfere with normal accelerator operation. +!SUBENTRY 1 org.eclipse.jface 2 0 2022-03-01 20:45:37.782 +!MESSAGE A conflict occurred for CTRL+SHIFT+T: +Binding(CTRL+SHIFT+T, + ParameterizedCommand(Command(org.eclipse.jdt.ui.navigate.open.type,Open Type, + Open a type in a Java editor, + Category(org.eclipse.ui.category.navigate,Navigate,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@33a8f3e7, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) +Binding(CTRL+SHIFT+T, + ParameterizedCommand(Command(org.eclipse.lsp4e.symbolinworkspace,Go to Symbol in Workspace, + , + Category(org.eclipse.lsp4e.category,Language Servers,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@19fce226, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) +!SUBENTRY 1 org.eclipse.jface 2 0 2022-03-01 20:45:37.782 +!MESSAGE A conflict occurred for ALT+SHIFT+R: +Binding(ALT+SHIFT+R, + ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.rename.element,Rename - Refactoring , + Rename the selected element, + Category(org.eclipse.jdt.ui.category.refactoring,Refactor - Java,Java Refactoring Actions,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@1bf2cf15, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) +Binding(ALT+SHIFT+R, + ParameterizedCommand(Command(org.eclipse.ui.edit.rename,Rename, + Rename the selected item, + Category(org.eclipse.ui.category.file,File,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@3b76809d, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) + +!ENTRY org.eclipse.egit.ui 2 0 2022-03-01 20:45:40.117 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\holde'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. + +!ENTRY org.eclipse.osgi 4 0 2022-03-01 21:01:35.909 +!MESSAGE An error occurred while automatically activating bundle org.eclipse.papyrus.views.modelexplorer (1008). +!STACK 0 +org.osgi.framework.BundleException: Exception in org.eclipse.papyrus.views.modelexplorer.Activator.start() of bundle org.eclipse.papyrus.views.modelexplorer. + at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:759) + at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1019) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:365) + at org.eclipse.osgi.container.Module.doStart(Module.java:605) + at org.eclipse.osgi.container.Module.start(Module.java:468) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:404) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:117) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:570) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:335) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:384) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:475) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:403) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:168) + at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:616) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:196) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:920) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:246) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:63) + at org.eclipse.ui.internal.commands.CommandStateProxy.loadState(CommandStateProxy.java:177) + at org.eclipse.ui.internal.commands.CommandStateProxy.loadState(CommandStateProxy.java:161) + at org.eclipse.ui.internal.commands.CommandStateProxy.shouldPersist(CommandStateProxy.java:255) + at org.eclipse.ui.internal.commands.CommandService.dispose(CommandService.java:142) + at org.eclipse.ui.internal.services.ServiceLocator$3.run(ServiceLocator.java:182) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.ui.internal.services.ServiceLocator.disposeServices(ServiceLocator.java:179) + at org.eclipse.ui.internal.services.ServiceLocator.dispose(ServiceLocator.java:152) + at org.eclipse.ui.internal.Workbench.shutdown(Workbench.java:2965) + at org.eclipse.ui.internal.Workbench.busyClose(Workbench.java:1124) + at org.eclipse.ui.internal.Workbench.lambda$4(Workbench.java:1392) + at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) + at org.eclipse.ui.internal.Workbench.close(Workbench.java:1392) + at org.eclipse.ui.internal.Workbench.close(Workbench.java:1368) + at org.eclipse.ui.internal.WorkbenchWindow.busyClose(WorkbenchWindow.java:1716) + at org.eclipse.ui.internal.WorkbenchWindow.lambda$5(WorkbenchWindow.java:1743) + at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) + at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1743) + at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1752) + at org.eclipse.ui.internal.WorkbenchWindow.lambda$2(WorkbenchWindow.java:503) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.lambda$4(WBWRenderer.java:570) + at org.eclipse.swt.events.ShellListener$2.shellClosed(ShellListener.java:102) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:102) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4243) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1060) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1069) + at org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:269) + at org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1552) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4755) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(Native Method) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:508) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4854) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(Native Method) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:508) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4854) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DispatchMessage(Native Method) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3630) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1154) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1045) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:596) + at org.eclipse.equinox.launcher.Main.run(Main.java:1467) + at org.eclipse.equinox.launcher.Main.main(Main.java:1440) +Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.e4.core.contexts.IEclipseContext.get(java.lang.Class)" because "context" is null + at org.eclipse.ui.internal.handlers.LegacyHandlerService.registerLegacyHandler(LegacyHandlerService.java:164) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.registerLegacyHandler(LegacyHandlerService.java:158) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.activateHandler(LegacyHandlerService.java:306) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.activateHandler(LegacyHandlerService.java:294) + at org.eclipse.papyrus.views.modelexplorer.Activator.start(Activator.java:70) + at org.eclipse.osgi.internal.framework.BundleContextImpl.lambda$2(BundleContextImpl.java:808) + at java.base/java.security.AccessController.doPrivileged(AccessController.java:569) + at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:802) + ... 92 more +Root exception: +java.lang.NullPointerException: Cannot invoke "org.eclipse.e4.core.contexts.IEclipseContext.get(java.lang.Class)" because "context" is null + at org.eclipse.ui.internal.handlers.LegacyHandlerService.registerLegacyHandler(LegacyHandlerService.java:164) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.registerLegacyHandler(LegacyHandlerService.java:158) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.activateHandler(LegacyHandlerService.java:306) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.activateHandler(LegacyHandlerService.java:294) + at org.eclipse.papyrus.views.modelexplorer.Activator.start(Activator.java:70) + at org.eclipse.osgi.internal.framework.BundleContextImpl.lambda$2(BundleContextImpl.java:808) + at java.base/java.security.AccessController.doPrivileged(AccessController.java:569) + at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:802) + at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:759) + at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1019) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:365) + at org.eclipse.osgi.container.Module.doStart(Module.java:605) + at org.eclipse.osgi.container.Module.start(Module.java:468) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:404) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:117) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:570) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:335) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:384) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:475) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:403) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:168) + at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:616) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:196) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:920) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:246) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:63) + at org.eclipse.ui.internal.commands.CommandStateProxy.loadState(CommandStateProxy.java:177) + at org.eclipse.ui.internal.commands.CommandStateProxy.loadState(CommandStateProxy.java:161) + at org.eclipse.ui.internal.commands.CommandStateProxy.shouldPersist(CommandStateProxy.java:255) + at org.eclipse.ui.internal.commands.CommandService.dispose(CommandService.java:142) + at org.eclipse.ui.internal.services.ServiceLocator$3.run(ServiceLocator.java:182) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.ui.internal.services.ServiceLocator.disposeServices(ServiceLocator.java:179) + at org.eclipse.ui.internal.services.ServiceLocator.dispose(ServiceLocator.java:152) + at org.eclipse.ui.internal.Workbench.shutdown(Workbench.java:2965) + at org.eclipse.ui.internal.Workbench.busyClose(Workbench.java:1124) + at org.eclipse.ui.internal.Workbench.lambda$4(Workbench.java:1392) + at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) + at org.eclipse.ui.internal.Workbench.close(Workbench.java:1392) + at org.eclipse.ui.internal.Workbench.close(Workbench.java:1368) + at org.eclipse.ui.internal.WorkbenchWindow.busyClose(WorkbenchWindow.java:1716) + at org.eclipse.ui.internal.WorkbenchWindow.lambda$5(WorkbenchWindow.java:1743) + at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) + at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1743) + at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1752) + at org.eclipse.ui.internal.WorkbenchWindow.lambda$2(WorkbenchWindow.java:503) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.lambda$4(WBWRenderer.java:570) + at org.eclipse.swt.events.ShellListener$2.shellClosed(ShellListener.java:102) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:102) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4243) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1060) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1069) + at org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:269) + at org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1552) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4755) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(Native Method) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:508) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4854) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(Native Method) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:508) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4854) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DispatchMessage(Native Method) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3630) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1154) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1045) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:596) + at org.eclipse.equinox.launcher.Main.run(Main.java:1467) + at org.eclipse.equinox.launcher.Main.main(Main.java:1440) + +!ENTRY org.eclipse.ui 4 0 2022-03-01 21:01:35.911 +!MESSAGE The proxied state for 'org.eclipse.papyrus.views.modelexplorer.handler.SortElementState:org.eclipse.papyrus.views.modelexplorer.modelexplorer' could not be loaded +!STACK 1 +org.eclipse.core.runtime.CoreException: Plug-in org.eclipse.papyrus.views.modelexplorer was unable to load class org.eclipse.papyrus.views.modelexplorer.handler.SortElementState. + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.throwException(RegistryStrategyOSGI.java:212) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:198) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:920) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:246) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:63) + at org.eclipse.ui.internal.commands.CommandStateProxy.loadState(CommandStateProxy.java:177) + at org.eclipse.ui.internal.commands.CommandStateProxy.loadState(CommandStateProxy.java:161) + at org.eclipse.ui.internal.commands.CommandStateProxy.shouldPersist(CommandStateProxy.java:255) + at org.eclipse.ui.internal.commands.CommandService.dispose(CommandService.java:142) + at org.eclipse.ui.internal.services.ServiceLocator$3.run(ServiceLocator.java:182) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.ui.internal.services.ServiceLocator.disposeServices(ServiceLocator.java:179) + at org.eclipse.ui.internal.services.ServiceLocator.dispose(ServiceLocator.java:152) + at org.eclipse.ui.internal.Workbench.shutdown(Workbench.java:2965) + at org.eclipse.ui.internal.Workbench.busyClose(Workbench.java:1124) + at org.eclipse.ui.internal.Workbench.lambda$4(Workbench.java:1392) + at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) + at org.eclipse.ui.internal.Workbench.close(Workbench.java:1392) + at org.eclipse.ui.internal.Workbench.close(Workbench.java:1368) + at org.eclipse.ui.internal.WorkbenchWindow.busyClose(WorkbenchWindow.java:1716) + at org.eclipse.ui.internal.WorkbenchWindow.lambda$5(WorkbenchWindow.java:1743) + at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) + at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1743) + at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1752) + at org.eclipse.ui.internal.WorkbenchWindow.lambda$2(WorkbenchWindow.java:503) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.lambda$4(WBWRenderer.java:570) + at org.eclipse.swt.events.ShellListener$2.shellClosed(ShellListener.java:102) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:102) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4243) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1060) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1069) + at org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:269) + at org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1552) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4755) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(Native Method) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:508) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4854) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(Native Method) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:508) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4854) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DispatchMessage(Native Method) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3630) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1154) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1045) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:596) + at org.eclipse.equinox.launcher.Main.run(Main.java:1467) + at org.eclipse.equinox.launcher.Main.main(Main.java:1440) +Caused by: java.lang.ClassNotFoundException: An error occurred while automatically activating bundle org.eclipse.papyrus.views.modelexplorer (1008). + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:126) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:570) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:335) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:384) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:475) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:403) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:168) + at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:616) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:196) + ... 76 more +Caused by: org.osgi.framework.BundleException: Exception in org.eclipse.papyrus.views.modelexplorer.Activator.start() of bundle org.eclipse.papyrus.views.modelexplorer. + at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:759) + at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1019) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:365) + at org.eclipse.osgi.container.Module.doStart(Module.java:605) + at org.eclipse.osgi.container.Module.start(Module.java:468) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:404) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:117) + ... 85 more +Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.e4.core.contexts.IEclipseContext.get(java.lang.Class)" because "context" is null + at org.eclipse.ui.internal.handlers.LegacyHandlerService.registerLegacyHandler(LegacyHandlerService.java:164) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.registerLegacyHandler(LegacyHandlerService.java:158) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.activateHandler(LegacyHandlerService.java:306) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.activateHandler(LegacyHandlerService.java:294) + at org.eclipse.papyrus.views.modelexplorer.Activator.start(Activator.java:70) + at org.eclipse.osgi.internal.framework.BundleContextImpl.lambda$2(BundleContextImpl.java:808) + at java.base/java.security.AccessController.doPrivileged(AccessController.java:569) + at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:802) + ... 92 more +!SUBENTRY 1 org.eclipse.equinox.registry 4 1 2022-03-01 21:01:35.911 +!MESSAGE Plug-in org.eclipse.papyrus.views.modelexplorer was unable to load class org.eclipse.papyrus.views.modelexplorer.handler.SortElementState. +!STACK 0 +java.lang.ClassNotFoundException: An error occurred while automatically activating bundle org.eclipse.papyrus.views.modelexplorer (1008). + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:126) + at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:570) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:335) + at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:384) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:475) + at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:403) + at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:168) + at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) + at org.eclipse.osgi.internal.framework.EquinoxBundle.loadClass(EquinoxBundle.java:616) + at org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:196) + at org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:920) + at org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:246) + at org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:63) + at org.eclipse.ui.internal.commands.CommandStateProxy.loadState(CommandStateProxy.java:177) + at org.eclipse.ui.internal.commands.CommandStateProxy.loadState(CommandStateProxy.java:161) + at org.eclipse.ui.internal.commands.CommandStateProxy.shouldPersist(CommandStateProxy.java:255) + at org.eclipse.ui.internal.commands.CommandService.dispose(CommandService.java:142) + at org.eclipse.ui.internal.services.ServiceLocator$3.run(ServiceLocator.java:182) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.ui.internal.services.ServiceLocator.disposeServices(ServiceLocator.java:179) + at org.eclipse.ui.internal.services.ServiceLocator.dispose(ServiceLocator.java:152) + at org.eclipse.ui.internal.Workbench.shutdown(Workbench.java:2965) + at org.eclipse.ui.internal.Workbench.busyClose(Workbench.java:1124) + at org.eclipse.ui.internal.Workbench.lambda$4(Workbench.java:1392) + at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) + at org.eclipse.ui.internal.Workbench.close(Workbench.java:1392) + at org.eclipse.ui.internal.Workbench.close(Workbench.java:1368) + at org.eclipse.ui.internal.WorkbenchWindow.busyClose(WorkbenchWindow.java:1716) + at org.eclipse.ui.internal.WorkbenchWindow.lambda$5(WorkbenchWindow.java:1743) + at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74) + at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1743) + at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1752) + at org.eclipse.ui.internal.WorkbenchWindow.lambda$2(WorkbenchWindow.java:503) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.lambda$4(WBWRenderer.java:570) + at org.eclipse.swt.events.ShellListener$2.shellClosed(ShellListener.java:102) + at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:102) + at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) + at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4243) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1060) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084) + at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1069) + at org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:269) + at org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1552) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4755) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(Native Method) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:508) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4854) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DefWindowProc(Native Method) + at org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:508) + at org.eclipse.swt.widgets.Control.windowProc(Control.java:4854) + at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340) + at org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1480) + at org.eclipse.swt.widgets.Shell.windowProc(Shell.java:2286) + at org.eclipse.swt.widgets.Display.windowProc(Display.java:5002) + at org.eclipse.swt.internal.win32.OS.DispatchMessage(Native Method) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3630) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1154) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1045) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:596) + at org.eclipse.equinox.launcher.Main.run(Main.java:1467) + at org.eclipse.equinox.launcher.Main.main(Main.java:1440) +Caused by: org.osgi.framework.BundleException: Exception in org.eclipse.papyrus.views.modelexplorer.Activator.start() of bundle org.eclipse.papyrus.views.modelexplorer. + at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:828) + at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:759) + at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1019) + at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:365) + at org.eclipse.osgi.container.Module.doStart(Module.java:605) + at org.eclipse.osgi.container.Module.start(Module.java:468) + at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:404) + at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:117) + ... 85 more +Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.e4.core.contexts.IEclipseContext.get(java.lang.Class)" because "context" is null + at org.eclipse.ui.internal.handlers.LegacyHandlerService.registerLegacyHandler(LegacyHandlerService.java:164) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.registerLegacyHandler(LegacyHandlerService.java:158) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.activateHandler(LegacyHandlerService.java:306) + at org.eclipse.ui.internal.handlers.LegacyHandlerService.activateHandler(LegacyHandlerService.java:294) + at org.eclipse.papyrus.views.modelexplorer.Activator.start(Activator.java:70) + at org.eclipse.osgi.internal.framework.BundleContextImpl.lambda$2(BundleContextImpl.java:808) + at java.base/java.security.AccessController.doPrivileged(AccessController.java:569) + at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:802) + ... 92 more diff --git a/.metadata/.plugins/com.genuitec.eclipse.devstyle/recent.json b/.metadata/.plugins/com.genuitec.eclipse.devstyle/recent.json index 6eca118..bbec984 100644 --- a/.metadata/.plugins/com.genuitec.eclipse.devstyle/recent.json +++ b/.metadata/.plugins/com.genuitec.eclipse.devstyle/recent.json @@ -1 +1 @@ -{"lastUsed":1644160213593,"path":"C:\/Users\/holde\/MARS-UCA","projectCount":1,"recentFiles":[{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"RegistersWindow.java"},{"path":"\/source\/mars\/mips\/dump","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"IntelHexDumpFormat.java","lastModified":1644112661696,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/mips\/dump\/IntelHexDumpFormat.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"VenusUI.java","lastModified":1644112757617},{"path":"\/source\/mars\/assembler","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"Assembler.java","lastModified":1644112757617,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/assembler\/Assembler.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"GuiAction.java","lastModified":1644112881009,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/GuiAction.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"Editor.java","lastModified":1644112891938,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/Editor.java"},{"path":"\/source\/mars","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"MarsLaunch.java","lastModified":1644112757617},{"path":"\/source\/mars\/mips\/instructions","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"BasicInstruction.java","lastModified":1644112757617,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/mips\/instructions\/BasicInstruction.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"EditTabbedPane.java","lastModified":1644160214346,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/EditTabbedPane.java"},{"path":"\/source","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"Mars.java","lastModified":1644112594962},{"path":"\/source\/mars","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"MarsSplashScreen.java","lastModified":1644112592722},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"FileOpenAction.java","lastModified":1644112757617,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/FileOpenAction.java"},{"path":"\/source\/mars","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"Globals.java","lastModified":1644112757617}]} \ No newline at end of file +{"lastUsed":1646190095219,"path":"C:\/Users\/holde\/MARS-UCA","projectCount":1,"recentFiles":[{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"RegistersWindow.java"},{"path":"\/source\/mars\/mips\/dump","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"IntelHexDumpFormat.java","lastModified":1644112661696,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/mips\/dump\/IntelHexDumpFormat.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"FileTree.java","lastModified":1646189413107,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/FileTree.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"VenusUI.java","lastModified":1646189168118},{"path":"\/source\/mars\/assembler","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"Assembler.java","lastModified":1644112757617,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/assembler\/Assembler.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"GuiAction.java","lastModified":1644112881009,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/GuiAction.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"Editor.java","lastModified":1644112891938,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/Editor.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"MessagesPane.java","lastModified":1646189853490,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/MessagesPane.java"},{"path":"\/source\/mars","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"MarsLaunch.java","lastModified":1644112757617},{"path":"\/source\/mars\/mips\/instructions","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"BasicInstruction.java","lastModified":1644112757617,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/mips\/instructions\/BasicInstruction.java"},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"EditTabbedPane.java","lastModified":1644160214346,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/EditTabbedPane.java"},{"path":"\/source","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"Mars.java","lastModified":1644112594962},{"path":"\/source\/mars","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"MarsSplashScreen.java","lastModified":1644112592722},{"path":"\/source\/mars\/venus","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"FileOpenAction.java","lastModified":1644112757617,"locationURI":"file:\/C:\/Users\/holde\/MARS-UCA\/source\/mars\/venus\/FileOpenAction.java"},{"path":"\/source\/mars","parentWorkspace":"C:\/Users\/holde\/MARS-UCA","name":"Globals.java","lastModified":1644112757617}]} \ No newline at end of file diff --git a/.metadata/.plugins/com.genuitec.eclipse.monitor/myeclipse-usage.properties b/.metadata/.plugins/com.genuitec.eclipse.monitor/myeclipse-usage.properties index 652c8d9..b657286 100644 --- a/.metadata/.plugins/com.genuitec.eclipse.monitor/myeclipse-usage.properties +++ b/.metadata/.plugins/com.genuitec.eclipse.monitor/myeclipse-usage.properties @@ -1,62 +1,62 @@ #MyEclipse Usage Data -#Sun Feb 06 09:11:13 CST 2022 +#Tue Mar 01 21:01:36 CST 2022 bundle/com.genuitec.eclipse.tm4e.languageconfiguration=-1 misc/arch=x86_64 -bundle/com.genuitec.eclipse.startup.workspace=4 -bundle/com.genuitec.eclipse.theming.ui=4 +bundle/com.genuitec.eclipse.startup.workspace=5 +bundle/com.genuitec.eclipse.theming.ui=5 bundle/com.genuitec.eclipse.theming.elevation.win32=-1 -view/org.eclipse.ui.console.ConsoleView=3 +view/org.eclipse.ui.console.ConsoleView=4 bundle/com.genuitec.eclipse.theming.css=-1 -bundle/com.genuitec.eclipse.codetogether.ui.client=4 -misc/timestamp=Feb 6, 2022, 3\:11\:13 PM -editor/org.eclipse.jdt.ui.CompilationUnitEditor=36 -bundle/com.genuitec.eclipse.lsp4e=4 -bundle/com.genuitec.eclipse.theming.scrollbar=7 -bundle/com.genuitec.eclipse.codetogether.ui=4 -bundle/com.genuitec.eclipse.theming.base=7 +bundle/com.genuitec.eclipse.codetogether.ui.client=5 +misc/timestamp=Mar 2, 2022, 3\:01\:36 AM +editor/org.eclipse.jdt.ui.CompilationUnitEditor=47 +bundle/com.genuitec.eclipse.lsp4e=5 +bundle/com.genuitec.eclipse.theming.scrollbar=9 +bundle/com.genuitec.eclipse.codetogether.ui=5 devstyle/state/iconsColor/primary=1 -bundle/com.genuitec.eclipse.inlinesearch=4 -bundle/com.genuitec.eclipse.codetogether.patches=7 +bundle/com.genuitec.eclipse.theming.base=9 +bundle/com.genuitec.eclipse.inlinesearch=5 misc/product/org.eclipse.epp.package.java.product=1 -bundle/com.genuitec.eclipse.monitor=4 +bundle/com.genuitec.eclipse.codetogether.patches=9 +bundle/com.genuitec.eclipse.monitor=5 devstyle/state/enabled=1 editor/org.eclipse.jdt.ui.ClassFileEditor=2 -bundle/com.genuitec.eclipse.webclipse.evergreen=4 +bundle/com.genuitec.eclipse.webclipse.evergreen=5 bundle/com.genuitec.eclipse.news=-1 bundle/com.genuitec.eclipse.theming.scrollbar.win=-1 -misc/period=3837792 +misc/period=4793240 bundle/com.genuitec.eclipse.codetogether.epl=-1 bundle/com.genuitec.eclipse.codetogether.api=-1 devstyle/state/inlinesearch=1 -bundle/com.genuitec.eclipse.ui.common.platform=7 -misc/count=7 +bundle/com.genuitec.eclipse.ui.common.platform=9 +misc/count=9 bundle/com.genuitec.eclipse.codetogether.cm=-1 -bundle/com.genuitec.eclipse.meexplorer=4 +bundle/com.genuitec.eclipse.meexplorer=5 misc/productType/devstyle=1 misc/os=win32 -bundle/com.genuitec.eclipse.meexplorer.jdt=4 +bundle/com.genuitec.eclipse.meexplorer.jdt=5 devstyle/state/workbenchColor/Dark_Gray=1 -view/org.eclipse.jdt.ui.PackageExplorer=10 -bundle/com.genuitec.eclipse.webicons=7 +view/org.eclipse.jdt.ui.PackageExplorer=13 +bundle/com.genuitec.eclipse.webicons=9 misc/core_version= -view/org.eclipse.ui.views.ContentOutline=8 +view/org.eclipse.ui.views.ContentOutline=9 misc/installmode/stable=0 devstyle/state/editorColor/Darkest_Dark=1 view/org.eclipse.jdt.callhierarchy.view=5 bundle/com.genuitec.eclipse.codetogether.webicons=-1 bundle/com.genuitec.eclipse.genericeditor=-1 misc/ws=win32 -bundle/com.genuitec.eclipse.patches=7 -bundle/com.genuitec.eclipse.startup=4 +bundle/com.genuitec.eclipse.patches=9 +bundle/com.genuitec.eclipse.startup=5 misc/eclipseVersion/4.22.0.I20211124-1800=1 bundle/com.genuitec.eclipse.theming.base.win=-1 bundle/com.genuitec.eclipse.codetogether.ui.client.tests=-1 misc/installmode/standalone=0 misc/locale=en_US misc/workspace_hash=1161802909 -perspective/org.eclipse.jdt.ui.JavaPerspective=3 +perspective/org.eclipse.jdt.ui.JavaPerspective=4 bundle/com.genuitec.eclipse.theming.epl=-1 -bundle/com.genuitec.eclipsecolortheme.api=7 -bundle/com.genuitec.eclipse.codetogether.core=4 -bundle/com.genuitec.eclipse.theming.core=7 -bundle/com.genuitec.eclipse.core.common.platform=7 +bundle/com.genuitec.eclipsecolortheme.api=9 +bundle/com.genuitec.eclipse.codetogether.core=5 +bundle/com.genuitec.eclipse.theming.core=9 +bundle/com.genuitec.eclipse.core.common.platform=9 diff --git a/.metadata/.plugins/com.genuitec.eclipse.ui.common.platform/color-definitions-fix.css b/.metadata/.plugins/com.genuitec.eclipse.ui.common.platform/color-definitions-fix.css index a465acc..92cb27a 100644 --- a/.metadata/.plugins/com.genuitec.eclipse.ui.common.platform/color-definitions-fix.css +++ b/.metadata/.plugins/com.genuitec.eclipse.ui.common.platform/color-definitions-fix.css @@ -2100,20 +2100,107 @@ IEclipsePreferences#org-eclipse-ui-genericeditor { IEclipsePreferences#org-eclipse-ui-workbench { preferences: 'ACTIVE_HYPERLINK_COLOR=255,200,0' + 'ATMARK_RULE=89,179,179' + 'ATTRIBUTE_DELIM=89,179,179' + 'ATTRIBUTE_NAME=89,179,179' + 'ATTRIBUTE_OPERATOR=89,179,179' + 'ATTRIBUTE_VALUE=89,179,179' + 'CLASS=89,179,179' + 'COMBINATOR=89,179,179' + 'COMMENT=75,113,227' 'CONFLICTING_COLOR=232,14,64' 'CONTENT_ASSIST_BACKGROUND_COLOR=46,52,56' 'CONTENT_ASSIST_FOREGROUND_COLOR=233,235,237' 'COUNTER_COLOR=0,208,255' 'DECORATIONS_COLOR=181,152,86' + 'ERROR=255,96,96' 'ERROR_COLOR=247,68,117' 'HYPERLINK_COLOR=111,197,238' + 'ID=89,179,179' 'INCOMING_COLOR=31,179,235' + 'MEDIA=242,0,255' 'OUTGOING_COLOR=235,237,239' + 'PROPERTY_NAME=255,0,255' + 'PROPERTY_VALUE=242,0,255' + 'PSEUDO=89,179,179' 'RESOLVED_COLOR=104,203,16' + 'SCRIPT_AREA_BORDER=227,113,75' + 'SELECTOR=89,179,179' + 'STRING=242,0,255' + 'UNIVERSAL=89,179,179' + 'URI=242,0,255' + 'cdataBorder=0,254,254' + 'cdataText=255,255,255' + 'commentBorder=75,113,227' + 'commentText=75,113,227' 'content_assist_parameters_background=46,52,56' 'content_assist_parameters_foreground=233,235,237' 'content_assist_proposals_background=46,52,56' 'content_assist_proposals_foreground=233,235,237' + 'declBoder=0,254,254' + 'doctypeExternalId=110,124,135' + 'doctypeExternalPubref=0,254,254' + 'doctypeExtrenalSysref=106,213,160' + 'doctypeName=0,254,254' + 'dtdComment=115,130,140' + 'dtdData=186,92,92' + 'dtdDefault=255,255,255' + 'dtdKeyword=255,191,191' + 'dtdString=89,224,134' + 'dtdSymbol=255,191,191' + 'dtdTag=96,96,255' + 'dtdTagName=96,96,255' + 'entityReference=212,0,255' + 'org.eclipse.cdt.internal.ui.text.doctools.doxygen.multi=75,113,227' + 'org.eclipse.cdt.internal.ui.text.doctools.doxygen.recognizedTag=73,93,111' + 'org.eclipse.cdt.internal.ui.text.doctools.doxygen.single=75,113,227' + 'org.eclipse.cdt.ui.ColoredLabels.writeaccess_highlight=52,46,35' + 'org.eclipse.cdt.ui.asm_directive=255,0,255' + 'org.eclipse.cdt.ui.asm_label=255,0,255' + 'org.eclipse.cdt.ui.c_braces=255,255,255' + 'org.eclipse.cdt.ui.c_comment_task_tag=73,93,111' + 'org.eclipse.cdt.ui.c_default=255,255,255' + 'org.eclipse.cdt.ui.c_keyword=255,0,255' + 'org.eclipse.cdt.ui.c_multi_line_comment=106,213,160' + 'org.eclipse.cdt.ui.c_numbers=255,255,255' + 'org.eclipse.cdt.ui.c_operators=255,255,255' + 'org.eclipse.cdt.ui.c_single_line_comment=106,213,160' + 'org.eclipse.cdt.ui.c_string=212,0,255' + 'org.eclipse.cdt.ui.c_type=255,0,255' + 'org.eclipse.cdt.ui.classHighlighting=0,255,255' + 'org.eclipse.cdt.ui.content_assist_parameters_background=0,0,0' + 'org.eclipse.cdt.ui.content_assist_parameters_foreground=255,255,255' + 'org.eclipse.cdt.ui.content_assist_proposals_background=0,0,0' + 'org.eclipse.cdt.ui.content_assist_proposals_foreground=255,255,255' + 'org.eclipse.cdt.ui.enumClassHighlighting=0,255,255' + 'org.eclipse.cdt.ui.enumHighlighting=247,173,123' + 'org.eclipse.cdt.ui.enumeratorHighlighting=159,159,255' + 'org.eclipse.cdt.ui.externalSDKHighlighting=185,74,237' + 'org.eclipse.cdt.ui.fieldHighlighting=159,159,255' + 'org.eclipse.cdt.ui.functionDeclarationHighlighting=255,255,255' + 'org.eclipse.cdt.ui.functionHighlighting=255,255,255' + 'org.eclipse.cdt.ui.globalVariableHighlighting=255,255,255' + 'org.eclipse.cdt.ui.labelHighlighting=255,255,255' + 'org.eclipse.cdt.ui.localVariableDeclarationHighlighting=255,191,191' + 'org.eclipse.cdt.ui.localVariableHighlighting=255,255,255' + 'org.eclipse.cdt.ui.macroDefinitionHighlighting=255,255,255' + 'org.eclipse.cdt.ui.macroSubstitutionHighlighting=255,255,255' + 'org.eclipse.cdt.ui.methodDeclarationHighlighting=255,255,255' + 'org.eclipse.cdt.ui.methodHighlighting=255,255,255' + 'org.eclipse.cdt.ui.namespaceHighlighting=255,255,255' + 'org.eclipse.cdt.ui.outline.mark.dividercolor=46,52,56' + 'org.eclipse.cdt.ui.outline.mark.textcolor=165,175,182' + 'org.eclipse.cdt.ui.overloadedOperatorHighlighting=255,210,0' + 'org.eclipse.cdt.ui.parameterVariableHighlighting=255,255,255' + 'org.eclipse.cdt.ui.pp_default=255,255,255' + 'org.eclipse.cdt.ui.pp_directive=255,0,255' + 'org.eclipse.cdt.ui.pp_header=212,0,255' + 'org.eclipse.cdt.ui.problemHighlighting=255,143,143' + 'org.eclipse.cdt.ui.staticFieldHighlighting=159,159,255' + 'org.eclipse.cdt.ui.staticMethodHighlighting=255,255,255' + 'org.eclipse.cdt.ui.templateParameterHighlighting=247,173,123' + 'org.eclipse.cdt.ui.typedefHighlighting=0,255,255' + 'org.eclipse.cdt.ui.variablePassedByNonConstReferenceHighlighting=135,67,101' 'org.eclipse.debug.ui.console.background=0,0,0' 'org.eclipse.debug.ui.console.stream.err=255,127,127' 'org.eclipse.debug.ui.console.stream.in=0,255,184' @@ -2195,30 +2282,82 @@ IEclipsePreferences#org-eclipse-ui-workbench { 'org.eclipse.ui.editors.lineNumberRulerColor=120,135,145' 'org.eclipse.ui.editors.printMarginColor=62,70,76' 'org.eclipse.ui.showkeys.backgroundColor=182,190,195' + 'org.eclipse.wst.jsdt.ui.abstractMethodInvocationHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.annotationElementReferenceHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.annotationHighlighting=143,155,163' + 'org.eclipse.wst.jsdt.ui.autoboxingHighlighting=255,255,0' + 'org.eclipse.wst.jsdt.ui.classHighlighting=0,255,255' + 'org.eclipse.wst.jsdt.ui.content_assist_completion_replacement_background=123,123,0' + 'org.eclipse.wst.jsdt.ui.content_assist_completion_replacement_foreground=255,127,127' + 'org.eclipse.wst.jsdt.ui.content_assist_parameters_background=0,0,0' + 'org.eclipse.wst.jsdt.ui.content_assist_parameters_foreground=255,255,255' + 'org.eclipse.wst.jsdt.ui.content_assist_proposals_background=0,0,0' + 'org.eclipse.wst.jsdt.ui.content_assist_proposals_foreground=255,255,255' + 'org.eclipse.wst.jsdt.ui.deprecatedMemberHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.enumHighlighting=247,173,123' + 'org.eclipse.wst.jsdt.ui.fieldHighlighting=159,159,255' + 'org.eclipse.wst.jsdt.ui.inheritedMethodInvocationHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.interfaceHighlighting=125,158,255' + 'org.eclipse.wst.jsdt.ui.java_bracket=255,255,255' + 'org.eclipse.wst.jsdt.ui.java_comment_task_tag=73,93,111' + 'org.eclipse.wst.jsdt.ui.java_default=255,255,255' + 'org.eclipse.wst.jsdt.ui.java_doc_default=75,113,227' + 'org.eclipse.wst.jsdt.ui.java_doc_keyword=73,93,111' + 'org.eclipse.wst.jsdt.ui.java_doc_link=96,96,255' + 'org.eclipse.wst.jsdt.ui.java_doc_tag=104,104,130' + 'org.eclipse.wst.jsdt.ui.java_keyword=255,0,255' + 'org.eclipse.wst.jsdt.ui.java_keyword_return=255,0,255' + 'org.eclipse.wst.jsdt.ui.java_multi_line_comment=106,213,160' + 'org.eclipse.wst.jsdt.ui.java_operator=255,255,255' + 'org.eclipse.wst.jsdt.ui.java_single_line_comment=106,213,160' + 'org.eclipse.wst.jsdt.ui.java_string=212,0,255' + 'org.eclipse.wst.jsdt.ui.localVariableDeclarationHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.localVariableHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.matchingBracketsColor=53,60,65' + 'org.eclipse.wst.jsdt.ui.methodDeclarationHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.methodDeclarationNameHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.methodHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.parameterVariableHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.pf_coloring_argument=255,0,255' + 'org.eclipse.wst.jsdt.ui.pf_coloring_assignment=255,255,255' + 'org.eclipse.wst.jsdt.ui.pf_coloring_comment=106,213,160' + 'org.eclipse.wst.jsdt.ui.pf_coloring_key=255,255,255' + 'org.eclipse.wst.jsdt.ui.pf_coloring_value=212,0,255' + 'org.eclipse.wst.jsdt.ui.staticFieldHighlighting=159,159,255' + 'org.eclipse.wst.jsdt.ui.staticFinalFieldHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.staticMethodInvocationHighlighting=255,255,255' + 'org.eclipse.wst.jsdt.ui.typeArgumentHighlighting=255,255,0' + 'org.eclipse.wst.jsdt.ui.typeParameterHighlighting=247,173,123' + 'org.eclipse.wst.jsdt.ui.typeVariableDeclarationHighlighting=247,173,123' + 'piBorder=0,254,254' + 'tagAttributeName=255,0,255' + 'tagAttributeValue=212,0,255' + 'tagBorder=0,254,254' + 'tagName=89,179,179' } IEclipsePreferences#org-eclipse-wst-css-ui { preferences: + 'ATMARK_RULE=#FFFFFF | null | null | null | null | null' 'ATTRIBUTE_DELIM=#FFFFFF | null | null | null | null | null' - 'UNIVERSAL=#FFFFFF | null | null | null | null | null' + 'ATTRIBUTE_NAME=#FFFFFF | null | null | null | null | null' + 'ATTRIBUTE_OPERATOR=#FFFFFF | null | null | null | null | null' 'ATTRIBUTE_VALUE=#FFFFFF | null | null | null | null | null' - 'COLON=#D8D8D8 | null | null | null | null | null' 'CLASS=#FFFFFF | null | null | null | null | null' - 'PSEUDO=#FFFFFF | null | null | null | null | null' - 'PROPERTY_VALUE=#FFC600 | null | null | null | null | null' - 'URI=#FFC600 | null | null | null | null | null' - 'PROPERTY_NAME=#BED6FF | null | null | null | null | null' + 'COLON=#D8D8D8 | null | null | null | null | null' + 'COMBINATOR=#FFFFFF | null | null | null | null | null' 'COMMENT=#C7DD0C | null | null | false | null | null' 'CURLY_BRACE=#D8D8D8 | null | null | null | null | null' - 'ATTRIBUTE_NAME=#FFFFFF | null | null | null | null | null' - 'ATMARK_RULE=#FFFFFF | null | null | null | null | null' - 'COMBINATOR=#FFFFFF | null | null | null | null | null' - 'SELECTOR=#FFFFFF | null | null | null | null | null' - 'STRING=#FFC600 | null | null | null | null | null' - 'MEDIA=#8DCBE2 | null | null | null | null | null' - 'SEMI_COLON=#D8D8D8 | null | null | null | null | null' 'ID=#FFFFFF | null | null | null | null | null' + 'MEDIA=#8DCBE2 | null | null | null | null | null' 'NORMAL=#D8D8D8 | null | null | null | null | null' - 'ATTRIBUTE_OPERATOR=#FFFFFF | null | null | null | null | null' + 'PROPERTY_NAME=#BED6FF | null | null | null | null | null' + 'PROPERTY_VALUE=#FFC600 | null | null | null | null | null' + 'PSEUDO=#FFFFFF | null | null | null | null | null' + 'SELECTOR=#FFFFFF | null | null | null | null | null' + 'SEMI_COLON=#D8D8D8 | null | null | null | null | null' + 'STRING=#FFC600 | null | null | null | null | null' + 'UNIVERSAL=#FFFFFF | null | null | null | null | null' + 'URI=#FFC600 | null | null | null | null | null' } IEclipsePreferences#org-eclipse-wst-dtd-ui { preferences: @@ -2233,19 +2372,19 @@ IEclipsePreferences#org-eclipse-wst-dtd-ui { } IEclipsePreferences#org-eclipse-wst-html-ui { preferences: - 'doctypeExternalPubref=#FFFFFF | null | null | null | null | null' - 'tagBorder=#79ABFF | null | null | null | null | null' - 'declBoder=#FFFFFF | null | null | null | null | null' - 'doctypeExtrenalSysref=#FFFFFF | null | null | null | null | null' - 'tagName=#BED6FF | null | null | null | null | null' + 'commentBorder=#C7DD0C | null | null | false | null | null' 'commentText=#C7DD0C | null | null | false | null | null' + 'declBoder=#FFFFFF | null | null | null | null | null' 'doctypeExternalId=#FFFFFF | null | null | null | null | null' + 'doctypeExternalPubref=#FFFFFF | null | null | null | null | null' + 'doctypeExtrenalSysref=#FFFFFF | null | null | null | null | null' 'doctypeName=#FFFFFF | null | null | null | null | null' - 'tagAttributeValue=#FFC600 | null | null | null | null | null' - 'tagAttributeEquals=#D8D8D8 | null | null | null | null | null' 'entityReference=#8DCBE2 | null | null | null | null | null' - 'commentBorder=#C7DD0C | null | null | false | null | null' + 'tagAttributeEquals=#D8D8D8 | null | null | null | null | null' 'tagAttributeName=#BED6FF | null | null | null | null | null' + 'tagAttributeValue=#FFC600 | null | null | null | null | null' + 'tagBorder=#79ABFF | null | null | null | null | null' + 'tagName=#BED6FF | null | null | null | null | null' 'xmlContent=#D8D8D8 | null | null | null | null | null' } IEclipsePreferences#org-eclipse-wst-jsdt-ui { @@ -2289,26 +2428,46 @@ IEclipsePreferences#org-eclipse-wst-jsdt-ui { 'semanticHighlighting.methodDeclarationName.underline=false' 'tagName=255,255,255' } +IEclipsePreferences#org-eclipse-wst-json-ui { + preferences: + 'COLON=#ffffff | null | false | false | false | false' + 'COMMA=#ffffff | null | false | false | false | false' + 'CURLY_BRACE=#ffffff | null | false | false | false | false' + 'OBJECT_KEY=#bed6ff | null | false | false | false | false' + 'VALUE_BOOLEAN=#03a8d8 | null | false | false | false | false' + 'VALUE_NULL=#89969f | null | false | false | false | false' + 'VALUE_NUMBER=#cb4f40 | null | false | false | false | false' + 'VALUE_STRING=#ffc600 | null | true | true | false | false' +} +IEclipsePreferences#org-eclipse-wst-sse-ui { + preferences: + 'content_assist_completion_replacement_background=200,200,0' + 'content_assist_completion_replacement_foreground=194,0,0' + 'content_assist_parameters_background=48,54,59' + 'content_assist_parameters_foreground=235,237,239' + 'content_assist_proposals_background=48,54,59' + 'content_assist_proposals_foreground=235,237,239' +} IEclipsePreferences#org-eclipse-wst-xml-ui { preferences: - 'doctypeExternalPubref=#FFFFFF | null | null | null | null | null' - 'declBorder=#FFFFFF | null | null | null | null | null' - 'tagBorder=#79ABFF | null | null | null | null | null' + 'cdataBorder=#FFFFFF | null | null | null | null | null' 'cdataText=#D8D8D8 | null | null | null | null | null' - 'declBoder=#FFFFFF | null | null | null | null | null' - 'piBorder=#FFFFFF | null | null | null | null | null' - 'doctypeExtrenalSysref=#FFFFFF | null | null | null | null | null' - 'tagName=#BED6FF | null | null | null | null | null' + 'commentBorder=#C7DD0C | null | null | false | null | null' 'commentText=#C7DD0C | null | null | false | null | null' + 'declBoder=#FFFFFF | null | null | null | null | null' + 'declBorder=#FFFFFF | null | null | null | null | null' 'doctypeExternalId=#FFFFFF | null | null | null | null | null' + 'doctypeExternalPubref=#FFFFFF | null | null | null | null | null' + 'doctypeExtrenalSysref=#FFFFFF | null | null | null | null | null' 'doctypeName=#FFFFFF | null | null | null | null | null' - 'tagAttributeValue=#FFC600 | null | null | null | null | null' - 'tagAttributeEquals=#D8D8D8 | null | null | null | null | null' 'entityReference=#8DCBE2 | null | null | null | null | null' - 'commentBorder=#C7DD0C | null | null | false | null | null' - 'tagAttributeName=#BED6FF | null | null | null | null | null' + 'piBorder=#FFFFFF | null | null | null | null | null' 'piContent=#D8D8D8 | null | null | null | null | null' - 'cdataBorder=#FFFFFF | null | null | null | null | null' + 'tagAttributeEquals=#D8D8D8 | null | null | null | null | null' + 'tagAttributeName=#BED6FF | null | null | null | null | null' + 'tagAttributeValue=#FFC600 | null | null | null | null | null' + 'tagBorder=#79ABFF | null | null | null | null | null' + 'tagName=#BED6FF | null | null | null | null | null' 'xmlContent=#D8D8D8 | null | null | null | null | null' } IEclipsePreferences#org-eclipse-wst-xsl-ui { @@ -2335,6 +2494,28 @@ IEclipsePreferences#org-eclipse-xtend-core-Xtend { 'org.eclipse.xtend.core.Xtend.syntaxColorer.tokenStyles.xbase.static.method.invocation.color=190,214,255' 'org.eclipse.xtend.core.Xtend.syntaxColorer.tokenStyles.xtend.richText.bgColor=39,44,48' } +IEclipsePreferences#org-eclipse-xtext-ui { + preferences: + 'syntaxColorer.comment.color=85,96,104' + 'syntaxColorer.default.color=227,230,232' + 'syntaxColorer.error.color=173,25,62' + 'syntaxColorer.keyword.color=214,38,99' + 'syntaxColorer.keyword.style=1' + 'syntaxColorer.number.color=104,151,187' + 'syntaxColorer.punctuation.color=227,230,232' + 'syntaxColorer.string.color=41,197,163' + 'syntaxColorer.task.color=126,140,149' + 'syntaxColorer.task.style=1' + 'syntaxColorer.xbase.annotation.color=255,147,147' + 'syntaxColorer.xbase.deprecated.members.color=165,30,52' + 'syntaxColorer.xbase.deprecated.members.style=536870912' + 'syntaxColorer.xbase.extension.method.invacation.color=165,46,0' + 'syntaxColorer.xbase.field.color=102,225,248' + 'syntaxColorer.xbase.static.field.color=141,218,248' + 'syntaxColorer.xbase.static.field.style=2' + 'syntaxColorer.xbase.static.method.invocation.color=150,236,63' + 'syntaxColorer.xbase.static.method.invocation.style=2' +} IEclipsePreferences#org-epic-perleditor { preferences: 'taskIndicationColorBold=false' diff --git a/.metadata/.plugins/org.eclipse.cdt.core/.log b/.metadata/.plugins/org.eclipse.cdt.core/.log new file mode 100644 index 0000000..e7a4161 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.cdt.core/.log @@ -0,0 +1 @@ +*** SESSION Mar 01, 2022 20:45:40.279 ------------------------------------------ diff --git a/.metadata/.plugins/org.eclipse.cdt.make.core/specs.c b/.metadata/.plugins/org.eclipse.cdt.make.core/specs.c new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.cdt.make.core/specs.c @@ -0,0 +1 @@ + diff --git a/.metadata/.plugins/org.eclipse.cdt.make.core/specs.cpp b/.metadata/.plugins/org.eclipse.cdt.make.core/specs.cpp new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.cdt.make.core/specs.cpp @@ -0,0 +1 @@ + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/0/f026ae1bd399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/0/f026ae1bd399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..9130044 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/0/f026ae1bd399001c1d8ae14b8d89d874 @@ -0,0 +1,505 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; + import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new JPanel(new BorderLayout()); + fileTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/12/207261105e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/12/207261105e87001c1c94b070776e38c3 deleted file mode 100644 index 37f9627..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/12/207261105e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } -// theFile = saveDialog.getSelectedFile(); - theFile = new File(saver.getFile()); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/18/407f2aecd399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/18/407f2aecd399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..751468c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/18/407f2aecd399001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File(".")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/23/006ec962d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/23/006ec962d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..5fea2b8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/23/006ec962d399001c1d8ae14b8d89d874 @@ -0,0 +1,5 @@ +package mars.venus; + +public class FileTree { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/26/b00745585d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/26/b00745585d87001c1c94b070776e38c3 deleted file mode 100644 index 52afc9f..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/26/b00745585d87001c1c94b070776e38c3 +++ /dev/null @@ -1,750 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2a/40100ae95a87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/2a/40100ae95a87001c12a89c1e3bf7e9be deleted file mode 100644 index dcada64..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/2a/40100ae95a87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,738 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2b/400c26a0d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/2b/400c26a0d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..fcd7640 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2b/400c26a0d399001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File(".")); + fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2b/404dc76cd499001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/2b/404dc76cd499001c1d8ae14b8d89d874 new file mode 100644 index 0000000..bfe7ce8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2b/404dc76cd499001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("..")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2d/807aa58cf486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/807aa58cf486001c1970df1b0fc2e419 deleted file mode 100644 index ca6cc28..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/2d/807aa58cf486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/00a37e6d6284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/2e/00a37e6d6284001c1eb5866612b6e642 deleted file mode 100644 index fbbe1bb..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/2e/00a37e6d6284001c1eb5866612b6e642 +++ /dev/null @@ -1,470 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(40); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][3]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - tableData[i][3]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),10); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,10), number, 3); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,10), number, 3); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/33/10e4bb225d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/33/10e4bb225d87001c1c94b070776e38c3 deleted file mode 100644 index 635c573..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/33/10e4bb225d87001c1c94b070776e38c3 +++ /dev/null @@ -1,747 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/35/60041bb2f486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/35/60041bb2f486001c1970df1b0fc2e419 deleted file mode 100644 index f9fd535..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/35/60041bb2f486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/39/702945305d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/39/702945305d87001c1c94b070776e38c3 deleted file mode 100644 index 6b43038..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/39/702945305d87001c1c94b070776e38c3 +++ /dev/null @@ -1,747 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3d/e08bfdbb6284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/3d/e08bfdbb6284001c1eb5866612b6e642 deleted file mode 100644 index 06a1613..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/3d/e08bfdbb6284001c1eb5866612b6e642 +++ /dev/null @@ -1,470 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(40); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][4]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - tableData[i][3]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),10); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,10), number, 3); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,10), number, 3); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/43/00064cbb5e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/43/00064cbb5e87001c1c94b070776e38c3 deleted file mode 100644 index 90c648e..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/43/00064cbb5e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - -// int decision = saveDialog.showSaveDialog(mainUI); -// if (decision != JFileChooser.APPROVE_OPTION) { -// return null; -// } -// theFile = saveDialog.getSelectedFile(); - theFile = new File(saver.getDirectory() + saver.getFile()); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5/00dc7daaf486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/5/00dc7daaf486001c1970df1b0fc2e419 deleted file mode 100644 index 84fbbf2..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/5/00dc7daaf486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5/b0d20351f486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/5/b0d20351f486001c1970df1b0fc2e419 deleted file mode 100644 index abac887..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/5/b0d20351f486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. - if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { - mainUI.getRunAssembleAction().actionPerformed(null); - } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/51/80f203c36284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/51/80f203c36284001c1eb5866612b6e642 deleted file mode 100644 index 1518ecc..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/51/80f203c36284001c1eb5866612b6e642 +++ /dev/null @@ -1,470 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(20); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][4]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - tableData[i][3]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),10); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,10), number, 3); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,10), number, 3); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/53/f0a289f5d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/53/f0a289f5d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..c797403 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/53/f0a289f5d399001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/56/805e0b5c5d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/56/805e0b5c5d87001c1c94b070776e38c3 deleted file mode 100644 index 0d79f0a..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/56/805e0b5c5d87001c1c94b070776e38c3 +++ /dev/null @@ -1,750 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/102a3eb95d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/57/102a3eb95d87001c1c94b070776e38c3 deleted file mode 100644 index c815f69..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/57/102a3eb95d87001c1c94b070776e38c3 +++ /dev/null @@ -1,753 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/58/802681bef486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/58/802681bef486001c1970df1b0fc2e419 deleted file mode 100644 index 6bbd29a..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/58/802681bef486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. - if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { - mainUI.getRunAssembleAction().actionPerformed(null); - } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/58/90c8190ed499001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/58/90c8190ed499001c1d8ae14b8d89d874 new file mode 100644 index 0000000..0d4c33e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/58/90c8190ed499001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("D:\\")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5a/70336e9df486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/70336e9df486001c1970df1b0fc2e419 deleted file mode 100644 index db500b0..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/5a/70336e9df486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5a/f01ddfd9d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/f01ddfd9d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..decb1c1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5a/f01ddfd9d399001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("C:\\")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5d/b0b2f1415d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/b0b2f1415d87001c1c94b070776e38c3 deleted file mode 100644 index bcc0965..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/5d/b0b2f1415d87001c1c94b070776e38c3 +++ /dev/null @@ -1,748 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/66/10dc06426284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/66/10dc06426284001c1eb5866612b6e642 deleted file mode 100644 index be342fd..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/66/10dc06426284001c1eb5866612b6e642 +++ /dev/null @@ -1,467 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(40); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][3]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/66/6097dca85d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/66/6097dca85d87001c1c94b070776e38c3 deleted file mode 100644 index abd8fdf..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/66/6097dca85d87001c1c94b070776e38c3 +++ /dev/null @@ -1,753 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/67/20b24081d499001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/67/20b24081d499001c1d8ae14b8d89d874 new file mode 100644 index 0000000..decb1c1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/67/20b24081d499001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("C:\\")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6c/e033fbe35a87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/6c/e033fbe35a87001c12a89c1e3bf7e9be deleted file mode 100644 index cd344c7..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/6c/e033fbe35a87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,738 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6d/b06ad4c25a87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/6d/b06ad4c25a87001c12a89c1e3bf7e9be deleted file mode 100644 index eb439de..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/6d/b06ad4c25a87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,733 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/70/1081c502d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/70/1081c502d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..c72c707 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/70/1081c502d399001c1d8ae14b8d89d874 @@ -0,0 +1,501 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; + import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/72/d0bb465af486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/72/d0bb465af486001c1970df1b0fc2e419 deleted file mode 100644 index 6bbd29a..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/72/d0bb465af486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. - if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { - mainUI.getRunAssembleAction().actionPerformed(null); - } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/74/100cb78e5a87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/74/100cb78e5a87001c12a89c1e3bf7e9be deleted file mode 100644 index cdeda62..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/74/100cb78e5a87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,733 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. - if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { - mainUI.getRunAssembleAction().actionPerformed(null); - } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/75/20d8d5396284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/75/20d8d5396284001c1eb5866612b6e642 deleted file mode 100644 index 304fb1c..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/75/20d8d5396284001c1eb5866612b6e642 +++ /dev/null @@ -1,464 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][3]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/77/403771de5e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/77/403771de5e87001c1c94b070776e38c3 deleted file mode 100644 index 5f4c921..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/77/403771de5e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - -// int decision = saveDialog.showSaveDialog(mainUI); -// if (decision != JFileChooser.APPROVE_OPTION) { -// return null; -// } -// theFile = saveDialog.getSelectedFile(); - theFile = new File(saver.getDirectory() + saver.getFile()); -// operationOK = true; -// if (theFile.exists()) { -// int overwrite = JOptionPane.showConfirmDialog(mainUI, -// "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", -// "Overwrite existing file?", -// JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); -// switch (overwrite) { -// case JOptionPane.YES_OPTION : -// operationOK = true; -// break; -// case JOptionPane.NO_OPTION : -// operationOK = false; -// break; -// case JOptionPane.CANCEL_OPTION : -// return null; -// default : // should never occur -// return null; -// } -// } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/78/c0850554d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/78/c0850554d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7b/b082de556284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/7b/b082de556284001c1eb5866612b6e642 deleted file mode 100644 index f9f48e8..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/7b/b082de556284001c1eb5866612b6e642 +++ /dev/null @@ -1,468 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(40); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][3]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - tableData[i][3]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),10); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/80/90b75b00d499001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/80/90b75b00d499001c1d8ae14b8d89d874 new file mode 100644 index 0000000..decb1c1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/80/90b75b00d499001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("C:\\")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/81/8077f51c5d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/81/8077f51c5d87001c1c94b070776e38c3 deleted file mode 100644 index 79bb603..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/81/8077f51c5d87001c1c94b070776e38c3 +++ /dev/null @@ -1,746 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/85/508e05d0f486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/85/508e05d0f486001c1970df1b0fc2e419 deleted file mode 100644 index 230fd22..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/85/508e05d0f486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. - if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { - mainUI.getRunAssembleAction().actionPerformed(null); - } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/85/e0da54d5d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/85/e0da54d5d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..1ea9f40 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/85/e0da54d5d399001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("C:\")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/92/90f353525b87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/92/90f353525b87001c12a89c1e3bf7e9be deleted file mode 100644 index 43fa830..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/92/90f353525b87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,743 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/92/f07cbadf5a87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/92/f07cbadf5a87001c12a89c1e3bf7e9be deleted file mode 100644 index 63e46d5..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/92/f07cbadf5a87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,737 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/97/703d08035e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/97/703d08035e87001c1c94b070776e38c3 deleted file mode 100644 index 464f4d4..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/97/703d08035e87001c1c94b070776e38c3 +++ /dev/null @@ -1,753 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/97/c02619345b87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/97/c02619345b87001c12a89c1e3bf7e9be deleted file mode 100644 index ce42c82..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/97/c02619345b87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,740 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/99/f0d49d13d499001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/99/f0d49d13d499001c1d8ae14b8d89d874 new file mode 100644 index 0000000..751dc09 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/99/f0d49d13d499001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("..\")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9e/905659c75a87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/9e/905659c75a87001c12a89c1e3bf7e9be deleted file mode 100644 index 0833811..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/9e/905659c75a87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,737 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a2/10e23b1b6784001c1510d797f7689ac2 b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/10e23b1b6784001c1510d797f7689ac2 deleted file mode 100644 index 342d3ab..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/a2/10e23b1b6784001c1510d797f7689ac2 +++ /dev/null @@ -1,118 +0,0 @@ - package mars; - import java.awt.*; - import javax.swing.*; - -/* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - -/** - * Produces MARS splash screen.
- * Adapted from http://www.java-tips.org/content/view/1267/2/
- */ - - public class MarsSplashScreen extends JWindow { - - private int duration; - - public MarsSplashScreen(int d) { - duration = d; - } - - /** - * A simple little method to show a title screen in the center - * of the screen for the amount of time given in the constructor - */ - public void showSplash() { - ImageBackgroundPanel content = new ImageBackgroundPanel(); - this.setContentPane(content); - - // Set the window's bounds, centering the window - // Wee bit of a hack. I've hardcoded the image dimensions of - // MarsSurfacePathfinder.jpg, because obtaining them via - // getHeight() and getWidth() is not trival -- it is possible - // that at the time of the call the image has not completed - // loading so the Image object doesn't know how big it is. - // So observers are involved -- see the API. - int width = 390; - int height =215; - Toolkit tk = Toolkit.getDefaultToolkit(); - Dimension screen = tk.getScreenSize(); - int x = (screen.width-width)/2; - int y = (screen.height-height)/2; - setBounds(x,y,width,height); - - // Build the splash screen - JLabel title = new JLabel("MARS-UCA", JLabel.CENTER); - JLabel copyrt1 = new JLabel - ("

Version "+Globals.version+" Copyright (c) "+Globals.copyrightYears+"", JLabel.CENTER); - JLabel copyrt2 = new JLabel - ("

"+Globals.copyrightHolders+"", JLabel.CENTER); - title.setFont(new Font("Sans-Serif", Font.BOLD, 16)); - title.setForeground(Color.black); - copyrt1.setFont(new Font("Sans-Serif", Font.BOLD, 14)); - copyrt2.setFont(new Font("Sans-Serif", Font.BOLD, 14)); - copyrt1.setForeground(Color.white); - copyrt2.setForeground(Color.white); - - content.add(title,BorderLayout.NORTH); - content.add(copyrt1,BorderLayout.CENTER); - content.add(copyrt2,BorderLayout.SOUTH); - - // Display it - setVisible(true); - // Wait a little while, maybe while loading resources - try { Thread.sleep(duration); } - catch (Exception e) {} - setVisible(false); - } - - class ImageBackgroundPanel extends JPanel - { - Image image; - public ImageBackgroundPanel() - { - try - { - image = new ImageIcon(Toolkit.getDefaultToolkit().getImage(this.getClass().getResource(Globals.imagesPath+"MarsSurfacePathfinder.jpg"))).getImage(); - } - catch (Exception e) {System.out.println(e); /*handled in paintComponent()*/ } - } - - @Override - protected void paintComponent(Graphics g) - { - super.paintComponent(g); - if (image != null) - g.drawImage(image, 0,0,this.getWidth(),this.getHeight(),this); - } - } - - - - - } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a3/b0509f115b87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/b0509f115b87001c12a89c1e3bf7e9be deleted file mode 100644 index 7a947eb..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/a3/b0509f115b87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,739 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a4/30551484f486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/30551484f486001c1970df1b0fc2e419 deleted file mode 100644 index f072044..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/a4/30551484f486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a4/5048b339d499001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/5048b339d499001c1d8ae14b8d89d874 new file mode 100644 index 0000000..bfe7ce8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/5048b339d499001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("..")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a4/d0cad140d499001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/d0cad140d499001c1d8ae14b8d89d874 new file mode 100644 index 0000000..86276b3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/d0cad140d499001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("..\\..")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a7/0059552dd399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/0059552dd399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..73be0f2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/0059552dd399001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; + import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new JPanel(new BorderLayout()); + fileTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ab/6026bcad5d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/6026bcad5d87001c1c94b070776e38c3 deleted file mode 100644 index 74ab941..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/ab/6026bcad5d87001c1c94b070776e38c3 +++ /dev/null @@ -1,753 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ab/70d9257bd399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/70d9257bd399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..43de457 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/70d9257bd399001c1d8ae14b8d89d874 @@ -0,0 +1,122 @@ +package mars.venus; +/* + * Copyright (c) Ian F. Darwin, http://www.darwinsys.com/, 1996-2002. + * All rights reserved. Software written by Ian F. Darwin and others. + * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee + * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's, + * pioneering role in inventing and promulgating (and standardizing) the Java + * language and environment is gratefully acknowledged. + * + * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for + * inventing predecessor languages C and C++ is also gratefully acknowledged. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.io.File; +import java.util.Collections; +import java.util.Vector; + +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; + +/** + * Display a file system in a JTree view + * + * @version $Id: FileTree.java,v 1.9 2004/02/23 03:39:22 ian Exp $ + * @author Ian Darwin + */ +public class FileTree extends JPanel { + /** Construct a FileTree */ + public FileTree(File dir) { + setLayout(new BorderLayout()); + + // Make a tree list with all the nodes, and make it a JTree + JTree tree = new JTree(addNodes(null, dir)); + + // Add a listener + tree.addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) e + .getPath().getLastPathComponent(); + System.out.println("You selected " + node); + } + }); + + // Lastly, put the JTree into a JScrollPane. + JScrollPane scrollpane = new JScrollPane(); + scrollpane.getViewport().add(tree); + add(BorderLayout.CENTER, scrollpane); + } + + /** Add nodes from under "dir" into curTop. Highly recursive. */ + DefaultMutableTreeNode addNodes(DefaultMutableTreeNode curTop, File dir) { + String curPath = dir.getPath(); + DefaultMutableTreeNode curDir = new DefaultMutableTreeNode(curPath); + if (curTop != null) { // should only be null at root + curTop.add(curDir); + } + Vector ol = new Vector(); + String[] tmp = dir.list(); + for (int i = 0; i < tmp.length; i++) + ol.addElement(tmp[i]); + Collections.sort(ol, String.CASE_INSENSITIVE_ORDER); + File f; + Vector files = new Vector(); + // Make two passes, one for Dirs and one for Files. This is #1. + for (int i = 0; i < ol.size(); i++) { + String thisObject = (String) ol.elementAt(i); + String newPath; + if (curPath.equals(".")) + newPath = thisObject; + else + newPath = curPath + File.separator + thisObject; + if ((f = new File(newPath)).isDirectory()) + addNodes(curDir, f); + else + files.addElement(thisObject); + } + // Pass two: for files. + for (int fnum = 0; fnum < files.size(); fnum++) + curDir.add(new DefaultMutableTreeNode(files.elementAt(fnum))); + return curDir; + } + + public Dimension getMinimumSize() { + return new Dimension(200, 400); + } + + public Dimension getPreferredSize() { + return new Dimension(200, 400); + } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ac/20f0d68fd399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/20f0d68fd399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..bfa432b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/20f0d68fd399001c1d8ae14b8d89d874 @@ -0,0 +1,507 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; + import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new JPanel(new BorderLayout()); + fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ac/a0269b1f5e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/a0269b1f5e87001c1c94b070776e38c3 deleted file mode 100644 index 8de8dae..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/ac/a0269b1f5e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - theFile = new File(saver.getFile()); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b/005180265b87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/b/005180265b87001c12a89c1e3bf7e9be deleted file mode 100644 index 51a9b6d..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/b/005180265b87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,740 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b0/70ee67c95e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/b0/70ee67c95e87001c1c94b070776e38c3 deleted file mode 100644 index ec4a64e..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/b0/70ee67c95e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - -// int decision = saveDialog.showSaveDialog(mainUI); -// if (decision != JFileChooser.APPROVE_OPTION) { -// return null; -// } -// theFile = saveDialog.getSelectedFile(); - theFile = new File(saver.getDirectory() + saver.getFile()); - operationOK = true; -// if (theFile.exists()) { -// int overwrite = JOptionPane.showConfirmDialog(mainUI, -// "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", -// "Overwrite existing file?", -// JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); -// switch (overwrite) { -// case JOptionPane.YES_OPTION : -// operationOK = true; -// break; -// case JOptionPane.NO_OPTION : -// operationOK = false; -// break; -// case JOptionPane.CANCEL_OPTION : -// return null; -// default : // should never occur -// return null; -// } -// } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b2/7012a02a5b87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/7012a02a5b87001c12a89c1e3bf7e9be deleted file mode 100644 index aceef84..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/b2/7012a02a5b87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,741 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b3/a03c2467d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/a03c2467d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..56efa44 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/a03c2467d399001c1d8ae14b8d89d874 @@ -0,0 +1,122 @@ +package mars.venus +/* + * Copyright (c) Ian F. Darwin, http://www.darwinsys.com/, 1996-2002. + * All rights reserved. Software written by Ian F. Darwin and others. + * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee + * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's, + * pioneering role in inventing and promulgating (and standardizing) the Java + * language and environment is gratefully acknowledged. + * + * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for + * inventing predecessor languages C and C++ is also gratefully acknowledged. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.io.File; +import java.util.Collections; +import java.util.Vector; + +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; + +/** + * Display a file system in a JTree view + * + * @version $Id: FileTree.java,v 1.9 2004/02/23 03:39:22 ian Exp $ + * @author Ian Darwin + */ +public class FileTree extends JPanel { + /** Construct a FileTree */ + public FileTree(File dir) { + setLayout(new BorderLayout()); + + // Make a tree list with all the nodes, and make it a JTree + JTree tree = new JTree(addNodes(null, dir)); + + // Add a listener + tree.addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) e + .getPath().getLastPathComponent(); + System.out.println("You selected " + node); + } + }); + + // Lastly, put the JTree into a JScrollPane. + JScrollPane scrollpane = new JScrollPane(); + scrollpane.getViewport().add(tree); + add(BorderLayout.CENTER, scrollpane); + } + + /** Add nodes from under "dir" into curTop. Highly recursive. */ + DefaultMutableTreeNode addNodes(DefaultMutableTreeNode curTop, File dir) { + String curPath = dir.getPath(); + DefaultMutableTreeNode curDir = new DefaultMutableTreeNode(curPath); + if (curTop != null) { // should only be null at root + curTop.add(curDir); + } + Vector ol = new Vector(); + String[] tmp = dir.list(); + for (int i = 0; i < tmp.length; i++) + ol.addElement(tmp[i]); + Collections.sort(ol, String.CASE_INSENSITIVE_ORDER); + File f; + Vector files = new Vector(); + // Make two passes, one for Dirs and one for Files. This is #1. + for (int i = 0; i < ol.size(); i++) { + String thisObject = (String) ol.elementAt(i); + String newPath; + if (curPath.equals(".")) + newPath = thisObject; + else + newPath = curPath + File.separator + thisObject; + if ((f = new File(newPath)).isDirectory()) + addNodes(curDir, f); + else + files.addElement(thisObject); + } + // Pass two: for files. + for (int fnum = 0; fnum < files.size(); fnum++) + curDir.add(new DefaultMutableTreeNode(files.elementAt(fnum))); + return curDir; + } + + public Dimension getMinimumSize() { + return new Dimension(200, 400); + } + + public Dimension getPreferredSize() { + return new Dimension(200, 400); + } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/807c50265d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/807c50265d87001c1c94b070776e38c3 deleted file mode 100644 index b5bd46c..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/807c50265d87001c1c94b070776e38c3 +++ /dev/null @@ -1,747 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/d0e55bc86284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/d0e55bc86284001c1eb5866612b6e642 deleted file mode 100644 index 3466282..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/d0e55bc86284001c1eb5866612b6e642 +++ /dev/null @@ -1,470 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - //table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(20); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][4]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - tableData[i][3]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),10); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,10), number, 3); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,10), number, 3); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/2079bf565d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/2079bf565d87001c1c94b070776e38c3 deleted file mode 100644 index d3110cf..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/2079bf565d87001c1c94b070776e38c3 +++ /dev/null @@ -1,748 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c9/80a396fff386001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/c9/80a396fff386001c1970df1b0fc2e419 deleted file mode 100644 index ddc85de..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/c9/80a396fff386001c1970df1b0fc2e419 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cd/f0f755e9d299001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/cd/f0f755e9d299001c1d8ae14b8d89d874 new file mode 100644 index 0000000..6345d04 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cd/f0f755e9d299001c1d8ae14b8d89d874 @@ -0,0 +1,501 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; + import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d/20bfe3e45a87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/d/20bfe3e45a87001c12a89c1e3bf7e9be deleted file mode 100644 index bda6b39..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/d/20bfe3e45a87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,738 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d7/808763a35d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/808763a35d87001c1c94b070776e38c3 deleted file mode 100644 index 833b60e..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/d7/808763a35d87001c1c94b070776e38c3 +++ /dev/null @@ -1,752 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d8/40b800515e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/d8/40b800515e87001c1c94b070776e38c3 deleted file mode 100644 index 5b3f097..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/d8/40b800515e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - -// int decision = saveDialog.showSaveDialog(mainUI); -// if (decision != JFileChooser.APPROVE_OPTION) { -// return null; -// } -// theFile = saveDialog.getSelectedFile(); - theFile = new File(saver.getFile()); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/de/6032030a5e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/de/6032030a5e87001c1c94b070776e38c3 deleted file mode 100644 index 5cf13b9..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/de/6032030a5e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - theFile = saver.getFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e1/705441bcd399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/e1/705441bcd399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..a7a23a7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e1/705441bcd399001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("C:")); + fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e2/40c2644d5d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/40c2644d5d87001c1c94b070776e38c3 deleted file mode 100644 index fb80e9a..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/e2/40c2644d5d87001c1c94b070776e38c3 +++ /dev/null @@ -1,748 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e3/a0fddc3c6284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/e3/a0fddc3c6284001c1eb5866612b6e642 deleted file mode 100644 index 871e016..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/e3/a0fddc3c6284001c1eb5866612b6e642 +++ /dev/null @@ -1,465 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(40); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][3]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e4/503c6fd96284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/e4/503c6fd96284001c1eb5866612b6e642 deleted file mode 100644 index 1518ecc..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/e4/503c6fd96284001c1eb5866612b6e642 +++ /dev/null @@ -1,470 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(20); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][4]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - tableData[i][3]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),10); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,10), number, 3); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,10), number, 3); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e4/e0b0f6d0d399001c1d8ae14b8d89d874 b/.metadata/.plugins/org.eclipse.core.resources/.history/e4/e0b0f6d0d399001c1d8ae14b8d89d874 new file mode 100644 index 0000000..a27fce9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e4/e0b0f6d0d399001c1d8ae14b8d89d874 @@ -0,0 +1,508 @@ + package mars.venus; + import mars.*; + import javax.swing.*; + import javax.swing.text.*; + import java.awt.*; + import java.awt.event.*; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; + import javax.swing.event.DocumentListener; + import javax.swing.undo.UndoableEdit; + import mars.simulator.Simulator; + import javax.swing.event.DocumentEvent; + import javax.swing.text.Position.Bias; + +/* +Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +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. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ + +/** + * Creates the message window at the bottom of the UI. + * @author Team JSpim + **/ + + public class MessagesPane extends JTabbedPane{ + JTextArea assemble, run; + JPanel assembleTab, runTab, fileTab; + // These constants are designed to keep scrolled contents of the + // two message areas from becoming overwhelmingly large (which + // seems to slow things down as new text is appended). Once it + // reaches MAXIMUM_SCROLLED_CHARACTERS in length then cut off + // the first NUMBER_OF_CHARACTERS_TO_CUT characters. The latter + // must obviously be smaller than the former. + public static final int MAXIMUM_SCROLLED_CHARACTERS = Globals.maximumMessageCharacters; + public static final int NUMBER_OF_CHARACTERS_TO_CUT = Globals.maximumMessageCharacters/10 ; // 10% + + /** + * Constructor for the class, sets up two fresh tabbed text areas for program feedback. + **/ + + public MessagesPane() { + super(); + this.setMinimumSize(new Dimension(0,0)); + assemble= new JTextArea(); + run= new JTextArea(); + assemble.setEditable(false); + run.setEditable(false); + // Set both text areas to mono font. For assemble + // pane, will make messages more readable. For run + // pane, will allow properly aligned "text graphics" + // DPS 15 Dec 2008 + Font monoFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + assemble.setFont(monoFont); + run.setFont(monoFont); + + JButton assembleTabClearButton = new JButton("Clear"); + assembleTabClearButton.setToolTipText("Clear the Mars Messages area"); + assembleTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + assemble.setText(""); + } + }); + assembleTab = new JPanel(new BorderLayout()); + assembleTab.add(createBoxForButton(assembleTabClearButton),BorderLayout.WEST); + assembleTab.add(new JScrollPane(assemble, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + assemble.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + String text; + int lineStart = 0; + int lineEnd = 0; + try { + int line = assemble.getLineOfOffset(assemble.viewToModel(e.getPoint())); + lineStart = assemble.getLineStartOffset(line); + lineEnd = assemble.getLineEndOffset(line); + text = assemble.getText(lineStart, lineEnd-lineStart); + } + catch (BadLocationException ble) { + text = ""; + } + if (text.length() > 0) { + // If error or warning, parse out the line and column number. + if (text.startsWith(ErrorList.ERROR_MESSAGE_PREFIX) || text.startsWith(ErrorList.WARNING_MESSAGE_PREFIX)) { + assemble.select(lineStart,lineEnd); + assemble.setSelectionColor(Color.YELLOW); + assemble.repaint(); + int separatorPosition = text.indexOf(ErrorList.MESSAGE_SEPARATOR); + if (separatorPosition >= 0) { + text = text.substring(0,separatorPosition); + } + String[] stringTokens = text.split("\\s"); // tokenize with whitespace delimiter + String lineToken = ErrorList.LINE_PREFIX.trim(); + String columnToken = ErrorList.POSITION_PREFIX.trim(); + String lineString = ""; + String columnString = ""; + for (int i=0; i= ErrorList.FILENAME_PREFIX.length()) { + fileName = text.substring(fileNameStart, fileNameEnd).trim(); + } + if (fileName != null && fileName.length() > 0) { + selectEditorTextLine(fileName, line, column); + selectErrorMessage(fileName, line, column); + } + } + } + } + }); + + JButton runTabClearButton = new JButton("Clear"); + runTabClearButton.setToolTipText("Clear the Run I/O area"); + runTabClearButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + run.setText(""); + } + }); + runTab = new JPanel(new BorderLayout()); + runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); + runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File("C:")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + this.addTab("Mars Messages", assembleTab); + this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); + this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); + this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + + } + + // Center given button in a box, centered vertically and 6 pixels on left and right + private Box createBoxForButton(JButton button) { + Box buttonRow = Box.createHorizontalBox(); + buttonRow.add(Box.createHorizontalStrut(6)); + buttonRow.add(button); + buttonRow.add(Box.createHorizontalStrut(6)); + Box buttonBox = Box.createVerticalBox(); + buttonBox.add(Box.createVerticalGlue()); + buttonBox.add(buttonRow); + buttonBox.add(Box.createVerticalGlue()); + return buttonBox; + } + + /** + * Will select the Mars Messages tab error message that matches the given + * specifications, if it is found. Matching is done by constructing + * a string using the parameter values and searching the text area for the last + * occurrance of that string. + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectErrorMessage(String fileName, int line, int column) { + String errorReportSubstring = new java.io.File(fileName).getName() + ErrorList.LINE_PREFIX + line + ErrorList.POSITION_PREFIX + column; + int textPosition = assemble.getText().lastIndexOf(errorReportSubstring); + if (textPosition >= 0) { + int textLine = 0; + int lineStart = 0; + int lineEnd = 0; + try { + textLine = assemble.getLineOfOffset(textPosition); + lineStart = assemble.getLineStartOffset(textLine); + lineEnd = assemble.getLineEndOffset(textLine); + assemble.setSelectionColor(Color.YELLOW); + assemble.select(lineStart,lineEnd); + assemble.getCaret().setSelectionVisible(true); + assemble.repaint(); + } + catch (BadLocationException ble) { + // If there is a problem, simply skip the selection + } + } + } + + + /** + * Will select the specified line in an editor tab. If the file is open + * but not current, its tab will be made current. If the file is not open, + * it will be opened in a new tab and made current, however the line will + * not be selected (apparent apparent problem with JEditTextArea). + * @param fileName A String containing the file path name. + * @param line Line number for error message + * @param column Column number for error message + */ + public void selectEditorTextLine(String fileName, int line, int column) { + EditTabbedPane editTabbedPane = (EditTabbedPane) Globals.getGui().getMainPane().getEditTabbedPane(); + EditPane editPane, currentPane = null; + editPane = editTabbedPane.getEditPaneForFile(new java.io.File(fileName).getPath()); + if (editPane != null) { + if (editPane != editTabbedPane.getCurrentEditTab()) { + editTabbedPane.setCurrentEditTab(editPane); + } + currentPane = editPane; + } + else { // file is not open. Try to open it. + if (editTabbedPane.openFile(new java.io.File(fileName))) { + currentPane = editTabbedPane.getCurrentEditTab(); + } + } + // If editPane == null, it means the desired file was not open. Line selection + // does not properly with the JEditTextArea editor in this situation (it works + // fine for the original generic editor). So we just won't do it. DPS 9-Aug-2010 + if (editPane != null && currentPane != null) { + currentPane.selectLine(line, column); + } + } + + /** + * Returns component used to display assembler messages + * + * @return assembler message text component + */ + public JTextArea getAssembleTextArea() { + return assemble; + } + /** + * Returns component used to display runtime messages + * + * @return runtime message text component + */ + public JTextArea getRunTextArea() { + return run; + } + + /** + * Post a message to the assembler display + * + * @param message String to append to assembler display text + */ + public void postMarsMessage(String message) { + assemble.append(message); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (assemble.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + assemble.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + assemble.setCaretPosition(assemble.getDocument().getLength()); + setSelectedComponent(assembleTab); + } + + /** + * Post a message to the runtime display + * + * @param message String to append to runtime display text + */ + // The work of this method is done by "invokeLater" because + // its JTextArea is maintained by the main event thread + // but also used, via this method, by the execution thread for + // "print" syscalls. "invokeLater" schedules the code to be + // run under the event-processing thread no matter what. + // DPS, 23 Aug 2005. + public void postRunMessage(String message) { + final String mess = message; + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + setSelectedComponent(runTab); + run.append(mess); + // can do some crude cutting here. If the document gets "very large", + // let's cut off the oldest text. This will limit scrolling but the limit + // can be set reasonably high. + if (run.getDocument().getLength() > MAXIMUM_SCROLLED_CHARACTERS) { + try { + run.getDocument().remove(0, NUMBER_OF_CHARACTERS_TO_CUT); + } + catch (BadLocationException ble) { + // only if NUMBER_OF_CHARACTERS_TO_CUT > MAXIMUM_SCROLLED_CHARACTERS + } + } + } + }); + } + + /** + * Make the assembler message tab current (up front) + */ + public void selectMarsMessageTab() { + setSelectedComponent(assembleTab); + } + /** + * Make the runtime message tab current (up front) + */ + public void selectRunMessageTab() { + setSelectedComponent(runTab); + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the String parameter, + * is used to get input from a popup dialog. + * + * @param prompt Prompt to display to the user. + * @return User input. + */ + public String getInputString(String prompt) { + String input; + JOptionPane pane = new JOptionPane(prompt,JOptionPane.QUESTION_MESSAGE,JOptionPane.DEFAULT_OPTION); + pane.setWantsInput(true); + JDialog dialog = pane.createDialog(Globals.getGui(), "MIPS Keyboard Input"); + dialog.setVisible(true); + input = (String) pane.getInputValue(); + this.postRunMessage(Globals.userInputAlert+input+"\n"); + return input; + } + + /** + * Method used by the SystemIO class to get interactive user input + * requested by a running MIPS program (e.g. syscall #5 to read an + * integer). SystemIO knows whether simulator is being run at + * command line by the user, or by the GUI. If run at command line, + * it gets input from System.in rather than here. + * + * This is an overloaded method. This version, with the int parameter, + * is used to get input from the MARS Run I/O window. + * + * @param maxLen: maximum length of input. This method returns when maxLen characters have been read. Use -1 for no length restrictions. + * @return User input. + */ + public String getInputString(int maxLen) { + Asker asker = new Asker(maxLen); // Asker defined immediately below. + return asker.response(); + } + + //////////////////////////////////////////////////////////////////////////// + // Thread class for obtaining user input in the Run I/O window (MessagesPane) + // Written by Ricardo Fernández Pascual [rfernandez@ditec.um.es] December 2009. + class Asker implements Runnable { + ArrayBlockingQueue resultQueue = new ArrayBlockingQueue(1); + int initialPos; + int maxLen; + Asker(int maxLen) { + this.maxLen = maxLen; + // initialPos will be set in run() + } + final DocumentListener listener = + new DocumentListener() { + public void insertUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + try { + String inserted = e.getDocument().getText(e.getOffset(), e.getLength()); + int i = inserted.indexOf('\n'); + if (i >= 0) { + int offset = e.getOffset() + i; + if (offset + 1 == e.getDocument().getLength()) { + returnResponse(); + } + else { + // remove the '\n' and put it at the end + e.getDocument().remove(offset, 1); + e.getDocument().insertString(e.getDocument().getLength(), "\n", null); + // insertUpdate will be called again, since we have inserted the '\n' at the end + } + } + else if (maxLen >= 0 && e.getDocument().getLength() - initialPos >= maxLen) { + returnResponse(); + } + } + catch (BadLocationException ex) { + returnResponse(); + } + } + }); + } + public void removeUpdate(final DocumentEvent e) { + EventQueue.invokeLater( + new Runnable() { + public void run() { + if ((e.getDocument().getLength() < initialPos || e.getOffset() < initialPos) && e instanceof UndoableEdit) { + ((UndoableEdit) e).undo(); + run.setCaretPosition(e.getOffset() + e.getLength()); + } + } + }); + } + public void changedUpdate(DocumentEvent e) { } + }; + final NavigationFilter navigationFilter = + new NavigationFilter() { + public void moveDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.moveDot(dot, bias); + } + public void setDot(FilterBypass fb, int dot, Bias bias) { + if (dot < initialPos) { + dot = Math.min(initialPos, run.getDocument().getLength()); + } + fb.setDot(dot, bias); + } + }; + final Simulator.StopListener stopListener = + new Simulator.StopListener() { + public void stopped(Simulator s) { + returnResponse(); + } + }; + public void run() { // must be invoked from the GUI thread + setSelectedComponent(runTab); + run.setEditable(true); + run.requestFocusInWindow(); + run.setCaretPosition(run.getDocument().getLength()); + initialPos = run.getCaretPosition(); + run.setNavigationFilter(navigationFilter); + run.getDocument().addDocumentListener(listener); + Simulator.getInstance().addStopListener(stopListener); + } + void cleanup() { // not required to be called from the GUI thread + EventQueue.invokeLater( + new Runnable() { + public void run() { + run.getDocument().removeDocumentListener(listener); + run.setEditable(false); + run.setNavigationFilter(null); + run.setCaretPosition(run.getDocument().getLength()); + Simulator.getInstance().removeStopListener(stopListener); + } + }); + } + void returnResponse() { + try { + int p = Math.min(initialPos, run.getDocument().getLength()); + int l = Math.min(run.getDocument().getLength() - p, maxLen >= 0 ? maxLen : Integer.MAX_VALUE); + resultQueue.offer(run.getText(p, l)); + } + catch (BadLocationException ex) { + // this cannot happen + resultQueue.offer(""); + } + } + String response() { + EventQueue.invokeLater(this); + try { + return resultQueue.take(); + } + catch (InterruptedException ex) { + return null; + } + finally { + cleanup(); + } + } + } // Asker class + //////////////////////////////////////////////////////////////////////////// + } diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e7/30b7fc8b5e84001c1413be1fff78b6c5 b/.metadata/.plugins/org.eclipse.core.resources/.history/e7/30b7fc8b5e84001c1413be1fff78b6c5 deleted file mode 100644 index d4540a5..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/e7/30b7fc8b5e84001c1413be1fff78b6c5 +++ /dev/null @@ -1,10 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e9/10096c165d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/10096c165d87001c1c94b070776e38c3 deleted file mode 100644 index d7ecfba..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/e9/10096c165d87001c1c94b070776e38c3 +++ /dev/null @@ -1,745 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ec/50fce65d5d87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/ec/50fce65d5d87001c1c94b070776e38c3 deleted file mode 100644 index a0e0b3e..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/ec/50fce65d5d87001c1c94b070776e38c3 +++ /dev/null @@ -1,752 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ed/70890dd86284001c1eb5866612b6e642 b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/70890dd86284001c1eb5866612b6e642 deleted file mode 100644 index 1518ecc..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/ed/70890dd86284001c1eb5866612b6e642 +++ /dev/null @@ -1,470 +0,0 @@ - package mars.venus; - import mars.*; - import mars.util.*; - import mars.simulator.*; - import mars.mips.hardware.*; - import javax.swing.*; - import java.awt.*; - import java.awt.event.*; - import java.util.*; - import javax.swing.table.*; - import javax.swing.event.*; - -/* -Copyright (c) 2003-2009, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Sets up a window to display registers in the UI. - * @author Sanderson, Bumgarner - **/ - - public class RegistersWindow extends JPanel implements Observer { - private static JTable table; - private static Register [] registers; - private Object[][] tableData; - private boolean highlighting; - private int highlightRow; - private ExecutePane executePane; - private static final int NAME_COLUMN = 0; - private static final int NUMBER_COLUMN = 1; - private static final int VALUE_COLUMN = 2; - private static final int DECIMAL_COLUMN = 3; - private static Settings settings; - /** - * Constructor which sets up a fresh window with a table that contains the register values. - **/ - - public RegistersWindow(){ - Simulator.getInstance().addObserver(this); - settings = Globals.getSettings(); - this.highlighting = false; - table = new MyTippedJTable(new RegTableModel(setupWindow())); - table.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(NUMBER_COLUMN).setPreferredWidth(25); - table.getColumnModel().getColumn(VALUE_COLUMN).setPreferredWidth(60); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setPreferredWidth(20); - // Display register values (String-ified) right-justified in mono font - table.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.LEFT)); - table.getColumnModel().getColumn(NUMBER_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - table.getColumnModel().getColumn(DECIMAL_COLUMN).setCellRenderer(new RegisterCellRenderer(MonoRightCellRenderer.MONOSPACED_PLAIN_12POINT, SwingConstants.RIGHT)); - - table.setPreferredScrollableViewportSize(new Dimension(200,700)); - this.setLayout(new BorderLayout()); // table display will occupy entire width if widened - this.add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)); - } - - /** - * Sets up the data for the window. - * @return The array object with the data for the window. - **/ - - public Object[][] setupWindow(){ - int valueBase = NumberDisplayBaseChooser.getBase(settings.getDisplayValuesInHex()); - tableData = new Object[35][4]; - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - tableData[i][0]= registers[i].getName(); - tableData[i][1]= new Integer(registers[i].getNumber()); - tableData[i][2]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),valueBase); - tableData[i][3]= NumberDisplayBaseChooser.formatNumber(registers[i].getValue(),10); - } - tableData[32][0]= "pc"; - tableData[32][1]= "";//new Integer(32); - tableData[32][2]= NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(),valueBase); - - tableData[33][0]= "hi"; - tableData[33][1]= "";//new Integer(33); - tableData[33][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(33),valueBase); - - tableData[34][0]= "lo"; - tableData[34][1]= "";//new Integer(34); - tableData[34][2]= NumberDisplayBaseChooser.formatNumber(RegisterFile.getValue(34),valueBase); - - return tableData; - } - /** - * clear and redisplay registers - */ - public void clearWindow() { - this.clearHighlighting(); - RegisterFile.resetRegisters(); - this.updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * Clear highlight background color from any cell currently highlighted. - */ - public void clearHighlighting() { - highlighting=false; - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - highlightRow = -1; // assure highlight will not occur upon re-assemble. - } - - /** - * Refresh the table, triggering re-rendering. - */ - public void refresh() { - if (table != null) { - table.tableChanged(new TableModelEvent(table.getModel())); - } - } - - /** - * update register display using current number base (10 or 16) - */ - public void updateRegisters() { - updateRegisters(Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase()); - } - - /** - * update register display using specified number base (10 or 16) - * - * @param base desired number base - */ - public void updateRegisters(int base) { - registers = RegisterFile.getRegisters(); - for(int i=0; i< registers.length; i++){ - updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); - } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); - updateRegisterValue(33, RegisterFile.getValue(33), base); - updateRegisterValue(34, RegisterFile.getValue(34), base); - } - - /** - * This method handles the updating of the GUI. - * @param number The number of the register to update. - * @param val New value. - **/ - - public void updateRegisterValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatNumber(val,10), number, 3); - } - - - private void updateRegisterUnsignedValue(int number,int val, int base){ - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,base), number, 2); - ((RegTableModel)table.getModel()).setDisplayAndModelValueAt(NumberDisplayBaseChooser.formatUnsignedInteger(val,10), number, 3); - } - - /** Required by Observer interface. Called when notified by an Observable that we are registered with. - * Observables include: - * The Simulator object, which lets us know when it starts and stops running - * A register object, which lets us know of register operations - * The Simulator keeps us informed of when simulated MIPS execution is active. - * This is the only time we care about register operations. - * @param observable The Observable object who is notifying us - * @param obj Auxiliary object with additional information. - */ - public void update(Observable observable, Object obj) { - if (observable == mars.simulator.Simulator.getInstance()) { - SimulatorNotice notice = (SimulatorNotice) obj; - if (notice.getAction()==SimulatorNotice.SIMULATOR_START) { - // Simulated MIPS execution starts. Respond to memory changes if running in timed - // or stepped mode. - if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps()==1) { - RegisterFile.addRegistersObserver(this); - this.highlighting = true; - } - } - else { - // Simulated MIPS execution stops. Stop responding. - RegisterFile.deleteRegistersObserver(this); - } - } - else if (obj instanceof RegisterAccessNotice) { - // NOTE: each register is a separate Observable - RegisterAccessNotice access = (RegisterAccessNotice) obj; - if (access.getAccessType()==AccessNotice.WRITE) { - // Uses the same highlighting technique as for Text Segment -- see - // AddressCellRenderer class in DataSegmentWindow.java. - this.highlighting = true; - this.highlightCellForRegister((Register)observable); - Globals.getGui().getRegistersPane().setSelectedComponent(this); - } - } - } - - /** - * Highlight the row corresponding to the given register. - * @param register Register object corresponding to row to be selected. - */ - void highlightCellForRegister(Register register) { - this.highlightRow = register.getNumber(); - // Tell the system that table contents have changed. This will trigger re-rendering - // during which cell renderers are obtained. The row of interest (identified by - // instance variabls this.registerRow) will get a renderer - // with highlight background color and all others get renderer with default background. - table.tableChanged(new TableModelEvent(table.getModel())); - } - - /* - * Cell renderer for displaying register entries. This does highlighting, so if you - * don't want highlighting for a given column, don't use this. Currently we highlight - * all columns. - */ - private class RegisterCellRenderer extends DefaultTableCellRenderer { - private Font font; - private int alignment; - - public RegisterCellRenderer(Font font, int alignment) { - super(); - this.font = font; - this.alignment = alignment; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int row, int column) { - JLabel cell = (JLabel) super.getTableCellRendererComponent(table, value, - isSelected, hasFocus, row, column); - cell.setFont(font); - cell.setHorizontalAlignment(alignment); - if (settings.getRegistersHighlighting() && highlighting && row==highlightRow) { - cell.setBackground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.REGISTER_HIGHLIGHT_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.REGISTER_HIGHLIGHT_FONT) ); - } - else if (row%2==0) { - cell.setBackground( settings.getColorSettingByPosition(Settings.EVEN_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.EVEN_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.EVEN_ROW_FONT) ); - } - else { - cell.setBackground( settings.getColorSettingByPosition(Settings.ODD_ROW_BACKGROUND) ); - cell.setForeground( settings.getColorSettingByPosition(Settings.ODD_ROW_FOREGROUND) ); - cell.setFont( settings.getFontByPosition(Settings.ODD_ROW_FONT) ); - } - return cell; - } - } - - - //////////////////////////////////////////////////////////////////////////// - - class RegTableModel extends AbstractTableModel { - final String[] columnNames = {"Name", "Number", "Value"}; - Object[][] data; - - public RegTableModel(Object[][] d){ - data=d; - } - - public int getColumnCount() { - return columnNames.length; - } - - public int getRowCount() { - return data.length; - } - - public String getColumnName(int col) { - return columnNames[col]; - } - - public Object getValueAt(int row, int col) { - return data[row][col]; - } - - /* - * JTable uses this method to determine the default renderer/ - * editor for each cell. - */ - public Class getColumnClass(int c) { - return getValueAt(0, c).getClass(); - } - - /* - * Don't need to implement this method unless your table's - * editable. - */ - public boolean isCellEditable(int row, int col) { - //Note that the data/cell address is constant, - //no matter where the cell appears onscreen. - // these registers are not editable: $zero (0), $pc (32), $ra (31) - if (col == VALUE_COLUMN && row != 0 && row != 32 && row != 31) { - return true; - } - else { - return false; - } - } - - - /* - * Update cell contents in table model. This method should be called - * only when user edits cell, so input validation has to be done. If - * value is valid, MIPS register is updated. - */ - public void setValueAt(Object value, int row, int col) { - int val=0; - try { - val = Binary.stringToInt((String) value); - } - catch (NumberFormatException nfe) { - data[row][col] = "INVALID"; - fireTableCellUpdated(row, col); - return; - } - // Assures that if changed during MIPS program execution, the update will - // occur only between MIPS instructions. - synchronized (Globals.memoryAndRegistersLock) { - RegisterFile.updateRegister(row, val); - } - int valueBase = Globals.getGui().getMainPane().getExecutePane().getValueDisplayBase(); - data[row][col] = NumberDisplayBaseChooser.formatNumber(val, valueBase); - fireTableCellUpdated(row, col); - return; - } - - - /** - * Update cell contents in table model. Does not affect MIPS register. - */ - private void setDisplayAndModelValueAt(Object value, int row, int col) { - data[row][col] = value; - fireTableCellUpdated(row, col); - } - - - // handy for debugging.... - private void printDebugData() { - int numRows = getRowCount(); - int numCols = getColumnCount(); - - for (int i=0; i < numRows; i++) { - System.out.print(" row " + i + ":"); - for (int j=0; j < numCols; j++) { - System.out.print(" " + data[i][j]); - } - System.out.println(); - } - System.out.println("--------------------------"); - } - } - - /////////////////////////////////////////////////////////////////// - // - // JTable subclass to provide custom tool tips for each of the - // register table column headers and for each register name in - // the first column. From Sun's JTable tutorial. - // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html - // - private class MyTippedJTable extends JTable { - MyTippedJTable(RegTableModel m) { - super(m); - this.setRowSelectionAllowed(true); // highlights background color of entire row - this.setSelectionBackground(Color.GREEN); - } - - private String[] regToolTips = { - /* $zero */ "constant 0", - /* $at */ "reserved for assembler", - /* $v0 */ "expression evaluation and results of a function", - /* $v1 */ "expression evaluation and results of a function", - /* $a0 */ "argument 1", - /* $a1 */ "argument 2", - /* $a2 */ "argument 3", - /* $a3 */ "argument 4", - /* $t0 */ "temporary (not preserved across call)", - /* $t1 */ "temporary (not preserved across call)", - /* $t2 */ "temporary (not preserved across call)", - /* $t3 */ "temporary (not preserved across call)", - /* $t4 */ "temporary (not preserved across call)", - /* $t5 */ "temporary (not preserved across call)", - /* $t6 */ "temporary (not preserved across call)", - /* $t7 */ "temporary (not preserved across call)", - /* $s0 */ "saved temporary (preserved across call)", - /* $s1 */ "saved temporary (preserved across call)", - /* $s2 */ "saved temporary (preserved across call)", - /* $s3 */ "saved temporary (preserved across call)", - /* $s4 */ "saved temporary (preserved across call)", - /* $s5 */ "saved temporary (preserved across call)", - /* $s6 */ "saved temporary (preserved across call)", - /* $s7 */ "saved temporary (preserved across call)", - /* $t8 */ "temporary (not preserved across call)", - /* $t9 */ "temporary (not preserved across call)", - /* $k0 */ "reserved for OS kernel", - /* $k1 */ "reserved for OS kernel", - /* $gp */ "pointer to global area", - /* $sp */ "stack pointer", - /* $fp */ "frame pointer", - /* $ra */ "return address (used by function call)", - /* pc */ "program counter", - /* hi */ "high-order word of multiply product, or divide remainder", - /* lo */ "low-order word of multiply product, or divide quotient" - }; - - //Implement table cell tool tips. - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int rowIndex = rowAtPoint(p); - int colIndex = columnAtPoint(p); - int realColumnIndex = convertColumnIndexToModel(colIndex); - if (realColumnIndex == NAME_COLUMN) { //Register name column - tip = regToolTips[rowIndex]; - /* You can customize each tip to encorporiate cell contents if you like: - TableModel model = getModel(); - String regName = (String)model.getValueAt(rowIndex,0); - ....... etc ....... - */ - } - else { - //You can omit this part if you know you don't have any - //renderers that supply their own tool tips. - tip = super.getToolTipText(e); - } - return tip; - } - - private String[] columnToolTips = { - /* name */ "Each register has a tool tip describing its usage convention", - /* number */ "Corresponding register number", - /* value */ "Current 32 bit value" - }; - - //Implement table header tool tips. - protected JTableHeader createDefaultTableHeader() { - return - new JTableHeader(columnModel) { - public String getToolTipText(MouseEvent e) { - String tip = null; - java.awt.Point p = e.getPoint(); - int index = columnModel.getColumnIndexAtX(p.x); - int realIndex = columnModel.getColumn(index).getModelIndex(); - return columnToolTips[realIndex]; - } - }; - } - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ef/b01bbc0d5e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/ef/b01bbc0d5e87001c1c94b070776e38c3 deleted file mode 100644 index 8de8dae..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/ef/b01bbc0d5e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - theFile = new File(saver.getFile()); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f1/f0f92644f486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/f1/f0f92644f486001c1970df1b0fc2e419 deleted file mode 100644 index 882d195..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/f1/f0f92644f486001c1970df1b0fc2e419 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. - if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { - mainUI.getRunAssembleAction().actionPerformed(null); - } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f5/20e359e25e87001c1c94b070776e38c3 b/.metadata/.plugins/org.eclipse.core.resources/.history/f5/20e359e25e87001c1c94b070776e38c3 deleted file mode 100644 index 551958d..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/f5/20e359e25e87001c1c94b070776e38c3 +++ /dev/null @@ -1,754 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - FileDialog saver = null; - boolean operationOK = false; -// while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { -// saveDialog = new JFileChooser(f.getParent()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - else { -// saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - saver = new FileDialog(mainUI, "Save as", FileDialog.SAVE); - saver.setVisible(true); - } - } - String paneFile = editPane.getFilename(); -// if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - if (paneFile != null) saver.setFile(paneFile); - // end of 13-July-2011 code. -// saveDialog.setDialogTitle("Save As"); - -// int decision = saveDialog.showSaveDialog(mainUI); -// if (decision != JFileChooser.APPROVE_OPTION) { -// return null; -// } -// theFile = saveDialog.getSelectedFile(); - theFile = new File(saver.getDirectory() + saver.getFile()); -// operationOK = true; -// if (theFile.exists()) { -// int overwrite = JOptionPane.showConfirmDialog(mainUI, -// "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", -// "Overwrite existing file?", -// JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); -// switch (overwrite) { -// case JOptionPane.YES_OPTION : -// operationOK = true; -// break; -// case JOptionPane.NO_OPTION : -// operationOK = false; -// break; -// case JOptionPane.CANCEL_OPTION : -// return null; -// default : // should never occur -// return null; -// } -// } -// } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fd/c0e111035b87001c12a89c1e3bf7e9be b/.metadata/.plugins/org.eclipse.core.resources/.history/fd/c0e111035b87001c12a89c1e3bf7e9be deleted file mode 100644 index 16568b5..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/fd/c0e111035b87001c12a89c1e3bf7e9be +++ /dev/null @@ -1,739 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's -// // actionPerformed() method. -// if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { -// mainUI.getRunAssembleAction().actionPerformed(null); -// } -// } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ff/3009bde0f486001c1970df1b0fc2e419 b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/3009bde0f486001c1970df1b0fc2e419 deleted file mode 100644 index 6bbd29a..0000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.history/ff/3009bde0f486001c1970df1b0fc2e419 +++ /dev/null @@ -1,755 +0,0 @@ - package mars.venus; - import mars.mips.hardware.*; - import mars.util.*; - import mars.*; - import javax.swing.*; - import javax.swing.event.*; - import java.awt.*; - import java.awt.event.*; - import javax.swing.undo.*; - import java.text.*; - import java.util.*; - import java.io.*; - import java.beans.PropertyChangeListener; - import javax.swing.filechooser.FileFilter; - - /* -Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -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. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - - /** - * Tabbed pane for the editor. Each of its tabs represents an open file. - * @author Sanderson - **/ - - public class EditTabbedPane extends JTabbedPane{ - EditPane editTab; - MainPane mainPane; - - private VenusUI mainUI; - private Editor editor; - private FileOpener fileOpener; - - /** - * Constructor for the EditTabbedPane class. - **/ - - public EditTabbedPane(VenusUI appFrame, Editor editor, MainPane mainPane){ - super(); - this.mainUI = appFrame; - this.editor = editor; - this.fileOpener = new FileOpener(editor); - this.mainPane = mainPane; - this.editor.setEditTabbedPane(this); - this.addChangeListener( - new ChangeListener() { - public void stateChanged(ChangeEvent e) { - EditPane editPane = (EditPane) getSelectedComponent(); - if (editPane != null) { - // New IF statement to permit free traversal of edit panes w/o invalidating - // assembly if assemble-all is selected. DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - EditTabbedPane.this.updateTitles(editPane); - } - else { - EditTabbedPane.this.updateTitlesAndMenuState(editPane); - EditTabbedPane.this.mainPane.getExecutePane().clearPane(); - } - editPane.tellEditingComponentToRequestFocusInWindow(); - } - } - }); - } - - /** - * The current EditPane representing a file. Returns null if - * no files open. - * - * @return the current editor pane - */ - public EditPane getCurrentEditTab() { - return (EditPane)this.getSelectedComponent(); - } - - /** - * Select the specified EditPane to be the current tab. - * - * @param editPane The EditPane tab to become current. - */ - public void setCurrentEditTab(EditPane editPane) { - this.setSelectedComponent(editPane); - } - - /** - * If the given file is open in the tabbed pane, make it the - * current tab. If not opened, open it in a new tab and make - * it the current tab. If file is unable to be opened, - * leave current tab as is. - * @param file File object for the desired file. - * @return EditPane for the specified file, or null if file is unable to be opened in an EditPane - */ - public EditPane getCurrentEditTabForFile(File file) { - EditPane result = null; - EditPane tab = getEditPaneForFile(file.getPath()); - if (tab != null) { - if (tab != getCurrentEditTab()) { - setCurrentEditTab(tab); - } - return tab; - } - // If no return yet, then file is not open. Try to open it. - if (openFile(file)) { - result = getCurrentEditTab(); - } - return result; - } - - /** - * Carries out all necessary operations to implement - * the New operation from the File menu. - */ - public void newFile() { - EditPane editPane = new EditPane(this.mainUI); - editPane.setSourceCode("", true); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NEW_NOT_EDITED); - String name = editor.getNextDefaultFilename(); - editPane.setPathname(name); - this.addTab(name, editPane); - - FileStatus.reset(); - FileStatus.setName(name); - FileStatus.set(FileStatus.NEW_NOT_EDITED); - - RegisterFile.resetRegisters(); - mainUI.setReset(true); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - editPane.displayCaretPosition(new Point(1,1)); - this.setSelectedComponent(editPane); - updateTitlesAndMenuState(editPane); - editPane.tellEditingComponentToRequestFocusInWindow(); - } - - - /** - * Carries out all necessary operations to implement - * the Open operation from the File menu. This - * begins with an Open File dialog. - * @return true if file was opened, false otherwise. - */ - public boolean openFile() { - return fileOpener.openFile(); - } - - /** - * Carries out all necessary operations to open the - * specified file in the editor. - * @return true if file was opened, false otherwise. - */ - public boolean openFile(File file) { - return fileOpener.openFile(file); - } - - - /** - * Carries out all necessary operations to implement - * the Close operation from the File menu. May return - * false, for instance when file has unsaved changes - * and user selects Cancel from the warning dialog. - * @return true if file was closed, false otherwise. - */ - public boolean closeCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (editPane != null) { - if (editsSavedOrAbandoned()) { - this.remove(editPane); - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - } - else { - return false; - } - } - return true; - } - - /** - * Carries out all necessary operations to implement - * the Close All operation from the File menu. - * @return true if files closed, false otherwise. - */ - public boolean closeAllFiles() { - boolean result = true; - boolean unsavedChanges = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - mainPane.getExecutePane().clearPane(); - mainPane.setSelectedComponent(this); - EditPane[] tabs = new EditPane[tabCount]; - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - unsavedChanges = true; - } - } - if (unsavedChanges) { - switch (confirm("one or more files")) { - case JOptionPane.YES_OPTION : - boolean removedAll = true; - for (int i=0; i < tabCount; i++) { - if ( tabs[i].hasUnsavedEdits() ) { - setSelectedComponent(tabs[i]); - boolean saved = saveCurrentFile(); - if (saved) { - this.remove(tabs[i]); - } - else { - removedAll = false; - } - } - else { - this.remove(tabs[i]); - } - } - return removedAll; - case JOptionPane.NO_OPTION : - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - return true; - case JOptionPane.CANCEL_OPTION : - return false; - default : // should never occur - return false; - } - } - else { - for (int i=0; i < tabCount; i++) { - this.remove(tabs[i]); - } - } - } - return result; - } - - /** - * Saves file under existing name. If no name, will invoke Save As. - * @return true if the file was actually saved. - */ - public boolean saveCurrentFile() { - EditPane editPane = getCurrentEditTab(); - if (saveFile(editPane)) { - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // Save file associatd with specified edit pane. - // Returns true if save operation worked, else false. - private boolean saveFile(EditPane editPane) { - if (editPane != null) { - if (editPane.isNew()) { - File theFile = saveAsFile(editPane); - if (theFile != null) { - editPane.setPathname(theFile.getPath()); - } - return (theFile != null); - } - File theFile = new File(editPane.getPathname()); - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save operation could not be completed due to an error:\n"+c, - "Save Operation Failed", JOptionPane.ERROR_MESSAGE); - return false; - } - return true; - } - return false; - } - - - - /** - * Pops up a dialog box to do "Save As" operation. If necessary - * an additional overwrite dialog is performed. - * @return true if the file was actually saved. - */ - public boolean saveAsCurrentFile() { - EditPane editPane = getCurrentEditTab(); - File theFile = saveAsFile(editPane); - if (theFile != null) { - FileStatus.setFile(theFile); - FileStatus.setName(theFile.getPath()); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editor.setCurrentSaveDirectory(theFile.getParent()); - editPane.setPathname(theFile.getPath()); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - return true; - } - return false; - } - - // perform Save As for selected edit pane. If the save is performed, - // return its File object. Otherwise return null. - private File saveAsFile(EditPane editPane) { - File theFile = null; - if (editPane != null) { - JFileChooser saveDialog = null; - boolean operationOK = false; - while (!operationOK) { - // Set Save As dialog directory in a logical way. If file in - // edit pane had been previously saved, default to its directory. - // If a new file (mipsN.asm), default to current save directory. - // DPS 13-July-2011 - if (editPane.isNew()) { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - else { - File f = new File(editPane.getPathname()); - if (f != null) { - saveDialog = new JFileChooser(f.getParent()); - } - else { - saveDialog = new JFileChooser(editor.getCurrentSaveDirectory()); - } - } - String paneFile = editPane.getFilename(); - if (paneFile != null) saveDialog.setSelectedFile(new File(paneFile)); - // end of 13-July-2011 code. - saveDialog.setDialogTitle("Save As"); - - int decision = saveDialog.showSaveDialog(mainUI); - if (decision != JFileChooser.APPROVE_OPTION) { - return null; - } - theFile = saveDialog.getSelectedFile(); - operationOK = true; - if (theFile.exists()) { - int overwrite = JOptionPane.showConfirmDialog(mainUI, - "File "+theFile.getName()+" already exists. Do you wish to overwrite it?", - "Overwrite existing file?", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); - switch (overwrite) { - case JOptionPane.YES_OPTION : - operationOK = true; - break; - case JOptionPane.NO_OPTION : - operationOK = false; - break; - case JOptionPane.CANCEL_OPTION : - return null; - default : // should never occur - return null; - } - } - } - // Either file with selected name does not exist or user wants to - // overwrite it, so go for it! - try { - BufferedWriter outFileStream = new BufferedWriter(new FileWriter(theFile)); - outFileStream.write(editPane.getSource(), 0, editPane.getSource().length()); - outFileStream.close(); - } - catch(java.io.IOException c) { - JOptionPane.showMessageDialog(null,"Save As operation could not be completed due to an error:\n"+c, - "Save As Operation Failed", JOptionPane.ERROR_MESSAGE); - return null; - } - } - return theFile; - } - - - - - /** - * Saves all files currently open in the editor. - * - * @return true if operation succeeded otherwise false. - */ - public boolean saveAllFiles() { - boolean result = false; - int tabCount = getTabCount(); - if (tabCount > 0) { - - result = true; - EditPane[] tabs = new EditPane[tabCount]; - EditPane savedPane = getCurrentEditTab(); - for (int i=0; i < tabCount; i++) { - tabs[i] = (EditPane)getComponentAt(i); - if ( tabs[i].hasUnsavedEdits() ) { - setCurrentEditTab(tabs[i]); - if (saveFile(tabs[i])) { - tabs[i].setFileStatus(FileStatus.NOT_EDITED); - editor.setTitle(tabs[i].getPathname(), tabs[i].getFilename(), tabs[i].getFileStatus()); - } - else { - result = false; - } - } - } - setCurrentEditTab(savedPane); - if (result) { - EditPane editPane = getCurrentEditTab(); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - editPane.setFileStatus(FileStatus.NOT_EDITED); - updateTitlesAndMenuState(editPane); - } - } - return result; - } - - - - /** - * Remove the pane and update menu status - */ - public void remove(EditPane editPane) { - super.remove(editPane); - editPane = getCurrentEditTab(); // is now next tab or null - if (editPane == null) { - FileStatus.set(FileStatus.NO_FILE); - this.editor.setTitle("","",FileStatus.NO_FILE); - Globals.getGui().setMenuState(FileStatus.NO_FILE); - } - else { - FileStatus.set(editPane.getFileStatus()); - updateTitlesAndMenuState(editPane); - } - // When last file is closed, menu is unable to respond to mnemonics - // and accelerators. Let's have it request focus so it may do so. - if (getTabCount()==0) mainUI.haveMenuRequestFocus(); - } - - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - private void updateTitlesAndMenuState(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - Globals.getGui().setMenuState(editPane.getFileStatus()); - } - - // Handy little utility to update the title on the current tab and the frame title bar - // and also to update the MARS menu state (controls which actions are enabled). - // DPS 9-Aug-2011 - private void updateTitles(EditPane editPane) { - editor.setTitle(editPane.getPathname(), editPane.getFilename(), editPane.getFileStatus()); - boolean assembled = FileStatus.isAssembled(); - editPane.updateStaticFileStatus(); // for legacy code that depends on the static FileStatus (pre 4.0) - FileStatus.setAssembled(assembled); - } - - /** - * If there is an EditPane for the given file pathname, return it else return null. - * - * @param pathname Pathname for desired file - * @return the EditPane for this file if it is open in the editor, or null if not. - */ - public EditPane getEditPaneForFile(String pathname) { - EditPane openPane = null; - for (int i=0; iAssemble's - // actionPerformed() method. - if (theFile.canRead() && Globals.getSettings().getAssembleOnOpenEnabled()) { - mainUI.getRunAssembleAction().actionPerformed(null); - } - } - return true; - } - - /* - * Open the specified file. Return true if file opened, false otherwise - */ - - private boolean openFile(File theFile) { - try { - theFile = theFile.getCanonicalFile(); - } - catch (IOException ioe) { - // nothing to do, theFile will keep current value - } - String currentFilePath = theFile.getPath(); - // If this file is currently already open, then simply select its tab - EditPane editPane = getEditPaneForFile(currentFilePath); - if (editPane != null) { - setSelectedComponent(editPane); - //updateTitlesAndMenuState(editPane); - updateTitles(editPane); - return false; - } - else { - editPane = new EditPane(mainUI); - } - editPane.setPathname(currentFilePath); - //FileStatus.reset(); - FileStatus.setName(currentFilePath); - FileStatus.setFile(theFile); - FileStatus.set(FileStatus.OPENING);// DPS 9-Aug-2011 - if (theFile.canRead()) { - Globals.program = new MIPSprogram(); - try { - Globals.program.readSource(currentFilePath); - } - catch (ProcessingException pe) { - } - // DPS 1 Nov 2006. Defined a StringBuffer to receive all file contents, - // one line at a time, before adding to the Edit pane with one setText. - // StringBuffer is preallocated to full filelength to eliminate dynamic - // expansion as lines are added to it. Previously, each line was appended - // to the Edit pane as it was read, way slower due to dynamic string alloc. - StringBuffer fileContents = new StringBuffer((int)theFile.length()); - int lineNumber = 1; - String line = Globals.program.getSourceLine(lineNumber++); - while (line != null) { - fileContents.append(line+"\n"); - line = Globals.program.getSourceLine(lineNumber++); - } - editPane.setSourceCode(fileContents.toString(), true); - // The above operation generates an undoable edit, setting the initial - // text area contents, that should not be seen as undoable by the Undo - // action. Let's get rid of it. - editPane.discardAllUndoableEdits(); - editPane.setShowLineNumbersEnabled(true); - editPane.setFileStatus(FileStatus.NOT_EDITED); - - addTab(editPane.getFilename(), editPane); - setToolTipTextAt(indexOfComponent(editPane), editPane.getPathname()); - setSelectedComponent(editPane); - FileStatus.setSaved(true); - FileStatus.setEdited(false); - FileStatus.set(FileStatus.NOT_EDITED); - - // If assemble-all, then allow opening of any file w/o invalidating assembly. - // DPS 9-Aug-2011 - if (Globals.getSettings().getBooleanSetting(mars.Settings.ASSEMBLE_ALL_ENABLED)) { - updateTitles(editPane); - } - else {// this was the original code... - updateTitlesAndMenuState(editPane); - mainPane.getExecutePane().clearPane(); - } - - mainPane.setSelectedComponent(EditTabbedPane.this); - editPane.tellEditingComponentToRequestFocusInWindow(); - mostRecentlyOpenedFile = theFile; - } - return true; - } - - // Private method to generate the file chooser's list of choosable file filters. - // It is called when the file chooser is created, and called again each time the Open - // dialog is activated. We do this because the user may have added a new filter - // during the previous dialog. This can be done by entering e.g. *.txt in the file - // name text field. Java is funny, however, in that if the user does this then - // cancels the dialog, the new filter will remain in the list BUT if the user does - // this then ACCEPTS the dialog, the new filter will NOT remain in the list. However - // the act of entering it causes a property change event to occur, and we have a - // handler that will add the new filter to our internal filter list and "restore" it - // the next time this method is called. Strangely, if the user then similarly - // adds yet another new filter, the new one becomes simply a description change - // to the previous one, the previous object is modified AND NO PROPERTY CHANGE EVENT - // IS FIRED! I could obviously deal with this situation if I wanted to, but enough - // is enough. The limit will be one alternative filter at a time. - // DPS... 9 July 2008 - - private void setChoosableFileFilters() { - // See if a new filter has been added to the master list. If so, - // regenerate the fileChooser list from the master list. - if (fileFilterCount < fileFilterList.size() || - fileFilterList.size() != fileChooser.getChoosableFileFilters().length) { - fileFilterCount = fileFilterList.size(); - // First, "deactivate" the listener, because our addChoosableFileFilter - // calls would otherwise activate it! We want it to be triggered only - // by MARS user action. - boolean activeListener = false; - if (fileChooser.getPropertyChangeListeners().length > 0) { - fileChooser.removePropertyChangeListener(listenForUserAddedFileFilter); - activeListener = true; // we'll note this, for re-activation later - } - // clear out the list and populate from our own ArrayList. - // Last one added becomes the default. - fileChooser.resetChoosableFileFilters(); - for (int i=0; i < fileFilterList.size(); i++) { - fileChooser.addChoosableFileFilter((FileFilter)fileFilterList.get(i)); - } - // Restore listener. - if (activeListener) { - fileChooser.addPropertyChangeListener(listenForUserAddedFileFilter); - } - } - }////////////////////////////////////////////////////////////////////////////////// - // Private inner class for special property change listener. DPS 9 July 2008. - // If user adds a file filter, e.g. by typing *.txt into the file text field then pressing - // Enter, then it is automatically added to the array of choosable file filters. BUT, unless you - // Cancel out of the Open dialog, it is then REMOVED from the list automatically also. Here - // we will achieve a sort of persistence at least through the current activation of MARS. - - private class ChoosableFileFilterChangeListener implements PropertyChangeListener { - public void propertyChange(java.beans.PropertyChangeEvent e) { - if (e.getPropertyName()==JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) { - FileFilter[] newFilters = (FileFilter[]) e.getNewValue(); - FileFilter[] oldFilters = (FileFilter[]) e.getOldValue(); - if (newFilters.length > fileFilterList.size()) { - // new filter added, so add to end of master list. - fileFilterList.add(newFilters[newFilters.length-1]); - } - } - } - } - - - } - - } \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/source/.indexes/af/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/source/.indexes/af/history.index deleted file mode 100644 index 5f2bf3eb4ca7c567075a0e7acee9828af78c5df6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70 zcmZQ#U|?WmP}SEfPAw_P%u6rU&o4^XOHIznEGSOZ%StKHOU^G!)hj4UO)F+#G}!*9 aJFbO6Mnrg@{Qrt=M`fB`?XF{FU;qIA<`_Ew diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/source/.indexes/d5/7d/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/source/.indexes/d5/7d/history.index index 31c6c51211d3c8fda09c526f2a4109eaa8b4db9e..16fce6a5e3bcb92704ada3440ded6578ebfc26c4 100644 GIT binary patch literal 619 zcmZQ#U|?Wkkk!vkEGpJ7OU)}S*7r>28OEe=S`OV!ItEK6h%R@mgwcx5JojBM9K z@7~TEC87rX9`%e23=Y1>bCAUu1p2_@7fxMtKo$>s*b5d9@YrmLEPmj54_N%emAS&m z;N zgCuf9yJhC2h7_ejBblY(rfM~^VcE4EU`rO*sH7u{KTLp#Gvu92LKc@{fQTPxWeq_V J|L`B;IRN)i`@jGI literal 1516 zcmYk*Ye7dS;`1*%F*6KBcF!ccr z>`xNFhrVRmvESbY&i>#IU^gvz)1HZj6$^IpJeN9YtuDl#oeFNQb){fW9_G+I&*>A7 zUEdCFT5-l=zjF&*;P@1SU8MjgVfZFeRes3{Wp1uoB~xnEa1ya#I(QTnkPQTEZAR)E<;Z@kz@CtX`*ftUJt{5uohfU ztmI+;#(A}q(xN_{go#1mz!UXI+>QUOmwzm9TKzGo0IH>;vH8WKM diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/source/.indexes/d5/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/source/.indexes/d5/history.index deleted file mode 100644 index 977c3ba5dac5b45754862f799326613f473e6bf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60 zcmZQ#U|?Wmkk-#lEGpLb1rospIf=y?!O2Cbsd;)?iDiili~^6WrPEs&WJCq7Pye1V O>rk7H(w;g-1_l5PHWLc~ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/source/.markers b/.metadata/.plugins/org.eclipse.core.resources/.projects/source/.markers index 2e55e4abfcf19a9ae53ff8dbf5d42593ec4b863e..fd413a28514eeb9534d7e9e2f29b4970f9eb5ce9 100644 GIT binary patch delta 5403 zcmZXYdstLu9>+PC_W)jIKxbgM$VI_R0?jlYyn#ZBcTv1crOsodlre!wrj}r`n^`Ho z!fzLAV@&O;fg_IDmQa?NWs8!Jr9Q?+rfo~`JiE`X*4Dn~cV=MTlh5NHeC9jf-}m=B z@B5xJ=WJ)(xvKcaYDKWq$WtnPSE(Afb;kBvuY}+~`(awzuF|JMuM7yL;0cpdS|4_m z)4olcgfY|?ewEYG+|w#;@5f7?PcO#1&KIjTp(5K_!gL!;H$5Sjkeuq}=ROu?~w_JlzV3kzw_NYXG;EcSl zMej=x9TAv1H1`ut+_g`irvn`8Sd55!4b)R9t2AZ`cG#;Oj1HMod1}$9cVS+lz#He5 zGGp&FUL1wuzfISt(d!(I*gn&MZBROZsAgM8=<2nuvb>T9#gLGBS>V|x-J$ift$e-K zMn&~@&o)@ZqVxQ@1{{aDG2ejWHB2Ms^Pz_zO)ubS0$R*kkk0o_TjN!FVj-_hqMk)< zd|by?Z9I!#;%QS2n|sX?kG3d!r!x%euU}fn(G;Y!mR;s(D$>=SAziUIVBz5tEPvo;3LpK3M5^7A&MZ*d=5$^c)iJhZc{7 z8>2TFxa>rQq$0^I?5*vQwm?pTXi!8>Bx=N$;lXxaTJ@P6bw_c@PGJLIrf^y{Fq55h z!CGsmK9^J)aXR|x8}2{ea0~3e=)2*TZe@wisakLEv3{!a_UnUoLT;y`!WW07Y94#O zW4QK+bdW{pQ%{G|>w*ef-j)vWa@V`E3acBXS2_7iEiue)k`D4}N42Pe z;JD1jHQOs)lK} zxm#r`%>PZaNen?op_D?e*P|C3TwgqJ9T8PA>F1a*t$1CLHcN2WB?~P7UbfXeB+D|Qj&sr?xIavc zr1sG=pP{EwR3l7p1$�LTQfpCOlc9XqzM`u;YTv#DC?)AM}a2)DM88KvB)n!D4e7 zeAb}+Oe(PXT1m8{8FSYB3K zvSw0buyDs!>#W%+fGe^FjZ-75ys27zBOD=|pI zR4&LgE=ZmeDs#kmI;3Bv4+*U!2mfWmSyKrniR0!B-7R7cASMM6oT&#_ZcwFIP&U{UhAL z59hMgJ?drI%dWxpTW$Jgv7gq@+m^NRHhgAk^L4x|+vbXyHb`C}spe_HGYMS)E$L!3 zEcvHg14(g0U}5b#-lf}Rg7z#D5t$VHt;q2(w@W??<^m;>=G>N99rgvE{U=#Y6`hMP z9K;aq9#);#tQ$EOBR&>Ow8yhPj7J2#7iUl})t-%gSK>*6_7vMEU#3rSVgk{gLHaoE zL71CJzT)J#ao+O~KVl);gKVG4 zeEmp&#!9sNeIJM9kK{}^7)5G1`2rlv=4jH+t8<$r6?WUm$9Nbw!*7F$4ZJC2i0E8_ zh0mq>^PKPxcqJZb@a=H&JXQ$sReGSKBm8XzxC<+PG15P>0DeGUKkr-2o7Q8a$u8_LfN95*nUI@CKIbSj z{fUY5)5%31N7gg!${=6!IQJ&I!EL$Q-$KCJjXz%i?BqjUu5B&&RT9nchJ#e_pVhq2 z2JX6tJk9m=AoScrnmJU2F@Nu89cS2*ZpkKXSf&*s(^;8s zbI1r$be8MaG;XV`JqTClo%Yw+fUS_JPF|&-H}+qN{@~W_kFpJW zi299uhAsgNZI?y0c9`-Bngr-}6sHNwHyo~pD#B{!i^>^}|AE$gr@~T6xz2khOY9Ny zaaqw1(13ZZz_vgoF?jF5k{-p7f_^Lf&tm=pagM9;5osnn=<3U`I zWWf6o7bY9W($>i$t{!SoA3*gww)(jww6#%%4Jk&Nd{l*}QVkZbLaT#WKQr9ejZ0)r z?jB+2=5?&tG}7P=Z5G!1$x#ONo2b5WmqD$)n}g2L%4ggXJdEO=H03o zw{sAFw?VAEo&%d*Y3H2r{T!q_6#ecQSc3R|4sz~M^s_jC@dX{sa~dih!+6WaC?E6j zv^R9HQdLfJC67bLY&O>WG8O$W44C`SW#w4qWA;P0IT&RTkrjJub38F(n z&A2^^8MaSQDwyx~AExT3phIS#sgN~MxxiBNVelj}d}zG#g7*8FsVDc^T6|eq%E06Q E2kJOpAOHXW delta 4595 zcmZWreNa@_72mh--N&xVryz?c282ZX1m%GmKo>y?0t$Z6v`JH}Hrh#5OvWUQDMCe? zQVrx)PSvWcu|XQYaDhz>!JtMlQ39!H{D28N8f-gl3^Ptr$8@Imo%i1E-pkJHKfn9C zzjMy-o_o*xv}(eYyRoNhWFZo~uS@A_hrC^F{EKAEwcsyO?J85$*Ms`i!6ZKjecL2O z-ETwGZc;%s=6 z(^eqbQFMdxeWlw~Jci9_6%xN$R>y2#jp(`MSeCHXJ@c9D(e&ML6-r82?>{U-KVM(I zC2!+etHsj$5UTEzD0RxFMog>DxB%-kg|I;q$Q=xaiZQ}ob>_nud#6c+iaer(4LTTN zvME}t7H^1Rgr7&@JG%n;cmANZZot>fZpyAl+P!xJY4@(HHNW&~h1yISgb&e@EU|$! z%Or43mo|>_rC5%49A@4TLWGxL_#Nvr@R3V&_z7#&;TM$96@eo5XZH?^+hAdw)e%r@ zeWyqb>@nx!a zn*xO`hK?`ra;UmX6qtQR{1Ud`5hZ^BtzDtOEnY|5x1m%G?^obwt>PCfjx7sY+r-~v zU@^;*3ibP?v7Yhm;@P)6U1icC!PAp3{U-#DSwae+y=j+bn(v{e3=#?1kPSBH2tn4BI3HvQi1PF(N>xQEPB0olP#WxC`-r zC-8BPAZ|}2-N^Ur_uUl~h)Cl3N7ah!iYMi95+`7yz71;EX$9VVf_%>EsPShMI5LIY z)Nbo}Gy5iRZK5`Om`wV$x6Fq_xs`U`t*Ly}X3X;YX*_;_;tE8~Ab*GDuMkNX4^;`o z0m>XQky_msNiBMBz#0ne8RRAO&pyHM`(51m#vEg(&BWF4a|$%3kv%N^1Rl?3#mLuW zgUd$q-JMQu60M90o>_Cr9>MB(5A#jTG-cwAsPAj;!Glb44a+uRD2bvn)@<@Qx@5v1 zc)ZypSYWUYaDG9ZOIb*6F!+ZU@hK;{sQYhfsLqQD6z7l{y&e;8(Jw~SB2vvRoY5Du zPm*95T0~xCSKa8^fn4$l`fWGmTG5`SJkrM`)rQS`b}_le!0iY>n8&d_2nRh$`q9jI z{aU(~kS38Hrni8WegBFO3Lh7lhnZ;DdI8gVt(f%cX_@#%{Sm5MYM5o>AM5zOLL*cn zgwK$oU~>tPJR6pg$yTeQTlXQhQmV0^pK8Q`zRC2Qc9xRQ^f)H|2?*cPK7Y4Zss0fjNz-sL#R-<7GoC=k{Vi$Ho{1obbZ$GkB-B@=1gs6)?`QKWO`1wW8qd~;tzF^i&Cr!fyJ&2>(O!O=aiGr0;5TTq zGz~K6^0whDeRdvCKY{dL%r`E*Uml0)i%-fuY~P+jesw0FKaRHAES}zi^!?eg@nvMb zA7>ChwLsRtP<*#un`voqej%^Zig=%sPrnWETRF1vg=OluBko-!pJmhcfOjdib0AmN zpKo7a{UgDfM}@RUQQT*l11(GBSkINkat{aQpuOT*CW1 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/source/org.eclipse.jdt.core/state.dat b/.metadata/.plugins/org.eclipse.core.resources/.projects/source/org.eclipse.jdt.core/state.dat index aacf05912cbd0c4c796c1c6eae73b21895552ebf..7233aa93c3f04cf1598e5bd738eb0f638eaf63b4 100644 GIT binary patch delta 11139 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 this use of "getMenuShortcutKeyMask"; it is deprecated.(ÙÏ…ÉH­bRMINORZ CODE_SMELL -~ java:S116R"NRename this field "Cut" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ÒƒÒ¨ýÿÿÿÿHï!RMINORZ +u +java:S5738°"HRemove this call to a deprecated method, it has been marked for removal.(—Õª·H®bRMAJORZ CODE_SMELL - java:S116R"ORename this field "Copy" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ÒƒÒ¨ýÿÿÿÿHð!RMINORZ +z +java:S5738•"HRemove this call to a deprecated method, it has been marked for removal.(¦Üÿ²ýÿÿÿÿH¯bRMAJORZ CODE_SMELL -€ java:S116R"PRename this field "Paste" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ÒƒÒ¨ýÿÿÿÿHñ!RMINORZ +o +java:S1948e"@Make "settingsDelayedBranchingAction" transient or serializable.(ÿ”È­H°bRCRITICALZ CODE_SMELL -† java:S116R"VRename this field "FindReplace" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ÒƒÒ¨ýÿÿÿÿHò!RMINORZ +ƒ +java:S1450I"WRemove the "editCopy" field and declare it as a local variable in the relevant methods.(ƒçíöH±bRMINORZ CODE_SMELL -„ java:S116R"TRename this field "SelectAll" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ÒƒÒ¨ýÿÿÿÿHó!RMINORZ +b +java:S1948`"3Make "runBackstepAction" transient or serializable.(ùüßÐH²bRCRITICALZ CODE_SMELL -~ java:S116S"NRename this field "New" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ûä¿ûÿÿÿÿHô!RMINORZ +ƒ +java:S1450S"RRemove the "New" field and declare it as a local variable in the relevant methods.(Ûä¿ûÿÿÿÿH³bRMINORZ CODE_SMELL - java:S116S"ORename this field "Open" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ûä¿ûÿÿÿÿHõ!RMINORZ +z +java:S5738ü"HRemove this call to a deprecated method, it has been marked for removal.(™ †ÛýÿÿÿÿH´bRMAJORZ CODE_SMELL - java:S116S"ORename this field "Save" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ûä¿ûÿÿÿÿHö!RMINORZ +e +java:S1948g"1Make "helpAboutAction" transient or serializable.( ã¹ŒýÿÿÿÿHµbRCRITICALZ CODE_SMELL - java:S116S"QRename this field "SaveAs" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ûä¿ûÿÿÿÿH÷!RMINORZ +m java:S125£"Use isEmpty() to check whether the collection is empty or not.(ÜôÎíHÃbRMINORZ CODE_SMELL -} -java:S1845T"JRename field "Run" to prevent any misunderstanding/clash with field "run".(Çý˜úÿÿÿÿHƒ"RBLOCKERZ +g java:S125¨"Make "settingsAssembleOnOpenAction" transient or serializable.(¡ÛɈHëbRCRITICALZ CODE_SMELL -ˆ -java:S1450T"WRemove the "Backstep" field and declare it as a local variable in the relevant methods.(Çý˜úÿÿÿÿHÎ#RMINORZ +– +java:S1450L"eRemove the "settingsAssembleOnOpen" field and declare it as a local variable in the relevant methods.(çíλýÿÿÿÿHìbRMINORZ CODE_SMELL „ -java:S1450R"SRemove the "Copy" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿHÏ#RMINORZ +java:S1450O"XRemove the "helpAbout" field and declare it as a local variable in the relevant methods.(¾ßó£HíbRMINORZ CODE_SMELL -ƒ -java:S1450R"RRemove the "Cut" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿHÐ#RMINORZ +˜ +java:S1450M"gRemove the "settingsProgramArguments" field and declare it as a local variable in the relevant methods.(—‹ÌäýÿÿÿÿHîbRMINORZ CODE_SMELL -Š -java:S1450S"YRemove the "DumpMemory" field and declare it as a local variable in the relevant methods.(Ûä¿ûÿÿÿÿHÑ#RMINORZ +^ +java:S1948\"0Make "fileExitAction" transient or serializable.(¤ÕñpHïbRCRITICALZ CODE_SMELL -‹ -java:S1450R"ZRemove the "FindReplace" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿHÒ#RMINORZ +N +java:S2129ó"!Remove this "Integer" constructor(ôÈ‚ÛHðbRMAJORZ CODE_SMELL - -java:S1450U"SRemove the "Help" field and declare it as a local variable in the relevant methods.(€ú¢ÚHÓ#RMINORZ +N +java:S2129é"!Remove this "Integer" constructor(Àù¾¿HñbRMAJORZ CODE_SMELL -ƒ -java:S1450S"RRemove the "New" field and declare it as a local variable in the relevant methods.(Ûä¿ûÿÿÿÿHÔ#RMINORZ +_ +java:S1948\"1Make "filePrintAction" transient or serializable.(¤ÕñpHòbRCRITICALZ CODE_SMELL -„ -java:S1450S"SRemove the "Open" field and declare it as a local variable in the relevant methods.(Ûä¿ûÿÿÿÿHÕ#RMINORZ +z +java:S5738Î"HRemove this call to a deprecated method, it has been marked for removal.(òëÛûýÿÿÿÿHóbRMAJORZ CODE_SMELL -… -java:S1450R"TRemove the "Paste" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿHÖ#RMINORZ + +java:S1450N"cRemove the "settingsHighlighting" field and declare it as a local variable in the relevant methods.(Õ—Û’HôbRMINORZ CODE_SMELL -… -java:S1450T"TRemove the "Pause" field and declare it as a local variable in the relevant methods.(Çý˜úÿÿÿÿH×#RMINORZ +‡ +java:S1450H"[Remove the "fileCloseAll" field and declare it as a local variable in the relevant methods.(и«ðHõbRMINORZ CODE_SMELL -… -java:S1450S"TRemove the "Print" field and declare it as a local variable in the relevant methods.(Ûä¿ûÿÿÿÿHØ#RMINORZ +^ +java:S1659g"-Declare "helpAboutAction" on a separate line.( ã¹ŒýÿÿÿÿHöbRMINORZ CODE_SMELL -„ -java:S1450R"SRemove the "Redo" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿHÙ#RMINORZ + +java:S1450U"SRemove the "Help" field and declare it as a local variable in the relevant methods.(€ú¢ÚHøbRMINORZ CODE_SMELL -… -java:S1450T"TRemove the "Reset" field and declare it as a local variable in the relevant methods.(Çý˜úÿÿÿÿHÚ#RMINORZ +p +java:S1874§">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(鉔ŽûÿÿÿÿHùbRMINORZ CODE_SMELL -ƒ -java:S1450T"RRemove the "Run" field and declare it as a local variable in the relevant methods.(Çý˜úÿÿÿÿHÛ#RMINORZ +s +java:S5738Ó"HRemove this call to a deprecated method, it has been marked for removal.(§úHúbRMAJORZ CODE_SMELL -„ -java:S1450S"SRemove the "Save" field and declare it as a local variable in the relevant methods.(Ûä¿ûÿÿÿÿHÜ#RMINORZ +h java:S125‘"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ß®œÚúÿÿÿÿH§dRMINORZ CODE_SMELL -g -java:S1948c"8Make "settingsExtendedAction" transient or serializable.(¡ÛɈH®$RCRITICALZ +\ +java:S3740Ô"/Provide the parametrized type for this generic.(”äÃH¨dRMAJORZ CODE_SMELL -m -java:S1948c">Make "settingsAssembleOnOpenAction" transient or serializable.(¡ÛɈH¯$RCRITICALZ +‚ java:S116S"RRename this field "SaveAll" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ûä¿ûÿÿÿÿH©dRMINORZ CODE_SMELL -j -java:S1948c";Make "settingsAssembleAllAction" transient or serializable.(¡ÛɈH°$RCRITICALZ +z +java:S5738Ø"HRemove this call to a deprecated method, it has been marked for removal.(ºµÍªþÿÿÿÿHªdRMAJORZ CODE_SMELL -p -java:S1948d"AMake "settingsWarningsAreErrorsAction" transient or serializable.(Ú—â„H±$RCRITICALZ +„ +java:S1450G"SRemove the "file" field and declare it as a local variable in the relevant methods.(ÛÏΰûÿÿÿÿH«dRMINORZ CODE_SMELL -j -java:S1948d";Make "settingsStartAtMainAction" transient or serializable.(Ú—â„H²$RCRITICALZ +ƒ java:S116T"SRename this field "Assemble" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Çý˜úÿÿÿÿH¬dRMINORZ CODE_SMELL -o -java:S1948d"@Make "settingsProgramArgumentsAction" transient or serializable.(Ú—â„H³$RCRITICALZ +– +java:S1450N"jRemove the "settingsMemoryConfiguration" field and declare it as a local variable in the relevant methods.(Õ—Û’H­dRMINORZ CODE_SMELL -o -java:S1948e"@Make "settingsDelayedBranchingAction" transient or serializable.(ÿ”È­H´$RCRITICALZ +ƒ java:S116T"SRename this field "Backstep" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Çý˜úÿÿÿÿH®dRMINORZ CODE_SMELL -o -java:S1948e"@Make "settingsExceptionHandlerAction" transient or serializable.(ÿ”È­Hµ$RCRITICALZ +W +java:S1948D"(Make "editor" transient or serializable.(ó‰ŒæH¯dRCRITICALZ CODE_SMELL -e -java:S1948e"6Make "settingsEditorAction" transient or serializable.(ÿ”È­H¶$RCRITICALZ +s +java:S5738Œ"HRemove this call to a deprecated method, it has been marked for removal.(ŽñIH°dRMAJORZ CODE_SMELL -j -java:S1948f"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(×ëËèH³dRMINORZ CODE_SMELL -d -java:S1948g"0Make "helpHelpAction" transient or serializable.( ã¹ŒýÿÿÿÿHº$RCRITICALZ +Z +java:S1125"(Remove the unnecessary boolean literals.(‘ÞàšýÿÿÿÿH´dRMINORZ CODE_SMELL -e -java:S1948g"1Make "helpAboutAction" transient or serializable.( ã¹ŒýÿÿÿÿH»$RCRITICALZ +„ +java:S1450R"SRemove the "Undo" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿH·dRMINORZ CODE_SMELL -h java:S125…"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(…¥Ä÷H»dRMINORZ CODE_SMELL -g java:S125¨"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(à˜¦H¾dRMINORZ CODE_SMELL r -java:S3252Ï"=Use static access with "java.awt.Frame" for "MAXIMIZED_BOTH".(½ç³‚úÿÿÿÿHÃ$RCRITICALZ +java:S3252Ï"=Use static access with "java.awt.Frame" for "MAXIMIZED_BOTH".(½ç³‚úÿÿÿÿH¿dRCRITICALZ CODE_SMELL -l -java:S1161×":Add the "@Override" annotation above this method signature(ž†§þýÿÿÿÿHÅ$RMAJORZ +d +java:S1948b"5Make "settingsLabelAction" transient or serializable.(Ó¿’HÁdRCRITICALZ CODE_SMELL -N -java:S2129ó"!Remove this "Integer" constructor(ôÈ‚ÛHÇ$RMAJORZ +h java:S125‰"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ãªÈÂÿÿÿÿÿHÃdRMINORZ CODE_SMELL -k -java:S1874ô">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(…¥Ä÷HÉ$RMINORZ +„ +java:S1450R"SRemove the "Redo" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿHÄdRMINORZ CODE_SMELL -N -java:S2129ø"!Remove this "Integer" constructor(çÍ”ÕHÊ$RMAJORZ +o +java:S1874Ó"=Remove this use of "getAssembleAllEnabled"; it is deprecated.(¼‡ëÿÿÿÿÿHÅdRMINORZ CODE_SMELL -u -java:S5738ø"HRemove this call to a deprecated method, it has been marked for removal.(çÍ”ÕHË$RMAJORZ +W +java:S1128"+Remove this unused import 'mars.mips.dump'.(ø¤ü×HÆdRMINORZ CODE_SMELL -k -java:S1874ù">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(‚êôHÌ$RMINORZ +j +java:S1948d";Make "settingsStartAtMainAction" transient or serializable.(Ú—â„HÈdRCRITICALZ CODE_SMELL -S -java:S2129ü"!Remove this "Integer" constructor(™ †ÛýÿÿÿÿHÍ$RMAJORZ +m java:S125“"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ñ†œüÿÿÿÿHÏ$RMINORZ +q +java:S1659I"EDeclare "editRedo" and all following declarations on a separate line.(ƒçíöHËdRMINORZ CODE_SMELL -S -java:S2129€"!Remove this "Integer" constructor(¿ï·°úÿÿÿÿHÐ$RMAJORZ + java:S116S"QRename this field "SaveAs" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ûä¿ûÿÿÿÿH×dRMINORZ CODE_SMELL z -java:S5738€"HRemove this call to a deprecated method, it has been marked for removal.(¿ï·°úÿÿÿÿHÑ$RMAJORZ +java:S5738˜"HRemove this call to a deprecated method, it has been marked for removal.(ËçöˆùÿÿÿÿHØdRMAJORZ CODE_SMELL -S -java:S2129„"!Remove this "Integer" constructor(ºÊÐëÿÿÿÿÿHÒ$RMAJORZ +\ +java:S3740ï"/Provide the parametrized type for this generic.(”äÃHÙdRMAJORZ CODE_SMELL -z -java:S5738„"HRemove this call to a deprecated method, it has been marked for removal.(ºÊÐëÿÿÿÿÿHÓ$RMAJORZ +† java:S116R"VRename this field "FindReplace" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ÒƒÒ¨ýÿÿÿÿHÚdRMINORZ CODE_SMELL -k -java:S1874…">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(½ä·‡HÔ$RMINORZ +… +java:S1450J"TRemove the "runGo" field and declare it as a local variable in the relevant methods.(·…›‡ùÿÿÿÿHÛdRMINORZ CODE_SMELL -S -java:S2129‰"!Remove this "Integer" constructor(…¶ôþÿÿÿÿHÕ$RMAJORZ +~ java:S116S"NRename this field "New" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ûä¿ûÿÿÿÿHÜdRMINORZ CODE_SMELL -z -java:S5738‰"HRemove this call to a deprecated method, it has been marked for removal.(…¶ôþÿÿÿÿHÖ$RMAJORZ +b +java:S1948`"3Make "runAssembleAction" transient or serializable.(ùüßÐHÝdRCRITICALZ CODE_SMELL -L -java:S2129Œ"!Remove this "Integer" constructor(ŽñIH×$RMAJORZ +m +java:S1874Ñ"@Remove this use of "getAssembleOnOpenEnabled"; it is deprecated.(Ö€—èHÞdRMINORZ CODE_SMELL -s -java:S5738Œ"HRemove this call to a deprecated method, it has been marked for removal.(ŽñIHØ$RMAJORZ +f +java:S2696è"6Make the enclosing method "static" or remove this set.(˺¢¸HßdRCRITICALZ CODE_SMELL -S -java:S2129"!Remove this "Integer" constructor(ï‰ò›ûÿÿÿÿHÙ$RMAJORZ +™ +java:S1450L"hRemove the "settingsWarningsAreErrors" field and declare it as a local variable in the relevant methods.(çíλýÿÿÿÿHàdRMINORZ CODE_SMELL z -java:S5738"HRemove this call to a deprecated method, it has been marked for removal.(ï‰ò›ûÿÿÿÿHÚ$RMAJORZ -CODE_SMELL -p -java:S1874‘">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ãªÈÂÿÿÿÿÿHÛ$RMINORZ +java:S5738€"HRemove this call to a deprecated method, it has been marked for removal.(¿ï·°úÿÿÿÿHádRMAJORZ CODE_SMELL S -java:S2129•"!Remove this "Integer" constructor(¦Üÿ²ýÿÿÿÿHÜ$RMAJORZ +java:S2129˜"!Remove this "Integer" constructor(ËçöˆùÿÿÿÿHâdRMAJORZ CODE_SMELL -z -java:S5738•"HRemove this call to a deprecated method, it has been marked for removal.(¦Üÿ²ýÿÿÿÿHÝ$RMAJORZ +k +java:S1874¢">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(‰á˜ÚHãdRMINORZ CODE_SMELL -S -java:S2129˜"!Remove this "Integer" constructor(ËçöˆùÿÿÿÿHÞ$RMAJORZ +q +java:S1659G"@Declare "run" and all following declarations on a separate line.(ÛÏΰûÿÿÿÿHädRMINORZ CODE_SMELL -z -java:S5738˜"HRemove this call to a deprecated method, it has been marked for removal.(ËçöˆùÿÿÿÿHß$RMAJORZ +S +java:S2129„"!Remove this "Integer" constructor(ºÊÐëÿÿÿÿÿHîdRMAJORZ CODE_SMELL S -java:S2129œ"!Remove this "Integer" constructor(óí¥ôÿÿÿÿÿHà$RMAJORZ +java:S2129Ý"!Remove this "Integer" constructor(ˆ³ë²þÿÿÿÿHïdRMAJORZ CODE_SMELL -z -java:S5738œ"HRemove this call to a deprecated method, it has been marked for removal.(óí¥ôÿÿÿÿÿHá$RMAJORZ +r +java:S1659S"ADeclare "Open" and all following declarations on a separate line.(Ûä¿ûÿÿÿÿHðdRMINORZ CODE_SMELL -k -java:S1874">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(à˜¦Hâ$RMINORZ +ˆ +java:S1450T"WRemove the "Backstep" field and declare it as a local variable in the relevant methods.(Çý˜úÿÿÿÿHüdRMINORZ CODE_SMELL -S -java:S2129¡"!Remove this "Integer" constructor(ûÓÄéüÿÿÿÿHã$RMAJORZ +„ +java:S1450I"XRemove the "editPaste" field and declare it as a local variable in the relevant methods.(ƒçíöHýdRMINORZ CODE_SMELL z -java:S5738¡"HRemove this call to a deprecated method, it has been marked for removal.(ûÓÄéüÿÿÿÿHä$RMAJORZ -CODE_SMELL -k -java:S1874¢">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(‰á˜ÚHå$RMINORZ +java:S1845U"LRename field "Help" to prevent any misunderstanding/clash with field "help".(€ú¢ÚHþdRBLOCKERZ CODE_SMELL -S -java:S2129¦"!Remove this "Integer" constructor(ï†ÓÛüÿÿÿÿHæ$RMAJORZ +„ +java:S1450R"SRemove the "Copy" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿH€eRMINORZ CODE_SMELL -z -java:S5738¦"HRemove this call to a deprecated method, it has been marked for removal.(ï†ÓÛüÿÿÿÿHç$RMAJORZ +ƒ +java:S1450H"WRemove the "fileSave" field and declare it as a local variable in the relevant methods.(и«ðHeRMINORZ CODE_SMELL -p -java:S1874§">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(鉔ŽûÿÿÿÿHè$RMINORZ +Š +java:S1450I"^Remove the "editFindReplace" field and declare it as a local variable in the relevant methods.(ƒçíöH‚eRMINORZ CODE_SMELL -N -java:S2129«"!Remove this "Integer" constructor(®ŸÍÄHé$RMAJORZ + java:S116R"ORename this field "Undo" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ÒƒÒ¨ýÿÿÿÿHƒeRMINORZ CODE_SMELL -u -java:S5738«"HRemove this call to a deprecated method, it has been marked for removal.(®ŸÍÄHê$RMAJORZ + +java:S1845T"NRename field "Reset" to prevent any misunderstanding/clash with field "reset".(Çý˜úÿÿÿÿH„eRBLOCKERZ CODE_SMELL -k -java:S1874¬">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(þ¤£›Hë$RMINORZ +˜ +java:S1450M"gRemove the "settingsDelayedBranching" field and declare it as a local variable in the relevant methods.(—‹ÌäýÿÿÿÿH†eRMINORZ CODE_SMELL N -java:S2129°"!Remove this "Integer" constructor(—Õª·Hì$RMAJORZ +java:S2129¿"!Remove this "Integer" constructor(ˆêÇØH‡eRMAJORZ CODE_SMELL -u -java:S5738°"HRemove this call to a deprecated method, it has been marked for removal.(—Õª·Hí$RMAJORZ +N +java:S2129º"!Remove this "Integer" constructor(ÄÚ†åHˆeRMAJORZ CODE_SMELL -p -java:S1874±">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ðëýÌøÿÿÿÿHî$RMINORZ +` +java:S1144… "3Remove this unused private "setupPopupMenu" method.(ÏéùÛH‰eRMAJORZ CODE_SMELL -S -java:S2129µ"!Remove this "Integer" constructor(ý½‹æûÿÿÿÿHï$RMAJORZ +d +java:S1948_"5Make "editSelectAllAction" transient or serializable.(ÿÑÑ·H‹eRCRITICALZ CODE_SMELL -z -java:S5738µ"HRemove this call to a deprecated method, it has been marked for removal.(ý½‹æûÿÿÿÿHð$RMAJORZ +m java:S125Ã"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(“ÖÂùÿÿÿÿHñ$RMINORZ +java:S1874¶">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(“ÖÂùÿÿÿÿHeRMINORZ CODE_SMELL -N -java:S2129º"!Remove this "Integer" constructor(ÄÚ†åHò$RMAJORZ +m java:S125‹"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(×ëËèHô$RMINORZ +€ java:S116R"PRename this field "Paste" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ÒƒÒ¨ýÿÿÿÿHeRMINORZ CODE_SMELL -N -java:S2129¿"!Remove this "Integer" constructor(ˆêÇØHõ$RMAJORZ +_ +java:S1948`"0Make "runResetAction" transient or serializable.(ùüßÐH‘eRCRITICALZ CODE_SMELL -u -java:S5738¿"HRemove this call to a deprecated method, it has been marked for removal.(ˆêÇØHö$RMAJORZ +p +java:S1874±">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ðëýÌøÿÿÿÿH’eRMINORZ CODE_SMELL -N -java:S2129Ä"!Remove this "Integer" constructor(бÊñH÷$RMAJORZ +a +java:S1948\"3Make "fileSaveAllAction" transient or serializable.(¤ÕñpH“eRCRITICALZ CODE_SMELL -u -java:S5738Ä"HRemove this call to a deprecated method, it has been marked for removal.(бÊñHø$RMAJORZ +q +java:S1948f"CMake "settingsMemoryConfigurationAction" transient or serializable.(ðÚ‹4H”eRCRITICALZ CODE_SMELL -M -java:S2129É"!Remove this "Integer" constructor(çêÛ^Hù$RMAJORZ +S +java:S2129•"!Remove this "Integer" constructor(¦Üÿ²ýÿÿÿÿH•eRMAJORZ CODE_SMELL -t -java:S5738É"HRemove this call to a deprecated method, it has been marked for removal.(çêÛ^Hú$RMAJORZ +m +java:S1874Ù";Remove this use of "getProgramArguments"; it is deprecated.(ŽÊóÿüÿÿÿÿH–eRMINORZ CODE_SMELL -S -java:S2129Î"!Remove this "Integer" constructor(òëÛûýÿÿÿÿHû$RMAJORZ +ƒ +java:S1450R"RRemove the "Cut" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿH—eRMINORZ CODE_SMELL -z -java:S5738Î"HRemove this call to a deprecated method, it has been marked for removal.(òëÛûýÿÿÿÿHü$RMAJORZ +e +java:S1948e"6Make "settingsEditorAction" transient or serializable.(ÿ”È­H˜eRCRITICALZ CODE_SMELL -L -java:S2129Ó"!Remove this "Integer" constructor(§úHý$RMAJORZ +j java:S106…"9Replace this use of System.out or System.err by a logger.(ÄæÒ¨ûÿÿÿÿH™eRMAJORZ CODE_SMELL -s -java:S5738Ó"HRemove this call to a deprecated method, it has been marked for removal.(§úHþ$RMAJORZ +~ java:S116T"NRename this field "Run" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Çý˜úÿÿÿÿHšeRMINORZ CODE_SMELL -S -java:S2129Ø"!Remove this "Integer" constructor(ºµÍªþÿÿÿÿHÿ$RMAJORZ +_ +java:S1948["0Make "fileSaveAction" transient or serializable.(»â·¼H›eRCRITICALZ CODE_SMELL -z -java:S5738Ø"HRemove this call to a deprecated method, it has been marked for removal.(ºµÍªþÿÿÿÿH€%RMAJORZ +k +java:S1874¬">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(þ¤£›HœeRMINORZ CODE_SMELL -S -java:S2129Ý"!Remove this "Integer" constructor(ˆ³ë²þÿÿÿÿH%RMAJORZ +† +java:S1450H"ZRemove the "fileSaveAll" field and declare it as a local variable in the relevant methods.(и«ðHeRMINORZ CODE_SMELL -z -java:S5738Ý"HRemove this call to a deprecated method, it has been marked for removal.(ˆ³ë²þÿÿÿÿH‚%RMAJORZ +ƒ +java:S1450I"WRemove the "editRedo" field and declare it as a local variable in the relevant methods.(ƒçíöHžeRMINORZ +CODE_SMELL +ˆ +java:S1450T"WRemove the "Assemble" field and declare it as a local variable in the relevant methods.(Çý˜úÿÿÿÿHŸeRMINORZ CODE_SMELL N -java:S2129ã"!Remove this "Integer" constructor(ˆä‚Hƒ%RMAJORZ +java:S2129ã"!Remove this "Integer" constructor(ˆä‚H eRMAJORZ CODE_SMELL -u -java:S5738ã"HRemove this call to a deprecated method, it has been marked for removal.(ˆä‚H„%RMAJORZ +h java:S125ô"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ß®œÚúÿÿÿÿH…%RMINORZ +ƒ +java:S1450T"RRemove the "Run" field and declare it as a local variable in the relevant methods.(Çý˜úÿÿÿÿH¢eRMINORZ CODE_SMELL -N -java:S2129é"!Remove this "Integer" constructor(Àù¾¿H†%RMAJORZ +“ +java:S1450N"gRemove the "settingsExceptionHandler" field and declare it as a local variable in the relevant methods.(Õ—Û’H£eRMINORZ CODE_SMELL -u -java:S5738é"HRemove this call to a deprecated method, it has been marked for removal.(Àù¾¿H‡%RMAJORZ +t +java:S1659`"HDeclare "runGoAction" and all following declarations on a separate line.(ùüßÐH¤eRMINORZ +CODE_SMELL +i +java:S1948b":Make "settingsPopupInputAction" transient or serializable.(Ó¿’H´eRCRITICALZ CODE_SMELL k -java:S1874ê">Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ÙÏ…ÉHˆ%RMINORZ +java:S1948a"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(½ä·‡HÌeRMINORZ CODE_SMELL -m java:S125§"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(ñ†œüÿÿÿÿHàeRMINORZ CODE_SMELL -m java:S125­"".Remove this unused "frameState" private field.(ÈÅ̾üÿÿÿÿHéeRMAJORZ CODE_SMELL -m -java:S1874Ñ"@Remove this use of "getAssembleOnOpenEnabled"; it is deprecated.(Ö€—èH¡%RMINORZ +N +java:S2129«"!Remove this "Integer" constructor(®ŸÍÄHëeRMAJORZ CODE_SMELL -o -java:S1874Ó"=Remove this use of "getAssembleAllEnabled"; it is deprecated.(¼‡ëÿÿÿÿÿH¢%RMINORZ +z java:S116U"ORename this field "Help" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(€ú¢ÚHìeRMINORZ CODE_SMELL -i -java:S1874Õ"Remove this use of "getMenuShortcutKeyMask"; it is deprecated.(‚êôHïeRMINORZ CODE_SMELL -h java:S125ô"Use isEmpty() to check whether the collection is empty or not.(ÜôÎíHõeRMINORZ CODE_SMELL -W -java:S1128"+Remove this unused import 'mars.mips.dump'.(ø¤ü×H°%RMINORZ +… +java:S1450R"TRemove the "Paste" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿHøeRMINORZ CODE_SMELL -_ -java:S1128".Remove this unused import 'javax.swing.event'.(œë»ŽúÿÿÿÿH²%RMINORZ +u +java:S5738«"HRemove this call to a deprecated method, it has been marked for removal.(®ŸÍÄHùeRMAJORZ CODE_SMELL -O -java:S1128"$Remove this unused import 'java.io'.(¬›ãDH´%RMINORZ +‰ +java:S1450R"XRemove the "SelectAll" field and declare it as a local variable in the relevant methods.(ÒƒÒ¨ýÿÿÿÿHúeRMINORZ CODE_SMELL -_ -java:S1068>".Remove this unused "frameState" private field.(ÈÅ̾üÿÿÿÿH¶%RMAJORZ +^ +java:S1948`"/Make "runStepAction" transient or serializable.(ùüßÐHûeRCRITICALZ CODE_SMELL -[ -java:S1068G"*Remove this unused "window" private field.(ÛÏΰûÿÿÿÿH¸%RMAJORZ +t +java:S1874Í"BRemove this use of "getDelayedBranchingEnabled"; it is deprecated.(ØÖâÆûÿÿÿÿHüeRMINORZ CODE_SMELL -\ -java:S1068S"+Remove this unused "SaveAll" private field.(Ûä¿ûÿÿÿÿHº%RMAJORZ +_ +java:S1128".Remove this unused import 'javax.swing.event'.(œë»ŽúÿÿÿÿHýeRMINORZ CODE_SMELL -` -java:S1144… "3Remove this unused private "setupPopupMenu" method.(ÏéùÛH¼%RMAJORZ +ƒ +java:S1450I"WRemove the "editUndo" field and declare it as a local variable in the relevant methods.(ƒçíöHÿeRMINORZ CODE_SMELL ~ -java:S1192é"NDefine a constant instead of duplicating this literal "MyBlank16.gif" 8 times.(ÁðÓÎH¾%RCRITICALZ +java:S1192é"NDefine a constant instead of duplicating this literal "MyBlank16.gif" 8 times.(ÁðÓÎH€fRCRITICALZ CODE_SMELL -k -java:S1155€">Use isEmpty() to check whether the collection is empty or not.(ÜôÎíHÇ%RMINORZ + java:S116S"ORename this field "Save" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ûä¿ûÿÿÿÿH‰fRMINORZ CODE_SMELL -k -java:S1155Â">Use isEmpty() to check whether the collection is empty or not.(ÜôÎíHÊ%RMINORZ +N +java:S2129°"!Remove this "Integer" constructor(—Õª·HŠfRMAJORZ CODE_SMELL -| -java:S11043"PMake menu a static final constant or non-public and provide accessors if needed.(¶´Ð—HÍ%RMINORZ +„ +java:S1450H"XRemove the "fileClose" field and declare it as a local variable in the relevant methods.(и«ðH‹fRMINORZ +CODE_SMELL +„ +java:S1450S"SRemove the "Save" field and declare it as a local variable in the relevant methods.(Ûä¿ûÿÿÿÿHŒfRMINORZ CODE_SMELL \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/source/org.sonarlint.eclipse.core/issues/3/a/3af9e2743710c60c846aa60276509696a3b79be9 b/.metadata/.plugins/org.eclipse.core.resources/.projects/source/org.sonarlint.eclipse.core/issues/3/a/3af9e2743710c60c846aa60276509696a3b79be9 new file mode 100644 index 0000000..99876e2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.projects/source/org.sonarlint.eclipse.core/issues/3/a/3af9e2743710c60c846aa60276509696a3b79be9 @@ -0,0 +1,67 @@ + +‹ +java:S2293…"YReplace the type specification in this constructor call with the diamond operator ("<>").(–²òûÿÿÿÿH²fRMINORZ +CODE_SMELL +R +java:S16591"!Declare "run" on a separate line.(ò¼›ùÿÿÿÿHfRMINORZ +CODE_SMELL +t java:S125«"2jFtMQ)S5!s*zS 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 O6*Eg7P5hdk1g7@2_9`dW16$Oyk(4(Cz3G0ooa6 znqg{|IWo-AQC~a0oM@I|S>29D0kadJ9A76aMBq`9W`I&35Kal=NkTJ+GqFhWbLw=O z5{5ZR;u?SJbL1rq9MkUE=Fl*P{eeAbjQ7D6VR@j;Zm1z+*HT4dRrC;X28$}a#{2W! zvV$NkUgvH0y2yeSZ(F**VSy=!DMzj#)CX2oZ9rv9VN-K{&WHPr)rUNx{HO!NAhW(9p`zc=Bx~gNey{TqcHQ21e$_MkWT6KQKy8 z&Sv49Je$#ZvK}+%#HX^8W0|=p?pK^Fz`{CNkV$TG9FrBNzFtXDYN{>Jgagbvrn#Ok)52(tPVC@mNgpHU}nA2%*h3;5&)RMHI)DW diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.papyrus.infra.emf.1 b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.papyrus.infra.emf.1 new file mode 100644 index 0000000..04fec89 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.papyrus.infra.emf.1 @@ -0,0 +1,2 @@ +#safe table +#Tue Mar 01 21:01:35 CST 2022 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.theming.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.theming.ui.prefs index 9e23a96..20eb53d 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.theming.ui.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.genuitec.eclipse.theming.ui.prefs @@ -3,7 +3,7 @@ approved.defs.file.last.changed.time=1624986146000 configurationInstallLocation=/C\:/Users/holde/eclipse/java-2021-12/eclipse/ eclipse.preferences.version=1 iconcolormode=primary -last.download.attempt.time=1644159198775 -lastConfiguration=1644159193912 +last.download.attempt.time=1646189140757 +lastConfiguration=1646189134821 newinstall=true workbench.theme=Dark Gray diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.debug.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.debug.core.prefs new file mode 100644 index 0000000..223c6da --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.debug.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.cdt.debug.core.cDebug.default_source_containers=\r\n\r\n \r\n \r\n \r\n \r\n \r\n\r\n diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.make.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.make.ui.prefs deleted file mode 100644 index 8f9a5b4..0000000 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.make.ui.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.cdt.make.ui.editor.comment=199,221,12 -org.eclipse.cdt.make.ui.editor.default=216,216,216 -org.eclipse.cdt.make.ui.editor.function=255,255,255 -org.eclipse.cdt.make.ui.editor.keyword=141,203,226 -org.eclipse.cdt.make.ui.editor.macro_def=190,214,255 -org.eclipse.cdt.make.ui.editor.macro_ref=190,214,255 -overriddenByCSS=,org.eclipse.cdt.make.ui.editor.comment,org.eclipse.cdt.make.ui.editor.macro_ref,org.eclipse.cdt.make.ui.editor.macro_def,org.eclipse.cdt.make.ui.editor.default,org.eclipse.cdt.make.ui.editor.function,org.eclipse.cdt.make.ui.editor.keyword, diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.ui.prefs index cf20a8b..5e2da66 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.ui.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.ui.prefs @@ -1,143 +1,4 @@ -asm_directive=141,203,226 -asm_label=216,216,216 -buildConsoleBackgroundColor=25,29,31 -buildConsoleErrorStreamColor=218,29,67 -buildConsoleInfoStreamColor=121,171,255 -buildConsoleOutputStreamColor=233,235,237 -buildConsoleProblemBackgroundColor=11,13,14 -buildConsoleProblemHighlightedColor=255,127,127 -buildConsoleProblemInfoBackgroundColor=25,29,31 -buildConsoleProblemWarningBackgroundColor=10,12,13 -c_braces=216,216,216 -c_comment_task_tag=204,223,50 -c_default=216,216,216 -c_keyword=141,203,226 -c_multi_line_comment=199,221,12 -c_numbers=127,179,71 -c_operators=216,216,216 -c_single_line_comment=199,221,12 -c_string=255,198,0 -c_type=141,203,226 -content_assist_parameters_background=25,29,31 -content_assist_parameters_foreground=216,216,216 -content_assist_proposals_background=25,29,31 -content_assist_proposals_foreground=216,216,216 eclipse.preferences.version=1 -inactiveCodeColor=65,65,4 -org.eclipse.cdt.internal.ui.text.doctools.multi=204,223,50 -org.eclipse.cdt.internal.ui.text.doctools.recognizedTag=217,229,119 -org.eclipse.cdt.internal.ui.text.doctools.single=204,223,50 -overriddenByCSS=,asm_directive,asm_label,buildConsoleBackgroundColor,buildConsoleErrorStreamColor,buildConsoleInfoStreamColor,buildConsoleOutputStreamColor,buildConsoleProblemBackgroundColor,buildConsoleProblemHighlightedColor,buildConsoleProblemInfoBackgroundColor,buildConsoleProblemWarningBackgroundColor,c_braces,c_comment_task_tag,c_default,c_keyword,c_multi_line_comment,c_numbers,c_operators,c_single_line_comment,c_string,c_type,content_assist_parameters_background,content_assist_parameters_foreground,content_assist_proposals_background,content_assist_proposals_foreground,inactiveCodeColor,org.eclipse.cdt.internal.ui.text.doctools.multi,org.eclipse.cdt.internal.ui.text.doctools.recognizedTag,org.eclipse.cdt.internal.ui.text.doctools.single,pp_default,pp_directive,pp_header,semanticHighlighting.class.bold,semanticHighlighting.class.color,semanticHighlighting.class.enabled,semanticHighlighting.class.italic,semanticHighlighting.class.strikethrough,semanticHighlighting.class.underline,semanticHighlighting.enum.bold,semanticHighlighting.enum.color,semanticHighlighting.enum.enabled,semanticHighlighting.enum.italic,semanticHighlighting.enum.strikethrough,semanticHighlighting.enum.underline,semanticHighlighting.enumerator.bold,semanticHighlighting.enumerator.color,semanticHighlighting.enumerator.enabled,semanticHighlighting.enumerator.italic,semanticHighlighting.enumerator.strikethrough,semanticHighlighting.enumerator.underline,semanticHighlighting.externalSDK.bold,semanticHighlighting.externalSDK.color,semanticHighlighting.externalSDK.enabled,semanticHighlighting.externalSDK.italic,semanticHighlighting.externalSDK.strikethrough,semanticHighlighting.externalSDK.underline,semanticHighlighting.field.bold,semanticHighlighting.field.color,semanticHighlighting.field.enabled,semanticHighlighting.field.italic,semanticHighlighting.field.strikethrough,semanticHighlighting.field.underline,semanticHighlighting.function.bold,semanticHighlighting.function.color,semanticHighlighting.function.enabled,semanticHighlighting.function.italic,semanticHighlighting.function.strikethrough,semanticHighlighting.function.underline,semanticHighlighting.functionDeclaration.bold,semanticHighlighting.functionDeclaration.color,semanticHighlighting.functionDeclaration.enabled,semanticHighlighting.functionDeclaration.italic,semanticHighlighting.functionDeclaration.strikethrough,semanticHighlighting.functionDeclaration.underline,semanticHighlighting.localVariable.bold,semanticHighlighting.localVariable.color,semanticHighlighting.localVariable.enabled,semanticHighlighting.localVariable.italic,semanticHighlighting.localVariable.strikethrough,semanticHighlighting.localVariable.underline,semanticHighlighting.localVariableDeclaration.bold,semanticHighlighting.localVariableDeclaration.color,semanticHighlighting.localVariableDeclaration.enabled,semanticHighlighting.localVariableDeclaration.italic,semanticHighlighting.localVariableDeclaration.strikethrough,semanticHighlighting.localVariableDeclaration.underline,semanticHighlighting.macroDefinition.bold,semanticHighlighting.macroDefinition.color,semanticHighlighting.macroDefinition.enabled,semanticHighlighting.macroDefinition.italic,semanticHighlighting.macroDefinition.strikethrough,semanticHighlighting.macroDefinition.underline,semanticHighlighting.method.bold,semanticHighlighting.method.color,semanticHighlighting.method.enabled,semanticHighlighting.method.italic,semanticHighlighting.method.strikethrough,semanticHighlighting.method.underline,semanticHighlighting.methodDeclaration.bold,semanticHighlighting.methodDeclaration.color,semanticHighlighting.methodDeclaration.enabled,semanticHighlighting.methodDeclaration.italic,semanticHighlighting.methodDeclaration.strikethrough,semanticHighlighting.methodDeclaration.underline,semanticHighlighting.namespace.bold,semanticHighlighting.namespace.color,semanticHighlighting.namespace.enabled,semanticHighlighting.namespace.italic,semanticHighlighting.namespace.strikethrough,semanticHighlighting.namespace.underline,semanticHighlighting.parameterVariable.bold,semanticHighlighting.parameterVariable.color,semanticHighlighting.parameterVariable.enabled,semanticHighlighting.parameterVariable.italic,semanticHighlighting.parameterVariable.strikethrough,semanticHighlighting.parameterVariable.underline,semanticHighlighting.staticField.bold,semanticHighlighting.staticField.color,semanticHighlighting.staticField.enabled,semanticHighlighting.staticField.italic,semanticHighlighting.staticField.strikethrough,semanticHighlighting.staticField.underline,semanticHighlighting.staticMethod.bold,semanticHighlighting.staticMethod.color,semanticHighlighting.staticMethod.enabled,semanticHighlighting.staticMethod.italic,semanticHighlighting.staticMethod.strikethrough,semanticHighlighting.staticMethod.underline,semanticHighlighting.typeParameter.bold,semanticHighlighting.typeParameter.color,semanticHighlighting.typeParameter.enabled,semanticHighlighting.typeParameter.italic,semanticHighlighting.typeParameter.strikethrough,semanticHighlighting.typeParameter.underline,semanticHighlighting.typedef.bold,semanticHighlighting.typedef.color,semanticHighlighting.typedef.enabled,semanticHighlighting.typedef.italic,semanticHighlighting.typedef.strikethrough,semanticHighlighting.typedef.underline,sourceHoverBackgroundColor,sourceHoverBackgroundColor.SystemDefault, -pp_default=216,216,216 -pp_directive=141,203,226 -pp_header=255,198,0 -semanticHighlighting.class.bold=false -semanticHighlighting.class.color=210,82,82 -semanticHighlighting.class.enabled=true -semanticHighlighting.class.italic=false -semanticHighlighting.class.strikethrough=false -semanticHighlighting.class.underline=false -semanticHighlighting.enum.bold=false -semanticHighlighting.enum.color=127,179,71 -semanticHighlighting.enum.enabled=true -semanticHighlighting.enum.italic=false -semanticHighlighting.enum.strikethrough=false -semanticHighlighting.enum.underline=false -semanticHighlighting.enumerator.bold=false -semanticHighlighting.enumerator.color=239,192,144 -semanticHighlighting.enumerator.enabled=true -semanticHighlighting.enumerator.italic=false -semanticHighlighting.enumerator.strikethrough=false -semanticHighlighting.enumerator.underline=false -semanticHighlighting.externalSDK.bold=false -semanticHighlighting.externalSDK.color=190,214,255 -semanticHighlighting.externalSDK.enabled=true -semanticHighlighting.externalSDK.italic=false -semanticHighlighting.externalSDK.strikethrough=false -semanticHighlighting.externalSDK.underline=false -semanticHighlighting.field.bold=false -semanticHighlighting.field.color=190,214,255 -semanticHighlighting.field.enabled=true -semanticHighlighting.field.italic=false -semanticHighlighting.field.strikethrough=false -semanticHighlighting.field.underline=false -semanticHighlighting.function.bold=false -semanticHighlighting.function.color=255,255,255 -semanticHighlighting.function.enabled=true -semanticHighlighting.function.italic=false -semanticHighlighting.function.strikethrough=false -semanticHighlighting.function.underline=false -semanticHighlighting.functionDeclaration.bold=false -semanticHighlighting.functionDeclaration.color=190,214,255 -semanticHighlighting.functionDeclaration.enabled=true -semanticHighlighting.functionDeclaration.italic=false -semanticHighlighting.functionDeclaration.strikethrough=false -semanticHighlighting.functionDeclaration.underline=false -semanticHighlighting.localVariable.bold=false -semanticHighlighting.localVariable.color=121,171,255 -semanticHighlighting.localVariable.enabled=true -semanticHighlighting.localVariable.italic=false -semanticHighlighting.localVariable.strikethrough=false -semanticHighlighting.localVariable.underline=false -semanticHighlighting.localVariableDeclaration.bold=false -semanticHighlighting.localVariableDeclaration.color=190,214,255 -semanticHighlighting.localVariableDeclaration.enabled=true -semanticHighlighting.localVariableDeclaration.italic=false -semanticHighlighting.localVariableDeclaration.strikethrough=false -semanticHighlighting.localVariableDeclaration.underline=false -semanticHighlighting.macroDefinition.bold=false -semanticHighlighting.macroDefinition.color=190,214,255 -semanticHighlighting.macroDefinition.enabled=true -semanticHighlighting.macroDefinition.italic=false -semanticHighlighting.macroDefinition.strikethrough=false -semanticHighlighting.macroDefinition.underline=false -semanticHighlighting.method.bold=false -semanticHighlighting.method.color=255,255,255 -semanticHighlighting.method.enabled=true -semanticHighlighting.method.italic=false -semanticHighlighting.method.strikethrough=false -semanticHighlighting.method.underline=false -semanticHighlighting.methodDeclaration.bold=false -semanticHighlighting.methodDeclaration.color=190,214,255 -semanticHighlighting.methodDeclaration.enabled=true -semanticHighlighting.methodDeclaration.italic=false -semanticHighlighting.methodDeclaration.strikethrough=false -semanticHighlighting.methodDeclaration.underline=false -semanticHighlighting.namespace.bold=false -semanticHighlighting.namespace.color=209,151,217 -semanticHighlighting.namespace.enabled=true -semanticHighlighting.namespace.italic=false -semanticHighlighting.namespace.strikethrough=false -semanticHighlighting.namespace.underline=false -semanticHighlighting.parameterVariable.bold=false -semanticHighlighting.parameterVariable.color=121,171,255 -semanticHighlighting.parameterVariable.enabled=true -semanticHighlighting.parameterVariable.italic=false -semanticHighlighting.parameterVariable.strikethrough=false -semanticHighlighting.parameterVariable.underline=false -semanticHighlighting.staticField.bold=false -semanticHighlighting.staticField.color=239,192,144 -semanticHighlighting.staticField.enabled=true -semanticHighlighting.staticField.italic=false -semanticHighlighting.staticField.strikethrough=false -semanticHighlighting.staticField.underline=false -semanticHighlighting.staticMethod.bold=false -semanticHighlighting.staticMethod.color=190,214,255 -semanticHighlighting.staticMethod.enabled=true -semanticHighlighting.staticMethod.italic=false -semanticHighlighting.staticMethod.strikethrough=false -semanticHighlighting.staticMethod.underline=false -semanticHighlighting.typeParameter.bold=false -semanticHighlighting.typeParameter.color=191,164,164 -semanticHighlighting.typeParameter.enabled=true -semanticHighlighting.typeParameter.italic=false -semanticHighlighting.typeParameter.strikethrough=false -semanticHighlighting.typeParameter.underline=false -semanticHighlighting.typedef.bold=false -semanticHighlighting.typedef.color=210,82,82 -semanticHighlighting.typedef.enabled=true -semanticHighlighting.typedef.italic=false -semanticHighlighting.typedef.strikethrough=false -semanticHighlighting.typedef.underline=false -sourceHoverBackgroundColor=0,0,0 -sourceHoverBackgroundColor.SystemDefault=false +spelling_locale_initialized=true +useAnnotationsPrefPage=true +useQuickDiffPrefPage=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.core.prefs new file mode 100644 index 0000000..03da32b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.core.prefs @@ -0,0 +1,4 @@ +//org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.applicationLaunchType=org.eclipse.cdt.dsf.gdb.launch.localCLaunch,debug,;org.eclipse.cdt.cdi.launch.localCLaunch,run,; +//org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.attachLaunchType=org.eclipse.cdt.dsf.gdb.launch.attachCLaunch,debug,; +//org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.postmortemLaunchType=org.eclipse.cdt.dsf.gdb.launch.coreCLaunch,debug,; +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.launchbar.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.launchbar.core.prefs new file mode 100644 index 0000000..371cf83 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.launchbar.core.prefs @@ -0,0 +1,7 @@ +LaunchTargetManager/org.eclipse.launchbar.core.launchTargetType.local,Local/arch=x86_64 +LaunchTargetManager/org.eclipse.launchbar.core.launchTargetType.local,Local/name=Local +LaunchTargetManager/org.eclipse.launchbar.core.launchTargetType.local,Local/os=win32 +configDescList=org.eclipse.launchbar.core.descriptorType.default\:Mars +eclipse.preferences.version=1 +org.eclipse.launchbar.core.descriptorType.default\:Mars/activeLaunchMode=run +org.eclipse.launchbar.core.descriptorType.default\:Mars/activeLaunchTarget=org.eclipse.launchbar.core.launchTargetType.local\:Local diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs index c5ef299..8442100 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs @@ -1,4 +1,4 @@ eclipse.preferences.version=1 -platformState=1642266909598 +platformState=1642266910353 quickStart=false tipsAndTricks=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs index 4f64f11..9353b86 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs @@ -1,3 +1,6 @@ +//org.eclipse.ui.commands/state/org.eclipse.papyrus.infra.nattable.column.index.style/org.eclipse.ui.commands.radioState=Alphabetic +//org.eclipse.ui.commands/state/org.eclipse.papyrus.infra.nattable.row.index.style/org.eclipse.ui.commands.radioState=Alphabetic +//org.eclipse.ui.commands/state/org.eclipse.papyrus.infra.nattable.table.hierarchic.style/org.eclipse.ui.commands.radioState=HIERARCHIC_MULTI_TREE_COLUMN //org.eclipse.ui.commands/state/org.eclipse.ui.navigator.resources.nested.changeProjectPresentation/org.eclipse.ui.commands.radioState=false PLUGINS_NOT_ACTIVATED_ON_STARTUP=;org.eclipse.m2e.discovery; eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.json.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.json.ui.prefs new file mode 100644 index 0000000..d9391aa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.json.ui.prefs @@ -0,0 +1,10 @@ +COLON=\#ffffff | null | false | false | false | false +COMMA=\#ffffff | null | false | false | false | false +CURLY_BRACE=\#ffffff | null | false | false | false | false +OBJECT_KEY=\#bed6ff | null | false | false | false | false +VALUE_BOOLEAN=\#03a8d8 | null | false | false | false | false +VALUE_NULL=\#89969f | null | false | false | false | false +VALUE_NUMBER=\#cb4f40 | null | false | false | false | false +VALUE_STRING=\#ffc600 | null | true | true | false | false +eclipse.preferences.version=1 +overriddenByCSS=,COLON,COMMA,CURLY_BRACE,OBJECT_KEY,VALUE_BOOLEAN,VALUE_NULL,VALUE_NUMBER,VALUE_STRING, diff --git a/.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml new file mode 100644 index 0000000..4c8f907 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.debug.ui/dialog_settings.xml @@ -0,0 +1,8 @@ + +
+
+ + + +
+
diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi index 1452871..337975f 100644 --- a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi +++ b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi @@ -1,8 +1,8 @@ - + activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration - + @@ -71,11 +71,10 @@ persp.actionSet:org.eclipse.jdt.junit.JUnitActionSet persp.viewSC:org.eclipse.ant.ui.views.AntView persp.actionSet:org.eclipse.wb.core.ui.actionset - + org.eclipse.e4.primaryNavigationStack - active View categoryTag:Java @@ -207,9 +206,24 @@ categoryTag:Help - + org.eclipse.e4.primaryDataStack EditorStack + active + + + Editor + removeOnHide + org.eclipse.jdt.ui.CompilationUnitEditor + + + + Editor + removeOnHide + org.eclipse.jdt.ui.CompilationUnitEditor + active + activeOnClose + @@ -218,8 +232,6 @@ View categoryTag:Java - active - activeOnClose ViewMenu menuContribution:menu @@ -241,7 +253,7 @@ - + View categoryTag:General @@ -359,7 +371,7 @@ Draggable - + toolbarSeparator @@ -381,7 +393,7 @@ Draggable - + Draggable @@ -390,7 +402,7 @@ Draggable - + toolbarSeparator @@ -675,6 +687,17 @@ + + + + + + + + + + + @@ -877,6 +900,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + platform:win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -896,6 +1159,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -905,6 +1193,8 @@ + + @@ -914,13 +1204,30 @@ + + + + + + + + + + + + + + + + + + - @@ -955,6 +1262,26 @@ + + + + + + + + + + + + + + + + + + + + Editor removeOnHide @@ -1120,9 +1447,9 @@ View categoryTag:Java - + - + View categoryTag:General @@ -1280,30 +1607,30 @@ View categoryTag:General - + View Spy categoryTag:Eclipse Runtime Spies - - - - + + + + - - - + + + - + - - + + - + @@ -1428,6 +1755,210 @@ View categoryTag:SonarLint + + + + View + categoryTag:General + + + + + View + categoryTag:OCL + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:C/C++ + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Make + + + + + View + categoryTag:C/C++ + + + + + View + categoryTag:C/C++ + + + + + View + categoryTag:C/C++ + + + + + View + categoryTag:C/C++ + + + + + View + categoryTag:C/C++ + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:Other + + + + + View + categoryTag:Papyrus + + + + + View + categoryTag:General + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Other + + + + + View + categoryTag:Other + + + + + View + categoryTag:Other + + + + + View + categoryTag:Server + + + + + View + categoryTag:XML + + + + + View + categoryTag:XML + glue @@ -2407,6 +2938,937 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2418,8 +3880,9 @@ - + + @@ -2460,4 +3923,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.core/1865797976.index b/.metadata/.plugins/org.eclipse.jdt.core/1865797976.index index 5c7e1124bd40a13344dae0c75db6b369b9d2e43b..20a99691312af0b3cb5eef8e7f30468954ecf15c 100644 GIT binary patch delta 595385 zcmZ^L30zfW`u|+G`@ZihT)3>43%F|nE+{C7vZPr7$^}v6BAZ%cVvE^KCH5vyWhzc- zyJAkZD{b0lVv8-7(q?6)wAo_i|9j2_rRMja&u3-;FXz1HeV^sKJcq9RM+9H?9uag} zVyYAyY;l5pY8|$yyu+7YbKD|OdIkL2=y19BmLzwmY zE$pW(EnBNHv#gPZGErIm(s1)Xxc?|7FRE^=3r}qiH@5OW5EWG~Y>x0>$_ghh3NKtT zDYAn9Rxv5u9&VTvX|5Uk-PrOuGx>kP7X@rxypx?Z=-FpwdXc`YIUHuYr3O~!vKt!1 zD_ScX>KnuShlPtGOT%on+sfKT+0$fA&EfXSg^Q}A%aOG#iZr**zheFs=kcF^sOGda zmNtdMH6_)J;Rbf3ByPNDa&>b!x>Wg;Fn)Vsb!)f=SC09I;2-k*`i5|6YjtZ|3x6+J zeItLd=;hdMk%>*7Ze+109s6vQmH85FWzy1cYioUDUGx{^3mfX2Dx0cXTBC~<4|`lm z!P4rwaKSA8%Bs@VX8hKqw)%#l?T{5k+FHT|jkOVW$s|j|`#U8{J(%GU7w zD+br8omx}h8fngtG`3EuuWpFcvEQe;74rJVmT+@xWoz{UcI#9pdr@kT;|wB87esId zY;%moBIi%JY-Lk8x?XW%8Gpk6^14LADcA{?JJG6C;CGhRxAG^+KJ>-2wp?6k>Wc8f zHr%y^9UpBIm}$cmAv4>maLJ^FrA_sXjp1gNJKCkyOsa0FUsx1wY%6FDFD)-%zG4fT zGs9t$O+nN&w$w)&`5h1yau3H!=9$?YGnA~$q?5_Y7Bz>fYbvU5bNG~sqJomrrshap zbM;bI66a^-Iu~0j)UY3l^sFhv#(ZNu0y}+trNPeLHRa0A=WzK!v8h5 zhF46S$lqC86kZx>UO8(4cB`FxeEz3a>b%uwWf8ZDO_x~ZvZCs`#`@ZNJk^>@ZF7{9 zBW;bX;pWMahDbEjq}&;BamD|(ys$LPr3>!Ke=oVLzKIJa{u}AE=IW+J^$VkWE-9&Q z#g*8D6{*}#H#A_S*pwFbu+7axN(~`?mQE^}6p1v1s~cJ7Xk$=T8eY~GZd^E+Y~o9s>v30pJ>qEiM8BT3 zU@;cJ8gqPZO*AM=!-GqTE`Ca6VH*yvmHjw3e!O-{xS@LG%y45}>moj>_|GUyk@F1= zGpkod+M>(TBc)4MHnvu;n7U$NxQTl}wtt$7?HAbC^m!_ln65Dj8zPN$_Mr*OT%^CI;PaOG+_;VGN1sJG>2=$&D?{wu<9}+ z`%ln1Mp+c8;m)pRGIEGtp&ZxGtEp}p+5%bOP=xaTEH2DPn1$JFhe?9U$DIj#-JQhl znXhA$b$Yex()z}l$nwD}up^hnvytUCRz6L`CdCeZjXwpoA^sgqY*rKsIuwREsK!)gE6NeU07gbyM-2J6>7wy$qm&lE$saf$uep5 zl;>Z;Cb+D6-IQ=`bz4L06?|=vMhSmgV@WhAxjGr<4unfO z{$E6VcCa@*&Ljy}!BHCdpKB4QeAz9DwA6EUng!OA(Qc3B`mW9;~ z4QzMF%BGI=xYQ-+33;t(1`FC+2aB?_sJgkO4B^6d&9|AvEqprik2chlTiL`Ci&8S! z?D!h6I@#<{BMj$+Tf(h*d`01ZMI7BHCeR1eL#=ACXLx;HuXdY1|8qWWcjBjHL zBTXyWOtXzP$aO|G-sffBd=slk(`nSx(LtKgl9%wo!ETOo#tR3VFqh5Znn+tT5V`N9 zLubZbA7f({m62VN;c$u&KMR*cA1nItp$Pbgg9fHs9IR=sgBhmTSgp{@+GiOw>Owy9 z!YwV6xJu6!iyZ9U8G80~LV{K{m>Yv(;-e#1_!8O9QFf`MB+{_54&|q4j*Z3H^z4x_ zex+hkTWf2iaawbvt%+R`>tVOKoZKh*e$QH^ekO2P#3DYZSa5E#S~aDmPagXifp2EjY&T+8oojP<$uHs9Kb=K#q+{vnTM9k(y+Sb|3^;=4C{=yID{eIZ=A6JUJ~8!Ilh+T{5S zk>$h6uoOL*Z%Qm}yq*1cSpxghW@gLnMz(jNh56!qE_q=Y;8lKoxFLE^WeI9)xEWZW z8h712*Qinsc6ZcNV5sd=lN53eDdb0*msYp3V1gYbeOZQqsd5yodYpkx&2}3le7PAs z49V06u1>I=v0kaPkPGZd)$HbR?tqvBFoPeG5B12bDg3i5OIssN(d}iQCwXjgzJT!I z#{WBtAJ@0AMnOSoSYU5D0*UNE ziI!zpJ#5!B6AOFd*z*R928VSKJYdBWMkKM?d1`@`PCVpwCCj3~aN%HGl$940RX3t6 zL~~Kt9^u0QH)5;jB_s(8hCV3aD*jM2&~nvuR$D8o5$bywnCW-`C8D+=QjJaGOGM^u zEBjdO5R39!mH>YoE3mU}k0~TufIMtzs$LlFl&VSGx2@r(i}@+xTGh~c3{zc@73ouH&?Hm)DT&?1hsf} zTevOy5y_>%NhmDrb*-K0i{e=P6r))NhS6NTaHw&Mr|_kP`EpHWQ?$tpqLrasWUo%} zc+`{HYB^X?GY5cja3>W}1RDl!VLvM4*(YKftHJUO>4se8@U7$5%X5KfrHp>h$KJ)o zs`6?Ux3vtFes;u_gLFs6=SVp^77L{#ai^CR&Afo# zGf!`} zfpo733>to&vT1Gg(Whs5a)Uz7M@O_-Y?9mMvht=H)R1YQ2gR8#b_C_4Gysk<7-+~5 z-)IwCBTmRx6op%>i%|2C5d4*OTzuA{a5vTfG$$^T;}((S7vPa}R(rS^b#^fDrZq$sR5uKAB5YC^$l%yiFWZ-6W>eDitY$J8 za6r#~DACE}ST(?E zMJ49qgfI47CEIN`%A_+9?L6PTSz%>slT7T<0-L}{y(){5WlR?dV>#M-b*9ZB9+pT_ zKq%nOK^|?V>IYKoY*o2MBA!&=SlzsmosLb>3c1e0@2jM!x^>|qcGG01O@1Mj2FW^C zGP(M|&Y9v9MSQ6od@R-AHbo@Zj}E8~Z+F5R3Sd&vZ!;RMPZX#RYOOxZ9@{7G};=YXAkY`k@-{ zp^`h|`~nU6#113-LS$zrmB!K1Nz=^HD@2q*@&Atf=7a|3a>sdOgWYzp9Ba7k zpWF~>8Qg!iE5^aPGW0B5pote1a?OjsM6`@H4HY;k_iNlgvgI;A`wWtpC{vfA8mxiC zc1<}%-7Y9vGM-EF$vh)yXJwP(A*0|(2cwyVQmoooJWq7xd>3wE&y`!*XW33RDp$+4 z&b7#-QSjf^$_jH_?56@3%W)?#;douSc4%h?ZyenXMd2)--(S!|R3(w7wx;Rfh9*t{ ziaugN<05P#ls0~+6+F@oH}lEAbzVGME%!0wr3Pj+IoL*l%rxHVfao-+9`Kh@ zM9ECFk9<7RtdJM-_u`(B^?E&QAl}FZye8$K61D*Ka|xT^wXyAE!3YP**USh93D|v7 zmqs2fN*B8FvUHbN#9xwiPqyfIP{k)u%V0Bm&S7HzniR(j6O2qh4hletk@e-<)1dz} zp@&}B0~wMMH36-HU$}Dc^mv@jD$Sl$A=gRqZ(I=txP;IJ0Ru%m6#e|LpJcLgmwI&I zr!`@Yq(|cs>)+|N>f{&EI{$lm>K<@gGUU9J$Zr$>V;+#q3D-o16$1HC^+h^Wj&QOc z-3Hb=-^gA{HV1VVlv{3RFPx%+tE%Y7$dTyLi+E1Mu1xWi~FHZNc|D?HDOOk;lmY57>fP7JM zC)cptCRMVvTJZ?PM+EjRGGn`%{_7L{f`I zT7pz=EsQMS7bWGeL@BT?^C58FbUHHRd?n&*5dR4T13u4x89P*ldDs@sLv~A{wL&4@g}lhdbeY(ei5?bP z;pX_O{(ldMX|mjiMl(BU(6I`wj@w-kui`MotaM0^WFOD*viHl)&c8E7MKm;`I}Liv zfqJeSu;osb3~i{sky{B1x1&2$F%QA;D)z)w?KTGQk`(*LPLoXg}kx zF$lNbsqnGiE=gzOFLkr2W9_WMp=CQpTOe6l6Ncmv{_}q|FNUc;4^PK27wIh*M2qOh zIlRh;!O8@uWH7tg>@?mLV)-FGivvRFsYsBB2UY9TIRUobYaODT5Fr%9@c@__C$vWe zvIcg%)FZnfYO*_gX&YYFva)Gf_ShvB_D`9Ili)a#&nr3u=myEmEmiE$a7fn~k@<0G>Dk43EjiMy41fgE|$vf0~m;MCPHg0W`;sj?0>;(1SXt&1X<@)e2 z1^x`2!RwuIA|7VmW`K zt<1)=!7p8UHfN6Uwz){%VFqLFNIx&pK*wT&={A-)TFZ=fGn+cv3aK+H@-?#v(Bsb% zHPcN=lu8CkHt#6@kmE4&x<0?T!+JK5{r_l^7xtbfYnjC^p4FGmjC204Eq4)kvCLA- zMGKm9uf&6RMV*c{UJ%)H(k#xu`?kX|E!#cOY5u!2Eav4$_Q6yiCnIV9ZcDJQfjL2! zB!iY6tFLf~cm<5t-T=TLVLHfY2(e>zxhN_4N~_%J^;I6Qh?=@p%(pxc(4s7GZPoY zng4GYhGnK1bpPWKvTA|jf27$5{SF{Lm+CKa279E$#@SxZAxOtR-`|ak^x00%f7kxa z#Ea77Oa51?{l5)gaa8Bw?{HCySYdUsQKL27Z~;pgYhq^<&~Jv@iL3zeH{a(+ZHrD! zgqv^6_DF_!Am?Z2jfiKL&egHDx$yEPSatv7f3Yf0fGvo%v(CvTPE+C-Atyx&qWGOn znxv0H9u8$PjnAz8yJF1-3gS3G%Z}+~taH3WB94kqobf+QkDrxeWpfc=P@%!AoSMH8 z0R}OA$V2ZG`lLgOGB@!tq?ey6x3lf@TpSA@G$T`^0T{K$qTBZu31XPe8fI4~+u8Lq z6F6$&9dudwUy1G>*B|+Bqh=t657@l`cL&|-3+nr~aLTTCqidGytrv`v=p`-)*B~&i zl)u|C!xTaO;}_>oSf0_z%Hurj$Don5}-}M=l^usFEV$2trs)^{=2`j zM^4=g%eCw*xB%uV*rUZ(PB>#b0uFK1*=P4ood7MBA2)$nz>ZIGZur5H@fS&PNKYR! z-lI3VXu9ChI8_c-bkZ=X;(|87fBbKLBikCE%%&omr@+0PJWa~oUIN7AQE%# ztmE%u4Zo#>zU1$75-pP9O4Kl2yEtHFpN=-d#sXd`H;v(^f%wG?A6nsm@c(le{_(8v zA3^H1N`2J!U$dT)N2>xfzSbwFuJ`O-GJa>U(9$&yH+?xbT}{`FP{+|DnNkB*zU+FR zfwo<#^^p4-ubkevTci|>rK*3&I>=1+cq+fjucw@+;&rsQFT+Mv)pj|3TwutInO;Um zik%L6bf(NgCr@Y$T`y;wsI$ck{B)CF)Y4p8G?jLrS3BwSuR1C1jwA(W6N{Bmr%#qa z_q-=bpbB%QnSyP83!SYEWYV*+56C-Sproebu?qT^6F1d<7$c%-#*C44_K#RQ^=|h{ z==icY2c3M&W2UCX{s0|T#ENKUU6P8rACRjk=ZstgnETxR1QYE)qtMaMziQRgBu$o3 zM~U1(+CFtTE#Da%pji#rAM;&U%`>-{JZ$;riFD$tR2i**JVr^KPp7G9AXcRjIBDA_ z9s}LF)32s{OE8Jn-Y6bT19{0hI+j+FuniJx>DDSugN zJzcWKq7W7=ZE7G#d}uViv&EyKE6>Tb^xicwChFhk7n8OnLr?FXNcGXghIkjfwMjFH zzTECl5zfpjo%ek@jp0UD_2g(og5iUJAXXmQY`Of|7h{g_CT( zY84&bnv_N{Oq)js|47xd+&U4RzRN15mER|t>GD9fiVmGt25D+bMhac`j>keJfA~c- zf1OrA6D1NS&D&*)qrTlT6*aA}iU%9e>Q07^M^DcI$2;yi*7bz zH^1U`#v+rBLLt4DPQPfA(prmuJeky~qv(diDH$}nJ2{1#Dg_eiDN_n#3Ti0nIY**e zvJ@j2!H}OXBr_=U{g8)N?@G_4)v7oVO`N8WiT;IcFk<=gaDdgKSa zS&%@p#W-X2*Df3VxDDA5suDS=q8vHY4-`+rLYtX1_Cy(ZHtSWSeL^k7#SCWp@M{}> zCbVk1E|JM7_+Yx3rgx;NsiV!Jr&oWo8wBHMO-Y=Gf)B(KA^U;>=F=9&Xv|A{4Ze{|l)Mx3aIGk#tFZbbp`hSiwQuPaR3%%OyNTsSgpOAVg zGz!|=tuxc@l|BcpYIVtI*A?+9Dm&%&P}d5PfsR(jo9Snh!AL!sF!BR!Ikz zW2b(}LGIr0fXzf93m$xbf4rXF`d;UW2JI;pBd3#-49TROqEpj50BFhV?^G|mBvbiDmt>wkDG_onSvzB>lc`)VV8VAr8gha80d~Nv7S1QtL1chGoH`?MM4Ul+>~G-PlHTDk6!DxM7Mp$oiPfsEHaIw ztMX+g7FvrqbjZcD>8E%r-TS**M>EdhB>4JQR!oB1ogu1SEY{GhN8BO_=6tweO*;LP z$Vb|davxo{&pnDH2ND0LyO54`wK_ko2;o4rr_vFD?@B~eHgAN55*yP(NTD@Ph>di* zTx+IJS^|2S^-_$QR*ygjxcm(IWnY|AOrhllF?Das($g2C^m_W~fNV6SRHVr%qunPW z=XR{lUzTDJ1SxNxAdaqIWYP+PUE@49TIcoI>CU*Ik=CZB+3B$@>3YgNg$z9Ru0};9 zb67}Qg2r&0OKqf~B)7(%{TU9fw}&xz7cu^ka!;E}fm{Pon*n zOqA!}v^wfsZ8uPEtVBsauh0MtEKs6a9~Ua9`nxP6jla*KqRJ1AB7XmuANZ=(u}yVl(YGNF20co=`)Dp97&)jg@F= zq7-TL_>(qMmjrV-Sssyz5@ZOWC)<=dy5pOGmP(QpBj}ZD-6rbxOVw1j->jypk6db6 ztXDy3twK-k-5iT6waPQ7*PND2FU31dWcp{iflfS=D5h~Oeie0%lj4ZNiAoVV3KFjS zh0HX;MEcGzwXx6YQ)qOIO-%#+5($M4d&D%NU1g+`Un?~9Y?0JVwHN@T(d*IeR-Un_ z=?$k2_@yCM7(1mjj|9G03-yc_$Y@r3vU;OeBj0!_QmXrGl8nwhsZ!DlGct|z+8nEw zByFh1xj(2ADErAY7foM;@NHU>W)yN$#H5{VH&W=vECl5kt(Z>u%pQ6q0?@Si0XrUi zAVWi^TTveFyGJ*QWHYlB)Onp>L7^Es3FVSNN4Ebub<}aYNh0FPRtp_D6KA45OQkmI zor(H!dPjnkycHr5RekH$QwIxKsOfzG$NpcvB5GNz^U~^T#V$IyRe`;j33yiWy+B3x zk4do6v=@+v-W^#^`t5O{iE?jMTIr8utDSE96dm@RfYZzd7E3Ae7H;mJQ!%Rv<4LhL z>Mza^Q|>1kVb>X#l~r^h%zj1srQ8nubnaERj4B&bl~g#vuc2QmkwpDBWnxXQhfuv1 z+Z9yXm7Pj6q$y^4`ckQka!d|vOGvMvlFV$SC|HbHVSFj@(lhVMU6lBGhJmctIX$Fl z@OZkemWpCRemZ=3faT=BDqF9mtv#k z4*|DU6=z7Ob54v{Qqr~{ucV-bzN-ybs3Tb@qd&Jf%{1n$CX;^p&>Bw-nNYZMyA_nS zLIl(2oEz1PpN*#P&c|6uUZ#NUC)HF>3X@bl@hNtTBy55&2v*n5d-pHl^aYH|Z3#_@6cn zRWulppKT~4RXUxDDh|r^)bk;ffX-k@O2@7R+_e;2&6In&0FCf{VDQr2s2nFCbJ5Kn zg^XtBdYshf!g{nD-6BeS-a3iQ$5E#HYfuEgT?`B@zCKMa^K%18t*t1%g8rCGXu_u< zCFNErMRe{F2|$a+8lW9VP(N}Cv9w6DO+<#T^Z|M~PH&_+Gk~L>+UwI$UzIV1esiPU zdtX4=?8(J4-1(>;KR+t8)A4uWrF7~b_{GV2icz#utu)i>UUcI>{lLoaEk$D)eFh!8 zDrH=IW^r3()0MQZY>>fiqy1|9I~#X%1o*~n*`3XS1jYKPdX$8^g3NG z)zG_VGqR>HbgjisT{q&}s<%)wZ*NJ$!d}$jRe^0TRLv|m z{nDyb(Zn8L#D6ae+31Of1!;8PA?(b+Eohr>JqwUqaolO6iFd2TboVy78im53quygi z8SPP_j&Ik+Xy~qNrJUHNKq`gC0fO#$J2Rg0H>>P)wjDgA=WbIv&0mbPy#Ea_uUp>q zNa)tb6sUNUfeX(DY(}!Rt5Bt0&lZtyjl)ULdK1)LMrpEa^7Onpl?BE5v*^enLn3v| z0%+>pDAQ8wli+#{U%8U$+}UJoO|o7o!5m(Gq@jj#>QX&a@ozjtf2u%DyVir@3ObD* z8u7H&OUsX^X3>&oLCgb%8Vz+9sN~f9Yd}ru3uC=hyCK<1;%5BX{txw;bno?+skA&> z%_l}S?LCjLLYXo#HN_+IZ!8;ev1!?<<`Uvvlr%sh$Mn8%5 zc4}WK_fxkiR!W}OWIN5D3yxg3-m9k277&hKRs$2?+hI+lPm6#WT(7A0wEg!aeb;?n z9VYf+rZl$Fnuydu?!qJm!&Enru(S8I2Ym0k@%T1pS;Eh%o^m z@eL?4on~)_AV9nSEj7~X_X@2vMV&m7#y%6P?#fCCQ0I*yND9w&~Q6>-{KWw*!B)`vV&C6eh`O#%VP0#KlG*_5D+nNE40&oXxln3_bKCz}foU z02YhxkZ9;|uNPv>3UxZwPO>efg`ay;DDlc9KNbI$1?mt)8|d%$Yw7o82*a*k^zfYJ z$cEQrS9My-!CF1iNDe5Y3yv9lkN;7&HB@=61r`Z&qk6D zbOw5J8@A)o1#T~GZ3CKkqS z#p$T24&ifubpSHSu~d+UZ*a>Dg<3(EoQ>7f4Nlo8`lAKyAs@yeb;}iEs>;$T>B}0W z2Dod@L@WL$Hwew;d;CslO&Y2%0|wc=5@=UZk|Cq9*Ce=U=b>a9ed&~{NYjYD?Aoc1 z;tf(I1ODXi^P$r=fH%zk8Mk_|TOUU|=461(&D4nL+%Le8dvwMOno}#ViGuw8Y#V`= zed2PvgqmuzW%RFwDhus>CBZ|U7pw+a{u+>E--~|GWDe53o#viEkF+}iw0ut-54cSd ze;z+7PQKaN0C_!9FU?sGs*VaoE0L9Pgfp|M>3|2Z=qR~;65<=4GpAlUlGrHf_0~QsXem%xS z6Tir?lVuY`y9KMkQ&Pe*Q`dKL58bd^Y>ggwNrpp2`(BlcV=*X7%jR1hT%FL+zHWr+ zm|mxkLO*EiG*%@yQN`8DV#?hi1%jRLGH`s#PPwxsa$0!+7_@7z$WAZcsdds#&&L6m zi4}6XvIEZ{RtOE0(;IK39ghJ5zi~t*rO3F>xU`U|!#k91N_GO)oRaJ^;^ko40r(cmv$#M<_Li?^oP910Cu_4cAN$5lw z6rXoS*(uMevodYEpI~Weefl#ku+DNs_4uCK)Ob~GoGG(1bDUmNw0x=Z_JFN^J79H z3hqcj#*GD9NA78;|8r=}`J-d~^hHP!M+b`iezGMc*?8UN(7GgD*9%rHbsWR3|9n|v zphUI8LaR%3V(Kfy^GKAyPN5b^9jC9Ru}&)c&oKS!!(CEqBhX`Nb4pZtKN`C<=BNz5FQp$Z!hP@$+W1;cnL$=$0dC zvkoumBzA}BgaTbAsE`4JT&l!Y{UB1%s&v%3rC(|dG++cS9e5mq$l7JDtk|rq5tR3G zl9A5Hp*zie#iyqE4@q6rxer?1lcQu-s`x;bA-ZZ&<#Z^TH3|&Ipb5&6(87?U9Y=@LTZFNrpOY{4EmV#I^*PgBp$PJmr5j85e`4HP(-s3C8a!%Rg*4hil3&Y&mn zM4ejB4V3Z|rZ6IAA;J3Y1QXbGZKjO6nH~$gOsW!cGqSYJVTz|6m%B`~{AqzHW`v)7 z-=p~=NsJVE3Vr6lb?|2sdvg9qfh}@ZIxW123@p>=^MN8dA73H2V>nMMHjBn#rc0J8a zfbPJ{Hn(gAWn3H!Q!4e836d?BU)v_d%%x8oAj~JCCK`Q{@ad-PNF&#`7m{{+ddTKakLd9N(TrT-NMjlg{ zNxon_0>8qcCa2#WPv@5)1>7!6BK6*aUNeOEQT;|hVmh_~jj4N&TS7U%>145}&!n@1 z`1M=~MAmf1D5jFHp=3XL44j;&IlcKZO4)0B=%x)_k>37@c*zbV#0J-o0 zvOo?}Rsp-Mc|qo(o$F8)m%gU4pe=4&4kTR6672NFmx`p=6_Gl6?n!{hfzCMiT(eO< z)}4|&Y4nK%oSRv%gz|%~Sbhnb+1584NT;um9!|4lkZq3`a`e*Jc)B$N zwQJ27aAoP*gm{>NA8(b|==+->wEX!z z^){b`X5F8rrEwBRAlyeIjdHF>?SCB^aC16v67MN=nB01m z>O$F=RNqQZEVDt1z7|}j>hm}i)xT#n(flU>Nd|5<7$`Ik@}YT+$4k9SR0;~ugg!7g zH$EU*5U!jwk7i%3EagyyNmQCwQd&xaBxFqJZn>Afj>&-Bo~|mQC&r9G_fSD0do2NN zWm;Z_n%>WFgT&{gf}y*h$o1u?OKEn8#X*`+_XqM^In zpkQrzE+nJ#GhJHhjMK^KkBuU=$X`+4QcpQ^APKy`0%DHji=c|UPiH&m!}ri{My0|< z{>AM#bqNJRI$nEf|`Iq&UEOQd^}k^|KA0ebegx25>V zeAZ;@vO`t<@WCLQ%W8D#x?7OYeOn+Omh~cB9ZnasK|LZRZiM07?nxipmAl~2hO%j3X~0h z+Dg+8I&_qL8ot(BDd7pr3zv zj&`p|G0?6fDGo~g5#DRZ2S%t=pFwdsG#$BfLmqsCAxy5NjO(EqikCwWs9Gpi(7KPX z@du9!JY>y<;9c@_dMX|JA|AQC+muA3MvO?Ns#>FvZhi$G&~?lY+xc<8$AKKQ?w$de zl&X3`llDGhw$u8@03~w&3DeESrRK>DAjjS>v9z!LjhzYItbp8eJPAd-NiCwvH9|QZ zc+zF1rrmlCN5Ie*rsCJ~_hD#q+CBrVodEr%V*&VXyGgF2a(T9w9vU5|r5ypQQxTkj zzaPNov!7-g#Lz|Sp)zW3*NX7mAHM-Cx9mgEz8ycMSV-iE`bYcPiuQz*jitoI`mHnL_KSuu>Sf_z~htI&J_Ac zVv&%0GlKWO4=1Mb5P}@9NaggMItE(a$JoxkpHw+*W>V2fbc(*Q7O2?Um11(A zz=muv2LqIwi)o0a^JuY2W2eAvN{uRZ{LPD((#zntcbDX|D$kWZ7bP-A6a4=xEeZ zy@f72ZbIb?V5?OsRF#k2wP@0wtUr_P4}@Bi4Qm(UgGz}zLThjPg=A69K{$e@V{ zSJT=R9uF#>ZVR-?&tgR$8n-6{lL4C$@%#S?C;Xv4tBkDOfI0hidgY`sI+f&l)2O6n z<=M&f(C11d*%Vs><(>u{+GR1QDWM1R1${j>6}|IxP)qCD(FO~ufvfr#0_`-7v`A^m zDm(nOE)0vDd(38_yG|j#n|_B6b@)G+q`2{1VhRVCX5~#GfeGxCS6Ul)C+X;94Q{Y? zE##b|Cjp0!PlTh;yB#RBqAoU#$0)S_YV`EI55tJ_#tXBkq9ith-fh&_*+89;>bNFf zF+Iabir5S%jhO=dXY-ZV-mfyVlyvrpA&-8}l_$~%A*@aODB9T82ZUPje3Sq570sgb)lXSF(FdX(plXNEP{aN6OEo*M0Wou#_)Nv-q_g8so5MLev zhu0)Svl&$bT70G*Bs{0hsOxG)No2R{vuJbyb|m*REbPNeljRin0^4$Ro>n$Eu807I zDzW!!a7$2UF?HMuy7Xm`6@-jnbm_ueZp(K|^ZE%o+7L)R>iw{E-1HT}M>#248aN zDUm#5sJ+euZ?Q;`LQAiZYq<_Odjy6GmY+b!T2(7`(icaeIrmj+&G=gb3(42-_t9Ik zK~}{#d7X64O_)9lZ(IW@uxe_ih8C>N%Ai)0A(P_PtGr~sTL?H=Cxmu-0&;Cmr$!jOtD*XTEH3{53znlicTtS6Bh z){xUn9T<2Sd6z^h^AEk#MQ1)r&lqNn@y@vRVQiQ;-R7XQ`g9e0qc?%pmdWBt^Q~7* z4~R2e7>R%onRqYyuXYuZB==9CDgH4>7N**0{~QSH91!F5h$U|!j=PMICV4+5_%^JI zL}d&nrV?C2QooBPaq?p&Paox&ZA09=YEJ_mS`N*;CP4|+QH(>@{2F5*<)<;pRQp>9 zvpW009W z*y+w9e05@pSusfZkJQDa)3@b%IpudslVVp^w^QU8;OV*Ps0erT>nzk?g|Vl|2pICC zW1%oMT_MzVy&#s;ihI#YMUN;mX#FAR8(XfmD!I8hctkm9rQNrJ*X+*&2A!9VdX=#) zRnpagxSzKb*ff8o$xJ(5iucm-|Hg}BOY5(q*%2rbl`q*vRN^xx@RlI;N@7hcRH>k% zy(stZerX-1*o^-}t)Wl;4LN1tKj7vsopX+%q-tnNiO+(A6@Q9xv_C|EXh&^gAN~6q zlY?f>1OIF21nQnRS74*1KR`75&quK^2sGe{p%>BABXJe5+J?P}qwjru}eiO*)&ks_; z4PL{dPIl|T4T=Hhzr0+jrSlJC6sPuz^aQ%K5^y@h1ShG)n?9DL`A~nW_MxnotOEa6 zC!qvC<_qle?E5m0G&s4ahrK>QguBbOOtp(BrCUl1kSw*Vy%oJXCH4H}Z^s6}L? zTUP_z4fusZ+A;&faT}&2XVVwsV$kr@kqAl+gw-GPE}b-U)Xb@slV%l>?tKWIef!g` zG`bLCS-TzEynk*;!d04Qe~+^PK8s`$fbwR%n@!JMqwrB~F^q2czBCJczSZNWz*yAj zj(gKE_4NRnVeSv$5l73B>YW|1z5n}S>}V37fW)=xIdmEKYnY?``jPm-IhiMaj`u{_ zVD9slIHD_r$#nAw;F!==@FD}(z!LYK6Kcsi6&~-}Wtf-!_(tf;FDFCG$-NV>GN%(K zu=*Vk5lbQ%Zs-rOggtiHPWM;9dFs0!U3c{+=)-efiknL1e_{dNH$cOjJE4pn=1PC} zOuT1bU&oox?$PNfbmdjRI~{V6{JxcH8C{VW6Gu0`2F4S58}o_0zqhLcNUuw#!qnkD zkj`3Pwt=3xR&UyP0Am=Hn_-&XvJ$YbkQQz;dfxHtvNQ`OXcrq_QN9;Hcz<=W+ zgPHXm5N>=AVw8&sfrC;uJ7$}ketGD7?)X=-$3OZ@|d~lua>ogW}Hf2g_?^Qr(O=?sf z?@wwCSjxxey=MAlA3$lrJ3v@&i_vv~!igzvyvjybOK=W{<9rz;wyEN&uQ3sD>I}M5 zZ3%Md@GnUox@i^6iK_gdjka!4E9n=J%1`QRFgsLr#HXZbQ&7zoeQQ>;(|g=>>Ld6m zRqr^Zn4$H`=)K$E%OBkUX5Oo{0FIr5i0%CXgVi}dAcqp;WPWP95}=mv1N{NcwE79c zzw2AOlU1C+!!%&b=-XKk+yWM)*uX)kse1}jF+(*?Dy63j%^I3<4FvR;u7#t?59gK~ zG&t!Kfn_x1=fmV(f2TmPF-Mq6>#JQNYTuzxpdZ&^l7@G+_t(jl^h8P`P+tcICdHp5 znYtJT%fDQV*4_Cey2!)-ih~C9Axxj1E(Dg?gw*l=DTJt12A+NFW(cRX4+7p)-GF-W zz-Ex`+}jZ+k8cG;%4I2X+WEdMi5z1LgKn|+C%7zc;7=!#XvaL25=VjvXNhM*ox!%|49Uo^dQQlUg4|`|WVx`CpIo+G+YH5)7>E z0IGXtj?qgej|&o`^Y`Lr4AJ+l0&x5)A7JgJW<@gPcrans_@+xr<{yw@=YN9^K6`{1 z6Km%&e4%N|il-_cr+oB5r~dJ4jAs_DgErJX0R^g7l952azlwRKQHNk_^nHi|`s{;9 zA-4%I(D6M+Dv$SPDya8UkCdKz7=zB|jlKXq^#yR5wix85uU{ddjaMOzO$mu{(UtO( z@a^vb7xswFdWeG`w`h#CG#v%#E9Ia*Bdy=2hQpWnfE9}t12H8>#Io-T)nH0m;!o9gg(8E{kebZmD? z0`_pt*jO|5R03M`CD>rfj+G1P3PCI!u&*E#eL59I0Js6F`@@)k$jOE3cEfePARXN# z%%t*H!S&l)-3EGoGVIqozk*EoMRrUG9^8H4l3CT zpX2AX6EKu^VkX4;*VbbYWTOK}V~YvUWcO>J7}{mFcq)7btTp&9O#Z+!K{9#G1|e14 zY1BqdgvdA?=avs4TfV1(402j-lM7l%dqRW3tD|`H+jdH&@7jj4?(By^^1x;wF8&JZ z55w_2@-ce!&d17tpsuY>wmhtZhYPcl=f{}~|o2`_`n zPv7HHv8^>S5*|@&+4dXU^hrk=OwxN`tYp*!$`w7Wg4H4NO30g%<|K1gc93T6<%<6N z7$DQ*nC2l0?r|T>~$Ey_-!1N*?|sB zQfX&ml(nZtD`Me?VdPwoW)s{Gp*J!W0?h3!74LzJgy_+JiOxpaIY39h&IZ{>ra?jP zL6r1;iH`V29WrD89+906eCM1%6~6$r@R{EGEOjMgj6(Atz1e}3PKBeUd>r=X+C8R8wDT1;tX31`-k;9HnVysf zvAeS_AQu-!8o>r=V3p3w2400XvJy^LXhyb}rYy$mB;4Bg0l1mTVuR7ZtJ@0AOof!4uz;ZJ zU}}0hUbtx*Z$ba~5zo5jgLLR!SBgf^!7-5Zig$yvCG?3#(cX<&YD&{X^yr)kkhSt! z)S-J;daYP8=6vUVi-OCIyLI_Nmq!UTR$y%et0xE4U~32z_pW>J`xlAr<3aa=ujq%$%);r(X`_=jECfYohgfnv`}U` zQn}HO7lC$tl&L4R6Gl;*8LZ=q-(k;m`$j-ZI0)s-n}SKKSz{nA+;ItV>r@Q%#Xc`b zdy4SN6t<0fwJ1^>Fv7I-EC>3#r3L$QKPdwA(Xm8p*DB~4p0U6(`A-1EZj>aM>C&I# zK@;uSnCV#tG0yxJh{>PFY-W>@KbJ<%rNrN5YL5PeH(LLN+d(BWxi%kwf+ara$Y9ex z2Pomjz%f54rI#PWF!>A_R1$@31pc<ufk{|KjdU7^rVy(O?0*Z%~!VP0|IpH%&eKR^e@ zfikPD5D%N0aqK&83R!7)I#PY*ElOm$(CVh&wm@Q^+z;!@w_a-^LnFrYvN8CO zB~@U&>#mP6Idk$R{bZVV!lj}ur>r>jUat{aV&206JH30e-c3)PgbvyNw%komug5rC z$IF;(SpPmqi*_DnNZJ>{N4fF?n*x5Z1%tZ@rmlOC!KX{{)*DYd|8Sr<|Im)o(|w0r zOuNUxz4y+-JmAfL*ieqjkZUEYp&3851aJ1V0f5qh)tEu+HTYHRw?~Zh!!*>nLNn)n zaZ^YA^Dzch+NzGHnb&0Dy|_C>3J4KaS$X4<#>nzUz~_%fqD20Yh?#TwwHh0B{}<|v zIt<6HRtrRSq5=q}>8@Czi2nmUqsF z5%=rCh99~NbF^bKQ&GOY#)uF;N0gYQHsG!0p}(QcI|pgB?O{wxuYU;RAIWF2 z^Ih`|DKzg(2t{j`!j&mHfNS#;@)d`nDQ#UQl8dq{xv2p7NqJQJ6g1B>pUWlm;P-fy z@RyMe57U06qOqL({IDSzqVs%&1^}y;iXKD*sEyN%quN5JO**->A_(-~N=HtldTHPi zwC8u+IOcbLGUd@xM-TwV0zqcp8sO45^AjAj_8N#6C6}Z3#TDRXxyYZuS5@a#5an+d zN@(VJ-2cAA!Bm#`CZv@cFg4r%1FF=ul_o2F{;mmB^|T=R#!B%6ettN3bv5P_dv1h6 z*}eut4?C`jizCSa3}`l8kp=U6A8J_tG$`o(mrL>9!kt;kc(utUq4<%IBQLo2v6EJ| z((e1@Knb%zg^!flMw4U@#(g@vG4TGz3b}&rOjANE-mLI-?arJWeT6V&awbsaACOM+ zHUV3-U+##b(n1UzEfIt;k~s(OYW@6F5)|@8nHz6xe7q2W_Ie@)3zk(S`S~FRT5&h@ z)rx}%`H6ExHoETXznm4Fie2`7kaH zmEaxEPnUznj6DX?UYn2U$Q?P5_NGZOM4yJ*b+!ya(LWO>b7B-wocR-j27fS&|6_~b zpiLz6XJah?PH2w3?P?3X{x7MPd(Xv4pHD!2d30BN3VpSmi-dEA3>x(oh~z`JyD=p% z01ys*9#T1hxqb{K9>%=>s#P8f-b96c?xfB) zLFP8+fyXGOI0Nu&j}&Tcbdv*ez>d8}czx%9%9}2Mx%bqq7+kE4!@O}u7ue#-MR>Pi zY9rnXeWV+H9lW_g?v`-|-K2d){Fq_GY6Fkr_2wPFz;tkrNFenVC#6{zKk*g2EqZ3R_C!?~)IP_v3?Yg19B zrABnvBU-yv;kIl1o}W*+@9*!Ad$fpiKA-ovuGhM@=ndk$&}fk8VJz+1C`Ug{+t!L* zWcqg70PEYl?~)&*hsd{qwE5p|0Iw*HiuEl&^@Y3jO00);nS`Pzqba|ZsU@l@QdU&( zwyV$BYvu8m!Ac|2vXQO7@&)5ggn(i#4IV0!F2woBR%dN}$=IW7F1I)OC{hv1z6o?I z*+HN#E^WA;RUmb$f4EN76lVUd^Fx9TEWD|)vLk16sJ_~m;3VnuqfM@nN|I8WEcM(A zk}C(Ok4t_rILiGgQIJNRs58$8qEb-NyN6+EXv0^4M7~@K7S-!#tUzS}sG`oc(nQI{ zJevCIZa|b}9(){2JvWV3i7@KbL9x9=32tggeZ^d{X&-x}_AQR@ZJEv~a_lQ)<9Ans zwCk&rpv>md8|&A?Fnp96jSn^iTS)x-{s!sx5`0os1^he?XL$SFT!%eO2w{#Da0x2n zXU7g*TMksx-K5Q4o@mA@_Ojs{gT}diUT$HJqEUEFC&--#zKLR8>=7eDYw%w@U8Hny znNCL0&jJDaZW%(Po{QY;$+)LBuGUVr8f)|9IGZqQ4@6G2t~}FhMU$mCs%!RQU^@B- zH~)*RkU1xIa?>?#5@0ZR4IebZJbdtIL?n4*1_DNQ>6#WKIlKJKGX5(4S>_T9l_#Sk zBIUYGq`#E?8WkiSf%I`*8qo;FgadnK^aZ&zocBwUX#rtgk{A<#CD}VHNNS=$NS4_n zNh!%fy3O10l;$<~HWdD)9A}VpT^XUry)oT@)u3xF5{_dPGit>S&jJNF&U8r}{f@dK? zPLW*;7`s50wY*5Si;<_B=mKh=q@daC13iCx7s9;Wh4dl%yO7*jw!|=!oH=Z))O3qa z73+GeiBTlanW|w^APjx#5<*;^b zV4Spfqv+Ik0FqDdmF$lTamzZ`*P8E9JT!EtQP-~EgYVK~mYp<`63=Ww3%Om(zR9k@ z+*MlyVOOy|0`XM^Q0RpVJhkFy{JYxHM0fc;DJDv^^$;agwTB3cN#)zTOp1t*2B~IB zr%tJyex(=>_3uFuo_OgRC_T$4%&rH8dD%6rpC(s=xYPDqSXXa;rn3$Dzr`N0R&Sbc z`%57G9VR;X%BMY0$QQiFy{In5r^+8W_lQQj@wTuS>nh+Y?GcAMxZ7^z=z+4|&XXR& zf#a|8C%)dwdT|Y8*hf5w%0*OECG9}op6m&wqgrO`W8Zc>ueqxw*dkXI&cX1MS|W2z zu!FeYN%oS9t3q96-%5&*FC%f!)USy3u?|9Xu=L9~R%$WF(&j0CVe;ZQ1pVbA1bubi zu0e9$w>y!-M))={GF1-cfSAwApq#9E2Eg|1Q%7&*i3Q2KS5f}YQlJw3FJV4XZ>guM z%tRAZUl%CeB^b;fiLQZ7PYD}D+(6Qo;f>_PdZ?qb_d~pt^ET|OC_hbB?#QCN^7n2< zsO^p2#34h=(B=H6wnO#Q^DuD9lLwUdCARdZC5L?I42Ds*oAMnj z(&-FpCg?Iw*-#+qX09OooO?b};}GT{p<4K&6;u3@lvf@i8B?7wP4zVS$?^>;9ujvL z;qLiX+yE2r+nHrfxiMC`ZQW$jHWp)f4jX^#Y`lwcO9)F+YTSzLanOGQooQq8Aj4JM zq|161UxrOwkfisf(JVYmZ=#~(072}$tpKYBm!tA8X~x0vasf2s-8A5V#mP`cWq+7M z6rUAbUl=!N_DHIU6WN$lLmR_t2NqjWb2J9sL zaX8p*Jc!Q8H0LC={9L|?2jGey-C;`?3;|s#X->skF%g2|-UA@So}&UiWcgT-;(~!O zTIqKU$y`!Ws!odfxy8zj(LP?%%bFA}bMJe&$#@^kqFri`&)*mTxlh{HSjoR5YWx_@2?VM@elL(4@l4817~TrQue6%nP65%F$cX#@SKkc)$z! zoYnWPgPwAFrT9pLLWfXsnU3sa)*-I?(qtCzZ{^{B<>}uC%DhJ2sWKznJ3u1;ljLV@ zhoGkQf0Ep#QzAHwkdkBkt-d!imNM-bsmYJxn-TuO~-ff04SV{{V zk)Hb-93&|Nb5WTs28Y?R5vO$>;$)I`%h8&v^3~0gs3P*ceN-91$!m1C`tw?d%4Y7a z)*9-^>%{?a;@dBbD*nqr7p*b_fC|PEkYJIEwi-RaicJW`<@8a3KGwf=nnh0#8MxIC z^W&j#wXXT0T$RR-*+Mjw#c`2(d3UMbXe{= z(R>)L(hXPt7VjV{zr>$xOa~InT!PRzd1Y#p+&Dz7`cVnBg6bLEFeB7O7W@a2|JBiW zhw{w}bkeJ#b0Z0872z*|_B`CUV*gl~rccqyOGsU48mEN;iDovA^#EeA@s zXUH;C6?UgdticI0_3%_JF|OoMtN!W;45c@U6&A12}mct#gzG}zI0?1Z7rIsqUB zeZe~UDb7*4nEfN=rf+Dv7+>KgKc(kavp+}T)!aZg;^Yu^FTM*dl9))EFpWIEb;mS-OYxXOqFCSPeGY`iy^O@J(^q#w+y2n!Y61kSpH8{Ly+V{c+Ob_Gyw=j%;w z(q}WP&N4nqTV68FUDleDQ8J%|1Tqhz(d_X~3Z>O(T;zc>6Lq`+n?#BuLm7Q<@fNPx zb{25Q4-Px~OVLAcipe?uPm(wzsB>j5cX`Ybj= z>NkbUt?Y;>>uZ~E%8KtIlVyGqcBgM+-BP4c2Q-Z-2O~YD(G^9KlARJQpZ4Q?tr!u~ zP_%b&9|a7<1YwG2&(9l*0{F;ks>1q{aR=6X_+7dlldlX zs3OM&cXy#(TlaQ2ePcM=vC9{T2(#A09lS|!V6!db40taHmHxG7PEC}IAFXU|>489Z zcWAJjc|akUxzjIL#(xju)OHDIX`4SeU#l`fY@Q_X##$A-p?tq;z_C8Z%TcB4U%3US zBJa6*iO&DEaXHE{bAq$ntsp<+&|+|toHVu#I(ApNI+zP(!pAl_{0(b*T_h*!=^43SzNu*}T9ihihNnnC{k41{WKFYc2QCOG112gJ0a9wQ@u{62+6 z`XWfi^;$e78Rh1>IHrW2oc<>t+J)57h=yoDfzTQjTJ#a9ujXSldb{p=FjIuR}$Gp4=5na*Ksh(QB3ipxx z7RYqJ`imwhkvW*sTf@%2e}_+Xx<^og)LsT;i)tN|A~^-@_CEbFOgtJzs>_mZc{*y+ zlQuWNAXioz2&`$yMV%yHaC=H!KZqKaL5-zt+X35nl`#XzzB=&-pEzrF&^l^R-X0eTqCk4Gi!|vLn$sd{By0@IHpztH^gqQjlHSqg`06rcy=Rho} zaCMdM4g>%>r*b@9Tu!J)&OX;LDY<|{Id5g0r*)vSMmcL1JcJaSeH{{XV0W{(b#jze zy5{mz^(XO!&3ub@S@te6^ogB}-17dUEExaN+Ls4SiIO2B!HS4r(#Z1mY&FevKXLVaE&vF&k!1!s$$CEkl(`$oDr7Ycx~>S0BZbsfP$_lIXGQ3MmO0V%W%%N zGq8K=xFoxVqv)!1Mrbwd2s)OWeM)YND=pZG`}XegU@z!xm-K@8!bc3{mAmZid$ex}Bjc+Wk0Ypkia&rI2aQUwK7bBr<^b5CZNnc| zZHW3N5HF*g*i?m=sbZUrGP=mP#MnqYtl_@eNDv?JHrLtqNpeV0UR2(tz{vd74`WGZ zmPxv=OPW}`xjC*cLumDQN))H2cTBXD9(1oBm&(d6 z9t_go;~QH}t1g;&k>k+haUX{{i`AGM3Y~;fTdlA6?r?H(QX**7pWwBKz60(G6gFCvED|Rs6gs#S}jkeK^STKXQpyBwCPnV=zgrn8zZj zSAkrj(gn50tpy2gs5cfIH3!I%j0i6qqnbZ8{+mD-S@^a#7SuQ}N=|&sd9}F>L}ca$ zr)ZRKT-C;|$QgC{-X7&qKSY$j+^>~(1JJx=pQB9+I!D)TYEG$8IG?^@T2F)uowlPq zdbEk#V)M87P04D~$&O?+G@G_@tElD6|DtQ0rqJZ{yy=oE6)RYa2EkfglmmY-q9_ba z*CmuQH3PW0(!5ZB{Q6ZWX4u?R)xLHw#em@OAXmm^Q#9&^0eauj&Anv6``hF5eyDk6=X`5b1f-s#>R73s$5mcQVgp`9hAk)2PEQDze#@- z4?UHw8fg=B8PJti#+y;R1;!ehibcOVq{>h~#lUeDns4&)cu0<2Ak;Z4D6O)SNqx(6 zhkp6P48B@3jx3C>A-v>eW(CB~k76hFN^_PLt*Dv*%MMDviyXA|W04>&-$7-Q)g8Hc z`fmQ+h3~mHW_ojmST;bUZ2W;7J!^9she8{$mq|s@PAcB~-q|3t92%oxO^--)kQK2Z z(X#3i4A=D&e3Y8w>_F$}81f)Iox$jyAm4CN*wMUhPO&(+UOaX7*C-wu+C;C&ARMqj zhZQ^Nhf?NiTazh43(<5kz}nT%X?{+O;Sd~ogCp$v4GzoWAAkrieAhojrp41-uWJFO zcidLzWY;sJp%m=E-&HdirBTRc4j}FJaEs)H;#4~|MNun^aB)(O%_9SK;R-ejDL;+B zrTzyI-nJb?0L>NOonWs*R|O3Vk(wW>D@iV zU*3Cz&P)7mzeYFZt`orRb#HBuM2PxazB992tJ{M5_9Gbb`V?qefi|!$qWm zR%~xW>^z+g!*%@~Lu=*B_;9r*e-II9(?F&zjZ9FVr(L7eMsjj9u@MEyFglrY5fiWW zqrMn?$4D;QJjM0WmXL*Cn!uZG%LH>8(2{_?b)&dX4-DsU9Q6w&P23-#1V4__c zUT&3+OK7nTr<{a6LSlLE}=@ABtyJSs1JS7O@%V zOLTIvg#R-2#b$GGD+_ClmMgaQTfL)98wmE)Y#P>F3UA(`h7)G)`fxHp;Xdpd)w4*q zeByk|4ko+E%e8TyvSx00gcMplbk1GJF-S@!ucGD3aDYbFk&u3CJ+RlM*Ps{c=Y?d) zE*(Yh%M_zOMoY6ATlsP7G@?wp{NyX6*#x-9~t-?DKC#L;<2 zx;_^0mCBEl*g4=v!>FS%U!UW}ilzSNb&=Om-=__x>_&&FAS# zBHmkWuJZP2v|xT=jvm(K5Pe6d*}7S)kS5@N_QIWn%4bJU95@v4hk2a zmRe7jw)xCZB-wln1ED1>1()HXOiXM!+u;LC9XUm5oB=HJS#4kSggx4thKYOAY52_Z zj>wm)YH-_Ul@Rp9sYw|$!^hqY+wz zr*sYi*=TbRlR$&5-qA9$A1kXW4?9S<(rBHic4;o{-qJJ?lLMzxm20F~tofQ0Da!`} z+`5O3sd756H*_M`$7Fk4WBh8vy5C|h&@@*Rj^R=prlFer#!=Rua*Pl|g^jbkbOmKT zp7rOHzCI3CJZCQySwWF_P`3u#eL17j9w0Fb|FO1)lrO_uLhd)8;q&jO7PUX#-6ShVgTtj?VBg=^LiWKwV-q9Abv@KVVO&VCrf_U_tL_rkTxs>2 zkvV%h6)`|fNW8{+hTFZgr%#j=?s3<>4spJh2{dm$LZVISeOSE#ouMnOo49b#xF*9? zI^!Kac?6QUrXL!J79V=Lv0svv`08KpQ7%~@0T4C1#|1hpoNNXCLQK6~zlEI(Jrd!F z4lQgU)%vva{J0hkxIJI(qkT|;5tkP*f2W(^H7r~X;O`oVu6S+#fG~M$5l{7bQy!ur z2y*|>Wx8#*Wl35MNw|Xxq~w@?xEOvzJ=5TmC_nirAc*L*5`N66&(YVud<b)*bwyN@ldY3wDGh$mt)k4rDIp$gasn zZ2USboFAFX**#?)u>9FJiZ4US8unQUy_&Vw-AnANkQ>!6w5u=Le#lI!rUPIqe}g!= zpdUTe1TOENWGclAUM%5h(=a>qvQm_o8u*8l8-8$-MMm!Vbsb3XeEE!@erm zAy=*}Bbuef*l3Cbs{_4_Gs+27JX7#6Rxh{e<6uzUgmpDkyLBRWP1QVh^52~~6wdns z3eIzfPFORTTiSTk%PgVYi2|v(M@_KdzI|YwNXU|ati8~X@*qzmeF_rm zB_A58Ux&wfl}|f_z{<%sL>BL)sCd#HB8HO2U6yo>Km$tWPA;a4tXqq4M0sYmgL0)q zsU8))`VV9<&PH3iVH6^!k&}3@1?%A(jUT!?SwBm#mwijH(jgn8JN36DNQ-zd+Rp-L zOx1g6z;D215o@Dkga{RUy~lpZbn$b0vYtn@q2#<(yNR>-o~H$vuq%Y&WTjL<=25^|TEPpEp<3?l1K z&CD=ofM%P{(lquu7vyf!Tc+QL?=96$xu5@vK~wk!okriRLE~!Nhen~G4R!ykw__Zn zy$vvL$!;p3kLzP%;z>k{`$s&W^m<4r`>uqzZgIg|UtabF%#VT1rp9Ntc!keiHN{MJ z_D@j$)Z2AtfvQVf1*c!|U$jhd4v{^2cj(!=y<8aw%B#STwjDENK}Q4Ph67sP^1^NQ z68Afbv#fO7k)PhedRO5I9-Y0I`|*;84W=L$xMk}3aE0yBZaMIEe;ctkLiZiq;HTlR#O`oUMlVX2OqC9GX6s|0g zE8@v`TEqE$9HYgdEdYPcOR&(AEKryC{51)({}RA=!3ECFf(8`0C1c&)%YVPaAKevb zFMoM*7#-Ya?@0oK@;()7>B(u(#p+jmtGlG%w@a2;JA%9x)tdZe?p1UL?XodoWG~?Y zo!SR%_TOeSG#M{BUJ4WKTnXq<=7)&!v4U~l;I!;}gFdffH%D39C&+Uh76$(hI8+kX zNd(<~&Wl{H|0XI-Jd7Z_=L`V6gy+1%H5=^W<)I6=@w^Q{ZWlNG7d&AiH}9Ji zBv#rr5-lub@Hn>a-m?x3nSPBDd9B9BRY_=)yA24A?fEvGZdn_%w|x($bc>;vR|rT< z1PDmgD~A>`p|QqfGgMZjAZ?`=uP1IdOmw4Pg4pLY;2e8vJa?J8+lCI4lan~FE!(-_ z9hyO&ZJic^eA7uWe0~pnKgq@=P@X6TB( zdg+qWQX^kC9VdM?@qCD|PB2*^Rq%-8yZQUc;CCInNZa{1wFX>EHrAOK)#L`_d1Ua5 zILGAGKY@|5W?fKo@%z}=NDdtcjgg$M16<@rM+D1j{>8dc^CcRt!6|;t5XW$lVrDnT@;X+~vsk+zCn{>#UB9do2~a(!u0aeu8MMN&Y;it1VGX{QRRa zqVA{ei{fDvZH?-JqAGbjVw;-%ysXc=!}RHTv$fQN;Nl(nfv5GUYjfK8#ERqm2yTLX z4qAr}UF))k7A!_ww5%^5>%*V9g8ovdf3PD=;EupYV5&jhj+%Ob$3FF zJ9*J#M#z@5fM~9M8%H_P6I6@H+hDo#6{!vR?b(PRh9n7@1Dvei+d0UsoBY(l;~d?s z$wV4QcC2#|ZqWoK%kW}2`~&Y{JhEH_h=DAn9@&G=;AMaOt;dQyDJvQ{fL^{IL6BTF z?Qi-4nuJN^s5~9Loa&l{1LIgwI~GOz*eg@gp649%zaM2czDFlqGSPiyZL!5mGTX-~(K~AWeDW~uR+S$=rYtkjR}x0V`^w6b zmT)Q^(iy#EY964_n3(rCE6t=}8p636aHT~s92(f}dV?%C)P54E=Sv7V$?RyQH_ys}y3Ll&YM1lJ?4r(J;%(Tna336n}-h?W{#}W^{HEal;qyw zcnSRtF1g7;dmYVjYnTDV>0+er-IERSc6{`CGy>rVSymRHZI7ar&W5NubS8hwh z8D+UhL^j(fWy4(-1d+oC%KMKvUe=Mc*j{*zvBp&aTOM-Diiz0IB|BBn;ZNU@2Zou zsdS4GQ@aGSm@-Xd+-UW#Hti+%ExeDHyb~g1|6n_lWV`xu16@Ye)^0dX?!hG?-qP+e zgl^7)=m`1w1K#(+wcbf`Vj@twZXK=hr0)?!l^oLsNbA|2p;GTuU}L#Myn&o5!ERo4 zhBEzFY8@2mY}G5eyj&nLYoo{nyOwR*lvl6oDC3uK##KG!9DRDx-Q&MGSa_lCBgm?K z*I=rfR-^j3pDaa}qjp_}TC=k}N`R$*mPGaa{aYz5<>qAG=#-vdCvOx_jL+#wTkx9; zCWsS1Bfl_&AWZW9kH))vTf;zk--Cnq;t!lhBhGN;s^{?X#+;ZRHsXNX^f$cL%6<`8 zZoG)S*`05Xf_{FOxxC#r0FQ>+aM?GVlTWRn?)Ei@ORq*;^JVX(#>>#2P9d_RHquqz z@hrS+Q4(UtTr+6OPmrN&4_JA<>il+_jXd(7Px?omt@ip`;I1qjUh;$gmgv2cqSs@ zt|wuW0gfs^1vXqi6n<&*b&^dh47T>t*pF{?C|wh6Qy?u}NEN~rA0_uEGo_)ab68OM zn!(7oYB@4o`l2A}+km#fcmjHM*@v7enu*vtnh!HDqG>3q0N;DyC^@$g?12cd7D{k~ zROQpit&0G-sn;#mEbqMF*%>_mC}y_enr!tAsPNZ2>0xprflbx(YFKN2;o&OhK(W_& z`jJ`E@;9pZan-bM+KGWN4u!edEl20RtNv!&F~u^~%RXA_Zz89$It_4mes>Ec-UW94 zw zzctf$)TO7-VChY* z(FE8eO5&v$lPpd_;*>mzwfG|=U3^RC`T< z4}-qi_kdlgI&F{6@fOT(tJ@XMe4i}VHsy*7f*Htu6fc55me&(-a>t;! zf_!Y+lBY>Bi&1aZ$g!RH!ql~1>Jc7AgF5{$U0`|UIuA+oNC4>>!Znnm<4@0zO!k#k z-x66=IuEBw)!)c-+ik(mn&_r=5T_B5CNV7~?|#r*tS##kP-Qwhv=aFg4VSlZ?eX*D zr8LBgu(YActz^wE7@0;;~*1#bZt>oI%PDQdYzy=&{&i7!B%0uQi z*`%a-O8>q#4(01!`AClu-tnUIrR7l6W{YZ>n6+&OJIgYP6THmFPqQe>K82(o8hJD` z*i!uAh|=deC(6<;amqNx1r-#370csP=o5g+t8Nff*=27h`SBavc7(%nJ70YeMGp(-S}jNO!5DSuMC~<+p=y6fMO+eg_WrY4#&zioOj;D zi|xKGiS3@fhvUk!801*_RY%fcIGN2=j?v|Tt%xqH1g3+jYnNC93{)U6Uos2 zOMw3S9iu5MRKV1RtsC!y*7O)rj2ZxB$80 zZ1X`S`cpS}-DJiOOWt;^yGdxmHxTeS&A1_Zuwz-4bcJh8a z|7vpjiDh&a>fasu2k&3I7gTIcEz#Mhe*#lcTyTzcV~>$psxGVQzSO(UEs)C>|B68G zk3W#cX}<=#Rag7Op~{XUuHY&^tWH9;+LoA-2cZ3GO+B+^XlUJ&9g-`vbi_4(G=bPN zbvQv`A4ucJEfSIX8$m*L{z9*L-7YZxji4ed9#_t9EcTKHtiBKXfMr{jtDS^}j=H`P2B+XnCh7 z8a{Whr;qhkEO^vEY{sJ+*95t?lNU8R6;jQi6lrYD0R%(uhX+TLo9-B7T7pg|AsZZ` zxWc+XL;nKuanF4m3 zhonCH`C+{GfyJOu^DB9t(uGs3@IS<~4ZcGSoIRcwUXj5{x?V)}uc{`8Ioo>gwJ`NjN|Lx(hF&s)VG2hi6#OAw4XJPJcsu zQxbqG&JqB6X|s+CrnZtr{>fdK%R|+ugYeGlW#|ErGgX!IpCv@~E1%hR*dRHv2Rh}) zB&yGuejGpPO%cjnpC4qfeuYf7*>Qy3iJ`D5^_2ML+FfpxUvn7T^P-4@RQ=kuwQnAP z@gDzgNG2(c4~BC->BqUoOS@=T%FbUWD~7ntG+>Z)S7(wVVtJ7DcP1yv@}KF^cKq(Z z94$ul@aF$ODZP1DDqf(^& zzLA*~O2Vw=J@}3a8?^sVav5*2+ZQSH><0k!*ZZf2%KRb7QXgDE5!N^j2LuNqU=Z^Q z)COr(o-FXxCn*esPP+EO>vsK_Z-SZ=S6;DzDJysAK2&#Rt%VTOoLR`|zB!uWF5ce- z26D`wT;P)=EuIr%ys0VEBZpiy^cDRiAT*^jtZPvc72!~q`yBD=d!r3JrxG_hf?ra=(*k7bi(zhq^tY#JXgzB}Q3YR8~( zh{@m*IW;IDwr&~jQ+^90rhM&Sam8{jDpCsVNH#TEP?XkA)3}QBN-9}H1X?DGPOp&< z*V@DNZzZ~^UN1=Asu`$_3qOSfoe`?K|N9yJ&<34nDvj&Ab z%Ely?MaM`3cPnX#)?Mt)b;+6&h|<=t8`m}#&OAUa*r!YqnycY)g(!7yn(p`eG$g( zPD)HrlV%o8FEF^!Kp?j-cur;E=!VWw8hRLdmLbko=MA)3T)zbuS`CO96}QG6CS% zW*NvmsfW3+$I%#qrS4ELyl}-$sWq*ov&_2d27*;|nBzEOXXn1v+71yS} zxIRa8@@CSRx9nYyb3vJOMx%IHml&w%VfMcavdC8^#_VPPjWVfpkP*{%KDwYavw}Pw zM-M4d8ccHHCI+R;kYmtFYU)jiCwQ8EEmg%sCA3YAyl*iB&2iFgRyZI+oGj_f&%{5; zIpu2`V6S9})h)Eq1+srJdn=vPP)B82b?aP~`2KP6L1LLjmO^ERWb_360dmWJB93{~ zEI$W3h6Bs~rjSeXKR_xntOFPF=pxBps!x>b?;@078cCegoC4W@6^)kSd@N@8xUa+M zTV@i_o-F(S&=ZO>C(6NE0R1>-QmR>=J5Vwny+yk|H5SDFjF#K@Zg)!DvX9_PZ!aXp zX~;;h$>xiqc%(0tdyknHa=ABEb!~f2|JWIcND=0kf37P?`JGiKc66(kRxJ)TsT zB=DrxTg^D#f78<!4?_SqcM9bs?2Fgvn#|wL-k<`n@({LdlZVL~Q)lXep%96ivT9R`B z5!0v-XMUK2gF3`#Kn)35U7n^G#5NGH;rKWZn_Yuw zd~dV_St|>VbwD(NqkG|h5Df=6BT%YCr87~Rr4*%#);x0#YpF{cGBrHkN%5CMs|mE2 zEO1B%Yhg+5{tJnlrR?udn^OtuwF(RIpLjp*>rqt;W@*|nvN^4R{9vS&t}+1CZGT8C zv5LD^?}K(sSiylf$A?NS{aaq`4KvI8!ZRpj+&vr&Gr>hZi$@JO^lj?y!gNCCO1`Jw zG*l1`Gcto?)gu%^6E1s8o!L1*#GYs43r?l)jFMBmP5=Os-=hNj^%JCe8`o>2CI1Q} z<=}ksSE_4JIaxhaU54LdXO@2S$uC2Jzd%s7-Up9r{TI8QIxRJbUK?a zpf%ncLLN=D8*r;SEO6>BKBhVV3a|n*Oc3bans@kO11iw@AC2aD)i*lymaE4sJ~AW1 z$6(V?j(13jF8}yPW-V@peO5CFOU~Q5DlXfq{RY_YMLgDz_gEl4vyy@0J(2L23_#SJ za{>2KNxcxW6b-@fcUqH-6L1ZT(VHoPMwvVZF)bRNV3hJ6mPBb0#+hV% zi!dMWZd{m|r3voxxhI-0%LLp%KMZg%NQZp{-xjYi8kJPJ67tzj6(t&E&<3>QU2kzx zFW!Mm*|LZWa@s@+f1;NW5*{L-VMU&6WBGIxt$D%KKqfP8jzoUho}TSeb0#kocjMC_ zebvd~*@)YVLjbZ>duKvF&Y4e_M4RN}^(1UODo&<-^Jg|hpRZW`nT9|IxC)B_QI~}Q z^GfyOBY)`}(O~ZQ3#o|89F-4lKh(PF><*0Y*F)(-J zYcU+@jI&&Q%RR>f7WEGC)0ow130rD#e$B5T6VdV)jb&9d?b?(1=w*$okib>Ugv-$S zlD-$WjCeysAgb_;p2$GUJa7^j;v*PJ+!KPgwh1E3W#ehm{_O?L{5aN>BxeWEdVLdb z>%+OfDc&~FCPn$5W=O@oTGjpg2D0Esy~)X()me$k=Mq$ZTO;}AE>b?&m-;d!nlJ5U zi_4-^2go%s5G3e&AF`l8;YZ52_)UMq2SS1{L2@8F;*~idQns}tx3QwBy|Zhp+(ATjjZxJE zWZC~7?NfK|H52!1&W*%42M15rY7#qkQrmD;v3=#nC_1gLJ(>O`7*OPR&Qy?~V1SOY&b%^T>`y2cJJdIeX0+REAM}mX&lcPc6y-?*ZH_>x(J!o78zUI zJ}v;mLPCiLmzv@X|C?vgo35c?oUG6*_V`MjBh&blT(0^)j?!r|l=05pK*`qiijvTe zAyS@E$kA1hU(I)!If!ukZF?Mz;uw+WX?3I&zna0PAKE4c0(rLr9&MrdKp??E`!yGl zb)*+gt`b{|+;{>tZ5e8757{&QIij@qvk32BUgmUM+!Ka+p1)ZyO&mz=NOnN^TeJnm zh)*Kb6>uO?9VPF zG*g|WgeXv_RaKb=`+HB|wYp_j=hIeGqupth~m_3owcenrYyNag&T_yl#SC1qLyAVzC3ASmjbA zl+72oxR=j(MQZbOzIm4{BqA!h@Mf$SzMVld7(8T?ZAN#wGBzwldj3H0VfM+16+o>TYY0oem*_e$|yK*Dv(U857W8~UbKRVB)&oj4{ZJFQK^3@8THl+JpnK_H$M? zgJS5Hj)T|-c+qiWCxO7_ruXc-D5s3n!19a7(lzR0*dvhN+cv=7CIH`Jsp=iQtKe({1Oj&Ul9jy+Y(20|6tQ%2M zezA%GF|((1YlRVF&larpr>{908KhUIj9ks3^N%YDCf=*H;D}0`y;|**wM9#I?KndI z2FY^P=_7UB%3#ba7u8-(l zhuYIcrk9gB^V3^)K;IRybrrmQr(yXcN(L!zX^MmmP6w^&E(&*4O<*}*NT znqf8_0N(wx)(|66*$8vrchi~W*d{zgk6zeCNz)x9;f(2PNUY1iE32T^+A{^VON9=% zmr*X{U55b=-IdHH`5Ka(=u~eRJ{G}k`~K{$%v`TnXFOw#M|E{|k8z<*7Fd^vc z0s0Ki35il>KN`#HuOtiBmpJS-P0bmELBcjx-$SC*ZXyz#^zeirIrlXlp_%&v^%Ap( z)mS}+FS*B!oWJU~X{stN1G(Nk4?4W<6lYG?1^i=+ues^)12OFL8JFph!FGPuFVI&X zxkL}RYCX&uS_iC1s80fd+B`x<2q_XwDEtSG%T4*Q~l+kaLmGoXdh}bsUBiB^Raxsib;{G zzuYzUk*YoP5~-cFr%h&AI|p%X;R|LQ-0JG@uf#E^n=VLVjQp|9%DkdigTQlZqFqRi zUgYdkURCNPBV){njXuJFn%R0~g7F_*Y8n0{*uKQQ(adx(u%lTN^4)a`>C~8)#Cb^}w z>jS2(4**F${|z^4@mn$e4)nsUhZPQ$1z%8>TaKYOo!bn-(cXd78om9I@-v2#ad6!X zj^!5)>6O5~i1N%LH`^`+Qhgra%Gj81efqYYr%hb>f(1kf>j(+(wR*oMhAz*;TVr|{ z?_R!Lh!*IA#N|dA{_s7&(Mv7e2iR6x>Z2I4!^Qts#tpjVQgm3`M#H(jruy`fI*#)$ zzZ(eGr{xI=RL{nxQOUB;2n4)#0i|ZnQW|K*POlv^W~6#Af98muq9{~jO$sJ*dl2EJ z^^UNFc5106d)K3svRp#P()FJ}m-3qzsUQ?_$*phc#fy8OKk06PINIGV4KrbTL@pH{ zIfRS$8eU_i$dFIE`vggw(b4s#>jTIdx3;tjM|bi57%Gz}mz#xzD)|~+l<9F^PTf0X zw(Z;|xxPhgW@#-lZxh%+!3N&Z@+B}beVaGs(WjPucen=WOm1|76J@ zMLK4}t2icOt~LFicHGbn;>KXZb0vAzLvGBr=oK5XUgplGp{=NafAI0rvMolEpsQVj z*ixBIQ6Bm|-{*I-_N}d{3OfGjN;umy3^m!xmGJGeq%a;2N7)i3t1xjB613u*eq{G= zrT5RAo)jX-uLU}lznTfi^mZ^ga4TY*WaK$WsnVsGPQX+3vN2LZJ#ksC#SZMko@QfD@gSbWMqJ5CCx#qS>ToICwIT6!Cu{l zFm3cUKtE>)JT@xKZyEWG>Q_K#QLVvdnO69RZVc5>F%Rb=rxMDZ8t`7f?fMJ zHe5cN>Kh`R{(#@Do{Z3eBwJic-@6AvUtWnrA??-=G{mQhV9EK{IaH^A1+6@H1fT%< z8+FX99NC2}WmQs4tX+@1u}q}X5U_EPxc98t)E9>ylzke~Fl#Np@6{lkb9u=(q`m#i zHaIt%1PQa*V##ub%$|VqiiV*Ve>YN#G z#_G8`n%m^7^P^=-vd08KUsCkdp?H(dq`HWQLwu5qoab$jzNZou(}+9KX0Gn#j%9U| z)Z}>>gzv^532r!@0Euk*mn@>{HYncm{k=@$H-^i*YB2>;^Iied56fyb#ei;xOY7Q0xi-hf*k^6 zS{LY~A0s&CX$1ikGZT{-sDu++b=F4w!ulEVBM?#T2B3x)E0I9@=;1%+$HJ2DTgIoj zKHoFewnJMvsfShiZ@`a3kD*0_2an8?y&saf+xsck^So&QDn+|!CSHwa=@-Pig3Z^E z15$Iy+ugQx8~JW3m`ZdxYhcs7NKa;rMlfr2u#1D#?qwH5hoL{n$<_sG`{w12Zj&Wj zf(hSO6KQ6gMvT4uF1eMlPAe}@m+R)5_~^2PC5j-bJuyZk%)%%mJkopQnIdkn{C^4lzaY`Q0qms8vmqmQ+fMR zkW}}fvFo*-)0^GRy3?Bz#IJ`(lKkiv954SI!oZh1EWCllmY{N}Y6rkJH%&(p(MG4n zb(K$<9hAbOHVj%JNGop9N)#-`v%G`kstM(NRz0T49Ir)I9zBT*Qk`D#YM#bb$sJXu znBn(W57YXfhUgEkuK_`N9*Z-}ci%f3WynGtjU>1+=0|N8!I4$bmCcXbV6~U*9Hn-$ zm%T&l%ntd3^2SR)EA^AgMs>YN@o}QLozB}^v1^Stj~Rzo+Z@@kGr7vGa^=0Bc>u@~z?vZ}2gui@6dqq)kDKRQLoB%kPf1 z3G!Dm8B~!{;Esr6u?@cdj0})o6=srNz!{bdOI-IN*($ zY@`HTfj<0+o}V}p20I3^SN8=bzaf#70Nr+(93|aP;0L}QN2AvCZMyQTKFAv1N#{yd z=1R-PA%MG`hI0_N{GBB@EfP;z%pCyxDO+*D-})B>JgXN{s&9wd;lQ|$lAzi*AXKb7 z=#1&5U2XFRm*>unsN2u&dty(si&xrQC!)#GQydG2HClZPDNvU!@$ml3h|2UG&mG|w zz;!xr1S-kGEbi3LZxRKiiNGj1?-xX)<4%B`s9xgyI0&eW40F63-a^&9Jx`1Ddr`QP z{4Hq0XV#`PlSg5({#vEGgXF874Mg*16g&dZB#_j?4?L}HxX>@J3kP)mk&{3fPALN& zi11KN%jtLQVx@Bm{86*Rz!>$O(9h*ON)Dl~viXX#vCmpC>P#QdsmJ4}XG(mijB1X6 zuodos)fBD)mn_y_=UTPSVIw+Fmh%4r4PF6$7WCSh+0 zHMf-kt(dB;wUEY@^ec?iwky<2mp@NoD$4D6#PfbB0rJZ~bcm0>H1TzmtNWj+oU899 z(K{5KV+41}c*5*mUr`B6{TlO-kDVq~u6GV;%tV*IR_y;D1FUH|cI@aevgI^x@Uoj6Kr#kgtYTWAuH10TUc6g!nW~`N zzc=Cb5%_;hASHmci%c9uDfPcuQihJ`()YEArBUmJWqN%&Apl>UGdWrRFuIgi-$40# zA1(ejQv!W~$})Rojvkgzg0545wFC8j*?PwEE}ZS+Q||S`{>Sa&xrdTdYNGS~(E@Bs+*)z#Z3;m0%>r6B^{? z&}Kq@?x*DG$K1R}N%XK8p{8}8Z)i}``0xNLHIfNz)X_4O@Zur64pJJ9QByC7H@+C2?A z{T%@P7FAlUCbH#d(4cOcgIdX{{%OD^UBVnRZHpC|{PLr?(mP$}ek2qjTqZ<7t{3+L zZinQ-O|_bBFyT*yRh~x9+w)^kODb|wwcf?WdQTT>TQHh$%NUI6hRAtK`o$rms;0kH zhtt-)4>VDo?f~u>!h!$lkfT}FjX`YUKnGO$2}!UoY{5nKnYL83O z`^^;1$zYkiCSp3+*p9O9Kfmhg$hO(eDocc?5>Xy2WkK0&N9Cu!pIUz-qpTR3eVUr z6u_G+DbTO;2j$%st{6g3L=2ZlZ4sqdPGId{mBHs$XUm)#$8uAn`PClbk0WHoHyo!( zI38mcHMXE8vbf`zWY%K5OnFQpJZw6DmdyTWneT_b_t6Rvv&z%}d)cU=&UqAzWx8w; z%F1`z+c+}{J9mhz@S)`YrwxH06(^}mHs-JmF1Nzlw#GoLmm1G_qAe*BE}?*EC+{(M z6Bn&k=PjP>!*%JQd_ zEbHx2=6*QV*Imy2h701*LT^t;s{S_oXN=S?)^w;F%cRzZEq*Z?IF@?!sB2c^p94g< z_<`7Che{+z6%XiOgG z;;$Y<{`Z?s%~17;jhA!Jp`%fdDpLza%JjCVMP_9>c$L?`?;++MCYSQ-qxiJ*!d)CP zMi%6brIp0?g?MTmOSsu7q~h8tW~v2KFU@Ps;ThSAh>NGUDHy5d{iLQXXVga(q0ayH zI%^rOl%J19K8@yMQ3vKbu5U@LK|k#;zt46Lq;_N=gSV7B)9e=9XD_|ug$(%fKZtMo z-#?D8b_)E|gb|FLpT{e6fs?9_Pe z>+XKpLi$(J*A}xR?&oNIFq0;Jz!Inkb(AvvI>X+TZhG_uR9{i0dg@bO(Ao9HG;hWy zC_n$%j%087Ija89H5|2>GvOXSJ3|4?$WpGkEy)_`punwC<#wgl1?_c6;9Ak&rZHsveBSYId5{3ju%{zM4JX--*y2 z8qvHlvbeQvqHJFZ9i#>%81?}9pU|KaWFBZ5Xah!vPro2fO~HW6H|_P8CL2ft$#_or z$vkjRIVfDEr}AS|>#P`UL$St90ZU157Xtj#hZ3TBBp*0w0j8=^z6ghFTO+iiXmysK z+Q5R5?jnQ0%Z_(8<%?8pc@I;~|WW`q5$x=j^x_X^i22wv3I5mhX(lx8;x#gz<40zr)vL47Y^^ zb-#s|BGUnp1p&xrt2-Um@^=*(RT6MWwH<`U@@H%sS`=cPCh~%|Ub6Qu_c@;`#*eu@ zkDNuWboLB4|Isc`9zFw^SW~l{qovbjwrTBO6cHYW8Fs5qA4nIigI!94RH>Z@ZjQz{ zM)n&~dM=AJzAxLyqCFT9W&B+ZZ2@yFeII4tnW-W5{u_9JH zeTCvba{>sZ;{`ypf0bF}s=20G3-Y}03>VtT|3}t&$5mOs|Np@{Y&fjLhQm5+I1EM2 z0l638!g2vBjzT~b+=}H$bD-$CG8Z=711onbrnv`}nOjUltyHv9%hccVzR~)8AHRQk zs4>pD&wE_gYhBxHBBjLF)^BmCZ-jjIiKEe49VJzQkW~4#wc*5i@I->8Z-m|`PeS>V zeIzeM`8V^V6!oh}d~q=#0>2u?7ni0%brs&UW`w;u;#+PE@Ymyiz*;tgcY4muNW_}S zqmhJuMT7HWNg~fI4u-jA6%GQKgm!=RHI|B+KI_xn*Iw${G082`8$hkMEsHYedt(c+ zeFjst@=Dj7}0yRvC7BpVx9~e&6_eyrdZcU z?8uDM8_XIeLR4lF#H04+Wiuhhf5!DFRo@cJ7q6#)sM-&Mu%Q@}+GhhOKT+8exv7Cq zzwZq<81!8dQ`6d5xF{iua1NEct&T?_uv6_wEZTX&FA8RK>b@v)D~io*Dju%G<}rj$ z~bVl=6 zdRlSTztNqn9-DFy%*1urXWsb}gzVB~o-`+;wb&_k&DZoc(eFwXl>deqa)@$EgWSGE zg{@AjuUz70$*ceLo-XMQeTge z)~FMQ^wSIwo2Ot=-qmn!=|1FPa)1Vj(@;Hkm?ykeo+FUp&js9w+CZ?a@)NkqYyKv> z=1e~qj@NjaIK27}a@vxk91J#D+7+{I+6WTi=3`-nOfPsGYAoOi&tR8|VZR~9vE<4* zHII_~Tndv;?%ra_;WBYFT`+2-X$!C{79d4wBMM8)?-*z-N+ZNynGYR;x7lwjdT({6 zSB*1$XX9&BU+U0tZ77t_p<)-EOtrGrRW#m6>)sNn$@nRtHf3L1hcliP0o|1XfCWfD!156LlPBk54^p)62 zxTH_*<{Ga*fhu@QJTC8|X^27$pK-)zjHi;yTu4A{-D04)*J8H-Sv#3hoL_;OryiJe zRuky2vH&Cn+OEXE(DCVPS}X6oXK|j~S(Ru|@*MCs&#?4tPz(CXgVC`%E0vp(15Xmm zq`nu4Wlu*?GL_eHzt>k`d^;0P^{n!1HGd-h%h})&Om1gzf($E11My@&%C>dMgkQa$ zQK&}$yG%}kV>v=vlC3boXvQ}nsYU$=yGRYi9a2+EgJUrsFs79T6K%U{RFhl!;(#|E zL}^v)#WmRcEQXZFgSk9jx@4DA0u>>;0z#pL5(+VhbafA=w~U zXk`!fan~6OQ)4S|F6OLgUl|M25;PGczA>T6h8pzF7ZfP^O!5=-2bm2Tup6&U{gqfp z%Pxh8q(=6%!*tt>m+bVIkZ*OEos*z=;8P^^b47x+oIFVFz5OLRz%$xli0JRIbq|q9 zG=|GUx8S$`sKfa;E$Cezf8jl@hR}>(Q=}#uu9-e@7FM1D!X2zbF7)lgFFP0pUEHmkQVih4ok056Azao*j@lP?}Dtx7>NUmmB> zOUa{Etxrt!s7ROw3-SREX<9CB|H4P49na{E$IRKE4{hWVOl~_j(&1I@W+Sb9AN1}1 zkyyr~y&62L2O$qa26TcGQl05lUhQUUuh!72*Na)S*MPINH|=aJyOKUrk?;tG`XF~p z3#GB%-`^@j_FauLNcl4g?VgUPyff`t2oEmc4z4lS(1bl9TuJW>WWRAO!k%_VBb-eS z_#FE5retfE%$BOEioqk>QUg z)}z+Q3o_!vsz?0iF&*cF=T{h#9lbc{uFhc$b6uuOsH7I68t7Gn!z1iVpXLgcp-y@A zm8NTLTznctj*NaA6$c_!GD^ueA!EEaj|`g*u+K#|*$S8Dfu6N211#R&%^^l&ci@$* zn-Kget7zpAbRx|iY?2xzMb0a6uWP3mti)v*fH}#n4yOJFK#9+YS1jyC-fS;>dz3g2 zIRTwU5UMy~g1Jw{^3~{?#^L)^MXA}pv)R`t0y3yW7E{x?&O6kQygMVEtAt>0l4hII zrhWeu)v<9qm-uX3e&*fP&|ms2+)t#+I7sZgM0>HG2cJ=I4yrY87i3b_BxDh&zN}Q; z^IxT?7as3NeN?^#@T=O9-(y^$F`5oxPT2CdCPvo(jB=`a2W9%#wVZ#IpSW-U^m1z@ zjYq~9@wMq=jwS zJ;u4FBcqT}^`Q?calz66S4e8)R@!=%HKg&hl;UDI=m{IqE;|-sR%;VFFn84O zLD_>P&6}-$X1JN71h_@ID8D^Qe*Q}zDepXr$MzIrLG*3U*i@Oekvhk54z+Gw%Mkpp zU-GF19fOs>Ta5&S0>Ig-VW!~n+1^nS`z!76j&z*zWjfnNa(GNA{g;L}GvIMJzV2!S zSwmX$DKLLkBg5z0XyyHU{MJnIO0NmgTUNg)1`bN{gmKwG~()Z$qm*hX1&OiP!ogK-4vS0X9HaP!+qk5WE{b~)xvWym+t zZKdiUty}(nTC|ouP<$Nmh0#*kjG8Fi;Ykxghksm#>hw%UBSBd~NfG>lksXbGQoM_* z-MGRLfc`e2R^I-|YHI!@7-fzR3Zazuk+W)jLu_PReW0$Q!z?6C;h~nMB;d;Xk?8+7 zYy^Nx9k1NOj-;4QF2y8~Hqikk=C=(hRc|Sp4y)C#CF*<4Pk<5Xe1e0=3E(Pi5|Sii zx1oDPqZcks!l_c#)Td$7Nl{lN>6z1YUUH=#?(KZAuTMq&P)m9GEw>;^*hJOl`)Mqj zbk3vgevU*dHaJ`-7$HJs*g|-hAwM{`lcwyp)YQJInMmqBZcTi1%?<}EajMr+Kz#!&f@cE+ zHiT@oDU)DU^Qv)^W<3cBmmv=+*|e)DEl8@hmSyu2m=0b>Rk!dMk}6epc%c+2^|a>@ z9CzFess|-p$&w3^=PnE%`1xR@QI-bbv#V~N6eKyGOnn_vZAtX$`y9T@otP2W=Yoeq zsryTpTP*mxvoT%dmn9^5mM3^1#UFs7rzix|THV*UQF07~=|?`at6)ZnOpvZ;&+rsmEb%Z^0?qOHc@qKplTPq7r9i8yH_?|5=DBf#f=%&VC)7dp~; zD;4{?<<#y)H(8`B%j_M@(;2^E4FdtUPnqxvJkrjEfui0NXDyC$MV6m*a$x2l z_U&A5@34c`aPq&Hvq%TSS-T6k$f+jLM?`usfz`bJ~}d8hsW z99ri{yoTm6>dVyW+`r5AQv;%wXFkj#>n06+K>Z0%sp~aTb6me3JmV*IRy5Y@e@D%udYM%b)TNy)?mKVAQj1-qp1GH8>n_i>p(r^K zLh$GH^_*X0i?MX+tH3}G@4~cL?}kWW%Sao8gzO1w+c3(grZdQjdjQbsx4-g8U*>TL zWZg!vSaci&cf@S^>*_{`a&OO$Aa7=_N31j-i0tnC(O_?J3Wf1k=tC**1#D2*hV8YW zCGVwfK6G@j#T8cWBx^pgDiHp7SJjT)VZ zIblJxr_9YElwsJ%=%N45_#h`)aL+DYL54WMKJl`x$TCsdd_PDC2{dBuN?H1TaxyVAnpV zf@UOw42(a5*5_j{Fzf2_&^V^`xkZS}7F?GK@Gn8DtU{#fIL{{=EV2pR!AO=KG|}$K#>$QhRc7rT$`OEd%QL@%xuj$~oG^J2WV@ zI(o4jIvl2ES#dthp(1M>0=}>CYm}zCyH(`;ijO&m5)oe^t%gg8gUl@EfIQQe!SsmJ z-Nm*5rHO%@0Lkt|kNmtf8p_7X)D3+~6ti}FA<40^0tztvWbm!f9Ckx|%Am`-esn1~ zOf_=R7ay@{MFR8dDpve?(=q5A2&6A8P1X99X^WngEorEy8<*XVQLd;A+F&%E)% zr{QUBiR1&RdmIr%*b?m?0uK7*eMnYo+S_?Z`cR{$;@V>;vC0RM)%{`!k~w++`B5=` zF>=j?8?)>!Hsyqy9KolTfE@N-7ReRZ$=ORbUE!+S(uiNEe()Eg`0E=3+?o9{n=-0w z4+%BnHW0tKmvNvHzJ>Z@=sNE58D}wSjq5}Xn{Oq><@`I8#p=AvWg0WaUMlCc5^f&a zqj1P*#gh*i)Wn?GJw%J95^po*KuoTo|y0MuFA=-S0!BN`ur7UR@MEy0n z0v@Bt)1|32O5@+u*6!Y24&bi`ARa%n!yZ(7HoSFqAUCn`DH4$mjVUEkt5GMO};)>nVhl5*vOy!Au9Lkoo8!{w2ZE*gG>@MA9!DV!nFTO#YD2e1PR9)q0 z+xvM!qU=xxRJNVTsP&wyN`bwWrMA`*+`MHcUcv{@!(W+O;)f*I$}it=tnFz8igRYS zLzsAX!sT7vm%Od9aL9@zO)KkuWtpya1Iufc>FU(*v`6I)Dk&a5dR$!IAVp4}U`dnk zp(SgO;qJVpRR93JC&F^9>Ei2ddgS0|fy`#{S?u}RL+k_hpYaYoK1~jARtN6oq8?6G zuXGOmCpxuOIB-zGdkKC-TH4!HsxASjUc`y9bR`Vu;*t}wynn1CJpg+&@+>O9$c}g&6@9$~W_fEQXcx4rww@v+;28>)+V35#D;{6c z%l1bw9w!E4E;(NZVmIY6n;a=?!wN9((3zp7?%tY|1SLusc@Bc?S^0F5X+ud#YMdQS z7I9jbz1lygT|{(~bDY(@<2-4ldDU*w(lsocNfDnU+EzGk4OGN~K_<%}H(8#-3jSyZ zGGc}xz{yMi5)SCD4U&#$IIkyt$3tgI;4AoU;1LRM2E+h!r||f$-GdBMQ!-LNz$8AQ z3D?knFSuj6Y(DSMNLu}j^2yc^6l+HQe?qdSZ2t&!Kn)&g<`WYpi~l6rdq)r-c=ZK% zOvI!_Ak~0i_q73WE%Ro}tI68>Pb|p7)y9&R9Ly{tbcK+~CD>t1tLYO`7x7zO%p@l% z{yMIQ3no^qnkgLXNp|JqEio-KRVQNZ8#&mr4x4wvZLw1w}B%8n4PF8gwG_BGdF0Cjv zF+dhpKws+@;rG~dgA2pp!17>PDm~E_ls5i8ZVmdJ%JWR&EZ-YuDF=4>ca*GsRM+0Jz|1pR`gG#H%)Aq7Y4&zS!ba%JN!|#-Yq+(HgLojp*@6T= zu%n(_wGcy}aU^M37nJEP7ylsoRym^0)6-;XQ>uSe-*k6sG!;WTxEW%~0?muYN!3M= z&q^Z9<;DZ1bN%<8r~JZ;eDZ>BJEO)tOeU0p_?{Utul zC4?l05D%M@Ast5y%_tgGvFcM=3q?`-R}zToqC$LN>XlKD#YYkH25ljOQgAJt=Mo^~ z3<6vwg%uTSC^A@8$#(sZSp0*pa`Su%oM*?k`!O+EPRu~l-y)M1UVE7jr2h?YsqxP_ z0J=M&FZnr;bI$cPSIi+Nk4)L^3M^Zbi`3KQYrvK0G(Zz=ARfNLc3cE%-tWFOf%XUl zm3ekV7o-&iG?nMMJd>QaS^DZiY2Q^ATxCgBH)HI2&23Pblqu+RdLN@3`PBfpSi6Hp z$>;$&lhPR3+MOam;?#beVyQ}Vl0Fx;v+{%Fc_o{s?sGjB(=WNXe+d8_S#u+iOVACy z)&H4w=O-UkaZ8`ugyi>$vl#KL~_)Qv#oA0zAAiz9uEf zXTJm`%IP1dd_K^7c*u}Z=xORtCRv#(xT7a7*7(pjR?pz@S-A^gz>!M{22&fRU2Ui% zqioDu5T#YaxNXPXqk7#};}RvFxv+_hEVGl*b0|hXbVFtu(2M@4N=e$8U5R74i9A5|eEa zZIxG$-J^{h_|}Z!Pwn|l+w7s(*X{_7t9Ut*`s5WU5h$09&_hGV;{jVUhUP&Z0L!BP z9IU00dAPUf9V0(?2Wehhp>gJ%CjS&-d|@g;B#tkgi&=9?Nb^XL5i2a!kkBm>?Wer- zitD3nBs|(WmRM@2`xeYuRNhdJK2q3;y_I96?0k1B=)UG}h}5s_5fR6NmiV{Dr_{8C zc^7#z5`yoxA;?oY41}fbF~zgB^bU_UO2l5RD?h6d@E2uC)!zU&+cF6Oyypm;86UtC z&Vp!AKzCxd>Ipa>aTv@dd=*8ay7hatM~KhzQqPNa0~jd6XxC8Yzfg~S`))Y<`6M3O zEj>AM+y6;q4Jf>=njY1Qv;amT+eJ61K^dS)&hSYeW^#Ez&ZlAO_opRsctK5Y+>A$B z`5}VY#XInZtNAx8x(4DUsfV83>TRDW#(@Dg=G27`A3!oi=pYNX{}mjgszhY+VXp2O zdb&`>z$MlGiPnk%$oJKVzvgW2jMLDr$?rtBl)mjExY~|*M&RnG41=yceNwA~Sa(^0 z8GqKU7*ApLGKv@lrR#cvt=@48>c!h9=+d1h!#7;siDhH{@$kknqyqC%&hJ3#GmZlm zj@`qNS?Nd1k==vFMOWbJT2X%8Mq
  • ||~Vl-r%_4p>k;h=gvukm4+7oUOGfHcA=h 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 z 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%0D;Gh5gwNp7tFXl4o(#tbOHnsj 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%0Dl1h+mqV(mk%dRvVu0-NvtNu-Eez-; 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 delta 594857 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,{dVR2HN3u|ZQRAlbe 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

    C*AV9quje_ZC*xi{E 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

    E5tCfRj^=&CX+a*sM^YN4y^ zFsyWakM^Flo#_95udZiT^=u23&}U?F^v}h2aP@aM-Z9^D{3y_)eSz65JH*ItB+tf*2vBU%4S;f*r_=Zh;7G#*ek!OMIC&2rxv(w z)Y*l_!DhW(CnW0+dN89&{V+iv@L?i@!u+M+Bcvv`zeS<6;~QhJG%BI=den!FQdJ&r zlETj^tTnAE`I zwAvN%NcQt=-K6sZ)I=XYPXT_4WC3@%%(iwL2fi3JpA49cuH3Dw*We7jc|5p*hHiZn zNoUWla`r<%y8Ay;17z3739OTO?)Gxv07c$>FW$o(7taK{aU&4AcQ!IruK@8+;s0#B zL0MeH7;jDL|`SFp{Pg*uun|%ce6EAQKoe`9q~a% zO6P6%7NydlQ>u502U-CbuUkP^)H;LLw0;Q42r)|<9r^AJI_cbA9bh(C%4^?XJgS? z)neIeq}V#6mtj?pz2?uL?{hGSaZ|}W`0ENh*NYAO-SwZs0#{ckXI_9f+dI!^kdV}Z8|!SM(WX;Fw92pqrnSs7k(QbL9QXRxGz2x)H73%7l-UQK zz6d*-Tp~Q7_yBZt_33D5d3_HnKXy5ds~VkA+ZTNF^KaZ^&hQ-fPJe;0IxNr%Q|e0P7uf5(ERFTo67a}BjbXpWTcRne1HNtwtg6*kHGWV^Y~OE=iK*uT-R$|i>N6Jn<4f6Vo*4`j=f~YTVC+p2HFI=D)oOw z`cYePY769eJuG>^RivHyy}yHlIL!F@CZ)!HA|Xlt-UNAgo@A-HGYfNE$|h zES}y5LR#HTrvWl6@8RoZo3Hp63S(m8rRWNCn6h>tf2uJ+sFCXbk|Qx+qgG4bi`Q|orNAK z{?H{#E?7sttj%kGz^3FjhN^>XP)DU9ptjPbIv}&Q*R%1t@ITe9Y-7}!ZkV=RJ!z}>wB4<{KGFjVZ z!o+-8qU47>Y#o#)3zCRe0L+P!u``(KL9Y`l2ks+B{H=lvqjR%eyNSc^pgb<6acIi2 zu_HcT!D)ZaF(nxLAfm1UPqcW_pEJ_yE`GU$J9OtkK~ycv`|6x4=W!oQY6r2me!7+d zF#%FlJyhiH= zN^_Gh;A$q7idiTZp7%$JUs-J8gbYN8RNXmI^Z#uePjUX)!gQx=*feSm`^U+-3f^H( zPc*kL3@As+9)Q!U^ip~&@a>xX0RKvB)awV9qi=T3BVC=W@F1!6w{g}Ka>$;8ntYZP32o$?A zi#$Xpr~7z1itUZqVA*XX8oKTppjrI{vsN2UhB2+ulQV%~^kRTz$pPL>4eit(qo*3J zEQu*d1FP$h&}`ktjj7JiIruGH>bagk$YE!ADpkKz<<2?@*0|9c+-u?8AO<@sE=~T9 z@zOm_&oFT%Q*!VCd|Cv%MaaMo==ifPqA?wpNyHX|`+OTY_mx?U_?Y^pYfC~_%qfr_ z+_u@*^ii@Qkak#&TPc`Ktu-i`FIo5*hK7Shu(@Sh(4@?o%Cv*<#W7}S`WxtrVY`j( z|00ZWnr$W?rY0HD-N`R;1KZZ}wqLs!?u5H$&JjnGRFC7}3!cEua-$1S7s%IHuW!@K5>*bx|q%#rQO^k*zs`u=0Ck7gg@Q9Yeb~>)p zSgngP{z1(%hCATUOJax3Myq>JBkP~6@BAaEA zTNp)4wJ9`OewvLvQK`8ktrrBF`ppZSXtVylN!@(E9zo02H{l8f4nV$B7sG|KQIKL6 zv|yC6v5=UqFC9qG0TGUn<}0zk{CheeV?SeM(+mI%rqU$^4A5;dHTWYYPD+*{(b<^E zpLWpl6zj8Si+?kt;mz|VGHX>RdIn}uxX9vNiAY`y5Qi_`qR%>U2+GR06k$%<=D0|4 z=mdoGESNKR-QpO7EXt-iE%BzBvdl`*$h3C=3~O&wa+lUe1j*NHY3gb}AscJZOvs#N z&k1`iOrVyk`iZhYjT)^^18p|+COLQ76=S?+%CxNZ9pu2Lp^S(6EW}?bI=Uyx>LPqF zWzO;J`G`n#jT5OKI%RP8s|Wf|P9#F5E_K1`(wm}r>nREryc5cJqoS!JB-`5~*tXMD zro`9T7>TZQW{qUD0UC^G%PwbZaDbc&>S0@ zqwwUgiqhW*oy|dNSfjVHl?i(T8P1$-2t@>0UgYPe-0$1=N1CL5eV~I1uk<;}a<8$$ zs5{OEhh|PKc^VCalT8(`)*waifvB)|Dn;G717PUqb9uO?Z&5rP83(Xi=)jJ;Y_!(P zfXR_eJsV8)Z>CR*PvsG?qM^3n#M=)6>-GN9=;##QH#ev7C8KYaInzM+SM8&J+4GQ= z{m+UDy_OtXz%u7-aj#VO!(M=SGtLu%>ngL;G6&VGfyVa-n=(ek2|;&A)U2}|BH zEpacSxDqXAwUJ`JM4F-!fCtZy|6<~=K6*(VzyjGjEfE)ddlWmR%iwuu&g5c$s7%U2 z90*W!+FnUAsk^E3lTL1Mst0<)Ctk<^gsWG4bTuCk*)gUaq^8#ae$|<0j5j~0iI0#b zoe8R#9>^9^_N(=T*T6OL?$^cpMc^uAG}PaP?D%=zsaYDPvZ{^ySX(~@bCzy@2C!ST zf=9N)o8MaN1l_l3uEv!k=*(xJ;U|YfU_WpHVO3LDhqi+EP6>BtBH#OahsneKiHIY+ zI3Sf-P3HxD>?}jqQi&uEv-Vncl*1vT)XL4?)LB6da>iF!z3(n)8~kPVa&EpI{R7>d zO&xMaa@{q`Jd9%H;pDT-ht8sSt!tbF?*Z{E`v9vFiQo(_zD@)VlfI1d_n!p8s?!h` z9>v#bvqaxS%C;p2$e!mw?r+X8bdoNY2%m2#wIRo#4KVYbKVkMeuR;e`y#fj_?K`*_ z!^Z@nE&bI@vcqm_&r&;Nctd(8A<3*jO#9k)Hd|M3Slb0YA$q%x6N@Il%9^|XDYsYE zO;E$y0hBi#zD|slgPBgA%Q{mV6n@G1#VlK`yMqRkEYfuVFwJy-9KLxo zsd&`jsAsbiajvX@HEr3Q2I#>V#h~6)8Bg*pt=Ho)?yK4*FuD_-fS;Sw@g8kVfaR}x zgUhIP7Gl^H-Q3*W-IWyPA`)+=n8xOif!~v>Au&Fg-|@^r4OHH?4gql0CSGjd+f;S3 zfbRC$$Dz!k(b$HFQwyd^9EtW+MI$uDPeL_vU^1|0!979WUd&?>@XzW z4~gS5nW5mAMVyekF=q&B^>Ri@U6I)=@ixt>mQAI)x?zLuC>R(Fy4aH{T%w)?1QtvZ7C~2=X z1+v+m4-5e;;%?o!y-f0i%v@?0LFW1docgLD*E<-n`rkvldq+w9*18u0l7_P`ezGB! z+Zg~VRQ%3{(mFn5jz_=WNboJ|N&xbQL7;{E=g@~IGBE9IJrVsOcnlvy@DHO&{ZGdD*Co7ccW@J2wQU>=_c_BcIGb%A^3P z6)uP9P$_&g6US%u>LH2iY<+Zzrtp4fUzO2JZRc@Q{WmvpqlISommm)1y2Ftv;(XH4 z!JcfyM%r`pO5`J#UO~3<>^vnq3V0RDbP@%hKuL-!OZhuVsn`I#dCfijldXf zFrnB=v!Z6%nWF4~3+_65B^iB$5<7K2nes>7EiXI}9TdAaLU5Q-WI)-hX zFox}adLv3C<9o=<4}6TSW7k)-@zcNOm!!Xow8s!gg5!a&k$KE($pvF@A&@U;1})_G zJ;3beIf7PfnH8qfg|k$0rxfK(D3p*^3dL}qN~Ule9;vs>fd-AAd4@WSSM-g_CzP5o zQP{^mAl%8>3Wr*QS5TOoUrTYIWZ%l_R!&;meq(Zyq}MVGXFE&bD89-EA^bma?}g)Y z@=Pc|3Lb+4*N%rsu3muW`ixTDc+t* zL2{~;4szIQu&<+YNRT)D$)kAV0Ka+FA*F5Kk29>t9g;hkA>J6r)$3zef8TpyF%rsf zW-fRnhNj6A@=f797b5J1nJDnXA4PkLS3eF0=f{`@98ZPoY?WtAIv8rDvbkui+f1cZ z8$6ItQ~w1Jee0Dd9!hf1*VGJ%Y9?z(U_+P}9*gjPS%gc4(`I)h<82lxoa;Pil5v05 zxK+kD>ogrk(Bw%*A8IsXSge1A@e`eNf5M2M-Q$v6D-1adg4stH^y8c8XX;*|51(Da zdW+i1>6Q^hEYX1r&U#rgHNvRm81jZsSi}D--#|9egdK3?Qu!g5c+`{cQ%u#LK%bC~ zyhByvIE(p@@6zg`K2Mt8=}=D%MxE?b4G)lL5V?!gBJ;e8QbBZga1n&!8^bde;d<)9d&<)X&(yXT_TNi~;%L$IVVX}> zef$fm?^;EceR(glWp{R_dRTl39&e+Ck}-88TT<0aW-rD$k-3hiswQY&G2n;(`xi5X z!5Mmx+6In=8RZ;rN_4WM9iw#aG=nd4$K)6zw?kY!DyLx+@0v*Up?$%@Q)3fmZ>w;) za=*a8m872664mHVkkYAJNc;T`Sh;FD4rrg%f1n(UX2N+xGO+fa+58gntAfR=g4U}# z3?=2zbXt-{M`@Bywu7x-e4oVcZ@=Na2H$2IVG|;JVhpF4PoOSV_Wi>_WMP;0oPjz)rR%E&49ZksJLf z{L1Fro7A9XskQ_)6(1jytCFNs_an|~^-QbXLx;Yt3{8ReJNDhA)7P{q&%C+(Kl(#Y zzBJ2UdhX*;R2Nz2p3-)v6I|i|Hf9TJ9-r1jmn^3ntUV}4+HMRCmbYFfL_AtYRJCCQ zI7{Mo8*U$03e@Ut92^a4DNb6Ga)kE-U7@i!b%?5NxjS{gsz%8=2AB?KqqFV>Z*-UJ_ZU5Klvkv zHZAWOeOB5a9`)ls$f@g_vzUH&V&!(yuv-eP=|!`By`6N)%~DA29MiX7+s0^9mBZXM z86=dq-9Hh(gq(+4nEESq?}4)BdXz~DU!#O7u0tb{5vYgKJ`FQ_?O+m?zEwmZ zOnuGm7C*OR-T;nVkU@~7M4xMYTot(dNweI?)tL`C(81Xr|O zYV>)_g;uQzsoh#lL0LB}!3zkDh}KSvZ90m_=gf1NJ2W9h4(S77*1DtVc+v@tzLSkx zg3`w&$+{k7^-gpF+9IwI>SqAhoO5b|Rym|gKIR%L(V_wAYR|betpgNW^%gVUfl;ww zO+!Fv(Al!pRx^I16#j~YRWwqthS9P$LGPnQfTTe}=Q{Mvxsln9MO%kyF z{}@Z;>_xu!G-uOGxUKFUxPvlv%Wh!)^!_wR64(hMx8HKW64w#r1Byyv1KadZQae4Qd-@FN+_;4kVY5MTa~} z^~W<3xrozL{gt(E@;KDvqgQ7sAM0q54Wk)`V_Avau;)3-NcGC8D}_49{+;uF(JO8* z!O_}gl#FYd0ytDR(6Zz!4*XH~AbDSXLOt=n^H6H91KX)znfD~N`BN^rnlQ9g#5g+GsU2yD#dJgf0@w+gH*WEigH29R8& z-fWWS{2;f+e`z&93Wq0U$vQ(k?MPcJ#X#!-cd3fN;Uoc!>#}_#Ush!~(~3-ersht~ zW#PGgVu+T-w@~I>ZjyrCc{Ku}x*>68V8o#XJRfy3NZ~n! zcy^2vzEWufIgt zd#_KNodkcy)Yeb8Mz~e>=OW#C+7Kz{9uw{8vKI6<<1&Ci#>PmqjLYK=RpEu2%`l`t zUi3im9YryeI+8}_NDjiGZkJdx>&@Yv@G5yaRUG>P%B_@*WBxV_@$}vVce$_$G8c5) zNm}F)Idtv`y~ly$e!dl1*LYVe@R=0kQy*+R42p3eGnDx40xk}{A8@R?_OmNFZR&K~ z)qm~*g2+n@_miig{JS%`Uh($f?eZ0GVxhF%i#(*>;tM=D6F*VMKgfeKMgX=OK8V(f z-6)$lZD#%y206*_Y1U}_`f(vxej$}M>rDqcJJZYmR=*(0-;M;+qA9$q>It~xhusYf zsF0GEa-(ox8tttwV!Y&yKe=!Ix)g~-r9Z{~&i!27FWjk1e>~2jdo2#zQ@a;54TjG{ z!z6YMe$I9kXet}khRVGsGt0tE@@-TEZu-OY&TncR+$5<1l(^D{7|;ddZ2SqILZQ0& zHIN3jO-p6$9a-3OfttK#FouOj1%^qBpn02rN|+>Rsa^PUO{{uV+%Gap=S^&ZF`v;s zojVE}Kit=+jTCGoJLB9Pokd12(S=kb%qFI-2XYARFl5i~A-~4xrTKZRRR4ydVNNy*F?J@-v!^_IJ((mnMWt6d70p!n`$@Kps-SVS zIs-hv{yFb5^(Mr4Z4&}wzKF1kl6BX?EG=z#UTuDdHVfz&N1nhyE>d-XLhe84Afqnv zkCX*XboHW8PbAgrLY{n=%I<#CtZnBWh{7gnWSB-dh0oqRs3Uil@Lm(t?DQRle9@H$}nUtpP1GUK_ z>)AN?XA%T!%?f@tduyKGPgnJXsGi@h}uXY~1gwG-bz&kevn8bTsq!MHvZEtH*ij5`x6Pq;-i_Mt9YOqv; zJTk5b(dC!%TKPJI5r|&5{5|b55);+xeNHPTNNimS^0DdwwO{lfXy0na_yuVT)M;u= zK~qdRAED>5w+E)|G@d!0KE)nhsI+pH2K&qCBk+^w_j1lOtVO~Ue~n2vx|zr#5FEg^ z<=HyfFwk47&BRjmDtC5PuI#Hryn`#}aV=IENf>!+00mIwJ-VS?(XLUV>1`h>gS+~3 zhrWYiD8+%wXj)DLb2bj>bqqKMj&KTfkdHh;s=w@xNKZyPcxo--$_!q)`XkYEwI2dL zpFhm_kBcj~s~_KobzAl^1^z@0DW;icsplH{dxAur<(^;hu0K`&J4n+`x1b#vP{?1K z_A86IOECbxT^sI%ayyuc+ESgyq5tHmQ;HbAlPka7afl*bp|N<9dCU1rnl0v{wT!j* zz@fvE+try9)3Sgc?QMnlJvNzMSe<+ATuCkVtWz-2Rv~EZ3tJGC^55|u|6!!B+{$;2 zwC$P?>7u$5(y{{S2%p;0_U$F1rPl-$M|%v^0L;ZnQ^sXR%CJ_DwrUK3r3K1?`Uq@t z-LKljS~Zt5&b+3Q!2oV|4^fFPEFc5x@ja0Dx?Z6U75g{1%8h{}?$!L`8!ZKQsXnpX z#mLga*bw=pC;Rb4KInVfYQ| ztyS)@cuI>Vcn?1LG~P)%PPYw`fqOxDK(m0EZ$NjMxwKf2xe0@ z7!d1DXzPoL=xSWJ^f+wo^Kv@NnO7n5vhBkXL>@Vk=5@l|PLa50^vjg`H<@`{eJW8e z6aS&6eXy2`e^y(VpDlV0VKpr5liBWwpqqI_%6s4XxIl9-{v|pY2qp(IJo<2)qH@#9 zvCVLT#o6%e<{~dV5LaP^?(IP!-11mBo$Ef>%(yR5LI6PU$(vD#mR(Qo&^Q6Rd<4|T zw8hvY6g8)#Dk;lqJ9%;r-kO&)0bCW@36a+YO8fVYqqk9JT-yH+^|S0lu6F2ifYZF! zY!f8Y08yG*oJ_1s6^d$O2iWX3`E)Cj=XoZ`+y+#?YB+=E6`J9^u5PK4+6r0Qvkbg) z2x~h4arAiy&Zj03D)XEr#HBKl{<6rK8|AB9KI{Jif;bY z#f_sXkD|BjSJb;u>b8R+n2$%I*^C4b>i%5Oxr|7l?*7`_-fD_$eMP+8HR(ar~q zC`$G=gQ;1Z2wr=0hnCDNMcCDFl3OgX6~|G=Szjkj!T5s747(nNGax(E4Ql)}VL3h@ zQJJc_Zdf(i^_8n($#KH4dGL{D=qsw%(07`xpgC3z^NN?$KcY#yYL#HBu=_1YmJcPU zqW%qAciA0G9)~*nw8u#lZG)d;Txa|g?NC?bU4?HmAhT{1_w>Y90O

    ZPPj}4pr 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 diff --git a/.metadata/.plugins/org.eclipse.jdt.core/2538701421.index b/.metadata/.plugins/org.eclipse.jdt.core/2538701421.index index 5b42aa7af453f69aab0f350f9aee693bd175380d..2d026a37711934e7e3f2b7ac45d7670f65a604bd 100644 GIT binary patch delta 173315 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 F{{ivK)ieMA delta 171676 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 diff --git a/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt index fec7f58..490fac5 100644 --- a/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt +++ b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt @@ -1,4 +1,4 @@ INDEX VERSION 1.131+C:\Users\holde\MARS-UCA\.metadata\.plugins\org.eclipse.jdt.core 1865797976.index -760091825.index 2538701421.index +760091825.index diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml index 9e390f5..75a792a 100644 --- a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml +++ b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml @@ -1,2 +1,4 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<qualifiedTypeNameHistroy/> +<qualifiedTypeNameHistroy> + <fullyQualifiedTypeName name="java.io.File"/> +</qualifiedTypeNameHistroy> diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml index a48c62d..aa701ef 100644 --- a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml +++ b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml @@ -36,4 +36,11 @@ </section> <section name="CallHierarchySearchScope"> </section> + <section name="OptionalMessageDialog.hide."> + <item key="org.eclipse.jdt.ui.typecomment.deprecated" value="true"/> + </section> + <section name="NewClassWizardPage"> + <item key="create_constructor" value="false"/> + <item key="create_unimplemented" value="true"/> + </section> </section> diff --git a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log index a8d6bae..f207660 100644 --- a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log +++ b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log @@ -11,3 +11,4 @@ 2022-02-05 19:56:29,125 [Worker-7: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read. 2022-02-06 08:38:56,658 [Worker-6: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read. 2022-02-06 08:53:18,789 [Worker-9: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read. +2022-03-01 20:45:40,100 [Worker-7: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read. diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.collaborationuse.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.collaborationuse.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.collaborationuse.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.common.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.common.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.common.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.connectionpointreference.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.connectionpointreference.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.connectionpointreference.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.message.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.message.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.message.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.parameter.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.parameter.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.parameter.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.property.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.property.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.property.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.state.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.state.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.state.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.stereotypeproperty.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.stereotypeproperty.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.stereotypeproperty.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.transition.xtext.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.transition.xtext.ui/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.papyrus.uml.textedit.transition.xtext.ui/dialog_settings.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<section name="Workbench"> +</section> diff --git a/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties b/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties index 61a9af3..86b7005 100644 --- a/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties +++ b/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties @@ -1,2 +1,2 @@ #Cached timestamps -#Sun Feb 06 09:11:13 CST 2022 +#Tue Mar 01 21:01:36 CST 2022 diff --git a/.metadata/.plugins/org.eclipse.pde.core/SavedExternalPluginList.txt b/.metadata/.plugins/org.eclipse.pde.core/SavedExternalPluginList.txt index 77a44b9..b8c30b2 100644 --- a/.metadata/.plugins/org.eclipse.pde.core/SavedExternalPluginList.txt +++ b/.metadata/.plugins/org.eclipse.pde.core/SavedExternalPluginList.txt @@ -1,4 +1,5 @@ -# List of external plug-in models previously loaded. Timestamp: 1644113034040 +# List of external plug-in models previously loaded. Timestamp: 1646189440114 +file:/C:/Users/holde/.p2/pool/plugins/ca.odell.glazedlists_1.9.0.v201303080712.jar file:/C:/Users/holde/.p2/pool/plugins/ch.qos.logback.classic_1.2.3.v20200428-2012.jar file:/C:/Users/holde/.p2/pool/plugins/ch.qos.logback.core_1.2.3.v20200428-2012.jar file:/C:/Users/holde/.p2/pool/plugins/ch.qos.logback.slf4j_1.2.3.v20200428-2012.jar @@ -37,9 +38,12 @@ file:/C:/Users/holde/.p2/pool/plugins/com.genuitec.eclipse.webclipse.evergreen_1 file:/C:/Users/holde/.p2/pool/plugins/com.genuitec.eclipse.webicons_1.11.0.202105260439.jar file:/C:/Users/holde/.p2/pool/plugins/com.genuitec.eclipsecolortheme.api_1.11.0.202105260439.jar file:/C:/Users/holde/.p2/pool/plugins/com.google.gson_2.8.8.v20211029-0838.jar +file:/C:/Users/holde/.p2/pool/plugins/com.google.gson_2.7.0.v20170129-0911.jar file:/C:/Users/holde/.p2/pool/plugins/com.google.guava_30.1.0.v20210127-2300.jar file:/C:/Users/holde/.p2/pool/plugins/com.google.guava_27.1.0.v20190517-1946.jar file:/C:/Users/holde/.p2/pool/plugins/com.google.guava_21.0.0.v20170206-1425.jar +file:/C:/Users/holde/.p2/pool/plugins/com.google.inject_3.0.0.v201605172100.jar +file:/C:/Users/holde/.p2/pool/plugins/com.google.javascript_0.0.20160315.v20161124-1903.jar file:/C:/Users/holde/.p2/pool/plugins/com.googlecode.json-simple_1.1.1.me201606061543.jar file:/C:/Users/holde/.p2/pool/plugins/com.ibm.icu_67.1.0.v20200706-1749.jar file:/C:/Users/holde/.p2/pool/plugins/com.jcraft.jsch_0.1.55.v20190404-1902.jar @@ -50,6 +54,7 @@ file:/C:/Users/holde/.p2/pool/plugins/com.sun.jna.platform_5.8.0.v20210406-1004. file:/C:/Users/holde/.p2/pool/plugins/com.sun.jna.platform_4.5.1.v20190425-1842.jar file:/C:/Users/holde/.p2/pool/plugins/com.sun.xml.bind_2.3.3.v20201118-1818.jar file:/C:/Users/holde/.p2/pool/plugins/com.sun.xml.bind_2.2.0.v20201118-1845.jar +file:/C:/Users/holde/.p2/pool/plugins/io.github.classgraph_4.8.117.v20210930-0420.jar file:/C:/Users/holde/.p2/pool/plugins/jakarta.servlet-api_4.0.0.jar file:/C:/Users/holde/.p2/pool/plugins/jakarta.xml.bind_2.3.3.v20201118-1818.jar file:/C:/Users/holde/.p2/pool/plugins/javaewah_1.1.13.v20211029-0839.jar @@ -62,13 +67,28 @@ file:/C:/Users/holde/.p2/pool/plugins/javax.servlet.jsp_2.2.0.v201112011158.jar file:/C:/Users/holde/.p2/pool/plugins/javax.websocket-api_1.1.0.201606171313.jar file:/C:/Users/holde/.p2/pool/plugins/javax.xml_1.3.4.v201005080400.jar file:/C:/Users/holde/.p2/pool/plugins/javax.xml.bind_2.2.0.v201105210648.jar +file:/C:/Users/holde/.p2/pool/plugins/lpg.runtime.java_2.0.17.v201004271640.jar file:/C:/Users/holde/.p2/pool/plugins/minimal-json_0.9.5.jar file:/C:/Users/holde/.p2/pool/plugins/net.i2p.crypto.eddsa_0.3.0.v20210923-1401.jar +file:/C:/Users/holde/.p2/pool/plugins/org.antlr.runtime_3.2.0.v201101311130.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.ant_1.10.12.v20211102-1452/ +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.bridge_1.6.0.v201011041432.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.constants_1.14.0.v20210324-0332.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.css_1.14.0.v20210324-0332.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.css_1.6.0.v201011041432.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.dom_1.6.1.v201505192100.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.dom.svg_1.6.0.v201011041432.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.ext.awt_1.6.0.v201011041432.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.i18n_1.14.0.v20210324-0332.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.parser_1.6.0.v201011041432.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.pdf_1.6.0.v201105071520.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.svggen_1.6.0.v201011041432.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.transcoder_1.6.0.v201011041432.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.util_1.14.0.v20210324-0332.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.util_1.6.0.v201011041432.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.util.gui_1.6.0.v201011041432.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.batik.xml_1.6.0.v201011041432.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.commons.cli_1.4.0.v20200417-1444.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.commons.codec_1.14.0.v20200818-1422.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.commons.compress_1.21.0.v20211103-2100.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.commons.httpclient_3.1.0.v201012070820.jar @@ -88,6 +108,7 @@ file:/C:/Users/holde/.p2/pool/plugins/org.apache.httpcomponents.httpclient_4.5.1 file:/C:/Users/holde/.p2/pool/plugins/org.apache.httpcomponents.httpclient.win_4.5.13.v20210128-2225.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.httpcomponents.httpcore_4.4.14.v20210128-2225.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.jasper.glassfish_2.2.2.v201501141630.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.log4j_1.2.15.v201012070815.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.lucene.analyzers-common_8.4.1.v20200122-1459.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.lucene.analyzers-smartcn_8.4.1.v20200122-1459.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.lucene.core_8.4.1.v20200122-1459.jar @@ -95,10 +116,16 @@ file:/C:/Users/holde/.p2/pool/plugins/org.apache.sshd.osgi_2.7.0.v20210623-0618. file:/C:/Users/holde/.p2/pool/plugins/org.apache.sshd.sftp_2.7.0.v20210623-0618.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.xerces_2.12.1.v20210115-0812.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.xml.resolver_1.2.0.v201005080400.jar +file:/C:/Users/holde/.p2/pool/plugins/org.apache.xml.serializer_2.7.1.v201005080400.jar file:/C:/Users/holde/.p2/pool/plugins/org.apache.xmlgraphics_2.6.0.v20210409-0748.jar file:/C:/Users/holde/.p2/pool/plugins/org.apiguardian_1.1.2.v20211018-1956.jar +file:/C:/Users/holde/.p2/pool/plugins/org.aspectj.runtime_1.9.6.202103162301.jar file:/C:/Users/holde/.p2/pool/plugins/org.bouncycastle.bcpg_1.69.0.v20210713-1924.jar file:/C:/Users/holde/.p2/pool/plugins/org.bouncycastle.bcprov_1.69.0.v20210923-1401.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.acceleo.common_3.7.11.202102190929.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.acceleo.engine_3.7.11.202102190929.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.acceleo.model_3.7.11.202102190929.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.acceleo.profiler_3.7.11.202102190929.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ant.core_3.6.200.v20210907-1007.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ant.launching_1.3.100.v20211011-0944.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ant.ui_3.8.100.v20211011-0944.jar @@ -106,9 +133,39 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.buildship.branding_3.1.5.v2021 file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.buildship.core_3.1.5.v20210113-0929.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.buildship.stsmigration_3.1.5.v20210113-0929.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.buildship.ui_3.1.5.v20210113-0929.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt_10.5.0.202109270023.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.build.gcc.core_1.1.0.202008310002.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.build.gcc.ui_1.1.100.202104042017.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.codan.checkers_3.4.100.202010121414.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.codan.checkers.ui_3.3.0.202008310002.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.codan.core_4.1.100.202010121414.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.codan.core.cxx_3.5.100.202011201553.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.codan.ui_3.4.100.202011201553.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.codan.ui.cxx_3.6.0.202008310002.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.core_7.4.0.202110252256.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.core.native_6.2.0.202111152032.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.core.win32_6.0.200.202102030214.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.core.win32.x86_64_6.0.400.202112012329/ +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.debug.core_8.7.100.202110201027.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.debug.ui_8.4.300.202110151709.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.doc.user_5.4.1000.202109270023.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.dsf_2.11.0.202105311855.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.dsf.gdb_6.5.0.202111031828.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.dsf.gdb.ui_2.7.300.202111041518.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.dsf.ui_2.6.300.202110140133.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.flatpak.launcher_1.0.200.202106150220.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.gdb_7.1.100.202104042017.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.gdb.ui_7.1.0.202008310002.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.launch_10.3.100.202107280907.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.make.core_7.5.200.202108312208.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.make.ui_8.1.0.202105191403.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.managedbuilder.core_9.3.200.202111021145.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.managedbuilder.gnu.ui_8.4.200.202110181930.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.managedbuilder.headlessbuilderapp_1.0.100.202105281723.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.managedbuilder.ui_9.3.100.202104251526.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.native.serial_1.2.400.202112012329.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.platform.branding_10.5.0.202109270023.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.cdt.ui_7.3.100.202111091601.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.compare_3.8.200.v20210910-1335.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.compare.core_3.6.1000.v20201020-1107.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.compare.win32_1.2.800.v20200127-1343.jar @@ -133,6 +190,7 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.core.variables_3.5.100.v202107 file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.debug.core_3.18.300.v20211117-1829.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.debug.ui_3.15.200.v20211108-1752.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.debug.ui.launchview_1.0.2.v20211115-1052.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.draw2d_3.10.100.201606061308.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.e4.core.commands_1.0.0.v20210507-1901.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.e4.core.contexts_1.9.100.v20211011-1349.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.e4.core.di_1.8.100.v20210910-0640.jar @@ -174,16 +232,35 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.egit_6.0.0.202111291000-r.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.egit.core_6.0.0.202111291000-r.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.egit.doc_6.0.0.202111291000-r.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.egit.ui_6.0.0.202111291000-r.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf_2.8.0.v20180706-1146.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.codegen_2.22.0.v20210420-0623.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.codegen.ecore_2.28.0.v20210925-0555.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.codegen.ecore.ui_2.28.0.v20210925-0555.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.common_2.23.0.v20210924-1718.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.common.ui_2.19.0.v20211110-0654.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.converter_2.10.0.v20180706-1146.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.databinding_1.5.0.v20180706-1146.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.databinding.edit_1.7.0.v20210113-0340.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.ecore_2.25.0.v20210816-0937.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.ecore.change_2.14.0.v20190528-0725.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.ecore.edit_2.13.0.v20190822-1451.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.ecore.editor_2.17.0.v20190528-0725.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.ecore.xmi_2.16.0.v20190528-0725.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.edit_2.16.0.v20190920-0401.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.edit.ui_2.20.0.v20210506-1232.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.mapping.ecore2xml_2.11.0.v20180706-1146.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.mwe.core_1.6.1.v20210218-2134.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.mwe.utils_1.6.1.v20210218-2134.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.mwe2.language_2.12.1.v20210218-2134.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.mwe2.launch_2.12.1.v20210218-2134.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.mwe2.runtime_2.12.1.v20210218-2134.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.transaction_1.9.1.201805140824.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.transaction.ui_1.4.0.201805140824.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.validation_1.8.0.202008210805.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.validation.ocl_1.4.0.202008210805.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.validation.ui_1.7.0.202008210805.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.workspace_1.5.1.201805140824.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.emf.workspace.ui_1.3.0.201805140824.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.epp.mpc.core_1.9.2.v20210823-1346.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.epp.mpc.core.win32_1.9.2.v20210823-1346.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.epp.mpc.help.ui_1.9.2.v20210823-1346.jar @@ -243,6 +320,38 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.equinox.security.ui_1.3.100.v2 file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.equinox.security.win32.x86_64_1.1.300.v20211021-1418.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.equinox.simpleconfigurator_1.4.0.v20210315-2228.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.equinox.simpleconfigurator.manipulator_2.2.0.v20210315-2228.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gef_3.11.0.201606061308.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.common.core_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.common.ui_1.8.1.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.common.ui.action_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.common.ui.action.ide_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.common.ui.printing_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.common.ui.services_1.9.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.common.ui.services.action_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.common.ui.services.properties_1.9.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.core_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui_1.9.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.actions_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.printing_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.printing.render_1.8.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.properties_1.8.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.providers_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.providers.ide_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.render_1.7.2.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.resources.editor_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.draw2d.ui_1.9.1.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.draw2d.ui.render_1.7.1.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.draw2d.ui.render.awt_1.8.1.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.emf.clipboard.core_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.emf.commands.core_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.emf.core_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.emf.type.core_1.9.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.emf.ui_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.emf.ui.properties_1.7.0.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.gef.ui_1.7.1.202106221344.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.notation_1.10.0.202004160913.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.gmf.runtime.notation.edit_1.8.0.202004160913.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.help_3.9.100.v20210721-0601.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.help.base_4.3.500.v20211124-1800.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.help.ui_4.3.200.v20210922-1029.jar @@ -268,6 +377,7 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jdt.junit4.runtime_1.2.0.v2021 file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jdt.junit5.runtime_1.0.1400.v20211108-0640.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jdt.launching_3.19.400.v20211011-0920.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jdt.ui_3.25.0.v20211115-1252.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jem.util_2.1.300.v202103232321.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jetty.http_10.0.6.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jetty.io_10.0.6.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jetty.security_10.0.6.jar @@ -287,6 +397,9 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jgit.ssh.apache_6.0.0.20211129 file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jgit.ssh.apache.agent_6.0.0.202111291000-r.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jsch.core_1.3.900.v20200422-1935.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.jsch.ui_1.4.100.v20210917-1201.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.json_1.1.100.v201901071922.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.launchbar.core_2.4.200.202106071539.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.launchbar.ui_2.4.300.202111041518.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.lsp4e_0.13.8.202111241523.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.lsp4j_0.12.0.v20210402-1305.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.lsp4j.jsonrpc_0.12.0.v20210402-1305.jar @@ -318,6 +431,11 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2e.scm_1.17.2.20210603-1006.j file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2e.sourcelookup_1.17.4.20211002-1029/ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2e.sourcelookup.ui_1.17.3.20211002-1029.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2e.workspace.cli_0.3.1.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2m.qvt.oml_3.10.4.v20211130-1509.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2m.qvt.oml.common_3.10.2.v20211130-1509.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2m.qvt.oml.cst.parser_3.9.0.v20211130-1509.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2m.qvt.oml.ecore.imperativeocl_3.10.2.v20211130-1509.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.m2m.qvt.oml.emf.util_3.10.2.v20211130-1509.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.mylyn.commons.core_3.25.2.v20200813-0821.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.mylyn.commons.notifications.core_1.17.2.v20200813-0821.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.mylyn.commons.notifications.ui_1.17.2.v20200813-0821.jar @@ -344,8 +462,40 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.mylyn.wikitext.tracwiki.ui_3.0 file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.mylyn.wikitext.twiki_3.0.42.20220107230029.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.mylyn.wikitext.twiki.ui_3.0.42.202201072301.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.mylyn.wikitext.ui_3.0.42.202201072301.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.cwt_1.0.0.201703081533.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.gallery_1.0.0.201706221838.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.nattable.core_1.5.0.201703192131.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.nattable.extension.glazedlists_1.5.0.201703192131.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.nattable.extension.nebula_1.1.0.201703192131.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.richtext_1.2.0.201703081533/ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.tablecombo_1.2.0.202201100859.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl_3.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.common_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.common.ui_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.ecore_3.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.examples.debug_2.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.examples.debug.vm_2.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.examples.debug.vm.ui_2.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.examples.emf.validation.validity_2.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.examples.emf.validation.validity.ui_2.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.examples.ui_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.examples.xtext.console_4.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.examples.xtext.serializer_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.pivot_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.pivot.ui_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.pivot.uml_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.base_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.base.ui_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.completeocl_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.completeocl.ui_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.essentialocl_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.essentialocl.ui_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.markup_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.markup.ui_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.oclinecore_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.oclinecore.ui_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.oclstdlib_1.17.0.v20211130-1448.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ocl.xtext.oclstdlib.ui_1.17.0.v20211130-1448.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.oomph.base_1.15.0.v20211026-1304.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.oomph.base.edit_1.13.0.v20200720-0841.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.oomph.extractor.lib_1.9.0.v20211026-1304.jar @@ -381,6 +531,459 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.osgi_3.17.100.v20211104-1730.j file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.osgi.compatibility.state_1.2.500.v20210730-0750.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.osgi.services_3.10.200.v20210723-0643.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.osgi.util_3.6.100.v20210723-1119.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.paho.client.mqttv3_1.2.0.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.api.migration.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.copypaste.ui.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.components.fcm.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.components.modellibs.core_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.components.transformation_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.components.transformation.cpp_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.components.transformation.java_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.components.transformation.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.components.validation_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.deployment.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.deployment.tools_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.deployment.validation_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.doc.components_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.doc.main_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.c.codegen_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.c.codegen.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.c.examples_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.common.base_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.common.codegen.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.common.extensionpoints_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.common.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.common.profile.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.common.validation_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.cdt.project_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.cdt.texteditor_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.codegen_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.codegen.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.examples_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.library.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.profile.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.reverse_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.reverse.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.cpp.view_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.idl.codegen_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.idl.codegen.opensplice_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.idl.codegen.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.idl.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.codegen_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.codegen.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.jdt.project_2.1.0.202202061747.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.jdt.texteditor_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.library.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.profile.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.reverse_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.languages.java.reverse.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.monitoring.sm_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.architecture_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.pycpa.ecore_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.pycpa.ecore.edit_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.pycpa.ecore.editor_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.pycpa.ecore.tests_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.pycpa.m2m_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.pycpa.m2t_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.pycpa.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.rtsymbols.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.rtsymbols.profile.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.types_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.realtime.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.base_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.core_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.export_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.extensions_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.languages.cpp.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.languages.java.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.tracing.barectf.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.tracing.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.transformation.vsl_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.core_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.css_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.diagrams_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.library_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.modelexplorer_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.profile.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.properties_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.supplement.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.supplement.profile.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.types.profile_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.types.profile.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ucm.wizards_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.designer.ui_2.1.0.202201261931.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.developer.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.dsml.validation.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.eclipse.project.editors_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.editor_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.editor.perspectiveconfiguration_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.aggregate.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.architecture_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.architecture.edit_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.common.core_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.common.sdk.core_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.common.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.core_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.metamodel_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.metamodel.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.metamodel.editor_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.metamodel.editor.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.sdk.core_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.sdk.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.ui_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.catalog_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.core_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.editor_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.metamodel_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.metamodel.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.sdk.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.ui_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.java_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.java.core_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.java.metamodel_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.java.sdk.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.ocl.core_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.ocl.metamodel_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.ocl.sdk.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.core_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.emf.catalog_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.emf.core_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.emf.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.emf.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.jface.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.pde.core_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.swt_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.widgets_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.widgets.celleditors_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.widgets.celleditors.ecore_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.extensionpoints.editors_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.architecture_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.architecture.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.architecture.representation_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.architecture.representation.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.constraints_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.constraints.edit_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.constraints.editor_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.constraints.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core_4.3.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.architecture_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.architecture.edit_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.log_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.sasheditor_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.sasheditor.di_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.sashwindows.di_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.editor.welcome_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.editor.welcome.internationalization_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.editor.welcome.nattable_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf_4.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.appearance_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.diagram.common_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.editor_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.properties_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.gmf_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.nattable_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.readonly_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.types_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.types.ui_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.filters_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.filters.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.assistant_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.assistant.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.assistant.editor_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.assistant.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.canonical_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.commands_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.common_4.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.common.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.controlmode_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.configuration_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.model_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.model.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.properties_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.theme_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css3.xtext_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css3.xtext.ui_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.dnd_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.expansion_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.export_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.extensionpoints.editors_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.gef_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.gmfmenu.filter_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.hyperlink_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.menu_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.modelexplorer_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.navigation_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.outline_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.paletteconfiguration_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.paletteconfiguration.edit_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.preferences_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.properties_5.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.representation_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.representation.edit_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.style_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.style.edit_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.tooling.runtime_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.viewersearcher_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.welcome_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.widgets_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.guava_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.hyperlink_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.common_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.controlmode_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.readonly_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.utils_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable_7.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.common_6.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.controlmode_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.gmfdiag_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.model_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.model.edit_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.model.editor_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.modelexplorer_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.properties_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.representation_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.representation.edit_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.views.config_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.views.editor_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.edit_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.editor_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.onefile_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.onefile.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.properties_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.properties.edit_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.properties.editor_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.properties.ui_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.psf_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.architecture_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.controlmode_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.controlmode.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.controlmode.history_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.decoration_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.decoration.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.edit_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.edit.ui_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.labelprovider_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.localizer_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.markerlistener_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.navigation_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.navigation.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.openelement_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.resourceloading_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.resourceloading.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.semantic_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.validation_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.viewersearch_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.viewlabelprovider_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.sync_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.tools_4.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.core_5.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.doc_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.edit_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.editor_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.rulebased_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.ui_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui_3.4.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.architecture_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.emf_3.1.100.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.fonts_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.resources_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.viewpoints.policy_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.widgets_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.widgets.toolbox_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.java.profile_1.1.4.201602101324.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.java.profile.edit_1.1.4.201602101324.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.java.profile.editor_1.1.4.201602101324.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.marte.static.profile_1.2.2.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.marte.vsl_1.2.2.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.engine.schedulable_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.fuml.interfaces_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.kernel_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.kernel.animation_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.kernel.debug_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.kernel.scheduling_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.pscs.interfaces_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.pssm.interfaces_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.tracepoint.service_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.ui.tracepoint.view_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.utils_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.moka.utils.ui_4.1.0.202110220948.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.req.reqif.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.sdk_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.architecture.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.plugin.builder.doc_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.profilemigration.doc_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.recipe.elementtypes.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.validation.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.common_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.common.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.libraries_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.to.fuml_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.ui_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.appearance_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.architecture_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.commands_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.controlmode.profile_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.controlmode_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.properties_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.activity_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.clazz_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.common_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.common.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.common.groups_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.communication_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.component_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.composite_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.css_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.deployment_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.dnd_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.icons_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.interactionoverview_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.linklf_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.menu_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.modelexplorer_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.navigation_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.profile_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.profile.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.sequence_7.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.sequence.restrictions_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.statemachine_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.stereotype.edition_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.symbols_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.symbols.properties_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.timing_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.usecase_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.wizards_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.documentation.profile_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.export_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.expressions_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.expressions.edit_3.0.100.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.expressions.properties_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.extensionpoints_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.filters_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.filters.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.icons_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.import_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.internationalization_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.internationalization.edit_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.internationalization.utils_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.m2m.qvto.common_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.m2m.qvto.common.blackboxes_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.migration.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.modelexplorer_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.modelexplorer.widgets_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.modelrepair_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.modelrepair.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable_6.0.100.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.clazz.config_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.generic_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.generic.config_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.matrix_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.menu_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.properties_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.richtext_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.stereotype.display_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.xtext.integration_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.xtext.valuespecification_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.navigation_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.oclconstraintevaluation_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.perspective_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile_4.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.assistants.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.customization.doc_0.7.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.drafter_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.types.doc_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.properties_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.properties.xtext_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.resourceloading.profile_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.search.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.search.ui.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.service.types_5.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.service.types.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.service.validation_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.services.decoration_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.templaterepository_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.collaborationuse.xtext_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.collaborationuse.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.common.xtext_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.common.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.connectionpointreference.xtext_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.connectionpointreference.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.constraintwithessentialocl.xtext_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.javaconstraint_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.message.xtext_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.message.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.parameter.xtext_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.parameter.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.port.xtext_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.port.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.property.xtext_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.property.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.state.xtext_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.state.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.stereotypeproperty.xtext_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.stereotypeproperty.xtext.ui_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.transition.xtext_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.transition.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.valuespecification.xtext_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.valuespecification.xtext.ui_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.valuespecification.xtext.utils_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.tools_5.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.tools.utils_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.types.core_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.ui_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.xtext.integration.core_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.xtext.integration.ui_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.xtext.integration.validation_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.documentation_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.documentation.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.modelexplorer_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.modelexplorer.newchild_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.modelexplorer.resourceloading_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.modelexplorer.widgets_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.properties_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.properties.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.properties.model.xwt_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.references_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.references.doc_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.search_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.validation_3.1.0.202112011019.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.pde_3.13.1700.v20211124-1800.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.pde.api.tools_1.2.700.v20211108-0917.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.pde.api.tools.annotations_1.1.400.v20190929-1236.jar @@ -431,6 +1034,9 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.tm4e.core_0.4.3.202110141401.j file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.tm4e.registry_0.5.0.202111180858.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.tm4e.ui_0.5.0.202111180858.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.tools.layout.spy_1.1.0.v20210110-1247.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.tools.templates.core_1.2.0.202008310315.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.tools.templates.freemarker_1.2.200.202110311121.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.tools.templates.ui_1.3.0.202110311121.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ui_3.200.0.v20211026-0701.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ui.browser_3.7.100.v20211105-1434.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ui.cheatsheets_3.7.300.v20210507-0822.jar @@ -456,6 +1062,16 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ui.views.properties.tabbed_3.9 file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ui.win32_3.4.400.v20200414-1247.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ui.workbench_3.124.0.v20211116-0651.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.ui.workbench.texteditor_3.16.300.v20211119-1032.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.codegen.ecore_2.5.2.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.common_2.5.0.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.common.edit_2.5.0.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.types_2.5.0.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.uml_5.5.0.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.uml.edit_5.5.0.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.uml.editor_5.5.0.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.uml.profile.standard_1.5.0.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.uml.resources_5.5.0.v20210228-1829.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.uml2.uml.validation_5.5.0.v20210228-1829.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.update.configurator_3.4.800.v20210415-1314.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.urischeme_1.2.100.v20211001-1648.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.userstorage_1.2.0.v20210517-0327.jar @@ -493,13 +1109,104 @@ file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wb.swt.widgets.baseline_1.9.1. file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wildwebdeveloper.xml_0.13.1.202111081705.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.core_1.4.100.v202103232321.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.emf_1.2.700.v202007161535.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.emfworkbench.integration_1.2.102.v202007161535.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.environment_1.0.401.v202007142017.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.frameworks_1.2.202.v202108200212.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.frameworks.ui_1.2.401.v202007142017.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.infopop_1.0.301.v202007142017.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.modulecore_1.3.200.v202108200212.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.modulecore.ui_1.0.302.v202007142017.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.project.facet.core_1.4.402.v202111212041.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.project.facet.ui_1.4.602.v202007142017.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.snippets_1.2.500.v201811170421.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.ui_1.2.100.v202101112327.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.common.uriresolver_1.3.0.v202007161535.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.css.core_1.3.0.v202101180039.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.css.ui_1.2.0.v202101180039.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.doc.user_1.2.0.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.dtd.core_1.2.200.v202102251419.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.dtd.ui_1.1.300.v202008091424.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.dtd.ui.infopop_1.0.400.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.dtdeditor.doc.user_1.1.0.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.html.core_1.4.0.v202101180039.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.html.ui_1.1.600.v202105181958.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.html.ui.infopop_1.0.201.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.internet.cache_1.1.0.v202011161431.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.internet.monitor.core_1.0.700.v202007170127.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.internet.monitor.ui_1.0.800.v202007170127.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.jsdt.core_2.0.303.v202007221940.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.jsdt.manipulation_1.0.601.v201903222047.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.jsdt.ui_2.1.300.v202106021855.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.jsdt.web.core_1.1.100.v202005120035.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.jsdt.web.ui_1.2.300.v202107272335.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.bower.core_1.0.0.v201901071922.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.bower.ui_1.0.200.v201904210526.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.core_1.1.0.v201901152013.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.eslint.core_1.0.0.v201901071922.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.eslint.ui_1.0.200.v201904210526.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.jshint.core_1.0.1.v201908281850.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.jshint.ui_1.0.200.v201904210526.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.npm.core_1.0.0.v201901071922.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.npm.ui_1.0.100.v201904210526.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.schemaprocessor_1.0.200.v201901071922.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.json.ui_1.0.600.v202103121626.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.server.core_1.10.200.v202106020138.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.server.discovery_1.3.300.v202101040859.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.server.ui_1.5.800.v202111210116.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.server.ui.doc.user_1.1.600.v201901310132.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.server.ui.infopop_1.1.200.v201901310132.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.sse.core_1.2.700.v202107272335.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.sse.doc.user_1.2.0.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.sse.ui_1.7.300.v202111190506.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.sse.ui.infopop_1.0.300.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.standard.schemas_1.0.800.v201901071922.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.validation_1.2.801.v202007142017.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.validation.infopop_1.0.300.v202007131715.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.validation.ui_1.2.601.v202007142017.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.web_1.3.0.v202101070402.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.web.ui_1.2.200.v202107272335.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.web.ui.infopop_1.0.300.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.webtools.doc.user_1.0.500.v201903222120.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.xml.core_1.2.400.v202107272335.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.xml.ui_1.2.600.v202102222242.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.xml.ui.infopop_1.0.400.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.xmleditor.doc.user_1.1.0.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.xsd.core_1.2.100.v202008180353.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.xsd.ui_1.3.400.v202008091424.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.wst.xsdeditor.doc.user_1.0.800.v201903222120.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xpand_2.2.0.v201605260315.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xsd_2.18.0.v20210924-1719.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xsd.edit_2.11.0.v20200723-0820.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtend_2.2.0.v201605260315.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtend.lib_2.25.0.v20210301-0821.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtend.lib.macro_2.25.0.v20210301-0821.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtend.typesystem.emf_2.2.0.v201605260315.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext_2.25.0.v20210301-0843.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.builder_2.25.0.v20210301-0928.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.common.types_2.25.0.v20210301-0909.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.common.types.edit_2.25.0.v20210301-0928.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.common.types.ui_2.25.0.v20210301-0928.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.ecore_2.25.0.v20210301-0909.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.generator_2.25.0.v20210301-0909.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.ide_2.25.0.v20210301-0843.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.smap_2.25.0.v20210301-0909.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.ui_2.25.0.v20210301-0928.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.ui.codetemplates_2.25.0.v20210301-0928.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.ui.codetemplates.ide_2.25.0.v20210301-0928.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.ui.codetemplates.ui_2.25.0.v20210301-0928.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.ui.shared_2.25.0.v20210301-0928.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.util_2.25.0.v20210301-0843.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.xbase_2.25.0.v20210301-0909.jar file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.xbase.lib_2.25.0.v20210301-0821.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xtext.xtext.generator_2.25.0.v20210301-0843.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xwt_1.6.0.202105260718.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xwt.css_1.6.0.202105260718.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xwt.emf_1.6.0.202105260718.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xwt.forms_1.6.0.202105260718.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xwt.pde_1.6.0.202105260718.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xwt.ui.workbench_1.7.0.202105260718.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.xwt.xml_1.6.0.202105260718.jar +file:/C:/Users/holde/.p2/pool/plugins/org.freemarker_2.3.22.v20160210-1233.jar file:/C:/Users/holde/.p2/pool/plugins/org.gradle.toolingapi_6.8.0.v20210113-0929.jar file:/C:/Users/holde/.p2/pool/plugins/org.hamcrest.core_1.3.0.v20180420-1519.jar file:/C:/Users/holde/.p2/pool/plugins/org.jacoco.agent_0.8.7.v20210625-1418.jar @@ -527,6 +1234,7 @@ file:/C:/Users/holde/.p2/pool/plugins/org.objectweb.asm.commons_9.1.0.v20210209- file:/C:/Users/holde/.p2/pool/plugins/org.objectweb.asm.tree_9.2.0.v20210813-1119.jar file:/C:/Users/holde/.p2/pool/plugins/org.objectweb.asm.tree_9.1.0.v20210209-1849.jar file:/C:/Users/holde/.p2/pool/plugins/org.opentest4j_1.2.0.v20211018-1956.jar +file:/C:/Users/holde/.p2/pool/plugins/org.pushingpixels.trident_1.2.0.v201305152020.jar file:/C:/Users/holde/.p2/pool/plugins/org.sat4j.core_2.3.5.v201308161310.jar file:/C:/Users/holde/.p2/pool/plugins/org.sat4j.pb_2.3.5.v201404071733.jar file:/C:/Users/holde/.p2/pool/plugins/org.slf4j.api_1.7.30.v20200204-2150.jar @@ -541,3 +1249,361 @@ file:/C:/Users/holde/.p2/pool/plugins/org.w3c.css.sac_1.3.1.v200903091627.jar file:/C:/Users/holde/.p2/pool/plugins/org.w3c.dom.events_3.0.0.draft20060413_v201105210656.jar file:/C:/Users/holde/.p2/pool/plugins/org.w3c.dom.smil_1.0.1.v200903091627.jar file:/C:/Users/holde/.p2/pool/plugins/org.w3c.dom.svg_1.1.0.v201011041433.jar +file:/C:/Users/holde/.p2/pool/plugins/ca.odell.glazedlists.source_1.9.0.v201303080712.jar +file:/C:/Users/holde/.p2/pool/plugins/com.ibm.icu.source_67.1.0.v20200706-1749.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.cwt.source_1.0.0.201703081533.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.nattable.core.source_1.5.0.201703192131.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.nattable.extension.glazedlists.source_1.5.0.201703192131.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.nattable.extension.nebula.source_1.1.0.201703192131.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.nebula.widgets.richtext.source_1.2.0.201703081533.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.api.migration.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.copypaste.ui.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.developer.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.dsml.validation.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.eclipse.project.editors.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.editor.perspectiveconfiguration.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.editor.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.aggregate.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.architecture.edit.source_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.architecture.source_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.common.core.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.common.sdk.core.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.common.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.core.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.metamodel.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.metamodel.editor.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.metamodel.editor.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.metamodel.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.sdk.core.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.sdk.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.custom.ui.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.catalog.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.core.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.editor.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.metamodel.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.metamodel.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.sdk.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.efacet.ui.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.java.core.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.java.metamodel.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.java.sdk.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.java.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.ocl.core.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.ocl.metamodel.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.query.ocl.sdk.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.core.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.emf.catalog.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.emf.core.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.emf.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.emf.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.jface.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.pde.core.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.swt.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.util.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.widgets.celleditors.ecore.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.widgets.celleditors.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.facet.widgets.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.emf.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.extensionpoints.editors.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.architecture.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.architecture.representation.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.architecture.representation.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.architecture.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.constraints.edit.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.constraints.editor.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.constraints.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.constraints.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.architecture.edit.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.architecture.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.log.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.sasheditor.di.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.sasheditor.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.sashwindows.di.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.core.source_4.3.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.editor.welcome.internationalization.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.editor.welcome.nattable.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.editor.welcome.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.appearance.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.diagram.common.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.editor.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.properties.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.expressions.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.gmf.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.nattable.source_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.readonly.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.source_4.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.types.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.emf.types.ui.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.filters.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.filters.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.assistant.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.assistant.editor.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.assistant.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.assistant.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.canonical.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.commands.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.common.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.common.source_4.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.controlmode.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.configuration.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.model.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.model.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.properties.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css.theme.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css3.xtext.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.css3.xtext.ui.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.dnd.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.expansion.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.export.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.extensionpoints.editors.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.gef.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.gmfmenu.filter.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.hyperlink.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.menu.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.modelexplorer.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.navigation.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.outline.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.paletteconfiguration.edit.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.paletteconfiguration.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.preferences.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.properties.source_5.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.representation.edit.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.representation.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.style.edit.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.style.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.tooling.runtime.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.viewersearcher.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.welcome.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.gmfdiag.widgets.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.guava.source_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.hyperlink.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.common.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.controlmode.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.readonly.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.internationalization.utils.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.common.source_6.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.controlmode.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.gmfdiag.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.model.edit.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.model.editor.source_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.model.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.modelexplorer.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.properties.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.representation.edit.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.representation.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.source_7.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.views.config.source_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.nattable.views.editor.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.edit.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.editor.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.newchild.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.onefile.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.onefile.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.properties.edit.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.properties.editor.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.properties.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.properties.ui.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.psf.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.architecture.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.controlmode.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.controlmode.history.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.controlmode.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.decoration.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.decoration.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.edit.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.edit.ui.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.labelprovider.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.localizer.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.markerlistener.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.navigation.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.navigation.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.openelement.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.resourceloading.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.resourceloading.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.semantic.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.validation.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.viewersearch.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.services.viewlabelprovider.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.sync.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.tools.source_4.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.core.source_5.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.doc.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.edit.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.editor.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.rulebased.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.types.ui.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.architecture.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.emf.source_3.1.100.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.fonts.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.resources.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.ui.source_3.4.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.viewpoints.policy.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.widgets.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.infra.widgets.toolbox.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.java.profile.edit.source_1.1.4.201602101324.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.java.profile.editor.source_1.1.4.201602101324.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.java.profile.source_1.1.4.201602101324.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.req.reqif.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.sdk.source_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.architecture.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.plugin.builder.doc.source_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.profilemigration.doc.source_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.recipe.elementtypes.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.toolsmiths.validation.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.common.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.common.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.libraries.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.to.fuml.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.alf.ui.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.appearance.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.architecture.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.commands.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.controlmode.profile.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.controlmode.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.properties.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.decoratormodel.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.activity.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.clazz.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.common.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.common.groups.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.common.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.communication.source_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.component.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.composite.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.css.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.deployment.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.dnd.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.icons.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.interactionoverview.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.linklf.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.menu.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.modelexplorer.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.navigation.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.profile.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.profile.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.sequence.restrictions.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.sequence.source_7.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.statemachine.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.stereotype.edition.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.symbols.properties.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.symbols.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.timing.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.usecase.source_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.diagram.wizards.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.documentation.profile.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.export.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.expressions.edit.source_3.0.100.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.expressions.properties.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.expressions.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.extensionpoints.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.filters.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.filters.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.icons.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.import.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.internationalization.edit.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.internationalization.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.internationalization.utils.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.m2m.qvto.common.blackboxes.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.m2m.qvto.common.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.migration.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.modelexplorer.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.modelexplorer.widgets.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.modelrepair.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.modelrepair.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.clazz.config.source_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.generic.config.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.generic.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.matrix.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.menu.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.properties.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.richtext.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.source_6.0.100.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.stereotype.display.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.xtext.integration.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.nattable.xtext.valuespecification.source_6.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.navigation.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.oclconstraintevaluation.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.perspective.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.assistants.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.customization.doc.source_0.7.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.drafter.source_2.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.source_4.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.profile.types.doc.source_1.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.properties.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.properties.xtext.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.resourceloading.profile.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.search.ui.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.search.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.service.types.source_5.2.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.service.types.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.service.validation.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.services.decoration.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.templaterepository.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.collaborationuse.xtext.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.collaborationuse.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.common.xtext.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.common.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.connectionpointreference.xtext.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.connectionpointreference.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.constraintwithessentialocl.xtext.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.javaconstraint.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.message.xtext.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.message.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.parameter.xtext.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.parameter.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.port.xtext.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.port.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.property.xtext.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.property.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.state.xtext.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.state.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.stereotypeproperty.xtext.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.stereotypeproperty.xtext.ui.source_4.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.transition.xtext.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.transition.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.valuespecification.xtext.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.valuespecification.xtext.ui.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.textedit.valuespecification.xtext.utils.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.tools.source_5.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.tools.utils.source_4.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.types.core.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.ui.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.xtext.integration.core.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.xtext.integration.ui.source_3.1.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.uml.xtext.integration.validation.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.documentation.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.documentation.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.modelexplorer.newchild.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.modelexplorer.resourceloading.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.modelexplorer.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.modelexplorer.widgets.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.properties.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.properties.model.xwt.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.properties.source_5.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.references.doc.source_2.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.references.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.search.source_3.0.0.202112011019.jar +file:/C:/Users/holde/.p2/pool/plugins/org.eclipse.papyrus.views.validation.source_3.1.0.202112011019.jar diff --git a/.metadata/.plugins/org.eclipse.xtext.builder/builder.state b/.metadata/.plugins/org.eclipse.xtext.builder/builder.state new file mode 100644 index 0000000000000000000000000000000000000000..8e25fe2aa07e9c8a229311d944a45e196e90c4ca GIT binary patch literal 15 WcmeB7%}wLtmEvM#U|<krWCQ>jR00tI literal 0 HcmV?d00001 diff --git a/.metadata/version.ini b/.metadata/version.ini index 8b3c3c7..6cc1f6b 100644 --- a/.metadata/version.ini +++ b/.metadata/version.ini @@ -1,3 +1,3 @@ -#Sun Feb 06 08:53:13 CST 2022 +#Tue Mar 01 20:45:34 CST 2022 org.eclipse.core.runtime=2 org.eclipse.platform=4.22.0.v20211124-1800 diff --git a/Mars-UCA.jar b/Mars-UCA.jar index d24febee633a10f4311905ae9c68e07179a62baf..d8e165dbb0aebc1d0d07cad97af1f13b0fab0412 100644 GIT binary patch delta 84004 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 delta 79666 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 diff --git a/README.md b/README.md index d5b057d..faa8fb3 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,4 @@ List of modifications from the original version currently include: * Added a Decimal column to the registers window * Replaced JFileChooser with FileDialog as the default file opening choice * Replaced JFileChooser with FileDialog as the default file saving choice +* Added an extremely elementary file browser tab to the bottom messages pane - All implementation credit goes to Ian Darwin, sourced from [here](http://www.java2s.com/Code/Java/Swing-JFC/DisplayafilesysteminaJTreeview.htm) \ No newline at end of file diff --git a/source/mars/venus/FileTree$1.class b/source/mars/venus/FileTree$1.class new file mode 100644 index 0000000000000000000000000000000000000000..df622de9692045a756d53eb8906ae2bb37cf1285 GIT binary patch literal 1340 zcma)6YflqV5Iwh4w$xS18&tGng_Z&fiq8Tn<!wQd5)wWx?G=`6cbo1m>d(@|l4xT5 z?2j^@yRES$joM^4_fBWdoH;YIKYo7s24EQl4H1E%idplFbLj-0v0>TrpeAK%K|@p^ zab}*IhHW}0#+&0aS@Jb>3rs2Nd&7HY(JmS28!DzKZF*R)Q?NW=I<h9v?Vnm+YMwa? z9g^heuw*%wzalW2?&y&@6o}^Cvh0DtH60paade?qM-LJLU1{aeTd*9t7gUaA?Z7;? zr9gkdEt&SAS+mr=X^bi|0wbLgr4~p=KR4|_=1*C!EDL1Pg?|*fu4>O^4&xZb4Gm)g zssD-4aTB)$v=iy?oBpZ5cskRT%BPy4r0VZn9Ji6wa7SRQ6}`<#$6ZVa3=*<ndLeAy ztyEoy1Zi&Kw{|k8A$6&hA>x{RYX-Kz8~CAgWU?2^KZ&%4skV_Qeqf&~Ix?7ME8KvY zhQc}w%Qg0Emg5%*X;zqOhPo^A4F)uGbXEh)F3VaBb8PLA8zjAOfMhutM;7y{#S27i zbfGmcR6L7^Iu`MWGh|k)(qY49TU{ITnrjH#8r@7wS+jVe<0+mA#C*5G>9ST0D}8fV z*03Zn5LVG%pN<v9RI93zZAU<G1Si`%+F?r?!^81*s4u6j&Hpd0;Go8fZcr;pwXBrx z_s-5KYTSl(r)0Yx1>TkZsaw{tN!lIOPYJv&(AQLrH7O*D%T3sJxW9SZ^gPLxiS0?x z-*P=4Nv>fRpDPfFgxW@aM<RTB5U2GjPm8=OOME)}8T#}Eu73=D`uOgq53r7YzV+}N z#{dR-W1lhHM5rRl9Kb}jj*&XXzvJHSC*1#v>{0*h1&o<G9@O!;j^}@nhsg-oB*GS1 zZIa10H)1Eulx(0iGZ7ar@G{Ibf>&52+bHskj$n=4z}p5<c6d@XDaPvenok59zW|%h BRPO)) literal 0 HcmV?d00001 diff --git a/source/mars/venus/FileTree.class b/source/mars/venus/FileTree.class new file mode 100644 index 0000000000000000000000000000000000000000..29d019633c611c7e244081fa70963318cd46a74d GIT binary patch literal 3214 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 Hg{}KP;`=2Y literal 0 HcmV?d00001 diff --git a/source/mars/venus/FileTree.java b/source/mars/venus/FileTree.java new file mode 100644 index 0000000..ae360e2 --- /dev/null +++ b/source/mars/venus/FileTree.java @@ -0,0 +1,123 @@ +package mars.venus; +/* + * Copyright (c) Ian F. Darwin, http://www.darwinsys.com/, 1996-2002. + * All rights reserved. Software written by Ian F. Darwin and others. + * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee + * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's, + * pioneering role in inventing and promulgating (and standardizing) the Java + * language and environment is gratefully acknowledged. + * + * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for + * inventing predecessor languages C and C++ is also gratefully acknowledged. + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.io.File; +import java.util.Collections; +import java.util.Vector; + +import javax.swing.BoxLayout; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; + +/** + * Display a file system in a JTree view + * + * @version $Id: FileTree.java,v 1.9 2004/02/23 03:39:22 ian Exp $ + * @author Ian Darwin + */ +public class FileTree extends JPanel { + /** Construct a FileTree */ + public FileTree(File dir) { + setLayout(new BorderLayout()); + + // Make a tree list with all the nodes, and make it a JTree + JTree tree = new JTree(addNodes(null, dir)); + + // Add a listener + tree.addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) e + .getPath().getLastPathComponent(); + System.out.println("You selected " + node); + } + }); + + // Lastly, put the JTree into a JScrollPane. + JScrollPane scrollpane = new JScrollPane(); + scrollpane.getViewport().add(tree); + add(BorderLayout.CENTER, scrollpane); + } + + /** Add nodes from under "dir" into curTop. Highly recursive. */ + DefaultMutableTreeNode addNodes(DefaultMutableTreeNode curTop, File dir) { + String curPath = dir.getPath(); + DefaultMutableTreeNode curDir = new DefaultMutableTreeNode(curPath); + if (curTop != null) { // should only be null at root + curTop.add(curDir); + } + Vector ol = new Vector(); + String[] tmp = dir.list(); + for (int i = 0; i < tmp.length; i++) + ol.addElement(tmp[i]); + Collections.sort(ol, String.CASE_INSENSITIVE_ORDER); + File f; + Vector files = new Vector(); + // Make two passes, one for Dirs and one for Files. This is #1. + for (int i = 0; i < ol.size(); i++) { + String thisObject = (String) ol.elementAt(i); + String newPath; + if (curPath.equals(".")) + newPath = thisObject; + else + newPath = curPath + File.separator + thisObject; + if ((f = new File(newPath)).isDirectory()) + addNodes(curDir, f); + else + files.addElement(thisObject); + } + // Pass two: for files. + for (int fnum = 0; fnum < files.size(); fnum++) + curDir.add(new DefaultMutableTreeNode(files.elementAt(fnum))); + return curDir; + } + + public Dimension getMinimumSize() { + return new Dimension(200, 400); + } + + public Dimension getPreferredSize() { + return new Dimension(200, 400); + } +} \ No newline at end of file diff --git a/source/mars/venus/MessagesPane$1.class b/source/mars/venus/MessagesPane$1.class index ee60b17a78e7dad2b2da5953453ba39f6cd6ff4c..cb472e252f7e82b591b793b7aa2f628376170f68 100644 GIT binary patch delta 23 fcmdnMwt;QKJSN7V$@7_9SVI_i7(yq%VDbO}S`!Bc delta 23 fcmdnMwt;QKJSN7#$@7_9Sc4gO7(yn$VDbO}S@s76 diff --git a/source/mars/venus/MessagesPane$2.class b/source/mars/venus/MessagesPane$2.class index fa6f6cd474516a1614193138dc0fed387aed40b7..9b49ee1f0b592ad62ec6c941fbc128ff50c42224 100644 GIT binary patch delta 206 zcmWN{O>4mc0LSs~ZzaoB(N0!c?Vwhsl)H=4;-*%XJy^qxj4>h)#a4_Nr5zm=^}jhd z?Brc22kl+VKIhNYzO^qt&AK#(=AEih4!FWZ3<uY^xWUIQ0qzJA=Yo5}JP;vCf)p=2 z(jrZdC&py>Cd-r@GoCTXv!uZ4fBjHoO^FS!{8HwRiVi8tN>w&$I-;&)8glw*>V%d~ nY3q!R+`P%dyS#Mer>7tv3ei`Lfzk|B=1Uz$8Zj}>EpzPw@E9<{ delta 206 zcmWN{yGnuq0EXfB3&dy@6ek4<8ic?E!M#Ng(M<#+D<jk_G!H3?C)B`9)Fg0h6cql= zp`ppU5FDbrD0$XrXWQ9UW3yt$#QdXroC7W}afyQjZm#fiO@JGMBnfd#ggc_7_R^Hd z(BYmTS!O&i=aElxEXZT<#F_$M6#3rI4P~}G^Gk(4syd`33pH7(%T7a1nsWJR>6o@o n=<1Z7JoM$|MLq^P=T$+53iGA}BV`$@%0zvpdgsG9J6h@=-83+g diff --git a/source/mars/venus/MessagesPane$3.class b/source/mars/venus/MessagesPane$3.class index 818434e7a779c445a898c2a7836fc78c7b40ff45..2ef2decfb3c439b49f07de29b6696035aab2fcd7 100644 GIT binary patch delta 23 fcmZ3@wwi6jOeV$!lV>rxur6ZYVOTu*F_Q-XVPgl_ delta 23 fcmZ3@wwi6jOeV(plV>rxur6faVOTWzF_Q-XVMYhl diff --git a/source/mars/venus/MessagesPane$4.class b/source/mars/venus/MessagesPane$4.class index a2904550db5941e2b0ef6ac83dd37e9f65791ff5..3370384952eebfe23e43664b30829568c4a3eee2 100644 GIT binary patch delta 43 ycmZqRYT()+$iiqoS%{@W(vpFX(TYKa(T>58(SgB*(UHNO(TTx>(QWc(7GD6a-Us0T delta 43 ycmZqRYT()+$iiqaS%{@W(ujeN(U?Jo(VW4M(UQT1(Tc&H(VD@7(SGt~7GD6Ws0XP4 diff --git a/source/mars/venus/MessagesPane$Asker$1$1.class b/source/mars/venus/MessagesPane$Asker$1$1.class index edc784035f09dcae23dc36e5f3fa2b5975a75480..3209117eeaea481017850b37395c25f47b221106 100644 GIT binary patch delta 80 zcmV-W0I&c44*m|XlLY~gvy=rE0X>rdApw*CC;^oKECH4PI02UcOaYhxRsop+Spl2? mX#t%8hykDgivghkz5${D$N{7P%K@bT%mJnV)&Z!K=LVOrR2ZB9 delta 80 zcmV-W0I&c44*m|XlLY~Zvy=rE0X>WWApwm5C;^TDECG)II029VOaYMqRsoU#Spk&* mX#ti1hyj@ZivgMdz5$y6$N`-I%K@GM%mJSO)&ZfD=LVOa3>YN< diff --git a/source/mars/venus/MessagesPane$Asker$1$2.class b/source/mars/venus/MessagesPane$Asker$1$2.class index 19cde5cd2a63ba5697da57e6fa4894ff9ebc7df0..93796645c77892a8821592f86034399393d7d552 100644 GIT binary patch delta 31 ncmey&{h52iYZk_}li#o`;$6>R&A5TVopB>W7USm0vsohm&yWkb delta 31 ncmey&{h52iYZk_3li#o`;$6XD&A5`mopBXI7UP=9vsohm&ASVh diff --git a/source/mars/venus/MessagesPane$Asker$1.class b/source/mars/venus/MessagesPane$Asker$1.class index f238e0f340c8b211d78b2bf094a9f4301dd59699..9aa8176ea81b768ba2f251c51c33f8d5b8ae07d5 100644 GIT binary patch delta 57 zcmX@jb((9#1!l(H$rqVjI43Z0GWIj@Fs_;`$KuDi7RXxz<ZT7=<R?#IQD)pWc?XLd JQ0;#f9{~Eu5nliR delta 57 zcmX@jb((9#1!l&!$rqVjI6E0Q89Nww7#B~LWAWo$2IMUT^40-)@{^~qC^N2~yo1FJ JsP;dL4*>JQ5g-5n diff --git a/source/mars/venus/MessagesPane$Asker$2.class b/source/mars/venus/MessagesPane$Asker$2.class index 488349a040f614f97c4ff1704043a30211e89bbf..aca769e6e2e67b1e714174085ef715f10f966b12 100644 GIT binary patch delta 53 zcmZqRZQ$MTm4$KV<Zmo#yt^5=8TT+~Fz#c}W86PEleL%kAW-BGP~-?u<S0<YYO*bx FGXT^m5H$b* delta 53 zcmZqRZQ$MTm4$KB<Zmo#yjvK!8MiWMFm7kiW85)0leL$37f@t3P-HJqWFJt(YO*bx FGXTx45B2~6 diff --git a/source/mars/venus/MessagesPane$Asker$3.class b/source/mars/venus/MessagesPane$Asker$3.class index efd8b840bd5ff99f05ba9bd095d85af2c23080a8..054fbb4caa3737b14219ae1f4e15eb43e4aaabc1 100644 GIT binary patch delta 23 fcmX@cc8qPqN+!k=lUFg>vz}sLXFNUm9a97VY+MMq delta 23 fcmX@cc8qPqN+!mGlUFg>vmRz(XFM|b9a97VYmo?} diff --git a/source/mars/venus/MessagesPane$Asker$4.class b/source/mars/venus/MessagesPane$Asker$4.class index 30978fba8da733d2e7d66d526e72ee4d143ee49b..6ed51b0de0647c570c3059084204b904171b0b67 100644 GIT binary patch delta 39 vcmX@ZbB1SwKP%(S$pNf0MQ<}mGTvcOXS~Z`%6N|<gz-K@BIAR}|5*J14Dt<W delta 39 vcmX@ZbB1SwKP%&<$pNf0MXxYOGG1j+XS~K>%6Oe2gz*MLBIC`;|5*J138M`- diff --git a/source/mars/venus/MessagesPane$Asker.class b/source/mars/venus/MessagesPane$Asker.class index d0fd40be40d33b283c13d8f5c568f8081ec4d26f..7f70d00382f5a5ed5ab9b0212fdadf3ac8ac1104 100644 GIT binary patch delta 179 zcmWO0I}1T^0EY4REd!3rphIrM5hFWcF<OL_McK{r0T5yO?>>X^n2cm_CsyT_B#~ou zrsp?4Q}5I}h?_$#nAm{KE}ZN^p^5;92y=`GCy26*Bs-#PR+SlSoWsopf?OiO71CUz z$PFsoqRO3!Nh#9-M(!c;D4J5=eS(W;#Cbu6SLAp@o_Cb^5DCjD^n`&g*r~yxSLR!P W(BR<*K7QfXt?(xlYk_r9vu6Jemokt5 delta 179 zcmWO0I}1T^0EY4REra8@3_{0YIAUZcEJllvvM9S*7K-o%{=3hB$%YBXEmq~0BoV%W zGd;iY(N$gT$1R~IBsSn;2X1zuaex4a2y=o6r--tJB-^5F8EG@vIfudpg4B`V5^1hb z<Qf%jP~}#{<dn3BnLEflh_2jIj_~k=IM2xNf*h~N^M(@dB4Hhe9x(9<2fuI{b@639 WeBtFAK7Qagtnnu_TY+^^vt|FSJ~4Oz diff --git a/source/mars/venus/MessagesPane.class b/source/mars/venus/MessagesPane.class index 95bf958f7d3a5392fe30dc1a96d98208588e577d..d997f09e9fecc01d6fea54f394d94297e41ff228 100644 GIT binary patch literal 7957 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 S)OcDRkO$=<c|;zS&;B04Obti? literal 7779 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 D&!yyj diff --git a/source/mars/venus/MessagesPane.java b/source/mars/venus/MessagesPane.java index 6345d04..751468c 100644 --- a/source/mars/venus/MessagesPane.java +++ b/source/mars/venus/MessagesPane.java @@ -4,7 +4,8 @@ import javax.swing.text.*; import java.awt.*; import java.awt.event.*; - import java.util.concurrent.ArrayBlockingQueue; +import java.io.File; +import java.util.concurrent.ArrayBlockingQueue; import javax.swing.event.DocumentListener; import javax.swing.undo.UndoableEdit; import mars.simulator.Simulator; @@ -46,7 +47,7 @@ a copy of this software and associated documentation files (the public class MessagesPane extends JTabbedPane{ JTextArea assemble, run; - JPanel assembleTab, runTab; + JPanel assembleTab, runTab, fileTab; // These constants are designed to keep scrolled contents of the // two message areas from becoming overwhelmingly large (which // seems to slow things down as new text is appended). Once it @@ -164,11 +165,17 @@ public void actionPerformed(ActionEvent e){ runTab = new JPanel(new BorderLayout()); runTab.add(createBoxForButton(runTabClearButton),BorderLayout.WEST); runTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, - ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); + fileTab = new FileTree(new File(".")); +// fileTab.add(new JScrollPane(run, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, +// ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER); this.addTab("Mars Messages", assembleTab); this.addTab("Run I/O", runTab); + this.addTab("File Browser", fileTab); this.setToolTipTextAt(0,"Messages produced by Run menu. Click on assemble error message to select erroneous line"); this.setToolTipTextAt(1,"Simulated MIPS console input and output"); + this.setToolTipTextAt(2,"View filesystem"); + } // Center given button in a box, centered vertically and 6 pixels on left and right