Merge pull request #1395 from SiboVG/rightClick

Implement right-click popup menus (+ others...)
This commit is contained in:
Joe Pfeiffer 2022-06-02 19:23:30 -06:00 committed by GitHub
commit 02fd230df8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 993 additions and 388 deletions

View File

@ -33,8 +33,12 @@ RocketActions.CopyAct.Copy = Copy
RocketActions.CopyAct.ttip.Copy = Copy this component (and subcomponents) to the clipboard.
RocketActions.PasteAct.Paste = Paste
RocketActions.PasteAct.ttip.Paste = Paste the component or simulation on the clipboard to the design.
RocketActions.DuplicateAct.Duplicate = Duplicate
RocketActions.DuplicateAct.ttip.Duplicate = Duplicate this component (and subcomponents).
RocketActions.EditAct.Edit = Edit
RocketActions.EditAct.ttip.Edit = Edit the selected component.
RocketActions.ScaleAct.Scale = Scale
RocketActions.ScaleAct.ttip.Scale = Scale parts of the rocket design
RocketActions.NewStageAct.Newstage = New stage
RocketActions.NewStageAct.ttip.Newstage = Add a new stage to the rocket design.
RocketActions.MoveUpAct.Moveup = Move up
@ -187,7 +191,7 @@ edtmotorconfdlg.col.configuration = Configuration
edtmotorconfdlg.but.Removeconfiguration = Remove Configuration
edtmotorconfdlg.but.Renameconfiguration = Rename Configuration
edtmotorconfdlg.but.Newconfiguration = New Configuration
edtmotorconfdlg.but.Copyconfiguration = Copy Configuration
edtmotorconfdlg.but.Duplicateconfiguration = Duplicate Configuration
edtmotorconfdlg.title.Editmotorconf = Edit Flight configurations
edtmotorconfdlg.title.Renameconf = Rename Flight Configuration
edtmotorconfdlg.title.Selectdeploymentconf = Select Deployment Configuration
@ -203,11 +207,11 @@ edtmotorconfdlg.tbl.None = None
edtmotorconfdlg.tbl.Motorheader = Motor
edtmotorconfdlg.tbl.Mountheader = Motor Mount
edtmotorconfdlg.tbl.Ignitionheader = Ignition
edtmotorconfdlg.but.Resetdeployment = Reset to default
edtmotorconfdlg.but.Resetdeployment = Reset deployment
edtmotorconfdlg.but.Selectdeployment = Select deployment
edtmotorconfdlg.tbl.Recoveryheader = Recovery Device
edtmotorconfdlg.tbl.Deploymentheader = Deployment
edtmotorconfdlg.but.Resetseparation = Reset to default
edtmotorconfdlg.but.Resetseparation = Reset separation
edtmotorconfdlg.but.Selectseparation = Select separation
edtmotorconfdlg.tbl.Stageheader = Stage
edtmotorconfdlg.tbl.Separationheader = Separation
@ -491,6 +495,11 @@ simpanel.but.ttip.newsimulation = Add a new simulation
simpanel.but.ttip.editsim = Edit the selected simulation
simpanel.but.ttip.runsimu = Re-run the selected simulations
simpanel.but.ttip.deletesim = Delete the selected simulations
simpanel.pop.edit = Edit
simpanel.pop.plot = Plot / Export
simpanel.pop.run = Run
simpanel.pop.delete = Delete
simpanel.pop.duplicate = Duplicate
simpanel.checkbox.donotask = Do not ask me again
simpanel.lbl.defpref = You can change the default operation in the preferences.
simpanel.dlg.lbl.DeleteSim1 = Delete the selected simulations?
@ -1342,8 +1351,6 @@ main.menu.edit.cut = Cut
main.menu.edit.copy = Copy
main.menu.edit.paste = Paste
main.menu.edit.delete = Delete
main.menu.edit.resize = Scale\u2026
main.menu.edit.resize.desc = Scale parts of the rocket design
main.menu.edit.editpreset= Edit Component Preset File
main.menu.edit.preferences = Preferences
main.menu.edit.preferences.desc = Setup the application preferences

View File

@ -35,6 +35,8 @@ RocketActions.PasteAct.Paste = Paste
RocketActions.PasteAct.ttip.Paste = Paste the component or simulation on the clipboard to the design.
RocketActions.EditAct.Edit = Edit
RocketActions.EditAct.ttip.Edit = Edituj vybranou komponentu.
RocketActions.ScaleAct.Scale = Merítko
RocketActions.ScaleAct.ttip.Scale = Merítko cástí návrhu rakety
RocketActions.NewStageAct.Newstage = Nový stupen
RocketActions.NewStageAct.ttip.Newstage = Pridej nový stupen rakety.
RocketActions.ActBoosterstage = Urychlovací stupen
@ -1000,8 +1002,6 @@ main.menu.edit.cut = Vyjmout
main.menu.edit.copy = Kopírovat
main.menu.edit.paste = Vlo\u017Eit
main.menu.edit.delete = Smazat
main.menu.edit.resize = Merítko...
main.menu.edit.resize.desc = Merítko cástí návrhu rakety
main.menu.edit.preferences = Nastavení
main.menu.edit.preferences.desc = Nastavení aplikace

View File

@ -35,6 +35,8 @@ RocketActions.PasteAct.Paste = Einf
RocketActions.PasteAct.ttip.Paste = Fügt die Komponente oder Simulation aus der Zwischenablage in das Design ein.
RocketActions.EditAct.Edit = Bearbeiten
RocketActions.EditAct.ttip.Edit = Die ausgewählte Komponente bearbeiten.
RocketActions.ScaleAct.Scale = Skalieren
RocketActions.ScaleAct.ttip.Scale = Teile des Raketendesigns skalieren
RocketActions.NewStageAct.Newstage = Neue Stufe
RocketActions.NewStageAct.ttip.Newstage = Fügt eine neue Stufe in das Raketendesign ein.
RocketActions.ActBoosterstage = Booster-Stufe
@ -1057,8 +1059,6 @@ main.menu.edit.cut = Ausschneiden
main.menu.edit.copy = Kopieren
main.menu.edit.paste = Einfügen
main.menu.edit.delete = Löschen
main.menu.edit.resize = Skalieren...
main.menu.edit.resize.desc = Teile des Raketendesigns skalieren
main.menu.edit.preferences = Einstellungen
main.menu.edit.preferences.desc = Einstellungen der Anwenung ändern

View File

@ -802,6 +802,8 @@ RocketActions.DelSimuAct.Delete = Borrar
RocketActions.DelSimuAct.ttip.Delete = Borrar la simulaci\u00f3n seleccionada
RocketActions.EditAct.Edit = Editar componente
RocketActions.EditAct.ttip.Edit = Editar valores del componente seleccionado
RocketActions.ScaleAct.Scale = Dimensionar
RocketActions.ScaleAct.ttip.Scale = Dimensionar las partes del dise\u00f1o del cohete
RocketActions.MoveDownAct.Movedown = Mover hacia abajo
RocketActions.MoveDownAct.ttip.Movedown = Mover este componente hacia abajo
RocketActions.MoveUpAct.Moveup = Mover hacia arriba
@ -1380,13 +1382,13 @@ dlg.but.close = Cerrar
! Common labels used in buttons of dialog windows
dlg.but.ok = OK
edtmotorconfdlg.but.Copyconfiguration = Copiar
edtmotorconfdlg.but.Duplicateconfiguration = Duplicar
edtmotorconfdlg.but.Newconfiguration = Nueva configuraci\u00f3n
! Edit Motor configuration dialog
edtmotorconfdlg.but.Removeconfiguration = Quitar configuraci\u00f3n
edtmotorconfdlg.but.Renameconfiguration = Renombrar configuraci\u00f3n
edtmotorconfdlg.but.Resetdeployment = Reiniciar valor por defecto
edtmotorconfdlg.but.Resetseparation = Reiniciar valor por defecto
edtmotorconfdlg.but.Resetdeployment = Reiniciar despliegue
edtmotorconfdlg.but.Resetseparation = Reiniciar separaci\u00f3n
edtmotorconfdlg.but.Selectdeployment = Seleccionar despliegue
edtmotorconfdlg.but.Selectseparation = Seleccionar separaci\u00f3n
edtmotorconfdlg.col.configuration = Configuraci\u00f3n
@ -1449,8 +1451,6 @@ main.menu.edit.preferences = Preferencias
main.menu.edit.preferences.desc = Configurar las preferencias de la aplicaci\u00f3n
main.menu.edit.redo = Rehacer
main.menu.edit.redo.desc = Rehacer la operaci\u00f3n anterior
main.menu.edit.resize = Dimensionar...
main.menu.edit.resize.desc = Dimensionar las partes del dise\u00f1o del cohete
main.menu.edit.undo = Deshacer
main.menu.edit.undo.desc = Deshacer la operaci\u00f3n anterior
! "main" prefix is used for the main application dialog

View File

@ -793,6 +793,8 @@ RocketActions.DelSimuAct.Delete = Effacer
RocketActions.DelSimuAct.ttip.Delete = Effacer la simulation s\u00E9lectionn\u00E9e.
RocketActions.EditAct.Edit = Modifier
RocketActions.EditAct.ttip.Edit = Modifier la pi\u00E8ce s\u00E9lectionn\u00E9e.
RocketActions.ScaleAct.Scale = Redimensionner
RocketActions.ScaleAct.ttip.Scale = Redimensionner certaines parties de la fus\u00E9e
RocketActions.MoveDownAct.Movedown = Descendre
RocketActions.MoveDownAct.ttip.Movedown = Descendre la pi\u00E8ce.
RocketActions.MoveUpAct.Moveup = Monter
@ -1375,12 +1377,12 @@ dlg.but.close = Fermer
! Common labels used in buttons of dialog windows
dlg.but.ok = Accepter
edtmotorconfdlg.but.Copyconfiguration = Copier
edtmotorconfdlg.but.Duplicateconfiguration = Dupliquer
edtmotorconfdlg.but.Newconfiguration = Nouvelle configuration
edtmotorconfdlg.but.Removeconfiguration = Supprimer la configuration
edtmotorconfdlg.but.Renameconfiguration = Renommer
edtmotorconfdlg.but.Resetdeployment = R\u00E9initialiser \u00E0 la valeur par d\u00E9faut
edtmotorconfdlg.but.Resetseparation = R\u00E9initialiser \u00E0 la valeur par d\u00E9faut
edtmotorconfdlg.but.Resetdeployment = R\u00E9initialiserle d\u00E9ploiement
edtmotorconfdlg.but.Resetseparation = R\u00E9initialiser la s\u00E9paration
edtmotorconfdlg.but.Selectdeployment = Choisir le d\u00E9ploiement
edtmotorconfdlg.but.Selectseparation = Choisir la s\u00E9paration
edtmotorconfdlg.col.configuration = Configuration
@ -1443,8 +1445,6 @@ main.menu.edit.preferences = Pr\u00E9f\u00E9rences
main.menu.edit.preferences.desc = Configure les pr\u00E9f\u00E9rences de l'application
main.menu.edit.redo = Refaire modification
main.menu.edit.redo.desc = Refaire l'op\u00E9ration precedente qui avait \u00E9t\u00E9 d\u00E9faite
main.menu.edit.resize = Redimensionner...
main.menu.edit.resize.desc = Redimensionner certaines parties de la fus\u00E9e
main.menu.edit.undo = Annuler modification
main.menu.edit.undo.desc = Annuler l'op\u00E9ration pr\u00E9c\u00E9dente
! "main" prefix is used for the main application dialog

View File

@ -35,6 +35,8 @@ RocketActions.PasteAct.Paste = Incolla
RocketActions.PasteAct.ttip.Paste = Incolla il componente o la simulazione dagli appunti al disegno.
RocketActions.EditAct.Edit = Modifica
RocketActions.EditAct.ttip.Edit = Modifica il componente selezionato.
RocketActions.ScaleAct.Scale = Scala
RocketActions.ScaleAct.ttip.Scale = Scala parti del razzo
RocketActions.NewStageAct.Newstage = Nuovo stadio
RocketActions.NewStageAct.ttip.Newstage = Aggiungi un nuovo stadio al disegno del razzo.
RocketActions.ActBoosterstage = Stadio Booster
@ -1061,8 +1063,6 @@ main.menu.edit.cut = Taglia
main.menu.edit.copy = Copia
main.menu.edit.paste = Incolla
main.menu.edit.delete = Cancella
main.menu.edit.resize = Scala...
main.menu.edit.resize.desc = Scala parti del razzo
main.menu.edit.preferences = Preferenze
main.menu.edit.preferences.desc = Imposta le preferenze dell'applicazione

View File

@ -31,6 +31,8 @@ RocketActions.PasteAct.Paste = \u8CBC\u308A\u4ED8\u3051
RocketActions.PasteAct.ttip.Paste = \u90E8\u54C1\u3084\u30B7\u30DF\u30E5\u30EC\u30FC\u30B7\u30E7\u30F3\u3092\u8CBC\u308A\u4ED8\u3051
RocketActions.EditAct.Edit = \u7DE8\u96C6
RocketActions.EditAct.ttip.Edit = \u9078\u629E\u3057\u305F\u90E8\u54C1\u306E\u7DE8\u96C6
RocketActions.ScaleAct.Scale = \u62E1\u5927\u7E2E\u5C0F
RocketActions.ScaleAct.ttip.Scale = \u90E8\u54C1\u306E\u5927\u304D\u3055\u3092\u8CB7\u3048\u308B
RocketActions.NewStageAct.Newstage = \u65B0\u3057\u3044\u30B9\u30C6\u30FC\u30B8
RocketActions.NewStageAct.ttip.Newstage = \u30ED\u30B1\u30C3\u30C8\u306B\u65B0\u3057\u3044\u30B9\u30C6\u30FC\u30B8\u3092\u8FFD\u52A0\u3059\u308B
RocketActions.ActBoosterstage = \u30D6\u30FC\u30B9\u30BF\u30FC\u30B9\u30C6\u30FC\u30B8
@ -1092,8 +1094,6 @@ main.menu.edit.cut = \u5207\u308A\u53D6\u308A
main.menu.edit.copy = \u30B3\u30D4\u30FC
main.menu.edit.paste = \u8CBC\u308A\u4ED8\u3051
main.menu.edit.delete = \u524A\u9664
main.menu.edit.resize = \u62E1\u5927\u7E2E\u5C0F...
main.menu.edit.resize.desc = \u90E8\u54C1\u306E\u5927\u304D\u3055\u3092\u8CB7\u3048\u308B
main.menu.edit.editpreset = Component Preset File\u306E\u7DE8\u96C6
main.menu.edit.preferences = \u8A2D\u5B9A
main.menu.edit.preferences.desc = \u30A2\u30D7\u30EA\u306E\u8A2D\u5B9A\u3092\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7

View File

@ -37,6 +37,8 @@ RocketActions.PasteAct.Paste = Plak
RocketActions.PasteAct.ttip.Paste = Plak dit onderdeel of simulatie van het klembord naar het ontwerp.
RocketActions.EditAct.Edit = Bewerk
RocketActions.EditAct.ttip.Edit = Pas geselecteerd onderdeel aan.
RocketActions.ScaleAct.Scale = Herschaal
RocketActions.ScaleAct.ttip.Scale = Herschaal delen van het raketontwerp
RocketActions.NewStageAct.Newstage = Nieuwe trap
RocketActions.NewStageAct.ttip.Newstage = Voeg nieuwe trap toe aan het raketontwerp.
RocketActions.MoveUpAct.Moveup = Beweeg omhoog
@ -179,7 +181,7 @@ edtmotorconfdlg.col.configuration = Configuratie
edtmotorconfdlg.but.Removeconfiguration = Verwijder Configuratie
edtmotorconfdlg.but.Renameconfiguration = Hernoem Configuratie
edtmotorconfdlg.but.Newconfiguration = Nieuwe Configuratie
edtmotorconfdlg.but.Copyconfiguration = Kopieer Configuratie
edtmotorconfdlg.but.Duplicateconfiguration = Dupliceer Configuratie
edtmotorconfdlg.title.Editmotorconf = Pas Vluchtconfiguratie Aan
edtmotorconfdlg.title.Renameconf = Hernoem Vluchtconfiguratie
edtmotorconfdlg.title.Selectdeploymentconf = Selecteer Ontplooiingconfiguratie
@ -195,11 +197,11 @@ edtmotorconfdlg.tbl.None = Geen
edtmotorconfdlg.tbl.Motorheader = Motor
edtmotorconfdlg.tbl.Mountheader = Motorbevestiging
edtmotorconfdlg.tbl.Ignitionheader = Ontsteking
edtmotorconfdlg.but.Resetdeployment = Herstel naar standaard
edtmotorconfdlg.but.Resetdeployment = Herstel ontplooiing
edtmotorconfdlg.but.Selectdeployment = Selecteer ontplooiing
edtmotorconfdlg.tbl.Recoveryheader = Herstelapparaat
edtmotorconfdlg.tbl.Deploymentheader = Ontplooiing
edtmotorconfdlg.but.Resetseparation = Herstel naar standaard
edtmotorconfdlg.but.Resetseparation = Herstel afscheiding
edtmotorconfdlg.but.Selectseparation = Selecteer afscheiding
edtmotorconfdlg.tbl.Stageheader = Trap
edtmotorconfdlg.tbl.Separationheader = Afscheiding
@ -1269,8 +1271,6 @@ main.menu.edit.cut = Knop
main.menu.edit.copy = Kopieer
main.menu.edit.paste = Plak
main.menu.edit.delete = Verwijder
main.menu.edit.resize = Schaal...
main.menu.edit.resize.desc = Schaal delen van het raketontwerp
main.menu.edit.editpreset= Bewerk Component Preset bestand
main.menu.edit.preferences = Voorkeuren
main.menu.edit.preferences.desc = Stel de programma voorkeuren in

View File

@ -35,6 +35,8 @@
RocketActions.PasteAct.ttip.Paste = Wklej wybran\u0105 cz\u0119\u015B\u0107 lub symulacj\u0119 ze schowka do projektu.
RocketActions.EditAct.Edit = Edycja
RocketActions.EditAct.ttip.Edit = Edytuj zaznaczon\u0105 cz\u0119\u015B\u0107.
RocketActions.ScaleAct.Scale = Skaluj
RocketActions.ScaleAct.ttip.Scale = Skaluj cz\u0119\u015Bci modelu rakiety
RocketActions.NewStageAct.Newstage = Nowy stopie\u0144
RocketActions.NewStageAct.ttip.Newstage = Dodaj stopie\u0144 do projektu rakiety.
RocketActions.ActBoosterstage = Stopie\u0144 startowy rakiety
@ -1002,8 +1004,6 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
main.menu.edit.copy = Kopiuj
main.menu.edit.paste = Wklej
main.menu.edit.delete = Usu\u0144
main.menu.edit.resize = Skaluj...
main.menu.edit.resize.desc = Skaluj cz\u0119\u015Bci modelu rakiety...
main.menu.edit.preferences = Ustawienia
main.menu.edit.preferences.desc = Edytuj ustawienia programu

View File

@ -778,6 +778,8 @@ RocketActions.DelSimuAct.Delete = Excluir
RocketActions.DelSimuAct.ttip.Delete = Excluir a simula\u00e7\u00e3o selecionada.
RocketActions.EditAct.Edit = Editar
RocketActions.EditAct.ttip.Edit = Edite o componente selecionado.
RocketActions.ScaleAct.Scale = Escala...
RocketActions.ScaleAct.ttip.Scale = Escalar partes do projeto do foguete
RocketActions.MoveDownAct.Movedown = Mover para baixo
RocketActions.MoveDownAct.ttip.Movedown = Mover este componente para baixo.
RocketActions.MoveUpAct.Moveup = Mover para cima
@ -1338,12 +1340,12 @@ dlg.but.close = Fechar
# Common labels used in buttons of dialog windows
dlg.but.ok = Ok
edtmotorconfdlg.but.Copyconfiguration = Copiar
edtmotorconfdlg.but.Duplicateconfiguration = Duplikat
edtmotorconfdlg.but.Newconfiguration = Nova configura\u00e7\u00e3o
edtmotorconfdlg.but.Removeconfiguration = Remover configura\u00e7\u00e3o
edtmotorconfdlg.but.Renameconfiguration = Renomear
edtmotorconfdlg.but.Resetdeployment = Retornar aos padr\u00f5es
edtmotorconfdlg.but.Resetseparation = Retornar aos padr\u00f5es
edtmotorconfdlg.but.Resetdeployment = Retornar o lan\u00e7amento
edtmotorconfdlg.but.Resetseparation = Retornar a separa\u00e7\u00e3o
edtmotorconfdlg.but.Selectdeployment = Selecionar o lan\u00e7amento
edtmotorconfdlg.but.Selectseparation = Selecionar a separa\u00e7\u00e3o
edtmotorconfdlg.lbl.Configname = Nome de configura\u00e7\u00e3o:
@ -1405,8 +1407,6 @@ main.menu.edit.preferences = Prefer\u00eancias
main.menu.edit.preferences.desc = Configurar as prefer\u00eancias do aplicativo
main.menu.edit.redo = Refazer
main.menu.edit.redo.desc = Refazer a opera\u00e7\u00e3o previamente desfeita
main.menu.edit.resize = Escala...
main.menu.edit.resize.desc = Escalar partes do projeto do foguete
main.menu.edit.undo = Desfazer
main.menu.edit.undo.desc = Desfazer a opera\u00e7\u00e3o anterior
# "main" prefix is used for the main application dialog

