1 module libxlsxd.workbook;
2 
3 import libxlsxd.xlsxwrap;
4 import std.string : toStringz;
5 import std.typecons : refCounted, RefCounted;
6 
7 import libxlsxd.worksheet;
8 import libxlsxd.format;
9 import libxlsxd.chart;
10 import libxlsxd.chartsheet;
11 import libxlsxd.datetime;
12 import libxlsxd.docproperties;
13 
14 alias Workbook = RefCounted!WorkbookImpl;
15 
16 Workbook newWorkbook(string filename) {
17 	Workbook wb;
18 	wb.filename = filename;
19 	wb.open();
20 	return wb;
21 }
22 
23 struct WorkbookImpl {
24 	WorkbookOpen workBook;
25 
26 	alias workBook this;
27 
28 	~this() {
29 		this.workBook.close();
30 	}
31 }
32 
33 struct WorkbookOpen {
34 	import std.exception : enforce;
35 	import std.datetime : DateTime;
36 	lxw_workbook* handle;
37 	string filename;
38 
39 	Format[string] formats;
40 
41 	static WorkbookOpen opCall(string filename) {
42 		WorkbookOpen ret;
43 		ret.filename = filename;
44 		ret.open();
45 		return ret;
46 	}
47 
48 	void open() {
49 		this.handle = workbook_new(this.filename.toStringz());
50 	}
51 
52 	void close() {
53 		workbook_close(this.handle);
54 	}
55 
56 	Worksheet addWorksheet(string name) nothrow {
57 		return Worksheet(workbook_add_worksheet(this.handle,
58 					name.toStringz())
59 				);
60 	}
61 
62 	Chartsheet addChartsheet(string name) {
63 		return Chartsheet(workbook_add_chartsheet(this.handle,
64 					name.toStringz())
65 				);
66 	}
67 
68 	Format addFormat() nothrow @nogc {
69 		return Format(workbook_add_format(this.handle));
70 	}
71 
72 	version(No_Overloads_Or_Templates) {
73 		Format addFormatNamed(string name) nothrow {
74 			return this.addFormatNamedImpl(name);
75 		}
76 	} else {
77 		Format addFormat(string name) nothrow {
78 			return this.addFormatNamedImpl(name);
79 		}
80 	}
81 
82 	private Format addFormatNamedImpl(string name) nothrow {
83 		auto t = Format(workbook_add_format(this.handle));
84 		this.formats[name] = t;
85 		return t;
86 	}
87 
88 	Format getFormat(string name) nothrow {
89 		return this.formats[name];
90 	}
91 
92 	Chart addChart(ubyte chartType) @nogc nothrow {
93 		return Chart(workbook_add_chart(this.handle, chartType));
94 	}
95 
96 	void setProperties(DocProperties property) {
97 		enforce(workbook_set_properties(this.handle, property.handle)
98 				== LXW_NO_ERROR
99 			);
100 	}
101 
102 	version(No_Overloads_Or_Templates) {
103 		void setCustomPropertiesBool(string name, bool b) {
104 			return this.setCustomPropertiesImpl(name, b);
105 		}
106 		void setCustomPropertiesInt(string name, long l) {
107 			return this.setCustomPropertiesImpl(name, l);
108 		}
109 		void setCustomPropertiesNumber(string name, double d) {
110 			return this.setCustomPropertiesImpl(name, d);
111 		}
112 		void setCustomPropertiesDateTime(string name, DateTime d) {
113 			return this.setCustomPropertiesImpl(name, Datetime(d));
114 		}
115 	} else {
116 		alias setCustomProperties = setCustomPropertiesImpl;
117 	}
118 
119 	private void setCustomPropertiesImpl(T)(string name, T t) {
120 		import std.traits : isIntegral, isFloatingPoint, isSomeString;
121 		import std.conv : to;
122 
123 		static if(is(T == bool)) {
124 			enforce(workbook_set_custom_property_boolean(this.handle,
125 						name.toStringz(), t
126 					)
127 					== LXW_NO_ERROR
128 				);
129 		} else static if(isIntegral!T) {
130 			enforce(workbook_set_custom_property_integer(this.handle,
131 						name.toStringz(), to!int(t)
132 					)
133 					== LXW_NO_ERROR
134 				);
135 		} else static if(isFloatingPoint!T) {
136 			enforce(workbook_set_custom_property_number(this.handle,
137 						name.toStringz(), to!double(t)
138 					)
139 					== LXW_NO_ERROR
140 				);
141 		} else static if(is(T == Datetime)) {
142 			enforce(workbook_set_custom_property_datetime(this.handle,
143 						toStringz(name), &t.handle)
144 					== LXW_NO_ERROR
145 				);
146 		} else {
147 			static assert(false, "setCustomProperties does not work with '" ~
148 					T.stringof ~ "'");
149 		}
150 	}
151 
152 	void defineName(string name, string formula) {
153 		enforce(workbook_define_name(this.handle, name.toStringz(),
154 						formula.toStringz()
155 					)
156 				== LXW_NO_ERROR
157 			);
158 	}
159 
160 	Worksheet getWorksheetByName(string name) {
161 		return Worksheet(workbook_get_worksheet_by_name(this.handle,
162 						name.toStringz()
163 					)
164 				);
165 	}
166 
167 	Chartsheet getChartByName(string name) {
168 		return Chartsheet(workbook_get_chartsheet_by_name(this.handle,
169 						name.toStringz()
170 					)
171 				);
172 	}
173 
174 	bool validateSheetName(string name) {
175 		return workbook_validate_sheet_name(this.handle, name.toStringz())
176 				== LXW_NO_ERROR;
177 	}
178 }