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(VMDMENU_CHOOSER_BG);
00169 o->selection_color(VMDMENU_CHOOSER_SEL);
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(VMDMENU_VALUE_SEL);
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(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
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(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
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(VMDMENU_VALUE_SEL);
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(VMDMENU_VALUE_SEL);
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(VMDMENU_VALUE_SEL);
00210 }
00211 o->end();
00212 datasetbrowser = new Fl_Multi_Browser(195, 145, 240, 95, "Volumetric Datasets");
00213 datasetbrowser->align(5);
00214 datasetbrowser->color(VMDMENU_BROWSER_BG, VMDMENU_BROWSER_SEL);
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(int type) {
00236 if (type == Command::MOL_NEW ||
00237 type == Command::MOL_DEL ||
00238 type == Command::MOL_RENAME) {
00239
00240 fill_fltk_molchooser(molchooser, app, "No Molecule Selected");
00241 }
00242
00243 molchooser->value(0);
00244 #if 1
00245 int m = app->molecule_index_from_id(selected_molid);
00246 if (m >= 0) {
00247 molchooser->value(m);
00248 molchooser_activate_selection();
00249 }
00250 #else
00251 for (int m=1; m<molchooser->size()-1; m++) {
00252 int tmpid = app->molecule_id(m-1);
00253 if (tmpid == selected_molid) {
00254 molchooser->value(m);
00255 molchooser_activate_selection();
00256 break;
00257 }
00258 }
00259 #endif
00260 }
00261
00262
00263
00264 int SaveTrajectoryFltkMenu::act_on_command(int type, Command *command) {
00265 switch(type) {
00266 case Command::PLUGIN_UPDATE:
00267 {
00268 filetypechooser->clear();
00269 PluginList plugins;
00270 int n = app->list_plugins(plugins, "mol file reader");
00271 for (int p=0; p<n; p++) {
00272 MolFilePlugin m(plugins[p]);
00273 if (m.can_write_timesteps())
00274 filetypechooser->add(m.name(), 0, 0, (void *)m.extension());
00275 }
00276
00277
00278 filetypechooser->value(0);
00279
00280
00281
00282
00283
00284
00285 #if 1
00286 set_chooser_from_string("pdb", filetypechooser);
00287 #else
00288 Fl_Menu_Item *pdbitem = NULL;
00289 pdbitem = filetypechooser->find_item("pdb");
00290 if (pdbitem)
00291 filetypechooser->value(pdbitem);
00292 #endif
00293 }
00294 break;
00295
00296 case Command::MOL_NEW:
00297 case Command::MOL_DEL:
00298 case Command::MOL_RENAME:
00299 case Command::MOL_ADDREP:
00300 case Command::MOL_DELREP:
00301 case Command::MOL_MODREP:
00302 case Command::MOL_MODREPITEM:
00303 update_molchooser(type);
00304 break;
00305
00306 case Command::ANIM_DELETE:
00307 if (selected_molid == ((CmdAnimDelete*)command)->whichMol)
00308 molchooser_activate_selection();
00309 break;
00310
00311 default:
00312 return 0;
00313 }
00314
00315 return 1;
00316 }
00317
00318
00319 int SaveTrajectoryFltkMenu::selectmol(int molindex) {
00320 if (molindex < 0 || molindex >= app->num_molecules())
00321 molchooser->value(0);
00322 else {
00323 molchooser->value(molindex+1);
00324 molchooser_activate_selection();
00325 }
00326 return TRUE;
00327 }
00328
00329