1 #include <QtSingleApplication>
24 using namespace US_WinData;
38 int main(
int argc,
char* argv[] )
40 QtSingleApplication application(
"UltraScan III", argc, argv );
41 QString options( getenv(
"ULTRASCAN_OPTIONS" ) );
45 if ( ! options.contains(
"multiple" ) )
47 if ( application.sendMessage(
"Wake up" ) )
return 0;
50 application.initialize();
53 QString locale = QLocale::system().name();
55 QTranslator translator;
56 translator.load( QString(
"us_" ) + locale );
57 application.installTranslator( &translator );
67 QPushButton* cancel = mBox.addButton( QMessageBox::Cancel );
68 QPushButton* Register = mBox.addButton( qApp->translate(
"UltraScan III",
"Register"),
69 QMessageBox::ActionRole);
71 mBox.setDefaultButton( Register );
72 mBox.setWindowTitle ( qApp->translate(
"UltraScan III",
"UltraScan License Problem" ) );
73 mBox.setText ( ErrorMessage );
74 mBox.setIcon ( QMessageBox::Critical );
77 if ( mBox.clickedButton() == cancel ) exit( -1 );
81 application.setActivationWindow( license );
82 return application.exec();
88 application.setActivationWindow( &w );
89 return application.exec();
94 : QAction( text, parent ), index( i )
96 connect(
this, SIGNAL( triggered (
bool ) ),
106 : QMainWindow( parent, flags )
112 qDebug(
"US_Win: invalid global memory" );
117 setGeometry( QRect( p, p + QPoint( 710, 532 ) ) );
120 setWindowTitle(
"UltraScan III" );
123 setWindowIcon( us3_icon );
125 procs = QList<procData*>();
128 QMenu* file =
new QMenu( tr(
"&File" ),
this );
142 QMenu* edit =
new QMenu( tr(
"&Edit" ),
this );
147 edit->addSeparator();
151 QMenu* velocity =
new QMenu( tr(
"&Velocity" ),
this );
152 addMenu(
P_VHWE , tr(
"&Enhanced van Holde - Weischet" ), velocity );
154 addMenu(
P_2DSA , tr(
"&2-D Spectrum Analysis" ), velocity );
156 addMenu(
P_PCSA , tr(
"&Parametrically Constrained Spectrum Analysis" ),
169 QMenu* equilibrium =
new QMenu( tr(
"E&quilibrium" ),
this );
179 QMenu* utilities =
new QMenu( tr(
"&Utilities" ),
this );
188 addMenu(
P_VHWCOMB , tr(
"Combine Distribution &Plots (vHW)" ), utilities );
189 addMenu(
P_DDCOMB , tr(
"Combine &Discrete Distributions" ), utilities );
194 QMenu* simulation =
new QMenu( tr(
"S&imulation" ),
this );
195 addMenu(
P_ASTFEM, tr(
"&Finite Element Simulation (ASTFEM)" ), simulation );
197 tr(
"Estimate Equilibrium &Times" ), simulation );
198 addMenu(
P_SASSOC, tr(
"&Self-Association Equilibrium" ), simulation );
199 addMenu(
P_MODEL1, tr(
"&Model s, D and f from MW for 4 basic shapes" ),
201 addMenu(
P_MODEL2, tr(
"&Predict f and axial ratios for 4 basic shapes" ),
206 QMenu* database =
new QMenu( tr(
"&Database" ),
this );
217 QMenu*
help =
new QMenu( tr(
"&Help" ),
this );
231 menuBar()->setFont( bfont );
233 menuBar()->addMenu( file );
234 menuBar()->addMenu( edit );
235 menuBar()->addMenu( velocity );
237 menuBar()->addMenu( equilibrium );
240 menuBar()->addMenu( utilities );
241 menuBar()->addMenu( simulation );
242 menuBar()->addMenu( database );
243 menuBar()->addMenu( help );
249 file ->setFont( mfont );
250 edit ->setFont( mfont );
251 velocity ->setFont( mfont );
253 equilibrium->setFont( mfont );
256 utilities ->setFont( mfont );
257 simulation ->setFont( mfont );
258 database ->setFont( mfont );
259 help ->setFont( mfont );
263 statusBar()->showMessage( tr(
"Ready" ) );
282 action->setFont( font );
285 connect( action, SIGNAL( indexTriggered (
int ) ),
288 menu->addAction( action );
293 if ( index == 4 ) close();
302 qDebug() <<
"PROCESS terminated: code" << code <<
"status" << status;
303 QList<procData*>::iterator pr;
305 for ( pr =
procs.begin(); pr !=
procs.end(); pr++ )
308 QProcess* process = d->
proc;
309 int index = d->
index;
311 if ( process->state() == QProcess::NotRunning )
313 qDebug() <<
"PROCESS NotRunning index" << index <<
"Proc name" << d->
name;
315 if ( status == QProcess::CrashExit )
320 QString estderr = QString( process->readAllStandardError() )
322 bool badallo = estderr.contains(
"bad_alloc" );
323 qDebug() <<
"PROCESS status" << status <<
"e-stderr len" << estderr.length();
328 msg_sb = tr(
"MEMORY ALLOC crash: " ) + msg_ru;
329 msg_mb = tr(
"Process MEMORY ALLOCATION Crash:\n" ) + msg_ru;
334 int kwhat = estderr.lastIndexOf(
"what(): " );
338 QString msg_wh = estderr.mid( kwhat + 7, 20 ).simplified();
339 msg_sb =
"[ " + msg_wh +
" ] crash: " + msg_ru;
340 msg_mb = tr(
"Process Crash [ " ) + msg_wh +
" ]\n" + msg_ru;
345 msg_sb =
"[ unknown type ] crash: " + msg_ru;
346 msg_mb = tr(
"Process Crash [ unknown type ]\n" ) + msg_ru;
351 statusBar()->showMessage( msg_sb );
352 QString selines = estderr.endsWith(
"\n" )
353 ? estderr.section(
"\n", -4, -2 )
354 : estderr.section(
"\n", -3, -1 );
355 msg_mb += tr(
"\n\nLast several stderr lines --\n\n" ) + selines;
356 QMessageBox::warning(
this, tr(
"Process Crash" ), msg_mb );
359 procs.removeOne( d );
374 static const int trig_secs=3600;
377 QString pname =
p[ index ].
name;
380 if (
ln_time.secsTo( QDateTime::currentDateTime() ) > trig_secs )
383 if (
p[ index ].maxRunCount <=
p[ index ].currentRunCount &&
384 p[ index ].maxRunCount > 0 )
388 QMessageBox::information(
this,
389 tr(
"Already Running" ),
390 tr(
"The configuration program is already running.\n"
391 "Click on the task bar item named UltraScan "
392 "Configuration to continue." ) );
396 QMessageBox::warning(
this,
398 pname + tr(
" is already running." ) );
404 statusBar()->showMessage(
405 tr(
"Loading " ) +
p[ index ].runningMsg +
"..." );
407 QProcess* process =
new QProcess( 0 );
408 process->closeReadChannel( QProcess::StandardOutput );
409 process->closeReadChannel( QProcess::StandardError );
410 connect ( process, SIGNAL( finished (
int, QProcess::ExitStatus ) ),
411 this , SLOT (
terminated(
int, QProcess::ExitStatus ) ) );
414 process->start( pname );
417 QString procapp = procbin +
".app";
419 if ( !QFile( procapp ).exists() )
422 process->start(
"open", QStringList(procapp) );
425 if ( ! process->waitForStarted( 10000 ) )
427 QMessageBox::information(
this,
429 tr(
"There was a problem creating a subprocess\nfor " ) + pname );
442 statusBar()->showMessage(
443 tr(
"Loaded " ) +
p[ index ].runningMsg +
"..." );
449 QList<procData*>::iterator
p;
451 for ( p =
procs.begin(); p !=
procs.end(); p++ )
454 names += d->
name +
"\n";
457 QString isAre = (
procs.size() > 1 ) ?
"es are" :
" is";
458 QString itThem = (
procs.size() > 1 ) ?
"them" :
"it";
461 box.setWindowTitle( tr(
"Attention" ) );
462 box.setText( QString( tr(
"The following process%1 still running:\n%2"
463 "Do you want to close %3?" )
464 .arg( isAre ).arg( names ).arg( itThem ) ) );
466 QString killText = tr(
"&Kill" );
467 QString closeText = tr(
"&Close Gracefully" );
468 QString leaveText = tr(
"&Leave Running" );
470 QPushButton* kill = box.addButton( killText , QMessageBox::YesRole );
471 box.addButton( closeText, QMessageBox::YesRole );
472 QPushButton* leave = box.addButton( leaveText, QMessageBox::NoRole );
476 if ( box.clickedButton() == leave )
return;
478 for ( p =
procs.begin(); p !=
procs.end(); p++ )
481 QProcess* process = d->
proc;
483 if ( box.clickedButton() == kill )
486 process->terminate();
504 int y = menuBar ()->size().rheight();
505 int h = 532 - y - statusBar()->size().rheight();
509 bigframe->setFrameStyle ( QFrame::Box | QFrame::Raised);
511 bigframe->setGeometry ( 0, y, w, h );
512 bigframe->setAutoFillBackground(
true );
515 splash_shadow->setGeometry( (
unsigned int)( ( w / 2 ) - 210 ) , 130, 460, 276 );
516 splash_shadow->setPalette( QPalette( Qt::black, Qt::cyan ) );
529 int ph = rawpix.height();
530 int pw = rawpix.width();
532 QPixmap pixmap( pw, ph );
533 QPainter painter( &pixmap );
535 painter.drawPixmap( 0, 0, rawpix );
536 painter.setPen ( QPen( Qt::white, 3 ) );
541 QFont font(
"Arial" );
542 font.setWeight( QFont::DemiBold );
543 font.setPixelSize( 16 );
544 painter.setFont( font );
545 QFontMetrics metrics( font );
547 int sWidth = metrics.boundingRect( version ).width();
548 int x = ( pw - sWidth ) / 2;
550 painter.drawLine( 0, 111, pw, 111);
551 painter.drawText( x, 139, version );
552 painter.drawLine( 0, 153, pw, 153);
554 QString s =
"Author: Borries Demeler";
555 sWidth = metrics.boundingRect( s ).width();
556 painter.drawText( ( pw - sWidth ) / 2, 177, s );
558 s =
"The University of Texas";
559 sWidth = metrics.boundingRect( s ).width();
560 painter.drawText( ( pw - sWidth ) / 2, 207, s );
562 s =
"Health Science Center at San Antonio";
563 sWidth = metrics.boundingRect( s ).width();
564 painter.drawText( ( pw - sWidth ) / 2, 227, s );
566 s =
"Department of Biochemistry";
567 sWidth = metrics.boundingRect( s ).width();
568 painter.drawText( ( pw - sWidth ) / 2, 247, s );
572 smallframe->setGeometry( (
unsigned int)( (width / 2) - 230 ), 110, 460, 276);
584 int i = index -
HELP;
586 statusBar()->showMessage( tr(
h[i].loadMsg.toAscii() ) );
590 QMessageBox::information(
this,
591 tr(
"UltraScan Credits" ),
592 tr(
"The UltraScan-III and LIMS-III software were developed by:\n\n"
593 "Emre Brookes, Weiming Cao, Bruce Dubbs, Gary Gorbet, "
594 "Jeremy Mann, Suresh Marru, Shabhaz Memon, Marlon Pierce, \n"
595 "Raminder Singh and Dan Zollars.\n\n"
596 "Project Director: Borries Demeler\n\n"
597 "This development was funded by NIH Grant RR022200 "
598 "and NSF grants ACI-1339649 and TG-MCB070039.\n\n"
600 "We thank the following individuals for contributions "
601 "to the UltraScan project:\n\n"
603 " * Nikolay Dokholyan\n"
604 " * Jose Garcia de la Torre\n"
607 " * Luitgard Nagel-Steger\n"
612 " * Bruno Spotorno\n"
613 " * Giovanni Tassara\n"
615 " * Johannes Walter\n"
617 " * Josh Wilson" ) );
619 statusBar()->showMessage( tr(
"Ready" ) );
623 QMessageBox::information(
this,
624 tr(
"About UltraScan..." ),
625 tr(
"UltraScan III version %1\n"
627 "Copyright 1989 - 2014\n"
628 "Borries Demeler and the University of Texas System\n\n"
629 "For more information, please visit:\n"
630 "http://www.ultrascan.uthscsa.edu/\n\n"
631 "The author can be reached at:\n"
632 "The University of Texas Health Science Center\n"
633 "Department of Biochemistry\n"
634 "7703 Floyd Curl Drive\n"
635 "San Antonio, Texas 78229-3900\n"
636 "voice: (210) 767-3332\n"
637 "Fax: (210) 567-6595\n"
640 statusBar()->showMessage( tr(
"Ready" ) );
650 if (
h[i].type ==
URL )
659 statusBar()->showMessage( tr(
"Loaded " ) +
h[i].loadMsg.toAscii() );
673 menuBar()->setFont( bfont );
680 QList< QMenu* > mens = this->findChildren< QMenu* >();
682 for (
int ii = 0; ii < mens.count(); ii++ )
684 QList< QAction* > acts = mens.at( ii )->findChildren< QAction* >();
686 for (
int jj = 0; jj < acts.count(); jj++ )
688 acts.at( jj )->setFont( mfont );
702 bool do_abort =
false;
705 ln_time = QDateTime::currentDateTime();
715 QString host (
"uslims3.uthscsa.edu" );
716 QString dbname(
"us3_notice" );
717 QString user (
"us3_notice" );
718 QString passwd(
"us3_notice" );
721 if ( defaultDB.size() > 3 )
722 host = defaultDB.at( 3 );
724 if ( ! db.
connect( host, dbname, user, passwd, errmsg ) )
726 qDebug() <<
"US:NOTE: Unable to connect" << errmsg;
730 QString query(
"SELECT type, revision, message, lastUpdated"
731 " FROM us3_notice.notice;" );
737 qDebug() <<
"US:NOTE: No DB notices" << db.
lastError()
748 QMap< QString, QString > typeMap;
749 typeMap[
"info" ] = tr(
"Information" );
750 typeMap[
"warn" ] = tr(
"Warning" );
751 typeMap[
"crit" ] = tr(
"Critical" );
762 QString type = db.
value( 0 ).toString();
763 QString mrev = db.
value( 1 ).toString();
764 QString msg = db.
value( 2 ).toString();
765 QDateTime time_m = db.
value( 3 ).toDateTime();
767 if ( type ==
"info" ) nn_info++;
768 else if ( type ==
"warn" ) nn_warn++;
769 else if ( type ==
"crit" ) nn_crit++;
771 int m_rev = QString( mrev ).replace(
".",
"" ).toInt();
772 i_rev = qMax( i_rev, m_rev );
780 time_d = time_m.secsTo( time_d ) > 0
792 + QString(
REVISION ).section(
":", 1, 1 ).simplified();
793 int s_rev = QString( srev ).replace(
".",
"" ).toInt();
795 qDebug() <<
"s_rev i_rev" << s_rev << i_rev <<
"srev" << srev;
800 int n_dif = (int)time_d.secsTo( pn_time );
801 qDebug() <<
" n_dif" << n_dif <<
"time_d" << time_d <<
"pn_time" << pn_time;
806 level = ( nn_warn > 0 ) ? 1 : level;
807 level = ( nn_crit > 0 ) ? 2 : level;
808 QString msg_note = tr(
"UltraScan III notices posted (" )
809 + time_d.toString(
"yyyy/MM/dd" ) +
"):\n\n";
811 for (
int ii = 0; ii < nnotice; ii++ )
814 if ( ( irevs[ ii ] == s_rev && types[ ii ] !=
"info" ) ||
815 irevs[ ii ] < s_rev )
continue;
818 msg_note += typeMap[ types[ ii ] ] +
" for release "
823 if ( types[ ii ] ==
"crit" ) do_abort =
true;
828 msg_note += tr(
"\n\n*** US3 Abort: UPDATE REQUIRED!!! ***\n" );
833 QMessageBox::information(
this, tr(
"US3 Notices" ), msg_note );
834 else if ( level == 1 )
835 QMessageBox::warning (
this, tr(
"US3 Notices" ), msg_note );
836 else if ( level == 2 )
837 QMessageBox::critical (
this, tr(
"US3 Notices" ), msg_note );