How to issue Callback from Fl_Native_File_Chooser?

21 views
Skip to first unread message

b...@cadamail.com

unread,
Dec 29, 2017, 5:09:05 PM12/29/17
to fltkg...@googlegroups.com
I have a small project which requires a callback after the user has
selected a file from Fl_Native_File_Chooser. Unfortunately, I have been
unable to find any callback method.

Is there a known work around for this?

Complete source code for reference:
https://0bin.net/paste/1PPYEXnCzIGQRzuu#5m-jA1E+13U2cZK9R3uuQ3ZX1TweTddx21I+ys5InXp

Needs a callback inserted on Line 99, which would automatically open and
parse the file once user selects.

Greg Ercolano

unread,
Dec 29, 2017, 5:10:05 PM12/29/17
to fltkg...@googlegroups.com
You can use:
rbutton1->do_callback();

Greg Ercolano

unread,
Dec 29, 2017, 5:21:59 PM12/29/17
to fltkg...@googlegroups.com
Oh, and I should add, looks like rbutton1 is not in scope here.

The easiest thing would be to change rbutton1 to be a global
so you can access it as above.

Or, if you want to keep rbutton1 local to main(), then pass it
as userdata to browse_function, e.g. in main() change:

-button1->callback(browse_function);
+button1->callback(browse_function, (void*)rbutton1);

..so that you can then access it in browse_function() by changing:

