egami
C++ Image Processing program
/homes/esi30/DCS339/coursework/src/main_window.cpp
Go to the documentation of this file.
00001 #include <string>
00002 #include <vector>
00003 
00004 #include <glibmm/refptr.h>
00005 #include <glibmm/ustring.h>
00006 #include <gtkmm/aboutdialog.h>
00007 #include <gtkmm/action.h>
00008 #include <gtkmm/actiongroup.h>
00009 #include <gtkmm/enums.h>
00010 #include <gtkmm/filechooserdialog.h>
00011 #include <gtkmm/filefilter.h>
00012 #include <gtkmm/messagedialog.h>
00013 #include <gtkmm/stock.h>
00014 #include <gtkmm/uimanager.h>
00015 
00016 #include "catalogue.hpp"
00017 #include "main_window.hpp"
00018 #include "utils.hpp"
00019 
00020 Main_window::Main_window(): parent_table(2, 2) {
00021     set_title("Egami");
00022     add(parent_table);
00023     set_resizable();
00024     init_menu();
00025 
00026     parent_table.attach(*menu, 0, 2, 0, 1, Gtk::FILL, static_cast<Gtk::AttachOptions>(0));
00027     parent_table.attach(display_catalogue, 0, 1, 1, 2);
00028     parent_table.attach(processing_catalogue, 1, 2, 1, 2, static_cast<Gtk::AttachOptions>(0));
00029 
00030     show_all_children();
00031 }
00032 
00033 void Main_window::init_menu(){
00034     struct Leaf{ const std::string id; const Gtk::StockID ic; const std::string txt, info; void (Main_window::*fn)(); };
00035 
00036     menu_action_group = Gtk::ActionGroup::create();
00037     menu_action_group->add(Gtk::Action::create("FileMenu", "File"));
00038     menu_action_group->add(Gtk::Action::create("EditMenu", "Edit"));
00039     menu_action_group->add(Gtk::Action::create("HelpMenu", "Help"));
00040 
00041     std::vector<Leaf> menu_leafs{
00042         { "Open",               Gtk::Stock::OPEN,    "_Open",               "Open a new file",                  &Main_window::on_open },
00043         { "Save",               Gtk::Stock::SAVE,    "_Save",               "Save",                             &Main_window::on_save },
00044         { "Save As",            Gtk::Stock::SAVE_AS, "Save As...",          "Save as new file",                 &Main_window::on_save_as },
00045         { "Quit",               Gtk::Stock::QUIT,    "_Quit",               "Quit egami",                       &Main_window::on_quit },
00046         { "Undo",               Gtk::Stock::UNDO,    "_Undo",               "Undo previous action",             &Main_window::on_undo },
00047         { "Redo",               Gtk::Stock::REDO,    "_Redo",               "Redo previous undo",               &Main_window::on_redo },
00048         { "About",              Gtk::Stock::ABOUT,   "_About",              "About this program",               &Main_window::on_about },
00049         { "Region of Interest", Gtk::Stock::HELP,    "_Region of Interest", "Help on ROI",                      &Main_window::on_roi },
00050     };
00051 
00052     Glib::ustring menu_shape = 
00053             "<ui>"
00054             "  <menubar name='MenuBar'>"
00055             "    <menu action='FileMenu'>"
00056             "      <menuitem action='Open'/>"
00057             "      <menuitem action='Save'/>"
00058             "      <menuitem action='Save As'/>"
00059             "      <menuitem action='Quit'/>"
00060             "    </menu>"
00061             "    <menu action='EditMenu'>"
00062             "      <menuitem action='Undo'/>"
00063             "      <menuitem action='Redo'/>"
00064             "    </menu>"
00065             "    <menu action='HelpMenu'>"
00066             "      <menuitem action='About'/>"
00067             "      <menuitem action='Region of Interest'/>"
00068             "    </menu>"
00069             "  </menubar>"
00070             "</ui>";
00071 
00072     // Generate leafs' Action.
00073     for(std::vector<Leaf>::iterator it=menu_leafs.begin(); it!=menu_leafs.end(); ++it){
00074         Glib::RefPtr<Gtk::Action> o=Gtk::Action::create(it->id, it->ic, it->txt, it->info);
00075         o->set_always_show_image();
00076         menu_action_group->add(o, sigc::mem_fun(*this, it->fn));
00077     }
00078 
00079     // Populate menu_ui_manager.
00080     menu_ui_manager = Gtk::UIManager::create();
00081     menu_ui_manager->insert_action_group(menu_action_group);
00082     add_accel_group(menu_ui_manager->get_accel_group());
00083     menu_ui_manager->add_ui_from_string(menu_shape);
00084 
00085     // Extract the menu.
00086     menu = menu_ui_manager->get_widget("/MenuBar");
00087 }
00088 
00089 void Main_window::on_open(){
00090     Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_OPEN);
00091     dialog.set_transient_for(*this);
00092     dialog.set_select_multiple();
00093     dialog.set_current_folder(cmake_install_prefix+std::string("/share/egami/Image Library"));
00094     dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
00095     dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
00096 
00097 
00098     Glib::RefPtr<Gtk::FileFilter> filter_images = Gtk::FileFilter::create();
00099     filter_images->set_name("Image files");
00100     filter_images->add_mime_type("image/jpeg");
00101     filter_images->add_mime_type("image/png");
00102     filter_images->add_mime_type("image/bmp");
00103     filter_images->add_mime_type("image/tiff");
00104     dialog.add_filter(filter_images);
00105 
00106     Glib::RefPtr<Gtk::FileFilter> filter_any = Gtk::FileFilter::create();
00107     filter_any->set_name("Any files");
00108     filter_any->add_pattern("*");
00109     dialog.add_filter(filter_any);
00110 
00111     int result = dialog.run();
00112 
00113     std::vector<std::string> targetfilenames;
00114     switch(result){
00115         case(Gtk::RESPONSE_OK):
00116             targetfilenames = std::move(dialog.get_filenames());
00117             break;
00118         case(Gtk::RESPONSE_CANCEL):
00119             return;
00120     }
00121 
00122     for(std::vector<std::string>::iterator it=targetfilenames.begin(); it!=targetfilenames.end(); ++it)
00123         display_catalogue.open_image(*it);
00124 }
00125 
00126 void Main_window::on_save(){
00127     try{
00128         if(!display_catalogue.save())
00129             on_save_as();
00130     } catch(std::exception &e){
00131         Gtk::MessageDialog d(*this, e.what());
00132         d.run();
00133     }
00134 }
00135 
00136 void Main_window::on_save_as(){
00137     Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_SAVE);
00138     dialog.set_transient_for(*this);
00139     dialog.set_current_folder(cmake_install_prefix+std::string("/share/egami/Image Library"));
00140     dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
00141     dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
00142 
00143     int result = dialog.run();
00144 
00145     switch(result){
00146         case(Gtk::RESPONSE_OK):
00147             try{
00148                 display_catalogue.save_as(dialog.get_filename());
00149             } catch(std::exception &e){
00150                 Gtk::MessageDialog d(*this, e.what());
00151                 d.run();
00152             }
00153             break;
00154         case(Gtk::RESPONSE_CANCEL):
00155             return;
00156     }
00157 }
00158 
00159 void Main_window::on_quit(){
00160     hide();
00161 }
00162 
00163 void Main_window::on_undo(){
00164     display_catalogue.undo_current();
00165 }
00166 
00167 void Main_window::on_redo(){
00168     display_catalogue.redo_current();
00169 }
00170 
00171 void Main_window::on_about(){
00172     Gtk::AboutDialog d;
00173     d.set_program_name("Egami");
00174     d.set_version("Final");
00175     d.set_comments("For the DCS339: C++ for Image Processing course");
00176     d.set_authors(std::vector<Glib::ustring>{"Étienne Jean Lucien Simon"});
00177     d.run();
00178 }
00179 
00180 void Main_window::on_roi(){
00181     Gtk::Label text;
00182     text.set_markup("<big><b>Region of Interest</b></big>\n"
00183                     "\n"
00184                     "A region of interest is a subimage in an image. Like a normal image it must be rectangular.\n"
00185                     "When an image has a currently active ROI (region of interest), all processes apply to this region only.\n"
00186                     "Some processes are not avaible in ROI mode (e.g. Resizing, rotating). Moreover, copy has the special\n"
00187                     "semantic of slicing the image. That is, the copy process will \"cut out\" the ROI and it will open it in\n"
00188                     "another tab.\n"
00189                     "\n"
00190                     "In order to select a ROI: first click two times on the image (on two opposite angle of the sub image) then\n"
00191                     "click on the Select ROI process button (on the \"Tools\" tab). The ROI is persistant, in order to reselect\n"
00192                     "the image as a whole, you must click on the Unselect ROI process button (also on \"Tools\").\n"
00193                     "\n"
00194                     "Note that when a binary operation is effectued on an image in ROI mode, only the ROI portion is affected/used.\n");
00195     Gtk::Dialog d;
00196     d.set_resizable(false);
00197     d.get_vbox()->pack_start(text);
00198     d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
00199     d.show_all_children();
00200     d.run();
00201 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends