OSDN Git Service

refactor: 不要なコメントを削除
[importpicture/importpicture.git] / src / osm / jp / gpx / matchtime / gui / AdjustTime.java
1 package osm.jp.gpx.matchtime.gui;
2
3 import osm.jp.gpx.matchtime.gui.restamp.RestampDialog;
4 import java.awt.*;
5 import java.awt.event.ActionEvent;
6 import java.io.IOException;
7 import java.text.SimpleDateFormat;
8 import java.util.ResourceBundle;
9 import java.util.TimeZone;
10 import java.util.logging.Level;
11 import java.util.logging.Logger;
12 import javax.swing.*;
13 import javax.swing.event.DocumentEvent;
14 import osm.jp.gpx.*;
15 import osm.jp.gpx.matchtime.gui.restamp.CardImageFile;
16 import osm.jp.gpx.matchtime.gui.restamp.CardSourceFolder;
17
18 /**
19  * 本プログラムのメインクラス
20  */
21 @SuppressWarnings("serial")
22 public class AdjustTime extends JFrame
23 {
24     public static final String PROGRAM_NAME = "AdjustTime for JOSM";
25     public static final String PROGRAM_VARSION = "5.01";
26     public static final String PROGRAM_UPDATE = "2019/09/11";
27
28     AppParameters params;
29     public static SimpleDateFormat dfjp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
30
31     // Used for addNotify check.
32     boolean fComponentsAdjusted = false;
33     public static ResourceBundle i18n = ResourceBundle.getBundle("i18n");
34     
35     //{{DECLARE_CONTROLS
36     JTabbedPane cardPanel;       // ウィザード形式パネル(タブ型)
37     Card[] cards;
38     int cardPanelNo = 0;
39     JPanel argsPanel;           // パラメータ設定パネル       (上部)
40     JScrollPane imageSPane;     // スクロールパネル
41     JLabel imageLabel;          // 基準時刻画像表示
42     JCheckBox noFirstNode;      // GPX: <trkseg>セグメントの最初の1ノードは無視する。 {ON | OFF}
43     JCheckBox gpxReuse;         // 生成されたGPXファイル(ファイル名が'_.gpx'で終わるもの)も対象にする。 {ON | OFF}
44     JTextArea textArea;         // 実行結果表示領域
45
46     ParameterPanel arg3_basetime;       // 基準時刻:
47     JCheckBox outputIMG;        // IMGの変換 する/しない
48     JCheckBox outputIMG_all;    // 'out of GPX time'でもIMGの変換をする {ON | OFF}
49     JCheckBox exifON;           // EXIF 書き出しモード / !(EXIFの書き換えはしない)
50     JCheckBox gpxOutputWpt;     // GPXに<WPT>を書き出す
51     JCheckBox gpxOverwriteMagvar;       // ソースGPXの<MAGVAR>を無視する
52     JCheckBox gpxOutputSpeed;   // GPXに<SPEED>を書き出す
53     ParameterPanelFolder arg5_outputFolder;       // EXIF 書き出しフォルダ
54     ParameterPanelGpx arg4_gpxFolder;           // GPXファイル・フォルダ
55     
56     JPanel buttonPanel;         // ボタンパネル   (下部)
57     
58     JButton doButton;       // [処理実行]ボタン
59     //}}
60
61     //---入力フィールド----------------------------------------------------
62     ParameterPanelFolder arg1_srcFolder;    // 対象フォルダ
63     ParameterPanelImageFile arg2_baseTimeImg;   // 開始画像ファイルパス
64     ParameterPanelTime arg2_basetime;   // 開始画像の基準時刻:
65
66     //{{DECLARE_MENUS
67     java.awt.MenuBar mainMenuBar;
68     java.awt.Menu menu1;
69     java.awt.MenuItem miDoNewFileList;
70     java.awt.MenuItem miDoDirSize;
71     java.awt.MenuItem miDoReadXML;
72     java.awt.MenuItem miExit;
73     java.awt.Menu menu2;
74     java.awt.MenuItem miRestamp;
75     java.awt.Menu menu3;
76     java.awt.MenuItem miAbout;
77     //}}
78
79     class SymWindow extends java.awt.event.WindowAdapter {
80         /**
81          * このFrameが閉じられるときの動作。
82          * このパネルが閉じられたら、このアプリケーションも終了させる。
83          */
84         @Override
85         public void windowClosing(java.awt.event.WindowEvent event) {
86             Object object = event.getSource();
87             if (object == AdjustTime.this) {
88                 DbMang_WindowClosing(event);
89             }
90         }
91     }
92
93     class SymAction implements java.awt.event.ActionListener {
94         @Override
95         public void actionPerformed(java.awt.event.ActionEvent event) {
96             Object object = event.getSource();
97             if (object == miAbout) {
98                 miAbout_Action(event);
99             }
100             else if (object == miRestamp) {
101                 try {
102                     miRestamp_Action(event);
103                 } catch (IOException ex) {
104                     Logger.getLogger(AdjustTime.class.getName()).log(Level.SEVERE, null, ex);
105                 }
106             }
107             else if (object == miExit) {
108                 miExit_Action(event);
109             }
110             else if (object == outputIMG) {
111                 outputIMG_Action(event);
112             }
113             else if (object == outputIMG_all) {
114                 outputIMGall_Action(event);
115             }
116             else if (object == exifON) {
117                 exifON_Action(event);
118             }
119             else if (object == gpxOutputWpt) {
120                 gpxOutputWpt_Action(event);
121             }
122             else if (object == gpxOutputSpeed) {
123                 gpxOutputSpeed_Action(event);
124             }
125             else if (object == doButton) {
126                 doButton_Action(event);
127             }
128         }
129     }
130     
131     /**
132      * データベース内のテーブルを一覧で表示するFrame
133      * @throws IOException 
134      */
135     @SuppressWarnings("OverridableMethodCallInConstructor")
136     public AdjustTime() throws IOException
137     {
138         dfjp.setTimeZone(TimeZone.getTimeZone("JST"));
139
140         // INIT_CONTROLS
141         Container container = getContentPane();
142         container.setLayout(new BorderLayout());
143         setSize(
144             getInsets().left + getInsets().right + 720,
145             getInsets().top + getInsets().bottom + 480
146         );
147         setTitle(AdjustTime.PROGRAM_NAME +" v"+ AdjustTime.PROGRAM_VARSION);
148         
149         //---- CENTER -----
150         JPanel mainPanel = new JPanel();
151         mainPanel.setLayout(new BorderLayout());
152         container.add(mainPanel, BorderLayout.CENTER);
153         
154         //---- SOUTH -----
155         JPanel southPanel = new JPanel(new BorderLayout());
156         southPanel.add(Box.createVerticalStrut(10), BorderLayout.SOUTH);
157         southPanel.add(Box.createVerticalStrut(10), BorderLayout.NORTH);
158         container.add(southPanel, BorderLayout.SOUTH);
159         
160         //---- SPACE -----
161         container.add(Box.createVerticalStrut(30), BorderLayout.NORTH);
162         container.add(Box.createHorizontalStrut(10), BorderLayout.WEST);
163         container.add(Box.createHorizontalStrut(10), BorderLayout.EAST);
164         
165         params = new AppParameters();
166         
167         //---------------------------------------------------------------------
168         cardPanel = new JTabbedPane(JTabbedPane.LEFT);
169         mainPanel.add(cardPanel, BorderLayout.CENTER);
170         
171         cards = new Card[5];
172         int cardNo = 0;
173
174         //---------------------------------------------------------------------
175         // 1.[対象フォルダ]設定パネル
176         {
177             arg1_srcFolder = new ParameterPanelFolder(
178                     i18n.getString("label.110") +": ", 
179                     params.getProperty(AppParameters.IMG_SOURCE_FOLDER)
180             );
181             arg1_srcFolder.argField
182                 .getDocument()
183                 .addDocumentListener(
184                     new SimpleDocumentListener() {
185                         @Override
186                         public void update(DocumentEvent e) {
187                             toEnable(0, arg1_srcFolder.isEnable());
188                         }
189                     }
190                 );
191
192             Card card = new CardSourceFolder(cardPanel, arg1_srcFolder);
193             cardPanel.addTab(card.getTitle(), card);
194             cardPanel.setEnabledAt(cardNo, true);
195             cards[cardNo] = card;
196             cardNo++;
197         }
198         
199         //---------------------------------------------------------------------
200         // 2.[基準時刻画像]設定パネル
201         // 2a.基準時刻の入力画面
202         {
203             // 基準時刻画像
204             arg2_baseTimeImg = new ParameterPanelImageFile(
205                 i18n.getString("label.210") +": ", 
206                 null, 
207                 arg1_srcFolder
208             );
209
210             // 2a. 基準時刻:
211             arg2_basetime = new ParameterPanelTime(
212                     i18n.getString("label.310"), 
213                     null, 
214                     arg2_baseTimeImg
215             );
216             arg2_basetime.argField.getDocument().addDocumentListener(
217                 new SimpleDocumentListener() {
218                     @Override
219                     public void update(DocumentEvent e) {
220                         toEnable(1, arg2_basetime.isEnable());
221                     }
222                 }
223             );
224             
225             // EXIFの日時を基準にする
226             arg2_basetime.addExifBase(i18n.getString("label.220"), params);
227
228             // ファイル更新日時を基準にする
229             arg2_basetime.addFileUpdate(i18n.getString("label.230"), params);
230
231             CardImageFile card = new CardImageFile(
232                     cardPanel, arg2_basetime, (Window)this, 
233                     AdjustTime.i18n.getString("tab.300"), 0, 2);
234             cardPanel.addTab(card.getTitle(), card);
235             cardPanel.setEnabledAt(cardNo, false);
236             cards[cardNo] = card;
237             cardNo++;
238         }
239         
240         //---------------------------------------------------------------------
241         // 3.GPXファイル設定画面
242         {
243             // 3. GPXファイルを選択
244             Card card = new Card(cardPanel, i18n.getString("tab.400"), 2, 4);
245             cardPanel.addTab(card.getTitle(), card);
246             cards[cardNo] = card;
247
248             // 4. ヒモ付を行うGPXファイルを選択してください。
249             //    - フォルダを指定すると、フォルダ内のすべてのGPXファイルを対象とします。
250             JLabel label4 = new JLabel();
251             label4.setText(i18n.getString("label.400"));
252             card.mainPanel.add(label4, BorderLayout.NORTH);
253
254             JPanel tmpPanel4a = new JPanel();
255             tmpPanel4a.setLayout(new BoxLayout(tmpPanel4a, BoxLayout.Y_AXIS));
256
257             // "GPXフォルダ: "
258             arg4_gpxFolder = new ParameterPanelGpx(
259                 i18n.getString("label.410") + ": ", 
260                 params.getProperty(AppParameters.GPX_SOURCE_FOLDER)
261             );
262             tmpPanel4a.add(arg4_gpxFolder);
263
264             // "セグメント'trkseg'の最初の1ノードは無視する。"
265             noFirstNode = new JCheckBox(
266                 i18n.getString("label.420"), 
267                 params.getProperty(AppParameters.GPX_NO_FIRST_NODE).equals("ON")
268             );
269             tmpPanel4a.add(noFirstNode);
270
271             // "生成されたGPXファイル(ファイル名が'_.gpx'で終わるもの)も変換の対象にする"
272             gpxReuse = new JCheckBox(
273                 i18n.getString("label.430"),
274                 params.getProperty(AppParameters.GPX_REUSE).equals("ON")
275             );
276             gpxReuse.setEnabled(true);
277             tmpPanel4a.add(gpxReuse);
278             card.mainPanel.add(tmpPanel4a, BorderLayout.CENTER);
279             cardNo++;
280         }
281         
282         //---------------------------------------------------------------------
283         // 4.EXIF更新設定画面
284         {
285             Card card = new Card(cardPanel, i18n.getString("tab.500"), 3, -1);
286             cardPanel.addTab(card.getTitle(), card);
287             cards[cardNo] = card;
288             
289             // 5. EXIF変換を行うかどうかを選択してください。
290             //    - EXIF変換を行う場合には、変換ファイルを出力するフォルダも指定する必要があります。
291             //    - 出力フォルダには、書き込み権限と、十分な空き容量が必要です。
292             JLabel label5 = new JLabel();
293             label5.setText(
294                 String.format(
295                     "<html><p>5. %s</p><ul><li>%s</li><li>%s</li></ul>",
296                     i18n.getString("label.500"),
297                     i18n.getString("label.501"),
298                     i18n.getString("label.502")
299                 )
300             );
301             card.mainPanel.add(label5, BorderLayout.NORTH);
302
303             JPanel tmpPanel5 = new JPanel();
304             tmpPanel5.setLayout(new BoxLayout(tmpPanel5, BoxLayout.Y_AXIS));
305
306             // "IMGの変換をする"
307             outputIMG = new JCheckBox(
308                 i18n.getString("label.510"), 
309                 Boolean.parseBoolean(params.getProperty(AppParameters.IMG_OUTPUT))
310             );
311             tmpPanel5.add(outputIMG);
312
313             // "GPXファイル時間外のファイルもコピーする"
314             outputIMG_all = new JCheckBox(
315                 i18n.getString("label.520"),
316                 Boolean.parseBoolean(params.getProperty(AppParameters.IMG_OUTPUT_ALL))
317             );
318             tmpPanel5.add(outputIMG_all);
319
320             // "出力フォルダ: "
321             arg5_outputFolder = new ParameterPanelFolder(
322                 i18n.getString("label.530") + ": ",
323                 params.getProperty(AppParameters.IMG_OUTPUT_FOLDER)
324             );
325             tmpPanel5.add(arg5_outputFolder);
326
327             // "EXIFの変換をする"
328             exifON = new JCheckBox(
329                 i18n.getString("label.540"),
330                 Boolean.parseBoolean(params.getProperty(AppParameters.IMG_OUTPUT_EXIF))
331             );
332             tmpPanel5.add(exifON);
333
334             // "ポイントマーカー<WPT>をGPXファイルに出力する"
335             gpxOutputWpt = new JCheckBox(
336                 i18n.getString("label.550"),
337                 Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OUTPUT_WPT))
338             );
339             gpxOutputWpt.setEnabled(true);
340             tmpPanel5.add(gpxOutputWpt);
341
342             // "ソースGPXの<MAGVAR>を無視する"
343             gpxOverwriteMagvar = new JCheckBox(
344                 i18n.getString("label.560"),
345                 Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OVERWRITE_MAGVAR))
346             );
347             gpxOverwriteMagvar.setEnabled(true);
348             tmpPanel5.add(gpxOverwriteMagvar);
349
350             // "出力GPXに<SPEED>を上書きする"
351             gpxOutputSpeed = new JCheckBox(
352                 i18n.getString("label.570"),
353                 Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OUTPUT_SPEED))
354             );
355             gpxOutputSpeed.setEnabled(true);
356             tmpPanel5.add(gpxOutputSpeed);
357
358             card.mainPanel.add(tmpPanel5, BorderLayout.CENTER);
359
360             // "処理実行"
361             doButton = new JButton(
362                 i18n.getString("button.execute"),
363                 AdjustTime.createImageIcon("images/media_playback_start.png")
364             );
365             card.mainPanel.add(doButton, BorderLayout.SOUTH);
366             cardNo++;
367         }
368
369         //---------------------------------------------------------------------
370         // INIT_MENUS
371         menu1 = new java.awt.Menu("File");
372         miExit = new java.awt.MenuItem(i18n.getString("menu.quit"));
373         miExit.setFont(new Font("Dialog", Font.PLAIN, 12));
374         menu1.add(miExit);
375
376         miRestamp = new java.awt.MenuItem(i18n.getString("menu.restamp") + "...");
377         miRestamp.setFont(new Font("Dialog", Font.PLAIN, 12));
378         
379         menu2 = new java.awt.Menu(i18n.getString("menu.tools"));
380         menu2.setFont(new Font("Dialog", Font.PLAIN, 12));
381         menu2.add(miRestamp);
382
383         miAbout = new java.awt.MenuItem("About...");
384         miAbout.setFont(new Font("Dialog", Font.PLAIN, 12));
385
386         menu3 = new java.awt.Menu("Help");
387         menu3.setFont(new Font("Dialog", Font.PLAIN, 12));
388         menu3.add(miAbout);
389
390         mainMenuBar = new java.awt.MenuBar();
391         mainMenuBar.setHelpMenu(menu3);
392         mainMenuBar.add(menu1);
393         mainMenuBar.add(menu2);
394         mainMenuBar.add(menu3);
395         setMenuBar(mainMenuBar);
396
397         //{{REGISTER_LISTENERS
398         SymWindow aSymWindow = new SymWindow();
399         this.addWindowListener(aSymWindow);
400         SymAction lSymAction = new SymAction();
401         miAbout.addActionListener(lSymAction);
402         miRestamp.addActionListener(lSymAction);
403         miExit.addActionListener(lSymAction);
404         arg2_baseTimeImg.openButton.addActionListener(lSymAction);
405         doButton.addActionListener(lSymAction);
406         outputIMG_all.addActionListener(lSymAction);
407         exifON.addActionListener(lSymAction);
408         gpxOutputSpeed.addActionListener(lSymAction);
409         noFirstNode.addActionListener(lSymAction);
410         gpxReuse.addActionListener(lSymAction);
411         //}}
412     }
413     
414     /**
415      * Shows or hides the component depending on the boolean flag b.
416      * @param b trueのときコンポーネントを表示; その他のとき, componentを隠す.
417      * @see java.awt.Component#isVisible
418      */
419     @Override
420     public void setVisible(boolean b) {
421         if(b) {
422             setLocation(50, 50);
423         }
424         super.setVisible(b);
425     }
426     
427     /**
428      * このクラスをインスタンスを生成して表示する。
429      * コマンドラインの引数はありません。
430      * @param args
431      */    
432     @SuppressWarnings("UseSpecificCatch")
433     static public void main(String args[]) {
434         SwingUtilities.invokeLater(() -> {
435             try {
436                 createAndShowGUI();
437             } catch (Exception e) {
438                 e.printStackTrace();
439             }
440         });
441     }
442     private static void createAndShowGUI() throws IOException {
443         (new AdjustTime()).setVisible(true);
444     }
445
446     @Override
447     public void addNotify()     {
448         // Record the size of the window prior to calling parents addNotify.
449         Dimension d = getSize();
450
451         super.addNotify();
452
453         if (fComponentsAdjusted)
454             return;
455
456         // Adjust components according to the insets
457         setSize(getInsets().left + getInsets().right + d.width, getInsets().top + getInsets().bottom + d.height);
458         Component components[] = getComponents();
459         for (Component component : components) {
460             Point p = component.getLocation();
461             p.translate(getInsets().left, getInsets().top);
462             component.setLocation(p);
463         }
464         fComponentsAdjusted = true;
465     }
466
467     void DbMang_WindowClosing(java.awt.event.WindowEvent event) {
468         setVisible(false);  // hide the Manager
469         dispose();                      // free the system resources
470         System.exit(0);         // close the application
471     }
472
473     void miAbout_Action(java.awt.event.ActionEvent event) {
474         // Action from About Create and show as modal
475         (new AboutDialog(this, true)).setVisible(true);
476     }
477     
478     void miRestamp_Action(java.awt.event.ActionEvent event) throws IOException {
479         (new RestampDialog(this, false)).setVisible(true);
480     }
481     
482     void miExit_Action(java.awt.event.ActionEvent event) {
483         // Action from Exit Create and show as modal
484         //(new hayashi.yuu.tools.gui.QuitDialog(this, true)).setVisible(true);
485         (new QuitDialog(this, true)).setVisible(true);
486     }
487     
488     void toEnable(final int cardNo, final boolean enable) {
489         if ((cardNo >= 0) && (cardNo < cards.length)) {
490             cardPanel.setEnabledAt(cardNo, enable);
491             if ((cardNo -1) >= 0) {
492                 cards[cardNo -1].nextButton.setEnabled(enable);
493             }
494             if ((cardNo +1) < cards.length) {
495                 cardPanel.setEnabledAt(cardNo+1, enable);
496                 cards[cardNo +1].backButton.setEnabled(enable);
497                 cards[cardNo].nextButton.setEnabled(enable);
498             }
499         }
500     }
501
502     ImageIcon refImage;
503     
504     /**
505      * ソースディレクトリが選択された時のアクション
506      * → AdjustTime.ini に書き込む
507      * @param ev
508      */
509     public void selectSource_Action(ActionEvent ev) {
510     }
511     
512     /** Returns an ImageIcon, or null if the path was invalid.
513      * @param path
514      * @return  */
515     public static ImageIcon createImageIcon(String path) {
516         java.net.URL imgURL = AdjustTime.class.getResource(path);
517         if (imgURL != null) {
518             return new ImageIcon(imgURL);
519         } else {
520             System.err.println("Couldn't find file: " + path);
521             return null;
522         }
523     }
524     
525     /**
526      * checkbox[IMG変換]を変更した場合のアクション
527      *  ON ー> IMG出力フォルダのフィールドを有効にする
528      *  OFF -> IMG出力フォルダのフィールドを無効にする
529      * @param event
530      */
531     void outputIMG_Action (ActionEvent event) {
532         arg5_outputFolder.setEnabled(outputIMG.isEnabled());
533     }
534
535     /**
536      * checkbox[GPXファイル時間外のファイルもコピーする]を変更した場合のアクション
537      * @param event
538      */
539     void outputIMGall_Action (ActionEvent event) {
540     }
541
542     /**
543      * checkbox[EXIF書き出し]を変更した場合のアクション
544      * @param event
545      */
546     void exifON_Action (ActionEvent event) {
547     }
548
549     /**
550      * checkbox[GPXの<WPT>を出力する]を変更した場合のアクション
551      * @param event
552      */
553     void gpxOutputWpt_Action (ActionEvent event) {
554     }
555
556     /**
557      * checkbox[GPXの<SPPED>を書き換える]を変更した場合のアクション
558      * @param event
559      */
560     void gpxOutputSpeed_Action (ActionEvent event) {
561     }
562
563     /**
564      * [実行]ボタンをクリックしたときの動作
565      * @param event
566      */
567     @SuppressWarnings("UseSpecificCatch")
568     void doButton_Action(java.awt.event.ActionEvent event) {
569         doButton.setEnabled(false);
570
571         String[] argv = new String[0];
572         this.params.setProperty(AppParameters.GPX_NO_FIRST_NODE, String.valueOf(noFirstNode.isSelected()));
573         this.params.setProperty(AppParameters.GPX_REUSE, String.valueOf(gpxReuse.isSelected()));
574         this.params.setProperty(AppParameters.GPX_SOURCE_FOLDER, arg4_gpxFolder.getText());
575         /*
576         if (exifBase.isSelected()) {
577             this.params.setProperty(AppParameters.GPX_BASETIME, "EXIF_TIME");
578         }
579         else {
580             this.params.setProperty(AppParameters.GPX_BASETIME, "FILE_UPDATE");
581         }
582         */
583         try {
584             this.params.setProperty(AppParameters.IMG_SOURCE_FOLDER, arg1_srcFolder.getText());
585             this.params.setProperty(AppParameters.IMG_BASE_FILE, arg2_baseTimeImg.getText());
586             this.params.setProperty(AppParameters.IMG_TIME, ImportPicture.toUTCString(dfjp.parse(arg3_basetime.getText())));
587             this.params.setProperty(AppParameters.IMG_OUTPUT, String.valueOf(outputIMG.isSelected()));
588             this.params.setProperty(AppParameters.IMG_OUTPUT_FOLDER, arg5_outputFolder.getText());
589             this.params.setProperty(AppParameters.IMG_OUTPUT_ALL, String.valueOf(outputIMG_all.isSelected()));
590             this.params.setProperty(AppParameters.IMG_OUTPUT_EXIF, String.valueOf(exifON.isSelected()));
591             this.params.setProperty(AppParameters.GPX_OVERWRITE_MAGVAR, String.valueOf(gpxOverwriteMagvar.isSelected()));
592             this.params.setProperty(AppParameters.GPX_OUTPUT_SPEED, String.valueOf(gpxOutputSpeed.isSelected()));
593             this.params.setProperty(AppParameters.GPX_OUTPUT_WPT, String.valueOf(gpxOutputWpt.isSelected()));
594             this.params.store();
595         }
596         catch(Exception e) {
597             e.printStackTrace();
598         }
599
600         (new DoDialog(argv)).setVisible(true);
601                 
602         doButton.setEnabled(true);
603     }
604 }