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() ? -1 : 0;
00074
00075 if (first < 0) first=0;
00076 if (last > max) last=max;
00077 if (stride < 1) stride=1;
00078
00079 if ((last-first)/stride < 0) {
00080 fl_alert("No timesteps selected; trajectory file will not be written.");
00081 return;
00082 }
00083
00084
00085 const char *seltext = selectinput->value();
00086 AtomSel *atomsel = NULL;
00087 if (strlen(seltext)) {
00088 atomsel = new AtomSel(app->atomSelParser, molid);
00089 if (atomsel->change(seltext, app->moleculeList->mol_from_id(molid)) != AtomSel::PARSE_SUCCESS) {
00090 delete atomsel;
00091 fl_alert("Invalid atom selection: %s", seltext);
00092 return;
00093 }
00094 }
00095
00096 char *fname = app->vmd_choose_file(
00097 "Choose filename to save trajectory", mask, filetype, 1);
00098 if (fname) {
00099 FileSpec spec;
00100 spec.first = first;
00101 spec.last = last;
00102 spec.stride = stride;
00103 spec.waitfor = waitfor;
00104 if (atomsel) {
00105 spec.selection = atomsel->on;
00106 }
00107 if (app->molecule_savetrajectory(molid, fname, filetype, &spec) < 0) {
00109 fl_alert("Error writing trajectory file.");
00110 }
00111 delete [] fname;
00112 }
00113 delete atomsel;
00114 }
00115
00116 static void molchooser_cb(Fl_Widget *, void *v) {
00117 ((SaveTrajectoryFltkMenu *)v)->molchooser_activate_selection();
00118 }
00119
00120 void SaveTrajectoryFltkMenu::molchooser_activate_selection() {
00121 int m;
00122 selected_molid = app->molecule_id(molchooser->value()-1);
00123 if (selected_molid < 0) return;
00124
00125
00126 int numframes = app->molecule_numframes(selected_molid);
00127 firstinput->value("0");
00128 {
00129 char buf[32];
00130 sprintf(buf, "%d", numframes-1);
00131 lastinput->value(buf);
00132 }
00133 strideinput->value("1");
00134
00135
00136 Molecule *mol = app->moleculeList->mol_from_id(selected_molid);
00137 datasetbrowser->clear();
00138 for (m=0; m<mol->num_volume_data(); m++) {
00139 datasetbrowser->add(mol->get_volume_data(m)->name);
00140 }
00141
00142
00143 repchooser->clear();
00144 repchooser->add("Current selections:");
00145 for (m=0; m<app->num_molreps(selected_molid); m++) {
00146 repchooser->add(app->molrep_get_selection(selected_molid, m));
00147 }
00148 repchooser->value(0);
00149 }
00150
00151 static void repchooser_cb(Fl_Widget *w, void *v) {
00152 Fl_Choice *c = (Fl_Choice *)w;
00153 if (c->value())
00154 ((SaveTrajectoryFltkMenu *)v)->select_atoms(c->text());
00155 }
00156
00157 void SaveTrajectoryFltkMenu::select_atoms(const char *sel) {
00158 selectinput->value(sel);
00159 }
00160
00161 SaveTrajectoryFltkMenu::SaveTrajectoryFltkMenu(VMDApp *vmdapp)
00162 : VMDFltkMenu("save", "Save Trajectory", vmdapp) {
00163
00164 size(450, 250);
00165 { Fl_Choice* o = molchooser = new Fl_Choice(120, 10, 320, 25, "Save data from: ");
00166 o->box(FL_THIN_UP_BOX);
00167 o->down_box(FL_BORDER_BOX);
00168 o->color(FL_PALEGREEN);
00169 o->selection_color(0);
00170 o->callback(molchooser_cb, this);
00171 }
00172 { Fl_Input *o = selectinput = new Fl_Input(120, 45, 295, 25, "Selected atoms:");
00173 o->selection_color(FL_YELLOW);
00174 }
00175 { Fl_Choice* o = repchooser = new Fl_Choice(415, 45, 25, 25);
00176 o->down_box(FL_BORDER_BOX);
00177 o->align(FL_ALIGN_TOP_LEFT);
00178 o->color(FL_PALEGREEN, FL_BLACK);
00179 o->callback(repchooser_cb, this);
00180 }
00181 { Fl_Choice* o = filetypechooser = new Fl_Choice(20, 90, 115, 25, "File type:");
00182 o->down_box(FL_BORDER_BOX);
00183 o->align(FL_ALIGN_TOP_LEFT);
00184 o->color(FL_PALEGREEN, FL_BLACK);
00185 }
00186 savebutton = new Fl_Return_Button(345, 90, 95, 25, "Save...");
00187 savebutton->callback(save_cb, this);
00188 { Fl_Group* o = timestepgroup = new Fl_Group(20, 145, 165, 95, "Frames: ");
00189 o->box(FL_ENGRAVED_FRAME);
00190 o->align(FL_ALIGN_TOP_LEFT);
00191 { Fl_Button* o = saveinbackgroundbutton = new Fl_Round_Button(30, 215, 150, 20, "Save in background");
00192 o->down_box(FL_ROUND_DOWN_BOX);
00193 o->type(FL_RADIO_BUTTON);
00194 }
00195 { Fl_Button* o = allatoncebutton = new Fl_Round_Button(30, 195, 150, 20, "Save all at once");
00196 o->down_box(FL_ROUND_DOWN_BOX);
00197 o->type(FL_RADIO_BUTTON);
00198 }
00199 { Fl_Input* o = firstinput = new Fl_Int_Input(25, 170, 45, 20, "First:");
00200 o->align(FL_ALIGN_TOP);
00201 o->selection_color(FL_YELLOW);
00202 }
00203 { Fl_Input* o = lastinput = new Fl_Int_Input(80, 170, 45, 20, "Last:");
00204 o->align(FL_ALIGN_TOP);
00205 o->selection_color(FL_YELLOW);
00206 }
00207 { Fl_Input* o = strideinput = new Fl_Int_Input(135, 170, 45, 20, "Stride:");
00208 o->align(FL_ALIGN_TOP);
00209 o->selection_color(FL_YELLOW);
00210 }
00211 o->end();
00212 datasetbrowser = new Fl_Multi_Browser(195, 145, 240, 95, "Volumetric Datasets");
00213 datasetbrowser->align(5);
00214 datasetbrowser->color(FL_DARKCYAN, FL_YELLOW);
00215 }
00216 end();
00217
00218 allatoncebutton->value(1);
00219 selected_molid = -1;
00220 datasetbrowser->deactivate();
00221
00222 command_wanted(Command::PLUGIN_UPDATE);
00223 command_wanted(Command::MOL_NEW);
00224 command_wanted(Command::MOL_RENAME);
00225 command_wanted(Command::MOL_DEL);
00226 command_wanted(Command::MOL_ADDREP);
00227 command_wanted(Command::MOL_DELREP);
00228 command_wanted(Command::MOL_MODREP);
00229 command_wanted(Command::MOL_MODREPITEM);
00230 command_wanted(Command::ANIM_DELETE);
00231 }
00232
00233
00234
00235 void SaveTrajectoryFltkMenu::update_molchooser() {
00236 int tmpid;
00237
00238 molchooser->clear();
00239 molchooser->add("No Molecule Selected");
00240 fill_fltk_molchooser(molchooser, app);
00241
00242 molchooser->value(0);
00243 for (int m=1; m<molchooser->size()-1; m++) {
00244 tmpid = app->molecule_id(m-1);
00245 if (tmpid == selected_molid) {
00246 molchooser->value(m);
00247 molchooser_activate_selection();
00248 break;
00249 }
00250 }
00251 }
00252
00253
00254 int SaveTrajectoryFltkMenu::act_on_command(int type, Command *command) {
00255 switch(type) {
00256 case Command::PLUGIN_UPDATE:
00257 {
00258 filetypechooser->clear();
00259 PluginList plugins;
00260 int n = app->list_plugins(plugins, "mol file reader");
00261 for (int p=0; p<n; p++) {
00262 MolFilePlugin m(plugins[p]);
00263 if (m.can_write_timesteps())
00264 filetypechooser->add(m.name(), 0, 0, (void *)m.extension());
00265 }
00266 filetypechooser->value(0);
00267 }
00268 break;
00269 case Command::MOL_NEW:
00270 case Command::MOL_DEL:
00271 case Command::MOL_RENAME:
00272 case Command::MOL_ADDREP:
00273 case Command::MOL_DELREP:
00274 case Command::MOL_MODREP:
00275 case Command::MOL_MODREPITEM:
00276 update_molchooser();
00277 break;
00278 case Command::ANIM_DELETE:
00279 if (selected_molid == ((CmdAnimDelete*)command)->whichMol)
00280 molchooser_activate_selection();
00281 break;
00282 default:
00283 return 0;
00284 }
00285 return 1;
00286 }
00287
00288
00289 int SaveTrajectoryFltkMenu::selectmol(int molindex) {
00290 if (molindex < 0 || molindex >= app->num_molecules())
00291 molchooser->value(0);
00292 else {
00293 molchooser->value(molindex+1);
00294 molchooser_activate_selection();
00295 }
00296 return TRUE;
00297 }
00298
00299