Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

SaveTrajectoryFltkMenu.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: SaveTrajectoryFltkMenu.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.42 $       $Date: 2020/07/23 03:27:52 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *  Window to allow the user to save sets of trajectory frames etc.
00019  ***************************************************************************/
00020 
00021 #include "SaveTrajectoryFltkMenu.h"
00022 #include "Command.h"
00023 #include "VMDApp.h"
00024 #include "MolFilePlugin.h"
00025 #include "frame_selector.h"
00026 #include "CmdAnimate.h"
00027 #include "AtomSel.h"
00028 #include "MoleculeList.h"
00029 #include "VolumetricData.h"
00030 
00031 #include <stdio.h>
00032 #include <FL/Fl.H>
00033 #include <FL/forms.H>
00034 #include <FL/Fl_Window.H>
00035 #include <FL/Fl_Hold_Browser.H>
00036 #include <FL/Fl_Return_Button.H>
00037 #include <FL/Fl_Button.H>
00038 #include <FL/Fl_Choice.H>
00039 #include <FL/Fl_Int_Input.H>
00040 #include <FL/Fl_Multi_Browser.H>
00041 #include "utilities.h"
00042 
00043 static void save_cb(Fl_Widget *, void *v) {
00044   ((SaveTrajectoryFltkMenu *)v)->do_save();
00045 }
00046 
00047 void SaveTrajectoryFltkMenu::do_save() {
00048   int ind = molchooser->value()-1;
00049   if (ind < 0) {
00050     fl_alert("Please select a molecule first.");
00051     return;
00052   }
00053   int molid = app->molecule_id(ind);
00054   if (molid < 0) return;
00055   // Make sure the user selected a file type
00056   if (filetypechooser->value() < 0) {
00057     fl_alert("Please select a file type first.");
00058     return;
00059   }
00060 
00061   const char *filetype = filetypechooser->text();
00062   char mask[20];
00063   sprintf(mask, "*.%s", (const char *)filetypechooser->mvalue()->user_data());
00064 
00065   // read and check selected frames
00066   const char *firststr = firstinput->value();
00067   const char *laststr = lastinput->value();
00068   const char *stridestr = strideinput->value();
00069   int max = app->molecule_numframes(molid)-1;
00070   int first = strlen(firststr) ? atoi(firststr) : 0;
00071   int last = strlen(laststr) ? atoi(laststr) : max;
00072   int stride = strlen(stridestr) ? atoi(stridestr) : 1;
00073   int waitfor = allatoncebutton->value() ? 
00074                 FileSpec::WAIT_ALL : FileSpec::WAIT_BACK;
00075 
00076   if (first < 0) first=0;
00077   if (last > max) last=max;
00078   if (stride < 1) stride=1;
00079 
00080   if ((last-first)/stride < 0) {
00081     fl_alert("No timesteps selected; trajectory file will not be written.");
00082     return;
00083   }
00084 
00085   // check that selected atoms is valid
00086   const char *seltext = selectinput->value();
00087   AtomSel *atomsel = NULL;
00088   if (strlen(seltext)) {
00089     atomsel = new AtomSel(app, app->atomSelParser, molid);
00090     if (atomsel->change(seltext, app->moleculeList->mol_from_id(molid)) != AtomSel::PARSE_SUCCESS) {
00091       delete atomsel;
00092       fl_alert("Invalid atom selection: %s", seltext);
00093       return;
00094     }
00095   }
00096 
00097   char *fname = app->vmd_choose_file(
00098     "Choose filename to save trajectory", mask, filetype, 1);
00099   if (fname) {
00100     FileSpec spec;
00101     spec.first = first;
00102     spec.last = last;
00103     spec.stride = stride;
00104     spec.waitfor = waitfor;
00105     if (atomsel) {
00106       spec.selection = atomsel->on;
00107     }
00108     if (app->molecule_savetrajectory(molid, fname, filetype, &spec) < 0) {
00110       fl_alert("Error writing trajectory file.");
00111     }
00112     delete [] fname;
00113   }
00114   delete atomsel;
00115 }
00116 
00117 static void molchooser_cb(Fl_Widget *, void *v) {
00118   ((SaveTrajectoryFltkMenu *)v)->molchooser_activate_selection();
00119 }
00120 
00121 void SaveTrajectoryFltkMenu::molchooser_activate_selection() {
00122   int m;
00123   selected_molid = app->molecule_id(molchooser->value()-1);
00124   if (selected_molid < 0) return;
00125   
00126   // update frames
00127   int numframes = app->molecule_numframes(selected_molid); 
00128   firstinput->value("0");
00129   {
00130     char buf[32];
00131     sprintf(buf, "%d", numframes-1);
00132     lastinput->value(buf);
00133   }
00134   strideinput->value("1");
00135 
00136   // update volumetric datasets
00137   Molecule *mol = app->moleculeList->mol_from_id(selected_molid);
00138   datasetbrowser->clear();
00139   for (m=0; m<mol->num_volume_data(); m++) {
00140     datasetbrowser->add(mol->get_volume_data(m)->name);
00141   }
00142 
00143   // update reps in repchooser
00144   repchooser->clear();
00145   repchooser->add("Current selections:");
00146   for (m=0; m<app->num_molreps(selected_molid); m++) {
00147     repchooser->add(app->molrep_get_selection(selected_molid, m));
00148   }
00149   repchooser->value(0);
00150 }
00151 
00152 static void repchooser_cb(Fl_Widget *w, void *v) {
00153   Fl_Choice *c = (Fl_Choice *)w;
00154   if (c->value()) 
00155     ((SaveTrajectoryFltkMenu *)v)->select_atoms(c->text());
00156 }
00157 
00158 void SaveTrajectoryFltkMenu::select_atoms(const char *sel) {
00159   selectinput->value(sel);
00160 }
00161 
00162 SaveTrajectoryFltkMenu::SaveTrajectoryFltkMenu(VMDApp *vmdapp)
00163 : VMDFltkMenu("save", "Save Trajectory", vmdapp) {
00164   
00165   size(450, 250);
00166     { Fl_Choice* o = molchooser = new Fl_Choice(120, 10, 320, 25, "Save data from: ");
00167       o->box(FL_THIN_UP_BOX);
00168       o->down_box(FL_BORDER_BOX);
00169       o->color(VMDMENU_CHOOSER_BG);
00170       o->selection_color(VMDMENU_CHOOSER_SEL);
00171       o->callback(molchooser_cb, this);
00172     }
00173     { Fl_Input *o = selectinput = new Fl_Input(120, 45, 295, 25, "Selected atoms:");
00174       o->selection_color(VMDMENU_VALUE_SEL);
00175     }
00176     { Fl_Choice* o = repchooser = new Fl_Choice(415, 45, 25, 25);
00177       o->down_box(FL_BORDER_BOX);
00178       o->align(FL_ALIGN_TOP_LEFT);
00179       o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00180       o->callback(repchooser_cb, this);
00181     }
00182     { Fl_Choice* o = filetypechooser = new Fl_Choice(20, 90, 115, 25, "File type:");
00183       o->down_box(FL_BORDER_BOX);
00184       o->align(FL_ALIGN_TOP_LEFT);
00185       o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00186     }
00187     savebutton = new Fl_Return_Button(345, 90, 95, 25, "Save...");
00188     savebutton->callback(save_cb, this);
00189     { Fl_Group* o = timestepgroup = new Fl_Group(20, 145, 165, 95, "Frames: ");
00190       o->box(FL_ENGRAVED_FRAME);
00191       o->align(FL_ALIGN_TOP_LEFT);
00192       { Fl_Button* o = saveinbackgroundbutton = new Fl_Round_Button(30, 215, 150, 20, "Save in background");
00193         o->down_box(FL_ROUND_DOWN_BOX);
00194         o->type(FL_RADIO_BUTTON);
00195       }
00196       { Fl_Button* o = allatoncebutton = new Fl_Round_Button(30, 195, 150, 20, "Save all at once");
00197         o->down_box(FL_ROUND_DOWN_BOX);
00198         o->type(FL_RADIO_BUTTON);
00199       }
00200       { Fl_Input* o = firstinput = new Fl_Int_Input(25, 170, 45, 20, "First:");
00201         o->align(FL_ALIGN_TOP);
00202         o->selection_color(VMDMENU_VALUE_SEL);
00203       }
00204       { Fl_Input* o = lastinput = new Fl_Int_Input(80, 170, 45, 20, "Last:");
00205         o->align(FL_ALIGN_TOP);
00206         o->selection_color(VMDMENU_VALUE_SEL);
00207       }
00208       { Fl_Input* o = strideinput = new Fl_Int_Input(135, 170, 45, 20, "Stride:");
00209         o->align(FL_ALIGN_TOP);
00210         o->selection_color(VMDMENU_VALUE_SEL);
00211       }
00212       o->end();
00213       datasetbrowser = new Fl_Multi_Browser(195, 145, 240, 95, "Volumetric Datasets");
00214       datasetbrowser->align(5);
00215       datasetbrowser->color(VMDMENU_BROWSER_BG, VMDMENU_BROWSER_SEL);
00216     } 
00217     end();
00218 
00219   allatoncebutton->value(1);
00220   selected_molid = -1;
00221   datasetbrowser->deactivate();
00222   
00223   command_wanted(Command::PLUGIN_UPDATE);
00224   command_wanted(Command::MOL_NEW);
00225   command_wanted(Command::MOL_RENAME);
00226   command_wanted(Command::MOL_DEL);
00227   command_wanted(Command::MOL_ADDREP);
00228   command_wanted(Command::MOL_DELREP);
00229   command_wanted(Command::MOL_MODREP);
00230   command_wanted(Command::MOL_MODREPITEM);
00231   command_wanted(Command::ANIM_DELETE);
00232 }
00233 
00234 // This rebuilds the molecule chooser menu and selects the item 
00235 // corresponding to the previouly selected molid
00236 void SaveTrajectoryFltkMenu::update_molchooser(int type) {
00237   if (type == Command::MOL_NEW ||
00238       type == Command::MOL_DEL ||  
00239       type == Command::MOL_RENAME) {
00240     // don't regen the molecule list for rep changes
00241     fill_fltk_molchooser(molchooser, app, "No Molecule Selected");
00242   }
00243  
00244   molchooser->value(0);
00245 #if 1
00246   int m = app->molecule_index_from_id(selected_molid);
00247   if (m >= 0) {
00248     molchooser->value(m);
00249     molchooser_activate_selection();
00250   }
00251 #else
00252   for (int m=1; m<molchooser->size()-1; m++) { 
00253     int tmpid = app->molecule_id(m-1);
00254     if (tmpid == selected_molid) {
00255       molchooser->value(m);
00256       molchooser_activate_selection();
00257       break;
00258     }
00259   }
00260 #endif
00261 }
00262 
00263 
00264 // XXX just like FilesFltkMenu - maybe we should be subclassing or something
00265 int SaveTrajectoryFltkMenu::act_on_command(int type, Command *command) {
00266   switch(type) {
00267     case Command::PLUGIN_UPDATE: 
00268       {
00269         filetypechooser->clear();
00270         PluginList plugins;
00271         int n = app->list_plugins(plugins, "mol file reader");
00272         for (int p=0; p<n; p++) {
00273           MolFilePlugin m(plugins[p]);
00274           if (m.can_write_timesteps())
00275             filetypechooser->add(m.name(), 0, 0, (void *)m.extension());
00276         }
00277 
00278         // set the chooser to the first item initially, update from there
00279         filetypechooser->value(0);
00280 
00281         // Make PDB the default filetype, if we can find it in the menu
00282         // XXX Current code is listing them using extensions rather than the
00283         //     pretty names.
00284         // XXX This should be updated to use the built-in FLTK routines
00285         //     for FLTK versions 1.1.7 and newer.
00286 #if 1
00287         set_chooser_from_string("pdb", filetypechooser);
00288 #else
00289         Fl_Menu_Item *pdbitem = NULL;
00290         pdbitem = filetypechooser->find_item("pdb");
00291         if (pdbitem)
00292           filetypechooser->value(pdbitem); // set "pdb" as default
00293 #endif
00294       }
00295       break;
00296 
00297     case Command::MOL_NEW:
00298     case Command::MOL_DEL:
00299     case Command::MOL_RENAME:
00300     case Command::MOL_ADDREP:
00301     case Command::MOL_DELREP:
00302     case Command::MOL_MODREP:
00303     case Command::MOL_MODREPITEM:
00304       update_molchooser(type);
00305       break;
00306 
00307     case Command::ANIM_DELETE:
00308       if (selected_molid == ((CmdAnimDelete*)command)->whichMol)
00309         molchooser_activate_selection(); //to update the number of frames
00310       break;
00311 
00312     default:
00313       return 0;
00314   }
00315 
00316   return 1;
00317 }
00318 
00319 
00320 int SaveTrajectoryFltkMenu::selectmol(int molindex) {
00321   if (molindex < 0 || molindex >= app->num_molecules())
00322       molchooser->value(0);
00323   else {
00324     molchooser->value(molindex+1);
00325     molchooser_activate_selection();
00326   }
00327   return TRUE;
00328 }
00329 
00330 

Generated on Thu Apr 25 02:43:33 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002