itinial example sentences;added gUI::html_view;doxygen comments
[aoi.git] / src / gui_dialogs.cxx
blob99c917c605e5b253cc07a53f74c9ecd7b21387bd
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");
196 b_dload_->callback( scb_dload, (void*)this );
198 Fl_Box *l_main_ = new Fl_Box( 15, 25, 100, 30, "Version" );
199 l_main_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
200 l_main_->labelfont( FL_ITALIC );
201 lver_main_ = new Label( 150, 25, 100, 30, "---");
202 lver_main_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
203 b_check_main_ = new Fl_Button( w-65, 25, 60, 20, "Check");
204 b_check_main_->callback( scb_check_main, (void*)this );
205 b_check_main_->deactivate();
207 Fl_Box *l_created_ = new Fl_Box( 15, 45, 100, 30, "Created");
208 l_created_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
209 l_created_->labelfont( FL_ITALIC );
210 l_main_created_ = new Label( 150, 45, 100, 30, "---");
211 l_main_created_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
213 Fl_Box *l_jmdict_ = new Fl_Box( 15, 65, 100, 30, "JMdict version" );
214 l_jmdict_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
215 l_jmdict_->labelfont( FL_ITALIC );
216 lver_jmdict_ = new Label( 150, 65, 100, 30, "---");
217 lver_jmdict_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
219 Fl_Box *l_kanjidic_ = new Fl_Box( 15, 85, 100, 30, "Kanjidic2 version" );
220 l_kanjidic_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
221 l_kanjidic_->labelfont( FL_ITALIC );
222 lver_kanjidic_ = new Label( 150, 85, 100, 30, "---");
223 lver_kanjidic_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
225 Fl_Box *l_kradfile_ = new Fl_Box( 15, 105, 100, 30, "Kradfile version" );
226 l_kradfile_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
227 l_kradfile_->labelfont( FL_ITALIC );
228 lver_kradfile_ = new Label( 150, 105, 100, 30, "---");
229 lver_kradfile_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
231 Fl_Box *l_tatoeba_ = new Fl_Box( 15, 125, 100, 30, "Tatoeba version" );
232 l_tatoeba_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
233 l_tatoeba_->labelfont( FL_ITALIC );
234 lver_tatoeba_ = new Label( 150, 125, 100, 30, "---");
235 lver_tatoeba_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
237 Fl_Box *tmp2 = new Fl_Box( 5, 165, 100, 30, "User database");
238 tmp2->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
239 tmp2->labelfont( FL_BOLD );
241 Fl_Box *l_against_ = new Fl_Box( 15, 185, 100, 30, "Checked against" );
242 l_against_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
243 l_against_->labelfont( FL_ITALIC );
244 l_checked_against_ = new Label( 150, 185, 100, 30, "---" );
245 l_checked_against_->align( FL_ALIGN_INSIDE|FL_ALIGN_LEFT );
246 b_check_user_ = new Fl_Button ( w-65, 185, 60, 20, "Check");
247 b_check_user_->callback( scb_check_user, (void*)this );
248 b_check_user_->deactivate();
251 TITLE N_VALUES EDIT_BTN
252 user notes - kanji # edit_btn
253 user notes - words # edit_btn
254 user flags - kanji # edit_btn
255 user flags - words # edit_btn
259 b_close_ = new Fl_Button( w-65, h-25, 60, 20, "Close" );
260 b_close_->callback( scb_close, (void*)this );
261 end();
262 set_modal();
266 //////////////////////////////////////////////////////////////////////////
267 // KanjiPopupWindow
269 KanjiPopupWindow::KanjiPopupWindow ( int w, int h ) : Fl_Menu_Window(w,h)
271 box_ = new KanjiInfo(0,0,w,h);
272 box_->autoresize(true);
273 box_->box(FL_BORDER_BOX);
274 this->label("Kanji details");
278 int KanjiPopupWindow::handle ( int event )
280 switch(event) {
281 case FL_PUSH:
282 return 1;
283 case FL_DRAG: {
284 int xr = Fl::event_x_root();
285 int yr = Fl::event_y_root();
286 position( xr, yr );
288 return 1;
289 default:
290 return Fl_Widget::handle(event);
295 //////////////////////////////////////////////////////////////////////////
296 // DialogSettings
298 DialogSettings::DialogSettings( int w, int h ) : Fl_Double_Window(w,h)
300 browser_ = new Fl_Hold_Browser( 5, 5, w-10, h-45);
301 b_ok_ = new Fl_Button( w-65, h-35, 60, 30, "OK" );
302 b_defaults_= new Fl_Button( 5, h-35, 60, 30, "Defaults");
303 browser_->format_char('@');
304 resizable(browser_);
305 end();
306 label("Settings");
307 set_modal();
308 browser_->callback(static_callback, (void*)this);
309 b_ok_->callback( static_ok, (void*)this );
310 b_defaults_->callback( scb_restore_defaults, (void*)this );
314 void DialogSettings::set ( const std::map<string,Config::Value> &m, const std::map<string,Config::Value> &defaults ){
315 browser_->clear();
316 data_ = m;
317 defaults_ = defaults.empty() ? m:defaults;
318 for ( auto mi: data_ ){
319 string s = "@r@_";
320 if ( mi.second.type == Config::ValueType::COLOR ){
321 char buff[32];
322 sprintf(buff, "%s", mi.second.val.c_str() );
323 s += buff;
325 else
326 s += mi.second.val;
327 browser_->add( mi.first.c_str(), (void*)(mi.first.c_str()) );
328 browser_->add( s.c_str(), (void*)(mi.first.c_str()) );
333 std::map<string,Config::Value> DialogSettings::run ()
335 show();
336 while ( visible() ){
337 usleep(1000);
338 Fl::check();
340 return data_;
344 int DialogSettings::handle ( int event )
346 if ( event==FL_KEYDOWN && (Fl::event_key()==FL_Enter || Fl::event_key()==' ') ){
347 int line = browser_->value();
348 if ( line > 0 ){
349 cb(line);
350 return 1;
353 return Fl_Double_Window::handle( event );
357 void DialogSettings::cb ( int line )
359 // not double click nor ENTER/Spacebar
360 if ( Fl::event_key()!=FL_Enter && Fl::event_key()!=' ' && !Fl::event_clicks() )
361 return;
363 const char *var = (const char*)(browser_->data(line));
364 Config::Value *val = &data_.at(var);
366 fl_message_title(var);
368 // value clicked, display appropriate dialog
369 if ( line % 2 == 0 ){
370 switch ( val->type ){
371 case Config::ValueType::BOOL:
372 case Config::ValueType::INT:
374 const char *res = fl_input( var, val->val.c_str());
375 if ( !res )
376 break;
377 if ( !utils::isint(res) ){
378 fl_alert("Only integers allowed.");
379 break;
381 val->val = res;
382 char buff[32];
383 snprintf( buff, 32, "@r@_%s", res);
384 browser_->text( line, buff );
385 break;
387 case Config::ValueType::FONT:
389 DialogFontTest df;
390 df.set_modal();
391 int f = df.run();
392 if ( f == -1 )
393 break;
394 val->val = Fl::get_font_name(f);
395 char buff[128];
396 snprintf( buff, 128, "@r@_%s", val->val.c_str());
397 browser_->text( line, buff );
398 break;
400 case Config::ValueType::COLOR:
402 uchar r = 0;
403 uchar g = 0;
404 uchar b = 0;
405 std::stringstream ss;
406 ss << std::hex << val->val.substr(2);
407 Fl_Color c;
408 ss >> c;
409 Fl::get_color( c, r, g, b);
410 if ( fl_color_chooser("Select color", r, g, b ) ){
411 char buff[32];
412 int col = fl_rgb_color(r,g,b);
413 snprintf( buff, 32, "0x%08x", col);
414 val->val = buff;
415 snprintf( buff, 32, "@r@_0x%08x", col);
416 browser_->text( line, buff );
418 break;
420 default:
422 const char *res = fl_input( var, val->val.c_str());
423 if ( res ){
424 val->val = res;
425 char buff[256];
426 snprintf( buff, 256, "@r@_%s", res);
427 browser_->text( line, buff );
429 break;
433 // variable name clicked - show description
434 else {
435 fl_message("%s",val->desc.c_str());
439 } // namespace aoi_ui