i++;
}
continue;
+ } else if (strcmp(buf, "!:uff_types") == 0) {
+ i = 0;
+ while (ReadLine(buf, sizeof buf, fp, &lineNumber) > 0) {
+ if (buf[0] == '!')
+ continue;
+ if (buf[0] == '\n')
+ break;
+ /* idx uff_type */
+ if (sscanf(buf, "%d %6s", &ibuf[0], cbuf[0]) < 2) {
+ s_append_asprintf(errbuf, "line %d: uff type info cannot be read for atom %d", lineNumber, i + 1);
+ goto err_exit;
+ }
+ if (i >= mp->natoms) {
+ s_append_asprintf(errbuf, "line %d: too many uff type info\n", lineNumber);
+ goto err_exit;
+ }
+ ap = ATOM_AT_INDEX(mp->atoms, i);
+ strncpy(ap->uff_type, cbuf[0], 5);
+ ap->uff_type[5] = 0;
+ i++;
+ }
} else if (strcmp(buf, "!:mm_exclude") == 0) {
i = 0;
while (ReadLine(buf, sizeof buf, fp, &lineNumber) > 0) {
MoleculeWriteToMbsfFile(Molecule *mp, const char *fname, char **errbuf)
{
FILE *fp;
- Int i, j, k, n1, n2, n3, n_aniso, nframes, nanchors;
+ Int i, j, k, n1, n2, n3, n_aniso, nframes, nanchors, n_uff;
Atom *ap;
char bufs[6][8];
fprintf(fp, "!:atoms\n");
fprintf(fp, "! idx seg_name res_seq res_name name type charge weight element atomic_number occupancy temp_factor int_charge\n");
- n1 = n2 = n3 = n_aniso = nanchors = 0;
+ n1 = n2 = n3 = n_aniso = nanchors = n_uff = 0;
for (i = 0, ap = mp->atoms; i < mp->natoms; i++, ap = ATOM_NEXT(ap)) {
strncpy(bufs[0], ap->segName, 4);
bufs[0][4] = 0;
n_aniso++;
if (ap->anchor != NULL)
nanchors++;
+ if (ap->uff_type[0] != 0)
+ n_uff++;
fprintf(fp, "%d %s %d %s %s %s %.5f %.5f %s %d %f %f %d\n", i, bufs[0], ap->resSeq, bufs[1], bufs[2], bufs[3], ap->charge, ap->weight, bufs[4], ap->atomicNumber, ap->occupancy, ap->tempFactor, ap->intCharge);
}
fprintf(fp, "\n");
+ if (n_uff > 0) {
+ fprintf(fp, "!:uff_type\n");
+ fprintf(fp, "! idx uff_type\n");
+ for (i = 0, ap = mp->atoms; i < mp->natoms; i++, ap = ATOM_NEXT(ap)) {
+ int n;
+ fprintf(fp, "%d %.5s\n", i, ap->uff_type);
+ }
+ fprintf(fp, "\n");
+ }
+
if (n1 > 0) {
fprintf(fp, "!:atoms_symop\n");
fprintf(fp, "! idx symop symbase\n");
Vector fix_pos;
Byte mm_exclude; /* If nonzero, then this atom is excluded from MM/MD calculations */
Byte periodic_exclude; /* If nonzero, then this atom is excluded from periodic calculations */
+ char uff_type[6]; /* UFF type string */
} Atom;
extern Int gSizeOfAtomRecord;
/* This definition is to work around 'VALUE' type in sources without "ruby.h" */
typedef void *RubyValue;
+
+#define RubyNil ((RubyValue)4)
extern char *gRubyVersion;
extern char *gRubyCopyright;
extern int Ruby_methodType(const char *className, const char *methodName);
extern void Molby_buildARGV(int argc, const char **argv);
+/* RubyValue version of Ruby_funcall2_protect() */
+extern RubyValue Ruby_funcall2_protect_extern(RubyValue recv, int mid, int argc, RubyValue *argv, int *status);
+
+extern int g_RubyID_call; /* rb_intern("call") for extrenal use */
+
STUB char *MyAppCallback_getGUIDescriptionString(void);
STUB char *MyAppCallback_getGlobalSettings(const char *key);
STUB void MyAppCallback_setGlobalSettings(const char *key, const char *value);
char *gRubyVersion, *gRubyCopyright;
/* For convenience */
-static VALUE s_ID_equal; /* rb_intern("==") */
+static ID s_ID_equal; /* rb_intern("==") */
+
+int g_RubyID_call;
/* Symbols for atom attributes */
static VALUE
s_VSym, s_FSym, s_OccupancySym, s_TempFactorSym,
s_AnisoSym, s_SymopSym, s_IntChargeSym, s_FixForceSym,
s_FixPosSym, s_ExclusionSym, s_MMExcludeSym, s_PeriodicExcludeSym,
- s_HiddenSym, s_AnchorListSym;
+ s_HiddenSym, s_AnchorListSym, s_UFFTypeSym;
/* Symbols for parameter attributes */
static VALUE
return rb_protect(s_Ruby_funcall2_sub, (VALUE)&rec, status);
}
+RubyValue
+Ruby_funcall2_protect_extern(RubyValue recv, int mid, int argc, RubyValue *argv, int *status)
+{
+ return (RubyValue)Ruby_funcall2_protect((VALUE)recv, mid, argc, (VALUE *)argv, status);
+}
+
#pragma mark ====== ParameterRef Class ======
static UnionPar *
return retval;
}
+static VALUE s_AtomRef_GetUFFType(VALUE self) {
+ char *p = s_AtomFromValue(self)->uff_type;
+ return rb_str_new(p, strlen_limit(p, 5));
+}
+
static VALUE s_AtomRef_SetIndex(VALUE self, VALUE val) {
rb_raise(rb_eMolbyError, "index cannot be directly set");
return Qnil;
return val;
}
+static VALUE s_AtomRef_SetUFFType(VALUE self, VALUE val) {
+ Atom *ap = s_AtomFromValue(self);
+ char *p = StringValuePtr(val);
+ VALUE oval = s_AtomRef_GetUFFType(self);
+ strncpy(ap->uff_type, p, 5);
+ ap->uff_type[5] = 0;
+ s_RegisterUndoForAtomAttrChange(self, s_UFFTypeSym, val, oval);
+ return val;
+}
+
static struct s_AtomAttrDef {
char *name;
VALUE *symref; /* Address of s_IndexSymbol etc. */
{"periodic_exclude", &s_PeriodicExcludeSym, 0, s_AtomRef_GetPeriodicExclude, s_AtomRef_SetPeriodicExclude},
{"hidden", &s_HiddenSym, 0, s_AtomRef_GetHidden, s_AtomRef_SetHidden},
{"anchor_list", &s_AnchorListSym, 0, s_AtomRef_GetAnchorList, s_AtomRef_SetAnchorList},
+ {"uff_type", &s_UFFTypeSym, 0, s_AtomRef_GetUFFType, s_AtomRef_SetUFFType},
{NULL} /* Sentinel */
};
rb_define_method(rb_mKernel, "hide_console_window", s_Kernel_HideConsoleWindow, 0);
s_ID_equal = rb_intern("==");
+ g_RubyID_call = rb_intern("call");
}
#pragma mark ====== External functions ======
/* Data source for Table (= MyListCtrl) */
sOnCountSymbol, sOnGetValueSymbol, sOnSetValueSymbol, sOnSelectionChangedSymbol,
sOnSetColorSymbol, sIsItemEditableSymbol, sIsDragAndDropEnabledSymbol, sOnDragSelectionToRowSymbol,
- sSelectionSymbol, sColumnsSymbol;
+ sSelectionSymbol, sColumnsSymbol, sRefreshSymbol;
VALUE rb_cDialog = Qfalse;
VALUE rb_cDialogItem = Qfalse;
frame.size.height = NUM2DBL(rb_Float(Ruby_ObjectAtIndex(val, 3)));
RubyDialogCallback_setFrameOfItem(view, frame);
} else if (key == sFlexSymbol) {
- /* Glue to [left, top, right, bottom]
- An array of 4 integers or a string like "LTRB" (case insensitive) */
- int glue = 0;
+ /* Flex flags: [left, top, right, bottom, width, height] (0: fixed, 1: flex) */
+ int flex = 0;
if (val == Qnil) {
rb_ivar_set(self, key_id, val);
} else {
- if (rb_obj_is_kind_of(val, rb_cString)) {
- const char *sp = StringValuePtr(val);
- if (strchr(sp, 'l') || strchr(sp, 'L'))
- glue |= 1;
- if (strchr(sp, 't') || strchr(sp, 'T'))
- glue |= 2;
- if (strchr(sp, 'r') || strchr(sp, 'R'))
- glue |= 4;
- if (strchr(sp, 'b') || strchr(sp, 'B'))
- glue |= 8;
- } else if (rb_obj_is_kind_of(val, rb_mEnumerable)) {
+ if (rb_obj_is_kind_of(val, rb_mEnumerable)) {
int i;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 6; i++) {
VALUE gval = Ruby_ObjectAtIndex(val, i);
if (RTEST(gval) && NUM2INT(rb_Integer(gval)) != 0)
- glue |= (1 << i);
+ flex |= (1 << i);
}
} else if (rb_obj_is_kind_of(val, rb_cNumeric)) {
- glue = NUM2INT(rb_Integer(val));
+ flex = NUM2INT(rb_Integer(val));
} else {
- rb_raise(rb_eMolbyError, "the 'glue' attribute should be either an integer, an array of 4 boolean/integers or a string");
+ rb_raise(rb_eMolbyError, "the 'flex' attribute should be either an integer or an array of 4 boolean/integers");
}
- rb_ivar_set(self, key_id, INT2NUM(glue));
+ rb_ivar_set(self, key_id, INT2NUM(flex));
}
} else if (key == sFontSymbol) {
int size, family, style, weight, i;
}
RubyDialogCallback_setFontForItem(view, size, family, style, weight);
} else if (key == sSelectionSymbol) {
- /* Selection (for Table == MyTextCtrl item) */
+ /* Selection (for Table == MyListCtrl item) */
if (type == sTableSymbol) {
IntGroup *ig = IntGroupFromValue(val);
int row, count;
}
}
} else if (key == sColumnsSymbol) {
- /* Columns (for Table == MyTextCtrl item) */
+ /* Columns (for Table == MyListCtrl item) */
if (type == sTableSymbol) {
/* The value should be an array of [name, width, align (0: natural, 1: right, 2: center)] */
int col;
RubyDialogCallback_insertTableColumn((RDItem *)view, col, heading, format, width);
}
}
+ } else if (key == sRefreshSymbol) {
+ /* Refresh (for Table == MyListCtrl item) */
+ if (type == sTableSymbol) {
+ if (RTEST(val)) {
+ RubyDialogCallback_refreshTable((RDItem *)view);
+ }
+ }
} else {
if (key == sTagSymbol && rb_obj_is_kind_of(val, rb_cInteger))
rb_raise(rb_eMolbyError, "the dialog item tag must not be integers");
val = rb_ary_new3(4, rb_float_new(frame.origin.x), rb_float_new(frame.origin.y), rb_float_new(frame.size.width), rb_float_new(frame.size.height));
rb_obj_freeze(val);
} else if (key == sFlexSymbol) {
- int glue;
+ int i, flex;
val = rb_ivar_get(self, key_id);
if (val != Qnil) {
- glue = NUM2INT(rb_Integer(val));
+ flex = NUM2INT(rb_Integer(val));
val = rb_ary_new();
- rb_ary_push(val, ((glue & 1) ? INT2FIX(1) : INT2FIX(0)));
- rb_ary_push(val, ((glue & 2) ? INT2FIX(1) : INT2FIX(0)));
- rb_ary_push(val, ((glue & 4) ? INT2FIX(1) : INT2FIX(0)));
- rb_ary_push(val, ((glue & 8) ? INT2FIX(1) : INT2FIX(0)));
+ for (i = 0; i < 6; i++) {
+ rb_ary_push(val, ((flex & (1 << i)) ? INT2FIX(1) : INT2FIX(0)));
+ }
}
} else if (key == sFontSymbol) {
int size, family, style, weight;
/* Index for the layout view */
itag = RARRAY_LEN(items);
- /* Create a new hash for the layout view and push to _items */
- {
- new_item = rb_class_new_instance(0, NULL, rb_cDialogItem);
- rb_ivar_set(new_item, SYM2ID(sTypeSymbol), sViewSymbol);
- rb_ivar_set(new_item, SYM2ID(sDialogSymbol), self);
- rb_ivar_set(new_item, SYM2ID(sIndexSymbol), INT2NUM(itag));
- rb_ary_push(items, new_item);
+ /* Create a new item object for the layout view and push to _items */
+ new_item = rb_class_new_instance(0, NULL, rb_cDialogItem);
+ rb_ivar_set(new_item, SYM2ID(sTypeSymbol), sViewSymbol);
+ rb_ivar_set(new_item, SYM2ID(sDialogSymbol), self);
+ rb_ivar_set(new_item, SYM2ID(sIndexSymbol), INT2NUM(itag));
+ rb_ary_push(items, new_item);
+
+ if (oval != Qnil) {
+ /* Set the attributes given in the option hash */
+ VALUE keys = rb_funcall(oval, rb_intern("keys"), 0);
+ for (i = 0; i < RARRAY_LEN(keys); i++) {
+ VALUE kval = RARRAY_PTR(keys)[i];
+ if (TYPE(kval) == T_SYMBOL)
+ s_RubyDialogItem_SetAttr(new_item, kval, rb_hash_aref(oval, kval));
+ }
}
RubyDialogCallback_setAutoResizeEnabled(dref, autoResizeFlag);
/*
* call-seq:
+ * listen(obj, str, pr)
+ *
+ * Listen to the event invoked by the object. str = the name of the event (dependent on the
+ * object), pr = the callback procedure. The first argument to the callback procedure is
+ * always obj. Other arguments are dependent on the event and the object.
+ */
+static VALUE
+s_RubyDialog_Listen(VALUE self, VALUE oval, VALUE sval, VALUE pval)
+{
+ int i;
+ const char *sptr;
+ if (sval == Qnil)
+ sptr = NULL;
+ else
+ sptr = StringValuePtr(sval);
+ if (rb_obj_is_kind_of(oval, rb_cMolecule)) {
+ Molecule *mol = MoleculeFromValue(oval);
+ i = RubyDialogCallback_Listen(s_RubyDialog_GetController(self), mol, "Molecule", sptr, (RubyValue)oval, (RubyValue)pval);
+ if (i < 0) {
+ switch (i) {
+ case -1: rb_raise(rb_eMolbyError, "This dialog cannot be listened to."); break;
+ case -2: rb_raise(rb_eMolbyError, "This message is not supported"); break;
+ }
+ } else {
+ /* Keep the objects in the internal array, to protect from GC */
+ ID id = rb_intern("listen");
+ VALUE aval = rb_ivar_get(self, id);
+ if (aval == Qnil) {
+ aval = rb_ary_new();
+ rb_ivar_set(self, id, aval);
+ }
+ if (pval == Qfalse || pval == Qnil) {
+ rb_ary_delete_at(aval, i);
+ } else {
+ rb_ary_store(aval, i, rb_ary_new3(2, oval, pval));
+ }
+ }
+ } else {
+ rb_raise(rb_eMolbyError, "Dialog#listen is presently only available for Molecule object");
+ }
+ return self;
+}
+
+/*
+ * call-seq:
* save_panel(message = nil, directory = nil, default_filename = nil, wildcard = nil)
*
* Display the "save as" dialog and returns the fullpath filename.
int status;
void *vp[6] = { (void *)self, (void *)ip, (void *)sOnGetValueSymbol, (void *)row, (void *)column, NULL };
VALUE val = rb_protect(s_RubyDialog_doTableAction, (VALUE)vp, &status);
- if (status != 0) {
- Molby_showError(status);
+ if (status != 0 || val == Qnil) {
buf[0] = 0;
- } else if (val == Qnil)
- buf[0] = 0;
- else {
+ } else {
strncpy(buf, (char *)vp[5], buflen - 1);
buf[buflen - 1] = 0;
}
}
}
-int
-RubyDialog_getFlexFlags(RubyValue self, RDItem *ip)
+static VALUE
+s_RubyDialog_getFlexFlags(VALUE val)
{
+ VALUE self = (VALUE)(((void **)val)[0]);
+ RDItem *ip = (RDItem *)(((void **)val)[1]);
VALUE itval, pval;
- RubyDialog *dref = s_RubyDialog_GetController((VALUE)self);
+ RubyDialog *dref = s_RubyDialog_GetController(self);
int idx = RubyDialogCallback_indexOfItem(dref, ip);
if (idx < 0)
- return -1; /* No such item (this cannot happen) */
- itval = s_RubyDialog_ItemAtIndex((VALUE)self, INT2NUM(idx));
+ return Qnil; /* No such item (this cannot happen) */
+ itval = s_RubyDialog_ItemAtIndex(self, INT2NUM(idx));
pval = rb_ivar_get(itval, SYM2ID(sFlexSymbol));
if (pval == Qnil)
- return -1; /* Not set */
- else return NUM2INT(rb_Integer(pval));
+ return Qnil; /* Not set */
+ else {
+ pval = rb_Integer(pval);
+ ((void **)val)[2] = (void *)(NUM2INT(pval));
+ return pval;
+ }
+}
+
+int
+RubyDialog_getFlexFlags(RubyValue self, RDItem *ip)
+{
+ int status;
+ VALUE rval;
+ void *args[3] = { (void *)self, (void *)ip, NULL };
+ rval = rb_protect(s_RubyDialog_getFlexFlags, (VALUE)args, &status);
+ if (status != 0)
+ return -1;
+ else if (rval == Qnil)
+ return -1;
+ else return (int)args[2];
}
#pragma mark ====== Initialize class ======
rb_define_method(rb_cDialog, "size", s_RubyDialog_Size, 0);
rb_define_method(rb_cDialog, "set_min_size", s_RubyDialog_SetMinSize, -1);
rb_define_method(rb_cDialog, "min_size", s_RubyDialog_MinSize, 0);
+ rb_define_method(rb_cDialog, "listen", s_RubyDialog_Listen, 3);
rb_define_singleton_method(rb_cDialog, "save_panel", s_RubyDialog_SavePanel, -1);
rb_define_singleton_method(rb_cDialog, "open_panel", s_RubyDialog_OpenPanel, -1);
&sMediumSymbol, &sBoldSymbol, &sLightSymbol,
&sOnCountSymbol, &sOnGetValueSymbol, &sOnSetValueSymbol, &sOnSelectionChangedSymbol,
&sOnSetColorSymbol, &sIsItemEditableSymbol, &sIsDragAndDropEnabledSymbol, &sOnDragSelectionToRowSymbol,
- &sSelectionSymbol, &sColumnsSymbol
+ &sSelectionSymbol, &sColumnsSymbol, &sRefreshSymbol
};
static const char *sTable2[] = {
"text", "textfield", "radio", "button",
"medium", "bold", "light",
"on_count", "on_get_value", "on_set_value", "on_selection_changed",
"on_set_color", "is_item_editable", "is_drag_and_drop_enabled", "on_drag_selection_to_row",
- "selection", "columns"
+ "selection", "columns", "refresh"
};
int i;
for (i = 0; i < sizeof(sTable1) / sizeof(sTable1[0]); i++)
STUB void RubyDialogCallback_setAutoResizeEnabled(RubyDialog *dref, int flag);
STUB int RubyDialogCallback_isAutoResizeEnabled(RubyDialog *dref);
+STUB int RubyDialogCallback_Listen(RubyDialog *dref, void *obj, const char *objtype, const char *msg, RubyValue oval, RubyValue pval);
+
STUB void RubyDialogCallback_createStandardButtons(RubyDialog *dref, const char *oktitle, const char *canceltitle);
STUB RDItem *RubyDialogCallback_createItem(RubyDialog *dref, const char *type, const char *title, RDRect frame);
STUB RDItem *RubyDialogCallback_dialogItemAtIndex(RubyDialog *dref, int idx);
item(:textfield, :width=>"80", :tag=>"nc", :value=>(get_global_settings("antechamber.nc") || "0")),
(tool == "resp" ?
-1 :
- item(:checkbox, :title=>"Optimize structure and calculate charges (may be slow)", :tag=>"calc_charge",
- :value=>(get_global_settings("antechamber.calc_charge") || 0),
- :action=>proc { |it| set_attr("nc", :enabled=>(it[:value] != 0)) } )),
+ item(:checkbox, :title=>"Calculate partial charges", :tag=>"calc_charge",
+ :action=>proc { |it|
+ set_attr("optimize_structure", :enabled=>(it[:value] != 0)) } )),
+ -1,
+ (tool == "resp" ?
+ -1 :
+ layout(2,
+ item(:view, :width=>"12"),
+ item(:checkbox, :title=>"Optimize structure before calculating charges (may be slow)",
+ :tag=>"optimize_structure",
+ :value=>(get_global_settings("antechamber.optimize_structure") || 0)))),
+ -1,
+ (tool == "resp" ?
+ -1 :
+ item(:checkbox, :title=>"Guess atom types", :tag=>"guess_atom_types",
+ :value=>(get_global_settings("antechamber.guess_atom_types") || 1))),
-1,
item(:checkbox, :title=>"Use the residue information for connection analysis", :tag=>"use_residue",
:value=>(get_global_settings("antechamber.use_residue") || 0),
),
-1
)
+ it = item_with_tag("calc_charge")
+ if it
+ it[:value] = (get_global_settings("antechamber.calc_charge") || 0)
+ it[:action].call(it)
+ end
}
hash.each_pair { |key, value|
next if key == :status
end
- def import_ac(acfile)
+ def import_ac(acfile, read_charge, read_type)
open(acfile, "r") { |fp|
while (s = fp.gets)
next if s !~ /^ATOM/
s.chomp!
idx = Integer(s[4..11]) - 1
- charge = Float(s[54..63])
- type = s[72..-1]
- type.gsub!(/ /, "")
ap = atoms[idx]
- ap.charge = charge
- ap.atom_type = type
+ if read_charge != 0
+ charge = Float(s[54..63])
+ ap.charge = charge
+ end
+ if read_type != 0
+ type = s[72..-1]
+ type.gsub!(/ /, "")
+ ap.atom_type = type
+ end
end
}
return 0
}
names = indices.map { |i| sprintf("%d:%s", atoms[i].res_seq, atoms[i].name) }
types = indices.map { |i| atoms[i].atom_type }
+ utypes = indices.map { |i| atoms[i].uff_type }
names_str = names.join("-")
types_str = types.join("-")
recalc = proc { |i1, i2, i3, b1, b2|
if p.length == 1
type_selects.push(item(:text, :title=>UFFParams[p[0]][0]))
else
- type_selects.push(item(:popup, :subitems=>p.map { |pp| UFFParams[pp][0] }, :tag=>"uff_type_#{i}", :action=>action_proc))
+ subitems = p.map { |pp| UFFParams[pp][0] }
+ uff_idx = subitems.index(utypes[i]) || 0
+ type_selects.push(item(:popup, :subitems=>p.map { |pp| UFFParams[pp][0] }, :tag=>"uff_type_#{i}", :action=>action_proc, :value=>uff_idx))
end
}
bond_orders = []
)
}
if hash[:status] == 0
+ 3.times { |i|
+ idx = indices[i]
+ next unless idx
+ ii = uff_types[i][hash["uff_type_#{i}"].to_i]
+ puts "i = #{i}, idx = #{idx}, ii = #{ii}, UFFParams[ii][0] = #{UFFParams[ii][0].inspect}"
+ if ii
+ atoms[idx].uff_type = UFFParams[ii][0]
+ end
+ }
return hash["guessed"], current_value
else
return nil
MoleculeView::OnLeftDClickInListCtrl(wxMouseEvent &event)
{
listctrl->OnLeftDClick(event);
- if (mview->tableIndex >= kMainViewBondTableIndex && mview->tableIndex <= kMainViewImproperTableIndex && mview->mol->par != NULL) {
+ if (mview->tableIndex >= kMainViewBondTableIndex && mview->tableIndex <= kMainViewImproperTableIndex /* && mview->mol->par != NULL */ ) {
int row, col, i;
char indices[64], names[64], types[64], value[20], partypes[64], params[3][20];
char *ptype, *parstr;
MyAppCallback_errorMessageBox("%s is running: please stop it before closing", msg);
return false;
}
- return wxDocument::Close();
+ if (wxDocument::Close()) {
+ /* Send a message that this document will close */
+ wxCommandEvent myEvent(MyDocumentEvent, MyDocumentEvent_documentWillClose);
+ myEvent.SetEventObject(this);
+ ProcessEvent(myEvent);
+ return true;
+ } else return false;
}
void
MyDocument::OnInvokeAntechamber(wxCommandEvent &event)
{
char *ante_dir, buf[256];
- Int net_charge, i, n, calc_charge, use_residue;
+ Int net_charge, i, n, calc_charge, optimize_structure, use_residue, guess_atom_types;
int status;
/* Find the ambertool directory */
if ((status = MyAppCallback_getGlobalSettingsWithType("antechamber.nc", 'i', &net_charge))
|| (status = MyAppCallback_getGlobalSettingsWithType("antechamber.calc_charge", 'i', &calc_charge))
+ || (status = MyAppCallback_getGlobalSettingsWithType("antechamber.optimize_structure", 'i', &optimize_structure))
+ || (status = MyAppCallback_getGlobalSettingsWithType("antechamber.guess_atom_types", 'i', &guess_atom_types))
|| (status = MyAppCallback_getGlobalSettingsWithType("antechamber.use_residue", 'i', &use_residue))) {
Molby_showError(status);
return;
{
/* Run antechamber and parmck */
char *p;
+ int j_option = 4;
/* Set AMBERHOME environment variable if necessary */
n = strlen(ante_dir);
}
if (calc_charge) {
- snprintf(buf, sizeof buf, "-nc %d -c bcc", net_charge);
+ snprintf(buf, sizeof buf, "-nc %d -c bcc %s", net_charge,
+ (optimize_structure ? "" : " -ek 'maxcyc=0'"));
} else buf[0] = 0;
- asprintf(&p, "\"%s/antechamber\" -i mol.pdb -fi pdb -o mol.ac -fo ac %s", ante_dir, buf);
+ if (!guess_atom_types) {
+ j_option = 0;
+ }
+
+ asprintf(&p, "\"%s/antechamber\" -i mol.pdb -fi pdb -o mol.ac -fo ac -j %d %s", ante_dir, j_option, buf);
status = MyAppCallback_callSubProcess(p, "antechamber", NULL, NULL);
if (status != 0) {
MyAppCallback_errorMessageBox("Antechamber failed: status = %d.", status);
- } else {
+ } else if (guess_atom_types) {
asprintf(&p, "\"%s/parmchk\" -i mol.ac -f ac -o frcmod", ante_dir);
status = MyAppCallback_callSubProcess(p, "parmchk", NULL, NULL);
if (status != 0)
if (status == 0) {
wxString acfile = tdir + wxFileName::GetPathSeparator() + _T("mol.ac");
- status = MolActionCreateAndPerform(mol, SCRIPT_ACTION("s"), "import_ac", (const char *)acfile.mb_str(wxConvFile));
+ status = MolActionCreateAndPerform(mol, SCRIPT_ACTION("sii"), "import_ac", (const char *)acfile.mb_str(wxConvFile), calc_charge, guess_atom_types);
if (status != 0) {
MyAppCallback_errorMessageBox("Cannot import antechamber output.");
}
}
}
- if (status == 0) {
+ if (guess_atom_types && status == 0) {
wxString frcmodfile = tdir + wxFileName::GetPathSeparator() + _T("frcmod");
status = MolActionCreateAndPerform(mol, SCRIPT_ACTION("s"), "import_frcmod", (const char *)frcmodfile.mb_str(wxConvFile));
if (status != 0) {
if (doc && !doc->isModifyNotificationSent) {
doc->isModifyNotificationSent = true;
wxCommandEvent myEvent(MyDocumentEvent, MyDocumentEvent_documentModified);
+ myEvent.SetEventObject(doc);
if (now_flag)
doc->ProcessEvent(myEvent);
else
MyDocumentEvent_updateDisplay,
MyDocumentEvent_insertFrameFromMD,
MyDocumentEvent_threadTerminated,
- MyDocumentEvent_openFilesByIPC
+ MyDocumentEvent_openFilesByIPC,
+ MyDocumentEvent_documentWillClose
};
class MyDocument: public wxDocument
#include "RubyDialogFrame.h"
#include "MyApp.h"
#include "MyMBConv.h"
+#include "MyDocument.h"
BEGIN_EVENT_TABLE(RubyDialogFrame, wxDialog)
EVT_TIMER(-1, RubyDialogFrame::OnTimerEvent)
dval = NULL;
mySize = gZeroSize;
autoResizeEnabled = true;
-
+ messageData = NULL;
+ countMessageData = 0;
+
// Create a vertical box sizer that contains a panel containing all controls and a sizer containing
// OK/Cancel buttons
contentSizer = new wxBoxSizer(wxVERTICAL);
RubyDialogFrame::~RubyDialogFrame()
{
+ int i;
if (myTimer != NULL)
delete myTimer;
if (ditems != NULL)
free(ditems);
+ for (i = 0; i < countMessageData; i++) {
+ if (messageData[i * 5] != NULL) {
+ ((wxEvtHandler *)messageData[i * 5])->Disconnect((int)messageData[i * 5 + 1], (wxEventType)messageData[i * 5 + 2], wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent));
+ }
+ }
}
int
RubyDialog_doTimerAction((RubyValue)dval);
}
+static void
+sResizeSubWindows(RubyValue dval, wxWindow *win, int dx, int dy)
+{
+ wxWindowList & children = win->GetChildren();
+ wxWindowList::Node *node;
+ for (node = children.GetFirst(); node; node = node->GetNext()) {
+ int i, d, f, d1, d2, d3, ddx, ddy;
+ wxWindow *current = (wxWindow *)node->GetData();
+ wxRect frame = current->GetRect();
+ int flex = RubyDialog_getFlexFlags(dval, (RDItem *)current);
+ if (flex < 0)
+ continue;
+ for (i = 0, f = flex; i < 2; i++, f /= 2) {
+ if (i == 0)
+ d = dx;
+ else
+ d = dy;
+ switch (f & 21) { /* left, right, width (or top, bottom, height) */
+ case 21: /* all flex */
+ d1 = d2 = d / 3;
+ d3 = d - d1 - d2;
+ break;
+ case 5: /* left & right */
+ d1 = d / 2;
+ d2 = 0;
+ d3 = d - d1;
+ break;
+ case 17: /* left & width */
+ d1 = d / 2;
+ d2 = d - d1;
+ d3 = 0;
+ break;
+ case 20: /* right & width */
+ d1 = 0;
+ d2 = d / 2;
+ d3 = d - d2;
+ break;
+ case 1: /* left */
+ d1 = d;
+ d2 = d3 = 0;
+ break;
+ case 4: /* right */
+ d3 = d;
+ d1 = d2 = 0;
+ break;
+ case 16: /* width */
+ d2 = d;
+ d1 = d3 = 0;
+ break;
+ }
+ if (i == 0) {
+ frame.x += d1;
+ frame.width += d2;
+ ddx = d2;
+ } else {
+ frame.y += d1;
+ frame.height += d2;
+ ddy = d2;
+ }
+ }
+ if (ddx != 0 || ddy != 0)
+ sResizeSubWindows(dval, current, ddx, ddy);
+ current->SetSize(frame);
+ }
+}
+
void
RubyDialogFrame::OnSize(wxSizeEvent &event)
{
wxSize size = GetClientSize();
if (mySize.width != 0 && mySize.height != 0 && /*(mySize.width != size.x || mySize.height != size.y) &&*/ autoResizeEnabled) {
/* Resize the subviews */
- int i;
- for (i = 2; i < nditems; i++) {
- RDItem *item = ditems[i];
- int glue = RubyDialog_getFlexFlags((RubyValue)dval, item);
- if (glue >= 0) {
- RDRect frame = RubyDialogCallback_frameOfItem(item);
- switch (glue & 5) {
- case 5: /* left & right */
- frame.size.width += size.x - mySize.width;
- break;
- case 4: /* right */
- frame.origin.x += size.x - mySize.width;
- break;
- }
- switch (glue & 10) {
- case 10: /* top & bottom */
- frame.size.height += size.y - mySize.height;
- break;
- case 8: /* bottom */
- frame.origin.y += size.y - mySize.height;
- break;
- }
- RubyDialogCallback_setFrameOfItem(item, frame);
- } else if (wxDynamicCast((wxWindow *)item, wxPanel) != NULL) {
- wxWindowList & children = ((wxWindow *)item)->GetChildren();
- wxWindowList::Node *node;
- wxRect thisRect, origRect, thatRect;
- int count = 0, dx, dy;
- origRect = ((wxWindow *)item)->GetRect();
- for (node = children.GetFirst(); node; node = node->GetNext(), count++) {
- wxWindow *current = (wxWindow *)node->GetData();
- thatRect = current->GetRect();
- if (count == 0) {
- thisRect = thatRect;
- continue;
- }
- if (thisRect.x > thatRect.x) {
- thisRect.width += thisRect.x - thatRect.x;
- thisRect.x = thatRect.x;
- }
- if (thisRect.y > thatRect.y) {
- thisRect.height += thisRect.y - thatRect.y;
- thisRect.y = thatRect.y;
- }
- if (thatRect.x + thatRect.width > thisRect.x + thisRect.width)
- thisRect.width = thatRect.x + thatRect.width - thisRect.x;
- if (thatRect.y + thatRect.height > thisRect.y + thisRect.height)
- thisRect.height = thatRect.y + thatRect.height - thisRect.y;
- }
- /* Resize the view, while keeping the subviews at the same window position */
- dx = thisRect.x;
- dy = thisRect.y;
- for (node = children.GetFirst(); node; node = node->GetNext()) {
- wxWindow *current = (wxWindow *)node->GetData();
- thatRect = current->GetRect();
- current->Move(thatRect.x - dx, thatRect.y - dy);
- }
- origRect.x += dx;
- origRect.y += dy;
- origRect.width = thisRect.width;
- origRect.height = thisRect.height;
- ((wxWindow *)item)->SetSize(origRect);
- }
- }
+ sResizeSubWindows((RubyValue)dval, this, size.x - mySize.width, size.y - mySize.height);
}
mySize.width = size.x;
mySize.height = size.y;
event.Skip();
}
+int
+RubyDialogFrame::ListenToObject(void *obj, const char *objtype, const char *msg, RubyValue oval, RubyValue pval)
+{
+ int i, j, eventId;
+ wxEventType eventType;
+ wxEvtHandler *handler;
+ if (strcmp(objtype, "Molecule") == 0) {
+ eventType = MyDocumentEvent;
+ handler = MyDocumentFromMolecule((Molecule *)obj);
+ if (handler == NULL)
+ return -1; /* obj is not an event handler */
+ if (msg == NULL)
+ eventId = -1;
+ else if (strcmp(msg, "documentModified") == 0)
+ eventId = MyDocumentEvent_documentModified;
+ else if (strcmp(msg, "documentWillClose") == 0)
+ eventId = MyDocumentEvent_documentWillClose;
+ else return -2; /* this event type is not supported */
+ } else return -1;
+
+ if (pval == NULL || pval == RubyNil) {
+ /* Remove the registration */
+ for (i = 0; i < countMessageData; i++) {
+ if (messageData[i * 5] == (void *)handler &&
+ messageData[i * 5 + 1] == (void *)eventId &&
+ messageData[i * 5 + 2] == (void *)eventType) {
+ handler->Disconnect(eventId, eventType, wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent));
+ break;
+ }
+ }
+ if (i == countMessageData)
+ return -3; /* No such message */
+ messageData[i * 5] = NULL;
+ return i;
+ } else {
+ /* Check the duplicate */
+ j = countMessageData; /* The position to store info if it is new */
+ for (i = 0; i < countMessageData; i++) {
+ if (messageData[i * 5] == (void *)handler &&
+ messageData[i * 5 + 1] == (void *)eventId &&
+ messageData[i * 5 + 2] == (void *)eventType) {
+ /* Just replace the arguments */
+ messageData[i * 5 + 3] = (void *)oval;
+ messageData[i * 5 + 4] = (void *)pval;
+ break;
+ }
+ if (messageData[i * 5] == NULL)
+ j = i;
+ }
+ if (i == countMessageData) {
+ /* Register the data and establish a new connection */
+ if (j == countMessageData) {
+ /* Create a new entry */
+ InsertArray(&messageData, &countMessageData, sizeof(void *) * 5, i, 1, NULL);
+ }
+ messageData[j * 5] = (void *)handler;
+ messageData[j * 5 + 1] = (void *)eventId;
+ messageData[j * 5 + 2] = (void *)eventType;
+ messageData[j * 5 + 3] = (void *)oval;
+ messageData[j * 5 + 4] = (void *)pval;
+ handler->Connect(eventId, eventType, wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent), NULL, this);
+ i = j;
+ }
+ return i;
+ }
+}
+
+void
+RubyDialogFrame::HandleDocumentEvent(wxCommandEvent &event)
+{
+ int i;
+ int eventId = event.GetId();
+ int eventType = event.GetEventType();
+ wxObject *eventObject = event.GetEventObject();
+
+ /* Look up the message table */
+ for (i = 0; i < countMessageData; i++) {
+ if (messageData[i * 5] == (void *)eventObject &&
+ messageData[i * 5 + 1] == (void *)eventId &&
+ messageData[i * 5 + 2] == (void *)eventType) {
+ int status;
+ RubyValue oval = (RubyValue)messageData[i * 5 + 3];
+ RubyValue pval = (RubyValue)messageData[i * 5 + 4];
+ Ruby_funcall2_protect_extern(pval, g_RubyID_call, 1, &oval, &status);
+/* if (status != 0) {
+ Molby_showError(status);
+ } */
+ }
+ }
+ event.Skip();
+}
+
#pragma mark ====== MyListCtrlDataSource methods ======
int
return ((RubyDialogFrame *)dref)->IsAutoResizeEnabled();
}
+int
+RubyDialogCallback_Listen(RubyDialog *dref, void *obj, const char *objtype, const char *msg, RubyValue oval, RubyValue pval)
+{
+ return ((RubyDialogFrame *)dref)->ListenToObject(obj, objtype, msg, oval, pval);
+}
+
void
RubyDialogCallback_createStandardButtons(RubyDialog *dref, const char *oktitle, const char *canceltitle)
{
RDSize mySize; /* Previous size */
bool autoResizeEnabled; /* true if auto resizing is enabled */
+ /* Message bridge (with Ruby world); obj, objtype, msg, pval */
+ void **messageData;
+ Int countMessageData;
+
RubyDialogFrame(wxWindow* parent, wxWindowID wid, const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE);
virtual ~RubyDialogFrame();
void SetAutoResizeEnabled(int flag) { autoResizeEnabled = (flag != 0); }
bool IsAutoResizeEnabled() { return autoResizeEnabled; }
+ int ListenToObject(void *obj, const char *objtype, const char *msg, RubyValue oval, RubyValue pval);
+ void HandleDocumentEvent(wxCommandEvent &event);
+
int AddDialogItem(RDItem *item);
RDItem *DialogItemAtIndex(int index);
int SearchDialogItem(RDItem *item);