#include <MergeDialog.h>
Inheritance diagram for MergeDialog:
Public Methods | |
MergeDialog (Config &cfg_, Glib::RefPtr< Gtk::ListStore > clist_, const ModelColumns &columns_) | |
~MergeDialog () | |
virtual int | handle_read (int fd_) |
virtual int | handle_close (int fd_) |
void | run_merge () |
void | reply (int button_) |
Private Types | |
typedef std::vector< std::string > | PauseList |
enum | { pre = 0, post } |
Private Methods | |
void | init () |
void | roll_back (bool failed_=false) |
void | on_ok_button_clicked () |
void | on_cancel_button_clicked () |
int | create_pause_files (const string &, const string[], Delays &) |
void | refresh_gui () const |
Private Attributes | |
Config & | m_config |
Glib::RefPtr< Gtk::ListStore > | m_clist |
const ModelColumns & | m_columns |
bool | m_in_progress |
bool | m_pause_in_progress |
PauseList | m_pause_files |
std::string | m_result |
std::string | m_cwd |
uint | m_file_cnt |
uint | m_curr_file |
bool | m_del_old_file |
ASSA::Pipe | m_pipe |
FILE * | m_pinstream |
Friends | |
class | MergeDialog_ui |
|
Definition at line 62 of file MergeDialog.h. |
|
Definition at line 61 of file MergeDialog.h.
|
|
Definition at line 88 of file MergeDialog.h. References init.
00090 : m_config (cfg_), 00091 m_clist (clist_), 00092 m_columns (columns_), 00093 m_in_progress (false), 00094 m_pause_in_progress (false), 00095 m_del_old_file (false), 00096 m_pinstream (NULL) 00097 { 00098 trace("MergeDialog::MergeDialog"); 00099 init (); 00100 } |
|
Definition at line 104 of file MergeDialog.h.
00105 { 00106 trace("MergerDialog::~MergeDialog"); 00107 } |
|
Referenced by on_ok_button_clicked. |
|
handle_close () is called by the ASSA::Reactor in response to handle_read () returning -1 as an indication that no more data processing is required. Definition at line 335 of file MergeDialog.cpp. References m_pinstream, m_pipe, and roll_back.
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 } |
|
read one record (separated by the newline) keep the rest in the internal buffer parse the record and update window components accordingly count the files until the last one is processed Pipe - does it have blocking or non-blocking descriptor? Definition at line 296 of file MergeDialog.cpp. References m_curr_file, m_file_cnt, MergeDialog_ui::m_file_name_label, MergeDialog_ui::m_file_progress, m_pinstream, MergeDialog_ui::m_total_label, and MergeDialog_ui::m_total_progress.
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 } |
|
Definition at line 69 of file MergeDialog.cpp. References m_curr_file, m_cwd, m_del_old_file, m_file_cnt, MergeDialog_ui::m_file_name_label, MergeDialog_ui::m_file_progress, MergeDialog_ui::m_first_cd_track, m_in_progress, MergeDialog_ui::m_make_cd, m_pause_in_progress, m_result, MergeDialog_ui::m_total_label, and MergeDialog_ui::m_total_progress. Referenced by MergeDialog, and run_merge.
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 } |
|
User clicked 'Cancel' button Definition at line 387 of file MergeDialog.cpp. References m_cwd, m_in_progress, m_pause_in_progress, m_pipe, REACTOR, and roll_back. Referenced by MergeDialog_ui::MergeDialog_ui.
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 } |
|
User clicked 'Exec' button. This is a rather long function. But every time I try to break it down, it somehow manages to assemble itself again. Definition at line 109 of file MergeDialog.cpp. References create_pause_files, MergeDialog_ui::first_cd_track, Config::get_proj_name, Config::get_proj_path, GWAVMERGER, m_clist, m_columns, m_config, m_cwd, m_file_cnt, m_in_progress, m_pause_files, m_pause_in_progress, m_pinstream, m_pipe, m_result, MergeDialog_ui::make_cd_checked, Config::make_pause_pathname, Config::make_rel_pathname, post, pre, REACTOR, refresh_gui, roll_back, ModelColumns::row_a, and ModelColumns::row_b. Referenced by MergeDialog_ui::MergeDialog_ui.
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 } |
|
Consume all queued X11 events Definition at line 40 of file MergeDialog.cpp. Referenced by on_ok_button_clicked.
00041 { 00042 trace("MergeDialog::refresh_gui"); 00043 00044 while (Gtk::Main::events_pending ()) { 00045 Gtk::Main::iteration (); 00046 } 00047 } |
|
Definition at line 111 of file MergeDialog.h. References m_del_old_file.
00112 { 00113 m_del_old_file = button_ == 0 ? true : false; 00114 } |
|
roll_back does post-processing clean-up. If failed_ is false, then we delete pause files only. If, on the other hand, failed_ is true, we also remove result file and all files in cdimage/ directory (if any). Definition at line 358 of file MergeDialog.cpp. References m_in_progress, m_pause_files, m_result, and MergeDialog_ui::make_cd_checked. Referenced by handle_close, on_cancel_button_clicked, and on_ok_button_clicked.
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 } |
|
MergeDialog is a MainWindow's data member. It is created by MainWindow's constructor and destroyed by its destructor. "Close" event causes it to hide() and member function run() shows it again. init() resets all internal data members responsible for displaying the progress to their initial values. Definition at line 60 of file MergeDialog.cpp. References init. Referenced by MainWindow::merge_cb.
00061 { 00062 trace("MergeDialog::run_merge"); 00063 init (); 00064 run (); 00065 } |
|
Definition at line 49 of file MergeDialog.h. |
|
Definition at line 65 of file MergeDialog.h. Referenced by on_ok_button_clicked. |
|
Definition at line 66 of file MergeDialog.h. Referenced by on_ok_button_clicked. |
|
Definition at line 64 of file MergeDialog.h. Referenced by on_ok_button_clicked. |
|
Definition at line 75 of file MergeDialog.h. Referenced by handle_read, and init. |
|
Definition at line 73 of file MergeDialog.h. Referenced by init, on_cancel_button_clicked, and on_ok_button_clicked. |
|
Definition at line 76 of file MergeDialog.h. |
|
Definition at line 74 of file MergeDialog.h. Referenced by handle_read, init, and on_ok_button_clicked. |
|
Definition at line 68 of file MergeDialog.h. Referenced by init, on_cancel_button_clicked, on_ok_button_clicked, and roll_back. |
|
Definition at line 71 of file MergeDialog.h. Referenced by on_ok_button_clicked, and roll_back. |
|
Definition at line 69 of file MergeDialog.h. Referenced by init, on_cancel_button_clicked, and on_ok_button_clicked. |
|
Definition at line 79 of file MergeDialog.h. Referenced by handle_close, handle_read, and on_ok_button_clicked. |
|
Definition at line 78 of file MergeDialog.h. Referenced by handle_close, on_cancel_button_clicked, and on_ok_button_clicked. |
|
Definition at line 72 of file MergeDialog.h. Referenced by init, on_ok_button_clicked, and roll_back. |