View File

@ -35,6 +35,8 @@ RocketActions.PasteAct.Paste = \u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c
RocketActions.PasteAct.ttip.Paste = \u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438\u043b\u0438 \u0440\u0430\u0441\u0447\u0435\u0442 \u0438\u0437 \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0435\u043d\u0430.
RocketActions.EditAct.Edit = \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
RocketActions.EditAct.ttip.Edit = \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.
RocketActions.ScaleAct.Scale = \u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c
RocketActions.ScaleAct.ttip.Scale = \u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u0441\u0445\u0435\u043c\u044b
RocketActions.NewStageAct.Newstage = \u041d\u043e\u0432\u0430\u044f \u0441\u0442\u0443\u043f\u0435\u043d\u044c
RocketActions.NewStageAct.ttip.Newstage = \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0443\u043f\u0435\u043d\u044c \u0432 \u0441\u0445\u0435\u043c\u0443.
RocketActions.ActBoosterstage = \u0420\u0430\u0437\u0433\u043e\u043d\u043d\u0430\u044f \u0441\u0442\u0443\u043f\u0435\u043d\u044c
@ -1164,8 +1166,6 @@ main.menu.edit.cut = \u0412\u044b\u0440\u0435\u0437\u0430\u0442\u044c
main.menu.edit.copy = \u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c
main.menu.edit.paste = \u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c
main.menu.edit.delete = \u0423\u0434\u0430\u043b\u0438\u0442\u044c
main.menu.edit.resize = \u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c...
main.menu.edit.resize.desc = \u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u0441\u0445\u0435\u043c\u044b
main.menu.edit.editprese = \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430
main.menu.edit.preferences = \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
main.menu.edit.preferences.desc = \u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f

View File

@ -37,6 +37,8 @@ RocketActions.PasteAct.Paste = Paste
RocketActions.PasteAct.ttip.Paste = Paste the component or simulation on the clipboard to the design.
RocketActions.EditAct.Edit = Edit
RocketActions.EditAct.ttip.Edit = Edit the selected component.
RocketActions.ScaleAct.Scale = Scale
RocketActions.ScaleAct.ttip.Scale = Scale parts of the rocket design
RocketActions.NewStageAct.Newstage = New stage
RocketActions.NewStageAct.ttip.Newstage = Add a new stage to the rocket design.
RocketActions.ActBoosterstage = Booster stage
@ -181,7 +183,7 @@ edtmotorconfdlg.col.configuration = Configuration
edtmotorconfdlg.but.Removeconfiguration = Remove Configuration
edtmotorconfdlg.but.Renameconfiguration = Rename Configuration
edtmotorconfdlg.but.Newconfiguration = New Configuration
edtmotorconfdlg.but.Copyconfiguration = Copy Configuration
edtmotorconfdlg.but.Duplicateconfiguration = Duplicate Configuration
edtmotorconfdlg.title.Editmotorconf = Edit Flight configurations
edtmotorconfdlg.title.Renameconf = Rename Flight Configuration
edtmotorconfdlg.title.Selectdeploymentconf = Select Deployment Configuration
@ -197,11 +199,11 @@ edtmotorconfdlg.tbl.None = None
edtmotorconfdlg.tbl.Motorheader = Motor
edtmotorconfdlg.tbl.Mountheader = Motor Mount
edtmotorconfdlg.tbl.Ignitionheader = Ignition
edtmotorconfdlg.but.Resetdeployment = Reset to default
edtmotorconfdlg.but.Resetdeployment = Reset deployment
edtmotorconfdlg.but.Selectdeployment = Select deployment
edtmotorconfdlg.tbl.Recoveryheader = Recovery Device
edtmotorconfdlg.tbl.Deploymentheader = Deployment
edtmotorconfdlg.but.Resetseparation = Reset to default
edtmotorconfdlg.but.Resetseparation = Reset separation
edtmotorconfdlg.but.Selectseparation = Select separation
edtmotorconfdlg.tbl.Stageheader = Stage
edtmotorconfdlg.tbl.Separationheader = Separation
@ -1170,8 +1172,6 @@ main.menu.edit.cut = Cut
main.menu.edit.copy = Copy
main.menu.edit.paste = Paste
main.menu.edit.delete = Delete
main.menu.edit.resize = Scale...
main.menu.edit.resize.desc = Scale parts of the rocket design
main.menu.edit.editpreset= Edit Component Preset File
main.menu.edit.preferences = Preferences
main.menu.edit.preferences.desc = Setup the application preferences

View File

@ -867,6 +867,8 @@ RocketActions.DelSimuAct.Delete = \u5220\u9664
RocketActions.DelSimuAct.ttip.Delete = \u5220\u9664\u9009\u5B9A\u4EFF\u771F
RocketActions.EditAct.Edit = \u7F16\u8F91
RocketActions.EditAct.ttip.Edit = \u7F16\u8F91\u9009\u4E2D\u7EC4\u4EF6
RocketActions.ScaleAct.Scale = \u7F29\u653E
RocketActions.ScaleAct.ttip.Scale = \u7F29\u653E\u706B\u7BAD\u8BBE\u8BA1\u7A3F
RocketActions.MoveDownAct.Movedown = \u5411\u4E0B\u79FB\u52A8
RocketActions.MoveDownAct.ttip.Movedown = \u5411\u4E0B\u79FB\u52A8\u8BE5\u90E8\u4EF6
RocketActions.MoveUpAct.Moveup = \u5411\u4E0A\u79FB\u52A8
@ -1528,8 +1530,6 @@ main.menu.edit.preferences = \u9996\u9009\u9879
main.menu.edit.preferences.desc = \u4FEE\u6539\u5E94\u7528\u7A0B\u5E8F\u9996\u9009\u9879
main.menu.edit.redo = \u91CD\u505A
main.menu.edit.redo.desc = \u91CD\u505A\u64CD\u4F5C
main.menu.edit.resize = \u7F29\u653E...
main.menu.edit.resize.desc = \u7F29\u653E\u706B\u7BAD\u8BBE\u8BA1\u7A3F
main.menu.edit.undo = \u64A4\u9500
main.menu.edit.undo.desc = \u64A4\u9500\u64CD\u4F5C
! "main" prefix is used for the main application dialog

