OSDN Git Service

mainエントリのパッケージを変更。
[jindolf/Jindolf.git] / src / main / java / jp / sfjp / jindolf / Controller.java
@@ -5,7 +5,7 @@
  * Copyright(c) 2008 olyutorskii
  */
 
-package jp.sourceforge.jindolf;
+package jp.sfjp.jindolf;
 
 import java.awt.BorderLayout;
 import java.awt.Component;
@@ -55,8 +55,47 @@ import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
 import javax.swing.event.TreeWillExpandListener;
 import javax.swing.tree.TreePath;
+import jp.sfjp.jindolf.config.AppSetting;
+import jp.sfjp.jindolf.config.ConfigStore;
+import jp.sfjp.jindolf.config.OptionInfo;
+import jp.sfjp.jindolf.data.Anchor;
+import jp.sfjp.jindolf.data.DialogPref;
+import jp.sfjp.jindolf.data.Land;
+import jp.sfjp.jindolf.data.LandsModel;
+import jp.sfjp.jindolf.data.Period;
+import jp.sfjp.jindolf.data.RegexPattern;
+import jp.sfjp.jindolf.data.Talk;
+import jp.sfjp.jindolf.data.Village;
+import jp.sfjp.jindolf.dxchg.CsvExporter;
+import jp.sfjp.jindolf.dxchg.WebIPCDialog;
+import jp.sfjp.jindolf.editor.TalkPreview;
+import jp.sfjp.jindolf.glyph.AnchorHitEvent;
+import jp.sfjp.jindolf.glyph.AnchorHitListener;
+import jp.sfjp.jindolf.glyph.Discussion;
+import jp.sfjp.jindolf.glyph.FontInfo;
+import jp.sfjp.jindolf.glyph.TalkDraw;
+import jp.sfjp.jindolf.log.LogFrame;
+import jp.sfjp.jindolf.log.LogUtils;
+import jp.sfjp.jindolf.log.LogWrapper;
+import jp.sfjp.jindolf.net.ProxyInfo;
+import jp.sfjp.jindolf.net.ServerAccess;
+import jp.sfjp.jindolf.summary.DaySummary;
+import jp.sfjp.jindolf.summary.VillageDigest;
+import jp.sfjp.jindolf.util.GUIUtils;
+import jp.sfjp.jindolf.util.StringUtils;
+import jp.sfjp.jindolf.view.AccountPanel;
+import jp.sfjp.jindolf.view.ActionManager;
+import jp.sfjp.jindolf.view.FilterPanel;
+import jp.sfjp.jindolf.view.FindPanel;
+import jp.sfjp.jindolf.view.HelpFrame;
+import jp.sfjp.jindolf.view.LandsTree;
+import jp.sfjp.jindolf.view.OptionPanel;
+import jp.sfjp.jindolf.view.PeriodView;
+import jp.sfjp.jindolf.view.TabBrowser;
+import jp.sfjp.jindolf.view.TopView;
 import jp.sourceforge.jindolf.corelib.LandDef;
 import jp.sourceforge.jindolf.corelib.VillageState;
+import jp.sourceforge.jovsonz.JsObject;
 
 /**
  * いわゆるMVCでいうとこのコントローラ。
@@ -68,6 +107,29 @@ public class Controller
                    ChangeListener,
                    AnchorHitListener {
 
+    private static final String TITLE_LOGGER =
+            VerInfo.getFrameTitle("ログ表示");
+    private static final String TITLE_FILTER =
+            VerInfo.getFrameTitle("発言フィルタ");
+    private static final String TITLE_EDITOR =
+            VerInfo.getFrameTitle("発言エディタ");
+    private static final String TITLE_OPTION =
+            VerInfo.getFrameTitle("オプション設定");
+    private static final String TITLE_FIND =
+            VerInfo.getFrameTitle("発言検索");
+    private static final String TITLE_ACCOUNT =
+            VerInfo.getFrameTitle("アカウント管理");
+    private static final String TITLE_DIGEST =
+            VerInfo.getFrameTitle("村のダイジェスト");
+    private static final String TITLE_DAYSUMMARY =
+            VerInfo.getFrameTitle("発言集計");
+    private static final String TITLE_HELP =
+            VerInfo.getFrameTitle("ヘルプ");
+
+    private static final LogWrapper LOGGER = new LogWrapper();
+
+
+    private final AppSetting appSetting;
     private final ActionManager actionManager;
     private final TopView topView;
     private final LandsModel model;
@@ -90,15 +152,19 @@ public class Controller
 
     /**
      * コントローラの生成。
+     * @param setting アプリ設定
      * @param actionManager アクション管理
      * @param topView 最上位ビュー
      * @param model 最上位データモデル
      */
