1 #include "qui/MussaWindow.hpp"
2 #include "mussa_exceptions.hpp"
6 #include <QApplication>
7 #include <QAssistantClient>
9 #include <QDesktopServices>
11 #include <QFileDialog>
12 #include <QHBoxLayout>
14 #include <QLibraryInfo>
16 #include <QMessageBox>
21 #include <QStringList>
22 #include <QTextStream>
30 #include <boost/filesystem/path.hpp>
31 #include <boost/filesystem/operations.hpp>
32 #include <boost/filesystem/convenience.hpp>
33 namespace fs = boost::filesystem;
34 #include <boost/bind.hpp>
38 static void init_resources() {
39 static bool resources_loaded = false;
40 if (not resources_loaded) {
41 Q_INIT_RESOURCE(icons);
42 resources_loaded = true;
46 MussaWindow::MussaWindow(MussaRef analysis_, QWidget *parent) :
50 setup_analysis_dialog(0),
58 createNewAnalysisAction(0),
59 createSubAnalysisAction(0),
61 loadMotifListAction(0),
63 loadSavedAnalysisAction(0),
64 mussaManualAssistantAction(0),
65 newMussaWindowAction(0),
66 saveMotifListAction(0),
67 showMussaViewToolbarAction(0),
68 toggleMotifsAction(0),
69 saveBrowserPixmapAction(0),
71 viewMussaAlignmentAction(0),
76 default_dir.reset(new QDir(QDir::home().absolutePath()));
83 setWindowIcon(QIcon(":/icons/mussa.png"));
85 setCentralWidget(browser);
86 // well updatePosition isn't quite right as we really just need
88 connect(this, SIGNAL(changedAnnotations()), browser, SLOT(update()));
89 connect(this, SIGNAL(changedMotifs()), this, SLOT(updateAnnotations()));
90 connect(browser, SIGNAL(basepairsCopied(size_t)),
91 this, SLOT(showBasePairsCopied(size_t)));
92 connect(zoom, SIGNAL(valueChanged(double)),
93 browser, SLOT(setZoom(double)));
94 mussaViewTB->addWidget(zoom);
96 // Mouse Wheel triggered zooming
97 connect(browser, SIGNAL(mouseWheelZoom(double)),
98 zoom, SLOT(setValue(double)));
100 // threshold range is set in updateAnalysis
101 connect(threshold, SIGNAL(thresholdChanged(int)),
102 this, SLOT(setSoftThreshold(int)));
103 mussaViewTB->addWidget(threshold);
105 addToolBar(mussaViewTB);
107 statusBar()->showMessage("Welcome to mussa", 2000);
109 // FIXME: we should start refactoring the connect call to updateAnalysis or something
111 connect(analysis.get(), SIGNAL(progress(const QString&, int, int)),
112 this, SLOT(updateProgress(const QString&, int, int)));
113 connect(analysis.get(), SIGNAL(isModified(bool)),
114 this, SLOT(updateAnalysisModified(bool)));
120 void MussaWindow::setAnalysis(MussaRef new_analysis)
122 if (new_analysis != 0) {
123 // only switch mussas if we loaded without error
125 //std::cout << "analysis soft: " << analysis->get_soft_threshold()
126 // << " new analysis soft: " << new_analysis->get_soft_threshold()
128 analysis.swap(new_analysis);
129 //std::cout << "after swap soft thres: " << analysis->get_soft_threshold()
131 threshold->disconnect(this);
132 threshold->reset(analysis->get_threshold(),
133 analysis->get_window(),
134 analysis->get_soft_threshold());
135 connect(threshold, SIGNAL(thresholdChanged(int)),
136 this, SLOT(setSoftThreshold(int)));
142 void MussaWindow::setupActions()
144 // we really don't want to run this more than once.
145 assert (closeAction == 0);
147 // the ever popular about box
148 aboutAction = new QAction(tr("&About"), this);
149 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
150 aboutAction->setIcon(QIcon(":/icons/info.png"));
153 closeAction = new QAction(tr("&Close"), this);
154 closeAction->setStatusTip(tr("Close this window"));
155 connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
156 closeAction->setIcon(QIcon(":/icons/exit.png"));
158 createNewAnalysisAction = new QAction(tr("Create &New Analysis"), this);
159 connect(createNewAnalysisAction, SIGNAL(triggered()),
160 this, SLOT(createNewAnalysis()));
161 createNewAnalysisAction->setIcon(QIcon(":/icons/filenew.png"));
162 createNewAnalysisAction->setShortcut(Qt::CTRL | Qt::Key_N);
164 createSubAnalysisAction = new QAction(tr("Add to Subanalysis"), this);
165 connect(createSubAnalysisAction, SIGNAL(triggered()),
166 this, SLOT(createSubAnalysis()));
168 saveAnalysisAction = new QAction(tr("&Save Analysis"), this);
169 connect(saveAnalysisAction, SIGNAL(triggered()),
170 this, SLOT(saveAnalysis()));
171 saveAnalysisAction->setIcon(QIcon(":/icons/filesave.png"));
172 saveAnalysisAction->setShortcut(Qt::CTRL | Qt::Key_S);
174 saveAnalysisAsAction = new QAction(tr("Save Analysis &As"), this);
175 connect(saveAnalysisAsAction, SIGNAL(triggered()),
176 this, SLOT(saveAnalysisAs()));
177 saveAnalysisAsAction->setIcon(QIcon(":/icons/filesave.png"));
179 editMotifsAction = new QAction(tr("Edit Motifs"), this);;
180 connect(editMotifsAction, SIGNAL(triggered()), this, SLOT(editMotifs()));
182 loadMotifListAction = new QAction(tr("Open Motif List"), this);
183 connect(loadMotifListAction, SIGNAL(triggered()),
184 this, SLOT(loadMotifList()));
185 loadMotifListAction->setIcon(QIcon(":/icons/fileopen.png"));
187 loadMupaAction = new QAction(tr("Create Analysis from File"), this);
188 connect(loadMupaAction, SIGNAL(triggered()),
189 this, SLOT(loadMupa()));
190 loadMupaAction->setIcon(QIcon(":/icons/fileopen.png"));
192 loadSavedAnalysisAction = new QAction(tr("&Open Existing &Analysis"), this);
193 connect(loadSavedAnalysisAction, SIGNAL(triggered()),
194 this, SLOT(loadSavedAnalysis()));
195 loadSavedAnalysisAction->setIcon(QIcon(":/icons/fileopen.png"));
196 loadSavedAnalysisAction->setShortcut(Qt::CTRL | Qt::Key_O);
198 mussaManualAssistantAction = new QAction(tr("Mussagl Manual..."), this);
199 mussaManualAssistantAction->setIcon(QIcon(":/icons/contents.png"));
200 connect(mussaManualAssistantAction, SIGNAL(triggered()),
201 this, SLOT(showManual()));
203 newMussaWindowAction = new QAction(tr("&New Mussa Window"), this);
204 newMussaWindowAction->setStatusTip("open another mussa window to allow comparing results");
205 connect(newMussaWindowAction, SIGNAL(triggered()),
206 this, SLOT(newMussaWindow()));
207 newMussaWindowAction->setIcon(QIcon(":/icons/window_new.png"));
209 saveMotifListAction = new QAction(tr("Save Motifs"), this);
210 connect(saveMotifListAction, SIGNAL(triggered()),
211 this, SLOT(saveMotifList()));
212 saveMotifListAction->setIcon(QIcon(":/icons/filesave.png"));
214 showMussaViewToolbarAction = new QAction(tr("Show Toolbar"), this);
215 connect(showMussaViewToolbarAction, SIGNAL(triggered()),
216 this, SLOT(showMussaToolbar()));
217 showMussaViewToolbarAction->setCheckable(true);
218 showMussaViewToolbarAction->setChecked(true);
220 toggleMotifsAction = new QAction(tr("Toggle Motifs"), this);
221 connect(toggleMotifsAction, SIGNAL(triggered()),
222 this, SLOT(toggleMotifs()));
223 toggleMotifsAction->setCheckable(true);
224 toggleMotifsAction->setIcon(QIcon(":/icons/motif_icon.png"));
225 toggleMotifsAction->setWhatsThis(tr("Toggle motif annotations on/off\n\n"
226 "You can load motif annotations via "
227 "'File->Load Motif List' menu option."));
229 //Save pixel map action
230 saveBrowserPixmapAction = new QAction(tr("Save to image..."), this);
232 connect(saveBrowserPixmapAction, (SIGNAL(triggered())),
233 browser, SLOT(promptSaveBrowserPixmap()));
234 saveBrowserPixmapAction->setIcon(QIcon(":/icons/image2.png"));
237 viewMussaAlignmentAction = new QAction(tr("View sequence alignment"), this);
238 connect(viewMussaAlignmentAction, SIGNAL(triggered()),
239 this, SLOT(viewMussaAlignment() ));
240 viewMussaAlignmentAction->setWhatsThis(tr("Create a zoomed in window "
241 "showing alignment of the seqcomp "
244 whatsThisAction = QWhatsThis::createAction(this);
245 whatsThisAction->setIcon(QIcon(":/icons/help.png"));
250 void MussaWindow::closeEvent(QCloseEvent *event)
252 if(isClearingAnalysisSafe()) {
259 void MussaWindow::setupMainMenu()
261 // we need to run setupActions first
262 assert (closeAction != 0);
264 QMenu *newMenu = menuBar()->addMenu(tr("&File"));
266 newMenu->addAction(newMussaWindowAction);
267 newMenu->addAction(createNewAnalysisAction);
268 newMenu->addAction(loadMupaAction);
269 newMenu->addAction(loadSavedAnalysisAction);
270 newMenu->addAction(saveAnalysisAction);
271 newMenu->addAction(saveAnalysisAsAction);
272 newMenu->addSeparator();
273 newMenu->addAction(loadMotifListAction);
274 newMenu->addAction(saveMotifListAction);
275 newMenu->addSeparator();
276 newMenu->addAction(saveBrowserPixmapAction);
277 newMenu->addSeparator();
278 newMenu->addAction(closeAction);
280 newMenu = menuBar()->addMenu(tr("&Edit"));
281 newMenu->addAction(editMotifsAction);
282 if (browser) newMenu->addAction(browser->getCopySelectedSequenceAsStringAction());
283 if (browser) newMenu->addAction(browser->getCopySelectedSequenceAsFastaAction());
284 newMenu->addAction(createSubAnalysisAction);
285 if (browser) newMenu->addAction(browser->getEditSequencePropertiesAction());
287 newMenu = menuBar()->addMenu(tr("&View"));
288 newMenu->addAction(viewMussaAlignmentAction);
289 newMenu->addAction(showMussaViewToolbarAction);
291 newMenu = menuBar()->addMenu(tr("&Help"));
292 newMenu->addAction(mussaManualAssistantAction);
293 newMenu->addAction(whatsThisAction);
294 newMenu->addSeparator();
295 newMenu->addAction(aboutAction);
297 // add some extra features to the context menu
299 QMenu *popupMenu = browser->getPopupMenu();
301 popupMenu->addAction(viewMussaAlignmentAction);
302 popupMenu->addAction(createSubAnalysisAction);
307 void MussaWindow::setupWidgets()
309 setup_analysis_dialog = new MussaSetupDialog;
310 subanalysis_window.reset(new SubanalysisWindow(analysis));
311 browser = new SequenceBrowserWidget(default_dir);
312 mussaViewTB = new QToolBar("Path Views", this);
313 zoom = new ZoomWidget(mussaViewTB);
314 threshold = new ThresholdWidget(mussaViewTB);
317 void MussaWindow::setupAssistant()
319 #if defined(QT_QTASSISTANT_FOUND)
321 QStringList manualAssistantArgs;
322 manualAssistantArgs = QStringList();
323 manualAssistantArgs << "-profile" << "./doc/manual/mussagl_manual.adp";
324 manualAssistant = new QAssistantClient("assistant", this);
325 manualAssistant->setArguments(manualAssistantArgs);
326 connect(manualAssistant, SIGNAL(error(QString)),
327 this, SLOT(assistantError(QString)));
332 void MussaWindow::about()
335 msg += "Welcome to Multiple Species Sequence Analysis\n";
336 msg += "(c) 2005-2006 California Institute of Technology\n";
337 msg += "Diane Trout, Tristan De Buysscher, Brandon King\n";
339 msg += mussa_version;
345 msg += (char *)glGetString(GL_VERSION);
347 QMessageBox::about(this, tr("About mussa"), msg);
350 void MussaWindow::clear()
352 if (motif_editor != 0) {
353 motif_editor->hide();
357 aligned_windows.clear();
361 void MussaWindow::createNewAnalysis()
364 // ideally we should open a new window if there's an analysis
365 // but this should work for the moment.
366 if (not isClearingAnalysisSafe()) return;
368 if (setup_analysis_dialog->exec()) {
369 setAnalysis(setup_analysis_dialog->getMussa());
371 } catch(mussa_error e) {
372 QString msg(e.what());
373 QMessageBox::warning(this, tr("Create New Analysis"), msg);
377 void MussaWindow::createSubAnalysis()
379 list<SequenceLocation> result;
380 SequenceLocationModel& model = subanalysis_window->getModel();
381 browser->copySelectedTracksAsSeqLocation(result);
382 for(list<SequenceLocation>::iterator result_itor = result.begin();
383 result_itor != result.end();
386 model.push_back(*result_itor);
389 if (not subanalysis_window->isVisible()) {
390 subanalysis_window->show();
394 void MussaWindow::saveAnalysis()
396 // if we've got an analysis
397 if (analysis and not analysis->empty()) {
398 // if it doesn't have a name we need to pick one
399 if (analysis->get_analysis_path().empty()) {
402 // if we've got a name, has it changed any?
403 // this doesn't work when a sequence changes something (like its
405 //else if (analysis->is_dirty())
408 } catch (std::exception e) {
409 QMessageBox::critical(this,
410 tr("Mussa Save Error"),
412 QMessageBox::Ok, 0, 0);
419 void MussaWindow::saveAnalysisAs()
421 std::auto_ptr<QFileDialog> dialog(new QFileDialog(this));
422 dialog->setAcceptMode(QFileDialog::AcceptSave);
423 dialog->setFileMode(QFileDialog::AnyFile);
424 dialog->setDirectory(*default_dir);
426 QStringList fileNames;
427 if (not dialog->exec()) {
430 fileNames = dialog->selectedFiles();
432 if (fileNames.size() != 1) {
436 fs::path save_path(fileNames[0].toStdString(), fs::native);
437 // do you want to overwrite?
438 if (fs::exists(save_path) and
439 QMessageBox::question(
441 tr("Overwrite File? -- Mussa"),
442 tr("A file called %1 already exists"
443 "do you want to overwrite it?")
445 tr("&Yes"), tr("&No"),
450 analysis->save(save_path);
451 fs::path normalized_path = (save_path / "..").normalize();
452 default_dir->setPath(normalized_path.native_directory_string().c_str());
453 } catch (std::exception e) {
454 QMessageBox::critical(this,
455 tr("Mussa Save Error"),
457 QMessageBox::Ok, 0, 0);
461 bool MussaWindow::isClearingAnalysisSafe()
463 if (analysis and not analysis->empty() and analysis->is_dirty()) {
464 switch (QMessageBox::question(
466 tr("Save Unsaved Changes -- Mussa"),
467 tr("There are unsaved changes,\ndo you want to save?"),
468 tr("&Yes"), tr("&No"), tr("&Cancel"),
483 throw runtime_error("isClearingAnalysis QMesageBox failure");
486 // if we're here we've been saved and can replace
490 void MussaWindow::editMotifs()
492 if (not motif_editor) {
493 motif_editor = new MotifEditor(analysis);
494 connect(motif_editor, SIGNAL(changedMotifs()),
495 this, SLOT(updateAnnotations()));
497 motif_editor->show();
500 void MussaWindow::loadMotifList()
502 QString caption("Mussa Load Motifs");
503 QString filter("Motif list(*.txt *.mtl)");
504 QString path = QFileDialog::getOpenFileName(this,
506 default_dir->absolutePath(),
511 // try to load safely
513 fs::path converted_path(path.toStdString(), fs::native);
514 analysis->load_motifs(converted_path);
515 default_dir->setPath(converted_path.branch_path().native_directory_string().c_str());
516 emit changedMotifs();
517 } catch (std::exception e) {
518 QString msg("Unable to load ");
522 QMessageBox::warning(this, caption, msg);
526 void MussaWindow::saveMotifList()
528 QString caption("Mussa Save Motifs");
529 QString filter("Motif list(*.txt *.mtl)");
530 QString path = QFileDialog::getSaveFileName(this,
532 default_dir->absolutePath(),
537 // try to load safely
539 fs::path converted_path(path.toStdString(), fs::native);
540 if (fs::extension(converted_path).size() == 0) {
541 // no extension, so add one
542 fs::path base_path = converted_path.branch_path();
543 fs::path filename(converted_path.leaf() + ".mtl", fs::native);
544 converted_path = base_path / filename;
546 analysis->save_motifs(converted_path);
547 default_dir->setPath(converted_path.branch_path().native_directory_string().c_str());
548 } catch (std::exception e) {
549 QString msg("Unable to save ");
553 QMessageBox::warning(this, caption, msg);
556 void MussaWindow::loadMupa()
558 QString caption("Load a mussa parameter file");
559 QString filter("Mussa Parameters (*.mupa)");
560 QString mupa_path = QFileDialog::getOpenFileName(
563 default_dir->absolutePath(),
567 if (mupa_path.isNull())
569 // try to load safely
571 // ideally we should open a new window if there's an analysis
572 // but this should work for the moment.
573 if (not isClearingAnalysisSafe()) return;
575 MussaRef m = Mussa::init();
576 fs::path converted_path(mupa_path.toStdString(), fs::native);
577 connect(m.get(), SIGNAL(progress(const QString&, int, int)),
578 this, SLOT(updateProgress(const QString&, int, int)));
579 m->load_mupa_file(converted_path);
583 // grab the path ignoring the mupa file portion
584 default_dir->setPath(converted_path.branch_path().native_directory_string().c_str());
585 } catch (mussa_load_error e) {
586 QString msg("Unable to load ");
590 QMessageBox::warning(this, "Load Parameter", msg);
592 assert (analysis != 0);
595 void MussaWindow::loadSavedAnalysis()
597 QString caption("Load a previously run analysis");
598 QString muway_dir = QFileDialog::getExistingDirectory(
601 default_dir->absolutePath()
604 if (muway_dir.isNull())
606 // try to safely load
608 // ideally we should open a new window if there's an analysis
609 // but this should work for the moment.
610 if (not isClearingAnalysisSafe()) return;
612 MussaRef m = Mussa::init();
613 fs::path converted_path(muway_dir.toStdString(), fs::native);
614 connect(m.get(), SIGNAL(progress(const QString&, int, int)),
615 this, SLOT(updateProgress(const QString&, int, int)));
616 m->load(converted_path);
617 // only switch mussas if we loaded without error
618 if (analysis->empty()) {
619 // our current window is empty so load and replace.
622 default_dir->setPath(converted_path.branch_path().native_directory_string().c_str());
624 MussaWindow *win = new MussaWindow(m);
626 win->default_dir->setPath(converted_path.branch_path().native_directory_string().c_str());
629 } catch (boost::filesystem::filesystem_error e) {
630 QString msg("Unable to load ");
634 QMessageBox::warning(this, "Load Parameter", msg);
635 } catch (mussa_load_error e) {
636 QString msg("Unable to load ");
640 QMessageBox::warning(this, "Load Parameter", msg);
642 assert (analysis != 0);
645 void MussaWindow::newMussaWindow()
647 MussaWindow *win = new MussaWindow(Mussa::init());
648 win->default_dir = default_dir;
652 void MussaWindow::setSoftThreshold(int value)
654 //std::cout << "Soft: " << analysis->get_soft_threshold()
655 // << " Value: " << value << "\n";
656 if (analysis->get_soft_threshold() != value) {
657 threshold->setEnabled( false );
658 //std::cout << "Updating!!!!\n";
659 analysis->set_soft_threshold(value);
663 threshold->setEnabled( true );
667 // std::cout << "NOT Updating!!!!\n";
671 void MussaWindow::showMussaToolbar()
673 if (mussaViewTB->isVisible())
679 void MussaWindow::showBasePairsCopied(size_t bp_copied)
681 QString msg("Copied ");
683 num.setNum(bp_copied);
684 msg += num + " base pairs";
685 statusBar()->showMessage(msg, 5000);
689 void MussaWindow::toggleMotifs()
694 void MussaWindow::showManual()
696 #if defined(QT_QTASSISTANT_FOUND)
698 // Only define the process once.
699 if (!assistantProcess)
700 assistantProcess = new QProcess(this);
702 // No need to fire up the process again if it is already running.
703 if (assistantProcess->state() == QProcess::Running)
706 QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath)
707 + QLatin1String("/assistant");
709 assistantProcess->start(app, QStringList() << QLatin1String("-enableRemoteControl")
710 << QLatin1String("-collectionFile") << QLatin1String("mussagl_manual.qhc"));
711 if (!assistantProcess->waitForStarted()) {
712 QMessageBox::critical(this, tr("Remote Control"),
713 tr("Could not start Qt Assistant from %1.").arg(app));
718 QTextStream str(assistantProcess);
719 str << QLatin1String("SetSource qthelp://edu.caltech.woldlab.mussagl.1_0_0/doc/mussagl_manual.html;")
720 << QLatin1String("expandToc 0")
721 << QLatin1Char('\0') << endl;
724 QUrl manual_url("http://woldlab.caltech.edu/~king/mussagl_manual/");
725 if (not QDesktopServices::openUrl(manual_url)) {
726 QMessageBox::warning(this,
727 tr("Mussa Help Error"),
728 tr("Unable to launch webbrowser"),
730 QMessageBox::NoButton,
731 QMessageBox::NoButton);
733 #endif //QT_QTASSISTANT_FOUND
736 void MussaWindow::assistantError(QString message)
738 //std::cout << "QAssistantError: " << message.toStdString() << "\n";
739 QMessageBox::warning ( this, "Warning: Mussagl Manual", message,
741 QMessageBox::NoButton);
744 void MussaWindow::NotImplementedBox()
746 QMessageBox::warning(this, QObject::tr("mussa"), QObject::tr("Not implemented yet"));
749 void MussaWindow::viewMussaAlignment()
751 const set<int>& selected_paths = browser->selectedPaths();
752 if (selected_paths.size() == 0 ) {
753 QMessageBox::warning(this,
754 QObject::tr("mussa"),
755 QObject::tr("you should probably select some paths "
758 MussaAlignedWindowRef ma_win(
759 new MussaAlignedWindow(analysis, default_dir, selected_paths, subanalysis_window)
762 aligned_windows.push_back(ma_win);
763 connect(this, SIGNAL(changedAnnotations()),
764 aligned_windows.back().get(), SLOT(update()));
765 aligned_windows.back()->show();
769 void MussaWindow::updateAnalysis()
771 const Mussa::vector_sequence_type& seqs = analysis->sequences();
772 browser->setSequences(seqs, analysis->colorMapper());
773 assert(browser->sequences().size() == analysis->size());
775 // setRange eventually emits something that causes updateLinks to be called
776 // but it's possible for us to not have had a chance to set out sequences
778 threshold->setRange(analysis->get_threshold(),analysis->get_window());
779 threshold->setBasepairThreshold(analysis->get_soft_threshold());
782 zoom->setValue(browser->zoom());
785 void MussaWindow::updateAnnotations()
787 // motifs were changed in the sequences by
788 // Mussa::update_sequences_motifs
789 emit changedAnnotations();
793 void MussaWindow::updateLinks()
795 if(browser->sequences().size() == 0) {
796 // we don't have any sequences load so we have no business setting links
800 browser->clear_links();
801 bool reversed = false;
802 const NwayPaths& nway = analysis->paths();
804 typedef list<ConservedPath> conserved_paths;
805 typedef conserved_paths::const_iterator const_conserved_paths_itor;
806 for(const_conserved_paths_itor path_itor = nway.refined_pathz.begin();
807 path_itor != nway.refined_pathz.end();
810 // since we were drawing to the start of a window, and opengl lines
811 // are centered around the two connecting points our lines were slightly
812 // offset. the idea of window_offset is to adjust them to the
813 // right for forward compliment or left for reverse compliment
814 // FIXME: figure out how to unit test these computations
815 //GLfloat window_offset = (path_itor->window_size)/2.0;
817 size_t track_len = path_itor->track_indexes.size();
818 vector<int> normalized_path;
819 normalized_path.reserve(track_len);
820 vector<bool> rc_flags(false, track_len);
821 for (size_t track_i=0; track_i != track_len; ++track_i)
823 int x = path_itor->track_indexes[track_i];
824 // at some point when we modify the pathz data structure to keep
825 // track of the score we can put grab the depth here.
827 // are we reverse complimented?
835 normalized_path.push_back(x);
836 rc_flags.push_back(reversed);
838 browser->link(normalized_path, rc_flags, path_itor->window_size);
844 MussaWindow::updateProgress(const QString& description, int current, int max)
847 if (current == max) {
848 if (progress_dialog != 0) {
849 progress_dialog->hide();
850 delete progress_dialog;
854 // if we're starting, create the dialog
855 if (progress_dialog == 0) {
856 QString cancel("Cancel");
857 progress_dialog = new QProgressDialog(description, cancel, current, max, this);
858 progress_dialog->show();
860 // just update the dialog
861 progress_dialog->setValue(current);
864 qApp->processEvents();
867 void MussaWindow::updateAnalysisModified(bool is_modified)
869 setWindowModified(is_modified);
872 void MussaWindow::updateTitle()
875 QString title(analysis->get_title().c_str());
877 setWindowTitle(title);