00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qaction.h>
00022 #include <qbuttongroup.h>
00023 #include <qcheckbox.h>
00024 #include <qdatetime.h>
00025 #include <qfiledialog.h>
00026 #include <qmessagebox.h>
00027 #include <qpixmap.h>
00028 #include <qpushbutton.h>
00029 #include <qradiobutton.h>
00030 #include <qregexp.h>
00031 #include <qspinbox.h>
00032 #include <qtable.h>
00033 #include <qtextedit.h>
00034
00035 #include "aboutdlg.hh"
00036 #include "common.hh"
00037 #include "finddlg.h"
00038 #include "pasteselectdlg.h"
00039 #include "precisetimeedit.hh"
00040 #include "shifttimesdlg.h"
00041 #include "subtimerwnd.hh"
00042 #include "wavewidget.hh"
00043
00044 SubTimerWnd::SubTimerWnd(QWidget *parent, const char *name, WFlags fl)
00045 : SubTimerWndBase(parent, name, fl)
00046 {
00047 setIcon(QPixmap::fromMimeSource("timer-icon.xpm"));
00048 tableLines->horizontalHeader()->setLabel(0, tr("Start time"));
00049 tableLines->horizontalHeader()->setLabel(1, tr("End time"));
00050 tableLines->horizontalHeader()->setLabel(2, tr("Name"));
00051 tableLines->horizontalHeader()->setLabel(3, tr("Text"));
00052 tableLines->setColumnWidth(0, 100);
00053 tableLines->setColumnWidth(1, 100);
00054 tableLines->setColumnWidth(2, 60);
00055 tableLines->setColumnWidth(3, 1000);
00056 editCurrentLine->setTextFormat(QTextEdit::PlainText);
00057
00058 changed = false;
00059 sub = NULL;
00060 }
00061
00062 SubTimerWnd::~SubTimerWnd()
00063 {
00064 clearClipboard();
00065 if(sub != NULL) {
00066 sub->eraseAll();
00067 delete sub;
00068 }
00069 }
00070
00071 void SubTimerWnd::checkMultipleLines()
00072 {
00073 int seltop = tableLines->selection(0).topRow();
00074 if(seltop != tableLines->selection(0).bottomRow()) {
00075 editPaste_lineAction->setEnabled(false);
00076 editAdd_line_beforeAction->setEnabled(false);
00077 editAdd_line_afterAction->setEnabled(false);
00078 editSplit_lineAction->setEnabled(false);
00079 editMerge_with_next_lineAction->setEnabled(false);
00080 } else {
00081 editPaste_lineAction->setEnabled(true);
00082 editAdd_line_beforeAction->setEnabled(true);
00083 editAdd_line_afterAction->setEnabled(true);
00084 editSplit_lineAction->setEnabled(true);
00085 if(seltop == tableLines->numRows() - 1)
00086 editMerge_with_next_lineAction->setEnabled(false);
00087 else
00088 editMerge_with_next_lineAction->setEnabled(true);
00089 }
00090 }
00091
00092 void SubTimerWnd::clearClipboard()
00093 {
00094 for(std::list<SubTitle::Event *>::const_iterator ei = clipboard.begin();
00095 ei != clipboard.end(); ++ei)
00096 delete *ei;
00097 clipboard.clear();
00098 }
00099
00100 void SubTimerWnd::closeEvent(QCloseEvent *ce)
00101 {
00102 if(changed)
00103 if(QMessageBox::warning(this, tr("Unsaved changes"),
00104 tr("You have made unsaved changes. Continue?"),
00105 QMessageBox::No,
00106 QMessageBox::Yes) == QMessageBox::No)
00107 ce->ignore();
00108 else
00109 ce->accept();
00110 else
00111 ce->accept();
00112 }
00113
00114 void SubTimerWnd::copyLines(int from, int until)
00115 {
00116 clearClipboard();
00117 for(int i = from; i <= until; ++i)
00118 clipboard.push_front(new SubTitle::Event(*(*sub)[i]));
00119 }
00120
00121 void SubTimerWnd::eraseLines(int from, int until)
00122 {
00123 for(int i = 0; i <= until - from; ++i)
00124 sub->erase(from);
00125 }
00126
00127 void SubTimerWnd::loadEvent(int i, SubTitle::Event *e)
00128 {
00129 tableLines->setText(i, 0, e->start.toString("hh:mm:ss.zzz"));
00130 tableLines->setText(i, 1, e->end.toString("hh:mm:ss.zzz"));
00131 tableLines->setText(i, 2, e->name);
00132 tableLines->setText(i, 3, e->dialogue);
00133 if(!changed) {
00134 changed = true;
00135 setCaption(caption() + "*");
00136 }
00137 }
00138
00139 void SubTimerWnd::loadEventFromTable(bool scrolling)
00140 {
00141 int seltop = tableLines->selection(0).topRow();
00142 editCurrentLine->setText(convertNToEnter((*sub)[seltop]->dialogue));
00143 editStartTime->setTime((*sub)[seltop]->start);
00144 editEndTime->setTime((*sub)[seltop]->end);
00145 if(!waveBand->isVisible((*sub)[seltop]->start) ||
00146 !waveBand->isVisible((*sub)[seltop]->end)) {
00147 int newleft = SECS((*sub)[seltop]->start) - 2;
00148 if(scrolling) {
00149 if(newleft < 0)
00150 waveBand->scrollTo(0);
00151 else
00152 waveBand->scrollTo(newleft);
00153 }
00154 }
00155 }
00156
00157 QString SubTimerWnd::convertEnterToN(QString s) const
00158 {
00159 return s.replace('\n', "\\N");
00160 }
00161
00162 QString SubTimerWnd::convertNToEnter(QString s) const
00163 {
00164 return s.replace("\\N", "\n", FALSE);
00165 }
00166
00167 void SubTimerWnd::fileOpen()
00168 {
00169 if(changed)
00170 if(QMessageBox::warning(this, tr("Unsaved changes"),
00171 tr("You have made unsaved changes. Continue?"),
00172 QMessageBox::No,
00173 QMessageBox::Yes) == QMessageBox::No)
00174 return;
00175
00176 QString s = QFileDialog::getOpenFileName(QString::null,
00177 "SubStation Alpha (*.ssa);;"
00178 "SubRip (*.srt);;"
00179 "Text (*.txt)",
00180 this,
00181 "open subtitle dialog",
00182 tr("Open a subtitle..."));
00183 if(s == QString::null)
00184 return;
00185
00186 SubTitle *tsub;
00187
00188 if(s.right(4).upper() == ".SSA") {
00189 tsub = new SsaSub();
00190 } else if(s.right(4).upper() == ".SRT") {
00191 tsub = new SrtSub();
00192 } else {
00193 tsub = new TxtSub();
00194 }
00195
00196 QFile f(s);
00197 if(!f.open(IO_ReadOnly)) {
00198 QMessageBox::critical(this, tr("Cannot open file"),
00199 tr("Cannot open file: %1!").arg(s),
00200 QMessageBox::Cancel, QMessageBox::NoButton);
00201 return;
00202 }
00203 if(!tsub->loadFromFile(&f)) {
00204 QMessageBox::critical(this, tr("File not valid"),
00205 tr("%1 is not a valid subtitle file!").arg(s),
00206 QMessageBox::Cancel, QMessageBox::NoButton);
00207 return;
00208 }
00209 f.close();
00210
00211 if(sub != NULL) {
00212 sub->eraseAll();
00213 delete sub;
00214 }
00215 sub = tsub;
00216
00217 tableLines->setCurrentCell(0, 0);
00218 tableLines->clearSelection();
00219 tableLines->setNumRows(sub->count());
00220 for(size_t i = 0; i < sub->count(); ++i)
00221 loadEvent(i, (*sub)[i]);
00222
00223 changed = false;
00224 fname = s;
00225 setCaption("SubTimer - " +
00226 fname.right(fname.length() - fname.findRev('/') - 1));
00227
00228 fileSaveAction->setEnabled(true);
00229 fileSaveAsAction->setEnabled(true);
00230 editShift_timesAction->setEnabled(true);
00231 editFindAction->setEnabled(true);
00232 editCut_lineAction->setEnabled(true);
00233 editCopy_lineAction->setEnabled(true);
00234 editPaste_lineAction->setEnabled(true);
00235 editErase_lineAction->setEnabled(true);
00236 editAdd_line_beforeAction->setEnabled(true);
00237 editAdd_line_afterAction->setEnabled(true);
00238 editSplit_lineAction->setEnabled(true);
00239 editMerge_with_next_lineAction->setEnabled(true);
00240 buttonOpenWave->setEnabled(true);
00241 editStartTime->setEnabled(true);
00242 editEndTime->setEnabled(true);
00243 editDuration->setEnabled(true);
00244 buttonGrabSelected->setEnabled(true);
00245 editCurrentLine->setEnabled(true);
00246 tableLines->setEnabled(true);
00247
00248 tableLines->setFocus();
00249 tableLines->selectRow(0);
00250 }
00251
00252 void SubTimerWnd::fileSave()
00253 {
00254 if(!changed) return;
00255 QFile f(fname);
00256 if(!f.open(IO_WriteOnly)) {
00257 QMessageBox::critical(this, tr("Cannot write file"),
00258 tr("Cannot write file: %1!").arg(fname),
00259 QMessageBox::Cancel, QMessageBox::NoButton);
00260 return;
00261 }
00262 sub->saveToFile(&f);
00263 changed = false;
00264 setCaption(caption().left(caption().length() - 1));
00265 }
00266
00267 void SubTimerWnd::fileSaveAs()
00268 {
00269 QString *filter = new QString(QString::null);
00270 QString s = QFileDialog::getSaveFileName(QString::null,
00271 "SubStation Alpha (*.ssa);;"
00272 "SubRip (*.srt);;"
00273 "Text (*.txt)",
00274 this,
00275 "save subtitle dialog",
00276 tr("Save subtitle..."),
00277 filter);
00278 if(s == QString::null)
00279 return;
00280
00281 if(s.right(4).upper() != ".SSA" &&
00282 s.right(4).upper() != ".SRT" &&
00283 s.right(4).upper() != ".TXT")
00284 s += filter->right(5).left(4);
00285 delete filter;
00286
00287 SubTitle *tsub;
00288
00289 if(s.right(4).upper() == ".SSA") {
00290 tsub = new SsaSub(sub);
00291 } else if(s.right(4).upper() == ".SRT") {
00292 tsub = new SrtSub(sub);
00293 } else {
00294 tsub = new TxtSub(sub);
00295 }
00296
00297 if(QFile::exists(s)) {
00298 if(QMessageBox::warning(this, tr("Overwrite file"),
00299 tr("%1 already exists. Overwrite?").arg(s),
00300 QMessageBox::No,
00301 QMessageBox::Yes) == QMessageBox::No)
00302 return;
00303 }
00304 QFile f(s);
00305 if(!f.open(IO_WriteOnly)) {
00306 QMessageBox::critical(this, tr("Cannot write file"),
00307 tr("Cannot write file: %1!").arg(s),
00308 QMessageBox::Cancel, QMessageBox::NoButton);
00309 return;
00310 }
00311 tsub->saveToFile(&f);
00312 changed = false;
00313
00314 if(sub != NULL) {
00315 sub->eraseAll();
00316 delete sub;
00317 }
00318 sub = tsub;
00319
00320 fname = s;
00321 setCaption("SubTimer - " +
00322 fname.right(fname.length() - fname.findRev('/') - 1));
00323 }
00324
00325 void SubTimerWnd::editShiftTimes()
00326 {
00327 ShiftTimesDlg st(this);
00328 if(tableLines->selection(0).topRow() !=
00329 tableLines->selection(0).bottomRow())
00330 st.shiftSelected->setChecked(true);
00331 if(st.exec() == QDialog::Rejected) return;
00332
00333 int shift = MSECS(st.shiftTime->time());
00334 if(st.dirBackward->isChecked())
00335 shift *= -1;
00336 int seltop = tableLines->selection(0).topRow();
00337 int selbot;
00338 if(st.shiftAll->isChecked())
00339 selbot = tableLines->numRows() - 1;
00340 else
00341 selbot = tableLines->selection(0).bottomRow();
00342
00343 if(st.dirBackward->isChecked()) {
00344 QTime min = (*sub)[seltop]->start;
00345 int mini = seltop;
00346 for(int i = seltop + 1; i <= selbot; ++i)
00347 if((*sub)[i]->start < min) {
00348 min = (*sub)[i]->start;
00349 mini = i;
00350 }
00351 if(-shift > MSECS(min)) {
00352 QString s;
00353 QMessageBox::critical(this, tr("Cannot shift to negative time"),
00354 tr("After this shift line %1 would be in "
00355 "negative time!").arg(mini + 1),
00356 QMessageBox::Cancel, QMessageBox::NoButton);
00357 return;
00358 }
00359 } else {
00360 QTime max = (*sub)[seltop]->end;
00361 int maxi = seltop;
00362 for(int i = seltop + 1; i <= selbot; ++i)
00363 if((*sub)[i]->end > max) {
00364 max = (*sub)[i]->end;
00365 maxi = i;
00366 }
00367 if(shift > max.msecsTo(QTime(23, 59, 59, 999))) {
00368 QString s;
00369 QMessageBox::critical(this, tr("Cannot shift to over 24 hours"),
00370 tr("After this shift line %1 would exceed "
00371 "24 hours!").arg(maxi + 1),
00372 QMessageBox::Cancel, QMessageBox::NoButton);
00373 return;
00374 }
00375 }
00376
00377 for(int i = seltop; i <= selbot; ++i) {
00378 (*sub)[i]->start = (*sub)[i]->start.addMSecs(shift);
00379 (*sub)[i]->end = (*sub)[i]->end.addMSecs(shift);
00380 loadEvent(i, (*sub)[i]);
00381 }
00382 loadEventFromTable();
00383 }
00384
00385 void SubTimerWnd::editFind()
00386 {
00387 FindDlg f(this);
00388 if(f.exec() == QDialog::Rejected) return;
00389
00390 find_string = f.editSearchString->text();
00391 sensitive_find = f.checkCase->isChecked();
00392 editFind_AgainAction->setEnabled(true);
00393
00394 editFindAgain();
00395 }
00396
00397 void SubTimerWnd::editFindAgain()
00398 {
00399 int i = tableLines->selection(0).topRow();
00400 bool found = false;
00401 while(++i < tableLines->numRows())
00402 if(sensitive_find) {
00403 if(tableLines->text(i, 3).find(find_string) != -1) {
00404 found = true;
00405 break;
00406 }
00407 } else {
00408 if(tableLines->text(i, 3).lower().find(find_string.lower()) != -1) {
00409 found = true;
00410 break;
00411 }
00412 }
00413 if(!found)
00414 QMessageBox::information(this, tr("Not found"),
00415 tr("Search string \"%1\" not found!").
00416 arg(find_string), QMessageBox::Ok);
00417 else {
00418 tableLines->setCurrentCell(i, 0);
00419 tableLines->clearSelection();
00420 tableLines->selectRow(i);
00421 loadEventFromTable();
00422 checkMultipleLines();
00423 }
00424 }
00425
00426 void SubTimerWnd::editCutLine()
00427 {
00428 int seltop = tableLines->selection(0).topRow();
00429 int selbot = tableLines->selection(0).bottomRow();
00430 if(seltop == 0 && selbot == tableLines->numRows() - 1) {
00431 QMessageBox::critical(this, tr("Cannot cut all lines"),
00432 tr("You cannot cut all lines!"),
00433 QMessageBox::Cancel, QMessageBox::NoButton);
00434 return;
00435 }
00436 copyLines(seltop, selbot);
00437 eraseLines(seltop, selbot);
00438 tableLines->setNumRows(sub->count());
00439 for(int i = seltop; i < (int)sub->count(); ++i)
00440 loadEvent(i, (*sub)[i]);
00441 if((unsigned int)seltop == sub->count())
00442 --seltop;
00443 tableLines->setCurrentCell(seltop, 0);
00444 tableLines->clearSelection();
00445 tableLines->selectRow(seltop);
00446 loadEventFromTable();
00447 checkMultipleLines();
00448 }
00449
00450 void SubTimerWnd::editCopyLine()
00451 {
00452 int seltop = tableLines->selection(0).topRow();
00453 int selbot = tableLines->selection(0).bottomRow();
00454 copyLines(seltop, selbot);
00455 }
00456
00457 void SubTimerWnd::editPasteLine()
00458 {
00459 if(clipboard.empty()) return;
00460
00461 PasteSelectDlg psd(this);
00462 if(psd.exec() == QDialog::Rejected) return;
00463 int paste_mode = psd.pasteModeGroup->selectedId();
00464
00465 int i = tableLines->selection(0).topRow();
00466 QTime start_time;
00467 if(i == 0)
00468 start_time = QTime(0, 0);
00469 else
00470 start_time = (*sub)[i-1]->end;
00471 int shift = clipboard.back()->start.msecsTo(start_time);
00472 int dist = start_time.msecsTo((*sub)[i]->start) / clipboard.size();
00473
00474 bool shift_error = false;
00475
00476 std::list<SubTitle::Event *> cliptmp;
00477 int j = clipboard.size();
00478 for(std::list<SubTitle::Event *>::const_iterator ei = clipboard.begin();
00479 ei != clipboard.end(); ++ei) {
00480 SubTitle::Event *e = new SubTitle::Event;
00481 switch(paste_mode) {
00482 case 0:
00483 e->start = (*ei)->start;
00484 e->end = (*ei)->end;
00485 break;
00486 case 1:
00487 e->start = (*ei)->start.addMSecs(shift);
00488 e->end = (*ei)->end.addMSecs(shift);
00489 if(shift > (*ei)->end.msecsTo(QTime(23, 59, 59, 999)))
00490 shift_error = true;
00491 break;
00492 case 2:
00493 e->end = start_time.addMSecs(dist * j);
00494 e->start = start_time.addMSecs(dist * (--j));
00495 break;
00496 }
00497 e->name = (*ei)->name;
00498 e->dialogue = (*ei)->dialogue;
00499 cliptmp.push_back(e);
00500 }
00501
00502 if(shift_error) {
00503 QMessageBox::critical(this, tr("Paste over 24 hours"),
00504 tr("Pasted lines would exceed 24 hours!"),
00505 QMessageBox::Cancel, QMessageBox::NoButton);
00506 return;
00507 }
00508
00509 for(std::list<SubTitle::Event *>::const_iterator ei = cliptmp.begin();
00510 ei != cliptmp.end(); ++ei)
00511 sub->insertBefore(i, *ei);
00512 tableLines->setNumRows(sub->count());
00513 tableLines->setCurrentCell(i, 0);
00514 tableLines->clearSelection();
00515 tableLines->selectCells(i, 0, i + cliptmp.size() - 1, 3);
00516 for(; i < (int)sub->count(); ++i) {
00517 loadEvent(i, (*sub)[i]);
00518 }
00519 loadEventFromTable();
00520 checkMultipleLines();
00521 }
00522
00523 void SubTimerWnd::editEraseLine()
00524 {
00525 int seltop = tableLines->selection(0).topRow();
00526 int selbot = tableLines->selection(0).bottomRow();
00527 if(seltop == 0 && selbot == tableLines->numRows() - 1) {
00528 QMessageBox::critical(this, tr("Cannot erase all lines"),
00529 tr("You cannot erase all lines!"),
00530 QMessageBox::Cancel, QMessageBox::NoButton);
00531 return;
00532 }
00533 if(seltop != selbot) {
00534 QString s;
00535 if(QMessageBox::warning(this, tr("Delete lines"),
00536 tr("Are you sure you want to delete "
00537 "lines %1-%2?").arg(seltop + 1).arg(selbot + 1),
00538 QMessageBox::No,
00539 QMessageBox::Yes) == QMessageBox::No)
00540 return;
00541 }
00542 eraseLines(seltop, selbot);
00543 tableLines->setNumRows(sub->count());
00544 for(int i = seltop; i < (int)sub->count(); ++i)
00545 loadEvent(i, (*sub)[i]);
00546 if((unsigned int)seltop == sub->count())
00547 --seltop;
00548 tableLines->setCurrentCell(seltop, 0);
00549 tableLines->clearSelection();
00550 tableLines->selectRow(seltop);
00551 loadEventFromTable();
00552 checkMultipleLines();
00553 }
00554
00555 void SubTimerWnd::editAddLineBefore()
00556 {
00557 int i = tableLines->selection(0).topRow();
00558
00559 SubTitle::Event *e = new SubTitle::Event;
00560 if(i == 0)
00561 e->start = QTime(0, 0);
00562 else
00563 e->start = (*sub)[i-1]->end;
00564 e->end = (*sub)[i]->start;
00565 e->name = tr("Default");
00566 e->dialogue = "";
00567
00568 sub->insertBefore(i, e);
00569 tableLines->setNumRows(sub->count());
00570 for(; i < (int)sub->count(); ++i)
00571 loadEvent(i, (*sub)[i]);
00572 loadEventFromTable();
00573 }
00574
00575 void SubTimerWnd::editAddLineAfter()
00576 {
00577 int i = tableLines->selection(0).topRow();
00578
00579 SubTitle::Event *e = new SubTitle::Event;
00580 e->start = (*sub)[i]->end;
00581 if(i == tableLines->numRows() - 1)
00582 e->end = (*sub)[i]->end.addSecs(3);
00583 else
00584 e->end = (*sub)[i+1]->start;
00585 e->name = tr("Default");
00586 e->dialogue = "";
00587
00588 sub->insertAfter(i, e);
00589 tableLines->setNumRows(sub->count());
00590 tableLines->setCurrentCell(i+1, 0);
00591 tableLines->clearSelection();
00592 tableLines->selectRow(i+1);
00593 for(; i < (int)sub->count(); ++i)
00594 loadEvent(i, (*sub)[i]);
00595 loadEventFromTable();
00596 }
00597
00598 void SubTimerWnd::editSplit()
00599 {
00600 int i = tableLines->selection(0).topRow();
00601 QTime t;
00602 int j, k;
00603
00604 t = (*sub)[i]->start.addMSecs((*sub)[i]->start.msecsTo((*sub)[i]->end) / 2);
00605 j = (*sub)[i]->dialogue.find(' ', (*sub)[i]->dialogue.length() / 2);
00606 k = (*sub)[i]->dialogue.find('.', (*sub)[i]->dialogue.length() / 2);
00607 if(j < 0 || (k < j && k >= 0)) k = j;
00608 k = (*sub)[i]->dialogue.find(':', (*sub)[i]->dialogue.length() / 2);
00609 if(j < 0 || (k < j && k >= 0)) k = j;
00610 k = (*sub)[i]->dialogue.find(';', (*sub)[i]->dialogue.length() / 2);
00611 if(j < 0 || (k < j && k >= 0)) k = j;
00612 k = (*sub)[i]->dialogue.find('!', (*sub)[i]->dialogue.length() / 2);
00613 if(j < 0 || (k < j && k >= 0)) k = j;
00614 k = (*sub)[i]->dialogue.find('?', (*sub)[i]->dialogue.length() / 2);
00615 if(j < 0 || (k < j && k >= 0)) k = j;
00616
00617 if(j >= 0)
00618 j = (*sub)[i]->dialogue.find(QRegExp("[^ ]"), j + 1);
00619 if(j < 0)
00620 j = (*sub)[i]->dialogue.length() / 2;
00621
00622 SubTitle::Event *e = new SubTitle::Event;
00623 e->start = t;
00624 e->end = (*sub)[i]->end;
00625 e->name = (*sub)[i]->name;
00626 e->dialogue = (*sub)[i]->dialogue.mid(j);
00627 sub->insertAfter(i, e);
00628
00629 (*sub)[i]->end = t;
00630 (*sub)[i]->dialogue = (*sub)[i]->dialogue.left(j);
00631
00632 tableLines->setNumRows(sub->count());
00633 for(; i < (int)sub->count(); ++i)
00634 loadEvent(i, (*sub)[i]);
00635 loadEventFromTable();
00636 }
00637
00638 void SubTimerWnd::editMerge()
00639 {
00640 int i = tableLines->selection(0).topRow();
00641 (*sub)[i]->end = (*sub)[i+1]->end;
00642 (*sub)[i]->dialogue = (*sub)[i]->
00643 dialogue.stripWhiteSpace().append(" ").
00644 append((*sub)[i+1]->dialogue.stripWhiteSpace());
00645 sub->erase(i+1);
00646 tableLines->setNumRows(sub->count());
00647 for(; i < (int)sub->count(); ++i)
00648 loadEvent(i, (*sub)[i]);
00649 loadEventFromTable();
00650 }
00651
00652 void SubTimerWnd::optionsNextLineAfterGrab(bool on)
00653 {
00654 if(!on) {
00655 optionsGuess_time_after_grabAction->setOn(false);
00656 optionsGuess_time_after_grabAction->setEnabled(false);
00657 } else
00658 optionsGuess_time_after_grabAction->setEnabled(true);
00659 }
00660
00661 void SubTimerWnd::helpUsingSubTimer()
00662 {
00663 QMessageBox::information(this, tr("Using SubTimer..."),
00664 tr("Online help is not available yet. "
00665 "Please refer to the documentation "
00666 "that comes with the SubTimer package."),
00667 QMessageBox::Ok);
00668 }
00669
00670 void SubTimerWnd::helpAbout()
00671 {
00672 AboutDlg d(this);
00673 d.exec();
00674 }
00675
00676 void SubTimerWnd::helpAboutQt()
00677 {
00678 QMessageBox::aboutQt(this, tr("About Qt..."));
00679 }
00680
00681 void SubTimerWnd::onDurationChanged()
00682 {
00683 QTime temp = editStartTime->time().
00684 addMSecs(MSECS(editDuration->time()));
00685 if(temp != editEndTime->time()) {
00686 editEndTime->setTime(temp);
00687 waveBand->setEndTime(temp);
00688 }
00689 }
00690
00691 void SubTimerWnd::onEndTimeChanged(QTime *end)
00692 {
00693 editEndTime->setTime(*end);
00694 }
00695
00696 void SubTimerWnd::onGrabSelected()
00697 {
00698 int i = tableLines->selection(0).topRow();
00699 (*sub)[i]->start = editStartTime->time();
00700 (*sub)[i]->end = editEndTime->time();
00701 (*sub)[i]->dialogue = convertEnterToN(editCurrentLine->text());
00702 loadEvent(i, (*sub)[i]);
00703 if(optionsNext_line_after_grabAction->isOn() &&
00704 i != tableLines->numRows() - 1) {
00705 tableLines->setCurrentCell(i+1, 0);
00706 tableLines->clearSelection();
00707 tableLines->selectRow(i+1);
00708 if(optionsGuess_time_after_grabAction->isOn()) {
00709 loadEventFromTable(false);
00710 editStartTime->setTime((*sub)[i]->end);
00711 editEndTime->setTime((*sub)[i]->end.addSecs(2));
00712 } else
00713 loadEventFromTable();
00714 }
00715 }
00716
00717 void SubTimerWnd::onOpenWave()
00718 {
00719 QString s = QFileDialog::getOpenFileName(QString::null,
00720 "Ogg Vorbis (*.ogg)",
00721 this,
00722 "open wave dialog",
00723 tr("Open a wave file..."));
00724 if(s == QString::null)
00725 return;
00726
00727 QFile f(s);
00728 if(!f.open(IO_ReadOnly)) {
00729 QMessageBox::critical(this, tr("Cannot open file"),
00730 tr("Cannot open file: %1!").arg(s),
00731 QMessageBox::Cancel, QMessageBox::NoButton);
00732 return;
00733 }
00734 f.close();
00735
00736 if(!waveBand->loadFile(s)) {
00737 QMessageBox::critical(this, tr("File not valid"),
00738 tr("%1 is not a valid wave file!").arg(s),
00739 QMessageBox::Cancel, QMessageBox::NoButton);
00740 return;
00741 }
00742
00743 onTimeChanged();
00744 loadEventFromTable();
00745
00746 waveBand->setEnabled(true);
00747 scrollWave->setEnabled(true);
00748 spinXZoom->setEnabled(true);
00749 spinYZoom->setEnabled(true);
00750 buttonPlayNext->setEnabled(true);
00751 buttonStop->setEnabled(true);
00752 buttonPlaySelected->setEnabled(true);
00753 }
00754
00755 void SubTimerWnd::onPlayNext()
00756 {
00757 int i = tableLines->selection(0).topRow();
00758 tableLines->setCurrentCell(i+1, 0);
00759 tableLines->clearSelection();
00760 tableLines->selectRow(i+1);
00761 loadEventFromTable();
00762 waveBand->playSelected();
00763 }
00764
00765 void SubTimerWnd::onSelectionChanged()
00766 {
00767 int i = tableLines->selection(tableLines->currentSelection()).topRow();
00768 if(i != -1) {
00769 int seltop = std::min(tableLines->selection(0).topRow(), i);
00770 int selbot = std::max(tableLines->selection(0).bottomRow(),
00771 tableLines->
00772 selection(tableLines->
00773 currentSelection()).bottomRow());
00774 QTableSelection ts(seltop, 0, selbot, 3);
00775 tableLines->clearSelection();
00776 tableLines->addSelection(ts);
00777
00778 loadEventFromTable();
00779 checkMultipleLines();
00780 }
00781 }
00782
00783 void SubTimerWnd::onStartTimeChanged(QTime *start)
00784 {
00785 editStartTime->setTime(*start);
00786 }
00787
00788 void SubTimerWnd::onTimeChanged()
00789 {
00790 int change = editStartTime->time().msecsTo(editEndTime->time());
00791 if(change > 0) {
00792 QTime temp = QTIME_MS(change);
00793 if(temp != editDuration->time())
00794 editDuration->setTime(temp);
00795 }
00796 else
00797 editDuration->setTime(QTime(0, 0));
00798 waveBand->setStartTime(editStartTime->time());
00799 waveBand->setEndTime(editEndTime->time());
00800 }
00801
00802 void SubTimerWnd::setScrollMax(int length)
00803 {
00804 scrollWave->setMaxValue(length / 1000 + 2);
00805 scrollWave->setMinValue(0);
00806 }