}\r
\r
/**\r
+ * キャラクターデータの構造を表す文字列を返す.<br>\r
+ * カテゴリ、レイヤー、色グループのみで構成される.<br>\r
+ * id, revなどは含まない.<br>\r
+ * @return キャラクターデータの構造を表す文字列\r
+ */\r
+ public String toStructureString() {\r
+ // カラーグループ\r
+ StringBuilder buf = new StringBuilder();\r
+ buf.append("{colorGroup:[");\r
+ for (ColorGroup colorGroup : getColorGroups()) {\r
+ buf.append(colorGroup.getId());\r
+ buf.append(",");\r
+ }\r
+ buf.append("],");\r
+ \r
+ // カテゴリ\r
+ buf.append("category:[");\r
+ for (PartsCategory category : getPartsCategories()) {\r
+ buf.append("{id:");\r
+ buf.append(category.getCategoryId());\r
+\r
+ buf.append(",layer:[");\r
+ for (Layer layer : category.getLayers()) {\r
+ buf.append("{id:");\r
+ buf.append(layer.getId());\r
+ buf.append(",dir:");\r
+ buf.append(layer.getDir());\r
+ buf.append("},");\r
+ }\r
+ buf.append("]},");\r
+ }\r
+ buf.append("]}");\r
+ \r
+ return buf.toString();\r
+ }\r
+\r
+ /**\r
+ * キャラクターデータのID, REVと構造を識別するシグネチャの文字列を返す.<br>\r
+ * (構造はカテゴリ、レイヤー、色グループのみ).<br>\r
+ * @return シグネチャの文字列\r
+ */\r
+ public String toSignatureString() {\r
+ StringBuilder buf = new StringBuilder();\r
+ buf.append("{id:");\r
+ buf.append(getId());\r
+ buf.append(",rev:");\r
+ buf.append(getRev());\r
+ buf.append(",structure:");\r
+ buf.append(toStructureString());\r
+ buf.append("}");\r
+ return buf.toString();\r
+ }\r
+ \r
+ /**\r
* デシリアライズする.\r
* @param stream 入力もと\r
* @throws IOException 失敗\r
import java.io.File;\r
import java.io.IOException;\r
import java.io.ObjectInputStream;\r
+import java.io.ObjectInputStream.GetField;\r
import java.io.ObjectStreamClass;\r
import java.io.Serializable;\r
-import java.io.ObjectInputStream.GetField;\r
import java.net.URI;\r
import java.net.URL;\r
import java.util.Map;\r
this.characterDataRev = characterDataRev;\r
}\r
\r
+ /**\r
+ * REV情報.<br>\r
+ * キャラクターデータが設定されていない場合に使用される.<br>\r
+ * (ver0.96以前旧シリアライズデータ互換用)<br>\r
+ * @return\r
+ */\r
public String getCharacterDataRev() {\r
return characterDataRev;\r
}\r
\r
/**\r
* 最後に使用したお気に入りの情報.<br>\r
+ * 一度もプリセットを使ってなければnull.<br>\r
* ver0.94以前には存在しなかったため、nullになりえます。\r
* @return\r
*/\r
public PartsSet getLastUsePresetParts() {\r
return lastUsePresetParts;\r
}\r
- \r
+\r
+ /**\r
+ /**\r
+ * 最後に使用したお気に入りの情報.<br>\r
+ * 一度もプリセットを使ってなければnull.<br>\r
+ * (ver0.94以前には存在しなかったため、nullになりえます。)\r
+ * @param lastUsePresetParts\r
+ */\r
public void setLastUsePresetParts(PartsSet lastUsePresetParts) {\r
this.lastUsePresetParts = lastUsePresetParts;\r
}\r
/**\r
* キャラクター定義XMLファイルの名前空間\r
*/\r
- private static final String NS = "http://charactermanaj.sourceforge.jp/schema/charactermanaj";\r
+ private static final String DEFAULT_NS = "http://charactermanaj.sourceforge.jp/schema/charactermanaj";\r
\r
+ private final String NS;\r
+ \r
+ public CharacterDataXMLWriter() {\r
+ this(DEFAULT_NS);\r
+ }\r
+ \r
+ public CharacterDataXMLWriter(String ns) {\r
+ this.NS = ns;\r
+ }\r
+ \r
/**\r
* キャラクターデータのXMLの書き込み.\r
* \r
root.setAttribute("version", VERSION_SIG_1_0);\r
\r
root.setAttribute("xmlns:xml", XMLConstants.XML_NS_URI);\r
- root.setAttribute("xmlns:xsi",\r
- "http://www.w3.org/2001/XMLSchema-instance");\r
+ root.setAttribute("xmlns:xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);\r
root.setAttribute("xsi:schemaLocation", NS + " character.xsd");\r
root.setAttribute("id", characterData.getId());\r
root.setAttribute("rev", characterData.getRev());\r
}\r
tfmr.setOutputProperty(OutputKeys.INDENT, "yes");\r
\r
+ // JDK-4504745 : javax.xml.transform.Transformer encoding does not work properly\r
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504745\r
final String encoding = "UTF-8";\r
tfmr.setOutputProperty("encoding", encoding);\r
continue;\r
}\r
\r
- String partsSetId = partsSet.getPartsSetId();\r
- String localizedName = partsSet.getLocalizedName();\r
-\r
- Element nodePreset = doc.createElementNS(NS, "preset");\r
- nodePreset.setAttribute("id", partsSetId);\r
+ Element nodePreset = createPartsSetXML(doc, lang, partsSet);\r
baseElement.appendChild(nodePreset);\r
registeredPartsSetMap.put(partsSet.getPartsSetId(), partsSet);\r
-\r
- // display-name\r
- Element nodeName = doc.createElementNS(NS, "display-name");\r
- Attr attrLang = doc.createAttributeNS(XMLConstants.XML_NS_URI,\r
- "lang");\r
- attrLang.setValue(lang);\r
- nodeName.setAttributeNode(attrLang);\r
- nodeName.setTextContent(localizedName);\r
- nodePreset.appendChild(nodeName);\r
-\r
- // bgColor\r
- Color bgColor = partsSet.getBgColor();\r
- if (bgColor != null) {\r
- Element nodeBgColor = doc.createElementNS(NS,\r
- "background-color");\r
- nodeBgColor.setAttribute("color",\r
- "#" + Integer.toHexString(bgColor.getRGB() & 0xffffff));\r
- nodePreset.appendChild(nodeBgColor);\r
- }\r
-\r
- // affine transform parameter\r
- double[] affineTransformParameter = partsSet\r
- .getAffineTransformParameter();\r
- if (affineTransformParameter != null) {\r
- Element nodeAffineTransform = doc.createElementNS(NS,\r
- "affine-transform-parameter");\r
- StringBuilder tmp = new StringBuilder();\r
- for (double affineItem : affineTransformParameter) {\r
- if (tmp.length() > 0) {\r
- tmp.append(" ");\r
- }\r
- tmp.append(Double.toString(affineItem));\r
- }\r
- nodeAffineTransform.setTextContent(tmp.toString());\r
- nodePreset.appendChild(nodeAffineTransform);\r
- }\r
-\r
- // categories\r
- for (Map.Entry<PartsCategory, List<PartsIdentifier>> entry : partsSet\r
- .entrySet()) {\r
- PartsCategory partsCategory = entry.getKey();\r
-\r
- // category\r
- Element nodeCategory = doc.createElementNS(NS, "category");\r
- nodeCategory.setAttribute("refid",\r
- partsCategory.getCategoryId());\r
- nodePreset.appendChild(nodeCategory);\r
-\r
- List<PartsIdentifier> partsIdentifiers = entry.getValue();\r
- for (PartsIdentifier partsIdentifier : partsIdentifiers) {\r
- String partsName = partsIdentifier.getPartsName();\r
- Element nodeParts = doc.createElementNS(NS, "parts");\r
- nodeParts.setAttribute("name", partsName);\r
- nodeCategory.appendChild(nodeParts);\r
-\r
- PartsColorInfo partsColorInfo = partsSet\r
- .getColorInfo(partsIdentifier);\r
- if (partsColorInfo != null) {\r
- Element nodeColor = doc.createElementNS(NS, "color");\r
- nodeParts.appendChild(nodeColor);\r
-\r
- for (Map.Entry<Layer, ColorInfo> colorInfoEntry : partsColorInfo\r
- .entrySet()) {\r
- Layer layer = colorInfoEntry.getKey();\r
- ColorInfo colorInfo = colorInfoEntry.getValue();\r
-\r
- Element nodeLayer = doc\r
- .createElementNS(NS, "layer");\r
- nodeLayer.setAttribute("refid", layer.getId());\r
- nodeColor.appendChild(nodeLayer);\r
-\r
- // ColorGroup\r
- ColorGroup colorGroup = colorInfo.getColorGroup();\r
- boolean colorSync = colorInfo.isSyncColorGroup();\r
-\r
- if (colorGroup.isEnabled()) {\r
- Element nodeColorGroup = doc.createElementNS(\r
- NS, "color-group");\r
- nodeColorGroup.setAttribute("group",\r
- colorGroup.getId());\r
- nodeColorGroup.setAttribute("synchronized",\r
- colorSync ? "true" : "false");\r
- nodeLayer.appendChild(nodeColorGroup);\r
- }\r
-\r
- // RGB\r
- ColorConvertParameter param = colorInfo\r
- .getColorParameter();\r
-\r
- Element nodeRGB = doc.createElementNS(NS, "rgb");\r
- Object[][] rgbArgss = {\r
- {"red", param.getOffsetR(),\r
- param.getFactorR(),\r
- param.getGammaR()},\r
- {"green", param.getOffsetG(),\r
- param.getFactorG(),\r
- param.getGammaG()},\r
- {"blue", param.getOffsetB(),\r
- param.getFactorB(),\r
- param.getGammaB()},\r
- {"alpha", param.getOffsetA(),\r
- param.getFactorA(),\r
- param.getGammaA()},};\r
- for (Object[] rgbArgs : rgbArgss) {\r
- Element nodeRGBItem = doc.createElementNS(NS,\r
- rgbArgs[0].toString());\r
- nodeRGBItem.setAttribute("offset",\r
- rgbArgs[1].toString());\r
- nodeRGBItem.setAttribute("factor",\r
- rgbArgs[2].toString());\r
- nodeRGBItem.setAttribute("gamma",\r
- rgbArgs[3].toString());\r
- nodeRGB.appendChild(nodeRGBItem);\r
- }\r
- nodeLayer.appendChild(nodeRGB);\r
-\r
- // HSB\r
- Element nodeHSB = doc.createElementNS(NS, "hsb");\r
- nodeHSB.setAttribute("hue",\r
- Float.toString(param.getHue()));\r
- nodeHSB.setAttribute("saturation",\r
- Float.toString(param.getSaturation()));\r
- nodeHSB.setAttribute("brightness",\r
- Float.toString(param.getBrightness()));\r
- if (param.getContrast() != 0.f) {\r
- // ver0.96追加、optional\r
- // ぴったり0.0fだったら省略する.\r
- nodeHSB.setAttribute("contrast",\r
- Float.toString(param.getContrast()));\r
- }\r
- nodeLayer.appendChild(nodeHSB);\r
-\r
- // RGB Replace\r
- Element nodeRGBReplace = doc.createElementNS(NS,\r
- "rgb-replace");\r
- ColorConv colorConv = param.getColorReplace();\r
- if (colorConv == null) {\r
- colorConv = ColorConv.NONE;\r
- }\r
- nodeRGBReplace.setAttribute("replace-type",\r
- colorConv.name());\r
- nodeRGBReplace.setAttribute("gray",\r
- Float.toString(param.getGrayLevel()));\r
- nodeLayer.appendChild(nodeRGBReplace);\r
- }\r
- }\r
- }\r
- }\r
}\r
\r
// プリセット登録時はデフォルトのプリセットIDがあれば、それも登録する.\r
\r
return registeredPartsSetMap.size();\r
}\r
+ \r
+ /**\r
+ * パーツセットのXM要素を生成して返す.\r
+ * @param doc ノードを生成するためのファクトリ\r
+ * @param lang 言語識別用(パーツセット名などの登録時のlang属性に必要)\r
+ * @param partsSet パーツセット、nullの場合はxsi:nul="true"が返される.\r
+ * @return パーツセット1つ分のXML要素\r
+ */\r
+ public Element createPartsSetXML(Document doc, String lang, PartsSet partsSet) {\r
+ if (doc == null || lang == null) {\r
+ throw new IllegalArgumentException();\r
+ }\r
+\r
+ String partsSetId = partsSet.getPartsSetId();\r
+ String localizedName = partsSet.getLocalizedName();\r
+\r
+ Element nodePreset = doc.createElementNS(NS, "preset");\r
+ if (partsSet == null || partsSet.isEmpty()) {\r
+ // 指定されていないか有効でない場合は無しとみなす.\r
+ nodePreset.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");\r
+ return nodePreset;\r
+ }\r
+\r
+ nodePreset.setAttribute("id", partsSetId);\r
+\r
+ // display-name\r
+ Element nodeName = doc.createElementNS(NS, "display-name");\r
+ Attr attrLang = doc.createAttributeNS(XMLConstants.XML_NS_URI,\r
+ "lang");\r
+ attrLang.setValue(lang);\r
+ nodeName.setAttributeNode(attrLang);\r
+ nodeName.setTextContent(localizedName);\r
+ nodePreset.appendChild(nodeName);\r
+\r
+ // bgColor\r
+ Color bgColor = partsSet.getBgColor();\r
+ if (bgColor != null) {\r
+ Element nodeBgColor = doc.createElementNS(NS,\r
+ "background-color");\r
+ nodeBgColor.setAttribute("color",\r
+ "#" + Integer.toHexString(bgColor.getRGB() & 0xffffff));\r
+ nodePreset.appendChild(nodeBgColor);\r
+ }\r
+\r
+ // affine transform parameter\r
+ double[] affineTransformParameter = partsSet\r
+ .getAffineTransformParameter();\r
+ if (affineTransformParameter != null) {\r
+ Element nodeAffineTransform = doc.createElementNS(NS,\r
+ "affine-transform-parameter");\r
+ StringBuilder tmp = new StringBuilder();\r
+ for (double affineItem : affineTransformParameter) {\r
+ if (tmp.length() > 0) {\r
+ tmp.append(" ");\r
+ }\r
+ tmp.append(Double.toString(affineItem));\r
+ }\r
+ nodeAffineTransform.setTextContent(tmp.toString());\r
+ nodePreset.appendChild(nodeAffineTransform);\r
+ }\r
+\r
+ // categories\r
+ for (Map.Entry<PartsCategory, List<PartsIdentifier>> entry : partsSet\r
+ .entrySet()) {\r
+ PartsCategory partsCategory = entry.getKey();\r
+\r
+ // category\r
+ Element nodeCategory = doc.createElementNS(NS, "category");\r
+ nodeCategory.setAttribute("refid",\r
+ partsCategory.getCategoryId());\r
+ nodePreset.appendChild(nodeCategory);\r
+\r
+ List<PartsIdentifier> partsIdentifiers = entry.getValue();\r
+ for (PartsIdentifier partsIdentifier : partsIdentifiers) {\r
+ String partsName = partsIdentifier.getPartsName();\r
+ Element nodeParts = doc.createElementNS(NS, "parts");\r
+ nodeParts.setAttribute("name", partsName);\r
+ nodeCategory.appendChild(nodeParts);\r
+\r
+ PartsColorInfo partsColorInfo = partsSet\r
+ .getColorInfo(partsIdentifier);\r
+ if (partsColorInfo != null) {\r
+ Element nodeColor = createPartsColorInfoXML(doc, partsColorInfo);\r
+ nodeParts.appendChild(nodeColor);\r
+ }\r
+ }\r
+ }\r
+ \r
+ return nodePreset;\r
+ }\r
+ \r
+ /**\r
+ * パーツカラー情報のXML要素を生成して返す.<br>\r
+ * @param doc 要素を作成するためのファクトリ\r
+ * @param partsColorInfo パーツカラー情報\r
+ * @return パーツカラー情報の要素\r
+ */\r
+ public Element createPartsColorInfoXML(Document doc, PartsColorInfo partsColorInfo) {\r
+ if (doc == null || partsColorInfo == null) {\r
+ throw new IllegalArgumentException();\r
+ }\r
+\r
+ Element nodeColor = doc.createElementNS(NS, "color");\r
+\r
+ for (Map.Entry<Layer, ColorInfo> colorInfoEntry : partsColorInfo\r
+ .entrySet()) {\r
+ Layer layer = colorInfoEntry.getKey();\r
+ ColorInfo colorInfo = colorInfoEntry.getValue();\r
+\r
+ Element nodeLayer = doc\r
+ .createElementNS(NS, "layer");\r
+ nodeLayer.setAttribute("refid", layer.getId());\r
+ nodeColor.appendChild(nodeLayer);\r
+\r
+ // ColorGroup\r
+ ColorGroup colorGroup = colorInfo.getColorGroup();\r
+ boolean colorSync = colorInfo.isSyncColorGroup();\r
+\r
+ if (colorGroup.isEnabled()) {\r
+ Element nodeColorGroup = doc.createElementNS(\r
+ NS, "color-group");\r
+ nodeColorGroup.setAttribute("group",\r
+ colorGroup.getId());\r
+ nodeColorGroup.setAttribute("synchronized",\r
+ colorSync ? "true" : "false");\r
+ nodeLayer.appendChild(nodeColorGroup);\r
+ }\r
+\r
+ // RGB\r
+ ColorConvertParameter param = colorInfo\r
+ .getColorParameter();\r
+\r
+ Element nodeRGB = doc.createElementNS(NS, "rgb");\r
+ Object[][] rgbArgss = {\r
+ {"red", param.getOffsetR(),\r
+ param.getFactorR(),\r
+ param.getGammaR()},\r
+ {"green", param.getOffsetG(),\r
+ param.getFactorG(),\r
+ param.getGammaG()},\r
+ {"blue", param.getOffsetB(),\r
+ param.getFactorB(),\r
+ param.getGammaB()},\r
+ {"alpha", param.getOffsetA(),\r
+ param.getFactorA(),\r
+ param.getGammaA()},};\r
+ for (Object[] rgbArgs : rgbArgss) {\r
+ Element nodeRGBItem = doc.createElementNS(NS,\r
+ rgbArgs[0].toString());\r
+ nodeRGBItem.setAttribute("offset",\r
+ rgbArgs[1].toString());\r
+ nodeRGBItem.setAttribute("factor",\r
+ rgbArgs[2].toString());\r
+ nodeRGBItem.setAttribute("gamma",\r
+ rgbArgs[3].toString());\r
+ nodeRGB.appendChild(nodeRGBItem);\r
+ }\r
+ nodeLayer.appendChild(nodeRGB);\r
+\r
+ // HSB\r
+ Element nodeHSB = doc.createElementNS(NS, "hsb");\r
+ nodeHSB.setAttribute("hue",\r
+ Float.toString(param.getHue()));\r
+ nodeHSB.setAttribute("saturation",\r
+ Float.toString(param.getSaturation()));\r
+ nodeHSB.setAttribute("brightness",\r
+ Float.toString(param.getBrightness()));\r
+ if (param.getContrast() != 0.f) {\r
+ // ver0.96追加、optional\r
+ // ぴったり0.0fだったら省略する.\r
+ nodeHSB.setAttribute("contrast",\r
+ Float.toString(param.getContrast()));\r
+ }\r
+ nodeLayer.appendChild(nodeHSB);\r
+\r
+ // RGB Replace\r
+ Element nodeRGBReplace = doc.createElementNS(NS,\r
+ "rgb-replace");\r
+ ColorConv colorConv = param.getColorReplace();\r
+ if (colorConv == null) {\r
+ colorConv = ColorConv.NONE;\r
+ }\r
+ nodeRGBReplace.setAttribute("replace-type",\r
+ colorConv.name());\r
+ nodeRGBReplace.setAttribute("gray",\r
+ Float.toString(param.getGrayLevel()));\r
+ nodeLayer.appendChild(nodeRGBReplace);\r
+ }\r
+ \r
+ return nodeColor;\r
+ }\r
\r
public void saveFavorites(CharacterData characterData,\r
OutputStream outstm) throws IOException {\r
--- /dev/null
+package charactermanaj.model.io;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import charactermanaj.model.CharacterData;
+import charactermanaj.model.PartsColorInfo;
+import charactermanaj.model.PartsIdentifier;
+import charactermanaj.model.PartsSet;
+import charactermanaj.model.WorkingSet;
+import charactermanaj.ui.model.WallpaperInfo;
+import charactermanaj.ui.model.WallpaperInfo.WallpaperResourceType;
+
+/**
+ * WorkingSetのXMLへの書き込み
+ */
+public class WorkingSetXMLWriter {
+
+ /**
+ * WorkingSetのバージョン
+ */
+ private static final String VERSION_SIG_1_0 = "1.0";
+
+ /**
+ * WorkingSetのXMLファイルの名前空間
+ */
+ private static final String NS = "http://charactermanaj.sourceforge.jp/schema/charactermanaj-workingset";
+
+ /**
+ * キャラクターデータのXML化
+ */
+ private CharacterDataXMLWriter characterDataXmlWriter =
+ new CharacterDataXMLWriter(NS);
+
+ /**
+ * ワーキングセットをXML表現で出力ストリームに出力します.<br>
+ * @param ws ワーキングセット
+ * @param outstm 出力先ストリーム
+ * @throws IOException 失敗
+ */
+ public void writeWorkingSet(WorkingSet ws, OutputStream outstm) throws IOException {
+ if (ws == null || outstm == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Document doc = createWorkingSetXML(ws);
+
+ // output xml
+ TransformerFactory txFactory = TransformerFactory.newInstance();
+ txFactory.setAttribute("indent-number", Integer.valueOf(4));
+ Transformer tfmr;
+ try {
+ tfmr = txFactory.newTransformer();
+ } catch (TransformerConfigurationException ex) {
+ throw new RuntimeException("JAXP Configuration Failed.", ex);
+ }
+ tfmr.setOutputProperty(OutputKeys.INDENT, "yes");
+
+ // JDK-4504745 : javax.xml.transform.Transformer encoding does not work properly
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4504745
+ final String encoding = "UTF-8";
+ tfmr.setOutputProperty("encoding", encoding);
+ try {
+ tfmr.transform(new DOMSource(doc), new StreamResult(
+ new OutputStreamWriter(outstm, Charset.forName(encoding))));
+
+ } catch (TransformerException ex) {
+ IOException ex2 = new IOException("XML Convert failed.");
+ ex2.initCause(ex);
+ throw ex2;
+ }
+ }
+
+ /**
+ * ワーキングセットのXMLドキュメントを生成します.
+ * @param ws ワーキングセット
+ * @return XMLドキュメント
+ */
+ public Document createWorkingSetXML(WorkingSet ws) {
+ if (ws == null) {
+ throw new IllegalArgumentException();
+ }
+
+ Document doc;
+ try {
+ DocumentBuilderFactory factory = DocumentBuilderFactory
+ .newInstance();
+ factory.setNamespaceAware(true);
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ doc = builder.newDocument();
+ } catch (ParserConfigurationException ex) {
+ throw new RuntimeException("JAXP Configuration failed.", ex);
+ }
+
+ Locale locale = Locale.getDefault();
+ String lang = locale.getLanguage();
+
+ Element root = doc.createElementNS(NS, "character-workingset");
+ root.setAttribute("version", VERSION_SIG_1_0);
+
+ root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:xsi",
+ XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
+ root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:xml",
+ XMLConstants.XML_NS_URI);
+ root.setAttribute("xsi:schemaLocation", NS + " character_ws.xsd");
+
+ // ドキュメントベース
+ URI docbase = ws.getCharacterDocBase();
+ root.setAttribute("characterDocBase", docbase == null ? "" : docbase.toString());
+
+ // キャラクターデータのシグネチャ
+ CharacterData cd = ws.getCharacterData();
+ Element characterDataSigElm = doc.createElementNS(NS, "characterDataSig");
+ if (cd == null || !cd.isValid()) {
+ // 指定されていないか有効でない場合は無しとみなす.
+ characterDataSigElm.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");
+ } else {
+ characterDataSigElm.setTextContent(cd.toSignatureString());
+ }
+ root.appendChild(characterDataSigElm);
+
+ // パーツカラー情報
+ root.appendChild(writePartsColorInfoMap(doc, ws.getPartsColorInfoMap()));
+
+ // パーツセット
+ PartsSet partsSet = ws.getPartsSet();
+ Element partsSetElm = doc.createElementNS(NS, "partsSet");
+ if (partsSet == null || partsSet.isEmpty()) {
+ partsSetElm.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");
+
+ } else {
+ Element elm = characterDataXmlWriter.createPartsSetXML(doc, lang, partsSet);
+ partsSetElm.appendChild(elm);
+ }
+ root.appendChild(partsSetElm);
+
+ // 最後に使用した保存先ディレクトリ
+ Element lastUsedSaveDirElm = doc.createElementNS(NS, "lastUsedSaveDir");
+ File lastUsedSaveDir = ws.getLastUsedSaveDir();
+ if (lastUsedSaveDir == null) {
+ lastUsedSaveDirElm.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");
+
+ } else {
+ lastUsedSaveDirElm.setTextContent(lastUsedSaveDir.getPath());
+ }
+ root.appendChild(lastUsedSaveDirElm);
+
+ // 最後に使用したエクスポート先ディレクトリ
+ Element lastUsedExportDirElm = doc.createElementNS(NS, "lastUsedExportDir");
+ File lastUsedExportDir = ws.getLastUsedExportDir();
+ if (lastUsedExportDir == null) {
+ lastUsedExportDirElm.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");
+
+ } else {
+ lastUsedExportDirElm.setTextContent(lastUsedExportDir.getPath());
+ }
+ root.appendChild(lastUsedExportDirElm);
+
+ // 最後に使用したパーツセット情報、なければnull
+ PartsSet lastUsePresetParts = ws.getLastUsePresetParts();
+ Element lastUsePresetPartsElm = doc.createElementNS(NS, "lastUsePresetParts");
+ if (lastUsePresetParts == null || lastUsePresetParts.isEmpty()) {
+ lastUsePresetPartsElm.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");
+
+ } else {
+ Element elm = characterDataXmlWriter.createPartsSetXML(doc, lang, lastUsePresetParts);
+ lastUsePresetPartsElm.appendChild(elm);
+ }
+ root.appendChild(lastUsePresetPartsElm);
+
+ // 壁紙情報
+ root.appendChild(writeWallpaper(doc, ws.getWallpaperInfo()));
+
+ doc.appendChild(root);
+ return doc;
+ }
+
+ /**
+ * パーツごとのカラー情報のXML要素を生成して返します.
+ * @param doc 要素のファクトリ
+ * @param partsColorMap パーツごとのカラー情報のマップ
+ * @return パーツごとのカラー情報のXML要素
+ */
+ public Element writePartsColorInfoMap(Document doc, Map<PartsIdentifier, PartsColorInfo> partsColorMap) {
+ Element partsColorInfoMapElm = doc.createElementNS(NS, "partsColorInfoMap");
+ if (partsColorMap != null) {
+ // 使用しているカラーの設定ごとに番号を振る
+ // (同じカラー設定であれば同じ番号とする.)
+ LinkedHashMap<PartsColorInfo, String> colorMap = new LinkedHashMap<PartsColorInfo, String>();
+ for (Map.Entry<PartsIdentifier, PartsColorInfo> partsColorEntry : partsColorMap.entrySet()) {
+ PartsColorInfo partsColorInfo = partsColorEntry.getValue();
+ if (partsColorInfo != null && !partsColorInfo.isEmpty()) {
+ if (!colorMap.containsKey(partsColorInfo)) {
+ colorMap.put(partsColorInfo, Integer.toString(colorMap.size() + 1));
+ }
+ }
+ }
+
+ // すべてのカラー設定を出力する.
+ Element colorsElm = doc.createElementNS(NS, "colors");
+ for (Map.Entry<PartsColorInfo, String> colorMapEntry : colorMap.entrySet()) {
+ PartsColorInfo partsColorInfo = colorMapEntry.getKey();
+ String id = colorMapEntry.getValue();
+ Element partsColorElm = characterDataXmlWriter.createPartsColorInfoXML(doc, partsColorInfo);
+ partsColorElm.setAttribute("id", id);
+ colorsElm.appendChild(partsColorElm);
+ }
+ partsColorInfoMapElm.appendChild(colorsElm);
+
+ // パーツと、そのパーツのカラー設定番号の一覧を出力する.
+ Element partsListElm = doc.createElementNS(NS, "partsList");
+ for (Map.Entry<PartsIdentifier, PartsColorInfo> partsColorEntry : partsColorMap.entrySet()) {
+ PartsIdentifier partsIdentifier = partsColorEntry.getKey();
+ PartsColorInfo partsColorInfo = partsColorEntry.getValue();
+ if (partsColorInfo != null && !partsColorInfo.isEmpty()) {
+ String colorId = colorMap.get(partsColorInfo);
+ if (colorId == null) {
+ throw new RuntimeException("colorMapが不整合です");
+ }
+ Element partsElm = doc.createElementNS(NS, "partsIdentifier");
+ String categoryId = partsIdentifier.getPartsCategory().getCategoryId();
+ partsElm.setAttribute("categoryId", categoryId);
+ partsElm.setAttribute("name", partsIdentifier.getPartsName());
+ partsElm.setAttribute("colorId", colorId);
+ partsListElm.appendChild(partsElm);
+ }
+ }
+ partsColorInfoMapElm.appendChild(partsListElm);
+ }
+ return partsColorInfoMapElm;
+ }
+
+ /**
+ * 壁紙情報をXML要素として生成する.
+ * @param doc XML要素のファクトリ
+ * @param wallpaperInfo 壁紙情報
+ * @return 壁紙情報のXML要素
+ */
+ public Element writeWallpaper(Document doc, WallpaperInfo wallpaperInfo) {
+ Element elm = doc.createElementNS(NS, "wallpaperInfo");
+
+ if (wallpaperInfo == null) {
+ elm.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");
+
+ } else {
+ // タイプ
+ WallpaperResourceType typ = wallpaperInfo.getType();
+ Element typElm = doc.createElementNS(NS, "type");
+ typElm.setTextContent(typ.name());
+ elm.appendChild(typElm);
+
+ // リソース
+ String res = wallpaperInfo.getResource();
+ Element resElm = doc.createElementNS(NS, "resource");
+ if (res == null || res.trim().length() == 0) {
+ resElm.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");
+ } else {
+ resElm.setTextContent(res);
+ }
+ elm.appendChild(resElm);
+
+ // ファイル
+ File file = wallpaperInfo.getFile();
+ Element fileElm = doc.createElementNS(NS, "file");
+ if (file == null) {
+ fileElm.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:nil", "true");
+ } else {
+ fileElm.setTextContent(file.getPath());
+ }
+ elm.appendChild(fileElm);
+
+ // アルファ
+ float alpha = wallpaperInfo.getAlpha();
+ Element alphaElm = doc.createElementNS(NS, "alpha");
+ alphaElm.setTextContent(Float.toString(alpha));
+ elm.appendChild(alphaElm);
+
+ // 背景色
+ Color backgroundColor = wallpaperInfo.getBackgroundColor();
+ Element bgColorElm = doc.createElementNS(NS, "backgroundColor");
+ bgColorElm.setTextContent("#" + Integer.toHexString(backgroundColor.getRGB() & 0xffffff));
+ elm.appendChild(bgColorElm);
+ }
+
+ return elm;
+ }
+
+}
package charactermanaj.ui;\r
\r
-import static java.lang.Math.max;\r
-import static java.lang.Math.min;\r
+import static java.lang.Math.*;\r
\r
import java.awt.BorderLayout;\r
import java.awt.Color;\r
import java.awt.image.BufferedImage;\r
import java.io.File;\r
import java.io.IOException;\r
+import java.io.OutputStream;\r
import java.lang.reflect.InvocationTargetException;\r
import java.util.ArrayList;\r
import java.util.Collections;\r
import charactermanaj.model.io.PartsImageDirectoryWatchEvent;\r
import charactermanaj.model.io.PartsImageDirectoryWatchListener;\r
import charactermanaj.model.io.RecentDataPersistent;\r
+import charactermanaj.model.io.WorkingSetXMLWriter;\r
import charactermanaj.ui.ImageSelectPanel.ImageSelectPanelEvent;\r
import charactermanaj.ui.ImageSelectPanel.ImageSelectPanelListener;\r
import charactermanaj.ui.ManageFavoriteDialog.FavoriteManageCallback;\r
UserData workingSetStore = getWorkingSetUserData(false);\r
workingSetStore.save(workingSet);\r
\r
+ // XML形式でのワーキングセットの保存\r
+ UserDataFactory userDataFactory = UserDataFactory.getInstance();\r
+ UserData xmlData = userDataFactory.getMangledNamedUserData(characterData.getDocBase(), "workingset.xml");\r
+ OutputStream outstm = xmlData.getOutputStream();\r
+ try {\r
+ WorkingSetXMLWriter workingSetXmlWriter = new WorkingSetXMLWriter();\r
+ workingSetXmlWriter.writeWorkingSet(workingSet, outstm);\r
+ } finally {\r
+ outstm.close();\r
+ }\r
+ \r
} catch (Exception ex) {\r
ErrorMessageHelper.showErrorDialog(this, ex);\r
}\r
File userDataDir = ConfigurationDirUtilities.getUserDataDir();\r
\r
if (name != null && name.length() > 0) {\r
- int pos = name.lastIndexOf('.');\r
- if (pos >= 0) {\r
- String ext = name.substring(pos + 1);\r
- if (ext.length() > 0) {\r
- if ("ser".equals(ext)) {\r
- userDataDir = new File(userDataDir, "caches");\r
- } else {\r
- userDataDir = new File(userDataDir, ext + "s");\r
+ int seppos = name.lastIndexOf('-');\r
+ if (name.endsWith(".xml") && seppos >= 0) {\r
+ // 「foo-????.xml」形式の場合は「????」でグループ化する\r
+ String groupName = name.substring(seppos + 1, name.length() - 4);\r
+ if (groupName.length() > 0) {\r
+ userDataDir = new File(userDataDir, groupName);\r
+ }\r
+\r
+ } else {\r
+ // 拡張子によるグループ化\r
+ int pos = name.lastIndexOf('.');\r
+ if (pos >= 0) {\r
+ String ext = name.substring(pos + 1);\r
+ if (ext.length() > 0) {\r
+ if ("ser".equals(ext)) {\r
+ userDataDir = new File(userDataDir, "caches");\r
+ } else {\r
+ userDataDir = new File(userDataDir, ext + "s");\r
+ }\r
}\r
}\r
}\r