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

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

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------------
00003 //                              MergeDialog.cpp
00004 //------------------------------------------------------------------------------
00005 // $Id: MergeDialog.cpp,v 1.6 2003/02/07 05:15:09 vlg Exp $
00006 //------------------------------------------------------------------------------
00007 //  Copyright (c) 2001,2002 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 #ifdef HAVE_CONFIG_H
00016 #   include "config.h"
00017 #endif
00018 
00019 #include <stdlib.h>             // atoi(3)
00020 #include <unistd.h>             // access(2)
00021 #include <sys/stat.h>           // mkdir(2)
00022 #include <sys/types.h>          // mkdir(2)
00023 
00024 #include <assa/MemDump.h>
00025 #include <assa/Pipe.h>
00026 
00027 #include "MergeDialog.h"
00028 #include "gWavMerger.h"
00029 #include "Delays.h"
00030 #include "InfoMsgPopup.h"
00031 #include "SerialNumber.h"
00032 
00033 using namespace ASSA;
00034 
00038 void
00039 
00040 MergeDialog::refresh_gui () const
00041 {
00042     trace("MergeDialog::refresh_gui");
00043 
00044     while (Gtk::Main::events_pending ()) {
00045         Gtk::Main::iteration ();
00046     }
00047 }
00048 
00058 void
00059 
00060 MergeDialog::run_merge ()
00061 {
00062     trace("MergeDialog::run_merge");
00063     init ();
00064     run ();
00065 }
00066 
00067 void 
00068 
00069 MergeDialog::init ()
00070 {
00071     trace("MergeDialog::init");
00072 
00073     m_in_progress = false;
00074     m_pause_in_progress = false;
00075     m_result = "";
00076     m_cwd = "";
00077     m_file_cnt = 0;
00078     m_curr_file = 0;
00079     m_del_old_file = true;
00080 
00081     // Sensitize "exec" button
00082     set_response_sensitive (0, true);
00083     set_default_response (0);
00084     
00085     // Current file readings
00086     m_file_name_label->set_text ("");
00087     m_file_progress->set_fraction (0);
00088 
00089     // Total files processed readings
00090     m_total_label->set_text ("");
00091     m_total_progress->set_fraction (0);
00092 
00093     // CD tracks configuration
00094     m_make_cd->set_active (false);
00095     m_first_cd_track->set_text ("1");
00096 }
00097 
00098 /*******************************************************************************
00099                                Callbacks
00100 *******************************************************************************/
00101 
00107 void 
00108 
00109 MergeDialog::on_ok_button_clicked()
00110 {  
00111     trace("MergeDialog::on_ok_button_clicked");
00112 
00113     size_t size = m_clist->children ().size ();
00114 
00115     int ret = 0;
00116     string name;
00117     string an_A;
00118     string a_B; 
00119     string pause [2]; 
00120     string cmd;
00121     string final_list;
00122     string q;
00123     char* buf = NULL;
00124 
00125     Delays delays (m_config);   // functor object
00126     string cdpath ("cdimage");
00127     InfoMsgPopup imp ("Generating pause files...",
00128                       "\n  Wait while generating pause files...\n");
00129     Gtk::TreeModel::Children::iterator iter;
00130     Gtk::TreeModel::Row row;
00131 
00132     SerialNumber sernum (first_cd_track (), "track", ".wav", size);
00133 
00134     /* Change to the project directory. 
00135      * getcwd() always returns a path free from symbolic links.
00136      */
00137     buf = new char [PATH_MAX];
00138     getcwd (buf, PATH_MAX);
00139     m_cwd = buf;
00140     delete [] buf;
00141 
00142     /* Change to the project's root directory.
00143      */
00144     ::chdir (m_config.get_proj_path ().c_str ());
00145 
00146     /* Start compiling the merger list first by 
00147      * deriving the result WAV file name.
00148      */
00149     final_list = m_config.get_proj_name ();
00150     final_list.replace (final_list.find (".gwm"), 4, ".wav");
00151 
00152     q = "Remove old " + final_list + " file?";
00153 
00156     if (::access (final_list.c_str (), F_OK) == 0) {
00157         Gtk::MessageDialog qm (*this, q, Gtk::MESSAGE_QUESTION, 
00158                                Gtk::BUTTONS_NONE, true, true);
00159         qm.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
00160         qm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
00161 
00162         int ret = qm.run ();
00163         if (ret == Gtk::RESPONSE_CANCEL) {
00164             DL((APP, "Merger cancelled!\n"));
00165             goto error;
00166         }
00167         ::unlink (final_list.c_str ()); // Wack the old WAV file
00168     }
00169     m_result = final_list;  // Remember target WAV file name
00170 
00171     if (make_cd_checked ()) {
00172         struct stat st;
00173         if (::stat (cdpath.c_str (), &st) != 0 || !S_ISDIR (st.st_mode)) {
00174             ::mkdir (cdpath.c_str (), 0755);
00175         }
00176     }
00177 
00178     /* Start assembling the "command arguments" list
00179      */
00180     final_list = "--output=" + final_list + " ";
00181 
00182     DL((APP,"Number of elements in CList : %d\n",size));
00183     DL((APP,"Merging files : \n"));
00184 
00185     /* Make pause files. We block here with a popup 
00186      * waiting for all pause files to be generated.
00187      */
00188     imp.show ();
00189     refresh_gui ();
00190     m_pause_in_progress = true;
00191 
00192     iter = m_clist->children ().begin ();
00193     while (iter) {
00194         if (m_pause_in_progress == false) { // we've been cancelled by user
00195             imp.hide ();
00196             goto error;
00197         }
00198         row = *iter;
00199         std::string a = Glib::locale_from_utf8 (row [m_columns.row_a]);
00200         std::string b = Glib::locale_from_utf8 (row [m_columns.row_b]);
00201 
00202         an_A = m_config.make_rel_pathname ("A", a);
00203         a_B = m_config.make_rel_pathname ("B", b);
00204         
00205         pause [pre] = m_config.make_pause_pathname (pre, b);
00206         pause [post] = m_config.make_pause_pathname (post, b);
00207 
00208         if (create_pause_files (a_B, pause, delays) == -1) {
00209             goto error;
00210         }
00211 
00212         if (make_cd_checked ()) {
00213             cmd = "wavjoin --output=cdimage/" + string (sernum) + " "
00214                 + an_A + " " + pause [pre] + " " 
00215                 + a_B  + " " + pause [post];
00216             ret = system (cmd.c_str ());
00217             if (ret < 0) {
00218                 Gtk::MessageDialog error ("wavjoin failed!",MESSAGE_ERROR);
00219                 error.run ();
00220                 goto error;
00221             }
00222             final_list += " cdimage/" + string (sernum);
00223             sernum++;
00224         }
00225         else {
00226             final_list += 
00227                 an_A + " " + pause [pre]  + " " +
00228                 a_B  + " " + pause [post] + " ";
00229         }
00230 
00231         DL((APP,"%s %s %s %s\n", an_A.c_str (), pause [pre].c_str (),
00232             a_B.c_str (), pause [post].c_str ()));
00233         
00234         m_pause_files.push_back (pause [pre]);
00235         m_pause_files.push_back (pause [post]);
00236         m_file_cnt += 4;
00237 
00238         refresh_gui ();
00239         iter++;
00240     }
00241 
00242     m_pause_in_progress = false;
00243     imp.hide ();
00244     refresh_gui ();
00245 
00251     cmd = "wavjoin --percent " + GWAVMERGER->wavjoin_options () + " "
00252         + final_list;
00253 
00254     if (m_pipe.open (cmd.c_str (), "r") == NULL) {
00255         Gtk::MessageDialog emsg ("\"wavjoin\" failed!",MESSAGE_ERROR);
00256         emsg.run ();
00257         EL((ERROR,"popen (\"%s\") failed\n", cmd.c_str ()));
00258         goto error;
00259     }
00260     /* Make a C++ input stream out of file descriptor.
00261      * This is non-portable.
00262      */
00263     m_pinstream = m_pipe.fp ();
00264       
00265     /* Register self as IOHandler to read from the pipe.
00266      */
00267     REACTOR->registerIOHandler (this, m_pipe.fd (), READ_EVENT);
00268     
00269     /* Desensitize 'Exec' button
00270      */
00271     set_response_sensitive (0, false);
00272     m_in_progress = true;
00273 
00278     return;
00279 
00280  error:
00281     refresh_gui ();
00282     roll_back (true);
00283     ::chdir (m_cwd.c_str ());
00284 }
00285 
00286 
00294 int
00295 
00296 MergeDialog::handle_read (int fd_)
00297 {  
00298     trace("MergeDialog::handle_read");
00299     static int MAXLINE = 128;
00300     char line [MAXLINE];
00301 
00302     if (fgets (line, MAXLINE, m_pinstream) == NULL) {
00303         DL((TRACE,"Received EOF from Pipe\n"));
00304         return -1;
00305     }
00306     line [strlen (line)-1] = '\0';
00307     DL((APP, "Received \"%s\"\n", line));
00308 
00309     int percent = strtol(line, (char **)NULL, 10);
00310 
00311     if (percent == 0) { // next file
00312         m_file_name_label->set_text (line);
00313         m_file_progress->set_fraction (0);
00314         m_curr_file++;
00315         sprintf (line, "%03d / %03d", m_curr_file, m_file_cnt);
00316         m_total_label->set_text (line);
00317         m_total_progress->set_fraction (m_curr_file * 1.0 / m_file_cnt);
00318         DL((APP,"A new file name (%d of %d)\n", m_curr_file, m_file_cnt));
00319     }
00320     else {          // file progress status
00321         m_file_progress->set_fraction (percent / 100.0);
00322         DL((APP,"File progress: %5.2f (%d \%)\n", (percent / 100.0), percent));
00323     }
00324 
00325     return 0;
00326 }
00327 
00333 int
00334 
00335 MergeDialog::handle_close (int fd_)
00336 {  
00337     trace("MergeDialog::handle_close");
00338 
00339     m_pipe.close ();
00340     if (m_pinstream) {
00341         m_pinstream = NULL;
00342     }
00343 
00344     roll_back ();
00345     hide ();
00346     response (Gtk::RESPONSE_NONE);
00347     return 0;
00348 }
00349 
00356 void
00357 
00358 MergeDialog::roll_back (bool failed_)
00359 {  
00360     trace("MergeDialog::roll_back");
00361 
00362     PauseList::const_iterator i = m_pause_files.begin ();
00363     while (i != m_pause_files.end ()) {
00364         ::unlink ((*i).c_str ());
00365         i++;
00366     }
00367     m_pause_files.clear ();
00368 
00369     if (failed_) {
00370         if (m_result.size () != 0) {
00371             ::unlink (m_result.c_str ());
00372         }
00373         
00374         if (make_cd_checked ()) {
00375             ::system ("rm -f cdimage/*.wav");
00376         }
00377     }
00378 
00379     m_in_progress = false;
00380 }
00381 
00385 void 
00386 
00387 MergeDialog::on_cancel_button_clicked()
00388 {  
00389     trace("MergeDialog::on_cancel_button_clicked");
00390 
00391     if (m_pause_in_progress) {
00392         m_pause_in_progress = false;
00393     }
00394     if (m_in_progress) {
00395         m_pipe.kill ();
00396 
00397         REACTOR->removeHandler (this, READ_EVENT);
00398         m_in_progress = false;
00399     }
00400 
00401     roll_back (true);
00402     if (m_cwd.size ()) {
00403         ::chdir (m_cwd.c_str ());
00404     }
00405     hide_all ();
00406 }
00407 
00411 int
00412 
00413 MergeDialog::create_pause_files (const string& infile_, 
00414                     const string  pause [2], 
00415                     Delays& delays_)
00416 {
00417     trace("MergeDialog::create_pause_files");
00418     string cmd;
00419     int ret;
00420     
00421     for (int i = 0; m_pause_in_progress && i < 2; i++) {
00422         cmd = "wavpause --output-file=" + pause [i] + " "+ delays_ (i, infile_);
00423         ret = system (cmd.c_str ());
00424 
00425         if (ret == -1 || ret == 127) {
00426             Gtk::MessageDialog emsg ("wavpause failed!", MESSAGE_ERROR);
00427             emsg.run ();
00428             EL((ERROR,"system(\"%s\") error\n", cmd.c_str ()));
00429             roll_back (true);
00430             return -1;
00431         }
00432     }
00433 
00434     return 0;
00435 }

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