-    public Controller(ActionManager actionManager,
+    @SuppressWarnings("LeakingThisInConstructor")
+    public Controller(AppSetting setting,
+                       ActionManager actionManager,
                        TopView topView,
                        LandsModel model){
         super();
 
+        this.appSetting = setting;
         this.actionManager = actionManager;
         this.topView = topView;
         this.model = model;
@@ -124,43 +190,37 @@ public class Controller
         reloadVillageListButton.setEnabled(false);
 
         this.filterFrame = new FilterPanel(this.topFrame);
+        this.filterFrame.setTitle(TITLE_FILTER);
         this.filterFrame.addChangeListener(this);
         this.filterFrame.pack();
         this.filterFrame.setVisible(false);
 
         this.showlogFrame = new LogFrame(this.topFrame);
+        this.showlogFrame.setTitle(TITLE_LOGGER);
         this.showlogFrame.pack();
         this.showlogFrame.setSize(600, 500);
         this.showlogFrame.setLocationByPlatform(true);
         this.showlogFrame.setVisible(false);
-        if(Jindolf.hasLoggingPermission()){
-            Handler newHandler = this.showlogFrame.getHandler();
-            Logger jre14Logger = Jindolf.logger().getJre14Logger();
-            jre14Logger.addHandler(newHandler);
-            Handler[] handlers = jre14Logger.getHandlers();
-            for(Handler handler : handlers){
-                if( ! (handler instanceof PileHandler) ) continue;
-                PileHandler pile = (PileHandler) handler;
-                pile.delegate(newHandler);
-                pile.close();
-            }
-        }
+        Logger rootLogger = Logger.getLogger("");
+        Handler newHandler = this.showlogFrame.getHandler();
+        LogUtils.switchHandler(rootLogger, newHandler);
 
         this.talkPreview = new TalkPreview();
+        this.talkPreview.setTitle(TITLE_EDITOR);
         this.talkPreview.pack();
         this.talkPreview.setSize(700, 500);
         this.talkPreview.setVisible(false);
-        this.talkPreview.loadDraft();
 
         this.optionPanel = new OptionPanel(this.topFrame);
+        this.optionPanel.setTitle(TITLE_OPTION);
         this.optionPanel.pack();
         this.optionPanel.setSize(450, 500);
         this.optionPanel.setVisible(false);
 
         this.findPanel = new FindPanel(this.topFrame);
+        this.findPanel.setTitle(TITLE_FIND);
         this.findPanel.pack();
         this.findPanel.setVisible(false);
-        this.findPanel.loadHistory();
 
         this.windowMap.put(this.filterFrame,  true);
         this.windowMap.put(this.showlogFrame, false);
@@ -168,17 +228,23 @@ public class Controller
         this.windowMap.put(this.optionPanel,  false);
         this.windowMap.put(this.findPanel,    true);
 
-        AppSetting setting = Jindolf.getAppSetting();
+        ConfigStore config = this.appSetting.getConfigStore();
+
+        JsObject draft = config.loadDraftConfig();
+        this.talkPreview.putJson(draft);
 
-        FontInfo fontInfo = setting.getFontInfo();
+        JsObject history = config.loadHistoryConfig();
+        this.findPanel.putJson(history);
+
+        FontInfo fontInfo = this.appSetting.getFontInfo();
         this.topView.getTabBrowser().setFontInfo(fontInfo);
         this.talkPreview.setFontInfo(fontInfo);
         this.optionPanel.getFontChooser().setFontInfo(fontInfo);
 
-        ProxyInfo proxyInfo = setting.getProxyInfo();
+        ProxyInfo proxyInfo = this.appSetting.getProxyInfo();
         this.optionPanel.getProxyChooser().setProxyInfo(proxyInfo);
 
-        DialogPref pref = setting.getDialogPref();
+        DialogPref pref = this.appSetting.getDialogPref();
         this.topView.getTabBrowser().setDialogPref(pref);
         this.optionPanel.getDialogPrefPanel().setDialogPref(pref);
 
@@ -224,24 +290,14 @@ public class Controller
      * About画面を表示する。
      */
     private void actionAbout(){
-        String message =
-                Jindolf.TITLE
-                + "   Version " + Jindolf.VERSION + "\n"
-                + Jindolf.COPYRIGHT + "\n"
-                + "ライセンス: " + Jindolf.LICENSE + "\n"
-                + "連絡先: " + Jindolf.CONTACT;
-
-        if(Jindolf.COMMENT.length() > 0){
-            message += "\n" + Jindolf.COMMENT;
-        }
-
+        String message = VerInfo.getAboutMessage();
         JOptionPane pane = new JOptionPane(message,
                                            JOptionPane.INFORMATION_MESSAGE,
                                            JOptionPane.DEFAULT_OPTION,
                                            GUIUtils.getLogoIcon());
 
         JDialog dialog = pane.createDialog(this.topFrame,
-                                           Jindolf.TITLE + "について");
+                                           VerInfo.TITLE + "について");
 
         dialog.pack();
         dialog.setVisible(true);
@@ -267,7 +323,11 @@ public class Controller
             return;
         }
 
-        this.helpFrame = new HelpFrame();
+        OptionInfo optInfo = this.appSetting.getOptionInfo();
+        ConfigStore configStore = this.appSetting.getConfigStore();
+
+        this.helpFrame = new HelpFrame(optInfo, configStore);
+        this.helpFrame.setTitle(TITLE_HELP);
         this.helpFrame.pack();
         this.helpFrame.setSize(450, 450);
 
@@ -420,7 +480,7 @@ public class Controller
      * ポータルサイトをWebブラウザで表示する。
      */
     private void actionShowPortal(){
-        WebIPCDialog.showDialog(this.topFrame, Jindolf.CONTACT);
+        WebIPCDialog.showDialog(this.topFrame, VerInfo.CONTACT);
         return;
     }
 
@@ -431,11 +491,11 @@ public class Controller
      * @param e 例外
      */
     private void warnDialog(String title, String message, Throwable e){
-        Jindolf.logger().warn(message, e);
+        LOGGER.warn(message, e);
         JOptionPane.showMessageDialog(
             this.topFrame,
             message,
-            title + " - " + Jindolf.TITLE,
+            VerInfo.getFrameTitle(title),
             JOptionPane.WARNING_MESSAGE );
         return;
     }
@@ -481,7 +541,7 @@ public class Controller
             return;
         }
 
-        Jindolf.logger().info(
+        LOGGER.info(
                 "Look&Feelが["
                 +lnf.getName()
                 +"]に変更されました。");
@@ -510,10 +570,10 @@ public class Controller
                 try{
                     SwingUtilities.invokeAndWait(updateUITask);
                 }catch(InvocationTargetException e){
-                    Jindolf.logger().warn(
+                    LOGGER.warn(
                             "Look&Feelの更新に失敗しました。", e);
                 }catch(InterruptedException e){
-                    Jindolf.logger().warn(
+                    LOGGER.warn(
                             "Look&Feelの更新に失敗しました。", e);
                 }finally{
                     updateStatusBar("Look&Feelが更新されました");
@@ -544,6 +604,7 @@ public class Controller
         }
 
         this.accountFrame = new AccountPanel(this.topFrame, this.model);
+        this.accountFrame.setTitle(TITLE_ACCOUNT);
         this.accountFrame.pack();
         this.accountFrame.setVisible(true);
 
@@ -572,15 +633,13 @@ public class Controller
      * オプション設定画面を表示する。
      */
     private void actionOption(){
-        AppSetting setting = Jindolf.getAppSetting();
-
-        FontInfo fontInfo = setting.getFontInfo();
+        FontInfo fontInfo = this.appSetting.getFontInfo();
         this.optionPanel.getFontChooser().setFontInfo(fontInfo);
 
-        ProxyInfo proxyInfo = setting.getProxyInfo();
+        ProxyInfo proxyInfo = this.appSetting.getProxyInfo();
         this.optionPanel.getProxyChooser().setProxyInfo(proxyInfo);
 
-        DialogPref dialogPref = setting.getDialogPref();
+        DialogPref dialogPref = this.appSetting.getDialogPref();
         this.optionPanel.getDialogPrefPanel().setDialogPref(dialogPref);
 
         this.optionPanel.setVisible(true);
@@ -603,11 +662,10 @@ public class Controller
      * @param newFontInfo 新フォント設定
      */
     private void updateFontInfo(final FontInfo newFontInfo){
-        AppSetting setting = Jindolf.getAppSetting();
-        FontInfo oldInfo = setting.getFontInfo();
+        FontInfo oldInfo = this.appSetting.getFontInfo();
 
         if(newFontInfo.equals(oldInfo)) return;
-        setting.setFontInfo(newFontInfo);
+        this.appSetting.setFontInfo(newFontInfo);
 
         this.topView.getTabBrowser().setFontInfo(newFontInfo);
         this.talkPreview.setFontInfo(newFontInfo);
@@ -621,11 +679,10 @@ public class Controller
      * @param newProxyInfo 新プロクシ設定
      */
     private void updateProxyInfo(ProxyInfo newProxyInfo){
-        AppSetting setting = Jindolf.getAppSetting();
-        ProxyInfo oldProxyInfo = setting.getProxyInfo();
+        ProxyInfo oldProxyInfo = this.appSetting.getProxyInfo();
 
         if(newProxyInfo.equals(oldProxyInfo)) return;
-        setting.setProxyInfo(newProxyInfo);
+        this.appSetting.setProxyInfo(newProxyInfo);
 
         for(Land land : this.model.getLandList()){
             ServerAccess server = land.getServerAccess();
@@ -640,11 +697,10 @@ public class Controller
      * @param newDialogPref 表示設定
      */
     private void updateDialogPref(DialogPref newDialogPref){
-        AppSetting setting = Jindolf.getAppSetting();
-        DialogPref oldDialogPref = setting.getDialogPref();
+        DialogPref oldDialogPref = this.appSetting.getDialogPref();
 
         if(newDialogPref.equals(oldDialogPref)) return;
-        setting.setDialogPref(newDialogPref);
+        this.appSetting.setDialogPref(newDialogPref);
 
         this.topView.getTabBrowser().setDialogPref(newDialogPref);
 
@@ -665,7 +721,7 @@ public class Controller
            ) || ! village.isValid() ){
             String message = "エピローグを正常に迎えていない村は\n"
                             +"ダイジェスト機能を利用できません";
-            String title = "ダイジェスト不可 - " + Jindolf.TITLE;
+            String title = VerInfo.getFrameTitle("ダイジェスト不可");
             JOptionPane pane = new JOptionPane(message,
                                                JOptionPane.WARNING_MESSAGE,
                                                JOptionPane.DEFAULT_OPTION );
@@ -678,6 +734,7 @@ public class Controller
 
         if(this.digestPanel == null){
             this.digestPanel = new VillageDigest(this.topFrame);
+            this.digestPanel.setTitle(TITLE_DIGEST);
             this.digestPanel.pack();
             this.digestPanel.setSize(600, 550);
             this.windowMap.put(this.digestPanel, false);
@@ -774,7 +831,7 @@ public class Controller
             }
         }
         loginfo += hitMessage;
-        Jindolf.logger().info(loginfo);
+        LOGGER.info(loginfo);
 
         return;
     }
@@ -825,7 +882,7 @@ public class Controller
             }
         }
         loginfo += hitMessage;
-        Jindolf.logger().info(loginfo);
+        LOGGER.info(loginfo);
 
         return;
     }
@@ -853,6 +910,7 @@ public class Controller
 
         if(this.daySummaryPanel == null){
             this.daySummaryPanel = new DaySummary(this.topFrame);
+            this.daySummaryPanel.setTitle(TITLE_DAYSUMMARY);
             this.daySummaryPanel.pack();
             this.daySummaryPanel.setSize(400, 500);
         }
@@ -1205,10 +1263,10 @@ public class Controller
                         }
                     });
                 }catch(InvocationTargetException e){
-                    Jindolf.logger().fatal(
+                    LOGGER.fatal(
                             "タブ操作で致命的な障害が発生しました", e);
                 }catch(InterruptedException e){
-                    Jindolf.logger().fatal(
+                    LOGGER.fatal(
                             "タブ操作で致命的な障害が発生しました", e);
                 }
                 updateStatusBar("村情報を読み直しました…");
@@ -1227,10 +1285,10 @@ public class Controller
                             }
                         });
                     }catch(InvocationTargetException e){
-                        Jindolf.logger().fatal(
+                        LOGGER.fatal(
                                 "ブラウザ表示で致命的な障害が発生しました", e);
                     }catch(InterruptedException e){
-                        Jindolf.logger().fatal(
+                        LOGGER.fatal(
                                 "ブラウザ表示で致命的な障害が発生しました", e);
                     }
                     EventQueue.invokeLater(new Runnable(){
@@ -1342,7 +1400,7 @@ public class Controller
      * @param e ネットワークエラー
      */
     public void showNetworkError(Land land, IOException e){
-        Jindolf.logger().warn("ネットワークで障害が発生しました", e);
+        LOGGER.warn("ネットワークで障害が発生しました", e);
 
         ServerAccess server = land.getServerAccess();
         String message =
@@ -1357,8 +1415,8 @@ public class Controller
                                            JOptionPane.WARNING_MESSAGE,
                                            JOptionPane.DEFAULT_OPTION );
 
-        JDialog dialog = pane.createDialog(this.topFrame,
-                                           "通信異常発生 - " + Jindolf.TITLE);
+        String title = VerInfo.getFrameTitle("通信異常発生");
+        JDialog dialog = pane.createDialog(this.topFrame, title);
 
         dialog.pack();
         dialog.setVisible(true);
@@ -1642,9 +1700,9 @@ public class Controller
             try{
                 SwingUtilities.invokeAndWait(microJob);
             }catch(InvocationTargetException e){
-                Jindolf.logger().fatal("ビジー処理で失敗", e);
+                LOGGER.fatal("ビジー処理で失敗", e);
             }catch(InterruptedException e){
-                Jindolf.logger().fatal("ビジー処理で失敗", e);
+                LOGGER.fatal("ビジー処理で失敗", e);
             }
         }
 
@@ -1664,15 +1722,9 @@ public class Controller
      * タイトルは指定された国or村名 + " - Jindolf"
      * @param name 国or村名
      */
-    private void setFrameTitle(CharSequence name){
-        String title = Jindolf.TITLE;
-
-        if(name != null && name.length() > 0){
-            title = name + " - " + title;
-        }
-
+    private void setFrameTitle(String name){
+        String title = VerInfo.getFrameTitle(name);
         this.topFrame.setTitle(title);
-
         return;
     }
 
@@ -1680,10 +1732,24 @@ public class Controller
      * アプリ正常終了処理。
      */
     private void shutdown(){
-        this.findPanel.saveHistory();
-        this.talkPreview.saveDraft();
-        Jindolf.getAppSetting().saveConfig();
-        Jindolf.exit(0);
+        ConfigStore configStore = this.appSetting.getConfigStore();
+
+        JsObject findConf = this.findPanel.getJson();
+        if( ! this.findPanel.hasConfChanged(findConf) ){
+            configStore.saveHistoryConfig(findConf);
+        }
+
+        JsObject draftConf = this.talkPreview.getJson();
+        if( ! this.talkPreview.hasConfChanged(draftConf) ){
+            configStore.saveDraftConfig(draftConf);
+        }
+
+        this.appSetting.saveConfig();
+
+        LOGGER.info("VMごとアプリケーションを終了します。");
+        System.exit(0);  // invoke shutdown hooks... BYE !
+
+        assert false;
         return;
     }