1 // $Id$
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 
6 #include "gettext.h"
7 
8 #include <unistd.h>
9 #include <cassert>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <sstream>
14 
15 #include "yacurs.h"
16 
17 // Used when preloading libtestpreload.so
18 #ifdef YACURS_USE_WCHAR
19 wint_t
20 #else
21 int
22 #endif
23     __test_data_1[] = {
24         // Open dialog
25         '\n',
26 
27         // Up one dir
28         KEY_DOWN, '\n',
29 
30         // Up one dir
31         KEY_DOWN, '\n',
32 
33         // Up one dir
34         KEY_DOWN, '\n',
35 
36         // Up one dir
37         KEY_DOWN, '\n',
38 
39         // Up one dir
40         KEY_DOWN, '\n',
41 
42         // Up one dir
43         KEY_DOWN, '\n',
44 
45         // Up one dir
46         KEY_DOWN, '\n',
47 
48         // Up one dir
49         KEY_DOWN, '\n',
50 
51         // Up one dir
52         KEY_DOWN, '\n',
53 
54         // Up one dir
55         KEY_DOWN, '\n',
56 
57         // Up one dir
58         KEY_DOWN, '\n',
59 
60         // Up one dir
61         KEY_DOWN, '\n',
62 
63         0};
64 
65 #ifdef YACURS_USE_WCHAR
66 wint_t
67 #else
68 int
69 #endif
70     __dir_up_data[] = {KEY_DOWN, '\n',     KEY_DOWN, '\n',     KEY_DOWN,
71                        '\n',     KEY_DOWN, '\n',     KEY_DOWN, '\n',
72                        KEY_DOWN, '\n',     KEY_DOWN, '\n',     KEY_DOWN,
73                        '\n',     KEY_DOWN, '\n',     KEY_DOWN, '\n'};
74 
75 // Quit dialog
76 #ifdef YACURS_USE_WCHAR
77 wint_t
78 #else
79 int
80 #endif
81     __test_data_end_dialog[] = {'\t', '\t', '\t', '\t', '\n', 0};
82 
83 // Quit app
84 #ifdef YACURS_USE_WCHAR
85 wint_t
86 #else
87 int
88 #endif
89     __test_data_end_app[] = {'\t', '\t', '\n', 0};
90 
91 int* selection1[61];
92 
select_item()93 int select_item() {
94     int tmp;
95 
96     while ((tmp = (int)(drand48() * 100) % 20) < 2)
97         ;
98 
99     return tmp;
100 }
101 
quit()102 void quit() { YACURS::EventQueue::submit(YACURS::EVT_QUIT); }
103 
104 #ifdef YACURS_USE_WCHAR
__test_wget_wch(void *,wint_t * i)105 extern "C" int __test_wget_wch(void*, wint_t* i) {
106     static wint_t* ptr1 = __test_data_1;
107     static wint_t* ptr_end_dialog = __test_data_end_dialog;
108     static wint_t* ptr_end_app = __test_data_end_app;
109     static int selection_index = 0;
110     static int selection_index2 = 0;
111 
112 #ifdef SLOW_TESTS
113     usleep(70000);
114 #endif
115 
116     // Open dialog
117     if (*ptr1 != 0) {
118         *i = *ptr1++;
119         return OK;
120     }
121 
122     if (selection1[selection_index] != 0) {
123         if (selection1[selection_index][selection_index2] != 0) {
124             *i = selection1[selection_index][selection_index2++];
125             return OK;
126         } else {
127             if (selection1[selection_index + 1] != 0) {
128                 *i = selection1[++selection_index][selection_index2 = 0];
129                 return OK;
130             }
131         }
132     }
133 
134     if (*ptr_end_dialog != 0) {
135         *i = *ptr_end_dialog++;
136         return OK;
137     }
138 
139     if (*ptr_end_app != 0) {
140         *i = *ptr_end_app++;
141         return OK;
142     }
143 
144     return ERR;
145 }
146 #else
__test_wgetch(void *)147 extern "C" int __test_wgetch(void*) {
148     static int* ptr1 = __test_data_1;
149     static int* ptr_end_dialog = __test_data_end_dialog;
150     static int* ptr_end_app = __test_data_end_app;
151     static int selection_index = 0;
152     static int selection_index2 = 0;
153 
154 #ifdef SLOW_TESTS
155     usleep(70000);
156 #endif
157 
158     // Open dialog
159     if (*ptr1 != 0) return *ptr1++;
160 
161     if (selection1[selection_index] != 0) {
162         if (selection1[selection_index][selection_index2] != 0) {
163             return selection1[selection_index][selection_index2++];
164         } else {
165             if (selection1[selection_index + 1] != 0)
166                 return selection1[++selection_index][selection_index2 = 0];
167         }
168     }
169 
170     if (*ptr_end_dialog != 0) return *ptr_end_dialog++;
171 
172     if (*ptr_end_app != 0) return *ptr_end_app++;
173 
174     return 0;
175 }
176 #endif
177 
178 class MainWindow : public YACURS::Window {
179    private:
180     YACURS::VPack* vpack1;
181     YACURS::HPack* hpack2;
182     YACURS::VPack* vpack21;
183     YACURS::VPack* vpack22;
184     YACURS::HPack* hpack1;
185     YACURS::Button* button1;
186     YACURS::Button* button2;
187     YACURS::Button* button3;
188     YACURS::Label* diagstatus;
189     YACURS::Label* file;
190     YACURS::Label* path;
191     YACURS::Label* filepath;
192     YACURS::DynLabel* label1;
193     YACURS::DynLabel* label2;
194     YACURS::DynLabel* label3;
195     YACURS::DynLabel* label4;
196     YACURS::FileSaveDialog* filesavedialog;
197     YACURS::FileLoadDialog* fileloaddialog;
198 
199    protected:
window_close_handler(YACURS::Event & _e)200     void window_close_handler(YACURS::Event& _e) {
201         assert(_e == YACURS::EVT_WINDOW_CLOSE);
202         YACURS::EventEx<YACURS::WindowBase*>& evt =
203             dynamic_cast<YACURS::EventEx<YACURS::WindowBase*>&>(_e);
204 
205         if (filesavedialog != 0 && evt.data() == filesavedialog) {
206             YACURS::Curses::statusbar()->push("FileSaveDialog closed");
207 
208             if (filesavedialog->dialog_state() == YACURS::DIALOG_OK) {
209                 label1->label("DIALOG_OK");
210                 label2->label(filesavedialog->filepath());
211                 label3->label(filesavedialog->directory());
212                 label4->label(filesavedialog->filename());
213             } else {
214                 label1->label("DIALOG_CANCEL");
215                 label2->label("");
216                 label3->label("");
217                 label4->label("");
218             }
219 
220             delete filesavedialog;
221             filesavedialog = 0;
222         }
223 
224         if (fileloaddialog != 0 && evt.data() == fileloaddialog) {
225             YACURS::Curses::statusbar()->push("FileLoadDialog closed");
226 
227             if (fileloaddialog->dialog_state() == YACURS::DIALOG_OK) {
228                 label1->label("DIALOG_OK");
229                 label2->label(fileloaddialog->filepath());
230                 label3->label(fileloaddialog->directory());
231                 label4->label(fileloaddialog->filename());
232             } else {
233                 label1->label("DIALOG_CANCEL");
234                 label2->label("");
235                 label3->label("");
236                 label4->label("");
237             }
238 
239             delete fileloaddialog;
240             fileloaddialog = 0;
241         }
242     }
243 
button_press_handler(YACURS::Event & _e)244     void button_press_handler(YACURS::Event& _e) {
245         assert(_e == YACURS::EVT_BUTTON_PRESS);
246         YACURS::EventEx<YACURS::Button*>& e =
247             dynamic_cast<YACURS::EventEx<YACURS::Button*>&>(_e);
248 
249         if (e.data() == button1) {
250             assert(filesavedialog == 0);
251 
252             filesavedialog = new YACURS::FileSaveDialog;
253             filesavedialog->show();
254             return;
255         }
256 
257         if (e.data() == button3) {
258             assert(fileloaddialog == 0);
259 
260             fileloaddialog = new YACURS::FileLoadDialog;
261             fileloaddialog->show();
262             return;
263         }
264 
265         if (e.data() == button2) {
266             YACURS::EventQueue::submit(YACURS::EVT_QUIT);
267             return;
268         }
269     }
270 
271    public:
MainWindow()272     MainWindow()
273         : YACURS::Window(YACURS::Margin(1, 0, 1, 0)),
274           filesavedialog(0),
275           fileloaddialog(0) {
276         button1 = new YACURS::Button("File Save");
277         button3 = new YACURS::Button("File Load");
278         button2 = new YACURS::Button("Quit");
279         vpack1 = new YACURS::VPack;
280         hpack1 = new YACURS::HPack;
281         label1 = new YACURS::DynLabel;
282         label2 = new YACURS::DynLabel;
283         label3 = new YACURS::DynLabel;
284         label4 = new YACURS::DynLabel;
285 
286         diagstatus = new YACURS::Label("Dialog Status:");
287         file = new YACURS::Label("File:");
288         path = new YACURS::Label("Path:");
289         filepath = new YACURS::Label("File Path:");
290 
291         hpack2 = new YACURS::HPack;
292         vpack21 = new YACURS::VPack;
293         vpack22 = new YACURS::VPack;
294 
295         // vpack21->always_automatic(true);
296         vpack22->always_dynamic(true);
297         vpack22->hinting(false);
298         hpack2->always_dynamic(true);
299         hpack2->hinting(false);
300 
301         hpack2->add_back(vpack21);
302         hpack2->add_back(vpack22);
303 
304         vpack21->add_back(diagstatus);
305         vpack21->add_back(filepath);
306         vpack21->add_back(path);
307         vpack21->add_back(file);
308 
309         vpack22->add_front(label4);
310         vpack22->add_front(label3);
311         vpack22->add_front(label2);
312         vpack22->add_front(label1);
313 
314         hpack1->add_back(button1);
315         hpack1->add_back(button3);
316         hpack1->add_back(button2);
317 
318         vpack1->add_back(hpack2);
319         vpack1->add_back(hpack1);
320 
321         widget(vpack1);
322 
323         YACURS::EventQueue::connect_event(
324             YACURS::EventConnectorMethod1<MainWindow>(
325                 YACURS::EVT_BUTTON_PRESS, this,
326                 &MainWindow::button_press_handler));
327         YACURS::EventQueue::connect_event(
328             YACURS::EventConnectorMethod1<MainWindow>(
329                 YACURS::EVT_WINDOW_CLOSE, this,
330                 &MainWindow::window_close_handler));
331     }
332 
~MainWindow()333     ~MainWindow() {
334         if (filesavedialog) delete filesavedialog;
335         if (fileloaddialog) delete fileloaddialog;
336 
337         delete button1;
338         delete button2;
339         delete button3;
340         delete hpack1;
341         delete vpack1;
342         delete label1;
343         delete label2;
344         delete label3;
345         delete label4;
346         delete hpack2;
347         delete vpack21;
348         delete vpack22;
349         delete diagstatus;
350         delete file;
351         delete path;
352         delete filepath;
353 
354         YACURS::EventQueue::disconnect_event(
355             YACURS::EventConnectorMethod1<MainWindow>(
356                 YACURS::EVT_BUTTON_PRESS, this,
357                 &MainWindow::button_press_handler));
358         YACURS::EventQueue::disconnect_event(
359             YACURS::EventConnectorMethod1<MainWindow>(
360                 YACURS::EVT_WINDOW_CLOSE, this,
361                 &MainWindow::window_close_handler));
362     }
363 };
364 
main()365 int main() {
366     // test will not be run if stdout or stdin is not a tty.
367     if (isatty(STDOUT_FILENO) != 1 || isatty(STDIN_FILENO) != 1) exit(77);
368 
369 #if 0
370     std::cout << getpid() << std::endl;
371     sleep(15);
372 #endif
373 
374 #ifdef YACURS_USE_WCHAR
375     if (setlocale(LC_ALL, "en_US.UTF-8") == 0) exit(77);
376 #endif
377 #ifdef ENABLE_NLS
378     bindtextdomain("filedialog2", LOCALEDIR);
379     textdomain("filedialog2");
380 #endif
381 
382     srand48(time(0));
383 
384     // Initialize test data
385     for (int i = 0; i < 30; i++) {
386         if (i % 2 == 0) {
387             int tmp = select_item();
388             selection1[i] = (int*)calloc(tmp + 2, sizeof(int));
389 
390             for (int n = 0; n < tmp; n++) selection1[i][n] = KEY_DOWN;
391 
392             selection1[i][tmp] = '\n';
393             selection1[i][tmp + 1] = 0;
394         } else {
395             selection1[i] = (int*)calloc(21, sizeof(int));
396             std::memcpy(selection1[i], __dir_up_data, 20 * sizeof(int));
397             selection1[i][20] = 0;
398         }
399     }
400 
401     selection1[60] = 0;
402 
403     try {
404         YACURS::Curses::init();
405 
406         YACURS::Curses::title(
407             new YACURS::TitleBar(YACURS::TitleBar::POS_TOP, "FileDialog 2"));
408         YACURS::Curses::statusbar(new YACURS::StatusBar);
409 
410         YACURS::Curses::mainwindow(new MainWindow);
411         YACURS::Curses::mainwindow()->frame(true);
412 
413         YACURS::Curses::run();
414 
415         delete YACURS::Curses::mainwindow();
416         delete YACURS::Curses::title();
417         delete YACURS::Curses::statusbar();
418 
419         YACURS::Curses::end();
420     } catch (std::exception& e) {
421         YACURS::Curses::end();
422         std::cerr << e.what() << std::endl;
423         return 1;
424     }
425 
426     for (int i = 0; i < 30; i++) std::free(selection1[i]);
427 
428     return 0;
429 }
430