Binary file not shown.

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -345,17 +345,31 @@ public class ScaleDialog extends JDialog {
selectionOption.setToolTipText(tip);
panel.add(selectionOption, "growx, wrap para*2");
// Select the 'scale component / scale selection and all subcomponents' if a component is selected
if (selection != null && selection.size() > 0) {
boolean entireRocket = false; // Flag to scale entire rocket
for (RocketComponent component : selection) {
if (component instanceof Rocket || (component instanceof AxialStage && !(component instanceof ParallelStage))) {
entireRocket = true;
break;
}
}
if (!entireRocket) {
selectionOption.setSelectedIndex(1);
}
}
// Change the offset checkbox to false when 'Scale selection' is selection and only one component is selected,
// since this is a common action.
selectionOption.addItemListener(new ItemListener() {
ItemListener listener = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (SCALE_SELECTION.equals(selectionOption.getSelectedItem()) && (selection != null) &&
(selection.size() == 1) && (scaleOffsets != null)) {
scaleOffsets.setSelected(false);
if (scaleOffsets == null) return;
scaleOffsets.setSelected(!SCALE_SELECTION.equals(selectionOption.getSelectedItem()));
}
}
});
};
selectionOption.addItemListener(listener);
// Scale multiplier
@ -424,7 +438,7 @@ public class ScaleDialog extends JDialog {
// Scale offsets
scaleOffsets = new JCheckBox(trans.get("checkbox.scaleOffsets"));
scaleOffsets.setToolTipText(trans.get("checkbox.scaleOffsets.ttip"));
scaleOffsets.setSelected(true);
listener.itemStateChanged(null); // Triggers the selection state of scaleOffsets
panel.add(scaleOffsets, "span, wrap para*3");
@ -571,7 +585,7 @@ public class ScaleDialog extends JDialog {
*/
private void scaleChildren(RocketComponent component, List<RocketComponent> scaledComponents, double mul, boolean scaleMass) {
for (RocketComponent child : component.getChildren()) {
if (!scaledComponents.contains(component)) {
if (!scaledComponents.contains(child)) {
scale(child, mul, scaleMass, scaleOffsets.isSelected());
scaledComponents.add(child);
scaleChildren(child, scaledComponents, mul, scaleMass);

View File

@ -60,7 +60,7 @@ import com.google.inject.Module;
@SuppressWarnings("serial")
public class PhotoFrame extends JFrame {
private static final Logger log = LoggerFactory.getLogger(PhotoFrame.class);
private final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
private final Translator trans = Application.getTranslator();
private final PhotoPanel photoPanel;

View File

@ -51,7 +51,6 @@ import net.sf.openrocket.gui.dialogs.DecalNotFoundDialog;
import net.sf.openrocket.gui.dialogs.DetailDialog;
import net.sf.openrocket.gui.dialogs.LicenseDialog;
import net.sf.openrocket.gui.dialogs.PrintDialog;
import net.sf.openrocket.gui.dialogs.ScaleDialog;
import net.sf.openrocket.gui.dialogs.SwingWorkerDialog;
import net.sf.openrocket.gui.dialogs.WarningDialog;
import net.sf.openrocket.gui.dialogs.optimization.GeneralOptimizationDialog;
@ -87,6 +86,8 @@ import net.sf.openrocket.utils.ComponentPresetEditor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
public class BasicFrame extends JFrame {
private static final long serialVersionUID = 948877655223365313L;
@ -98,7 +99,10 @@ public class BasicFrame extends JFrame {
private static final Translator trans = Application.getTranslator();
private static final Preferences prefs = Application.getPreferences();
private static final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private static final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
private static final int SHIFT_SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() |
SHIFT_DOWN_MASK;
public static final int COMPONENT_TAB = 0;
public static final int CONFIGURATION_TAB = 1;
@ -124,6 +128,7 @@ public class BasicFrame extends JFrame {
private JTabbedPane tabbedPane;
private RocketPanel rocketpanel;
private ComponentTree tree = null;
private final JPopupMenu popupMenu;
private final DocumentSelectionModel selectionModel;
private final TreeSelectionModel componentSelectionModel;
@ -161,7 +166,18 @@ public class BasicFrame extends JFrame {
selectionModel.attachComponentTreeSelectionModel(componentSelectionModel);
selectionModel.attachSimulationListSelectionModel(simulationSelectionModel);
actions = new RocketActions(document, selectionModel, this);
actions = new RocketActions(document, selectionModel, this, simulationPanel);
// Populate the popup menu
popupMenu = new JPopupMenu();
popupMenu.add(actions.getEditAction());
popupMenu.add(actions.getCutAction());
popupMenu.add(actions.getCopyAction());
popupMenu.add(actions.getPasteAction());
popupMenu.add(actions.getDuplicateAction());
popupMenu.add(actions.getDeleteAction());
popupMenu.addSeparator();
popupMenu.add(actions.getScaleAction());
log.debug("Constructing the BasicFrame UI");
@ -278,16 +294,25 @@ public class BasicFrame extends JFrame {
// Double-click opens config dialog
MouseListener ml = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
public void mouseClicked(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY());
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
if (selRow != -1) {
if ((e.getClickCount() == 2) && !ComponentConfigDialog.isDialogVisible()) {
if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() == 2) && !ComponentConfigDialog.isDialogVisible()) {
// Double-click
RocketComponent c = (RocketComponent) selPath.getLastPathComponent();
ComponentConfigDialog.showDialog(BasicFrame.this,
BasicFrame.this.document, c);
} else if ((e.getButton() == MouseEvent.BUTTON3) && (e.getClickCount() == 1)) {
if (!tree.isPathSelected(selPath)) {
// Select new path
tree.setSelectionPath(selPath);
}
doComponentTreePopup(e);
}
} else {
tree.clearSelection();
}
}
};
@ -334,6 +359,13 @@ public class BasicFrame extends JFrame {
panel.add(button, "sizegroup buttons, aligny 0%");
button = new SelectColorButton(actions.getEditAction());
button.setIcon(null);
button.setMnemonic(0);
panel.add(button, "sizegroup buttons, gaptop 20%");
button = new SelectColorButton(actions.getDuplicateAction());
button.setIcon(null);
button.setMnemonic(0);
panel.add(button, "sizegroup buttons");
button = new SelectColorButton(actions.getDeleteAction());
@ -689,6 +721,9 @@ public class BasicFrame extends JFrame {
menu.addSeparator();
item = new JMenuItem(actions.getEditAction());
menu.add(item);
item = new JMenuItem(actions.getCutAction());
menu.add(item);
@ -698,24 +733,15 @@ public class BasicFrame extends JFrame {
item = new JMenuItem(actions.getPasteAction());
menu.add(item);
item = new JMenuItem(actions.getDuplicateAction());
menu.add(item);
item = new JMenuItem(actions.getDeleteAction());
menu.add(item);
menu.addSeparator();
item = new JMenuItem(trans.get("main.menu.edit.resize"));
item.setIcon(Icons.EDIT_SCALE);
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.edit.resize.desc"));
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
log.info(Markers.USER_MARKER, "Scale... selected");
ScaleDialog dialog = new ScaleDialog(document, getSelectedComponents(), BasicFrame.this);
dialog.setVisible(true);
dialog.dispose();
}
});
item = new JMenuItem(actions.getScaleAction());
menu.add(item);
@ -856,7 +882,7 @@ public class BasicFrame extends JFrame {
//// Debug log
item = new JMenuItem(trans.get("main.menu.help.debugLog"), KeyEvent.VK_D);
item.setIcon(Icons.HELP_DEBUG_LOG);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, SHORTCUT_KEY));
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, SHIFT_SHORTCUT_KEY));
item.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.help.debugLog.desc"));
item.addActionListener(new ActionListener() {
@Override
@ -898,6 +924,10 @@ public class BasicFrame extends JFrame {
this.setJMenuBar(menubar);
}
public void doComponentTreePopup(MouseEvent e) {
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
private JMenu makeDebugMenu() {
JMenu menu;
JMenuItem item;

View File

@ -5,6 +5,7 @@ import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
@ -21,8 +22,10 @@ import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
import net.sf.openrocket.gui.dialogs.ScaleDialog;
import net.sf.openrocket.gui.util.Icons;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.Markers;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
import net.sf.openrocket.rocketcomponent.ParallelStage;
@ -32,7 +35,8 @@ import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
@ -44,16 +48,21 @@ import net.sf.openrocket.util.Pair;
public class RocketActions {
public static final KeyStroke CUT_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_X,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke COPY_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_C,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke PASTE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_V,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke DUPLICATE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_D,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
public static final KeyStroke EDIT_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_E,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
private final OpenRocketDocument document;
private final Rocket rocket;
private final BasicFrame parentFrame;
private final DocumentSelectionModel selectionModel;
private final SimulationPanel simulationPanel;
private final RocketAction deleteComponentAction;
@ -62,19 +71,23 @@ public class RocketActions {
private final RocketAction cutAction;
private final RocketAction copyAction;
private final RocketAction pasteAction;
private final RocketAction duplicateAction;
private final RocketAction editAction;
private final RocketAction scaleAction;
private final RocketAction newStageAction;
private final RocketAction moveUpAction;
private final RocketAction moveDownAction;
private static final Translator trans = Application.getTranslator();
private static final Logger log = LoggerFactory.getLogger(RocketActions.class);
public RocketActions(OpenRocketDocument document, DocumentSelectionModel selectionModel,
BasicFrame parentFrame) {
BasicFrame parentFrame, SimulationPanel simulationPanel) {
this.document = document;
this.rocket = document.getRocket();
this.selectionModel = selectionModel;
this.parentFrame = parentFrame;
this.simulationPanel = simulationPanel;
// Add action also to updateActions()
this.deleteAction = new DeleteAction();
@ -83,7 +96,9 @@ public class RocketActions {
this.cutAction = new CutAction();
this.copyAction = new CopyAction();
this.pasteAction = new PasteAction();
this.duplicateAction = new DuplicateAction();
this.editAction = new EditAction();
this.scaleAction = new ScaleAction();
this.newStageAction = new NewStageAction();
this.moveUpAction = new MoveUpAction();
this.moveDownAction = new MoveDownAction();
@ -115,7 +130,9 @@ public class RocketActions {
cutAction.clipboardChanged();
copyAction.clipboardChanged();
pasteAction.clipboardChanged();
duplicateAction.clipboardChanged();
editAction.clipboardChanged();
scaleAction.clipboardChanged();
newStageAction.clipboardChanged();
moveUpAction.clipboardChanged();
moveDownAction.clipboardChanged();
@ -148,10 +165,18 @@ public class RocketActions {
return pasteAction;
}
public Action getDuplicateAction() {
return duplicateAction;
}
public Action getEditAction() {
return editAction;
}
public Action getScaleAction() {
return scaleAction;
}
public Action getNewStageAction() {
return newStageAction;
}
@ -243,20 +268,10 @@ public class RocketActions {
for (int i = 0; i < components.size(); i++) {
if (components.contains(components.get(i).getParent())) {
RocketComponent oldChild = components.get(i);
RocketComponent oldParent = oldChild.getParent();
RocketComponent originalParent = components.get(i).getParent();
int originalParentIdx = components.indexOf(originalParent);
int index = components.indexOf(oldParent);
int childPos = oldParent.getChildPosition(oldChild);
RocketComponent newChild = result.get(i);
RocketComponent newParent = result.get(index);
// Add the newly copied child to the parent
newParent.addChild(newChild, childPos);
// Remove the old child from the parent
newParent.removeChild(oldChild);
result.get(originalParentIdx).addChild(result.get(i));
}
}
@ -646,7 +661,7 @@ public class RocketActions {
this.putValue(MNEMONIC_KEY, KeyEvent.VK_C);
this.putValue(ACCELERATOR_KEY, COPY_KEY_STROKE);
//// Copy this component (and subcomponents) to the clipboard.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CopyAct.Copy"));
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CopyAct.ttip.Copy"));
this.putValue(SMALL_ICON, Icons.EDIT_COPY);
clipboardChanged();
}
@ -667,12 +682,12 @@ public class RocketActions {
OpenRocketClipboard.setClipboard(copiedComponents);
parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
} else if (sims.length > 0) {
} else if (sims != null && sims.length > 0) {
Simulation[] simsCopy = new Simulation[sims.length];
for (int i=0; i < sims.length; i++) {
simsCopy[i] = sims[i].copy();
}
OpenRocketClipboard.setClipboard(simsCopy);
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
}
@ -767,7 +782,96 @@ public class RocketActions {
}
/**
* Action that duplicates the selected component.
*/
private class DuplicateAction extends RocketAction {
private static final long serialVersionUID = 1L;
public DuplicateAction() {
//// Copy
this.putValue(NAME, trans.get("RocketActions.DuplicateAct.Duplicate"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
this.putValue(ACCELERATOR_KEY, DUPLICATE_KEY_STROKE);
//// Copy this component (and subcomponents) to the clipboard.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DuplicateAct.ttip.Duplicate"));
this.putValue(SMALL_ICON, Icons.EDIT_DUPLICATE);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
List<RocketComponent> components = selectionModel.getSelectedComponents();
if (components != null) {
components.sort(Comparator.comparing(c -> c.getParent() != null ? c.getParent().getChildPosition(c) : 0));
components = new ArrayList<>(components);
fillInMissingSelections(components);
}
Simulation[] sims = selectionModel.getSelectedSimulations();
if (isCopyable(components)) {
ComponentConfigDialog.disposeDialog();
List<RocketComponent> copiedComponents = copyComponentsMaintainParent(components);
OpenRocketClipboard.setClipboard(copiedComponents);
copiedComponents = new LinkedList<>(OpenRocketClipboard.getClipboardComponents());
List<RocketComponent> duplicateComponents = new LinkedList<>();
for (RocketComponent component : copiedComponents) {
duplicateComponents.add(component.copy());
}
List<Pair<RocketComponent, Integer>> positions = new LinkedList<>();
for (RocketComponent component : duplicateComponents) {
positions.add(getPastePosition(component));
}
if (duplicateComponents.size() == 1) {
document.addUndoPosition("Duplicate " + duplicateComponents.get(0).getComponentName());
} else {
document.addUndoPosition("Duplicate components");
}
for (int i = 0; i < duplicateComponents.size(); i++) {
positions.get(i).getU().addChild(duplicateComponents.get(i), positions.get(i).getV());
}
selectionModel.setSelectedComponents(duplicateComponents);
parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
} else if (sims != null && sims.length > 0) {
ArrayList<Simulation> copySims = new ArrayList<Simulation>();
// TODO: the undoing doesn't do anything...
if (sims.length == 1) {
document.addUndoPosition("Duplicate " + sims[0].getName());
} else {
document.addUndoPosition("Duplicate simulations");
}
for (Simulation s: sims) {
Simulation copy = s.duplicateSimulation(rocket);
String name = copy.getName();
if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
copy.setName(document.getNextSimulationName());
}
document.addSimulation(copy);
copySims.add(copy);
}
selectionModel.setSelectedSimulations(copySims.toArray(new Simulation[0]));
parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
}
}
@Override
public void clipboardChanged() {
this.setEnabled(isCopyable(selectionModel.getSelectedComponent()) ||
isSimulationSelected());
}
}
@ -780,17 +884,20 @@ public class RocketActions {
public EditAction() {
//// Edit
this.putValue(NAME, trans.get("RocketActions.EditAct.Edit"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_E);
this.putValue(ACCELERATOR_KEY, EDIT_KEY_STROKE);
//// Edit the selected component.
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.EditAct.ttip.Edit"));
this.putValue(SMALL_ICON, Icons.EDIT_EDIT);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
List<RocketComponent> components = selectionModel.getSelectedComponents();
if (!checkAllClassesEqual(components))
return;
Simulation[] sims = selectionModel.getSelectedSimulations();
if ((components != null) && (components.size() > 0) && checkAllClassesEqual(components)) {
// Do nothing if the config dialog is already visible
if (ComponentConfigDialog.isDialogVisible())
return;
@ -800,13 +907,16 @@ public class RocketActions {
listeners = components.subList(1, components.size());
}
ComponentConfigDialog.showDialog(parentFrame, document, components.get(0), listeners);
} else if (sims != null && sims.length > 0 && (simulationPanel != null)) {
simulationPanel.editSimulation();
}
}
@Override
public void clipboardChanged() {
List<RocketComponent> components = selectionModel.getSelectedComponents();
this.setEnabled(checkAllClassesEqual(components));
this.setEnabled(checkAllClassesEqual(components) || isSimulationSelected());
}
/**
@ -828,7 +938,33 @@ public class RocketActions {
}
}
/**
* Action to scale the currently selected component.
*/
private class ScaleAction extends RocketAction {
private static final long serialVersionUID = 1L;
public ScaleAction() {
//// Scale
this.putValue(NAME, trans.get("RocketActions.ScaleAct.Scale"));
this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.ScaleAct.ttip.Scale"));
this.putValue(SMALL_ICON, Icons.EDIT_SCALE);
clipboardChanged();
}
@Override
public void actionPerformed(ActionEvent e) {
log.info(Markers.USER_MARKER, "Scale... selected");
ScaleDialog dialog = new ScaleDialog(document, selectionModel.getSelectedComponents(), null);
dialog.setVisible(true);
dialog.dispose();
}
@Override
public void clipboardChanged() {
this.setEnabled(true);
}
}

View File

@ -6,8 +6,6 @@ import java.awt.Component;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorEvent;
import java.awt.datatransfer.FlavorListener;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
@ -21,12 +19,10 @@ 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;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
@ -38,7 +34,6 @@ import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.text.DefaultEditorKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -142,17 +137,7 @@ public class SimulationPanel extends JPanel {
editButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int[] selection = simulationTable.getSelectedRows();
if (selection.length == 0) {
return;
}
Simulation[] sims = new Simulation[selection.length];
for (int i = 0; i < selection.length; i++) {
selection[i] = simulationTable.convertRowIndexToModel(selection[i]);
sims[i] = document.getSimulation(selection[i]);
}
openDialog(false, sims);
editSimulation();
}
});
this.add(editButton, "gapright para");
@ -164,21 +149,7 @@ public class SimulationPanel extends JPanel {
runButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int[] selection = simulationTable.getSelectedRows();
if (selection.length == 0) {
return;
}
Simulation[] sims = new Simulation[selection.length];
for (int i = 0; i < selection.length; i++) {
selection[i] = simulationTable.convertRowIndexToModel(selection[i]);
sims[i] = document.getSimulation(selection[i]);
}
long t = System.currentTimeMillis();
new SimulationRunDialog(SwingUtilities.getWindowAncestor(
SimulationPanel.this), document, sims).setVisible(true);
log.info("Running simulations took " + (System.currentTimeMillis() - t) + " ms");
fireMaintainSelection();
runSimulation();
}
});
this.add(runButton, "gapright para");
@ -190,50 +161,7 @@ public class SimulationPanel extends JPanel {
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int[] selection = simulationTable.getSelectedRows();
if (selection.length == 0) {
return;
}
// Verify deletion
boolean verify = Application.getPreferences().getBoolean(Preferences.CONFIRM_DELETE_SIMULATION, true);
if (verify) {
JPanel panel = new JPanel(new MigLayout());
//// Do not ask me again
JCheckBox dontAsk = new JCheckBox(trans.get("simpanel.checkbox.donotask"));
panel.add(dontAsk, "wrap");
//// You can change the default operation in the preferences.
panel.add(new StyledLabel(trans.get("simpanel.lbl.defpref"), -2));
int ret = JOptionPane.showConfirmDialog(SimulationPanel.this,
new Object[] {
//// Delete the selected simulations?
trans.get("simpanel.dlg.lbl.DeleteSim1"),
//// <html><i>This operation cannot be undone.</i>
trans.get("simpanel.dlg.lbl.DeleteSim2"),
"",
panel },
//// Delete simulations
trans.get("simpanel.dlg.lbl.DeleteSim3"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
if (ret != JOptionPane.OK_OPTION)
return;
if (dontAsk.isSelected()) {
Application.getPreferences().putBoolean(Preferences.CONFIRM_DELETE_SIMULATION, false);
}
}
// Delete simulations
for (int i = 0; i < selection.length; i++) {
selection[i] = simulationTable.convertRowIndexToModel(selection[i]);
}
Arrays.sort(selection);
for (int i = selection.length - 1; i >= 0; i--) {
document.removeSimulation(selection[i]);
}
simulationTableModel.fireTableDataChanged();
deleteSimulation();
}
});
this.add(deleteButton, "gapright para");
@ -244,26 +172,7 @@ public class SimulationPanel extends JPanel {
plotButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int selected = simulationTable.getSelectedRow();
if (selected < 0) {
return;
}
selected = simulationTable.convertRowIndexToModel(selected);
simulationTable.clearSelection();
simulationTable.addRowSelectionInterval(selected, selected);
Simulation sim = document.getSimulations().get(selected);
if (!sim.hasSimulationData()) {
new SimulationRunDialog(SwingUtilities.getWindowAncestor(
SimulationPanel.this), document, sim).setVisible(true);
}
fireMaintainSelection();
openDialog(true, sim);
plotSimulation();
}
});
this.add(plotButton, "wrap para");
@ -542,30 +451,45 @@ public class SimulationPanel extends JPanel {
simulationTableModel.setColumnWidths(simulationTable.getColumnModel());
pm = new JPopupMenu();
pm.add(new CopyAction(simulationTable));
pm.add(new EditSimulationAction());
pm.add(new DuplicateSimulationAction());
pm.add(new DeleteSimulationAction());
pm.addSeparator();
pm.add(new RunSimulationAction());
pm.add(new PlotSimulationAction());
// Mouse listener to act on double-clicks
simulationTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
int selectedRow = simulationTable.getSelectedRow();
if (selectedRow < 0) {
return;
}
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
int selected = simulationTable.convertRowIndexToModel(selectedRow);
int column = simulationTable.columnAtPoint(e.getPoint());
if (column == 0) {
SimulationWarningDialog.showWarningDialog(SimulationPanel.this, document.getSimulations().get(selected));
} else {
simulationTable.clearSelection();
simulationTable.addRowSelectionInterval(selectedRow, selectedRow);
openDialog(document.getSimulations().get(selected));
}
} else if (e.getButton() == MouseEvent.BUTTON3 && e.getClickCount() == 1) {
// Get the row that the right-click action happened on
int r = simulationTable.rowAtPoint(e.getPoint());
// Select new row
if (!simulationTable.isRowSelected(r)) {
if (r >= 0 && r < simulationTable.getRowCount()) {
simulationTable.setRowSelectionInterval(r, r);
} else {
return;
}
}
doPopup(e);
}
}
@ -608,6 +532,159 @@ public class SimulationPanel extends JPanel {
updateButtonStates();
}
private void plotSimulation() {
int selected = simulationTable.getSelectedRow();
if (selected < 0) {
return;
}
selected = simulationTable.convertRowIndexToModel(selected);
simulationTable.clearSelection();
simulationTable.addRowSelectionInterval(selected, selected);
Simulation sim = document.getSimulations().get(selected);
if (!sim.hasSimulationData()) {
new SimulationRunDialog(SwingUtilities.getWindowAncestor(
SimulationPanel.this), document, sim).setVisible(true);
}
fireMaintainSelection();
openDialog(true, sim);
}
private void deleteSimulation() {
int[] selection = simulationTable.getSelectedRows();
if (selection.length == 0) {
return;
}
// Verify deletion
boolean verify = Application.getPreferences().getBoolean(Preferences.CONFIRM_DELETE_SIMULATION, true);
if (verify) {
JPanel panel = new JPanel(new MigLayout());
//// Do not ask me again
JCheckBox dontAsk = new JCheckBox(trans.get("simpanel.checkbox.donotask"));
panel.add(dontAsk, "wrap");
//// You can change the default operation in the preferences.
panel.add(new StyledLabel(trans.get("simpanel.lbl.defpref"), -2));
int ret = JOptionPane.showConfirmDialog(SimulationPanel.this,
new Object[] {
//// Delete the selected simulations?
trans.get("simpanel.dlg.lbl.DeleteSim1"),
//// <html><i>This operation cannot be undone.</i>
trans.get("simpanel.dlg.lbl.DeleteSim2"),
"",
panel },
//// Delete simulations
trans.get("simpanel.dlg.lbl.DeleteSim3"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE);
if (ret != JOptionPane.OK_OPTION)
return;
if (dontAsk.isSelected()) {
Application.getPreferences().putBoolean(Preferences.CONFIRM_DELETE_SIMULATION, false);
}
}
// Delete simulations
for (int i = 0; i < selection.length; i++) {
selection[i] = simulationTable.convertRowIndexToModel(selection[i]);
}
Arrays.sort(selection);
for (int i = selection.length - 1; i >= 0; i--) {
document.removeSimulation(selection[i]);
}
simulationTableModel.fireTableDataChanged();
}
private void runSimulation() {
Simulation[] sims = getSelectedSimulations();
if (sims == null) return;
long t = System.currentTimeMillis();
new SimulationRunDialog(SwingUtilities.getWindowAncestor(
SimulationPanel.this), document, sims).setVisible(true);
log.info("Running simulations took " + (System.currentTimeMillis() - t) + " ms");
fireMaintainSelection();
}
public void editSimulation() {
Simulation[] sims = getSelectedSimulations();
if (sims == null) return;
openDialog(false, sims);
}
private Simulation[] getSelectedSimulations() {
int[] selection = simulationTable.getSelectedRows();
if (selection.length == 0) {
return null;
}
Simulation[] sims = new Simulation[selection.length];
for (int i = 0; i < selection.length; i++) {
selection[i] = simulationTable.convertRowIndexToModel(selection[i]);
sims[i] = document.getSimulation(selection[i]);
}
return sims;
}
private void copySimulationAction() {
int numCols=simulationTable.getColumnCount();
int numRows=simulationTable.getSelectedRowCount();
int[] rowsSelected=simulationTable.getSelectedRows();
if (numRows!=rowsSelected[rowsSelected.length-1]-rowsSelected[0]+1 || numRows!=rowsSelected.length) {
JOptionPane.showMessageDialog(null, "Invalid Copy Selection", "Invalid Copy Selection", JOptionPane.ERROR_MESSAGE);
return;
}
StringBuilder excelStr =new StringBuilder();
for (int k = 1; k < numCols; k++) {
excelStr.append(simulationTable.getColumnName(k));
if (k < numCols-1) {
excelStr.append("\t");
}
}
excelStr.append("\n");
for (int i = 0; i < numRows; i++) {
for (int j = 1; j < numCols; j++) {
excelStr.append(simulationTable.getValueAt(rowsSelected[i], j));
if (j < numCols-1) {
excelStr.append("\t");
}
}
excelStr.append("\n");
}
StringSelection sel = new StringSelection(excelStr.toString());
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(sel, sel);
}
private void duplicateSimulation() {
Simulation[] sims = getSelectedSimulations();
if (sims == null) return;
for (Simulation s: sims) {
Simulation copy = s.duplicateSimulation(document.getRocket());
String name = copy.getName();
if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
copy.setName(document.getNextSimulationName());
}
document.addSimulation(copy);
}
simulationTable.getSelectionModel().setSelectionInterval(simulationTable.getRowCount()-sims.length,simulationTable.getRowCount()-1);
}
protected void doPopup(MouseEvent e) {
pm.show(e.getComponent(), e.getX(), e.getY());
}
@ -701,52 +778,70 @@ public class SimulationPanel extends JPanel {
}
}
class CopyAction extends AbstractAction {
private JTable table;
public CopyAction(JTable table) {
this.table = table;
putValue(NAME, "Copy");
class EditSimulationAction extends AbstractAction {
public EditSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.edit"));
this.putValue(MNEMONIC_KEY, KeyEvent.VK_E);
this.putValue(ACCELERATOR_KEY, RocketActions.EDIT_KEY_STROKE);
this.putValue(SMALL_ICON, Icons.EDIT_EDIT);
}
@Override
public void actionPerformed(ActionEvent e) {
int numCols=table.getColumnCount();
int numRows=table.getSelectedRowCount();
int[] rowsSelected=table.getSelectedRows();
if (numRows!=rowsSelected[rowsSelected.length-1]-rowsSelected[0]+1 || numRows!=rowsSelected.length ) {
JOptionPane.showMessageDialog(null, "Invalid Copy Selection", "Invalid Copy Selection", JOptionPane.ERROR_MESSAGE);
return;
}
StringBuffer excelStr=new StringBuffer();
for (int k=1; k<numCols; k++) {
excelStr.append(table.getColumnName(k));
if (k<numCols-1) {
excelStr.append("\t");
editSimulation();
}
}
excelStr.append("\n");
for (int i=0; i<numRows; i++) {
for (int j=1; j<numCols; j++) {
excelStr.append(table.getValueAt(rowsSelected[i], j));
if (j<numCols-1) {
excelStr.append("\t");
}
}
excelStr.append("\n");
class RunSimulationAction extends AbstractAction {
public RunSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.run"));
putValue(SMALL_ICON, Icons.SIM_RUN);
}
StringSelection sel = new StringSelection(excelStr.toString());
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(sel, sel);
@Override
public void actionPerformed(ActionEvent e) {
runSimulation();
}
}
class DeleteSimulationAction extends AbstractAction {
public DeleteSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.delete"));
putValue(MNEMONIC_KEY, KeyEvent.VK_D);
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
putValue(SMALL_ICON, Icons.EDIT_DELETE);
}
@Override
public void actionPerformed(ActionEvent e) {
deleteSimulation();
}
}
class PlotSimulationAction extends AbstractAction {
public PlotSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.plot"));
putValue(SMALL_ICON, Icons.SIM_PLOT);
}
@Override
public void actionPerformed(ActionEvent e) {
plotSimulation();
}
}
class DuplicateSimulationAction extends AbstractAction {
public DuplicateSimulationAction() {
putValue(NAME, trans.get("simpanel.pop.duplicate"));
putValue(MNEMONIC_KEY, KeyEvent.VK_D);
putValue(ACCELERATOR_KEY, RocketActions.DUPLICATE_KEY_STROKE);
putValue(SMALL_ICON, Icons.EDIT_DUPLICATE);
}
@Override
public void actionPerformed(ActionEvent e) {
duplicateSimulation();
}
}
public static class CellTransferable implements Transferable {

View File

@ -1,15 +1,16 @@
package net.sf.openrocket.gui.main.flightconfigpanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
@ -31,7 +32,6 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketvisitors.ListComponents;
import net.sf.openrocket.rocketvisitors.ListMotorMounts;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.StateChangeListener;
import net.sf.openrocket.gui.widgets.SelectColorButton;
@ -43,13 +43,19 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
private final Rocket rocket;
private final BasicFrame basicFrame;
private final JButton newConfButton, renameConfButton, removeConfButton, copyConfButton;
private final JButton newConfButton, renameConfButton, removeConfButton, duplicateConfButton;
private final JTabbedPane tabs;
private final MotorConfigurationPanel motorConfigurationPanel;
private final RecoveryConfigurationPanel recoveryConfigurationPanel;
private final SeparationConfigurationPanel separationConfigurationPanel;
private final JPopupMenu popupMenuConfig;
private final AbstractAction newConfigAction;
private final AbstractAction renameConfigAction;
private final AbstractAction removeConfigAction;
private final AbstractAction duplicateConfigAction;
private final static int MOTOR_TAB_INDEX = 0;
private final static int RECOVERY_TAB_INDEX = 1;
private final static int SEPARATION_TAB_INDEX = 2;
@ -62,7 +68,16 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
this.rocket = doc.getRocket();
this.rocket.addChangeListener(this);
//JPanel panel = new JPanel(new MigLayout("fill","[grow][][][][][grow]"));
// Populate the popup menu
popupMenuConfig = new JPopupMenu();
newConfigAction = new NewConfigAction();
renameConfigAction = new RenameConfigAction();
removeConfigAction = new RemoveConfigAction();
duplicateConfigAction = new DuplicateConfigAction();
popupMenuConfig.add(newConfigAction);
popupMenuConfig.add(renameConfigAction);
popupMenuConfig.add(removeConfigAction);
popupMenuConfig.add(duplicateConfigAction);
//// Tabs for advanced view.
tabs = new JTabbedPane();
@ -79,45 +94,21 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
separationConfigurationPanel = new SeparationConfigurationPanel(this, rocket);
tabs.add(trans.get("edtmotorconfdlg.lbl.Stagetab"), separationConfigurationPanel);
newConfButton = new SelectColorButton(trans.get("edtmotorconfdlg.but.Newconfiguration"));
newConfButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
newOrCopyConfigAction(false);
}
});
//// New configuration
newConfButton = new SelectColorButton(newConfigAction);
this.add(newConfButton,"skip 1,gapright para");
renameConfButton = new SelectColorButton(trans.get("edtmotorconfdlg.but.Renameconfiguration"));
renameConfButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
renameConfiguration();
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
});
//// Rename configuration
renameConfButton = new SelectColorButton(renameConfigAction);
this.add(renameConfButton,"gapright para");
removeConfButton = new SelectColorButton(trans.get("edtmotorconfdlg.but.Removeconfiguration"));
removeConfButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
removeConfiguration();
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
});
//// Remove configuration
removeConfButton = new SelectColorButton(removeConfigAction);
this.add(removeConfButton,"gapright para");
copyConfButton = new SelectColorButton(trans.get("edtmotorconfdlg.but.Copyconfiguration"));
copyConfButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
newOrCopyConfigAction(true);
}
});
this.add(copyConfButton, "wrap");
//// Duplicate configuration
duplicateConfButton = new SelectColorButton(duplicateConfigAction);
this.add(duplicateConfButton, "wrap");
tabs.addChangeListener(new ChangeListener() {
@Override
@ -143,11 +134,11 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
}
/**
* Action for when the new configuration or copy configuration button is pressed.
* @param copy if True, then copy configuration operation, if False then create a new configuration
* Action for when the new configuration or duplicate configuration button is pressed.
* @param duplicate if True, then duplicate configuration operation, if False then create a new configuration
*/
private void newOrCopyConfigAction(boolean copy) {
addOrCopyConfiguration(copy);
private void newOrDuplicateConfigAction(boolean duplicate) {
addOrDuplicateConfiguration(duplicate);
configurationChanged(ComponentChangeEvent.MOTOR_CHANGE);
stateChanged(null);
switch (tabs.getSelectedIndex()) {
@ -165,15 +156,15 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
}
/**
* either create or copy configuration
* either create or duplicate configuration
* set new configuration as current
* create simulation for new configuration
*/
private void addOrCopyConfiguration(boolean copy) {
private void addOrDuplicateConfiguration(boolean duplicate) {
final Map<FlightConfigurationId, FlightConfiguration> newConfigs = new LinkedHashMap<>();
// create or copy configuration
if (copy) {
// create or duplicate configuration
if (duplicate) {
List<FlightConfigurationId> oldIds = getSelectedConfigurationIds();
if (oldIds == null || oldIds.size() == 0) return;
@ -217,7 +208,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
rocket.setSelectedConfiguration((FlightConfigurationId) newConfigs.keySet().toArray()[0]);
}
private void renameConfiguration() {
private void renameConfigurationAction() {
List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if (fcIds == null) return;
FlightConfigurationId initFcId = fcIds.get(0);
@ -226,9 +217,10 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
for (int i = 1; i < fcIds.size(); i++) {
rocket.getFlightConfiguration(fcIds.get(i)).setName(newName);
}
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
private void removeConfiguration() {
private void removeConfigurationAction() {
List<FlightConfigurationId> fcIds = getSelectedConfigurationIds();
if (fcIds == null || fcIds.size() == 0)
return;
@ -240,6 +232,26 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
}
public void doPopupConfig(MouseEvent e) {
popupMenuConfig.show(e.getComponent(), e.getX(), e.getY());
}
public AbstractAction getNewConfigAction() {
return newConfigAction;
}
public AbstractAction getRenameConfigAction() {
return renameConfigAction;
}
public AbstractAction getRemoveConfigAction() {
return removeConfigAction;
}
public AbstractAction getDuplicateConfigAction() {
return duplicateConfigAction;
}
private void configurationChanged(int cce) {
motorConfigurationPanel.fireTableDataChanged(cce);
recoveryConfigurationPanel.fireTableDataChanged(cce);
@ -248,10 +260,10 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
private void updateButtonState() {
FlightConfigurationId currentId = rocket.getSelectedConfiguration().getFlightConfigurationID();
// Enable the remove/rename/copy buttons only when a configuration is selected.
// Enable the remove/rename/duplicate buttons only when a configuration is selected.
removeConfButton.setEnabled(currentId.isValid());
renameConfButton.setEnabled(currentId.isValid());
copyConfButton.setEnabled(currentId.isValid());
duplicateConfButton.setEnabled(currentId.isValid());
// Count the number of motor mounts
int motorMountCount = rocket.accept(new ListMotorMounts()).size();
@ -310,4 +322,48 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
recoveryConfigurationPanel.synchronizeConfigurationSelection();
separationConfigurationPanel.synchronizeConfigurationSelection();
}
private class NewConfigAction extends AbstractAction {
public NewConfigAction() {
putValue(NAME, trans.get("edtmotorconfdlg.but.Newconfiguration"));
}
@Override
public void actionPerformed(ActionEvent e) {
newOrDuplicateConfigAction(false);
}
}
private class RenameConfigAction extends AbstractAction {
public RenameConfigAction() {
putValue(NAME, trans.get("edtmotorconfdlg.but.Renameconfiguration"));
}
@Override
public void actionPerformed(ActionEvent e) {
renameConfigurationAction();
}
}
private class RemoveConfigAction extends AbstractAction {
public RemoveConfigAction() {
putValue(NAME, trans.get("edtmotorconfdlg.but.Removeconfiguration"));
}
@Override
public void actionPerformed(ActionEvent e) {
removeConfigurationAction();
}
}
private class DuplicateConfigAction extends AbstractAction {
public DuplicateConfigAction() {
putValue(NAME, trans.get("edtmotorconfdlg.but.Duplicateconfiguration"));
}
@Override
public void actionPerformed(ActionEvent e) {
newOrDuplicateConfigAction(true);
}
}
}

View File

@ -3,7 +3,6 @@ package net.sf.openrocket.gui.main.flightconfigpanel;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
@ -19,6 +18,7 @@ import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
@ -62,6 +62,9 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
private final MotorChooserDialog motorChooserDialog;
protected FlightConfigurableTableModel<MotorMount> configurationTableModel;
private final JPopupMenu popupMenuFull; // popup menu containing all the options
MotorConfigurationPanel(final FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
super(flightConfigurationPanel, rocket);
@ -82,6 +85,27 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
cards = new JPanel(new CardLayout());
this.add(cards, "pushy");
// Get all the actions
AbstractAction selectMotorAction = new SelectMotorAction();
AbstractAction removeMotorAction = new RemoveMotorAction();
AbstractAction selectIgnitionAction = new SelectIgnitionAction();
AbstractAction resetIgnitionAction = new ResetIgnitionAction();
AbstractAction renameConfigAction = flightConfigurationPanel.getRenameConfigAction();
AbstractAction removeConfigAction = flightConfigurationPanel.getRemoveConfigAction();
AbstractAction duplicateConfigAction = flightConfigurationPanel.getDuplicateConfigAction();
// Populate the popup menu
popupMenuFull = new JPopupMenu();
popupMenuFull.add(selectMotorAction);
popupMenuFull.add(removeMotorAction);
popupMenuFull.addSeparator();
popupMenuFull.add(selectIgnitionAction);
popupMenuFull.add(resetIgnitionAction);
popupMenuFull.addSeparator();
popupMenuFull.add(renameConfigAction);
popupMenuFull.add(removeConfigAction);
popupMenuFull.add(duplicateConfigAction);
JLabel helpText = new JLabel(trans.get("MotorConfigurationPanel.lbl.nomotors"));
cards.add(helpText, HELP_LABEL );
@ -93,43 +117,19 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
configurationPanel.add(scroll, "spanx, grow, pushy, wrap");
//// Select motor
selectMotorButton = new SelectColorButton(trans.get("MotorConfigurationPanel.btn.selectMotor"));
selectMotorButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectMotor();
}
});
selectMotorButton = new SelectColorButton(selectMotorAction);
configurationPanel.add(selectMotorButton, "split, align right, sizegroup button");
//// Remove motor button
removeMotorButton = new SelectColorButton(trans.get("MotorConfigurationPanel.btn.removeMotor"));
removeMotorButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
removeMotor();
}
});
removeMotorButton = new SelectColorButton(removeMotorAction);
configurationPanel.add(removeMotorButton, "sizegroup button");
//// Select Ignition button
selectIgnitionButton = new SelectColorButton(trans.get("MotorConfigurationPanel.btn.selectIgnition"));
selectIgnitionButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectIgnition();
}
});
configurationPanel.add(selectIgnitionButton, "sizegroup button");
selectIgnitionButton = new SelectColorButton(selectIgnitionAction);
configurationPanel.add(selectIgnitionButton, "sizegroup button, gapleft para");
//// Reset Ignition button
resetIgnitionButton = new SelectColorButton(trans.get("MotorConfigurationPanel.btn.resetIgnition"));
resetIgnitionButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resetIgnition();
}
});
resetIgnitionButton = new SelectColorButton(resetIgnitionAction);
configurationPanel.add(resetIgnitionButton, "sizegroup button, wrap");
cards.add(configurationPanel, TABLE_LABEL );
@ -194,15 +194,55 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
configurationTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
configurationTable.setDefaultRenderer(Object.class, new MotorTableCellRenderer());
ListSelectionListener listener = new ListSelectionListener() {
private int previousRow = -1;
private int previousColumn = -1;
@Override
public void valueChanged(ListSelectionEvent event) {
if (table != null && (configurationTable.getSelectedRow() != previousRow ||
configurationTable.getSelectedColumn() != previousColumn)) {
updateButtonState();
previousRow = configurationTable.getSelectedRow();
previousColumn = configurationTable.getSelectedColumn();
}
}
};
configurationTable.getSelectionModel().addListSelectionListener(listener);
configurationTable.getColumnModel().getSelectionModel().addListSelectionListener(listener);
configurationTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
updateButtonState();
int selectedColumn = table.getSelectedColumn();
if (e.getClickCount() == 2) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
if (selectedColumn > 0) {
selectMotor();
}
} else if (e.getButton() == MouseEvent.BUTTON3 && e.getClickCount() == 1) {
// Get the row and column of the selected cell
int r = configurationTable.rowAtPoint(e.getPoint());
int c = configurationTable.columnAtPoint(e.getPoint());
// Select new cell
if (!configurationTable.isCellSelected(r, c)) {
if (r >= 0 && r < configurationTable.getRowCount() &&
c >= 0 && c < configurationTable.getColumnCount()) {
configurationTable.setRowSelectionInterval(r, r);
configurationTable.setColumnSelectionInterval(c, c);
} else {
configurationTable.clearSelection();
return;
}
}
if (c > 0) {
doPopupFull(e);
} else {
flightConfigurationPanel.doPopupConfig(e);
}
}
}
});
@ -234,6 +274,10 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
});
}
private void doPopupFull(MouseEvent e) {
popupMenuFull.show(e.getComponent(), e.getX(), e.getY());
}
public void updateComponentSelection(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
return;
@ -408,6 +452,50 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
}
private class SelectMotorAction extends AbstractAction {
public SelectMotorAction() {
putValue(NAME, trans.get("MotorConfigurationPanel.btn.selectMotor"));
}
@Override
public void actionPerformed(ActionEvent e) {
selectMotor();
}
}
private class RemoveMotorAction extends AbstractAction {
public RemoveMotorAction() {
putValue(NAME, trans.get("MotorConfigurationPanel.btn.removeMotor"));
}
@Override
public void actionPerformed(ActionEvent e) {
removeMotor();
}
}
private class SelectIgnitionAction extends AbstractAction {
public SelectIgnitionAction() {
putValue(NAME, trans.get("MotorConfigurationPanel.btn.selectIgnition"));
}
@Override
public void actionPerformed(ActionEvent e) {
selectIgnition();
}
}
private class ResetIgnitionAction extends AbstractAction {
public ResetIgnitionAction() {
putValue(NAME, trans.get("MotorConfigurationPanel.btn.resetIgnition"));
}
@Override
public void actionPerformed(ActionEvent e) {
resetIgnition();
}
}
private class MotorTableCellRenderer extends FlightConfigurablePanel<MotorMount>.FlightConfigurableCellRenderer {
@Override

View File

@ -1,7 +1,6 @@
package net.sf.openrocket.gui.main.flightconfigpanel;
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;
@ -12,11 +11,14 @@ import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.sf.openrocket.formatting.RocketDescriptor;
import net.sf.openrocket.gui.dialogs.flightconfiguration.DeploymentSelectionDialog;
@ -35,6 +37,7 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
private FlightConfigurableTableModel<RecoveryDevice> recoveryTableModel;
private final JButton selectDeploymentButton;
private final JButton resetDeploymentButton;
private final JPopupMenu popupMenuFull; // popup menu containing all the options
RecoveryConfigurationPanel(FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
@ -43,26 +46,30 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
JScrollPane scroll = new JScrollPane(table);
this.add(scroll, "span, grow, pushy, wrap");
// Get all the actions
AbstractAction selectDeploymentAction = new SelectDeploymentAction();
AbstractAction resetDeploymentAction = new ResetDeploymentAction();
AbstractAction renameConfigAction = flightConfigurationPanel.getRenameConfigAction();
AbstractAction removeConfigAction = flightConfigurationPanel.getRemoveConfigAction();
AbstractAction duplicateConfigAction = flightConfigurationPanel.getDuplicateConfigAction();
// Populate the popup menu
popupMenuFull = new JPopupMenu();
popupMenuFull.add(selectDeploymentAction);
popupMenuFull.add(resetDeploymentAction);
popupMenuFull.addSeparator();
popupMenuFull.add(renameConfigAction);
popupMenuFull.add(removeConfigAction);
popupMenuFull.add(duplicateConfigAction);
//// Select deployment
selectDeploymentButton = new SelectColorButton(trans.get("edtmotorconfdlg.but.Selectdeployment"));
selectDeploymentButton = new SelectColorButton(selectDeploymentAction);
selectDeploymentButton.setEnabled(false);
selectDeploymentButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectDeployment();
}
});
this.add(selectDeploymentButton, "split, align right, sizegroup button");
//// Reset deployment
resetDeploymentButton = new SelectColorButton(trans.get("edtmotorconfdlg.but.Resetdeployment"));
resetDeploymentButton = new SelectColorButton(resetDeploymentAction);
resetDeploymentButton.setEnabled(false);
resetDeploymentButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resetDeployment();
}
});
this.add(resetDeploymentButton, "sizegroup button, wrap");
// Set 'Enter' key action to open the recovery selection dialog
@ -84,17 +91,60 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
recoveryTable.getTableHeader().setReorderingAllowed(false);
recoveryTable.setCellSelectionEnabled(true);
recoveryTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
ListSelectionListener listener = new ListSelectionListener() {
private int previousRow = -1;
private int previousColumn = -1;
@Override
public void valueChanged(ListSelectionEvent event) {
if (table != null && (recoveryTable.getSelectedRow() != previousRow ||
recoveryTable.getSelectedColumn() != previousColumn)) {
updateButtonState();
previousRow = recoveryTable.getSelectedRow();
previousColumn = recoveryTable.getSelectedColumn();
}
}
};
recoveryTable.getSelectionModel().addListSelectionListener(listener);
recoveryTable.getColumnModel().getSelectionModel().addListSelectionListener(listener);
recoveryTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
updateButtonState();
int selectedColumn = table.getSelectedColumn();
if (e.getClickCount() == 2) {
// Double-click edits
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
if (selectedColumn > 0) {
selectDeployment();
}
} else if (e.getButton() == MouseEvent.BUTTON3 && e.getClickCount() == 1) {
// Get the row and column of the selected cell
int r = recoveryTable.rowAtPoint(e.getPoint());
int c = recoveryTable.columnAtPoint(e.getPoint());
// Select new cell
if (!recoveryTable.isCellSelected(r, c)) {
if (r >= 0 && r < recoveryTable.getRowCount() &&
c >= 0 && c < recoveryTable.getColumnCount()) {
recoveryTable.setRowSelectionInterval(r, r);
recoveryTable.setColumnSelectionInterval(c, c);
} else {
recoveryTable.clearSelection();
return;
}
}
if (c > 0) {
doPopupFull(e);
} else {
flightConfigurationPanel.doPopupConfig(e);
}
}
}
});
rocket.addComponentChangeListener(cce -> {
final RocketComponent source = cce.getSource();
if(source instanceof FlightConfigurableComponent) {
@ -185,6 +235,10 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
}
}
private void doPopupFull(MouseEvent e) {
popupMenuFull.show(e.getComponent(), e.getX(), e.getY());
}
public void updateButtonState() {
boolean componentSelected = getSelectedComponent() != null;
selectDeploymentButton.setEnabled(componentSelected);
@ -221,4 +275,25 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
}
}
private class SelectDeploymentAction extends AbstractAction {
public SelectDeploymentAction() {
putValue(NAME, trans.get("edtmotorconfdlg.but.Selectdeployment"));
}
@Override
public void actionPerformed(ActionEvent e) {
selectDeployment();
}
}
private class ResetDeploymentAction extends AbstractAction {
public ResetDeploymentAction() {
putValue(NAME, trans.get("edtmotorconfdlg.but.Resetdeployment"));
}
@Override
public void actionPerformed(ActionEvent e) {
resetDeployment();
}
}
}

