1 /*
2  * Copyright (c) 2018 Helmut Neemann.
3  * Use of this source code is governed by the GPL v3 license
4  * that can be found in the LICENSE file.
5  */
6 package de.neemann.digital.builder.ATF150x;
7 
8 import de.neemann.digital.builder.tt2.OSExecute;
9 import de.neemann.digital.core.element.Keys;
10 import de.neemann.digital.gui.Settings;
11 import de.neemann.digital.lang.Lang;
12 import de.neemann.gui.ErrorMessage;
13 import de.neemann.gui.LineBreaker;
14 import de.neemann.gui.ToolTipAction;
15 
16 import javax.swing.*;
17 import java.awt.*;
18 import java.awt.event.ActionEvent;
19 import java.awt.event.WindowAdapter;
20 import java.awt.event.WindowEvent;
21 import java.io.File;
22 import java.util.ArrayList;
23 
24 import static de.neemann.gui.Screen.isLinux;
25 
26 /**
27  * Dialog used to show the result of the external fitter.
28  */
29 public class ATFDialog extends JDialog {
30     private final JDialog parent;
31     private final JLabel label;
32     private final ToolTipAction startATMISPAction;
33     private final JButton okButton;
34     private File chnFile;
35     private String fitterResult;
36 
ATFDialog(JDialog parent)37     ATFDialog(JDialog parent) {
38         super(parent, Lang.get("msg_fitterResult"), true);
39         setDefaultCloseOperation(DISPOSE_ON_CLOSE);
40         this.parent = parent;
41 
42         label = new JLabel();
43         label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
44         getContentPane().add(label);
45 
46         JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
47         startATMISPAction = new ToolTipAction(Lang.get("btn_startATMISP")) {
48             @Override
49             public void actionPerformed(ActionEvent actionEvent) {
50                 File atmispFile = Settings.getInstance().get(Keys.SETTINGS_ATMISP);
51 
52                 ArrayList<String> args = new ArrayList<>();
53                 if (isLinux())
54                     args.add("wine");
55                 args.add(atmispFile.getPath());
56                 args.add(chnFile.getName());
57 
58                 startATMISPAction.setEnabled(false);
59 
60                 OSExecute atmisp = new OSExecute(args)
61                         .setWorkingDir(chnFile.getParentFile())
62                         .setTimeOutSec(6000);
63 
64                 final WindowAdapter windowListener = new WindowAdapter() {
65                     @Override
66                     public void windowClosed(WindowEvent e) {
67                         if (atmisp.isAlive()) {
68                             SwingUtilities.invokeLater(() -> {
69                                 JOptionPane.showMessageDialog(parent,
70                                         Lang.get("msg_ATMISPIsStillRunning"));
71                                 atmisp.terminate();
72                             });
73                         }
74                     }
75                 };
76                 addWindowListener(windowListener);
77 
78                 atmisp.startInThread(new OSExecute.ProcessCallback() {
79                     @Override
80                     public void processTerminated(String consoleOut) {
81                         SwingUtilities.invokeLater(() -> {
82                             startATMISPAction.setEnabled(true);
83                             removeWindowListener(windowListener);
84                         });
85                     }
86 
87                     @Override
88                     public void exception(Exception e) {
89                         SwingUtilities.invokeLater(() -> {
90                             startATMISPAction.setEnabled(true);
91                             removeWindowListener(windowListener);
92                             new ErrorMessage(Lang.get("msg_errorStartingATMISP")).addCause(e).show();
93                         });
94                     }
95                 });
96             }
97         }.setToolTip(Lang.get("btn_startATMISP_tt")).setEnabledChain(false);
98 
99         buttons.add(startATMISPAction.createJButton());
100 
101         okButton = new ToolTipAction(Lang.get("ok")) {
102             @Override
103             public void actionPerformed(ActionEvent actionEvent) {
104                 dispose();
105             }
106         }.createJButton();
107         buttons.add(okButton);
108         getContentPane().add(buttons, BorderLayout.SOUTH);
109         SwingUtilities.getRootPane(okButton).setDefaultButton(okButton);
110     }
111 
setChnFile(File chnFile)112     void setChnFile(File chnFile) {
113         this.chnFile = chnFile;
114         checkStartATMISP();
115     }
116 
checkStartATMISP()117     private void checkStartATMISP() {
118         if (fitterResult != null
119                 && chnFile != null
120                 && fitterResult.contains("Design fits successfully")) {
121             startATMISPAction.setEnabled(true);
122         } else
123             startATMISPAction.setEnabled(false);
124         okButton.requestFocusInWindow();
125     }
126 
127     /**
128      * Sets the result of the fitter.
129      *
130      * @param fitterResult the result message
131      */
setFitterResult(String fitterResult)132     public void setFitterResult(String fitterResult) {
133         this.fitterResult = fitterResult;
134         label.setText(new LineBreaker().preserveContainedLineBreaks().toHTML().breakLines(fitterResult));
135         checkStartATMISP();
136         pack();
137         setLocationRelativeTo(parent);
138         setVisible(true);
139     }
140 }
141