00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
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
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
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
00235
00236 void SaveTrajectoryFltkMenu::update_molchooser(int type) {
00237 if (type == Command::MOL_NEW ||
00238 type == Command::MOL_DEL ||
00239 type == Command::MOL_RENAME) {
00240
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
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
00279 filetypechooser->value(0);
00280
00281
00282
00283
00284
00285
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);
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();
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