View File

@ -1,7 +1,6 @@
package net.sf.openrocket.gui.main.flightconfigpanel;
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;
@ -12,11 +11,14 @@ import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.sf.openrocket.formatting.RocketDescriptor;
import net.sf.openrocket.gui.dialogs.flightconfiguration.SeparationSelectionDialog;
@ -39,6 +41,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
private FlightConfigurableTableModel<AxialStage> separationTableModel;
private final JButton selectSeparationButton;
private final JButton resetDeploymentButton;
private final JPopupMenu popupMenuFull; // popup menu containing all the options
SeparationConfigurationPanel(FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
@ -47,26 +50,30 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
JScrollPane scroll = new JScrollPane(table);
this.add(scroll, "span, grow, pushy, wrap");
//// Select deployment
selectSeparationButton = new SelectColorButton(trans.get("edtmotorconfdlg.but.Selectseparation"));
// Get all the actions
AbstractAction selectSeparationAction = new SelectSeparationAction();
AbstractAction resetSeparationAction = new ResetSeparationAction();
AbstractAction renameConfigAction = flightConfigurationPanel.getRenameConfigAction();
AbstractAction removeConfigAction = flightConfigurationPanel.getRemoveConfigAction();
AbstractAction duplicateConfigAction = flightConfigurationPanel.getDuplicateConfigAction();
// Populate the popup menu
popupMenuFull = new JPopupMenu();
popupMenuFull.add(selectSeparationAction);
popupMenuFull.add(resetSeparationAction);
popupMenuFull.addSeparator();
popupMenuFull.add(renameConfigAction);
popupMenuFull.add(removeConfigAction);
popupMenuFull.add(duplicateConfigAction);
//// Select separation
selectSeparationButton = new SelectColorButton(selectSeparationAction);
selectSeparationButton.setEnabled(false);
selectSeparationButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
selectSeparation();
}
});
this.add(selectSeparationButton, "split, align right, sizegroup button");
//// Reset deployment
resetDeploymentButton = new SelectColorButton(trans.get("edtmotorconfdlg.but.Resetseparation"));
//// Reset separation
resetDeploymentButton = new SelectColorButton(resetSeparationAction);
resetDeploymentButton.setEnabled(false);
resetDeploymentButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resetSeparation();
}
});
this.add(resetDeploymentButton, "sizegroup button, wrap");
// Set 'Enter' key action to open the separation selection dialog
@ -104,16 +111,60 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
separationTable.getTableHeader().setReorderingAllowed(false);
separationTable.setCellSelectionEnabled(true);
separationTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
ListSelectionListener listener = new ListSelectionListener() {
private int previousRow = -1;
private int previousColumn = -1;
@Override
public void valueChanged(ListSelectionEvent event) {
if (table != null && (separationTable.getSelectedRow() != previousRow ||
separationTable.getSelectedColumn() != previousColumn)) {
updateButtonState();
previousRow = separationTable.getSelectedRow();
previousColumn = separationTable.getSelectedColumn();
}
}
};
separationTable.getSelectionModel().addListSelectionListener(listener);
separationTable.getColumnModel().getSelectionModel().addListSelectionListener(listener);
separationTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
updateButtonState();
if (e.getClickCount() == 2) {
// Double-click edits
int selectedColumn = table.getSelectedColumn();
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
if (selectedColumn > 0) {
selectSeparation();
}
} else if (e.getButton() == MouseEvent.BUTTON3 && e.getClickCount() == 1) {
// Get the row and column of the selected cell
int r = separationTable.rowAtPoint(e.getPoint());
int c = separationTable.columnAtPoint(e.getPoint());
// Select new cell
if (!separationTable.isCellSelected(r, c)) {
if (r >= 0 && r < separationTable.getRowCount() &&
c >= 0 && c < separationTable.getColumnCount()) {
separationTable.setRowSelectionInterval(r, r);
separationTable.setColumnSelectionInterval(c, c);
} else {
separationTable.clearSelection();
return;
}
}
if (c > 0) {
doPopupFull(e);
} else {
flightConfigurationPanel.doPopupConfig(e);
}
}
}
});
separationTable.setDefaultRenderer(Object.class, new SeparationTableCellRenderer());
return separationTable;
@ -192,6 +243,11 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
}
}
private void doPopupFull(MouseEvent e) {
popupMenuFull.show(e.getComponent(), e.getX(), e.getY());
}
public void updateButtonState() {
boolean componentSelected = getSelectedComponent() != null;
selectSeparationButton.setEnabled(componentSelected);
@ -227,5 +283,25 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
}
}
private class SelectSeparationAction extends AbstractAction {
public SelectSeparationAction() {
putValue(NAME, trans.get("edtmotorconfdlg.but.Selectseparation"));
}
@Override
public void actionPerformed(ActionEvent e) {
selectSeparation();
}
}
private class ResetSeparationAction extends AbstractAction {
public ResetSeparationAction() {
putValue(NAME, trans.get("edtmotorconfdlg.but.Resetseparation"));
}
@Override
public void actionPerformed(ActionEvent e) {
resetSeparation();
}
}
}

