Move TSizeConstraint into new package
[fanfix.git] / src / be / nikiroo / fanfix / reader / tui / TuiReaderMainWindow.java
CommitLineData
16a81ef7 1package be.nikiroo.fanfix.reader.tui;
c1873e56 2
bc2ea776 3import java.io.IOException;
c1873e56
NR
4import java.util.ArrayList;
5import java.util.List;
6
5dd985cf 7import jexer.TAction;
ce424b19 8import jexer.TComboBox;
bce88a00
NR
9import jexer.TCommand;
10import jexer.TField;
e2d017a3 11import jexer.TFileOpenBox.Type;
bce88a00 12import jexer.TKeypress;
ce424b19 13import jexer.TLabel;
5dd985cf 14import jexer.TList;
bce88a00 15import jexer.TStatusBar;
5dd985cf 16import jexer.TWindow;
cf9c5ed1 17import jexer.event.TCommandEvent;
bce88a00 18import jexer.event.TKeypressEvent;
e2d017a3 19import jexer.event.TMenuEvent;
ce424b19 20import jexer.event.TResizeEvent;
bc2ea776 21import be.nikiroo.fanfix.Instance;
c1873e56 22import be.nikiroo.fanfix.data.MetaData;
bc2ea776 23import be.nikiroo.fanfix.library.BasicLibrary;
e2d017a3 24import be.nikiroo.fanfix.output.BasicOutput.OutputType;
16a81ef7 25import be.nikiroo.fanfix.reader.Reader;
0bcb5c7f 26import be.nikiroo.jexer.TSizeConstraint;
c1873e56 27
6322ab64
NR
28/**
29 * The library window, that will list all the (filtered) stories available in
bc2ea776 30 * this {@link BasicLibrary}.
6322ab64
NR
31 *
32 * @author niki
33 */
5dd985cf 34class TuiReaderMainWindow extends TWindow {
bce88a00
NR
35 public static final int MENU_SEARCH = 1100;
36 public static final TCommand CMD_SEARCH = new TCommand(MENU_SEARCH) {
37 };
38
b2274262
NR
39 public enum Mode {
40 SOURCE, AUTHOR,
41 }
42
c1873e56
NR
43 private TList list;
44 private List<MetaData> listKeys;
45 private List<String> listItems;
bc2ea776 46 private Reader reader;
b2274262
NR
47
48 private Mode mode = Mode.SOURCE;
49 private String target = null;
bce88a00 50 private String filter = "";
b2274262 51
ce424b19
NR
52 private List<TSizeConstraint> sizeConstraints = new ArrayList<TSizeConstraint>();
53
81a6120d 54 // The 2 comboboxes used to select by source/author
41627937
NR
55 private TComboBox selectTargetBox;
56 private TComboBox selectBox;
6322ab64
NR
57
58 /**
59 * Create a new {@link TuiReaderMainWindow} without any stories in the list.
60 *
61 * @param reader
62 * the reader and main application
63 */
64 public TuiReaderMainWindow(TuiReaderApplication reader) {
c1873e56 65 // Construct a demo window. X and Y don't matter because it will be
bc2ea776 66 // centred on screen.
4f66bfa8 67 super(reader, "Library", 0, 0, 60, 18, CENTERED | RESIZABLE);
c1873e56
NR
68
69 this.reader = reader;
70
c1873e56
NR
71 listKeys = new ArrayList<MetaData>();
72 listItems = new ArrayList<String>();
e9d43c7c 73
ce424b19 74 addList();
41627937 75 addSearch();
81a6120d 76 addSelect();
5dd985cf 77
bce88a00
NR
78 TStatusBar statusBar = reader.setStatusBar(this, "Library");
79 statusBar.addShortcutKeypress(TKeypress.kbCtrlF, CMD_SEARCH, "Search");
c1873e56 80
ce424b19
NR
81 TSizeConstraint.resize(sizeConstraints);
82
bc2ea776
NR
83 // TODO: remove when not used anymore
84
85 // addLabel("Label (1,1)", 1, 1);
86 // addButton("&Button (35,1)", 35, 1, new TAction() {
87 // public void DO() {
88 // }
89 // });
90 // addCheckbox(1, 2, "Checky (1,2)", false);
91 // addProgressBar(1, 3, 30, 42);
92 // TRadioGroup groupy = addRadioGroup(1, 4, "Radio groupy");
93 // groupy.addRadioButton("Fanfan");
94 // groupy.addRadioButton("Tulipe");
95 // addField(1, 10, 20, false, "text not fixed.");
96 // addField(1, 11, 20, true, "text fixed.");
97 // addText("20x4 Text in (12,20)", 1, 12, 20, 4);
98 //
99 // TTreeView tree = addTreeView(30, 5, 20, 5);
100 // TTreeItem root = new TTreeItem(tree, "expended root", true);
101 // tree.setSelected(root); // needed to allow arrow navigation without
102 // // mouse-clicking before
103 //
104 // root.addChild("child");
105 // root.addChild("child 2").addChild("sub child");
106 }
c1873e56 107
ce424b19
NR
108 private void addSearch() {
109 TLabel lblSearch = addLabel("Search: ", 0, 0);
110
111 TField search = new TField(this, 0, 0, 1, true) {
112 @Override
113 public void onKeypress(TKeypressEvent keypress) {
114 super.onKeypress(keypress);
115 TKeypress key = keypress.getKey();
116 if (key.isFnKey() && key.getKeyCode() == TKeypress.ENTER) {
117 TuiReaderMainWindow.this.filter = getText();
118 TuiReaderMainWindow.this.refreshStories();
119 }
120 }
121 };
122
123 TSizeConstraint.setSize(sizeConstraints, lblSearch, 5, 1, null, null);
124 TSizeConstraint.setSize(sizeConstraints, search, 15, 1, -5, null);
125 }
126
127 private void addList() {
128 list = addList(listItems, 0, 0, 10, 10, new TAction() {
129 @Override
130 public void DO() {
131 MetaData meta = getSelectedMeta();
132 if (meta != null) {
133 readStory(meta);
134 }
135 }
136 });
137
138 TSizeConstraint.setSize(sizeConstraints, list, 0, 7, 0, 0);
139 }
140
141 private void addSelect() {
41627937 142 // TODO: i18n
b2274262
NR
143 final List<String> selects = new ArrayList<String>();
144 selects.add("(show all)");
41627937
NR
145 selects.add("Sources");
146 selects.add("Author");
147
148 final List<String> selectTargets = new ArrayList<String>();
149 selectTargets.add("");
ce424b19
NR
150
151 TLabel lblSelect = addLabel("Select: ", 0, 0);
152
41627937
NR
153 TAction onSelect = new TAction() {
154 @Override
155 public void DO() {
156 String smode = selectBox.getText();
41627937
NR
157 boolean showTarget;
158 if (smode == null || smode.equals("(show all)")) {
41627937
NR
159 showTarget = false;
160 } else if (smode.equals("Sources")) {
41627937
NR
161 selectTargets.clear();
162 selectTargets.add("(show all)");
163 for (String source : reader.getLibrary().getSources()) {
164 selectTargets.add(source);
ce424b19 165 }
41627937
NR
166 showTarget = true;
167 } else {
41627937
NR
168 selectTargets.clear();
169 selectTargets.add("(show all)");
170 for (String author : reader.getLibrary().getAuthors()) {
171 selectTargets.add(author);
172 }
173
174 showTarget = true;
175 }
ce424b19 176
41627937
NR
177 selectTargetBox.setVisible(showTarget);
178 selectTargetBox.setEnabled(showTarget);
179 if (showTarget) {
180 selectTargetBox.reflowData();
181 }
182
183 selectTargetBox.setText(selectTargets.get(0));
81a6120d
NR
184 if (showTarget) {
185 TuiReaderMainWindow.this.activate(selectTargetBox);
186 } else {
187 TuiReaderMainWindow.this.activate(list);
188 }
41627937
NR
189 }
190 };
191
192 selectBox = addComboBox(0, 0, 10, selects, 0, -1, onSelect);
41627937
NR
193
194 selectTargetBox = addComboBox(0, 0, 0, selectTargets, 0, -1,
ce424b19
NR
195 new TAction() {
196 @Override
197 public void DO() {
81a6120d
NR
198 if (selectTargetBox.getText().equals(
199 selectTargets.get(0))) {
b2274262
NR
200 setMode(mode, null);
201 } else {
41627937 202 setMode(mode, selectTargetBox.getText());
ce424b19
NR
203 }
204 }
205 });
41627937
NR
206
207 // Set defaults
208 onSelect.DO();
ce424b19
NR
209
210 TSizeConstraint.setSize(sizeConstraints, lblSelect, 5, 3, null, null);
41627937
NR
211 TSizeConstraint.setSize(sizeConstraints, selectBox, 15, 3, -5, null);
212 TSizeConstraint.setSize(sizeConstraints, selectTargetBox, 15, 4, -5,
213 null);
ce424b19
NR
214 }
215
216 @Override
217 public void onResize(TResizeEvent resize) {
218 super.onResize(resize);
219 TSizeConstraint.resize(sizeConstraints);
220 }
221
4f66bfa8
NR
222 @Override
223 public void onClose() {
224 setVisible(false);
225 super.onClose();
226 }
227
e2d017a3 228 /**
bce88a00
NR
229 * Refresh the list of stories displayed in this library.
230 * <p>
231 * Will take the current settings into account (filter, source...).
e2d017a3 232 */
e2d017a3 233 public void refreshStories() {
b2274262
NR
234 List<MetaData> metas;
235 if (mode == Mode.SOURCE) {
236 metas = reader.getLibrary().getListBySource(target);
237 } else if (mode == Mode.AUTHOR) {
238 metas = reader.getLibrary().getListByAuthor(target);
239 } else {
240 metas = reader.getLibrary().getList();
241 }
242
e2d017a3
NR
243 setMetas(metas);
244 }
245
bc2ea776 246 /**
b2274262
NR
247 * Change the author/source filter and display all stories matching this
248 * target.
bc2ea776 249 *
b2274262
NR
250 * @param mode
251 * the new mode or NULL for no sorting
252 * @param target
253 * the actual target for the given mode, or NULL for all of them
bc2ea776 254 */
b2274262
NR
255 public void setMode(Mode mode, String target) {
256 this.mode = mode;
257 this.target = target;
bce88a00 258 refreshStories();
c1873e56
NR
259 }
260
6322ab64
NR
261 /**
262 * Update the list of stories displayed in this {@link TWindow}.
bce88a00
NR
263 * <p>
264 * If a filter is set, only the stories which pass the filter will be
265 * displayed.
6322ab64
NR
266 *
267 * @param metas
268 * the new list of stories to display
269 */
e2d017a3 270 private void setMetas(List<MetaData> metas) {
6322ab64
NR
271 listKeys.clear();
272 listItems.clear();
273
274 if (metas != null) {
275 for (MetaData meta : metas) {
bce88a00
NR
276 String desc = desc(meta);
277 if (filter.isEmpty()
278 || desc.toLowerCase().contains(filter.toLowerCase())) {
279 listKeys.add(meta);
280 listItems.add(desc);
281 }
6322ab64
NR
282 }
283 }
284
285 list.setList(listItems);
81a6120d
NR
286 if (listItems.size() > 0) {
287 list.setSelectedIndex(0);
288 }
6322ab64
NR
289 }
290
e2d017a3
NR
291 public MetaData getSelectedMeta() {
292 if (list.getSelectedIndex() >= 0) {
293 return listKeys.get(list.getSelectedIndex());
294 }
295
296 return null;
297 }
298
299 public void readStory(MetaData meta) {
bc2ea776
NR
300 try {
301 reader.setChapter(-1);
302 reader.setMeta(meta);
303 reader.read();
304 } catch (IOException e) {
62c63b07 305 Instance.getTraceHandler().error(e);
bc2ea776 306 }
c1873e56
NR
307 }
308
309 private String desc(MetaData meta) {
310 return String.format("%5s: %s", meta.getLuid(), meta.getTitle());
311 }
e2d017a3 312
cf9c5ed1
NR
313 @Override
314 public void onCommand(TCommandEvent command) {
315 if (command.getCmd().equals(TuiReaderApplication.CMD_EXIT)) {
316 TuiReaderApplication.close(this);
317 } else {
318 // Handle our own event if needed here
319 super.onCommand(command);
320 }
321 }
322
e2d017a3
NR
323 @Override
324 public void onMenu(TMenuEvent menu) {
325 MetaData meta = getSelectedMeta();
326 if (meta != null) {
327 switch (menu.getId()) {
328 case TuiReaderApplication.MENU_OPEN:
329 readStory(meta);
330
331 return;
332 case TuiReaderApplication.MENU_EXPORT:
333
334 try {
335 // TODO: choose type, pg, error
336 OutputType outputType = OutputType.EPUB;
337 String path = fileOpenBox(".", Type.SAVE);
338 reader.getLibrary().export(meta.getLuid(), outputType,
339 path, null);
340 } catch (IOException e) {
341 // TODO
342 e.printStackTrace();
343 }
344
345 return;
bce88a00 346
e2d017a3
NR
347 case -1:
348 try {
349 reader.getLibrary().delete(meta.getLuid());
350 } catch (IOException e) {
351 // TODO
352 }
353
354 return;
355 }
356 }
357
358 super.onMenu(menu);
359 }
360}