#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. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002