View File

@ -554,8 +554,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
public static final int CYCLE_SELECTION_MODIFIER = InputEvent.SHIFT_DOWN_MASK;
private void handleMouseClick(MouseEvent event) {
if (event.getButton() != MouseEvent.BUTTON1)
return;
// Get the component that is clicked on
Point p0 = event.getPoint();
Point p1 = scrollPane.getViewport().getViewPosition();
int x = p0.x + p1.x;
@ -563,16 +562,40 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
RocketComponent[] clicked = figure.getComponentsByPoint(x, y);
handleComponentClick(clicked, event);
}
private void handleComponentClick(RocketComponent[] clicked, MouseEvent event) {
// If no component is clicked, do nothing
if (clicked.length == 0) {
selectionModel.setSelectionPath(null);
return;
}
if (event.getButton() == MouseEvent.BUTTON1) {
handleComponentClick(clicked, event);
} else if (event.getButton() == MouseEvent.BUTTON3) {
List<RocketComponent> selectedComponents = Arrays.stream(selectionModel.getSelectionPaths())
.map(c -> (RocketComponent) c.getLastPathComponent()).collect(Collectors.toList());
boolean newClick = true;
for (RocketComponent component : clicked) {
if (selectedComponents.contains(component)) {
newClick = false;
break;
}
}
if (newClick) {
for (RocketComponent rocketComponent : clicked) {
if (!selectedComponents.contains(rocketComponent)) {
TreePath path = ComponentTreeModel.makeTreePath(rocketComponent);
selectionModel.setSelectionPath(path);
}
}
}
basicFrame.doComponentTreePopup(event);
}
}
private void handleComponentClick(RocketComponent[] clicked, MouseEvent event) {
List<RocketComponent> selectedComponents = Arrays.stream(selectionModel.getSelectionPaths())
.map(c -> (RocketComponent) c.getLastPathComponent()).collect(Collectors.toList());

View File

@ -58,12 +58,17 @@ public class Icons {
public static final Icon FILE_QUIT = loadImageIcon("pix/icons/application-exit.png", "Quit OpenRocket");
public static final Icon EDIT_UNDO = loadImageIcon("pix/icons/edit-undo.png", trans.get("Icons.Undo"));
public static final Icon EDIT_REDO = loadImageIcon("pix/icons/edit-redo.png", trans.get("Icons.Redo"));
public static final Icon EDIT_EDIT = loadImageIcon("pix/icons/edit-edit.png", "Edit");
public static final Icon EDIT_CUT = loadImageIcon("pix/icons/edit-cut.png", "Cut");
public static final Icon EDIT_COPY = loadImageIcon("pix/icons/edit-copy.png", "Copy");
public static final Icon EDIT_PASTE = loadImageIcon("pix/icons/edit-paste.png", "Paste");
public static final Icon EDIT_DUPLICATE = loadImageIcon("pix/icons/edit-duplicate.png", "Duplicate");
public static final Icon EDIT_DELETE = loadImageIcon("pix/icons/edit-delete.png", "Delete");
public static final Icon EDIT_SCALE = loadImageIcon("pix/icons/edit-scale.png", "Scale");
public static final Icon SIM_RUN = loadImageIcon("pix/icons/sim-run.png", "Run");
public static final Icon SIM_PLOT = loadImageIcon("pix/icons/sim-plot.png", "Plot");
public static final Icon HELP_ABOUT = loadImageIcon("pix/icons/help-about.png", "About");
public static final Icon HELP_LICENSE = loadImageIcon("pix/icons/help-license.png", "License");
public static final Icon HELP_BUG_REPORT = loadImageIcon("pix/icons/help-bug.png", "Bug report");