Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

/home/vlg/develop/gwavmerger/src/MainWindow.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------------
00003 //                              MainWindow.cpp
00004 //------------------------------------------------------------------------------
00005 // $Id: MainWindow.cpp,v 1.6 2003/02/07 05:15:09 vlg Exp $
00006 //------------------------------------------------------------------------------
00007 //  Copyright (c) 2001-2003 by Vladislav Grinchenko
00008 //
00009 //  This program is free software; you can redistribute it and/or
00010 //  modify it under the terms of the GNU General Public License
00011 //  as published by the Free Software Foundation; either version
00012 //  2 of the License, or (at your option) any later version.
00013 //------------------------------------------------------------------------------
00014 
00015 #include <sys/types.h>
00016 #include <dirent.h>
00017 #include <stdlib.h>
00018 #include <vector>
00019 #include <algorithm>
00020 
00021 #include <libgnome/gnome-help.h>
00022 
00023 #include <gtkmm/messagedialog.h>
00024 #include <libgnome/gnome-i18n.h>
00025 #include <libgnomeuimm/about.h>
00026 
00027 #include <glibmm/fileutils.h>
00028 
00029 #include <assa/Logger.h>
00030 #include <assa/AutoPtr.h>
00031 #include <assa/Assert.h>
00032 #include <assa/CmdLineOpts.h>
00033 #include <assa/Fork.h>
00034 
00035 #ifdef HAVE_CONFIG_H
00036 #   include "config.h"
00037 #endif
00038 
00039 #include "gWavMerger.h"
00040 #include "MainWindow.h"
00041 #include "PrefWindow.h"
00042 #include "FileOpen.h"
00043 #include "MergeDialog.h"
00044 #include "LoadProgress.h"
00045 #include "NameUtils.h"
00046 
00047 // gnome_pixmap_file ()
00048 // #include <libgnome/gnome-util.h> 
00049 
00050 using ASSA::ERROR;
00051 using SigC::slot;
00052 using SigC::bind;
00053 
00054 const char* MainWindow::titles [] = { "Dir A", "Dir B", NULL };
00055 const char* MainWindow::states [] = { "Start", "Dirty", "Clean", "Finish" };
00056 
00057 //==============================================================================
00058 //                          Static locals
00059 //==============================================================================
00060 
00061 static void 
00062 destroy_handler ()
00063 {
00064     trace("[static] destroy_handler");
00065 
00066     /* From Gtk 1.2 man pages:
00067      *  "Makes the innermost invocation of the main loop return when it 
00068      *   regains control."
00069      */
00070     Gtk::Main::quit ();
00071 }
00072 
00073 //==============================================================================
00074 //                       Public member functions
00075 //==============================================================================
00076 
00077 
00078 MainWindow::MainWindow ()
00079     : Gnome::UI::App (PACKAGE, PACKAGE),
00080       m_state (Start),
00081       m_about (NULL),
00082       m_pref_window (NULL),
00083       m_open_item (NULL),
00084       m_app_title (PACKAGE),
00085       m_top_menu_bar (*this, m_config),
00086       m_row (0),
00087       m_players_pid (-1),
00088       m_no_gaps (true)
00089 {
00090     trace("MainWindow");
00091 
00092     char pid [80];
00093     m_app_title += "-" + string (VERSION) + " (PID ";
00094     sprintf (pid, "%d", getpid ());
00095     m_app_title += pid + string (") ");
00096     
00097     set_title (m_app_title.c_str ());
00098     set_resizable ();
00099     set_size_request (430, 350); // width; height
00100     set_wmclass (PACKAGE, PACKAGE);
00101     set_border_width (2);
00102 
00105     m_list_store_ref = Gtk::ListStore::create (m_columns);
00106     m_tree_view.set_model (m_list_store_ref);
00107     m_tree_view.set_rules_hint ();
00108     add_columns ();
00109     m_tree_sel_ref = m_tree_view.get_selection();
00110     m_tree_sel_ref->set_mode (Gtk::SELECTION_SINGLE);
00111     m_tree_sel_ref->signal_changed ().connect (
00112         SigC::slot (*this, &MainWindow::selection_made_cb));
00113 
00117     m_merge_dialog = new MergeDialog (m_config, m_list_store_ref, m_columns);
00118     
00121     m_scrolled_window.set_policy (POLICY_NEVER, POLICY_ALWAYS);
00122     m_scrolled_window.add (m_tree_view);
00123     m_tree_view.show ();
00124     m_scrolled_window.show ();
00125 
00128     install_menus_and_toolbar ();
00129 
00130     set_contents (m_scrolled_window);
00131     show_all ();
00132 
00135     int width;
00136     int height;
00137     get_size (width, height);
00138     Gtk::TreeViewColumn* tvc;
00139 
00140     tvc = m_tree_view.get_column (0);
00141     tvc->set_min_width (width/2);
00142     tvc->set_alignment (0.5);
00143     tvc->get_first_cell_renderer ()->property_xalign () = 0.5;
00144 
00145     tvc = m_tree_view.get_column (1);
00146     tvc->set_alignment (0.5);
00147     tvc->get_first_cell_renderer ()->property_xalign () = 0.5;
00148 
00151     go_state (Start);
00152     print_state ();
00153 }
00154 
00155 
00156 MainWindow::~MainWindow ()
00157 {
00158     trace("MainWindow::~MainWindow");
00159     print_state ();
00160 
00161     if (m_pref_window != NULL) {
00162         delete m_pref_window;
00163         m_pref_window = NULL;
00164     }
00165 
00166     if (m_merge_dialog != NULL) {
00167         delete m_merge_dialog;
00168         m_merge_dialog = NULL;
00169     }
00170 }
00171 
00172 int
00173 
00174 MainWindow::delete_event_impl (GdkEventAny* /*event_*/)
00175 {
00176     trace("MainWindow::delete_event_impl");
00177     GWAVMERGER->setStopServerFlag ();
00178     return false;
00179 }
00180 
00181 void 
00182 
00183 MainWindow::install_menus_and_toolbar ()
00184 {
00185     trace("MainWindow::install_menus_and_toolbar");
00186 
00189     m_top_menu_bar.create ();
00190 
00193     set_statusbar (* manage (new Gtk::Statusbar));
00194     install_menu_hints ();
00195 
00198     m_top_menu_bar.fill_toolbar_with_doc_controls ();
00199 
00200     /* Create control buttons (Stop/Play/Up/Down) toolbar. 
00201      * Additional floating toolbar has to be created manually.
00202      */
00203     vector<Gnome::UI::Items::Info> toolbar;
00204     m_top_menu_bar.fill_toolbar_with_play_controls (toolbar);
00205 
00206     Gtk::Toolbar* ctrl_toolbar = manage (new Gtk::Toolbar);
00207     ctrl_toolbar->set_orientation (ORIENTATION_HORIZONTAL);
00208     ctrl_toolbar->set_toolbar_style (TOOLBAR_ICONS);
00209     ctrl_toolbar->set_icon_size (IconSize (24)); // 24 pixels?
00210 
00216     Glib::RefPtr<Gtk::AccelGroup> ac = Gtk::AccelGroup::create ();
00217     fill (*ctrl_toolbar, toolbar, ac);
00218 
00219     /* Add control toolbar to the App. */
00220     int band_num;     // Number of the band where the dock item should be placed
00221     int band_position; // Position of the new dock item in band
00222     int band_offset;   // Offset from the previous dock item in the band;
00223                        // if there is no previous  item, offset from 
00224                        // the beginning of the band.
00225 
00226     band_num = band_position = band_offset = 0;
00227 
00228     add_toolbar (*ctrl_toolbar, "control toolbar",
00229                  BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL,
00230                  BONOBO_DOCK_BOTTOM,
00231                  band_num, band_position, band_offset);
00232 }
00233 
00234 //==============================================================================
00235 // Callbacks
00236 //==============================================================================
00237 
00238 void
00239 
00240 MainWindow::open_cb ()
00241 {
00242     trace("MainWindow::open_cb");
00243     
00244     // Switch the state
00245     switch (m_state) {
00246 
00247     case Start: 
00248         go_state (Clean); 
00249         if (open_config_file () < 0) { // reset if project cannot be opened
00250             go_state (Start);
00251         }
00252         break;
00253 
00254     case Dirty:  /* ignored */
00255     {
00256         Gtk::MessageDialog emsg ("Project has been modified\n"
00257                                  "Please, save and close it first",
00258                                  MESSAGE_ERROR);
00259         emsg.run ();
00260     }
00261     break;
00262 
00263     case Clean:  /* ignored */ 
00264     {
00265         Gtk::MessageDialog emsg2 ("Project is opened\n"
00266                                   "Please, close it first",
00267                                   MESSAGE_ERROR);
00268         emsg2.run ();
00269     }
00270         break;
00271 
00272     case Finish: /* ignored */    
00273         break;
00274     }
00275     print_state ();
00276 }
00277 
00278 void
00279 
00280 MainWindow::open_recent_cb (guint index_)
00281 {
00282     trace("MainWindow::open_recent_cb");
00283 
00284     // Switch the state
00285     switch (m_state) {
00286     case Start: 
00287     {
00288         go_state (Clean); 
00289         const char* doc = 
00290             (m_config.get_document_history () [index_]).c_str ();
00291         DL((TRACE,"Opening [%d] \"%s\"\n", index_, doc));
00292         if (m_config.load_project (doc) < 0) {
00293             DL((TRACE,"Opening profile failed - removing from history\n"));
00294             m_config.remove_document_history (doc);
00295             m_top_menu_bar.refill_history_list ();
00296             go_state (Start);
00297         }
00298         break;
00299     }
00300     case Dirty:  /* ignored */    
00301     {
00302         Gtk::MessageDialog emsg1 ("Project has been modified.\n"
00303                                   "Please, save and close it first",
00304                                   MESSAGE_ERROR);
00305         emsg1.run ();
00306     }
00307         break;
00308     case Clean:  /* ignored */    
00309     {
00310         Gtk::MessageDialog emsg2 ("Project is opened.\n"
00311                                   "Please, close it first",
00312                                   MESSAGE_ERROR);
00313         emsg2.run ();
00314     }
00315         break;
00316     case Finish: /* ignored */    break;
00317     }
00318     print_state ();
00319 }
00320 
00321 void
00322 
00323 MainWindow::close_cb ()
00324 {
00325     trace("MainWindow::close_cb");
00326     // Switch the state
00327     switch (m_state) {
00328     case Start:  /* ignored */  break;
00329 
00330     case Dirty:  
00331         go_state (Clean); 
00332         save_config_file (); 
00333         /* No 'break' in Dirty state, for the transition Clean->Start
00334          * is an internal unconditional event.
00335          */
00336     case Clean:  
00337         go_state (Start); 
00338         /* Also add the file to the list of most recently-visited files
00339          * regardless of whether the file has been modified or not.
00340          */
00341         m_top_menu_bar.add_history ();
00342         m_list_store_ref->clear ();
00343 
00344         m_tree_view.get_column (0)->set_title ("Dir A");
00345         m_tree_view.get_column (1)->set_title ("Dir B");
00346 
00347         set_title (m_app_title.c_str ()); // clear up title of old project name
00348         break;
00349 
00350     case Finish: 
00351         /* ignored */   
00352         break;
00353     }
00354     print_state ();
00355 }
00356 
00357 void 
00358 
00359 MainWindow::reload_cb ()
00360 {
00361     trace("MainWindow::reload_cb");
00362     DL((APP,"Reloading ...\n"));
00363 
00364     if (m_state == Start) {
00365         Gtk::MessageDialog w ("Please, open or create\na project first!",
00366                               MESSAGE_WARNING);
00367         w.run ();
00368         return;
00369     }
00370     else if (m_state == Finish) { /* ignore */
00371         return;
00372     }
00373     size_t max_a = 0;
00374     size_t max_b = 0;
00375     vector<string> A_list;
00376     vector<string> B_list;
00377 
00378     m_config.dump ();
00379 
00380     // Load file names 
00381     max_a = read_dir (m_config.get_A_dir (), m_config.get_A_prefix (), A_list);
00382     print_wav_list   ("A", A_list);
00383 
00384     max_b = read_dir (m_config.get_B_dir (), m_config.get_B_prefix (), B_list);
00385     print_wav_list   ("B", B_list);
00386 
00387     // Reset column titles
00388     m_tree_view.get_column (0)->set_title (m_config.get_A_dir ());
00389     m_tree_view.get_column (1)->set_title (m_config.get_B_dir ());
00390 
00391     int max_size = max2 (max_a, max_b);
00392     m_list_store_ref->clear ();
00393 
00394     if (A_list.size () != B_list.size ()) {
00395         DL((APP,"List sizes don't match (ru=%d != en=%d)\n",
00396             A_list.size (), B_list.size ()));
00397     }
00398 
00399     DL((TRACE,"Fill CList with dummies\n"));
00400     m_vec_rows.clear ();
00401     for (int i = 0; i < max_size; i++) { // fill up list with dummies
00402         m_vec_rows.push_back (RowPair_t ("gap", "gap"));
00403     }
00404     DL((TRACE,"maxsize = %d; m_vec_rows.size() = %d\n",
00405         max_size, m_vec_rows.size ()));
00406 
00407     std::for_each (m_vec_rows.begin (), m_vec_rows.end (),
00408                    SigC::slot (*this, &MainWindow::liststore_add_item));
00409     dump_list_store ();
00410 
00411     vector<string>::const_iterator it;
00412     size_t s;
00413 
00414     DL((TRACE,"Process list A\n"));
00415     Gtk::TreeModel::Row row;
00416     it = A_list.begin ();
00417 
00418     while (it != A_list.end ()) {
00419         s = atoi ((*it).c_str ());
00420         if (s == 0) {
00421             DL((APP,"Warning: WAV file name cannot start with 0!\n"));
00422             DL((APP,"while processing \"%s\"\n", (*it).c_str ()));
00423         }
00424         else {
00425             row = m_list_store_ref->children ()[s-1];
00426             Glib::ustring v = row [m_columns.row_a];
00427             DL((TRACE,"Setting row[%d]=\"%s\" to \"%s\"\n",
00428                 s-1, v.c_str (), (*it).c_str ()));
00429             row [m_columns.row_a] = *it;
00430         }
00431         it++;
00432     }
00433     dump_list_store ();
00434     DL((TRACE,"Process list B\n"));
00435     it = B_list.begin ();
00436     while (it != B_list.end ()) {
00437         s = atoi ((*it).c_str ());
00438         if (s == 0) {
00439             DL((APP,"Warning: WAV file name cannot start with 0!\n"));
00440             DL((APP,"while processing \"%s\"\n", (*it).c_str ()));
00441         }
00442         else {
00443             // m_clist.row (s-1)[1].set_text ((*it).c_str ());
00444             row = m_list_store_ref->children ()[s-1];
00445             row [m_columns.row_b] = *it;
00446         }
00447         it++;
00448     }
00449     dump_list_store ();
00450     
00451     /* post-processing: we got to know if there are any gaps in the
00452      * sequence. If there are, we would block merger operation.
00453      */
00454     Glib::ustring gap ("gap");
00455     m_no_gaps = true;
00456     children_iterator_t iter = m_list_store_ref->children ().begin ();
00457     while (iter != m_list_store_ref->children ().end ()) {
00458         row = *iter;
00459         if ( row [m_columns.row_a] == gap || row [m_columns.row_b] == gap) {
00460             m_no_gaps = false;
00461             break;
00462         }
00463         iter++;
00464     }
00465     /* Let TopMenuBar know that list is loaded.
00466      */
00467     m_top_menu_bar.set_loaded ();
00468 }
00469 
00476 void 
00477 
00478 MainWindow::merge_cb ()
00479 {
00480     // NOTE: Make a progress report out of this ...
00481     trace("MainWindow::merge_cb");
00482 
00483     switch (m_state) {
00484     case Start: /* ignore */
00485     {
00486         Gtk::MessageDialog w1 ("Please, open or create\n"
00487                                "project first.",
00488                                MESSAGE_WARNING);
00489         w1.run ();
00490     }
00491         break;
00492     case Dirty:         // fall through
00493     case Clean: 
00494         if (m_no_gaps) {
00495             DL((APP,"Starting the merger ...\n"));
00496             m_merge_dialog->run_merge ();
00497         }
00498         else {
00499             Gtk::MessageDialog w2 (
00500                 "Your sound file sequence has one\n"
00501                 "or more gaps. For merge operation\n"
00502                 "to proceed, get rid of the gap(s).",
00503                 MESSAGE_WARNING);
00504             w2.run ();
00505         }
00506         break;
00507     case Finish: /* ignore */ 
00508         break;
00509     }
00510     return;
00511 }
00512 
00513 void 
00514 
00515 MainWindow::pref_cb ()
00516 {
00517     trace("MainWindow::pref_cb");
00518 
00519     switch (m_state)
00520     {
00521     case Start:  /* ignored */    
00522     {
00523         Gtk::MessageDialog w1 ("Please, open or create\n"
00524                                "project first.",
00525                                MESSAGE_WARNING);
00526         w1.run ();
00527     }
00528         break;
00529     case Dirty:  
00530     {
00531         change_preferences (); 
00532     }
00533         break;
00534     case Clean:  
00535     {
00536         go_state (change_preferences () ? Dirty : Clean);  
00537     }
00538         break;
00539     case Finish: /* ignored */    
00540     {
00541         Gtk::MessageDialog w2 ("Please, open or create\n"
00542                                "project first.",
00543                                MESSAGE_WARNING);
00544         w2.run ();
00545     }
00546         break;
00547     }
00548     print_state ();
00549 }
00550 
00551 void
00552 
00553 MainWindow::exit_cb ()
00554 {
00555     trace("MainWindow::exit_cb");
00556 
00557     switch (m_state)
00558     {
00559     case Start:  
00560         m_config.dont_save_project ();
00561         destroy_handler (); 
00562         go_state (Finish); 
00563         break;
00564     case Dirty:  /* put up warnging dialog*/    
00565     {
00566         Gtk::MessageDialog e ("Project has been modified\n"
00567                               "Please, save and close it first",
00568                               MESSAGE_ERROR);
00569         e.run ();
00570     }
00571         break;
00572     case Clean:  
00573         m_config.add_document_history ();
00574         destroy_handler (); 
00575         go_state (Finish); 
00576         break;
00577     case Finish: 
00578         /* ignored */ 
00579         break;
00580     }
00581     print_state ();
00582 }
00583 
00584 void
00585 
00586 MainWindow::new_cb ()
00587 {
00588     trace("MainWindow::new_cb");
00589 
00590     switch (m_state)
00591     {
00592     case Start:  
00593         go_state (change_preferences () ? Dirty : Start); 
00594         break;
00595     case Dirty:  /* ignored */    
00596     {
00597         Gtk::MessageDialog e1 ("Project has been modified.\n"
00598                                "Please, save and close it first",
00599                                MESSAGE_ERROR);
00600         e1.run ();
00601     }
00602         break;
00603     case Clean:  /* ignored */    
00604     {
00605         Gtk::MessageDialog e2 ("Project is opened.\n"
00606                                "Please, close it first", MESSAGE_ERROR);
00607         e2.run ();
00608     }
00609         break;
00610     case Finish: /* ignored */    break;
00611     }
00612     print_state ();
00613 }
00614 
00615 void
00616 
00617 MainWindow::save_cb ()
00618 {
00619     trace("MainWindow::save_cb");
00620 
00621     switch (m_state) {
00622     case Start:  /* ignored */    
00623     {
00624         Gtk::MessageDialog e1 ("Please open or create\nproject first",
00625                                MESSAGE_ERROR);
00626         e1.run ();
00627     }
00628         break;
00629     case Dirty:  
00630         go_state (Clean); 
00631         save_config_file (); 
00632         set_mw_name ();
00633         break;
00634     case Clean:  /* ignored */    
00635     {
00636         Gtk::MessageDialog e2 ("Project is not modified.\n"
00637                                "Close it to proceed.", MESSAGE_ERROR);
00638         e2.run ();
00639     }
00640         break;
00641     case Finish: /* ignored */    break;
00642     }
00643     print_state ();
00644 }
00645 void
00646 
00647 MainWindow::save_as_cb ()
00648 {
00649     trace("MainWindow::save_as_cb");
00650 
00651     switch (m_state)
00652     {
00653     case Start:  /* ignored */    
00654     {
00655         Gtk::MessageDialog emsg ("Please open or create\nproject first",
00656                                  MESSAGE_ERROR);
00657         emsg.run ();
00658     }
00659         break;
00660     case Dirty:  
00661         go_state (Clean); 
00662     case Clean:  
00663         save_config_file_as (); 
00664         set_mw_name ();
00665         break;
00666     case Finish: /* ignored */    break;
00667     }
00668     print_state ();
00669 }
00670 
00671 void 
00672 
00673 MainWindow::selection_made_cb ()
00674 {
00675     trace("MainWindow::selection_made_cb");
00676 
00677     Gtk::TreeModel::iterator iter = m_tree_sel_ref->get_selected ();
00678 
00679     if (!iter) {
00680         return;
00681     }
00682     Gtk::TreeModel::Row row = *iter;
00683     m_A_selection = Glib::locale_from_utf8 (row [m_columns.row_a]);
00684     m_B_selection = Glib::locale_from_utf8 (row [m_columns.row_b]);
00685     Gtk::TreeModel::Path path = m_list_store_ref->get_path (iter);
00686     m_row = *(path.get_indices ().begin ());
00687     DL((APP, "Selected row %d\n", m_row));
00688     DL((APP, "Cell text \"%s\" : \"%s\"\n", 
00689         m_A_selection.c_str (), m_B_selection.c_str ()));
00690 }
00691 
00692 string
00693 
00694 MainWindow::make_selected_file_name (Column column_)
00695 {
00696     string ret;
00697 
00698     if (left_column == column_) {
00699         if (m_A_selection == "gap") {
00700             return ret;
00701         }
00702         ret = m_config.make_abs_pathname ("A", m_A_selection);
00703     }
00704     else { // RIGH_COL
00705         if (m_B_selection == "gap") {
00706             return ret;
00707         }
00708         ret = m_config.make_abs_pathname ("B", m_B_selection);
00709     }
00710     return ret;
00711 }
00712 
00713 void 
00714 
00715 MainWindow::play_sound (Column column_)
00716 {
00717     trace("MainWindow::play_sound");
00718 
00719     string fname (make_selected_file_name (column_));
00720     if (fname.size () == 0) {
00721         DL((APP,"Skipping gap file"));
00722         return;
00723     }
00724     DL((APP,"\nPlaying file \"%s\"\n", fname.c_str ()));
00725 
00726     string args (fname);
00727     args += " -t ossdsp -s -w /dev/dsp";
00728     m_players_pid = ASSA::Fork::fork_exec ("sox", args, false);
00729 
00730     /* Check to see if we are at the last row.
00731      * If not, then move to the next row.
00732      */
00733     if (m_config.get_jump_next_row () && column_ == right_column) {
00734         go_next_row_cb ();
00735     }
00736 }
00737 
00755 void 
00756 
00757 MainWindow::help_contents_cb ()
00758 {
00759     trace ("MainWindow::help_contents_cb");
00760 
00761 // Help doesn't work - bloody hell!!!
00762 #if 0
00763     std::string datadir (DATADIR);
00764     datadir += "/gnome/help/gwavmerger/C/gwavmerger.xml";
00765 
00766 /*
00767     if (!Glib::file_test (datadir, 
00768                          Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR))
00769     {
00770         Gtk::MessageDialog emsg ("Help file does not exist", MESSAGE_ERROR);
00771         emsg.run ();
00772         EL((ERROR,"Failed to open \"%s\"\n", datadir.c_str ()));
00773         return;
00774     }
00775 */
00776     datadir = " ghelp:" + datadir;
00777 
00778     ASSA::Fork::fork_exec ("yelp", datadir, false);
00779 
00780 /*
00781     ASSA::Fork f (ASSA::Fork::LEAVE_ALONE);
00782 
00783     if (f.isChild ()) {
00784         int ret = ::execlp ("yelp", "yelp", datadir.c_str (), NULL);
00785         if (ret == -1) {
00786             DL((ERROR,"execlp(\"yelp\") failed\n"));
00787         }
00788     }
00789 */
00790 #endif
00791 
00792 
00796 #if 0
00797     GError* error;
00798     gnome_help_display ("gwavmerger.xml", NULL, &error);
00799     if (error != NULL) {
00800         Gtk::MessageDialog emsg ("Help support is broken in libgnomeuimm2\n"
00801                                  "Use Yelp : Application|gwavmerger instead.", 
00802                                  MESSAGE_ERROR);
00803         emsg.run ();
00804         if (error->message) {
00805             DL((ERROR,"gnome_help_display () error: \"%s\"\n",
00806                 error->message));
00807         }
00808         g_error_free (error);
00809     }
00810 #endif
00811 
00814         Gtk::MessageDialog emsg ("Help support is broken in libgnomeuimm2.\n"
00815                              "Use Yelp : Applications | gwavmerger instead", 
00816                                  MESSAGE_ERROR);
00817         emsg.run ();
00818 
00819 }
00820 
00821 void 
00822 
00823 MainWindow::about_cb ()
00824 {
00825 
00826     if (m_about != NULL) {
00827         m_about->run ();
00828         return;
00829     }
00830 
00831     Glib::ustring name (PACKAGE);
00832     Glib::ustring version (VERSION);
00833     Glib::ustring copyright ("2002-2003 (C) Vladislav Grinchenko");
00834     std::vector<Glib::ustring> authors;
00835     authors.push_back ("Vladislav Grinchenko <vladg@erols.com>");
00836     
00837     std::vector<Glib::ustring> documenters;
00838     documenters.push_back ("Vladislav Grinchenko <vladg@erols.com>");
00839     
00840     m_about = new Gnome::UI::About (name, version, copyright, authors,
00841                                     documenters);
00842                                     
00843     m_about->set_modal (false);
00844     m_about->run ();
00845 }
00846 
00847 void
00848 
00849 MainWindow::go_prev_row_cb ()
00850 {
00851     Gtk::TreeModel::iterator iter = m_tree_sel_ref->get_selected ();
00852     Gtk::TreeModel::Path path = m_list_store_ref->get_path (iter);
00853 
00854     if (path.prev ()) {
00855         m_tree_sel_ref->select (path);
00856         m_tree_view.scroll_to_row (path);
00857     }
00858     m_row = *(path.get_indices ().begin ());
00859 }
00860 
00861 void
00862 
00863 MainWindow::go_next_row_cb ()
00864 {
00865     Gtk::TreeModel::iterator iter = m_tree_sel_ref->get_selected ();
00866     if (iter) {
00867         Gtk::TreeModel::Path path = m_list_store_ref->get_path (iter);
00868         path.next ();
00869         m_tree_sel_ref->select (path);
00870         m_tree_view.scroll_to_row (path);
00871         m_row = *(path.get_indices ().begin ());
00872     }
00873 }
00874 
00875 void
00876 
00877 MainWindow::stop_cb ()
00878 {
00879     trace("MainWindow::stop_cb");
00880 
00881     if (m_players_pid != -1) {
00882         DL((TRACE,"killing PID %d\n",m_players_pid));
00883         // SIGINT is Ctrl-C signal
00884         int ret = kill (m_players_pid, SIGINT);
00885         if (ret != 0) {
00886             DL((APP,"kill (SIGINT) = -1 (%s)\n",strerror (errno)));
00887         }
00888         m_players_pid = -1;
00889     }
00890 }
00891 
00892 //==============================================================================
00893 //                          Internal Actions
00894 //==============================================================================
00895 
00899 bool
00900 
00901 MainWindow::change_preferences ()
00902 {
00903     trace("MainWindow::change_preferences");
00904 
00905     if (m_pref_window == NULL) {
00906         m_pref_window = new PrefWindow (m_config);
00907     }
00908     
00909     bool ret = m_pref_window->run ();
00910     DL((APP,"Preferences %s\n", ret ? "changed" : "unchanged"));
00911     return ret;
00912 }
00913 
00914 int
00915 
00916 MainWindow::open_config_file ()
00917 {
00918     trace("MainWindow::open_config_file");
00919     FileOpen f (m_config);
00920     f.run ();
00921     return 0;
00922 }
00923 
00938 int
00939 
00940 MainWindow::read_dir (const string&   subdir_, 
00941           const string&   prefix_,
00942           vector<string>& file_list_)
00943 {
00944     trace("MainWindow::read_dir");
00945     int max_val;
00946 
00947     LoadProgress lp;
00948     max_val = lp.run_load (subdir_, prefix_, 
00949                            m_config.get_proj_path (), file_list_);
00950     return max_val;
00951 }
00952 
00953 void 
00954 
00955 MainWindow::print_wav_list (const char* name_, const vector<string>& list_)
00956 {
00957     DL((APP,"==== List : %s ====\n",name_));
00958     if (list_.size () == 0) {
00959         DL((APP,"Empty list!\n"));
00960     }
00961     else {
00962         vector<string>::const_iterator i = list_.begin ();
00963         uint j = 0;
00964         while (i != list_.end ()) {
00965             DL((APP,"%02d : \"%s\"\n", j++, (*i).c_str ()));
00966             i++;
00967         }
00968     }
00969     DL((APP,"==== End-Of-List =====\n"));
00970 }
00971 
00975 void
00976 
00977 MainWindow::set_mw_name (void) 
00978 {
00979     trace("MainWindow::set_mw_name");
00980 
00981     string title (m_app_title);
00982     string p (m_config.get_proj_name ());
00983     DL((TRACE,"project_name = \"%s\"\n",p.c_str ()));
00984     if (p.size () != 0) {
00985         title = p + " : " + title;
00986     }
00987     set_title (title.c_str ());
00988 }
00989 
00994 MainWindow::ColList
00995 
00996 MainWindow::get_clist (Column column_, bool filter_gaps_)
00997 {
00998     static const char self[]="MainWindow::get_clist";
00999     trace (self);
01000 
01001     static const string gap ("gap");
01002     MainWindow::ColList list;
01003     std::string s;
01004 
01005     children_t children = m_list_store_ref->children ();
01006     children_iterator_t iter = children.begin ();
01007 
01008     while (iter != children.end ()) {
01009         Gtk::TreeModel::Row row = *iter;
01010         s = Glib::locale_from_utf8 (column_ == left_column ? 
01011                                     row [m_columns.row_a] : 
01012                                     row [m_columns.row_b]);
01013         if (!filter_gaps_ || s != gap) {
01014             list.push_back (s);
01015         }
01016         iter++;
01017     }
01018     return list;
01019 }
01020 
01021 void 
01022 
01023 MainWindow::liststore_add_item (const RowPair_t& elem_)
01024 {
01025     trace("MainWindow::liststore_add_item");
01026 
01027     Gtk::TreeModel::iterator iter = m_list_store_ref->append ();
01028     row_t row = *iter;
01029     row [m_columns.row_a] = elem_.first;
01030     row [m_columns.row_b] = elem_.second;
01031 }
01032 
01033 void
01034 
01035 MainWindow::dump_list_store ()
01036 {
01037     children_t c = m_list_store_ref->children ();
01038     children_iterator_t iter = c.begin ();
01039     u_int i = 0;
01040     DL((TRACE,"===== ListStore =====\n"));
01041     while (iter != c.end ()) {
01042         row_t row = *iter;
01043         Glib::ustring al = row [m_columns.row_a];
01044         Glib::ustring bl = row [m_columns.row_b];
01045         DL((TRACE,"[%02d] \"%s\" : \"%s\"\n", i++, al.c_str (), bl.c_str ()));
01046         iter++;
01047     }
01048     DL((TRACE,"=====================\n"));
01049 }

Generated on Tue Feb 11 23:05:19 2003 for gwavmerger by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002