OSDN Git Service

中国語リソースとフォント対応
[charactermanaj/CharacterManaJ.git] / src / charactermanaj / model / AppConfig.java
1 package charactermanaj.model;
2
3 import java.awt.Color;
4 import java.io.BufferedOutputStream;
5 import java.io.File;
6 import java.io.FileNotFoundException;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.io.OutputStream;
11 import java.net.URI;
12 import java.net.URL;
13 import java.nio.charset.Charset;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Locale;
17 import java.util.Properties;
18 import java.util.Set;
19 import java.util.logging.Level;
20 import java.util.logging.Logger;
21 import java.util.regex.Pattern;
22
23 import charactermanaj.util.ApplicationLogHandler;
24 import charactermanaj.util.BeanPropertiesUtilities;
25 import charactermanaj.util.ConfigurationDirUtilities;
26
27 /**
28  * アプリケーションの全域にわたる設定.<br>
29  * アプリケーション設定は、クラスパス上のリソース、コートベース直下のappConfig.xml、ユーザーごとのappConfig.xmlの順に読み込まれます
30  * .<br>
31  *
32  * @author seraphy
33  */
34 public final class AppConfig {
35
36         /**
37          * アプリケーション設定ファイルの名前
38          */
39         private static final String CONFIG_NAME = "appConfig.xml";
40
41         /**
42          * 全ユーザー用キャラクターディレクトリのシステムプロパティのキー名.<br>
43          */
44         public static final String COMMON_CHARACTER_DIR_PROPERTY_NAME = "character.dir";
45
46         /**
47          * 開発用仕様バージョン番号
48          */
49         private static final String DEFAULT_SPECIFICATION_VERSION = "1.0";
50
51
52         /**
53          * ロガー
54          */
55         private static final Logger logger = Logger.getLogger(AppConfig.class.getName());
56
57
58         /**
59          * シングルトンインスタンス
60          */
61         private static final AppConfig singleton = new AppConfig();
62
63
64         /**
65          * インスタンスを取得する.
66          *
67          * @return インスタンス
68          */
69         public static AppConfig getInstance() {
70                 return singleton;
71         }
72
73         /**
74          * プライベートコンストラクタ
75          */
76         private AppConfig() {
77                 loadAppVersions();
78         }
79
80         private String implementationVersion;
81
82         private String specificationVersion;
83
84         /**
85          * 実装バージョンを取得する.<br>
86          * ビルドされたjarパッケージからバージョン情報を取得する.<br>
87          * クラスパスの実行からのバージョンは常に「develop」となる.<br>
88          *
89          * @return 実装バージョン
90          */
91         public String getImplementationVersion() {
92                 return implementationVersion;
93         }
94
95         /**
96          * 仕様バージョンを取得する.<br>
97          * ビルドされたjarパッケージからバージョン情報を取得する.<br>
98          * クラスパスの実行からのバージョンは常に「develop」となる.<br>
99          *
100          * @return 仕様バージョン
101          */
102         public String getSpecificationVersion() {
103                 return specificationVersion;
104         }
105
106         /**
107          * ビルドされたjarパッケージからバージョン情報を取得する.<br>
108          * クラスパスの実行からのバージョンは常に「develop」となる.<br>
109          */
110         private void loadAppVersions() {
111                 Package pak = this.getClass().getPackage();
112                 String implementationVersion = "develop";
113                 String specificationVersion = DEFAULT_SPECIFICATION_VERSION;
114                 if (pak != null) {
115                         String vInfo = pak.getImplementationVersion();
116                         if (vInfo != null && implementationVersion.trim().length() > 0) {
117                                 implementationVersion = vInfo.trim();
118                         }
119                         String specVInfo = pak.getSpecificationVersion();
120                         if (specVInfo != null && specVInfo.trim().length() > 0) {
121                                 specificationVersion = specVInfo.trim();
122                         }
123                 }
124
125                 this.implementationVersion = implementationVersion;
126                 this.specificationVersion = specificationVersion;
127         }
128
129         /**
130          * 設定ファイルのロケール固有版へのファイル末尾の修飾文字列を読み込み順に取得する.
131          * @param locale ロケール、nullの場合はデフォルト
132          * @return ロケールを表すファイル末尾の修飾文字列の読み込み順のリスト
133          */
134         private String[] getLocalizedSuffix(Locale locale) {
135                 if (locale == null) {
136                         locale = Locale.getDefault();
137                 }
138
139                 String language = locale.getLanguage();
140                 String country = locale.getCountry();
141                 String variant = locale.getVariant();
142                 
143                 return new String[] {
144                         "",
145                         "_" + language,
146                         "_" + language + "_" + country,
147                         "_" + language + "_" + country + "_" + variant,
148                 };
149         }
150
151         /**
152          * 指定されたファイル名の拡張子の前にロケール固有の修飾文字列を付与したリスト作成して返す.
153          * @param base ファイル名
154          * @param locale ロケール、nullの場合はデフォルト
155          * @return ロケールの検索順序でのロケール固有の修飾文字列が付与されたファイルのリスト
156          */
157         private List<File> expandLocalizedSuffix(File base, Locale locale) {
158                 String path = base.getPath();
159
160                 int pt = path.lastIndexOf(".");
161                 String left, right;
162                 if (pt >= 0) {
163                         left = path.substring(0, pt);
164                         right = path.substring(pt);
165
166                 } else {
167                         left = path;
168                         right = "";
169                 }
170                 
171                 ArrayList<File> files = new ArrayList<File>();
172                 for (String suffix : getLocalizedSuffix(locale)) {
173                         String newPath = left + suffix + right;
174                         System.out.println("newpath=" + newPath);
175                         files.add(new File(newPath));
176                 }
177                 return files;
178         }
179
180         /**
181          * 設定ファイルの読み込み順序で、読み込むべきURIのリストを返す.<br>
182          * <ul>
183          * <li>(1) リソース上の/appConfig.xml</li>
184          * <li>(2) appConfigFileシステムプロパティで指定されたファイル</li>
185          * <li>(3) コードベース下のappConfig.xml</li>
186          * <li>(4) アプリケーションデータ保存先のappConfig.xml</li>
187          * </ul>
188          * appConfigFileシステムプロパティがある場合は、(1)(2)の順。 <br>
189          * 指定がない場合は、(1)(3)(4)の順に読み取る.<br>
190          *
191          * @return 優先順位での設定ファイルの読み込み先URIのリスト
192          * @throws IOException
193          */
194         public List<URI> getCandidateURIs() throws IOException {
195                 List<URI> uris = new ArrayList<URI>();
196                 // リソース中の既定 (ロケール識別あり)
197                 for (File localizedFile : expandLocalizedSuffix(new File(getClass()
198                                 .getResource("/" + CONFIG_NAME).getPath()), null)) {
199                         uris.add(localizedFile.toURI());
200                 }
201
202                 String specifiedAppConfig = System.getProperty("appConfigFile");
203                 if (specifiedAppConfig != null) {
204                         // システムプロパティでappConfig.xmlを明示している場合は、それを読み込む。
205                         // (appConfigFileシステムプロパティが空の場合は、リソース埋め込みの既定の設定だけをよみこむ)
206                         if (specifiedAppConfig.trim().length() > 0) {
207                                 File specifiedAppConfigFile = new File(specifiedAppConfig);
208                                 uris.add(specifiedAppConfigFile.toURI());
209                         }
210
211                 } else {
212                         // システムプロパティて明示していない場合は、まずコードベースを使用する.(ロケール識別あり)
213                         File codeBase = ConfigurationDirUtilities.getApplicationBaseDir();
214                         for (File localizedFile : expandLocalizedSuffix(new File(codeBase,
215                                         CONFIG_NAME).getCanonicalFile(), null)) {
216                                 uris.add(localizedFile.toURI());
217                         }
218
219                         // システムプロパティて明示していない場合は、次にユーザディレクトリを使用する.
220                         File userDataDir = ConfigurationDirUtilities.getUserDataDir();
221                         uris.add(new File(userDataDir, CONFIG_NAME).toURI());
222                 }
223                 return uris;
224         }
225
226         /**
227          * 保存先の試行順序ごとのファイルのリスト。
228          *
229          * @return 保存先(優先順)
230          */
231         public List<File> getPrioritySaveFileList() {
232                 ArrayList<File> saveFiles = new ArrayList<File>();
233
234                 String specifiedAppConfig = System.getProperty("appConfigFile");
235                 if (specifiedAppConfig != null) {
236                         // システムプロパティでappConfig.xmlを明示している場合
237                         if (specifiedAppConfig.trim().length() > 0) {
238                                 File specifiedAppConfigFile = new File(specifiedAppConfig);
239                                 if (!specifiedAppConfigFile.exists()
240                                                 || specifiedAppConfigFile.canWrite()) {
241                                         // まだ存在しないか、書き込み可能である場合のみ候補とする.
242                                         saveFiles.add(specifiedAppConfigFile);
243                                 }
244                         }
245                 } else {
246                         // システムプロパティappConfigFileがなければユーザディレクトリへ書き込む
247                         // ユーザディレクトリは常に候補とする.
248                         File userDataDir = ConfigurationDirUtilities.getUserDataDir();
249                         saveFiles.add(new File(userDataDir, CONFIG_NAME));
250                 }
251
252                 return saveFiles;
253         }
254
255         /**
256          * プロパティをロードする.<br>
257          * 存在しないか、読み取りに失敗した場合は、該当ファイルはスキップされる.<br>
258          */
259         public void loadConfig() {
260                 Properties config = new Properties();
261                 try {
262                         for (URI uri : getCandidateURIs()) {
263                                 if (uri == null) {
264                                         continue; // リソースがない場合はnullになる
265                                 }
266                                 // ファイルの実在チェック (チェックできる場合のみ)
267                                 if ("file".equals(uri.getScheme())) {
268                                         File file = new File(uri);
269                                         if (!file.exists()) {
270                                                 logger.log(Level.CONFIG, "appConfig.xml is not found.:" + file);
271                                                 continue;
272                                         }
273                                 }
274                                 // appConfig.xmlの読み込みを行う.
275                                 // Properties#loadFromXML() はXMLからキーを読み取り、既存のキーに対して上書きする.
276                                 // XMLに存在しないキーは読み込み前のままなので、繰り返し呼び出すことで「重ね合わせ」することができる.
277                                 try {
278                                         URL resourceURL = uri.toURL();
279                                         InputStream is = resourceURL.openStream();
280                                         try {
281                                                 config.loadFromXML(is);
282                                                 logger.log(Level.CONFIG, "appConfig.xml is loaded.:" + uri);
283                                         } finally {
284                                                 is.close();
285                                         }
286
287                                 } catch (FileNotFoundException ex) {
288                                         logger.log(Level.CONFIG, "appConfig.xml is not found.: " + uri, ex);
289                                         // 無視する (無い場合は十分にありえるので「情報」レベルでログ。)
290                                 } catch (Exception ex) {
291                                         logger.log(Level.WARNING, "appConfig.xml loading failed.: " + uri, ex);
292                                         // 無視する
293                                 }
294                         }
295
296                 } catch (IOException ex) {
297                         throw new RuntimeException("appConfig.xml loading failed.", ex);
298                 } catch (RuntimeException ex) {
299                         throw new RuntimeException("appConfig.xml loading failed.", ex);
300                 }
301                 BeanPropertiesUtilities.loadFromProperties(this, config);
302         }
303
304         /**
305          * プロパティをアプリケーションデータの指定した保存先に保存する.
306          *
307          * @throws IOException
308          *             保存に失敗した場合
309          */
310         public void saveConfig(List<File> prioritySaveFiles) throws IOException {
311                 Properties config = getProperties();
312                 IOException oex = null;
313                 for (File configStore : prioritySaveFiles) {
314                         try {
315                                 OutputStream os = new BufferedOutputStream(
316                                                 new FileOutputStream(configStore));
317                                 try {
318                                         config.storeToXML(os, CONFIG_NAME, "UTF-8");
319                                         return; // 成功した時点で終了
320
321                                 } finally {
322                                         os.close();
323                                 }
324
325                         } catch (IOException ex) {
326                                 logger.log(Level.WARNING, "アプリケーション設定の保存に失敗しました" + ex, ex);
327                                 oex = ex;
328                         }
329                 }
330
331                 // 例外が発生していれば、最後の例外を返す.
332                 if (oex != null) {
333                         throw oex;
334                 }
335         }
336
337         /**
338          * プロパティをアプリケーションデータの保存先に保存する.
339          *
340          * @throws IOException
341          *             保存に失敗した場合
342          */
343         public void saveConfig() throws IOException {
344                 saveConfig(getPrioritySaveFileList());
345         }
346
347         /**
348          * Propertiesの値を設定した場合に設定できない項目があるかチェックする.<br>
349          * このメソッドを呼び出しても、アプリケーション設定自身は何も影響されない.<br>
350          *
351          * @param props
352          *            適用するプロパティ
353          * @return 設定できなかったプロパティキーのコレクション、問題なければ空が返される.
354          */
355         public static Set<String> checkProperties(Properties props) {
356                 if (props == null) {
357                         throw new IllegalArgumentException();
358                 }
359                 AppConfig dummy = new AppConfig(); // アプリケーションから参照されないダミーのインスタンスを作成する.
360                 return BeanPropertiesUtilities.loadFromProperties(dummy, props);
361         }
362
363         /**
364          * Propertiesの値で設定を更新する.<br>
365          *
366          * @param props
367          *            適用するプロパティ
368          * @return 設定できなかったプロパティキーのコレクション、問題なければ空が返される.
369          */
370         public Set<String> update(Properties props) {
371                 if (props == null) {
372                         throw new IllegalArgumentException();
373                 }
374                 return BeanPropertiesUtilities.loadFromProperties(this, props);
375         }
376
377         /**
378          * このアプリケーション設定をプロパティに書き出して返します.<br>
379          *
380          * @return プロパティ
381          */
382         public Properties getProperties() {
383                 Properties config = new Properties();
384                 BeanPropertiesUtilities.saveToProperties(this, config);
385                 return config;
386         }
387
388
389         /**
390          * プロファイル選択ダイアログのプロファイルのサンプルイメージの背景色
391          *
392          * @return サンプルイメージの背景色
393          */
394         public Color getSampleImageBgColor() {
395                 return sampleImageBgColor;
396         }
397
398         public void setSampleImageBgColor(Color sampleImageBgColor) {
399                 if (sampleImageBgColor == null) {
400                         throw new IllegalArgumentException();
401                 }
402                 this.sampleImageBgColor = sampleImageBgColor;
403         }
404
405         private Color sampleImageBgColor = Color.white;
406
407
408         /**
409          * デフォルトのイメージ背景色を取得する.
410          *
411          * @return デフォルトのイメージ背景色
412          */
413         public Color getDefaultImageBgColor() {
414                 return defaultImageBgColor;
415         }
416
417         public void setDefaultImageBgColor(Color defaultImageBgColor) {
418                 if (defaultImageBgColor == null) {
419                         throw new IllegalArgumentException();
420                 }
421                 this.defaultImageBgColor = defaultImageBgColor;
422         }
423
424         private Color defaultImageBgColor = Color.white;
425
426         /**
427          * 使用中アイテムの背景色を取得する.
428          *
429          * @return 使用中アイテムの背景色
430          */
431         public Color getCheckedItemBgColor() {
432                 return checkedItemBgColor;
433         }
434
435         public void setCheckedItemBgColor(Color checkedItemBgColor) {
436                 if (checkedItemBgColor == null) {
437                         throw new IllegalArgumentException();
438                 }
439                 this.checkedItemBgColor = checkedItemBgColor;
440         }
441
442         private Color checkedItemBgColor = Color.cyan.brighter();
443
444
445         /**
446          *  選択アイテムの背景色を取得する
447          *
448          * @return 選択アイテムの背景色
449          */
450         public Color getSelectedItemBgColor() {
451                 return selectedItemBgColor;
452         }
453
454         public void setSelectedItemBgColor(Color selectedItemBgColor) {
455                 this.selectedItemBgColor = selectedItemBgColor;
456         }
457
458         private Color selectedItemBgColor = Color.orange;
459
460         /**
461          * 不備のあるデータ行の背景色を取得する.
462          *
463          * @return 不備のあるデータ行の背景色
464          */
465         public Color getInvalidBgColor() {
466                 return invalidBgColor;
467         }
468
469         public void setInvalidBgColor(Color invalidBgColor) {
470                 if (invalidBgColor == null) {
471                         throw new IllegalArgumentException();
472                 }
473                 this.invalidBgColor = invalidBgColor;
474         }
475
476         private Color invalidBgColor = Color.red.brighter().brighter();
477
478         /**
479          * JPEG画像変換時の圧縮率を取得する.
480          *
481          * @return 圧縮率
482          */
483         public float getCompressionQuality() {
484                 return compressionQuality;
485         }
486
487         public void setCompressionQuality(float compressionQuality) {
488                 if (compressionQuality < .1f || compressionQuality > 1f) {
489                         throw new IllegalArgumentException();
490                 }
491                 this.compressionQuality = compressionQuality;
492         }
493
494         private float compressionQuality = .8f;
495
496         /**
497          * エクスポートウィザードのプリセットにパーツ不足時の警告色(前景色)を取得する.
498          *
499          * @return エクスポートウィザードのプリセットにパーツ不足時の警告色(前景色)
500          */
501         public Color getExportPresetWarningsForegroundColor() {
502                 return exportPresetWarningsForegroundColor;
503         }
504
505         public void setExportPresetWarningsForegroundColor(
506                         Color exportPresetWarningsForegroundColor) {
507                 this.exportPresetWarningsForegroundColor = exportPresetWarningsForegroundColor;
508         }
509
510         private Color exportPresetWarningsForegroundColor = Color.red;
511
512         /**
513          * JARファイル転送用バッファサイズ.<br>
514          *
515          * @return JARファイル転送用バッファサイズ.
516          */
517         public int getJarTransferBufferSize() {
518                 return jarTransferBufferSize;
519         }
520
521         public void setJarTransferBufferSize(int jarTransferBufferSize) {
522                 if (jarTransferBufferSize <= 0) {
523                         throw new IllegalArgumentException();
524                 }
525                 this.jarTransferBufferSize = jarTransferBufferSize;
526         }
527
528         private int jarTransferBufferSize = 4096;
529
530         /**
531          * ZIPファイル名のエンコーディング.<br>
532          *
533          * @return ZIPファイル名のエンコーディング.<br>
534          */
535         public String getZipNameEncoding() {
536                 return zipNameEncoding;
537         }
538
539         public void setZipNameEncoding(String zipNameEncoding) {
540                 if (zipNameEncoding == null) {
541                         throw new IllegalArgumentException();
542                 }
543                 try {
544                         Charset.forName(zipNameEncoding);
545                 } catch (Exception ex) {
546                         throw new RuntimeException("unsupported charset: " + zipNameEncoding);
547                 }
548                 this.zipNameEncoding = zipNameEncoding;
549         }
550
551         private String zipNameEncoding = "csWindows31J";
552
553         /**
554          * ディセーブルなテーブルのセルのフォアグラウンドカラーを取得する.
555          *
556          * @return ディセーブルなテーブルのセルのフォアグラウンドカラー
557          */
558         public Color getDisabledCellForgroundColor() {
559                 return disabledCellForegroundColor;
560         }
561
562         public void setDisabledCellForegroundColor(Color disabledCellForegroundColor) {
563                 if (disabledCellForegroundColor == null) {
564                         throw new IllegalArgumentException();
565                 }
566                 this.disabledCellForegroundColor = disabledCellForegroundColor;
567         }
568
569         private Color disabledCellForegroundColor = Color.gray;
570
571
572         /**
573          * ディレクトリを監視する間隔(mSec)を取得する.
574          *
575          * @return ディレクトリを監視する間隔(mSec)
576          */
577         public int getDirWatchInterval() {
578                 return dirWatchInterval;
579         }
580
581         public void setDirWatchInterval(int dirWatchInterval) {
582                 if (dirWatchInterval <= 0) {
583                         throw new IllegalArgumentException();
584                 }
585                 this.dirWatchInterval = dirWatchInterval;
586         }
587
588         private int dirWatchInterval = 7 * 1000;
589
590         /**
591          * ディレクトリの監視を有効にするか?
592          *
593          * @return ディレクトリの監視を有効にする場合はtrue
594          */
595         public boolean isEnableDirWatch() {
596                 return enableDirWatch;
597         }
598
599         public void setEnableDirWatch(boolean enableDirWatch) {
600                 this.enableDirWatch = enableDirWatch;
601         }
602
603         private boolean enableDirWatch = true;
604
605         /**
606          * ファイル転送に使うバッファサイズ.<br>
607          *
608          * @return バッファサイズ
609          */
610         public int getFileTransferBufferSize() {
611                 return fileTransferBufferSize;
612         }
613
614         public void setFileTransferBufferSize(int fileTransferBufferSize) {
615                 if (fileTransferBufferSize <= 0) {
616                         throw new IllegalArgumentException();
617                 }
618                 this.fileTransferBufferSize = fileTransferBufferSize;
619         }
620
621         private int fileTransferBufferSize = 4096;
622
623         /**
624          * プレビューのインジケータを表示するまでのディレイ(mSec)を取得する.
625          *
626          * @return プレビューのインジケータを表示するまでのディレイ(mSec)
627          */
628         public long getPreviewIndicatorDelay() {
629                 return previewIndeicatorDelay;
630         }
631
632         public void setPreviewIndeicatorDelay(long previewIndeicatorDelay) {
633                 if (previewIndeicatorDelay < 0) {
634                         throw new IllegalArgumentException();
635                 }
636                 this.previewIndeicatorDelay = previewIndeicatorDelay;
637         }
638
639         private long previewIndeicatorDelay = 300;
640
641         /**
642          * 情報ダイアログの編集ボタンを「開く」アクションにする場合はtrue、「編集」アクションにする場合はfalse
643          *
644          * @return trueならばOpen、falseならばEdit
645          */
646         public boolean isInformationDialogOpenMethod() {
647                 return informationDialogOpenMethod;
648         }
649
650         public void setInformationDialogOpenMethod(
651                         boolean informationDialogOpenMethod) {
652                 this.informationDialogOpenMethod = informationDialogOpenMethod;
653         }
654
655         private boolean informationDialogOpenMethod = true;
656
657         /**
658          * ログを常に残すか?<br>
659          * falseの場合は{@link ApplicationLogHandler}の実装に従って終了時に 必要なければログは削除される.<br>
660          *
661          * @return 常に残す場合はtrue、そうでなければfalse
662          */
663         public boolean isNoRemoveLog() {
664                 return noRemoveLog;
665         }
666
667         public void setNoRemoveLog(boolean noRemoveLog) {
668                 this.noRemoveLog = noRemoveLog;
669         }
670
671         private boolean noRemoveLog = false;
672
673
674         /**
675          * テーブルのグリッド色.<br>
676          *
677          * @return テーブルのグリッド色
678          */
679         public Color getGridColor() {
680                 return gridColor;
681         }
682
683         public void setGridColor(Color gridColor) {
684                 if (gridColor == null) {
685                         throw new IllegalArgumentException();
686                 }
687                 this.gridColor = gridColor;
688         }
689
690         private Color gridColor = Color.gray;
691
692         /**
693          * カラーダイアログの値が変更されたら、自動的にプレビューを更新するか?
694          *
695          * @return カラーダイアログの値が変更されたら、自動的にプレビューを更新する場合はtrue (デフォルトはtrue)
696          */
697         public boolean isEnableAutoColorChange() {
698                 return enableAutoColorChange;
699         }
700
701         public void setEnableAutoColorChange(boolean enableAutoColorChange) {
702                 this.enableAutoColorChange = enableAutoColorChange;
703         }
704
705         private boolean enableAutoColorChange = true;
706
707         public void setAuthorEditConflictBgColor(Color authorEditConflictBgColor) {
708                 if (authorEditConflictBgColor == null) {
709                         throw new IllegalArgumentException();
710                 }
711                 this.authorEditConflictBgColor = authorEditConflictBgColor;
712         }
713
714         /**
715          * パーツの作者編集時に複数作者を選択した場合のに入力ボックスの背景色
716          *
717          * @return 背景色
718          */
719         public Color getAuthorEditConflictBgColor() {
720                 return authorEditConflictBgColor;
721         }
722
723         Color authorEditConflictBgColor = Color.yellow;
724
725
726         public void setMainFrameMaxWidth(int width) {
727                 this.mainFrameMaxWidth = width;
728         }
729
730         /**
731          * メインフレームの初期表示時の最大幅
732          *
733          * @return メインフレームの初期表示時の最大幅
734          */
735         public int getMainFrameMaxWidth() {
736                 return mainFrameMaxWidth;
737         }
738
739         private int mainFrameMaxWidth = 800;
740
741         public void setMainFrameMaxHeight(int height) {
742                 this.mainFrameMaxHeight = height;
743         }
744
745         /**
746          * メインフレームの初期表示時の最大高さ
747          *
748          * @return メインフレームの初期表示時の最大高さ
749          */
750         public int getMainFrameMaxHeight() {
751                 return mainFrameMaxHeight;
752         }
753
754         private int mainFrameMaxHeight = 600;
755
756
757         /**
758          * カラーダイアログで存在しないレイヤーをディセーブルにしない.
759          *
760          * @return ディセーブルにしない場合はtrue
761          */
762         public boolean isNotDisableLayerTab() {
763                 return notDisableLayerTab;
764         }
765
766         public void setNotDisableLayerTab(boolean notDisableLayerTab) {
767                 this.notDisableLayerTab = notDisableLayerTab;
768         }
769
770         private boolean notDisableLayerTab;
771
772
773         /**
774          * ログを消去する日数.<br>
775          * この指定日を経過した古いログは削除される.<br>
776          * 0の場合は削除されない.
777          *
778          * @return
779          */
780         public long getPurgeLogDays() {
781                 return purgeLogDays;
782         }
783
784         public void setPurgeLogDays(long purgeLogDays) {
785                 this.purgeLogDays = purgeLogDays;
786         }
787
788         private long purgeLogDays = 10;
789
790         public String getPartsColorGroupPattern() {
791                 return partsColorGroupPattern;
792         }
793
794         public void setPartsColorGroupPattern(String pattern) {
795                 if (pattern != null && pattern.trim().length() > 0) {
796                         Pattern.compile(pattern);
797                 }
798                 partsColorGroupPattern = pattern;
799         }
800
801         private String partsColorGroupPattern = "^.*\\(@\\).*$";
802
803         private Color selectPanelTitleColor = Color.BLUE;
804
805         public Color getSelectPanelTitleColor() {
806                 return selectPanelTitleColor;
807         }
808
809         public void setSelectPanelTitleColor(Color color) {
810                 if (color == null) {
811                         throw new IllegalArgumentException();
812                 }
813                 selectPanelTitleColor = color;
814         }
815
816         private boolean enableAutoShrinkPanel;
817
818         public boolean isEnableAutoShrinkPanel() {
819                 return enableAutoShrinkPanel;
820         }
821
822         public void setEnableAutoShrinkPanel(boolean enableAutoShrinkPanel) {
823                 this.enableAutoShrinkPanel = enableAutoShrinkPanel;
824         }
825
826         public boolean isDisableWatchDirIfNotWritable() {
827                 return disableWatchDirIfNotWritable;
828         }
829
830         public void setDisableWatchDirIfNotWritable(boolean disableWatchDirIfNotWritable) {
831                 this.disableWatchDirIfNotWritable = disableWatchDirIfNotWritable;
832         }
833
834         private boolean disableWatchDirIfNotWritable = true;
835
836         public void setEnablePNGSupportForWindows(boolean enablePNGSupportForWindows) {
837                 this.enablePNGSupportForWindows = enablePNGSupportForWindows;
838         }
839
840         public boolean isEnablePNGSupportForWindows() {
841                 return enablePNGSupportForWindows;
842         }
843
844         private boolean enablePNGSupportForWindows = true;
845
846         /**
847          * 画像表示(通常モード)でオプティマイズを有効にする最大倍率.
848          */
849         private double renderingOptimizeThresholdForNormal = 2.;
850
851         public void setRenderingOptimizeThresholdForNormal(
852                         double renderingOptimizeThresholdForNormal) {
853                 this.renderingOptimizeThresholdForNormal = renderingOptimizeThresholdForNormal;
854         }
855
856         public double getRenderingOptimizeThresholdForNormal() {
857                 return renderingOptimizeThresholdForNormal;
858         }
859         /**
860          * 画像表示(チェックモード)でオプティマイズを有効にする最大倍率.
861          */
862         private double renderingOptimizeThresholdForCheck = 0.;
863
864         public void setRenderingOptimizeThresholdForCheck(
865                         double renderingOptimizeThresholdForCheck) {
866                 this.renderingOptimizeThresholdForCheck = renderingOptimizeThresholdForCheck;
867         }
868
869         public double getRenderingOptimizeThresholdForCheck() {
870                 return renderingOptimizeThresholdForCheck;
871         }
872
873         /**
874          * バイキュービックをサポートする場合
875          */
876         private boolean enableInterpolationBicubic = true;
877
878         public void setEnableInterpolationBicubic(boolean enableInterpolationBicubic) {
879                 this.enableInterpolationBicubic = enableInterpolationBicubic;
880         }
881
882         public boolean isEnableInterpolationBicubic() {
883                 return enableInterpolationBicubic;
884         }
885
886         /**
887          * 事前定義済みの倍率候補.<br>
888          */
889         private String predefinedZoomRanges = "20, 50, 80, 100, 120, 150, 200, 300, 400, 800";
890
891         public String getPredefinedZoomRanges() {
892                 return predefinedZoomRanges;
893         }
894
895         public void setPredefinedZoomRanges(String predefinedZoomRanges) {
896                 this.predefinedZoomRanges = predefinedZoomRanges;
897         }
898
899         /**
900          * ズームパネルを初期状態で表示するか?
901          */
902         private boolean enableZoomPanel = true;
903
904         public boolean isEnableZoomPanel() {
905                 return enableZoomPanel;
906         }
907
908         public void setEnableZoomPanel(boolean enableZoomPanel) {
909                 this.enableZoomPanel = enableZoomPanel;
910         }
911
912         /**
913          * ズームパネルをアクティブにする下部範囲
914          */
915         private int zoomPanelActivationArea = 30;
916
917         public int getZoomPanelActivationArea() {
918                 return zoomPanelActivationArea;
919         }
920
921         public void setZoomPanelActivationArea(int zoomPanelActivationArea) {
922                 this.zoomPanelActivationArea = zoomPanelActivationArea;
923         }
924
925         /**
926          * レンダリングヒントを使用するか?
927          */
928         private boolean enableRenderingHints = true;
929
930         public void setEnableRenderingHints(boolean enableRenderingHints) {
931                 this.enableRenderingHints = enableRenderingHints;
932         }
933
934         public boolean isEnableRenderingHints() {
935                 return enableRenderingHints;
936         }
937
938         /**
939          * グリッド描画とマスク
940          */
941         private int drawGridMask = 2;
942
943         public int getDrawGridMask() {
944                 return drawGridMask;
945         }
946
947         public void setDrawGridMask(int drawGridMask) {
948                 this.drawGridMask = drawGridMask & 0x03;
949         }
950
951         private int previewGridColor = 0x7f7f0000;
952
953         public int getPreviewGridColor() {
954                 return previewGridColor;
955         }
956
957         public void setPreviewGridColor(int previewGridColor) {
958                 this.previewGridColor = previewGridColor;
959         }
960
961         private int previewGridSize = 20;
962
963         public int getPreviewGridSize() {
964                 return previewGridSize;
965         }
966
967         public void setPreviewGridSize(int previewGridSize) {
968                 this.previewGridSize = previewGridSize;
969         }
970
971         /**
972          * チェックモード時の余白サイズ(片側)
973          */
974         private int previewUnfilledSpaceForCheckMode = 0;
975
976         public int getPreviewUnfilledSpaceForCheckMode() {
977                 return previewUnfilledSpaceForCheckMode;
978         }
979
980         public void setPreviewUnfilledSpaceForCheckMode(
981                         int previewUnfilledSpaceForCheckMode) {
982                 this.previewUnfilledSpaceForCheckMode = previewUnfilledSpaceForCheckMode;
983         }
984
985         /**
986          * チェックモードでツールチップを表示するか?
987          */
988         private boolean enableCheckInfoTooltip = true;
989
990         public boolean isEnableCheckInfoTooltip() {
991                 return enableCheckInfoTooltip;
992         }
993
994         public void setEnableCheckInfoTooltip(boolean enableCheckInfoTooltip) {
995                 this.enableCheckInfoTooltip = enableCheckInfoTooltip;
996         }
997
998         /**
999          * ホイールによるスクロールの単位.<br>
1000          */
1001         private int wheelScrollUnit = 10;
1002
1003         public int getWheelScrollUnit() {
1004                 return wheelScrollUnit;
1005         }
1006
1007         public void setWheelScrollUnit(int wheelScrollUnit) {
1008                 this.wheelScrollUnit = wheelScrollUnit;
1009         }
1010
1011         /**
1012          * 壁紙にオフスクリーン描画を使用するか?.<br>
1013          * (あまり劇的なパフォーマンス効果はない.)
1014          */
1015         private boolean enableOffscreenWallpaper = false;
1016
1017         public boolean isEnableOffscreenWallpaper() {
1018                 return enableOffscreenWallpaper;
1019         }
1020
1021         public void setEnableOffscreenWallpaper(boolean enableOffscreenWallpaper) {
1022                 this.enableOffscreenWallpaper = enableOffscreenWallpaper;
1023         }
1024
1025         /**
1026          * 壁紙のオフスクリーンの既定サイズ.
1027          */
1028         private int offscreenWallpaperSize = 300;
1029
1030         public int getOffscreenWallpaperSize() {
1031                 return offscreenWallpaperSize;
1032         }
1033
1034         public void setOffscreenWallpaperSize(int offscreenWallpaperSize) {
1035                 this.offscreenWallpaperSize = offscreenWallpaperSize;
1036         }
1037
1038         /**
1039          * ランダム選択パーツの履歴数
1040          */
1041         private int randomChooserMaxHistory = 10;
1042
1043         public int getRandomChooserMaxHistory() {
1044                 return randomChooserMaxHistory;
1045         }
1046
1047         public void setRandomChooserMaxHistory(int randomChooserMaxHistory) {
1048                 this.randomChooserMaxHistory = randomChooserMaxHistory;
1049         }
1050
1051         /**
1052          * デフォルトのフォントサイズ、0以下の場合はシステム既定のまま
1053          */
1054         private int defaultFontSize = 12;
1055
1056         public int getDefaultFontSize() {
1057                 return defaultFontSize;
1058         }
1059
1060         public void setDefaultFontSize(int defaultFontSize) {
1061                 this.defaultFontSize = defaultFontSize;
1062         }
1063
1064         /**
1065          * デフォルトのフォントファミリー、カンマ区切り
1066          */
1067         private String fontPriority = "Lucida Grande";
1068         
1069         public String getFontPriority() {
1070                 return fontPriority;
1071         }
1072         
1073         public void setFontPriority(String fontPriority) {
1074                 this.fontPriority = fontPriority;
1075         }
1076 }