|
> I'll try to follow up with a rewrite of your app, so that you can get
> an idea of how it should be laid out. Shouldn't be hard.
I rewrote it -- you may not recognize it, but this is more likely
how it should be laid out.. this approach will 'scale' to larger apps.
Notice how everything is in the EditorWindow class now.. this
way all the methods/callbacks can access all the data it needs
without it being global.
This means you can easily create several instances of EditorWindow,
each with its own commands that can be running concurrently.
Notes on what I removed (for brevity):
> I wasn't sure what the multibrowser was for, so I took it out.
> I also removed the file load stuff, because it seemed unrelated
to the problem. Note that Fl_Text_Buffer has a loadfile() method,
so you can use that to load the editor with a text file, rather
than writing it yourself, though maybe you needed something custom,
I didn't look.
> I rewrote the menu code a bit.. I dislike using that static menu
array stuff, and prefer using the menubar->add() approach.
Study the design of this, and see if you can see why it has
been laid out this way. Putting all the variables into the class
cleans up all the variable scoping, so that everything has access
to what it needs, cleanly, without all those nasty globals.
Follow up with questions if you need to, but I think if you look
at it carefully, you'll get it.
The nasty globals in the original demo app were just to keep
the demo simple. It's assumed the reader is familiar with the
mechanics of C++, and after reading the example, can re-scope the
the variables as they please.
HTH.
---- snip
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#ifdef _WIN32
#include <windows.h>
#define popen _popen
#define pclose _pclose
#else
#include <unistd.h>
#endif
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Editor.H>
#include <FL/Fl_Window.H>
class EditorWindow : public Fl_Double_Window {
// Menubar
Fl_Menu_Bar *menubar;
// File editor
Fl_Text_Editor *file_edit;
Fl_Text_Buffer *file_buff;
// Console editor
Fl_Text_Editor *console_edit;
Fl_Text_Buffer *console_buff;
// Popen stuff
FILE *fp;
char command[512];
// DATA CALLBACK: Handle reading data from running command
void HandleFD() {
static char s[1024];
if ( fgets(s, sizeof(s)-1, fp) == NULL ) {
Fl::remove_fd(fileno(fp));
pclose(fp);
fp = 0;
console_buff->append("--- COMMAND COMPLETED\n");
} else {
console_buff->append(s);
}
}
static void HandleFD_CB(int, void *userdata) {
EditorWindow *ewin = (EditorWindow*)userdata;
ewin->HandleFD(); // avoids having to do ewin->xxx to access vars
}
// MENU CALLBACK: Build command
static void MakeCommand_CB(Fl_Widget*, void*userdata) {
EditorWindow *ewin = (EditorWindow*)userdata;
strcpy(ewin->command, "netstat -an 2>&1"); // create the command
}
// MENU CALLBACK: Start command running
void RunCommand() {
if ( fp != 0 ) return; // command already running? ignore
console_buff->text(""); // clear window
if ( command[0] == 0 ) { // no command? complain
console_buff->text("No command specified");
return;
}
fp = popen(command, "r"); // start command running..
if ( fp == NULL ) { // Failed? show error
console_buff->append("ERROR: popen: ");
console_buff->append(strerror(errno));
} else { // Worked? setup handler
Fl::add_fd(fileno(fp), HandleFD_CB, (void*)this);
}
}
// MENU CALLBACK: Start command running
static void RunCommand_CB(Fl_Widget*, void*userdata) {
EditorWindow *ewin = (EditorWindow*)userdata;
ewin->RunCommand(); // avoids having to do ewin->xxx to access vars
}
public:
// Ctor
EditorWindow(int w, int h, const char* t) : Fl_Double_Window(w, h, t) {
// Create menu bar
menubar = new Fl_Menu_Bar(0, 0, w, 25);
menubar->add("&File/Make Command", FL_CTRL+'s', MakeCommand_CB, (void*)this);
menubar->add("&File/Run", FL_CTRL+'r', RunCommand_CB, (void*)this);
// Create file editor
file_edit = new Fl_Text_Editor(0, 40, w, 260, "File Editor");
file_buff = new Fl_Text_Buffer();
file_edit->buffer(file_buff);
file_edit->textfont(FL_COURIER);
// Create console editor
console_edit = new Fl_Text_Editor(0, 320, w, 260, "Console Output");
console_buff = new Fl_Text_Buffer();
console_edit->buffer(console_buff);
console_edit->textfont(FL_COURIER);
// Popen stuff
fp = NULL;
command[0] = 0;
end();
resizable(this);
}
~EditorWindow() {
}
};
int main(int argc, char **argv) {
EditorWindow *ewin = new EditorWindow(600, 600, "Test");
ewin->show();
return(Fl::run());
}
[ Direct Link to Message ] | |