OSDN Git Service

行を生成するメソッドをLineToIndexTableに移動した
[fooeditengine/FooEditEngine.git] / Metro / FooEditEngine / Print / PrintOptionBuilder.cs
1 /*
2  * Copyright (C) 2013 FooProject
3  * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
5
6  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
7  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
10  */
11 using System;
12 using Windows.Graphics.Printing.OptionDetails;
13 using System.Reflection;
14 using Windows.ApplicationModel.Resources.Core;
15
16 namespace FooEditEngine
17 {
18     /// <summary>
19     /// 表示に使用するリソースID
20     /// </summary>
21     sealed class DisplayPrintOptionResourceIDAttribute : Attribute
22     {
23         public string ResourceID
24         {
25             get;
26             private set;
27         }
28         /// <summary>
29         /// コンストラクター
30         /// </summary>
31         /// <param name="resourceID">リソースID</param>
32         public DisplayPrintOptionResourceIDAttribute(string resourceID)
33         {
34             this.ResourceID = resourceID;
35         }
36     }
37     /// <summary>
38     /// IPrintPreviewSourceインターフェイス
39     /// </summary>
40     interface IPrintPreviewSource
41     {
42         /// <summary>
43         /// 再描写する
44         /// </summary>
45         void InvalidatePreview();
46     }
47     /// <summary>
48     /// 印刷プレビューのカスタムオプションリストビルダー
49     /// <para>
50     /// 印刷プレビューに表示させたいプロパティには「DisplayPrintOptionResourceID」属性を付ける必要があります。
51     /// また、このプロパティはenumを継承した型でなければならず、リソースに「型名.値」という形で印刷プレビューに表示される名前を定義する必要があります。
52     /// 定義しない場合、値がそのまま表示されます
53     /// </para>
54     /// </summary>
55     /// <typeparam name="T">IPrintPreviewSourceを継承したクラス</typeparam>
56     sealed class PrintOptionBuilder<T> where T : IPrintPreviewSource
57     {
58         T PrintDocument;
59         /// <summary>
60         /// コンストラクター
61         /// </summary>
62         /// <param name="source">対象となるオブジェクト</param>
63         public PrintOptionBuilder(T source)
64         {
65             this.PrintDocument = source;
66         }
67
68         /// <summary>
69         /// 印刷プレビューのオプションを作成する
70         /// </summary>
71         /// <param name="details">PrintTaskOptionDetailsオブジェクト</param>
72         public void BuildPrintOption(PrintTaskOptionDetails details)
73         {
74             ResourceMap map = ResourceManager.Current.MainResourceMap.GetSubtree("FooEditEngine.Metro/Resources");
75             ResourceContext context = ResourceContext.GetForCurrentView();
76
77             var properties = this.PrintDocument.GetType().GetRuntimeProperties();
78             foreach(PropertyInfo property in properties)
79             {
80                 DisplayPrintOptionResourceIDAttribute attr = property.GetCustomAttribute<DisplayPrintOptionResourceIDAttribute>();
81                 if (attr == null)
82                     continue;
83                 string resourceName;
84                 if(property.PropertyType.GetTypeInfo().IsEnum)
85                 {
86                     PrintCustomItemListOptionDetails iteminfo = details.CreateItemListOption(property.Name, map.GetValue(attr.ResourceID, context).ValueAsString);
87                     foreach (var enumvalue in Enum.GetValues(property.PropertyType))
88                     {
89                         string enumvalueStr = enumvalue.ToString();
90                         //リソース内部の"."は"/"に変換される
91                         resourceName = property.PropertyType.Name + "/" + enumvalueStr;
92                         ResourceCandidate resValue = map.GetValue(resourceName, context);
93 #if DEBUG
94                         if(resValue == null)
95                             System.Diagnostics.Debug.WriteLine("{0} is not defined by resource",resourceName.Replace('/','.'));
96 #endif
97                         iteminfo.AddItem(enumvalueStr, resValue != null ? resValue.ValueAsString : enumvalueStr);
98                     }
99                     iteminfo.TrySetValue(property.GetValue(this.PrintDocument).ToString());
100                     details.DisplayedOptions.Add(property.Name);
101                 }
102             }
103
104             details.OptionChanged += details_OptionChanged;
105         }
106
107         void details_OptionChanged(PrintTaskOptionDetails sender, PrintTaskOptionChangedEventArgs args)
108         {
109             string optionID = args.OptionId as string;
110             if (optionID == null)
111                 return;
112             string optionValue = sender.Options[optionID].Value as string;
113             var property = this.GetRuntimeProperty(this.PrintDocument.GetType(),optionID);
114             if (property == null)
115                 return;
116             if (property.PropertyType.GetTypeInfo().IsEnum)
117             {
118                 Enum output = (Enum)Enum.Parse(property.PropertyType, optionValue);
119                 property.SetMethod.Invoke(this.PrintDocument, new object[] { output });
120             }
121
122             this.PrintDocument.InvalidatePreview();
123         }
124
125         PropertyInfo GetRuntimeProperty(Type t,string name)
126         {
127             foreach(PropertyInfo property in t.GetRuntimeProperties())
128             {
129                 if (property.Name == name)
130                     return property;
131             }
132             return null;
133         }
134     }
135 }