Listing 2: A GUI version of the wc program
/* * Paulo Pinto ([email protected]) (c) 2001 * An GUI version of the wc program */ #include <gtk--/label.h> #include <gtk--/fileselection.h> #include <gnome--/main.h> #include <gnome--/app.h> #include <gnome--/stock.h> #include <iostream> #include <fstream> #include <sstream> #include <string> #include <cctype> //Bring the slot binding command to global scope using SigC::slot; // Application // A minimalist graphical view of wc class GWCApp: public Gnome::App { public: GWCApp (); virtual ~GWCApp (); protected: gint delete_event_impl (GdkEventAny*); //Signal handlers: virtual void on_menu_open (); void process_file (); private: bool count_words (const std::string &filename, int &words, int &lines, int &bytes); void init_menus (); void init_toolbar (); Gtk::Label *m_text; Gtk::FileSelection *m_filesel; }; // The program entry point. // Just create a GWCApp instance and // launch it. // Please note that in ANSI C++ the // return is optional int main (int argc, char *argv []) { // Initialize the framework Gnome::Main kit ("gwc", "0.0.1", argc, argv); GWCApp app; // Make the window appear app.show (); // Enter into the event loop kit.run (); } GWCApp::GWCApp (): Gnome::App ("gwc", "GWC") { // Create the text label for showing the word count m_text = new Gtk::Label ("No file counted"); // Set the window contents. Please note that // m_text must be deleted explicitly. // It is deleted in GWCApp::~GWCApp () set_contents (*m_text); // Create the dialog box for opening files // We don't need to create it here but this // is just for ilustrive purposes. m_filesel = manage (new Gtk::FileSelection ("Open File")); // Connect the ok_button to file_ok_sel function m_filesel->get_ok_button()->clicked.connect(slot(this, &GWCApp::process_file)); // Connect the cancel_button to hide the window m_filesel->get_cancel_button()->clicked.connect (m_filesel->hide.slot()); init_menus (); init_toolbar (); } GWCApp::~GWCApp () { // Delete the label. We don't need to delete // the file selection because it is handled // by manage. delete m_text; } // Creates the application menus void GWCApp::init_menus () { // Create a file menu using helper functios. // There are other ways of building menus but this // is the easiest. using namespace Gnome; using namespace Gtk::Menu_Helpers; // Entries for the file submenu UI::Info file_menu[] = { MenuItems::Open (slot (this, &GWCApp::on_menu_open)), UI::Separator(), MenuItems::Exit(Gtk::Main::quit.slot ()) }; // This is the for the menu toolbar UI::SubTree menus[] = { Menus::File(file_menu) }; // Create and attach the menus to the // application window create_menus(menus); } // Creates the application toolbar void GWCApp::init_toolbar () { // Create a toolbar using helper functios. using namespace Gnome; UI::Info toolbar[] = {UI::Item(UI::Icon(GNOME_STOCK_PIXMAP_OPEN), "Open", slot(this, &GWCApp::on_menu_open), "Open a file"), UI::Separator (), UI::Item(UI::Icon(GNOME_STOCK_PIXMAP_EXIT), "Exit", Gtk::Main::quit.slot (), "Exit the application") }; // Create and attach the toolbar to the // application window create_toolbar(toolbar); } // Called when the user presses the 'X' mark // on the window. // Redefining this method is another way of // receiving the 'delete' signal. gint GWCApp::delete_event_impl(GdkEventAny*) { Gtk::Main::quit(); return FALSE; } // Called when the user selects the // File->Open option void GWCApp::on_menu_open () { m_filesel->set_modal (true); m_filesel->show (); } // Called when the user presses the // Ok button on the FileSelection dialog void GWCApp::process_file () { m_filesel->hide (); std::string filename = m_filesel->get_filename (); int words, lines, bytes; std::ostringstream msg; // Clear and force a redraw, or else // the older string will appear m_text->set_text (""); draw (0); if (!count_words (filename, words, lines, bytes)) { msg << "Couldn't open " << filename; Gnome::Dialogs::error (msg.str ()); } else { msg << "The file " << filename; msg << ", has " << lines << " lines, " << words << " words and "; msg << bytes << " bytes." ; m_text->set_text (msg.str ()); } } // Counts all the words, lines and bytes. // This isn't the most eficient way to do it, but // it servers the purpose of the example. bool GWCApp::count_words (const std::string &filename, int &words, int &lines, int &bytes) { std::ifstream in (filename.c_str ()); if (!in) return false; words = 0; lines = 0; bytes = 0; char ch; while (!in.eof ()) { // Advance the file pointer to the next // word do { in.get (ch); if (!in.eof ()){ bytes++; // Ok, now changing for the next line if (ch == '\n') lines++; } } while (!in.eof () && isspace (ch)); // Advance the file pointer to the next // white space if (!in.eof ()) { words++; do { in.get (ch); if (!in.eof ()) bytes++; } while (!in.eof () && !isspace (ch)); } } return true; } End of Listing