Merge branch 'devel'
[aoi.git] / src / gui_dialogs.cxx
blob5f19bbc83deec7e5bb495aef7aa8973be654ad09
1 /*
2 Copyright 2013 Karel Matas
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.
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.
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/>.
17 #include "gui_dialogs.hxx"
18 #include <FL/fl_ask.H>
19 #include <FL/Fl_Color_Chooser.H>
20 #include <cstring>
21 #include <map>
23 namespace aoi_ui {
25 bool DialogDownload::abort_download_ = false;
27 //////////////////////////////////////////////////////////////////////////
28 // DialogDownload
30 DialogDownload::DialogDownload( int w, int h ) : Fl_Double_Window(w,h)
32 l_url_ = new Fl_Box( 5, 5, 70, 25, "URL");
33 l_fname_ = new Fl_Box( 5, 30, 70, 25, "Filename");
34 b_url_ = new Fl_Button( 85, 5, 310, 25);
35 b_fname_ = new Fl_Button( 85, 30, 310, 25);
36 progress_ = new Fl_Progress( 5, 60, w-10, 30 );
37 b_dload_ = new Fl_Button( 5, 95, 80, 25, "Download" );
38 b_abort_ = new Fl_Button( w-65, 95, 60, 25, "Close");
40 l_url_->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
41 l_fname_->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
42 b_url_->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT|FL_ALIGN_CLIP);
43 b_fname_->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT|FL_ALIGN_CLIP);
45 b_url_->callback( scb_url_callback, (void*)this );
46 b_fname_->callback( scb_fname_callback, (void*)this );
47 b_abort_->callback( scb_abort, (void*)this);
48 b_dload_->callback( scb_download, (void*)this);
49 progress_->minimum(0);
50 progress_->maximum(100);
52 end();
53 label("Download file");
54 set_modal();
55 callback( scb_close_window, (void*)this );
57 curl_global_cleanup();
58 curl_global_init(CURL_GLOBAL_ALL);
62 DialogDownload::~DialogDownload()
64 curl_global_cleanup();
68 void DialogDownload::download_url( const char *url, const char *fname )
70 CURL *curl = nullptr;
71 CURLcode res;
72 FILE *outfile = nullptr;
74 b_abort_->label("Abort");
75 downloading_ = true;
77 curl = curl_easy_init();
78 if(curl)
80 outfile = fopen( fname, "wb");
81 curl_easy_setopt(curl, CURLOPT_URL, url);
82 #ifdef DEBUG
83 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
84 #endif
85 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
86 curl_easy_setopt(curl, CURLOPT_FILE, outfile);
87 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, mycurl_write_func);
88 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, mycurl_progress_func );
89 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, (void*)progress_);
92 res = curl_easy_perform(curl);
93 downloading_ = false;
94 b_abort_->label("Close");
95 abort_download_ = false;
97 if ( res != CURLE_OK ){
98 if ( res == 42 ) // aborted by callback
99 progress_->label("Aborted");
100 else
101 fl_alert( "CURL ERROR %d: %s\n", res, curl_easy_strerror(res) );
103 else{
104 progress_->label("Done");
105 hide();
107 fclose(outfile);
108 curl_easy_cleanup(curl);
113 void DialogDownload::set_names ( const string &url, const string &fname )
115 downloading_ = false;
116 progress_->value(0.0);
117 url_ = url;
118 fname_ = ( fname.empty() ) ? utils::guess_fname_from_url(url_):fname;
119 b_url_->label( url_.c_str() );
120 b_fname_->label( fname_.c_str() );
124 void DialogDownload::abort (){
125 if ( downloading_ ) {
126 if ( !fl_choice("Abort download?", "Abort", "No", 0) ){
127 abort_download_ = true;
130 else {
131 hide();
136 void DialogDownload::cb_download ()
138 if (url_.empty() || fname_.empty() ){
139 fl_alert("You must set URL and filename.");
140 return;
142 download_url( url_.c_str(), fname_.c_str() );
146 void DialogDownload::cb_url_callback ( )
148 const char *ret = fl_input("New URL:", b_url_->label());
149 if ( ret ){
150 url_ = ret;
151 b_url_->label(url_.c_str());
153 fname_ = utils::guess_fname_from_url(url_);
154 b_fname_->label( fname_.c_str() );
158 void DialogDownload::cb_fname_callback ( )
160 const char *ret = fl_input("New filename:", b_fname_->label());
161 if ( ret ){
162 fname_ = ret;
163 b_fname_->label(fname_.c_str());
168 //////////////////////////////////////////////////////////////////////////
169 // DialogEditWord
171 DialogEditWord::DialogEditWord ( int w, int h, const char *l )
172 : Fl_Double_Window(w,h,l)
174 Fl_Box *tmp1 = new Fl_Box( 5, 5, 100, 30, "JMDict id:");
175 l_did_ = new Label( 105, 5, 60, 30 );
176 view_ = new Fl_Help_View(5, 35, w-10, h-80);
177 b_cancel_ = new Fl_Button( w-65, h-35, 60, 30, "Close");
178 end();
179 tmp1->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
180 tmp1->labelfont( FL_BOLD );
181 b_cancel_->callback( scb_cancel, (void*)this );
182 view_->textsize(16);
183 // set_modal();
186 //////////////////////////////////////////////////////////////////////////
187 // ManageDBDialog
189 ManageDBDialog::ManageDBDialog ( int w, int h, const char *l )
190 : Fl_Double_Window(w,h,l)
192 Fl_Box *tmp1 = new Fl_Box( 5, 5, 100, 30, "Main database");
193 tmp1->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
194 tmp1->labelfont( FL_BOLD );
195 b_dload_ = new Fl_Button ( w-85, 5, 80, 20, "Download");
197 Fl_Box *l_main_ = new Fl_Box( 15, 25, 100, 30, "Version" );
198 l_main_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
199 l_main_->labelfont( FL_ITALIC );
200 lver_main_ = new Label( 150, 25, 100, 30, "---");
201 lver_main_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
202 b_check_main_ = new Fl_Button( w-65, 25, 60, 20, "Check");
203 b_check_main_->callback( scb_check_main, (void*)this );
204 b_check_main_->deactivate();
206 Fl_Box *l_created_ = new Fl_Box( 15, 45, 100, 30, "Created");
207 l_created_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
208 l_created_->labelfont( FL_ITALIC );
209 l_main_created_ = new Label( 150, 45, 100, 30, "---");
210 l_main_created_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
212 Fl_Box *l_jmdict_ = new Fl_Box( 15, 65, 100, 30, "JMdict version" );
213 l_jmdict_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
214 l_jmdict_->labelfont( FL_ITALIC );
215 lver_jmdict_ = new Label( 150, 65, 100, 30, "---");
216 lver_jmdict_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
218 Fl_Box *l_kanjidic_ = new Fl_Box( 15, 85, 100, 30, "Kanjidic2 version" );
219 l_kanjidic_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
220 l_kanjidic_->labelfont( FL_ITALIC );
221 lver_kanjidic_ = new Label( 150, 85, 100, 30, "---");
222 lver_kanjidic_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
224 Fl_Box *l_kradfile_ = new Fl_Box( 15, 105, 100, 30, "Kradfile version" );
225 l_kradfile_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
226 l_kradfile_->labelfont( FL_ITALIC );
227 lver_kradfile_ = new Label( 150, 105, 100, 30, "---");
228 lver_kradfile_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
230 Fl_Box *l_tatoeba_ = new Fl_Box( 15, 125, 100, 30, "Tatoeba version" );
231 l_tatoeba_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
232 l_tatoeba_->labelfont( FL_ITALIC );
233 lver_tatoeba_ = new Label( 150, 125, 100, 30, "---");
234 lver_tatoeba_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
236 Fl_Box *tmp2 = new Fl_Box( 5, 165, 100, 30, "User database");
237 tmp2->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
238 tmp2->labelfont( FL_BOLD );
240 Fl_Box *l_against_ = new Fl_Box( 15, 185, 100, 30, "Checked against" );
241 l_against_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
242 l_against_->labelfont( FL_ITALIC );
243 l_checked_against_ = new Label( 150, 185, 100, 30, "---" );
244 l_checked_against_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
245 b_check_user_ = new Fl_Button ( w-65, 185, 60, 20, "Check");
246 b_check_user_->callback( scb_check_user, (void*)this );
247 b_check_user_->deactivate();
250 TITLE N_VALUES EDIT_BTN
251 user notes - kanji # edit_btn
252 user notes - words # edit_btn
253 user flags - kanji # edit_btn
254 user flags - words # edit_btn
258 b_close_ = new Fl_Button( w-65, h-25, 60, 20, "Close" );
259 b_close_->callback( scb_close, (void*)this );
260 end();
261 set_modal();
265 //////////////////////////////////////////////////////////////////////////
266 // KanjiPopupWindow
268 KanjiPopupWindow::KanjiPopupWindow ( int w, int h ) : Fl_Menu_Window(w,h)
270 box_ = new KanjiInfo(0,0,w,h);
271 box_->autoresize(true);
272 box_->box(FL_BORDER_BOX);
273 this->label("Kanji details");
277 int KanjiPopupWindow::handle ( int event )
279 switch(event) {
280 case FL_PUSH:
281 return 1;
282 case FL_DRAG: {
283 int xr = Fl::event_x_root();
284 int yr = Fl::event_y_root();
285 position( xr, yr );
287 return 1;
288 default:
289 return Fl_Widget::handle(event);
294 //////////////////////////////////////////////////////////////////////////
295 // DialogSettings
297 DialogSettings::DialogSettings( int w, int h ) : Fl_Double_Window(w,h)
299 browser_ = new Fl_Hold_Browser( 5, 5, w-10, h-45);
300 b_ok_ = new Fl_Button( w-65, h-35, 60, 30, "OK" );
301 b_defaults_= new Fl_Button( 5, h-35, 60, 30, "Defaults");
302 browser_->format_char('@');
303 resizable(browser_);
304 end();
305 label("Settings");
306 set_modal();
307 browser_->callback(static_callback, (void*)this);
308 b_ok_->callback( static_ok, (void*)this );
309 b_defaults_->callback( scb_restore_defaults, (void*)this );
313 void DialogSettings::set ( const std::map<string,Config::Value> &m, const std::map<string,Config::Value> &defaults ){
314 browser_->clear();
315 data_ = m;
316 defaults_ = defaults.empty() ? m:defaults;
317 for ( auto mi: data_ ){
318 string s = "@r@_";
319 if ( mi.second.type == Config::ValueType::COLOR ){
320 char buff[32];
321 sprintf(buff, "%s", mi.second.val.c_str() );
322 s += buff;
324 else
325 s += mi.second.val;
326 browser_->add( mi.first.c_str(), (void*)(mi.first.c_str()) );
327 browser_->add( s.c_str(), (void*)(mi.first.c_str()) );
332 std::map<string,Config::Value> DialogSettings::run ()
334 show();
335 while ( visible() ){
336 usleep(1000);
337 Fl::check();
339 return data_;
343 int DialogSettings::handle ( int event )
345 if ( event==FL_KEYDOWN && (Fl::event_key()==FL_Enter || Fl::event_key()==' ') ){
346 int line = browser_->value();
347 if ( line > 0 ){
348 cb(line);
349 return 1;
352 return Fl_Double_Window::handle( event );
356 void DialogSettings::cb ( int line )
358 // not double click nor ENTER/Spacebar
359 if ( Fl::event_key()!=FL_Enter && Fl::event_key()!=' ' && !Fl::event_clicks() )
360 return;
362 const char *var = (const char*)(browser_->data(line));
363 Config::Value *val = &data_.at(var);
365 fl_message_title(var);
367 // value clicked, display appropriate dialog
368 if ( line % 2 == 0 ){
369 switch ( val->type ){
370 case Config::ValueType::BOOL:
371 case Config::ValueType::INT:
373 const char *res = fl_input( var, val->val.c_str());
374 if ( !res )
375 break;
376 if ( !utils::isint(res) ){
377 fl_alert("Only integers allowed.");
378 break;
380 val->val = res;
381 char buff[32];
382 snprintf( buff, 32, "@r@_%s", res);
383 browser_->text( line, buff );
384 break;
386 case Config::ValueType::FONT:
388 DialogFontTest df;
389 df.set_modal();
390 int f = df.run();
391 if ( f == -1 )
392 break;
393 val->val = Fl::get_font_name(f);
394 char buff[128];
395 snprintf( buff, 128, "@r@_%s", val->val.c_str());
396 browser_->text( line, buff );
397 break;
399 case Config::ValueType::COLOR:
401 uchar r = 0;
402 uchar g = 0;
403 uchar b = 0;
404 std::stringstream ss;
405 ss << std::hex << val->val.substr(2);
406 Fl_Color c;
407 ss >> c;
408 Fl::get_color( c, r, g, b);
409 if ( fl_color_chooser("Select color", r, g, b ) ){
410 char buff[32];
411 int col = fl_rgb_color(r,g,b);
412 snprintf( buff, 32, "0x%08x", col);
413 val->val = buff;
414 snprintf( buff, 32, "@r@_0x%08x", col);
415 browser_->text( line, buff );
417 break;
419 default:
421 const char *res = fl_input( var, val->val.c_str());
422 if ( res ){
423 val->val = res;
424 char buff[256];
425 snprintf( buff, 256, "@r@_%s", res);
426 browser_->text( line, buff );
428 break;
432 // variable name clicked - show description
433 else {
434 fl_message("%s",val->desc.c_str());
438 } // namespace aoi_ui