1 | // Jomic - a viewer for comic book archives. |
2 | // Copyright (C) 2004-2011 Thomas Aglassinger |
3 | // |
4 | // This program is free software: you can redistribute it and/or modify |
5 | // it under the terms of the GNU General Public License as published by |
6 | // the Free Software Foundation, either version 3 of the License, or |
7 | // (at your option) any later version. |
8 | // |
9 | // This program is distributed in the hope that it will be useful, |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | // GNU General Public License for more details. |
13 | // |
14 | // You should have received a copy of the GNU General Public License |
15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | package net.sf.jomic.comic; |
17 | |
18 | import java.io.File; |
19 | import java.net.URL; |
20 | import java.util.Arrays; |
21 | import java.util.Iterator; |
22 | import java.util.LinkedList; |
23 | import java.util.List; |
24 | |
25 | import javax.swing.Icon; |
26 | import javax.swing.ImageIcon; |
27 | import javax.swing.event.ChangeEvent; |
28 | import javax.swing.event.ChangeListener; |
29 | |
30 | import net.sf.jomic.tools.StringTools; |
31 | |
32 | /** |
33 | * Information about the current state of the conversion of one particular comic. |
34 | * |
35 | * @see net.sf.jomic.comic.ComicToConvert |
36 | * @author Thomas Aglassinger |
37 | */ |
38 | public class ConversionReportItem |
39 | { |
40 | |
41 | /** |
42 | * State indicating that the conversion for this item has been cancelled. |
43 | */ |
44 | public static final String STATE_CANCELLED = "cancelled"; |
45 | |
46 | /** |
47 | * State indicating that the item is currently converted. |
48 | */ |
49 | public static final String STATE_CONVERTING = "converting"; |
50 | |
51 | /** |
52 | * State indicating that the item was sucessfully converted. |
53 | */ |
54 | public static final String STATE_DONE = "done"; |
55 | |
56 | /** |
57 | * State indicating that the conversion failed because of some error. |
58 | */ |
59 | public static final String STATE_ERROR_DURING_CONVERSION = "errorDuringConversion"; |
60 | |
61 | /** |
62 | * State indicating that the specified target could not be converted because another source |
63 | * comic already resulted in the same target. |
64 | */ |
65 | public static final String STATE_ERROR_NOT_UNIQUE = "errorNotUnique"; |
66 | |
67 | /** |
68 | * State indicating that thespecified source and target already where converted by another |
69 | * item. |
70 | */ |
71 | public static final String STATE_SKIPPED_DUPLICATE = "skippedDuplicate"; |
72 | /** |
73 | * State indicating that the item is waiting to be converted. |
74 | */ |
75 | public static final String STATE_WAITING = "waiting"; |
76 | |
77 | private String[] allStates; |
78 | private List changeListeners; |
79 | private Throwable error; |
80 | |
81 | private File sourceFile; |
82 | private long sourceFileSize; |
83 | |
84 | /** |
85 | * State of the conversion. |
86 | */ |
87 | private String state; |
88 | private File targetFile; |
89 | private long targetFileSize; |
90 | |
91 | public ConversionReportItem(ComicToConvert comicToConvert) { |
92 | assert comicToConvert != null; |
93 | sourceFile = comicToConvert.getSourceComicFile(); |
94 | targetFile = comicToConvert.getTargetComicFile(); |
95 | sourceFileSize = comicToConvert.getFileSize(); |
96 | allStates = new String[]{ |
97 | STATE_WAITING, |
98 | STATE_CONVERTING, |
99 | STATE_DONE, |
100 | STATE_SKIPPED_DUPLICATE, |
101 | STATE_ERROR_NOT_UNIQUE, |
102 | STATE_ERROR_DURING_CONVERSION |
103 | }; |
104 | Arrays.sort(allStates); |
105 | state = STATE_WAITING; |
106 | changeListeners = new LinkedList(); |
107 | } |
108 | |
109 | /** |
110 | * Set state to STATE_ERROR_DURING_CONVERSION and the related error information to <code>newError</code> |
111 | * . |
112 | */ |
113 | public void setConversionError(Throwable newError) { |
114 | assert error != newError; |
115 | setState(STATE_ERROR_DURING_CONVERSION); |
116 | error = newError; |
117 | fireChange(); |
118 | } |
119 | |
120 | /** |
121 | * Set the state of the conversion to any of the <code>STATE_xxx</code> values. If the state |
122 | * changes to <code>STATE_DONE</code>, obtain the file size of the target file. |
123 | * |
124 | * @see #STATE_DONE |
125 | * @see #getTargetFileSize() |
126 | */ |
127 | public void setState(String newState) { |
128 | assert isValidState(); |
129 | state = newState; |
130 | if (state.equals(STATE_DONE)) { |
131 | targetFileSize = targetFile.length(); |
132 | } |
133 | fireChange(); |
134 | } |
135 | |
136 | /** |
137 | * Get details about the error that prevented the conversion to succeed. |
138 | * |
139 | * @see #setConversionError(Throwable) |
140 | */ |
141 | public Throwable getError() { |
142 | assert state.equals(STATE_ERROR_DURING_CONVERSION) |
143 | : "state must be " + STATE_ERROR_DURING_CONVERSION + " but is " + getState(); |
144 | return error; |
145 | } |
146 | |
147 | public File getSourceFile() { |
148 | return sourceFile; |
149 | } |
150 | |
151 | public long getSourceFileSize() { |
152 | return sourceFileSize; |
153 | } |
154 | |
155 | public String getState() { |
156 | return state; |
157 | } |
158 | |
159 | public Icon getStateIcon() { |
160 | Icon result; |
161 | String stateImage; |
162 | |
163 | if (getState() == STATE_CANCELLED) { |
164 | stateImage = "statusError"; |
165 | } else if (getState() == STATE_CONVERTING) { |
166 | stateImage = "statusProcessing"; |
167 | } else if (getState() == STATE_DONE) { |
168 | stateImage = "statusDone"; |
169 | } else if (getState() == STATE_ERROR_DURING_CONVERSION) { |
170 | stateImage = "statusError"; |
171 | } else if (getState() == STATE_ERROR_NOT_UNIQUE) { |
172 | stateImage = "statusError"; |
173 | } else if (getState() == STATE_SKIPPED_DUPLICATE) { |
174 | stateImage = "statusWarning"; |
175 | } else if (getState() == STATE_WAITING) { |
176 | stateImage = null; |
177 | } else { |
178 | assert false : "state must be mapped to image: " + getState(); |
179 | stateImage = null; |
180 | } |
181 | if (stateImage != null) { |
182 | String imageResourcePath = "/net/sf/jomic/images/" + stateImage + ".png"; |
183 | URL imageResourceUrl = ConversionReportItem.class.getResource(imageResourcePath); |
184 | |
185 | if (imageResourceUrl == null) { |
186 | // TODO: Localize error message. |
187 | throw new IllegalStateException("cannot find resource: " + imageResourcePath); |
188 | } |
189 | result = new ImageIcon(imageResourceUrl); |
190 | } else { |
191 | result = null; |
192 | } |
193 | return result; |
194 | } |
195 | |
196 | public File getTargetFile() { |
197 | return targetFile; |
198 | } |
199 | |
200 | public long getTargetFileSize() { |
201 | return targetFileSize; |
202 | } |
203 | |
204 | private boolean isValidState() { |
205 | return StringTools.instance().equalsAnyOf(allStates, state); |
206 | } |
207 | |
208 | public void addChangeListener(ChangeListener listener) { |
209 | assert listener != null; |
210 | changeListeners.add(listener); |
211 | } |
212 | |
213 | public void removeChangeListener(ChangeListener listener) { |
214 | assert listener != null; |
215 | changeListeners.remove(listener); |
216 | } |
217 | |
218 | private void fireChange() { |
219 | Iterator rider = changeListeners.iterator(); |
220 | |
221 | while (rider.hasNext()) { |
222 | ChangeListener listener = (ChangeListener) rider.next(); |
223 | ChangeEvent changeEvent = new ChangeEvent(this); |
224 | |
225 | listener.stateChanged(changeEvent); |
226 | } |
227 | } |
228 | } |