void browse_function(Fl_Widget *o, void *) {
Fl_Native_File_Chooser fnfc;
..
..to instead read:

void browse_function(Fl_Widget *o, void *data) {
Fl_Radio_Round_Button *rbutton1 = (Fl_Radio_Round_Button*)data;
Fl_Native_File_Chooser fnfc;
..

The other way to go, it appears your rbutton1_function() doesn't
do anything with the Fl_Widget or void* arguments, in which case
you could just call the global function directly at line 99, e.g.

rbutton1_function(0,0);

..but that's a little hacky.

The "Right Thing" to do would be to make an Application class,
and make your rbutton1 a member, and then pass around 'this'
(pointer to your app class) as userdata to all callbacks, so
that the callbacks can all access members/methods in the class.

That'd rearrange your code quite a bit, putting almost everything
into a class. But that'd be 'the right thing' if you want to avoid
the above "small program" techniques.

Greg Ercolano

unread,
Dec 29, 2017, 5:29:24 PM12/29/17
to fltkg...@googlegroups.com
On 12/28/17 12:46, b...@cadamail.com wrote:
    Oh, and in case the above link has gone stale (years from now, when people might be reading this thread), here's the code in question; it's a single file
    and small enough to post here on the list directly:

  1. //g++ -I/usr/include -I/usr/include/fltk -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -o 'test' 'test_fltkcrypto.cpp' /usr/lib64/fltk/libfltk.a -lXrender -lXcursor -lXfixes -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm -lX11 -lcryptopp -std=c++14
  2. // http://seriss.com/people/erco/fltk/
  3. // Include FLTK headers
  4. #include <FL/Fl.H>
  5. #include <FL/Fl_Window.H>
  6. #include <FL/Fl_Button.H>
  7. #include <FL/Fl_Radio_Round_Button.H>
  8. #include <FL/Fl_Native_File_Chooser.H < /span>>
  9. #include <FL/Fl_Output.H>
  10. // Include Crypto++ headers
  11. #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 // For MD5 hash function
  12. #include <cryptopp/md5.h>
  13. #include <cryptopp/hex.h>
  14. #include <cryptopp/files.h>
  15. // Include standard headers
  16. #include <string>
  17. #include <iostream>
  18.  
  19. // Setup our function references so compiler knows to go find them.
  20. void rbutton1_function(Fl_Widget *o, void*);
  21. void browse_function(Fl_Widget *o, void*);
  22. // Set global command line args for all functions
  23. int user_browsed;
  24. int g_argc;
  25. char **g_argv;
  26. char *s1;
  27. Fl_Input* input; // Set global input box var
  28. Fl_Output* output; // Set global out box var
  29. std::string result; // set global result var
  30. std::string filename = ""; // Set global file var
  31. std::string browsed_filename = "";
  32.  
  33. // =======================
  34. // Hash Function by button
  35. // =======================
  36. void rbutton1_function(Fl_Widget *o, void*) {
  37. result = ""; // Clear result from any previous entry
  38. if (user_browsed == 0) {
  39. std::cout << user_browsed << std::endl;
  40. std::string filename = g_argv[1];
  41. std::cout << filename < /span><< std::endl;
  42. std::cout << "Clicked MD5!" << std::endl;
  43.  
  44. // Start MD5 Hashing process
  45. CryptoPP::Weak::MD5 hash;
  46. CryptoPP::FileSource(filename.c_str(),true,
  47. new CryptoPP::HashFilter(hash, new CryptoPP::HexEncoder(
  48. new CryptoPP::StringSink(res u lt), true)));
  49.  
  50. // Print result to terminal and Fl_Outbox.
  51. std::cout << result << std::endl;
  52. const char * hash_out_c = result.c_str();
  53. output->value(hash_out_c);
  54. output->redraw();
  55. }
  56.  
  57. else if (user_browsed == 1) {
  58. std::cout << user_browsed < / span><< std::endl;
  59. std::string filename = browsed_filename;
  60. std::cout << filename << std::endl;
  61. std::cout << "Clicked MD5!" << std< / span>::endl;
  62.  
  63. // Start MD5 Hashing process
  64. CryptoPP::Weak::MD5 hash;
  65. CryptoPP::FileSource(filename.c_str(),true,
  66. new CryptoPP::HashFilter(hash, new CryptoPP::HexEncoder(
  67. new CryptoPP::StringSink(result), true)));
  68.  
  69. // Print result to terminal and Fl_Outbox.
  70. std::cout << result << std::endl;
  71. const char * hash_out_c = result.c_str();
  72. output->value(hash_out_c);
  73. output->redraw();
  74. }
  75. }
  76. // ===============
  1.  
  2. void browse_function(Fl_Widget *o, void *) {
  3. Fl_Native_File_Chooser fnfc;
  1. fnfc.title("Pick a file");
  2. fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
  3. fnfc.filter("Text\t*.txt\n"
  4. "C Files\t*.{cxx,h,c}");
  5. fnfc.directory("/var/tmp"); // default directory to use
  6. // Show native chooser
  7. switch ( fnfc < span class="pun">.show() ) {
  8. case -1: printf("ERROR: %s\n", fnfc.errmsg()); break; // ERROR
  9. case 1: printf("CANCEL \ n"); break; // CANCEL
  10. default:
  11. // Dirty hack to override argv from user selected file.
  12. s1 = (char *)fnfc.filename();
  13. ::browsed_filename = s1;
  14. // test: printf("%s", s1);
  15. //::g_argv[1] = s1; // Override argv
  16. //::filename = s1; // override filename
  17. printf("\nPICKED: %s\n", fnfc.filename()); break; // FILE CHOSEN
  18.  
  19.  
  20. // TODO: Callback to MD5 func t ion (or user selected) <-----------
  21. // Need to call "rbutton1->callback(rbutton1_function);" <--- ???
  22.  
  23. }
  24. user_browsed = 1;
  25. }
  26.  
  27.  
  28. int main(int argc, char **argv) {
  29. //std::string filename = g_argv[1]; // Get filename from command line argument 1
  30. // Pass command line arguments back to global variable, so that other functions can access them.
  31. g_argc = argc;
  32. g_argv = argv;
  33.  
  34. // Ugly Hack to avoid segfault if no file loaded...
  35. if (filename == "") {
  36. std::cout << "Error: We couldn't find a filename!" << std::endl;
  37. std::string filename = "test.cpp";
  38. std::string browsed_filename = "test.cpp";
  39. ::g_argv[1] = (char *)filename.c_str();
  40. std::cout << filename << std::endl;
  41. std::cout << browsed_filename << std::endl;
  42. }
  43. //
  44.  
  45. // Setup Window
  46. Fl_Window *window = new Fl_Window(300,200, "Yet Another Ha s h Tool");
  47.  
  48. //if (filename == "") {
  49. //std::cout << "Error: We couldn't find a filename!" << std::endl;
  50. //window->callback(browse_function);
  51. //window->redraw();
  52. //}
  53.  
  54. Fl_Output output(60,10,220,20, "Hash:");
  55. ::output = &output; // Magical unkown cast to prevent segfault and make make things work...
  56. output.value("load a file...");
  57. output.color(FL_BLACK);
  58. output. textcolor(FL_GREEN);
  59. // Setup Hash Radio_Round_Buttons
  60. Fl_Radio_Round_Button *rbutton1 = new Fl_Radio_Round_Button(5, 25, 50, 30, "MD5");
  61. &n b sp;
  62. rbutton1->callback(rbutton1_function);
  63.  
  64. Fl_Button *button1 = new Fl_Button( 5, 140, 100, 30, "Browse");
  65. button1->callback(browse_function);
  66.  
  67. window->end();
  68. window->show();
  69. return Fl::run();
  70. }

Greg Ercolano

unread,
Dec 29, 2017, 5:49:45 PM12/29/17
to fltkg...@googlegroups.com
On 12/29/17 14:29, Greg Ercolano wrote:
> On 12/28/17 12:46, b...@cadamail.com wrote:
>> Complete source code for reference:
>> https://0bin.net/paste/1PPYEXnCzIGQRzuu#5m-jA1E+13U2cZK9R3uuQ3ZX1TweTddx21I+ys5InXp
>
> Oh, and in case the above link has gone stale..

OK, bear with me a sec; my Thunderbird mail client totally mangled
the OP's code when I pasted it. (The WYSIWYG preview looked OK, but
reading it back through the forum showed random html tags mixed in)

Trying again as plain text.
Hopefully anyone wanting to compile the OP's code below would have
a decent text editor with rectangular selection to remove the line#s..

* * *

1: //g++ -I/usr/include -I/usr/include/fltk -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -o 'test' 'test_fltkcrypto.cpp' /usr/lib64/fltk/libfltk.a -lXrender -lXcursor -lXfixes -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm -lX11 -lcryptopp -std=c++14
2: // http://seriss.com/people/erco/fltk/
3: // Include FLTK headers
4: #include <FL/Fl.H>
5: #include <FL/Fl_Window.H>
6: #include <FL/Fl_Button.H>
7: #include <FL/Fl_Radio_Round_Button.H>
8: #include <FL/Fl_Native_File_Chooser.H>
9: #include <FL/Fl_Output.H>
10: // Include Crypto++ headers
11: #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 // For MD5 hash function
12: #include <cryptopp/md5.h>
13: #include <cryptopp/hex.h>
14: #include <cryptopp/files.h>
15: // Include standard headers
16: #include <string>
17: #include <iostream>
18:
19: // Setup our function references so compiler knows to go find them.
20: void rbutton1_function(Fl_Widget *o, void*);
21: void browse_function(Fl_Widget *o, void*);
22: // Set global command line args for all functions
23: int user_browsed;
24: int g_argc;
25: char **g_argv;
26: char *s1;
27: Fl_Input* input; // Set global input box var
28: Fl_Output* output; // Set global out box var
29: std::string result; // set global result var
30: std::string filename = ""; // Set global file var
31: std::string browsed_filename = "";
32:
33: // =======================
34: // Hash Function by button
35: // =======================
36: void rbutton1_function(Fl_Widget *o, void*) {
37: result = ""; // Clear result from any previous entry
38: if (user_browsed == 0) {
39: std::cout << user_browsed << std::endl;
40: std::string filename = g_argv[1];
41: std::cout << filename << std::endl;
42: std::cout << "Clicked MD5!" << std::endl;
43:
44: // Start MD5 Hashing process
45: CryptoPP::Weak::MD5 hash;
46: CryptoPP::FileSource(filename.c_str(),true,
47: new CryptoPP::HashFilter(hash, new CryptoPP::HexEncoder(
48: new CryptoPP::StringSink(result), true)));
49:
50: // Print result to terminal and Fl_Outbox.
51: std::cout << result << std::endl;
52: const char * hash_out_c = result.c_str();
53: output->value(hash_out_c);
54: output->redraw();
55: }
56:
57: else if (user_browsed == 1) {
58: std::cout << user_browsed << std::endl;
59: std::string filename = browsed_filename;
60: std::cout << filename << std::endl;
61: std::cout << "Clicked MD5!" << std::endl;
62:
63: // Start MD5 Hashing process
64: CryptoPP::Weak::MD5 hash;
65: CryptoPP::FileSource(filename.c_str(),true,
66: new CryptoPP::HashFilter(hash, new CryptoPP::HexEncoder(
67: new CryptoPP::StringSink(result), true)));
68:
69: // Print result to terminal and Fl_Outbox.
70: std::cout << result << std::endl;
71: const char * hash_out_c = result.c_str();
72: output->value(hash_out_c);
73: output->redraw();
74: }
75: }
76: // ===============
77:
78: void browse_function(Fl_Widget *o, void *) {
79: Fl_Native_File_Chooser fnfc;
80: fnfc.title("Pick a file");
81: fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
82: fnfc.filter("Text\t*.txt\n"
83: "C Files\t*.{cxx,h,c}");
84: fnfc.directory("/var/tmp"); // default directory to use
85: // Show native chooser
86: switch ( fnfc.show() ) {
87: case -1: printf("ERROR: %s\n", fnfc.errmsg()); break; // ERROR
88: case 1: printf("CANCEL\n"); break; // CANCEL
89: default:
90: // Dirty hack to override argv from user selected file.
91: s1 = (char *)fnfc.filename();
92: ::browsed_filename = s1;
93: // test: printf("%s", s1);
94: //::g_argv[1] = s1; // Override argv
95: //::filename = s1; // override filename
96: printf("\nPICKED: %s\n", fnfc.filename()); break; // FILE CHOSEN
97:
98:
99: // TODO: Callback to MD5 function (or user selected) <-----------
100: // Need to call "rbutton1->callback(rbutton1_function);" <--- ???
101:
102: }
103: user_browsed = 1;
104: }
105:
106:
107: int main(int argc, char **argv) {
108: //std::string filename = g_argv[1]; // Get filename from command line argument 1
109: // Pass command line arguments back to global variable, so that other functions can access them.
110: g_argc = argc;
111: g_argv = argv;
112:
113: // Ugly Hack to avoid segfault if no file loaded...
114: if (filename == "") {
115: std::cout << "Error: We couldn't find a filename!" << std::endl;
116: std::string filename = "test.cpp";
117: std::string browsed_filename = "test.cpp";
118: ::g_argv[1] = (char *)filename.c_str();
119: std::cout << filename << std::endl;
120: std::cout << browsed_filename << std::endl;
121: }
122: //
123:
124: // Setup Window
125: Fl_Window *window = new Fl_Window(300,200, "Yet Another Hash Tool");
126:
127: //if (filename == "") {
128: //std::cout << "Error: We couldn't find a filename!" << std::endl;
129: //window->callback(browse_function);
130: //window->redraw();
131: //}
132:
133: Fl_Output output(60,10,220,20, "Hash:");
134: ::output = &output; // Magical unkown cast to prevent segfault and make make things work...
135: output.value("load a file...");
136: output.color(FL_BLACK);
137: output.textcolor(FL_GREEN);
138: // Setup Hash Radio_Round_Buttons
139: Fl_Radio_Round_Button *rbutton1 = new Fl_Radio_Round_Button(5, 25, 50, 30, "MD5");
140:
141: rbutton1->callback(rbutton1_function);
142:
143: Fl_Button *button1 = new Fl_Button( 5, 140, 100, 30, "Browse");
144: button1->callback(browse_function);
145:
146: window->end();
147: window->show();
148: return Fl::run();
149: }

Reply all
Reply to author
Forward
0 new messages