UltraScan III
us_mrecs_loader.cpp
Go to the documentation of this file.
1 
3 #include "us_mrecs_loader.h"
4 #include "us_settings.h"
5 #include "us_gui_settings.h"
6 #include "us_matrix.h"
7 #include "us_investigator.h"
8 #include "us_passwd.h"
9 #include "us_db2.h"
10 #include "us_editor.h"
11 #include "us_util.h"
12 
13 // Main constructor for loading a single model records entry
14 US_MrecsLoader::US_MrecsLoader( bool dbSrc, QString& search,
15  VEC_MRECS& amrecs, QString& adescr,
16  const QString eGUID, const QString arunID )
17  :US_WidgetsDialog( 0, 0 ), loadDB( dbSrc ), dsearch( search ),
18  omrecs( amrecs ), odescr( adescr )
19 {
20  editGUID = eGUID;
21  runID = arunID;
22 
23  setWindowTitle( tr( "Load a Model Records Vector" ) );
24  setPalette( US_GuiSettings::frameColor() );
25  setMinimumSize( 320, 300 );
26 
27  mrecs_descriptions.clear();
28  mrecs_descrs_recs .clear();
29 
30  // Main layout
31  QVBoxLayout* main = new QVBoxLayout( this );
32  main->setContentsMargins( 2, 2, 2, 2 );
33  main->setSpacing ( 2 );
34 
35  // Top layout: buttons and fields above list widget
36  QGridLayout* top = new QGridLayout( );
37  dbP = NULL;
38 
39  pb_filtvmrecs = us_pushbutton( tr( "Search" ) );
40  connect( pb_filtvmrecs, SIGNAL( clicked() ),
41  this, SLOT( list_vmrecs() ) );
42 
43  QString edGUID = editGUID;
44  can_edit = !editGUID.isEmpty();
45  do_edit = can_edit;
46 
47  if ( ! dsearch.isEmpty() )
48  { // If an input search string is given, look for special flags
49  do_edit = do_edit || dsearch.contains( "=e" );
50  dsearch = dsearch.replace( "=e", "" ).simplified();
51  }
52 qDebug() << "Bld: edit" << do_edit << " dsearch" << dsearch;
53 
54  le_mfilter = us_lineedit( dsearch, -1, false );
55  connect( le_mfilter, SIGNAL( returnPressed() ),
56  this, SLOT( list_vmrecs() ) );
57  connect( le_mfilter, SIGNAL( textChanged( const QString& ) ),
58  this, SLOT( msearch( const QString& ) ) );
59 
60  int row = 0;
61  top->addWidget( pb_filtvmrecs, row, 0 );
62  top->addWidget( le_mfilter, row++, 1 );
63 
64  main->addLayout( top );
65 
66  // List widget to show model choices
68 
69  main->addWidget( lw_vmrecs );
70 
71  // Advanced Mrecs List Options
72  QGridLayout* lo_edit = us_checkbox( tr( "Filter by Edit" ),
73  ck_edit, do_edit );
74  connect( ck_edit, SIGNAL( toggled ( bool ) ),
75  SLOT ( change_edit ( bool ) ) );
76 
77  main->addLayout( lo_edit );
78 
79  // Button Row
80  QHBoxLayout* buttons = new QHBoxLayout;
81 
82  pb_delete = us_pushbutton( tr( "Delete Entry" ) );
83  pb_details = us_pushbutton( tr( "Entry Details" ) );
84  QPushButton* pb_help = us_pushbutton( tr( "Help" ) );
85  QPushButton* pb_cancel = us_pushbutton( tr( "Cancel" ) );
86  pb_accept = us_pushbutton( tr( "Accept" ) );
87 
88  connect( pb_delete, SIGNAL( clicked() ), this, SLOT( delete_mrecs() ) );
89  connect( pb_details, SIGNAL( clicked() ), this, SLOT( show_mrecs_info() ) );
90  connect( pb_help, SIGNAL( clicked() ), this, SLOT( help() ) );
91  connect( pb_cancel, SIGNAL( clicked() ), this, SLOT( cancelled() ) );
92  connect( pb_accept, SIGNAL( clicked() ), this, SLOT( accepted() ) );
93 
94  buttons->addWidget( pb_details );
95  buttons->addWidget( pb_delete );
96  buttons->addWidget( pb_help );
97  buttons->addWidget( pb_cancel );
98  buttons->addWidget( pb_accept );
99 
100  pb_delete ->setEnabled( false );
101  pb_details->setEnabled( false );
102  pb_accept ->setEnabled( false );
103 
104  main->addLayout( buttons );
105 
106  db_id1 = -2; // flag all_models start,end IDs unknown
107  db_id2 = -2;
108 
109  list_vmrecs();
110 }
111 
112 // Load model records data by index
113 int US_MrecsLoader::load_mrecs( VEC_MRECS& mrecs, int index )
114 {
115  int rc = 0;
116  int nmrec = 0;
117  QString xmlstr;
118 
119  if ( loadDB )
120  {
121  if ( dbP == NULL )
122  {
123  US_Passwd pw;
124  dbP = new US_DB2( pw.getPasswd() );
125 
126  if ( ( rc = dbP->lastErrno() ) != US_DB2::OK )
127  {
128  QMessageBox::information( this,
129  tr( "DB Connection Problem" ),
130  tr( "There was an error connecting to the database:\n" )
131  + dbP->lastError() );
132  return rc;
133  }
134  }
135 
136 qDebug() << "LdM: index" << index << "descsz" << mrecs_descriptions.size();
137  QString mrecsID = mrecs_descriptions[ index ].DB_id;
138  QStringList query;
139  query << "get_mrecs_info" << mrecsID;
140 qDebug() << " query" << query;
141  dbP->query( query );
142 
143  if ( dbP->lastErrno() == US_DB2::OK && dbP->numRows() == 1 )
144  {
145 qDebug() << " numRows" << dbP->numRows();
146  dbP->next();
147  xmlstr = dbP->value( 1 ).toString();
148  QString dcksm = dbP->value( 7 ).toString();
149  int dsize = dbP->value( 8 ).toInt();
150 qDebug() << " len(xmlstr)" << xmlstr.length();
151 
152  // If no local copy exists, make one
153  QString descript = mrecs_descriptions[ index ].description;
154  QString frunID = QString( descript ).section( ".", -4, -4 );
155  QString triple = QString( descript ).section( ".", -3, -3 );
156  QString analID = QString( descript ).section( ".", -2, -2 );
157  QString anedit = QString( analID ).section( "_", -5, -5 );
158  QString anadat = QString( analID ).section( "_", -4, -4 );
159  QString antype = QString( analID ).section( "_", -3, -3 );
160  QString anrqid = QString( analID ).section( "_", -2, -2 );
161  analID = anedit.left( 7 ) + "_"
162  + anadat.left( 7 ) + "_"
163  + antype + "_" + anrqid;
164  QString fname = "pcsa-mrs." + triple + "." + analID + ".xml";
165  QString fpath = US_Settings::resultDir() + "/" + frunID
166  + "/" + fname;
167  QFile filemr( fpath );
168  if ( filemr.exists() )
169  { // File exists: check it size
170  QString sumsiz = US_Util::md5sum_file( fpath );
171  QString fcksm = QString( sumsiz ).section( " ", 0, 0 );
172  QString sfsize = QString( sumsiz ).section( " ", 1, 1 );
173  int fsize = sfsize.toInt();
174  if ( fcksm != dcksm || fsize != dsize )
175  { // Differs in checksum or size: so overwrite existing file
176  if ( filemr.open( QIODevice::WriteOnly | QIODevice::Text ) )
177  {
178  QTextStream tso( &filemr );
179  tso << xmlstr;
180  filemr.close();
181 qDebug() << "File written:" << fpath;
182  }
183  }
184  }
185  else
186  { // File does not exist: create it
187  if ( filemr.open( QIODevice::WriteOnly | QIODevice::Text ) )
188  {
189  QTextStream tso( &filemr );
190  tso << xmlstr;
191  filemr.close();
192 qDebug() << "File written:" << fpath;
193  }
194  }
195  }
196 
197  else
198  {
199 qDebug() << " *ERROR*" << dbP->lastErrno() << dbP->lastError();
200  }
201  }
202 
203  else
204  {
205  QString filepath = mrecs_descriptions[ index ].filename;
206  QString filedir = filepath.section( "/", 0, -2 );
207  QString filename = filepath.section( "/", -1, -1 );
208 
209  QFile filei( filepath );
210 
211  if ( filei.open( QIODevice::ReadOnly | QIODevice::Text ) )
212  {
213  QTextStream tsi( &filei );
214  xmlstr = tsi.readAll();
215  filei.close();
216  }
217 
218  else
219  {
220 qDebug() << " *ERROR* cannot open" << filepath;
221  }
222  }
223 
224  QXmlStreamReader xmlr( xmlstr );
225  int ctype = CTYPE_NONE;
226  double xmin = 0.0;
227  double xmax = 0.0;
228  double ymin = 0.0;
229  double ymax = 0.0;
230  int stype = 11;
231 
232 qDebug() << " ==Call load_modelrecs==";
233  nmrec = US_ModelRecord::load_modelrecs( xmlr, mrecs, mrdesc, ctype,
234  xmin, xmax, ymin, ymax, stype );
235  rc = ( nmrec > 0 ) ? 0 : 1;
236 qDebug() << " ==load_modelrecs== rc" << rc << "nmrec" << nmrec;
237 
238  return rc;
239 }
240 
241 // Return a concatenated description string for a model by index
243 {
244  QString sep = ";"; // use semi-colon as separator
245 
246  if ( mrecs_descriptions[ index ].description.contains( sep ) )
247  sep = "^"; // use carat if semi-colon already in use
248 
249  // Create and return a composite description string
250  QString cdesc = sep + mrecs_descriptions[ index ].description
251  + sep + mrecs_descriptions[ index ].filename
252  + sep + mrecs_descriptions[ index ].mrecsGUID
253  + sep + mrecs_descriptions[ index ].DB_id
254  + sep + mrecs_descriptions[ index ].editGUID;
255 
256  return cdesc;
257 }
258 
259 // List mrecs choices (disk/db and possibly filtered by search text)
261 {
262 qDebug() << "LIST_MODELS";
263 QDateTime time0=QDateTime::currentDateTime();
264 QDateTime time1=QDateTime::currentDateTime();
265 QDateTime time2=QDateTime::currentDateTime();
266  const QString uaGUID( "00000000-0000-0000-0000-000000000000" );
267  QString mfilt = le_mfilter->text();
268  le_mfilter->disconnect( SIGNAL( textChanged( const QString& ) ) );
269  bool listdesc = !mfilt.isEmpty(); // description filtered?
270  bool listedit = do_edit; // edit filtered?
271  bool listall = !listdesc; // unfiltered by description?
272  QRegExp mpart = QRegExp( ".*" + mfilt + ".*", Qt::CaseInsensitive );
273  mrecs_descriptions.clear(); // clear model descriptions
274 qDebug() << "LM: desc edit" << listdesc << listedit
275  << "editGUID" << editGUID;
276  int kmmnew = 0;
277  int kmmold = 0;
278  int kmmmod = 0;
279 
280  if ( listdesc )
281  { // filter is not empty
282  listedit = listedit | do_edit;
283 
284  if ( listedit && ! can_edit )
285  { // disallow edit filter if no edit GUID
286  QMessageBox::information( this,
287  tr( "Edit GUID Problem" ),
288  tr( "No EditGUID given.\nEdit filter turned off." ) );
289  listedit = false;
290  listdesc = listedit;
291  listall = !listdesc;
292  }
293  }
294 qDebug() << "listall" << listall << "listdesc listedit" << listdesc << listedit;
295 
296  if ( loadDB )
297  { // Mrecs list from DB
298  if ( dbP == NULL )
299  {
300  US_Passwd pw;
301  dbP = new US_DB2( pw.getPasswd() );
302 
303  if ( dbP->lastErrno() != US_DB2::OK )
304  {
305  QMessageBox::information( this,
306  tr( "DB Connection Problem" ),
307  tr( "There was an error connecting to the database:\n" )
308  + dbP->lastError() );
309  return;
310  }
311  }
312 
313  QStringList query;
314  QString invID = QString::number( US_Settings::us_inv_ID() );
315 
316  int countRD = mrecs_descrs_recs .size();
317  int kid1 = -3;
318  int kid2 = -3;
319 qDebug() << " rd count" << countRD;
320 // query << "count_models" << invID;
321 // int countDB = dbP->statusQuery( query );
322 //qDebug() << " db count" << countDB;
323  QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
324 
325  if ( countRD > 0 )
326  {
327  kid1 = mrecs_descrs_recs[ 0 ].DB_id.toInt();
328  kid2 = mrecs_descrs_recs[ countRD - 1 ].DB_id.toInt();
329  }
330 qDebug() << " kid1 kid2" << kid1 << kid2;
331 qDebug() << " db_id1 db_id2" << db_id1 << db_id2;
332 
333  if ( countRD == 0 || kid1 != db_id1 || kid2 != db_id2 )
334  { // only re-fetch all-models list if we don't yet have it
335  db_id1 = kid1; // save start,end all_models IDs
336  db_id2 = kid2;
337 qDebug() << " db_id1 db_id2" << db_id1 << db_id2;
338  mrecs_descrs_recs.clear();
339  QString editID = editGUID;
340  countRD = 0;
341 
342  if ( can_edit )
343  {
344  query.clear();
345  query << "get_editID" << editGUID;
346  dbP->query( query );
347  dbP->next();
348  editID = dbP->value( 0 ).toString();
349  }
350 qDebug() << " edit GUID,ID" << editGUID << editID;
351 
352  query.clear();
353 time1=QDateTime::currentDateTime();
354 
355  if ( listedit && can_edit )
356  {
357  query << "get_mrecs_desc_by_editID" << invID << editID;
358  }
359 
360  else
361  {
362  query << "get_mrecs_desc" << invID;
363  }
364 
365 qDebug() << " query" << query;
366  dbP->query( query );
367 qDebug() << " NumRows" << dbP->numRows();
368 time2=QDateTime::currentDateTime();
369 qDebug() << "Timing: get_mrecs_desc" << time1.msecsTo(time2);
370 
371  while ( dbP->next() )
372  {
373  MrecsDesc desc;
374  desc.DB_id = dbP->value( 0 ).toString();
375  desc.mrecsGUID = dbP->value( 1 ).toString();
376  desc.editGUID = dbP->value( 3 ).toString();
377  desc.modelGUID = dbP->value( 5 ).toString();
378  desc.description = dbP->value( 6 ).toString();
379  desc.rec_index = countRD++;
380 
381  desc.filename.clear();
382 
383  if ( desc.description.simplified().length() < 2 )
384  {
385  desc.description = " ( ID " + desc.DB_id
386  + tr( " : empty description )" );
387  }
388 //qDebug() << " desc" << desc.description << "DB_id" << desc.DB_id;
389 
390  mrecs_descrs_recs << desc; // add to full mrecs list
391  }
392  }
393 QDateTime time3=QDateTime::currentDateTime();
394 qDebug() << "a_m size" << mrecs_descrs_recs.size()
395  << "m_d size" << mrecs_descriptions.size();
396 
397  QApplication::restoreOverrideCursor();
398  }
399 
400  else
401  { // Mrecs list from local disk files
402  QDir dir;
403  QString path = US_Settings::resultDir();
404  if ( !dir.exists( path ) )
405  {
406  dir.mkpath( path );
407  }
408  dir = QDir( path );
409 
410  // Examine all "M*xml" files in models directory
411  QStringList filter( "pcsa-mrs*.xml" );
412  QStringList f_names;
413  QStringList f_paths;
414  int countRD = 0;
415 
416  if ( runID.isEmpty() )
417  { // Scan all results directories
418  QStringList r_dirs = dir.entryList( QDir::Dirs );
419 
420  for ( int jj = 0; jj < r_dirs.size(); jj++ )
421  {
422  QString rpath = r_dirs[ jj ];
423 
424  QDir rdir = QDir( rpath );
425 
426  QStringList rf_names = rdir.entryList( filter, QDir::Files,
427  QDir::Name );
428 
429  for ( int ii = 0; ii < rf_names.size(); ii++ )
430  {
431  f_names << rf_names[ ii ];
432  f_paths << path + "/" + rpath + "/" + rf_names[ ii ];
433  }
434  }
435  }
436 
437  else
438  { // Scan a specific results run directory
439  QString rpath = path + "/" + runID;
440 
441  QDir rdir = QDir( rpath );
442 
443  QStringList rf_names = rdir.entryList( filter, QDir::Files,
444  QDir::Name );
445 
446  for ( int ii = 0; ii < rf_names.size(); ii++ )
447  {
448  f_names << rf_names[ ii ];
449  f_paths << rpath + "/" + rf_names[ ii ];
450  }
451  }
452 
453  if ( f_paths.size() != mrecs_descrs_recs.size() )
454  { // only re-fetch all-models list if we don't yet have it
455  QXmlStreamAttributes attr;
456 
457  mrecs_descrs_recs.clear();
458 qDebug() << "editGUID" << editGUID;
459 
460  for ( int ii = 0; ii < f_paths.size(); ii++ )
461  {
462  QString fpath( f_paths[ ii ] );
463  QString fname( f_names[ ii ] );
464 qDebug() << "fpath" << f_paths[ii];
465  QFile m_file( fpath );
466 
467  if ( !m_file.open( QIODevice::ReadOnly | QIODevice::Text ) )
468  continue;
469 
470  QString mrGUID = "";
471  QString edGUID = "";
472  QString moGUID = "";
473  QString descript = "";
474 
475  QXmlStreamReader xml( &m_file );
476 
477  while ( ! xml.atEnd() )
478  { // Search XML elements for description and editGUID
479  xml.readNext();
480 
481  if ( xml.isStartElement() && xml.name() == "modelrecords" )
482  {
483  attr = xml.attributes();
484  mrGUID = attr.value( "mrecGUID" ).toString();
485  edGUID = attr.value( "editGUID" ).toString();
486  moGUID = attr.value( "modelGUID" ).toString();
487  descript = attr.value( "description" ).toString();
488  }
489 
490  else if ( xml.isStartElement() && xml.name() == "modelrecord" )
491  {
492  attr = xml.attributes();
493  mrGUID = ( ! mrGUID.isEmpty() ) ? mrGUID :
494  attr.value( "mrecGUID" ).toString();
495  edGUID = ( ! edGUID.isEmpty() ) ? edGUID :
496  attr.value( "editGUID" ).toString();
497  moGUID = ( ! moGUID.isEmpty() ) ? moGUID :
498  attr.value( "modelGUID" ).toString();
499  descript = ( ! descript.isEmpty() ) ? descript :
500  attr.value( "description" ).toString();
501  }
502 
503  else if ( xml.isEndElement() && xml.name() == "modelrecord" )
504  break;
505  }
506 
507  m_file.close();
508 
509  // Skip save if filtering and edit mismatch
510  if ( do_edit && edGUID != editGUID )
511  continue;
512 
513  if ( descript.isEmpty() )
514  {
515  descript = QString( fpath ).section( "/", -2, -2 )
516  + ".triple."
517  + QString( fname ).replace( ".xml", ".mrecs" );
518  }
519 qDebug() << " edGUID" << edGUID << "descr" << descript;
520 
521  MrecsDesc desc;
522  desc.DB_id = "-1";
523  desc.mrecsGUID = mrGUID;
524  desc.editGUID = edGUID;
525  desc.modelGUID = moGUID;
526  desc.description = descript;
527  desc.filename = fpath;
528  desc.rec_index = countRD++;
529 
530  if ( desc.description.simplified().length() < 2 )
531  {
532  desc.description = " ( Fname " + QString( fname ).left( 20 )
533  + tr( " : empty description )" );
534  }
535 //qDebug() << " desc" << desc.description << "DB_id" << desc.DB_id;
536 
537  mrecs_descrs_recs << desc; // add to full mrecs list
538 //*DEBUG
539 //if (!listall) {
540 //qDebug() << " ddesc" << desc.description;
541 //qDebug() << " mpart" << mpart.pattern();
542 //qDebug() << " degid" << desc.editGUID;
543 //qDebug() << " edgid" << editGUID;
544 //}
545 //*DEBUG
546  }
547  }
548  db_id1 = -2; // Flag all_models start,end IDs unknown
549  db_id2 = -2;
550  }
551 
552  if ( kmmold > 0 )
553  {
554  QString msg = tr( "%1 MC model sets are old-style separate models\n"
555  "%2 MC models are new-style composite models\n"
556  "%3 total MC model records currently exist.\n"
557  "The old-style models should be converted\n"
558  " or deleted." )
559  .arg( kmmold).arg( kmmnew ).arg( kmmmod );
560  QMessageBox::information( this,
561  tr( "Deprecated MC Model Types Exist" ), msg );
562  }
563 
564  // possibly pare down models list based on search field
565 QDateTime time5=QDateTime::currentDateTime();
566 qDebug() << "Timing: Time5" << time0.msecsTo(time5) << time2.msecsTo(time5);
567 qDebug() << " (3)m_d_u size" << mrecs_descrs_recs.size();
568 
569  if ( listall )
570  { // No filtering or filter by edit already done
571  for ( int jj = 0; jj < mrecs_descrs_recs.size(); jj++ )
572  {
574  }
575  }
576 
577  else
578  { // Filter by model description sub-string
579  for ( int jj = 0; jj < mrecs_descrs_recs.size(); jj++ )
580  {
581  if ( mrecs_descrs_recs[ jj ].description.contains( mpart ) )
582  { // description filter matches
584 //MrecsDesc desc = mrecs_descrs_recs[jj];
585 //qDebug() << " ddesc" << desc.description << jj;
586 //qDebug() << " mpart" << mpart.pattern();
587  }
588  }
589  }
590 qDebug() << " (4)m_d size" << mrecs_descriptions.size();
591 
592  lw_vmrecs->disconnect( SIGNAL( currentRowChanged( int ) ) );
593  lw_vmrecs->clear();
594  int maxlch = 0;
595 
596  if ( mrecs_descriptions.size() > 0 )
597  {
598  for ( int ii = 0; ii < mrecs_descriptions.size(); ii++ )
599  { // propagate list widget with descriptions
600  lw_vmrecs->addItem( mrecs_descriptions[ ii ].description );
601  maxlch = qMax( maxlch,
602  mrecs_descriptions[ ii ].description.length() );
603  }
604 
605  // Sort descriptions in ascending alphabetical order
606  lw_vmrecs->sortItems();
607  }
608 
609  else
610  {
611  lw_vmrecs->addItem( "No models found." );
612  }
613 QDateTime time6=QDateTime::currentDateTime();
614 qDebug() << "Timing: Time6" << time0.msecsTo(time6) << time2.msecsTo(time6);
615 
616  // Resize the widget to show listed items well
617  QFontMetrics fm = lw_vmrecs->fontMetrics();
618  int olwid = lw_vmrecs->width();
619  int olhgt = lw_vmrecs->height();
620  int nlines = qMin( mrecs_descriptions.size(), 30 );
621  int width = qMin( 600, maxlch * fm.maxWidth() );
622  int height = qMin( 800, nlines * fm.lineSpacing() );
623  width = qMax( width, olwid );
624  height = ( height > olhgt ) ? height : ( ( olhgt + height ) / 2 );
625  width = this->width() + width - olwid;
626  height = this->height() + height - olhgt;
627 
628  resize( width, height );
629 
630  connect( lw_vmrecs, SIGNAL( currentRowChanged( int ) ),
631  this, SLOT( row_selected ( int ) ) );
632  connect( le_mfilter, SIGNAL( textChanged( const QString& ) ),
633  this, SLOT( msearch( const QString& ) ) );
634 }
635 
636 // Cancel button: no models returned
638 {
639  reject();
640  close();
641 }
642 
643 // Accept button: set up to return model information
645 {
646  int mdx = 0;
647 
648  if ( ( sel_row = lw_vmrecs->currentRow() ) >= 0 )
649  { // Get row of selection then index in original descriptions list
650  QString mdesc = lw_vmrecs->currentItem()->text();
651  mdx = mrecsIndex( mdesc, mrecs_descriptions );
652 qDebug() << "ACC: sel_row mdx" << sel_row << mdx;
653  }
654 
655  else
656  {
657  QMessageBox::information( this,
658  tr( "No Mrecs Selected" ),
659  tr( "You have not selected a model.\nSelect+Accept or Cancel" ) );
660  return;
661  }
662 
663  // Load the mrecs and set the description
664 qDebug() << "ACC: load... (single)";
665  load_mrecs( omrecs, mdx );
666 qDebug() << "ACC: ...loaded (single)";
667  odescr = concat_description( mdx );
668 
669 
670  // Return search string that reflects current state
671  dsearch = le_mfilter->text();
672 
673  if ( do_edit )
674  dsearch = "=e " + dsearch;
675 
676  dsearch = dsearch.simplified();
677 
678  accept(); // signal that selection was accepted
679  close();
680 }
681 
682 // Get index in model description list of a model description
683 int US_MrecsLoader::mrecsIndex( QString mdesc, QList< MrecsDesc > mds )
684 {
685  int mdx = 0;
686 
687  for ( int jj = 0; jj < mds.size(); jj++ )
688  { // search for matching description and save its index
689  if ( mdesc.compare( mds[ jj ].description ) == 0 )
690  {
691  mdx = jj;
692  break;
693  }
694  }
695 
696  return mdx;
697 }
698 
699 // Show selected-mrecs information in text dialog
701 {
702  int mtype;
703 
704  QString mdesc;
705  QString tdesc;
706  QString cdesc;
707  QString runid;
708  QString dtext;
709  QString lblid;
710  QString mrcid;
711  QString anlid;
712 
713  int row = 0;
714  int mdx = 0;
715 
716  bool frDisk = ( mrecs_descriptions[ 0 ].filename.length() > 0 );
717 
718  if ( frDisk )
719  { // ID is filename
720  lblid = tr( "\n Mrecs File Name: " );
721  }
722 
723  else
724  { // ID is DB id
725  lblid = tr( "\n Database Mrecs ID: " );
726  }
727 
728  if ( ( sel_row = lw_vmrecs->currentRow() ) >= 0 )
729  { // Row selected: build information for single model records entry
730 
731  mdesc = lw_vmrecs->currentItem()->text();
732  mdx = mrecsIndex( mdesc, mrecs_descriptions ); // find index
733 qDebug() << " sel_row" << sel_row << "mdx" << mdx;
734 
735  load_mrecs( mrecs, mdx ); // load mrecs
736 
737  mrec = mrecs[ 0 ];
738  mtype = mrec.ctype; // mrecs info
739  tdesc = US_ModelRecord::ctype_text( mtype );
740  runid = mdesc.section( ".", 0, -4 );
741  mrcid = frDisk ?
742  mrecs_descriptions[ mdx ].filename : // ID is filename
743  mrecs_descriptions[ mdx ].DB_id; // ID is DB id
744  mrcid = mrcid.length() < 50 ? mrcid :
745  "*/" + mrcid.section( "/", -3, -1 ); // short filename
746 
747  dtext = tr( "Mrecs Information:" )
748  + tr( "\n Description: " ) + mdesc
749  + tr( "\n Implied RunID: " ) + runid
750  + tr( "\n Mrecs ID: " ) + mrcid
751  + tr( "\n Mrecs Global ID: " ) + mrec.mrecGUID
752  + tr( "\n Type: " ) + tdesc
753  + " (" + QString::number( (int)mtype ) + ")"
754  + tr( "\n Model Global ID: " ) + mrec.modelGUID
755  + tr( "\n Edit Global ID: " ) + mrec.editGUID
756  + tr( "\n List Row: " ) + QString::number( row + 1 )
757  + tr( "\n Mrecs xmin: " ) + QString::number( mrec.xmin )
758  + tr( "\n Mrecs xmax: " ) + QString::number( mrec.xmax )
759  + tr( "\n Mrecs ymin: " ) + QString::number( mrec.ymin )
760  + tr( "\n Mrecs ymax: " ) + QString::number( mrec.ymax )
761  + tr( "\n Mrecs count: " ) + QString::number( mrecs.count() )
762  + tr( "\n Best Model Type: " )
764  + tr( "\n Best Model taskx: " ) + QString::number( mrec.taskx )
765  + tr( "\n Best Model str_y: " ) + QString::number( mrec.str_y )
766  + tr( "\n Best Model end_y: " ) + QString::number( mrec.end_y )
767  + tr( "\n Best Model par1: " ) + QString::number( mrec.par1 )
768  + tr( "\n Best Model par2: " ) + QString::number( mrec.par2 )
769  + tr( "\n Best Model RMSD: " ) + QString::number( mrec.rmsd )
770  + tr( "\n BM C_Solutes size: " )
771  + QString::number( mrec.csolutes.size() )
772  + tr( "\n BM I_Solutes size: " )
773  + QString::number( mrec.isolutes.size() )
774  + "";
775  }
776 
777  // open a dialog and display model information
778  US_Editor* edit = new US_Editor( US_Editor::LOAD, true, "", this );
779  edit->setWindowTitle( tr( "Mrecs Entry Information" ) );
780  edit->move( this->pos() + QPoint( 200, 200 ) );
781  edit->resize( 800, 460 );
782  edit->e->setFont( QFont( "monospace", US_GuiSettings::fontSize() ) );
783  edit->e->setText( dtext );
784  edit->show();
785 }
786 
787 // Slot to re-list models when search text has changed
788 void US_MrecsLoader::msearch( const QString& search_string )
789 {
790  dsearch = search_string;
791 
792  if ( search_string.endsWith( "=" ) )
793  return;
794 
795  list_vmrecs();
796 }
797 
798 // Slot to re-list models after change in Edit checkbox
799 void US_MrecsLoader::change_edit( bool ckedit )
800 {
801  do_edit = ckedit;
802  db_id1 = -2; // flag re-list when list-edit flag changes
803  db_id2 = -2;
804 
805  list_vmrecs();
806 }
807 
808 // Slot to enable buttons when a row is selected and save that selection
810 {
811  sel_row = row;
812 
813  pb_details->setEnabled( true );
814  pb_delete ->setEnabled( true );
815  pb_accept ->setEnabled( true );
816 }
817 
818 // Slot to delete an mrecs entry
820 {
821  if ( ( sel_row = lw_vmrecs->currentRow() ) < 0 )
822  return;
823 
824  QString mdesc = lw_vmrecs->currentItem()->text();
825  int mdx = mrecsIndex( mdesc, mrecs_descriptions );
826 
827  if ( loadDB )
828  { // Delete an entry from the database
829  if ( dbP == NULL )
830  {
831  US_Passwd pw;
832  dbP = new US_DB2( pw.getPasswd() );
833 
834  if ( dbP->lastErrno() != US_DB2::OK )
835  {
836  QMessageBox::critical( this,
837  tr( "DB Connection Problem" ),
838  tr( "There was an error connecting to the database:\n" )
839  + dbP->lastError() );
840  return;
841  }
842  }
843 
844  QString mrecsID = mrecs_descriptions[ mdx ].DB_id;
845  QStringList qry;
846  qry.clear();
847  qry << "delete_mrecs" << mrecsID;
848 
849  if ( dbP->statusQuery( qry ) == 0 )
850  {
851  QMessageBox::information( this,
852  tr( "Successful DB Delete" ),
853  tr( "The mrecs record '%1' has been deleted from the database." )
854  .arg( mdesc ) );
855 
856  list_vmrecs();
857  }
858 
859  else
860  {
861  QMessageBox::critical( this,
862  tr( "DB Delete Problem" ),
863  tr( "There was an error deleting an entry from the database:\n" )
864  + dbP->lastError() );
865  }
866  }
867 
868  else
869  { // Delete a local file
870  QString fpath = mrecs_descriptions[ mdx ].filename;
871  QFile filemr( fpath );
872  if ( filemr.exists() )
873  {
874  if ( filemr.remove() )
875  {
876  QMessageBox::information( this,
877  tr( "Successful Local File Delete" ),
878  tr( "The mrecs file '%1' has been deleted." )
879  .arg( fpath ) );
880 
881  list_vmrecs();
882  }
883 
884  else
885  {
886  QMessageBox::critical( this,
887  tr( "Error in Local File Delete" ),
888  tr( "The mrecs file '%1' was not deleted"
889  " due to a remove error." ).arg( fpath ) );
890  }
891  }
892 
893  else
894  {
895  QMessageBox::critical( this,
896  tr( "Error in Local File Delete" ),
897  tr( "The mrecs file '%1' was not deleted."
898  " It did not exist." ).arg( fpath ) );
899  }
900  }
901 }
902