From 63c0a3cc86621703fd4a868ed7289f187b364b74 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 20 Jul 2022 22:15:47 +0200 Subject: [PATCH 01/16] Missing dependencies --- core/.classpath | 1 + swing/.classpath | 1 + 2 files changed, 2 insertions(+) diff --git a/core/.classpath b/core/.classpath index 453ab552f..06a9ed43d 100644 --- a/core/.classpath +++ b/core/.classpath @@ -17,6 +17,7 @@ + diff --git a/swing/.classpath b/swing/.classpath index 7daea48ea..6878da13d 100644 --- a/swing/.classpath +++ b/swing/.classpath @@ -19,6 +19,7 @@ + From 69637ef18d677f5f077f8ba6fac44838be645083 Mon Sep 17 00:00:00 2001 From: UncleRus Date: Thu, 21 Jul 2022 02:08:14 +0500 Subject: [PATCH 02/16] l10n: sync Russian translation --- core/resources/l10n/messages_ru.properties | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/core/resources/l10n/messages_ru.properties b/core/resources/l10n/messages_ru.properties index 2ae02679c..3a9c30318 100644 --- a/core/resources/l10n/messages_ru.properties +++ b/core/resources/l10n/messages_ru.properties @@ -293,8 +293,10 @@ pref.dlg.lbl.launchWarning.ttip = \u0412\u044B \u043D\u0435 \u043F\u0435\u0440\u pref.dlg.lbl.Positiontoinsert = \u041C\u0435\u0441\u0442\u043E \u0434\u043B\u044F \u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F \u043D\u043E\u0432\u044B\u0445 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432: pref.dlg.lbl.PositiontoinsertStages = \u041C\u0435\u0441\u0442\u043E \u0434\u043B\u044F \u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F \u043D\u043E\u0432\u044B\u0445 \u0441\u0442\u0443\u043F\u0435\u043D\u0435\u0439: pref.dlg.lbl.Confirmdeletion = \u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0440\u0430\u0441\u0447\u0435\u0442\u0430: -pref.dlg.checkbox.Runsimulations = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u0432\u043A\u043B\u0430\u0434\u043A\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432. +pref.dlg.checkbox.Runsimulations = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u0432\u043A\u043B\u0430\u0434\u043A\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432 pref.dlg.checkbox.Updateestimates = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u043F\u0440\u0435\u0434\u043F\u043E\u043B\u0430\u0433\u0430\u0435\u043C\u044B\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043F\u043E\u043B\u0435\u0442\u0430 \u0432 \u043E\u043A\u043D\u0435 \u043F\u0440\u043E\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F +pref.dlg.checkbox.Markers = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u043E\u043F\u043E\u0440/\u0440\u0430\u0437\u0433\u043E\u043D\u043D\u044B\u0445 \u0431\u043B\u043E\u043A\u043E\u0432 \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u043E\u043D\u0438 \u0432\u044B\u0431\u0440\u0430\u043D\u044B +pref.dlg.checkbox.Markers.ttip = \u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u043E\u043F\u043E\u0440/\u0440\u0430\u0437\u0433\u043E\u043D\u043D\u044B\u0445 \u0431\u043B\u043E\u043A\u043E\u0432 \u0431\u0443\u0434\u0443\u0442 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C\u0441\u044F, \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u043E\u043D\u0438 \u0432\u044B\u0431\u0440\u0430\u043D\u044B.
\u0412 \u043F\u0440\u043E\u0442\u0438\u0432\u043D\u043E\u043C \u0441\u043B\u0443\u0447\u0430\u0435 \u043C\u0430\u0440\u043A\u0435\u0440\u044B \u0431\u0443\u0434\u0443\u0442 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C\u0441\u044F \u0432\u0441\u0435\u0433\u0434\u0430. pref.dlg.checkbox.AlwaysOpenLeftmost = \u0412\u0441\u0435\u0433\u0434\u0430 \u0432\u044B\u0431\u0438\u0440\u0430\u0442\u044C \u043F\u0435\u0440\u0432\u0443\u044E \u0432\u043A\u043B\u0430\u0434\u043A\u0443 \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u043E\u043A\u043D\u0430 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = \u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u0435 \u043E\u043A\u043D\u043E \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0442\u044C\u0441\u044F \u0441 \u043F\u0435\u0440\u0432\u043E\u0439 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0439 \u0432\u043A\u043B\u0430\u0434\u043A\u043E\u0439.
\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C\u0441\u044F \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0430\u044F \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u0430\u044F \u0432\u043A\u043B\u0430\u0434\u043A\u0430. pref.dlg.lbl.User-definedthrust = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043F\u0440\u043E\u0444\u0438\u043B\u0438 \u0442\u044F\u0433\u0438: @@ -716,7 +718,7 @@ compaddbuttons.Launchlug = \u041D\u0430\u043F\u0440\u0430\u0432\u043B\u044F\u044 compaddbuttons.RailButton = \u0417\u0430\u0446\u0435\u043F\n\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u044F\u044E\u0449\u0435\u0439 compaddbuttons.InnerComponent = \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0435 \u0434\u0435\u0442\u0430\u043B\u0438 compaddbuttons.Innertube = \u0412\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u044F\u044F\n\u0442\u0440\u0443\u0431\u0430 -compaddbuttons.Coupler = \u041C\u0443\u0444\u0442\u0430 +compaddbuttons.Coupler = \u0422\u0440\u0443\u0431\u0447\u0430\u0442\u0430\u044F\n\u043C\u0443\u0444\u0442\u0430 compaddbuttons.Centeringring = \u0426\u0435\u043D\u0442\u0440\u0438\u0440\u0443\u044E\u0449\u0435\u0435\n\u043A\u043E\u043B\u044C\u0446\u043E compaddbuttons.Bulkhead = \u041F\u0435\u0440\u0435\u0431\u043E\u0440\u043A\u0430 compaddbuttons.Engineblock = \u0423\u043F\u043E\u0440\n\u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u044F @@ -898,6 +900,7 @@ RocketCompCfg.tab.Figstyleopt = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 RocketCompCfg.tab.Comment = \u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 RocketCompCfg.tab.Comment.ttip = \u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 \u043A \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0443 RocketCompCfg.tab.Appearance = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0432\u0438\u0434 +RocketCompCfg.tab.Appearance.ttip = \u0412\u043D\u0435\u0448\u043D\u0438\u0439 \u0432\u0438\u0434 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 RocketCompCfg.lbl.Mass = \u041C\u0430\u0441\u0441\u0430: RocketCompCfg.lbl.Componentmass = \u041C\u0430\u0441\u0441\u0430 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430: RocketCompCfg.lbl.overriddento = (\u043F\u0435\u0440\u0435\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043E \u043D\u0430 @@ -2075,8 +2078,10 @@ CustomFinImport.error.badimage = \u041D\u0435\u0432\u043E\u0437\u043C\u043E\u043 CustomFinImport.description = \u0418\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044F \u0432 \u0447\u0435\u0440\u043D\u043E-\u0431\u0435\u043B\u043E\u0435 (\u0433\u0434\u0435 \u0447\u0435\u0440\u043D\u044B\u0439 - \u0446\u0432\u0435\u0442 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430), \u0442\u0430\u043A \u0447\u0442\u043E \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0447\u0435\u0440\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 \u0434\u043B\u044F \u0440\u0438\u0441\u0443\u043D\u043A\u0430 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 \u0438 \u0431\u0435\u043B\u044B\u0439 \u0438\u043B\u0438 \u0441\u0432\u0435\u0442\u043B\u044B\u0439 \u0446\u0432\u0435\u0442 \u0434\u043B\u044F \u0444\u043E\u043D\u0430. \u041E\u0441\u043D\u043E\u0432\u0430\u043D\u0438\u0435 \u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0430\u0442\u043E\u0440\u0430 \u0434\u043E\u043B\u0436\u043D\u043E \u043D\u0430\u0447\u0438\u043D\u0430\u0442\u044C\u0441\u044F \u0441\u043D\u0438\u0437\u0443 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F. -PresetModel.lbl.custompreset = \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0020\u0434\u0435\u0442\u0430\u043b\u0435\u0439 -PresetModel.lbl.partsLib = \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0020\u0434\u0435\u0442\u0430\u043b\u0435\u0439 +PresetModel.combo.ttip = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u044B\u0445 (\u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0445 \u0432 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u043C \u043E\u043A\u043D\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043E\u043A \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432)
\u0438\u043B\u0438 \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0439", \u0435\u0441\u043B\u0438 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0430 \u043D\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F. +PresetModel.lbl.custompreset = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u0438\u0439 +PresetModel.lbl.partsLib = \u0411\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430 \u0434\u0435\u0442\u0430\u043B\u0435\u0439 +PresetModel.lbl.partsLib.ttip = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0434\u043B\u044F \u044D\u0442\u043E\u0433\u043E \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 \u0440\u0430\u043A\u0435\u0442\u044B \u0438\u0437 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u0435\u0442\u0430\u043B\u0435\u0439. DecalModel.lbl.select = <\u043D\u0435\u0442> DecalModel.lbl.choose = \u0418\u0437 \u0444\u0430\u0439\u043B\u0430... @@ -2098,7 +2103,7 @@ ComponentPresetChooserDialog.menu.sortDesc = \u041F\u043E \u0443\u0431\u044B\u04 ComponentPresetChooserDialog.menu.units = \u0415\u0434\u0438\u043D\u0438\u0446\u044B \u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u044F ComponentPresetChooserDialog.checkbox.showAllCompatible = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432\u0441\u0435 \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u044B\u0435 ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0431\u0430\u0437\u0443 \u0434\u0430\u043D\u043D\u044B\u0445 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0445 -ComponentPresetChooserDialog.lbl.favorites = \u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u043B\u044F \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0432 \u0432\u044B\u043F\u0430\u0434\u0430\u044E\u0449\u0435\u0435 \u043C\u0435\u043D\u044E +ComponentPresetChooserDialog.lbl.favorites = \u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A, \u0447\u0442\u043E\u0431\u044B \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043A\u0443 \u0432 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0435\u0435\u0441\u044F \u043C\u0435\u043D\u044E \u0437\u0430\u0433\u043E\u0442\u043E\u0432\u043E\u043A \u0432 \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u043C \u043E\u043A\u043D\u0435 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430. table.column.Favorite = \u0418\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0435 table.column.Legacy = \u0423\u0441\u0442\u0430\u0440\u0435\u043B\u043E table.column.Manufacturer = \u041F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C From 58c2df4336f9f69d7d4fe0d0e0eb3b2acd2aa269 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 21 Jul 2022 01:12:57 +0200 Subject: [PATCH 03/16] [#1516] Reselect preset row after favorite change --- .../sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java | 2 ++ .../gui/dialogs/preset/ComponentPresetTableColumn.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java index c361baebf..62c1bb31b 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java @@ -77,9 +77,11 @@ public class ComponentPresetTable extends JTable { if ( columnIndex != 0 ) { return; } + int selectedRow = ComponentPresetTable.this.getSelectedRow(); ComponentPreset preset = ComponentPresetTable.this.presets.get(rowIndex); Application.getComponentPresetDao().setFavorite(preset, presetType, (Boolean) aValue); ComponentPresetTable.this.updateFavorites(); + ComponentPresetTable.this.setRowSelectionInterval(selectedRow, selectedRow); } @Override diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java index 6bf137b28..04821f75d 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java @@ -33,7 +33,7 @@ public abstract class ComponentPresetTableColumn extends TableColumn { @Override public Object getValueFromPreset( Set favorites, ComponentPreset preset ) { - return Boolean.valueOf(favorites.contains(preset.preferenceKey())); + return favorites.contains(preset.preferenceKey()); } } From a9ede4b9728043e32f185ea350989505de644729 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Thu, 21 Jul 2022 01:20:57 +0200 Subject: [PATCH 04/16] Add clarifying text for applying preset selection --- core/resources/l10n/messages.properties | 2 +- .../gui/dialogs/preset/ComponentPresetChooserDialog.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index e70342af9..93872611c 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -2099,7 +2099,7 @@ ComponentPresetChooserDialog.menu.sortDesc = Sort Descending ComponentPresetChooserDialog.menu.units = Units ComponentPresetChooserDialog.checkbox.showAllCompatible = Show all compatible ComponentPresetChooserDialog.checkbox.showLegacyCheckBox = Show Legacy Database -ComponentPresetChooserDialog.lbl.favorites = Check to add preset to the preset drop-down menu in the component edit dialog +ComponentPresetChooserDialog.lbl.favorites = Check to add preset to the preset drop-down menu in the component edit dialog
Directly apply a preset by double-clicking it or by selecting it and closing this window. table.column.Favorite = Favorite table.column.Legacy = Legacy table.column.Manufacturer = Manufacturer diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java index 3061d6d62..6a1c417ad 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java @@ -25,6 +25,7 @@ import javax.swing.table.TableColumn; import javax.swing.table.TableModel; import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.preset.ComponentPreset; @@ -149,7 +150,7 @@ public class ComponentPresetChooserDialog extends JDialog { scrollpane.setViewportView(componentSelectionTable); panel.add(scrollpane, "grow, width 700lp, height 300lp, pushy, spanx, wrap rel"); - panel.add(new JLabel(Chars.UP_ARROW + " " + trans.get("lbl.favorites")), "spanx, gapleft 5px, wrap para"); + panel.add(new StyledLabel(String.format("%s %s", Chars.UP_ARROW, trans.get("lbl.favorites")), -1), "spanx, gapleft 5px, wrap para"); // Close buttons From 1c9838b94a0bc9526a9723be2d7833bc06aa2eca Mon Sep 17 00:00:00 2001 From: Jon Jagt Date: Thu, 21 Jul 2022 12:11:43 -0500 Subject: [PATCH 05/16] Pre-check "Match fore diameter" and "Match aft diameter" in preset chooser --- .../gui/dialogs/preset/ComponentPresetChooserDialog.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java index 3061d6d62..15be53e13 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java @@ -222,6 +222,7 @@ public class ComponentPresetChooserDialog extends JDialog { foreDiameterFilterCheckBox = new JCheckBox(trans.get("ComponentPresetChooserDialog.checkbox.filterForeDiameter")); final SymmetricComponent prevSym = curSym.getPreviousSymmetricComponent(); if (prevSym != null && foreDiameterColumnIndex >= 0) { + foreDiameterFilterCheckBox.setSelected(true); foreDiameterFilter = new ComponentPresetRowFilter(prevSym.getAftRadius() * 2.0, foreDiameterColumnIndex); panel.add(foreDiameterFilterCheckBox, "wrap"); foreDiameterFilterCheckBox.addItemListener(new ItemListener() { @@ -238,6 +239,7 @@ public class ComponentPresetChooserDialog extends JDialog { aftDiameterFilterCheckBox = new JCheckBox(trans.get("ComponentPresetChooserDialog.checkbox.filterAftDiameter")); final SymmetricComponent nextSym = curSym.getNextSymmetricComponent(); if (nextSym != null && aftDiameterColumnIndex >= 0) { + aftDiameterFilterCheckBox.setSelected(true); aftDiameterFilter = new ComponentPresetRowFilter(nextSym.getForeRadius() * 2.0, aftDiameterColumnIndex); panel.add(aftDiameterFilterCheckBox, "wrap"); aftDiameterFilterCheckBox.addItemListener(new ItemListener() { From 9b6f4bdeac9e31cacfd3fcf7a7aea2cce9edb099 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 22 Jul 2022 23:11:16 +0200 Subject: [PATCH 06/16] Fix sim button state not updating right --- .../net/sf/openrocket/gui/main/SimulationPanel.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index f8ac84ec5..b7f8fa649 100644 --- a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -496,11 +496,14 @@ public class SimulationPanel extends JPanel { }); simulationTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - private int previousRow = -1; + private int previousSelectedRow = -1; + private int previousSelectedRowCount = 0; public void valueChanged(ListSelectionEvent event) { - if (simulationTable.getSelectedRow() != previousRow) { + if ((simulationTable.getSelectedRow() != previousSelectedRow) || + (simulationTable.getSelectedRowCount() != previousSelectedRowCount)) { updateButtonStates(); - previousRow = simulationTable.getSelectedRow(); + previousSelectedRow = simulationTable.getSelectedRow(); + previousSelectedRowCount = simulationTable.getSelectedRowCount(); } } }); @@ -699,10 +702,11 @@ public class SimulationPanel extends JPanel { } else { if (selection.length > 1) { plotButton.setEnabled(false); + editButton.setEnabled(false); } else { plotButton.setEnabled(true); + editButton.setEnabled(true); } - editButton.setEnabled(true); runButton.setEnabled(true); deleteButton.setEnabled(true); } From 97a891ae1908722c2947a72a9cc225f551aafb26 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 23 Jul 2022 00:09:10 +0200 Subject: [PATCH 07/16] [#1549] Allow ctr/cmd + A command for sim table --- .../net/sf/openrocket/gui/main/SimulationPanel.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index b7f8fa649..447b6c0da 100644 --- a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -19,6 +19,7 @@ import java.util.Arrays; import java.util.Comparator; import javax.swing.AbstractAction; +import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; @@ -31,6 +32,7 @@ import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableCellRenderer; @@ -433,16 +435,7 @@ public class SimulationPanel extends JPanel { // Override processKeyBinding so that the JTable does not catch // key bindings used in menu accelerators simulationTable = new ColumnTable(simulationTableModel) { - private static final long serialVersionUID = -5799340181229735630L; - - @Override - protected boolean processKeyBinding(KeyStroke ks, - KeyEvent e, - int condition, - boolean pressed) { - return false; - } }; ColumnTableRowSorter simulationTableSorter = new ColumnTableRowSorter(simulationTableModel); simulationTable.setRowSorter(simulationTableSorter); From 3602700ff3c9f06c83e5504ca6fe8b30dea420cd Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 23 Jul 2022 00:15:19 +0200 Subject: [PATCH 08/16] [#1549] Select all shortcut in ComponentTree --- .../gui/main/componenttree/ComponentTree.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java b/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java index a02e626f9..a638ba8d0 100644 --- a/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java +++ b/swing/src/net/sf/openrocket/gui/main/componenttree/ComponentTree.java @@ -6,6 +6,9 @@ import javax.swing.ToolTipManager; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.gui.components.BasicTree; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + @SuppressWarnings("serial") public class ComponentTree extends BasicTree { @@ -13,7 +16,21 @@ public class ComponentTree extends BasicTree { public ComponentTree(OpenRocketDocument document) { super(); this.setModel(new ComponentTreeModel(document.getRocket(), this)); - + + addKeyListener(new KeyListener() { + @Override + public void keyTyped(KeyEvent e) { } + + @Override + public void keyPressed(KeyEvent e) { + if ((e.getKeyCode() == KeyEvent.VK_A) && ((e.getModifiersEx() & KeyEvent.META_DOWN_MASK) != 0)) { + setSelectionInterval(1, getRowCount()); // Don't select the rocket (row 0) + } + } + + @Override + public void keyReleased(KeyEvent e) { } + }); this.setCellRenderer(new ComponentTreeRenderer()); this.setDragEnabled(true); From ada48369e443f1e0195238ffe2b36de733b55d09 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 23 Jul 2022 13:44:07 +0200 Subject: [PATCH 09/16] Update sim panel context menu item state --- .../openrocket/gui/main/SimulationPanel.java | 207 ++++++++++-------- 1 file changed, 117 insertions(+), 90 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index 447b6c0da..a0904b7d1 100644 --- a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -19,7 +19,7 @@ import java.util.Arrays; import java.util.Comparator; import javax.swing.AbstractAction; -import javax.swing.InputMap; +import javax.swing.Action; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; @@ -32,7 +32,6 @@ import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; -import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableCellRenderer; @@ -100,83 +99,55 @@ public class SimulationPanel extends JPanel { private final JButton plotButton; private final JPopupMenu pm; + private final SimulationAction editSimulationAction; + private final SimulationAction runSimulationAction; + private final SimulationAction plotSimulationAction; + private final SimulationAction duplicateSimulationAction; + private final SimulationAction deleteSimulationAction; + public SimulationPanel(OpenRocketDocument doc) { super(new MigLayout("fill", "[grow][][][][][][grow]")); this.document = doc; + // Simulation actions + SimulationAction newSimulationAction = new NewSimulationAction(); + editSimulationAction = new EditSimulationAction(); + runSimulationAction = new RunSimulationAction(); + plotSimulationAction = new PlotSimulationAction(); + duplicateSimulationAction = new DuplicateSimulationAction(); + deleteSimulationAction = new DeleteSimulationAction(); - //////// The simulation action buttons + //////// The simulation action buttons //////// //// New simulation button - { - JButton button = new SelectColorButton(trans.get("simpanel.but.newsimulation")); - //// Add a new simulation - button.setToolTipText(trans.get("simpanel.but.ttip.newsimulation")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Simulation sim = new Simulation(document.getRocket()); - sim.setName(document.getNextSimulationName()); - - int n = document.getSimulationCount(); - document.addSimulation(sim); - simulationTableModel.fireTableDataChanged(); - simulationTable.clearSelection(); - simulationTable.addRowSelectionInterval(n, n); - - openDialog(false, sim); - } - }); - this.add(button, "skip 1, gapright para"); - } + JButton newButton = new SelectColorButton(); + tieActionToButtonNoIcon(newButton, newSimulationAction, trans.get("simpanel.but.newsimulation")); + newButton.setToolTipText(trans.get("simpanel.but.ttip.newsimulation")); + this.add(newButton, "skip 1, gapright para"); //// Edit simulation button - editButton = new SelectColorButton(trans.get("simpanel.but.editsimulation")); - //// Edit the selected simulation + editButton = new SelectColorButton(); + tieActionToButtonNoIcon(editButton, editSimulationAction, trans.get("simpanel.but.editsimulation")); editButton.setToolTipText(trans.get("simpanel.but.ttip.editsim")); - editButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - editSimulation(); - } - }); this.add(editButton, "gapright para"); //// Run simulations - runButton = new SelectColorButton(trans.get("simpanel.but.runsimulations")); - //// Re-run the selected simulations + runButton = new SelectColorButton(); + tieActionToButtonNoIcon(runButton, runSimulationAction, trans.get("simpanel.but.runsimulations")); runButton.setToolTipText(trans.get("simpanel.but.ttip.runsimu")); - runButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - runSimulation(); - } - }); this.add(runButton, "gapright para"); //// Delete simulations button - deleteButton = new SelectColorButton(trans.get("simpanel.but.deletesimulations")); - //// Delete the selected simulations + deleteButton = new SelectColorButton(); + tieActionToButtonNoIcon(deleteButton, deleteSimulationAction, trans.get("simpanel.but.deletesimulations")); deleteButton.setToolTipText(trans.get("simpanel.but.ttip.deletesim")); - deleteButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - deleteSimulation(); - } - }); this.add(deleteButton, "gapright para"); //// Plot / export button - plotButton = new SelectColorButton(trans.get("simpanel.but.plotexport")); - // button = new SelectColorButton("Plot flight"); - plotButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - plotSimulation(); - } - }); + plotButton = new SelectColorButton(); + tieActionToButtonNoIcon(plotButton, plotSimulationAction, trans.get("simpanel.but.plotexport")); this.add(plotButton, "wrap para"); @@ -268,7 +239,7 @@ public class SimulationPanel extends JPanel { if (row < 0 || row >= document.getSimulationCount()){ return null; } - + Rocket rkt = document.getRocket(); FlightConfigurationId fcid = document.getSimulation(row).getId(); return descriptor.format( rkt, fcid); @@ -423,7 +394,7 @@ public class SimulationPanel extends JPanel { } ) { - + private static final long serialVersionUID = 8686456963492628476L; @Override @@ -442,14 +413,15 @@ public class SimulationPanel extends JPanel { simulationTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); simulationTable.setDefaultRenderer(Object.class, new JLabelRenderer()); simulationTableModel.setColumnWidths(simulationTable.getColumnModel()); - - pm = new JPopupMenu(); - pm.add(new EditSimulationAction()); - pm.add(new DuplicateSimulationAction()); - pm.add(new DeleteSimulationAction()); - pm.addSeparator(); - pm.add(new RunSimulationAction()); - pm.add(new PlotSimulationAction()); + + // Context menu + pm = new JPopupMenu(); + pm.add(editSimulationAction); + pm.add(duplicateSimulationAction); + pm.add(deleteSimulationAction); + pm.addSeparator(); + pm.add(runSimulationAction); + pm.add(plotSimulationAction); // Mouse listener to act on double-clicks @@ -528,6 +500,19 @@ public class SimulationPanel extends JPanel { updateButtonStates(); } + private void newSimulation() { + Simulation sim = new Simulation(document.getRocket()); + sim.setName(document.getNextSimulationName()); + + int n = document.getSimulationCount(); + document.addSimulation(sim); + simulationTableModel.fireTableDataChanged(); + simulationTable.clearSelection(); + simulationTable.addRowSelectionInterval(n, n); + + openDialog(false, sim); + } + private void plotSimulation() { int selected = simulationTable.getSelectedRow(); if (selected < 0) { @@ -686,24 +671,11 @@ public class SimulationPanel extends JPanel { } private void updateButtonStates() { - int[] selection = simulationTable.getSelectedRows(); - if (selection.length == 0) { - editButton.setEnabled(false); - runButton.setEnabled(false); - deleteButton.setEnabled(false); - plotButton.setEnabled(false); - } else { - if (selection.length > 1) { - plotButton.setEnabled(false); - editButton.setEnabled(false); - } else { - plotButton.setEnabled(true); - editButton.setEnabled(true); - } - runButton.setEnabled(true); - deleteButton.setEnabled(true); - } - + editSimulationAction.updateEnabledState(); + deleteSimulationAction.updateEnabledState(); + runSimulationAction.updateEnabledState(); + plotSimulationAction.updateEnabledState(); + duplicateSimulationAction.updateEnabledState(); } /// when the simulation tab is selected this run outdated simulated if appropriate. @@ -775,7 +747,37 @@ public class SimulationPanel extends JPanel { } } - class EditSimulationAction extends AbstractAction { + private void tieActionToButtonNoIcon(JButton button, Action action, String text) { + button.setAction(action); + button.setIcon(null); + button.setText(text); + } + + private abstract static class SimulationAction extends AbstractAction { + private static final long serialVersionUID = 1L; + + public abstract void updateEnabledState(); + } + + class NewSimulationAction extends SimulationAction { + public NewSimulationAction() { + putValue(NAME, trans.get("simpanel.but.newsimulation")); + this.putValue(MNEMONIC_KEY, KeyEvent.VK_N); + this.putValue(SMALL_ICON, Icons.FILE_NEW); + } + + @Override + public void actionPerformed(ActionEvent e) { + newSimulation(); + } + + @Override + public void updateEnabledState() { + setEnabled(true); + } + } + + class EditSimulationAction extends SimulationAction { public EditSimulationAction() { putValue(NAME, trans.get("simpanel.pop.edit")); this.putValue(MNEMONIC_KEY, KeyEvent.VK_E); @@ -787,9 +789,14 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { editSimulation(); } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() == 1); + } } - class RunSimulationAction extends AbstractAction { + class RunSimulationAction extends SimulationAction { public RunSimulationAction() { putValue(NAME, trans.get("simpanel.pop.run")); putValue(SMALL_ICON, Icons.SIM_RUN); @@ -799,9 +806,14 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { runSimulation(); } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() > 0); + } } - class DeleteSimulationAction extends AbstractAction { + class DeleteSimulationAction extends SimulationAction { public DeleteSimulationAction() { putValue(NAME, trans.get("simpanel.pop.delete")); putValue(MNEMONIC_KEY, KeyEvent.VK_D); @@ -813,9 +825,14 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { deleteSimulation(); } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() > 0); + } } - class PlotSimulationAction extends AbstractAction { + class PlotSimulationAction extends SimulationAction { public PlotSimulationAction() { putValue(NAME, trans.get("simpanel.pop.plot")); putValue(SMALL_ICON, Icons.SIM_PLOT); @@ -825,9 +842,14 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { plotSimulation(); } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() == 1); + } } - class DuplicateSimulationAction extends AbstractAction { + class DuplicateSimulationAction extends SimulationAction { public DuplicateSimulationAction() { putValue(NAME, trans.get("simpanel.pop.duplicate")); putValue(MNEMONIC_KEY, KeyEvent.VK_D); @@ -839,7 +861,12 @@ public class SimulationPanel extends JPanel { public void actionPerformed(ActionEvent e) { duplicateSimulation(); } - } + + @Override + public void updateEnabledState() { + setEnabled(simulationTable.getSelectedRowCount() > 0); + } + } public static class CellTransferable implements Transferable { From c29955b7f859ae597a6f22298b80fe8f6b2165f6 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 23 Jul 2022 14:04:09 +0200 Subject: [PATCH 10/16] Move method to RocketActions --- .../sf/openrocket/gui/main/RocketActions.java | 30 +++++++++++++++++++ .../openrocket/gui/main/SimulationPanel.java | 18 ++++------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/main/RocketActions.java b/swing/src/net/sf/openrocket/gui/main/RocketActions.java index 86a3ea6bf..15ed1d597 100644 --- a/swing/src/net/sf/openrocket/gui/main/RocketActions.java +++ b/swing/src/net/sf/openrocket/gui/main/RocketActions.java @@ -12,6 +12,7 @@ import java.util.List; import javax.swing.AbstractAction; import javax.swing.Action; +import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -189,6 +190,35 @@ public class RocketActions { return moveDownAction; } + /** + * Tie an action to a JButton, without using the icon or text of the action for the button. + * + * For any smartass that wants to know why you don't just initialize the JButton with the action and then set the + * icon to null and set the button text: this causes a bug where the text of the icon becomes much smaller than is intended. + * + * @param button button to tie the action to + * @param action action to tie to the button + * @param text text to display on the button + */ + public static void tieActionToButtonNoIcon(JButton button, Action action, String text) { + button.setAction(action); + button.setIcon(null); + button.setText(text); + } + + /** + * Tie an action to a JButton, without using the icon of the action for the button. + * + * For any smartass that wants to know why you don't just initialize the JButton with the action and then set the + * icon to null: this causes a bug where the text of the icon becomes much smaller than is intended. + * + * @param button button to tie the action to + * @param action action to tie to the button + */ + public static void tieActionToButtonNoIcon(JButton button, Action action) { + button.setAction(action); + button.setIcon(null); + } //////// Helper methods for the actions diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index a0904b7d1..be9359509 100644 --- a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -10,7 +10,6 @@ import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -19,7 +18,6 @@ import java.util.Arrays; import java.util.Comparator; import javax.swing.AbstractAction; -import javax.swing.Action; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; @@ -123,31 +121,31 @@ public class SimulationPanel extends JPanel { //// New simulation button JButton newButton = new SelectColorButton(); - tieActionToButtonNoIcon(newButton, newSimulationAction, trans.get("simpanel.but.newsimulation")); + RocketActions.tieActionToButtonNoIcon(newButton, newSimulationAction, trans.get("simpanel.but.newsimulation")); newButton.setToolTipText(trans.get("simpanel.but.ttip.newsimulation")); this.add(newButton, "skip 1, gapright para"); //// Edit simulation button editButton = new SelectColorButton(); - tieActionToButtonNoIcon(editButton, editSimulationAction, trans.get("simpanel.but.editsimulation")); + RocketActions.tieActionToButtonNoIcon(editButton, editSimulationAction, trans.get("simpanel.but.editsimulation")); editButton.setToolTipText(trans.get("simpanel.but.ttip.editsim")); this.add(editButton, "gapright para"); //// Run simulations runButton = new SelectColorButton(); - tieActionToButtonNoIcon(runButton, runSimulationAction, trans.get("simpanel.but.runsimulations")); + RocketActions.tieActionToButtonNoIcon(runButton, runSimulationAction, trans.get("simpanel.but.runsimulations")); runButton.setToolTipText(trans.get("simpanel.but.ttip.runsimu")); this.add(runButton, "gapright para"); //// Delete simulations button deleteButton = new SelectColorButton(); - tieActionToButtonNoIcon(deleteButton, deleteSimulationAction, trans.get("simpanel.but.deletesimulations")); + RocketActions.tieActionToButtonNoIcon(deleteButton, deleteSimulationAction, trans.get("simpanel.but.deletesimulations")); deleteButton.setToolTipText(trans.get("simpanel.but.ttip.deletesim")); this.add(deleteButton, "gapright para"); //// Plot / export button plotButton = new SelectColorButton(); - tieActionToButtonNoIcon(plotButton, plotSimulationAction, trans.get("simpanel.but.plotexport")); + RocketActions.tieActionToButtonNoIcon(plotButton, plotSimulationAction, trans.get("simpanel.but.plotexport")); this.add(plotButton, "wrap para"); @@ -747,12 +745,6 @@ public class SimulationPanel extends JPanel { } } - private void tieActionToButtonNoIcon(JButton button, Action action, String text) { - button.setAction(action); - button.setIcon(null); - button.setText(text); - } - private abstract static class SimulationAction extends AbstractAction { private static final long serialVersionUID = 1L; From 587babb5669ef3c590128eab827f479dad83287f Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 23 Jul 2022 14:07:23 +0200 Subject: [PATCH 11/16] Use getDeleteAction in BasicFrame Fixes the bug of the text for edit, delete and duplicate button to become smaller --- swing/src/net/sf/openrocket/gui/main/BasicFrame.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java index 6f76a838d..e5e31ce87 100644 --- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -418,18 +418,18 @@ public class BasicFrame extends JFrame { button = new SelectColorButton(actions.getMoveDownAction()); panel.add(button, "sizegroup buttons, aligny 0%"); - button = new SelectColorButton(actions.getEditAction()); - button.setIcon(null); + button = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(button, actions.getEditAction()); button.setMnemonic(0); panel.add(button, "sizegroup buttons, gaptop 20%"); - button = new SelectColorButton(actions.getDuplicateAction()); - button.setIcon(null); + button = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(button, actions.getDuplicateAction()); button.setMnemonic(0); panel.add(button, "sizegroup buttons"); - button = new SelectColorButton(actions.getDeleteAction()); - button.setIcon(null); + button = new SelectColorButton(); + RocketActions.tieActionToButtonNoIcon(button, actions.getDeleteAction()); button.setMnemonic(0); panel.add(button, "sizegroup buttons"); From 651ba88a475daa8ec504eb0bd5e23e10a96cc038 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 23 Jul 2022 14:36:33 +0200 Subject: [PATCH 12/16] Clean up code... --- .../openrocket/gui/main/SimulationPanel.java | 498 +++++++++--------- 1 file changed, 249 insertions(+), 249 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java index be9359509..efd353b90 100644 --- a/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/SimulationPanel.java @@ -151,255 +151,7 @@ public class SimulationPanel extends JPanel { //////// The simulation table - - simulationTableModel = new ColumnTableModel( - - //// Status and warning column - new Column("") { - private JLabel label = null; - - @Override - public Object getValueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - // Initialize the label - if (label == null) { - label = new StyledLabel(2f); - label.setIconTextGap(1); - // label.setFont(label.getFont().deriveFont(Font.BOLD)); - } - - // Set simulation status icon - Simulation.Status status = document.getSimulation(row).getStatus(); - label.setIcon(Icons.SIMULATION_STATUS_ICON_MAP.get(status)); - - - // Set warning marker - if (status == Simulation.Status.NOT_SIMULATED || - status == Simulation.Status.EXTERNAL) { - - label.setText(""); - - } else { - - WarningSet w = document.getSimulation(row).getSimulatedWarnings(); - if (w == null) { - label.setText(""); - } else if (w.isEmpty()) { - label.setForeground(OK_COLOR); - label.setText(OK_TEXT); - } else { - label.setForeground(WARNING_COLOR); - label.setText(WARNING_TEXT); - } - } - - return label; - } - - @Override - public int getExactWidth() { - return 36; - } - - @Override - public Class getColumnClass() { - return JLabel.class; - } - }, - - //// Simulation name - //// Name - new Column(trans.get("simpanel.col.Name")) { - @Override - public Object getValueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - return document.getSimulation(row).getName(); - } - - @Override - public int getDefaultWidth() { - return 125; - } - - @Override - public Comparator getComparator() { - return new AlphanumComparator(); - } - }, - - //// Simulation configuration - new Column(trans.get("simpanel.col.Configuration")) { - @Override - public Object getValueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()){ - return null; - } - - Rocket rkt = document.getRocket(); - FlightConfigurationId fcid = document.getSimulation(row).getId(); - return descriptor.format( rkt, fcid); - } - - @Override - public int getDefaultWidth() { - return 125; - } - }, - - //// Launch rod velocity - new ValueColumn(trans.get("simpanel.col.Velocityoffrod"), UnitGroup.UNITS_VELOCITY) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getLaunchRodVelocity(); - } - - }, - - //// Apogee - new ValueColumn(trans.get("simpanel.col.Apogee"), UnitGroup.UNITS_DISTANCE) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getMaxAltitude(); - } - }, - - //// Velocity at deployment - new ValueColumn(trans.get("simpanel.col.Velocityatdeploy"), UnitGroup.UNITS_VELOCITY) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getDeploymentVelocity(); - } - }, - - //// Deployment Time from Apogee - new ValueColumn(trans.get("simpanel.col.OptimumCoastTime"), - trans.get("simpanel.col.OptimumCoastTime.ttip"), - UnitGroup.UNITS_SHORT_TIME) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null || data.getBranchCount() == 0) - return null; - - double val = data.getBranch(0).getOptimumDelay(); - if ( Double.isNaN(val) ) { - return null; - } - return val; - } - }, - - //// Maximum velocity - new ValueColumn(trans.get("simpanel.col.Maxvelocity"), UnitGroup.UNITS_VELOCITY) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getMaxVelocity(); - } - }, - - //// Maximum acceleration - new ValueColumn(trans.get("simpanel.col.Maxacceleration"), UnitGroup.UNITS_ACCELERATION) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getMaxAcceleration(); - } - }, - - //// Time to apogee - new ValueColumn(trans.get("simpanel.col.Timetoapogee"), UnitGroup.UNITS_FLIGHT_TIME) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getTimeToApogee(); - } - }, - - //// Flight time - new ValueColumn(trans.get("simpanel.col.Flighttime"), UnitGroup.UNITS_FLIGHT_TIME) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getFlightTime(); - } - }, - - //// Ground hit velocity - new ValueColumn(trans.get("simpanel.col.Groundhitvelocity"), UnitGroup.UNITS_VELOCITY) { - @Override - public Double valueAt(int row) { - if (row < 0 || row >= document.getSimulationCount()) - return null; - - FlightData data = document.getSimulation(row).getSimulatedData(); - if (data == null) - return null; - - return data.getGroundHitVelocity(); - } - } - - ) { - - private static final long serialVersionUID = 8686456963492628476L; - - @Override - public int getRowCount() { - return document.getSimulationCount(); - } - }; + simulationTableModel = new SimulationTableModel(); // Override processKeyBinding so that the JTable does not catch // key bindings used in menu accelerators @@ -971,6 +723,254 @@ public class SimulationPanel extends JPanel { return tip; } + } + private class SimulationTableModel extends ColumnTableModel { + private static final long serialVersionUID = 8686456963492628476L; + + public SimulationTableModel() { + super( + //// Status and warning column + new Column("") { + private JLabel label = null; + + @Override + public Object getValueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + // Initialize the label + if (label == null) { + label = new StyledLabel(2f); + label.setIconTextGap(1); + // label.setFont(label.getFont().deriveFont(Font.BOLD)); + } + + // Set simulation status icon + Simulation.Status status = document.getSimulation(row).getStatus(); + label.setIcon(Icons.SIMULATION_STATUS_ICON_MAP.get(status)); + + + // Set warning marker + if (status == Simulation.Status.NOT_SIMULATED || + status == Simulation.Status.EXTERNAL) { + + label.setText(""); + + } else { + + WarningSet w = document.getSimulation(row).getSimulatedWarnings(); + if (w == null) { + label.setText(""); + } else if (w.isEmpty()) { + label.setForeground(OK_COLOR); + label.setText(OK_TEXT); + } else { + label.setForeground(WARNING_COLOR); + label.setText(WARNING_TEXT); + } + } + + return label; + } + + @Override + public int getExactWidth() { + return 36; + } + + @Override + public Class getColumnClass() { + return JLabel.class; + } + }, + + //// Simulation name + //// Name + new Column(trans.get("simpanel.col.Name")) { + @Override + public Object getValueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + return document.getSimulation(row).getName(); + } + + @Override + public int getDefaultWidth() { + return 125; + } + + @Override + public Comparator getComparator() { + return new AlphanumComparator(); + } + }, + + //// Simulation configuration + new Column(trans.get("simpanel.col.Configuration")) { + @Override + public Object getValueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) { + return null; + } + + Rocket rkt = document.getRocket(); + FlightConfigurationId fcid = document.getSimulation(row).getId(); + return descriptor.format(rkt, fcid); + } + + @Override + public int getDefaultWidth() { + return 125; + } + }, + + //// Launch rod velocity + new ValueColumn(trans.get("simpanel.col.Velocityoffrod"), UnitGroup.UNITS_VELOCITY) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getLaunchRodVelocity(); + } + + }, + + //// Apogee + new ValueColumn(trans.get("simpanel.col.Apogee"), UnitGroup.UNITS_DISTANCE) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getMaxAltitude(); + } + }, + + //// Velocity at deployment + new ValueColumn(trans.get("simpanel.col.Velocityatdeploy"), UnitGroup.UNITS_VELOCITY) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getDeploymentVelocity(); + } + }, + + //// Deployment Time from Apogee + new ValueColumn(trans.get("simpanel.col.OptimumCoastTime"), + trans.get("simpanel.col.OptimumCoastTime.ttip"), UnitGroup.UNITS_SHORT_TIME) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null || data.getBranchCount() == 0) + return null; + + double val = data.getBranch(0).getOptimumDelay(); + if (Double.isNaN(val)) { + return null; + } + return val; + } + }, + + //// Maximum velocity + new ValueColumn(trans.get("simpanel.col.Maxvelocity"), UnitGroup.UNITS_VELOCITY) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getMaxVelocity(); + } + }, + + //// Maximum acceleration + new ValueColumn(trans.get("simpanel.col.Maxacceleration"), UnitGroup.UNITS_ACCELERATION) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getMaxAcceleration(); + } + }, + + //// Time to apogee + new ValueColumn(trans.get("simpanel.col.Timetoapogee"), UnitGroup.UNITS_FLIGHT_TIME) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getTimeToApogee(); + } + }, + + //// Flight time + new ValueColumn(trans.get("simpanel.col.Flighttime"), UnitGroup.UNITS_FLIGHT_TIME) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getFlightTime(); + } + }, + + //// Ground hit velocity + new ValueColumn(trans.get("simpanel.col.Groundhitvelocity"), UnitGroup.UNITS_VELOCITY) { + @Override + public Double valueAt(int row) { + if (row < 0 || row >= document.getSimulationCount()) + return null; + + FlightData data = document.getSimulation(row).getSimulatedData(); + if (data == null) + return null; + + return data.getGroundHitVelocity(); + } + } + ); + } + + @Override + public int getRowCount() { + return document.getSimulationCount(); + } } } From 9a595754248e11b1eeb8e68381233b48105eb925 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Sat, 23 Jul 2022 15:15:18 +0200 Subject: [PATCH 13/16] Update unit tests Because simulations are not exact, the sim results can vary, which causes unittests to fail sporadically. So increase the error margin... --- .../test/net/sf/openrocket/simulation/DisableStageTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/test/net/sf/openrocket/simulation/DisableStageTest.java b/core/test/net/sf/openrocket/simulation/DisableStageTest.java index 9b4b0f7df..d4b7d5a1d 100644 --- a/core/test/net/sf/openrocket/simulation/DisableStageTest.java +++ b/core/test/net/sf/openrocket/simulation/DisableStageTest.java @@ -19,6 +19,8 @@ import org.junit.Test; * @author Sibo Van Gool */ public class DisableStageTest extends BaseTestCase { + private final double delta = 0.08; // 8 % error margin (simulations are not exact) + /** * Tests that the simulation results are correct when a single stage is deactivated and re-activated. */ @@ -54,7 +56,6 @@ public class DisableStageTest extends BaseTestCase { simDisabled.getActiveConfiguration().setAllStages(); // Re-enable all stages. - double delta = 0.05; // 5 % error margin (simulations are not exact) compareSims(simOriginal, simDisabled, simulationListener, delta); } @@ -84,7 +85,6 @@ public class DisableStageTest extends BaseTestCase { SimulationListener simulationListener = new AbstractSimulationListener(); - double delta = 0.05; // 5 % error margin (simulations are not exact) compareSims(simRemoved, simDisabled, simulationListener, delta); //// Test re-enableing the stage. @@ -175,7 +175,6 @@ public class DisableStageTest extends BaseTestCase { SimulationListener simulationListener = new AbstractSimulationListener(); - double delta = 0.05; // 5 % error margin (simulations are not exact) compareSims(simRemoved, simDisabled, simulationListener, delta); //// Test re-enableing the stage. @@ -243,7 +242,6 @@ public class DisableStageTest extends BaseTestCase { simDisabled.getActiveConfiguration().setAllStages(); - double delta = 0.05; // 5 % error margin (simulations are not exact) compareSims(simOriginal, simDisabled, simulationListener, delta); } From 2badfe850d04cc3f5dd372b7363ca2b059d6d7eb Mon Sep 17 00:00:00 2001 From: Jon Jagt Date: Mon, 25 Jul 2022 10:51:57 -0500 Subject: [PATCH 14/16] Change Diameter Filters to use Preferences Add preferences for "match diameter" filters in the Component Preset Chooser to Preferences; change filter pre-checks to use those preferences. --- .../sf/openrocket/startup/Preferences.java | 41 +++++++++++++++++++ .../preset/ComponentPresetChooserDialog.java | 9 +++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java index 3d750c651..90da3c320 100644 --- a/core/src/net/sf/openrocket/startup/Preferences.java +++ b/core/src/net/sf/openrocket/startup/Preferences.java @@ -63,6 +63,9 @@ public abstract class Preferences implements ChangeSource { public static final String MOTOR_DIAMETER_FILTER = "MotorDiameterMatch"; public static final String MOTOR_HIDE_SIMILAR = "MotorHideSimilar"; public static final String MOTOR_HIDE_UNAVAILABLE = "MotorHideUnavailable"; + + public static final String MATCH_FORE_DIAMETER = "MatchForeDiameter"; + public static final String MATCH_AFT_DIAMETER = "MatchAftDiameter"; // Node names public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "preferredThrustCurveMotors"; @@ -490,6 +493,44 @@ public abstract class Preferences implements ChangeSource { return this.getBoolean(SHOW_MARKERS, false); } + /** + * Set whether the component preset chooser dialog should filter by fore diameter when the window is opened. + * @param enabled true if the fore diameter filter should be enabled, + * false if it should be disabled. + */ + public final void setMatchForeDiameter(boolean enabled) { + this.putBoolean(MATCH_FORE_DIAMETER, enabled); + } + + /** + * Answer if the component preset chooser dialog should filter by fore diameter when the window is opened. + * + * @return true if the fore diameter filter should be enabled, + * false if it should be disabled. + */ + public final boolean isMatchForeDiameter() { + return this.getBoolean(MATCH_FORE_DIAMETER, true); + } + + /** + * Set whether the component preset chooser dialog should filter by aft diameter when the window is opened. + * @param enabled true if the aft diameter filter should be enabled, + * false if it should be disabled. + */ + public final void setMatchAftDiameter(boolean enabled) { + this.putBoolean(MATCH_AFT_DIAMETER, enabled); + } + + /** + * Answer if the component preset chooser dialog should filter by aft diameter when the window is opened. + * + * @return true if the aft diameter filter should be enabled, + * false if it should be disabled. + */ + public final boolean isMatchAftDiameter() { + return this.getBoolean(MATCH_AFT_DIAMETER, true); + } + /** * Return the OpenRocket unique ID. * diff --git a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java index 15be53e13..ae556b57b 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java @@ -26,6 +26,7 @@ import javax.swing.table.TableModel; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.gui.util.GUIUtil; +import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.TypedKey; @@ -43,6 +44,8 @@ public class ComponentPresetChooserDialog extends JDialog { private static final Translator trans = Application.getTranslator(); + private final SwingPreferences preferences = (SwingPreferences) Application.getPreferences(); + private final RocketComponent component; private ComponentPresetTable componentSelectionTable; @@ -222,13 +225,14 @@ public class ComponentPresetChooserDialog extends JDialog { foreDiameterFilterCheckBox = new JCheckBox(trans.get("ComponentPresetChooserDialog.checkbox.filterForeDiameter")); final SymmetricComponent prevSym = curSym.getPreviousSymmetricComponent(); if (prevSym != null && foreDiameterColumnIndex >= 0) { - foreDiameterFilterCheckBox.setSelected(true); + foreDiameterFilterCheckBox.setSelected(preferences.isMatchForeDiameter()); foreDiameterFilter = new ComponentPresetRowFilter(prevSym.getAftRadius() * 2.0, foreDiameterColumnIndex); panel.add(foreDiameterFilterCheckBox, "wrap"); foreDiameterFilterCheckBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { updateFilters(); + preferences.setMatchForeDiameter(foreDiameterFilterCheckBox.isSelected()); } }); } @@ -239,13 +243,14 @@ public class ComponentPresetChooserDialog extends JDialog { aftDiameterFilterCheckBox = new JCheckBox(trans.get("ComponentPresetChooserDialog.checkbox.filterAftDiameter")); final SymmetricComponent nextSym = curSym.getNextSymmetricComponent(); if (nextSym != null && aftDiameterColumnIndex >= 0) { - aftDiameterFilterCheckBox.setSelected(true); + aftDiameterFilterCheckBox.setSelected(preferences.isMatchAftDiameter()); aftDiameterFilter = new ComponentPresetRowFilter(nextSym.getForeRadius() * 2.0, aftDiameterColumnIndex); panel.add(aftDiameterFilterCheckBox, "wrap"); aftDiameterFilterCheckBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { updateFilters(); + preferences.setMatchAftDiameter(aftDiameterFilterCheckBox.isSelected()); } }); } From 4b6f28b74f442bd2b4899c08e2e5b7f73cca9eae Mon Sep 17 00:00:00 2001 From: Billy Olsen Date: Mon, 25 Jul 2022 19:30:30 -0700 Subject: [PATCH 15/16] Mark the snap grade as stable The grade of the snap is marked as devel, which is great while the app is being developed but means that the snap is not eligible to be published to candidate or stable release channels. This change marks the snap grade as stable to allow it to be released. Additionally, the automatic snap publishing that happens for each commit pushed to the unstable branch has been failing to release the snap revisions due to a symlink introduced in the openjdk package for which leaves a dangling symlink certs. The blacklisted.certs should be now contained in blocked.certs so we add that to the list of files to remove when being primed (final preparation for snap packaging). Signed-off-by: Billy Olsen --- snap/snapcraft.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index aca598150..af6fe1e98 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: openrocket adopt-info: openrocket -grade: devel +grade: stable summary: A free, fully featured model rocket simulator. description: | OpenRocket is a free, fully featured model rocket simulator that allows you @@ -77,6 +77,7 @@ parts: prime: - -usr/lib/jvm/java-*/lib/security/cacerts - -usr/lib/jvm/java-*/jre/lib/security/cacerts + - -usr/lib/jvm/java-*/lib/security/blacklisted.certs launcher: plugin: dump From 49490506345be142c751a18ce86c4cf76626350d Mon Sep 17 00:00:00 2001 From: David Cain Date: Tue, 26 Jul 2022 22:54:54 -0400 Subject: [PATCH 16/16] Update Pods icons Update the xcf and ping files for improved pod icons. The new pod icons better match the current display of Pod markers and better indicate the function of the button. Signed-off-by: David Cain --- .../pix/componenticons/pods-large.xcf.gz | Bin 7835 -> 3231 bytes .../pix/componenticons/pods-small.xcf.gz | Bin 1008 -> 949 bytes .../pix/componenticons/pods-large.png | Bin 19209 -> 1020 bytes .../pix/componenticons/pods-small.png | Bin 5777 -> 182 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/core/resources-src/pix/componenticons/pods-large.xcf.gz b/core/resources-src/pix/componenticons/pods-large.xcf.gz index 0c28362eb6b1c6c8a8d3e157bc72003488ed7b63..6d81c3d0eac9217d7f0dfb1998c40409a32cb8ab 100644 GIT binary patch literal 3231 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 R93(MJ{{_CtbQIPa000QDNag?l literal 7835 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 diff --git a/core/resources-src/pix/componenticons/pods-small.xcf.gz b/core/resources-src/pix/componenticons/pods-small.xcf.gz index 3af13b5f1b92c6cc690c0faa4489f36e82b8ebb9..17e95a14e2a8eb200993c2772bfa29dfd2e009e3 100644 GIT binary patch literal 949 zcmV;m14{fKiwFocHQ!|wElp_pcPyE>vnf`Gnnj#-DyokRPd$;MMV#K5wC(?RnS8ZUQ|4)7Zt&i z7kd%>i*K^CI?>eB;=#AP%$s@Ndpqx&mq{#=&7r(*qA5jHC6I-nt)MlaS3oYP^=ZGx7d>HiM?H>k-H9>r%r?7s9sg81UY{u6-lh5ZvT1V&FZ7VW7L%ghnY3MEuksRAv1?!vZ3(+oZr^nPNLz#FT8ce@1JRHHy1 zpsRrQU}%|1hTR8e1VvZDkNyk@C3>TgYWc_Jj8CN<>V%W5A@@R$;Xm!&$EHXgXGRC% zux!sSc6Mrnh%qsu;yXsOxp0mJcxfl+Z)w;uX4_FYdS^13avhVfe%p?1>=GSqceMiI ztFvXG#5Ct{bPSpY9p=5y+SPAWS?QJ4=t$72veFY%Dt6(I6!3*I3-eDfJRIIZJnFcG z1L~oOM~9|pOw;|n=Um5_)UolG;htmCW15S%T0lc6vDGvQbY%ezVvktBB~rtx65jNe zS&yZ$UA@G37!xy>Xb*qwsiBG^c!($b1>Ek;H>pZjkP;>YVuw9$GKE5efhRBURSB literal 1008 zcmV3EPKsTRhM0PdHVOC&)@lVL!~(DRkvj|)`_%T~lF({e zp(Xc{d{SHQxeneZen6SGwrG|rivJ467k$5o*lLeb<;cx`cv8z;Hx9RpAa~n zZU~#&0X_=#>InSq>jj1SO0_)dW%kaD-)ggvl{Wa{KY;TDYGSdwZl^>9p7w~ddyBfn z3q6+34BHe*hqE@*Z6 z9B=syS4(E;#24j@@5u{t3rK@KRjOvOvQjixwyRfHuYIsut$rp~*UGQ&5*n7&<;bS3 z$Y!2J)_4`!?2X9go-bDBS+`FYKsmHo2PW@L`nzoOw5q<;={UVA_N3$97}-545V zt@MqU9FN~uK|_pR4__X>9Dp98)2I}GaVCjM)puMfRShYbb_`vzR_4o?9FKpaf+MKR z>r`_5BoUcX450Cd%%CALzKtPE)-ryG$?^D)$E!~#(vU=Q=%jI&LgRCoMnf|FDuyRn zD?1mHep=}F;a8pTUNGo*q5ph7iH^D~A-FxKy-SL7i_l~do02a%F0n~8B>A7U ziQ2rZbv_@HZ`?EMiI&7e<5-(82rf3S7=@qvG5aZHZOgKaL>yOfk#s?SAQ)1)H%NhW#zg|oA4%aZY0{*1=`5>h-KwV1|MqOc6lJb4}N4YD$tDoQjFS7@`sIzQ#>pR&(e`b2nS86}ga z(WFfaw#Uy}v~hnpQc^s!NQ*5gJB8rM7-BHA_?*jp!+pBM^chq;d|RQuJt^RE80r9Y z>2k<1F{eStQrRUaJQ*I31K<>R!y$+C^6X-{>>ASu-~ojPx*XGEh{IK>6LpS?H`Hjc zLW`KU#3a=ys`su@cv2E{_)V3=oI{79$@^^a8BI=!^Y(wJmhaP}##m>C9UNlajl?=c zId)i~o;S)RDJ%`HnHNg#$*v4VWGK6GPZ0BhYc#OS(Tr3yxMY64nmm)~cqUg9^9vVg zETcxD(A4ShwUVFZY&;Pq+^0hw{ag^Rv*Jw0m&A?M?~leC90fc+}_945upif>uk7@+6Xg)TSzjR zgoZ4)3YtB5UO@63U@siI!IELnvow0{u&o2N@O98r^00v9Axh{4tf2Rq}` zd#l&ExB7qq&}5xWHuyw+Ar?CB*nrC9dv@954f|o&s~mTIdTQE*-s)Aje~1MV`GZSb zIlg~Pm%rtZBf9*>NxrMlli3n)bwHm4;eeDr$L#Yb8c#x>e>mcVA=jzVX06zh*%EIR zli?X~!hjxKnnY+kDFb3+QZ!BKGz&agh6h{ftzrfYaVTOUA`BWIOkIXx5CmP|$=pau zxwlG4aUnIv1uD33tOifE*pt}`-YN^Pb7*SPoP=N{1dm(n$?TN3k^pqTe(+Y=ghO-_ z<@IjOhnLOA$z)BA6QD+uRhkUwF(An)WX`0Jyv~YnGHZ#{#20#o45zo27{moQGk08h gGEPaWI>a*EzXOO0<0*h7X#fBK07*qoM6N<$g7U7@-~a#s literal 19209 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 Z_BTb|qVU91*gu;9IVojGwS;Nd{{oWX+ok{j diff --git a/core/resources/pix/componenticons/pods-small.png b/core/resources/pix/componenticons/pods-small.png index 4deee6b90758a858253ea6415a9c6d8233f80e6c..17371e846f9a8ed8e3f095bc5feec28f0cc72813 100644 GIT binary patch delta 145 zcmV;C0B--0Ew%xW83+Ub000iV&+3!T6&QVJNklJA5QX7)#?5pHmod&` zp^Xe-;S@Ah&hXm^97bPt+?PiP2FfwHgBlM(=BO0~m2!MvOd5U?m>MT-=* z;F}h^wH7T!S8Z2$xD{c2fLb4`mMRLOP_1;;+GF!K#CWFCnSBEQOssG?R%+(qEZrt{@r*B?>T9UH3f@4nKD->KTZ z^7_HTrS3IzuIxYVc0WcL)l_?EXN&KLWkTrf=76y(?EK={=Ywl=$Et2jK3`ovUVfpb z_Rf?#SGSmJOhtq29siy)=HWWI|ET(p#__BC0!HuZ+@T`NUT1N)|J;o}@Y!_sQbo*N z?}t4XT`I08y`HLF?|b^z&mNmoJ8$hiUg6$+%5T93>vn#$Z{M+;tKSEA?YUUJrFhxZ z(wHgdR=9q?LtKypNr|Jcc`a z=uM0-bT5Z3**G~8PuO5!ooU)%b<>qS;`S-8)~x0)&mKbdUiRmEl#TrI0p`9?d~Z@< z%QrKZrN6lAe#xi@9jnh;&{ZkWOefc)2Q=CFzIQIIsCZ@AR%SuXf$wemy|@OLlgdN3j4xWR42Toy{X%`l=1-KRso!42*h(xdEmsO$&@ODu z{NkUIXCA9-+_RApI_|RJ9vqjy`hE7o$x@CNusrc~|h(vD>De zPTdr?)Y}|8_XGLX5bu`PCZ@kRzGmH`(c_2AOBuTI>$-KSPs?npQd+c#4-=DYU9Rcg zz03*mZiK%(+_U(6)VyKWrZ&Cz=-t_g-MzyIr|t!vKe>OgZ=coZQ5)4>gnO0;w+!FD zsJ?nd^22{TOgS<5c{Jxl<5G`>ml`UxYg5;p{8qJ#!Eky9S16*@3Ppe2gK96&TO|)a zFwLhaHSQDksE{d@uKLQzSCuNCFPN&z5gAKnj*Z|v9I-*`PalPDt-OFxX+T;5}kG!YNDfIJ3(Pu`tugPyC#&u}lsAU(<85uf! z=#OZ)ehq(;T79=<`~0DIbG+38yqR%KJ8hc(he#prvE3ue*y`Ms*Wo(p$i$n{ zo0V!W{{@{j9XH2x6*LbyUcBzR(?0XwNu0cU$H|7O^o+*R#+Zat0jY;+V#eeJKHY5?K>s%;ZWD$7iQ(2O09M}Rk3;2#^fJe zyW5;O)f+eLbeY}5$crj89I5u)9MF0DtNVY+i+i=Z{zZ6JeVg}vNgm_m>4aO(63Ngo zW?B8!+dU;`+Ir=ux_@wy4I@^`YHHRn7$aS9FozN~5in{tauA(ai*am53z$<3hHR?M zf}nFTlBLDcaFd+~xZ}z+7&2b~Yzl$T1UXT)tE)B zW)q9zM6~8iQqE=rJ*$r#Xi=372>TpR_cXng)N$3|Mg-Oa09*l&CxLhZNFe1p+5@dd zGhl79_GJ;|lWRjPTt0`#H5wnYu#&2*L4QxQu*QSqfE$Zh&6xy>sj@H=>F4OwV#u^Q z`pmRql!%Vopwn|fP_$=9o9Svz^neYO#x&e$p)Dx1BT|PB;4GPhfyU@iE@r@tAP_5H z=0Ap~j;#TU$JRq>eiI0Z>wgDMX?_C-(LI^GKfQG5^ftgsGnz@os8-6^)be1R8O3$5 z{Spbp5TQ^2_E3*NB2>$VB!OZ9q!l2TE+|kdkxFz9RBDrzL`*0~Q2}xe4tPWYiBKyP zYM~&Wga?U�aDnN>M0CDw3jDkXWx13mhn-2plvHVsMO#qS65>393gWm@p6$3K2jh z3`8J=j|4#y4An}6Jh4bC;n7sow!tCMYB^iLaganC5K?a@jB<7aZpyR`LgR5G7Dpmf z()dAwpg?gTUn~F@yuQ$AzL^+d1wBD=@_8J-gf`cqa2Q}jKyBhiBn{(QOlh=&+C?}T zw_%1vC15w%P5HuKDU%$Pd|F9uC=Aj7wgjP?5X3Ynr^?%qNr@9oIB;rD9c_|0sFSnB zp!0YKr987Q>|3?m&vB1(kBfODRJ5Annh zUmPzG!lEEpAV{X?2us#CA>arzN-u)u#dOq==^HblNE(;Em2sa2{tZ)Hx;fkQzwr!0 z2UtP~GTThdjUuA785l}Fo##p50j5|m;H@N)qyB?M{R$@oY1C-oaA0dDavc1}Ve{;F z_9<+@=~S^;^yGsP)Lsf!Bnz{59LS?xg{C8>Gz=Uuee&a|{z(UeMJ%W+|1A;CI)&#nT0v<XA zK~2D*?Cjgil5we1q*D0WxY1!)mI3;xa831C9}oC#Jtpeh24Z-&enXWbO#F zTPw_#958y)$*648Q{6uSXlIDPQPAe*r-l9)L`IK@1S>`;%tmSeI|LnK=)3DL2I}C2 z4Pc|eV1;y;9?3M2?BKqxVrAoGI*aO7d#(+59~GVXel8jJNe=B64re|vwadV>1b8&z z4m_LKIjR2rGynRk{?By5Vm){AO!~P$8RG3`BbJ-&&CuiynSxH_`r@87s+)BvCwbHf|yZ-zeI>j|N7n$-?G9mS*Z9#<20u6Ov{wr zdyr)nV>&K`J@PA^^2Y3#wB~D-QSH~;gh{uI-;8RWR4Xr$v==uYxwrH`ccL;5u}VYR SkCcFL7;06dvO4swg8u@x300#2