1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sourceforge.jarduino.gui;
18
19 import java.awt.BorderLayout;
20 import java.awt.CardLayout;
21 import java.awt.Dimension;
22 import java.awt.Font;
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.InputStreamReader;
28 import java.io.PrintWriter;
29 import java.nio.charset.Charset;
30 import javax.swing.BorderFactory;
31 import javax.swing.Box;
32 import javax.swing.BoxLayout;
33 import javax.swing.JButton;
34 import javax.swing.JComponent;
35 import javax.swing.JFrame;
36 import javax.swing.JPanel;
37 import javax.swing.JScrollPane;
38 import javax.swing.JTextArea;
39 import javax.swing.border.Border;
40
41 import net.sourceforge.jarduino.ArduinoException;
42 import net.sourceforge.jarduino.message.ArduinoChar;
43 import net.sourceforge.jarduino.message.ArduinoLibrary;
44 import net.sourceforge.jarduino.message.ArduinoGenerator;
45 import net.sourceforge.jarduino.message.ArduinoMsgFilter;
46 import net.sourceforge.jarduino.message.ArduinoParser;
47 import net.sourceforge.jarduino.message.ArduinoSystem;
48
49
50
51
52 public class ArduinoPanelSource {
53
54
55
56 private static final String FILTER = "Filter";
57
58
59
60
61 private static final String SOURCE = "Source";
62
63
64
65
66 static final Font FONT = new Font("monospaced", Font.PLAIN, 12);
67
68
69
70
71 private final JPanel thePanel;
72
73
74
75
76 private final ArduinoScrollButton<ArduinoFileSet> theFileSetButton;
77
78
79
80
81 private final ArduinoScrollButton<ArduinoFile> theFileButton;
82
83
84
85
86 private final JTextArea theSourceFile;
87
88
89
90
91 private final ArduinoPanelFilter theFilterPanel;
92
93
94
95
96 private ArduinoSystem theSystem;
97
98
99
100
101 private String theDBCFile;
102
103
104
105
106 private ArduinoException theError;
107
108
109
110
111
112 ArduinoPanelSource(final JFrame pFrame) {
113
114 thePanel = new JPanel(new CardLayout());
115
116
117 theFilterPanel = new ArduinoPanelFilter(this, pFrame);
118
119
120 theSourceFile = new JTextArea();
121 theSourceFile.setEditable(false);
122 theSourceFile.setFont(FONT);
123
124
125 final JButton myFilterButton = new JButton();
126 myFilterButton.setText("Sources");
127 myFilterButton.addActionListener(e -> showFilter());
128
129
130 theFileButton = new ArduinoScrollButton<>(pFrame);
131 theFileButton.onSelect(this::showSourceFile);
132 theFileButton.setFormatter(e -> e.getFileName(theSystem));
133
134
135 theFileSetButton = new ArduinoScrollButton<>(pFrame);
136 theFileSetButton.onSelect(this::populateFileSet);
137 for (ArduinoFileSet myFileSet : ArduinoFileSet.values()) {
138 theFileSetButton.add(myFileSet);
139 }
140
141
142 final JPanel myFilePanel = new JPanel();
143 myFilePanel.setLayout(new BoxLayout(myFilePanel, BoxLayout.X_AXIS));
144 myFilePanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
145 myFilePanel.add(theFileSetButton.getComponent());
146 myFilePanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
147 myFilePanel.add(theFileButton.getComponent());
148 myFilePanel.add(Box.createHorizontalGlue());
149 Border myBorder = BorderFactory.createTitledBorder("Select File To View");
150 myFilePanel.setBorder(myBorder);
151
152
153 final JPanel myFilterPanel = new JPanel();
154 myFilterPanel.setLayout(new BoxLayout(myFilterPanel, BoxLayout.X_AXIS));
155 myFilterPanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
156 myFilterPanel.add(myFilterButton);
157 myFilterPanel.add(Box.createHorizontalStrut(ArduinoPanelMain.STRUTSIZE));
158 myBorder = BorderFactory.createTitledBorder("View");
159 myFilterPanel.setBorder(myBorder);
160
161
162 final JPanel myControl = new JPanel();
163 myControl.setLayout(new BoxLayout(myControl, BoxLayout.X_AXIS));
164 myControl.add(myFilePanel);
165 myControl.add(myFilterPanel);
166
167
168 final JPanel myFileView = new JPanel(new BorderLayout());
169 myFileView.add(new JScrollPane(theSourceFile), BorderLayout.CENTER);
170 myBorder = BorderFactory.createTitledBorder(SOURCE);
171 myFileView.setBorder(myBorder);
172
173
174 final JPanel mySource = new JPanel(new BorderLayout());
175 mySource.add(myControl, BorderLayout.PAGE_START);
176 mySource.add(myFileView, BorderLayout.CENTER);
177
178
179 thePanel.add(mySource, SOURCE);
180 thePanel.add(theFilterPanel.getComponent(), FILTER);
181
182
183 thePanel.setPreferredSize(new Dimension(ArduinoPanelMain.WIDTH, ArduinoPanelMain.HEIGHT));
184 }
185
186
187
188
189
190 JComponent getComponent() {
191 return thePanel;
192 }
193
194
195
196
197
198 ArduinoSystem getSystem() {
199 return theSystem;
200 }
201
202
203
204
205
206 ArduinoException getError() {
207 return theError;
208 }
209
210
211
212
213 private void showFilter() {
214 ((CardLayout) thePanel.getLayout()).show(thePanel, FILTER);
215 }
216
217
218
219
220 void showSource() {
221 ((CardLayout) thePanel.getLayout()).show(thePanel, SOURCE);
222 }
223
224
225
226
227 void updateFilter() {
228 showSourceFile(theFileButton.getSelectedItem());
229 }
230
231
232
233
234
235
236
237 boolean setSelected(final File pSource,
238 final Charset pCharSet) {
239
240 try {
241
242 theError = null;
243
244
245 final ArduinoSystem mySystem = ArduinoParser.parseFile(pSource, pCharSet);
246
247
248 theDBCFile = loadSource(pSource, pCharSet);
249
250
251 theSystem = mySystem;
252 theFilterPanel.setSystem(mySystem);
253 theFileSetButton.setSelectedItem(ArduinoFileSet.SRCDBC);
254 return true;
255
256
257 } catch (ArduinoException e) {
258
259 theError = e;
260 return false;
261 }
262 }
263
264
265
266
267
268 private void showSourceFile(final ArduinoFile pFile) {
269
270 theSourceFile.setText(getSourceText(pFile));
271 theSourceFile.setCaretPosition(0);
272 }
273
274
275
276
277
278 private void populateFileSet(final ArduinoFileSet pFileSet) {
279
280 theFileButton.removeAll();
281 for (ArduinoFile myFile : ArduinoFile.values()) {
282 if (myFile.isInFileSet(pFileSet)) {
283 theFileButton.add(myFile);
284 }
285 }
286 }
287
288
289
290
291
292
293 private String getSourceText(final ArduinoFile pFile) {
294
295 if (theSystem == null) {
296 return null;
297 }
298
299
300 switch (pFile) {
301 case BASEHEADER:
302 return ArduinoLibrary.loadLibraryHeader();
303 case BASEBODY:
304 return ArduinoLibrary.loadLibraryCode();
305 case SRCHEADER:
306 return ArduinoGenerator.formatHeader(theSystem, theFilterPanel.getFilter());
307 case SRCBODY:
308 return ArduinoGenerator.formatBody(theSystem, theFilterPanel.getFilter());
309 case DBCFILE:
310 default:
311 return theDBCFile;
312 }
313 }
314
315
316
317
318
319
320
321
322 private static String loadSource(final File pSource,
323 final Charset pCharSet) throws ArduinoException {
324
325 try (FileInputStream myStream = new FileInputStream(pSource);
326 InputStreamReader myReader = new InputStreamReader(myStream, pCharSet);
327 BufferedReader myInput = new BufferedReader(myReader)) {
328
329 final StringBuilder myBuilder = new StringBuilder();
330
331
332 for (;;) {
333
334 final String myLine = myInput.readLine();
335 if (myLine == null) {
336 break;
337 }
338
339
340 myBuilder.append(myLine);
341 myBuilder.append(ArduinoChar.LF);
342 }
343
344
345 return myBuilder.toString();
346
347
348 } catch (IOException e) {
349 throw new ArduinoException("Failed to load File");
350 }
351 }
352
353
354
355
356
357
358
359 ArduinoException writeSketchToDirectory(final File pDirectory,
360 final Charset pCharSet) {
361
362 try {
363
364 final ArduinoMsgFilter myFilter = theFilterPanel.getFilter();
365
366
367 File myFile = new File(pDirectory, ArduinoFile.SRCHEADER.getFileName(theSystem));
368 writeStringToFile(ArduinoGenerator.formatHeader(theSystem, myFilter), pCharSet, myFile);
369
370
371 myFile = new File(pDirectory, ArduinoFile.SRCBODY.getFileName(theSystem));
372 writeStringToFile(ArduinoGenerator.formatBody(theSystem, myFilter), pCharSet, myFile);
373
374
375 return null;
376
377
378 } catch (ArduinoException e) {
379 return e;
380 }
381 }
382
383
384
385
386
387
388
389 ArduinoException writeLibraryToDirectory(final File pDirectory,
390 final Charset pCharSet) {
391
392 try {
393
394 File myFile = new File(pDirectory, ArduinoFile.BASEHEADER.getFileName(theSystem));
395 writeStringToFile(ArduinoLibrary.loadLibraryHeader(), pCharSet, myFile);
396
397
398 myFile = new File(pDirectory, ArduinoFile.BASEBODY.getFileName(theSystem));
399 writeStringToFile(ArduinoLibrary.loadLibraryCode(), pCharSet, myFile);
400
401
402 return null;
403
404
405 } catch (ArduinoException e) {
406 return e;
407 }
408 }
409
410
411
412
413
414
415
416
417 private static void writeStringToFile(final String pData,
418 final Charset pCharSet,
419 final File pFile) throws ArduinoException {
420
421 try (PrintWriter myWriter = new PrintWriter(pFile, pCharSet.name())) {
422
423 myWriter.print(pData);
424
425 } catch (IOException e) {
426 throw new ArduinoException("Failed to output to file", pFile.getAbsolutePath());
427 }
428 }
429
430
431
432
433 private enum ArduinoFile {
434
435
436
437 SRCHEADER,
438
439
440
441
442 SRCBODY,
443
444
445
446
447 BASEHEADER,
448
449
450
451
452 BASEBODY,
453
454
455
456
457 DBCFILE;
458
459
460
461
462
463
464 String getFileName(final ArduinoSystem pSystem) {
465
466 if (pSystem == null) {
467 return "Unknown";
468 }
469
470
471 switch (this) {
472 case SRCHEADER:
473 return pSystem.getCName() + ".h";
474 case SRCBODY:
475 return pSystem.getCName() + ".cpp";
476 case BASEHEADER:
477 return ArduinoLibrary.HEADER;
478 case BASEBODY:
479 return ArduinoLibrary.CODE;
480 case DBCFILE:
481 default:
482 return pSystem.getName() + ".dbc";
483 }
484 }
485
486
487
488
489
490
491 boolean isInFileSet(final ArduinoFileSet pFileSet) {
492
493 switch (this) {
494 case SRCBODY:
495 case SRCHEADER:
496 return ArduinoFileSet.SKETCH.equals(pFileSet);
497 case BASEHEADER:
498 case BASEBODY:
499 return ArduinoFileSet.LIBRARY.equals(pFileSet);
500 case DBCFILE:
501 default:
502 return ArduinoFileSet.SRCDBC.equals(pFileSet);
503 }
504 }
505 }
506
507
508
509
510 private enum ArduinoFileSet {
511
512
513
514 SRCDBC,
515
516
517
518
519 SKETCH,
520
521
522
523
524 LIBRARY;
525
526 @Override
527 public String toString() {
528 switch (this) {
529 case SRCDBC:
530 return "Source DBC";
531 case SKETCH:
532 return "Sketch";
533 case LIBRARY:
534 default:
535 return "Library";
536 }
537 }
538 }
539 }