revisionInfo.txt
latest_binaries
Documents/MolbyDoc/
+JANPA/*.jar
+
--- /dev/null
+Software License for JANPA package of programs
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+All advertising and/or published materials mentioning features or use
+of this software must display the following acknowledgement:
+
+This product includes components from JANPA package of programs
+( http://janpa.sourceforge.net/) developed by Tymofii Nikolaienko
+
+Neither the name of the developer, Tymofii Nikolaienko, nor the
+names of its contributors may be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+In case if any results obtained with JANPA package of programs are
+published, the following citations for the JANPA package of programs
+should be given:
+
+1) T. Yu. Nikolaienko, L. A. Bulavin; Localized orbitals for optimal
+decomposition of molecular properties, Int. J. Quantum Chem. (2019),
+Vol. 119, page e25798, DOI: 10.1002/qua.25798
+2) T.Y.Nikolaienko, L.A.Bulavin, D.M.Hovorun; JANPA: an open source
+cross-platform implementation of the Natural Population Analysis on the
+Java platform, Comput.Theor.Chem.(2014), V.1050, P.15-22,
+DOI: 10.1016/j.comptc.2014.10.002 , http://janpa.sourceforge.net
+
+THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL Tymofii Nikolaienko BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
cp -r ../bitmaps/bitmaps $(DESTPREFIX)/$(PRODUCT_DIR)
cp -r amber11 $(DESTPREFIX)/$(PRODUCT_DIR)
cp -r ortep3 $(DESTPREFIX)/$(PRODUCT_DIR)
+ cp -r ../JANPA $(DESTPREFIX)/$(PRODUCT_DIR)
cp -r ../Documents/MolbyDoc $(DESTPREFIX)/$(PRODUCT_DIR)
mkdir -p $(DESTPREFIX)/$(PRODUCT_DIR)/Scripts/lib
for i in $(RUBY_EXTLIB); do cp $(RUBY_DIR)/lib/$$i $(DESTPREFIX)/$(PRODUCT_DIR)/Scripts/lib; done
VALUE save_interruptFlag;
int n, exitstatus, pid;
char *sout, *serr;
+ const char *pnamestr;
FILE *fpout, *fperr;
rb_scan_args(argc, argv, "23", &cmd, &procname, &cproc, &stdout_val, &stderr_val);
}
save_interruptFlag = s_SetInterruptFlag(self, Qnil);
- n = MyAppCallback_callSubProcess(StringValuePtr(cmd), StringValuePtr(procname), (cproc == Qnil ? NULL : s_Kernel_CallSubProcess_Callback), (cproc == Qnil ? NULL : (void *)cproc), fpout, fperr, &exitstatus, &pid);
+ if (procname != Qnil)
+ pnamestr = StringValuePtr(procname);
+ else pnamestr = NULL;
+ n = MyAppCallback_callSubProcess(StringValuePtr(cmd), pnamestr, (cproc == Qnil ? NULL : s_Kernel_CallSubProcess_Callback), (cproc == Qnil ? NULL : (void *)cproc), fpout, fperr, &exitstatus, &pid);
s_SetInterruptFlag(self, save_interruptFlag);
if (fpout != NULL && fpout != (FILE *)1)
name2 = "Pre-orthogonal Natural Hybrid Orbitals"
elsif key2 == "PNBO"
name2 = "Pre-orthogonal Natural Bond Orbitals"
+ elsif key2 == "AHO"
+ name2 = "Atomic Hybrid Orbitals"
+ elsif key2 == "LHO"
+ name2 = "Localized Hybrid Orbitals"
+ elsif key2 == "LPO"
+ name2 = "Localized Property-optimized Orbitals"
+ elsif key2 == "CLPO"
+ name2 = "Chemist's Localized Property-optimized Orbitals"
end
mo_ao_items.push(name2)
mo_ao_keys.push(key2)
fp.print "# Generated by Molby at #{now}\n"
fp.print "import sys\n"
fp.print "import re\n"
+ fp.print "base = re.sub('\\.\\w*$', '', sys.argv[1]) # Basename of the input file\n"
fp.print "molecule mol {\n"
charge = Integer(hash["charge"])
mult = Integer(hash["mult"])
end
runtype = hash['runtype'].downcase
fp.print "energy, wfn = #{runtype}('scf', #{options})\n"
- fp.print "wfn.write_molden(re.sub('\\.\\w*$', '.molden', sys.argv[1]))\n"
+ fp.print "wfn.write_molden(f'{base}.molden')\n"
+ if hash['run_junpa'] != 0
+ fp.print "\n"
+ fp.print "# Interface for JANPA\n"
+ fp.print "# cf. https://sourceforge.net/p/janpa/wiki/psi4Examples/\n"
+ fp.print "d = wfn.Da().to_array()\n"
+ fp.print "s = wfn.S().to_array()\n"
+ fp.print "c = wfn.Ca().to_array()\n"
+ fp.print "occs = c.T.dot(s.dot(d).dot(s).dot(c))\n"
+ fp.print "molden(wfn, f'{base}.da.molden', density_a = psi4.core.Matrix.from_array(occs))\n"
+ end
end
if fname == nil
s = fp.buffer
end
end
+ # Execute JUNPA
+ # inppath is the input file minus extention
+ # mol is the molecule (may be nil)
+ def Molecule.execute_janpa(inppath, mol, spherical)
+ # nbo_desc = # JANPA
+ janpa_dir = "#{ResourcePath}/JANPA"
+ status = 0
+ if spherical
+ cmd1 = "java -jar #{janpa_dir}/molden2molden.jar -NormalizeBF -i #{inppath}.da.molden -o #{inppath}.in.molden >#{inppath}.janpa.log"
+ else
+ cmd1 = "java -jar #{janpa_dir}/molden2molden.jar -frompsi4v1mo -NormalizeBF -cart2pure -i #{inppath}.da.molden -o #{inppath}.in.molden >#{inppath}.janpa.log"
+ end
+ flag = system(cmd1)
+ if flag
+ cmd2 = "java -jar #{janpa_dir}/janpa.jar -i #{inppath}.in.molden"
+ ["nao", "pnao", "aho", "lho", "lpo", "clpo"].each { |type|
+ if (get_global_settings("psi4.#{type}").to_i != 0)
+ cmd2 += " -#{type.upcase}_Molden_File #{inppath}.#{type.upcase}.molden"
+ end
+ }
+ cmd2 += " >>#{inppath}.janpa.log"
+ flag = system(cmd2)
+ end
+ if flag
+ if mol
+ # import JANPA log and molden output
+ # Files: inppath.japa.log, inppath.{NAO,PNAO,AHO,LHO,LPO,CLPO}.molden
+ mol.sub_load_janpa_log(inppath)
+ end
+ else
+ status = $?.exitstatus
+ message_box("Execution of #{procname} failed with status #{status}.", "JANPA Failed")
+ end
+ return status
+ end
+
# Execute Psi4
# inpname is the input file
# mol (optional) is the molecule from which the Psi4 input was built.
hf_type = nil
nalpha = nil
nbeta = nil
+ spherical = false
outfile = inpdir + "/" + inpbody + ".out"
if File.exists?(outfile)
nalpha = Integer($1)
elsif line =~ /^ *Nbeta *= *(\d+)/
nbeta = Integer($1)
+ elsif line =~ /^ *Spherical Harmonics\?: *(\w+)/
+ spherical = ($1 == "true")
end
end
if next_index > 0
# Terminate callback
term_callback = lambda { |m, n|
+ do_janpa = false
begin
msg = "Psi4 execution of #{inpbase} "
hmsg = "Psi4 "
$stderr.write("#{e.backtrace.inspect}\n")
end
end
+ if (get_global_settings("psi4.run_janpa").to_i == 1)
+ do_janpa = true
+ end
elsif n == -1
# The child process actually did not start
# Restore the old file if outbackfile is not nil
if outbackfile && File.exists?(outbackfile)
File.delete(outbackfile)
end
+ if do_janpa
+ Molecule.execute_janpa(inpdir + "/" + inpbody, mol, spherical)
+ end
rescue => e
$stderr.write("#{e.message}\n")
$stderr.write("#{e.backtrace.inspect}\n")
dfttype_desc = ["B3LYP"]
runtype_desc = ["Energy", "Optimize"]
scftype_desc = ["RHF", "ROHF", "UHF"]
-# nbo_desc = ["nao", "nbo", "nho", "nlmo", "pnao", "pnbo", "pnho", "pnlmo"]
+ nbo_desc = ["nao", "pnao", "aho", "lho", "lpo", "clpo"] # JANPA
user_input = Hash.new
defaults = {"scftype"=>0, "runtype"=>0, "move_to_com"=>0, "do_reorient"=>0,
"use_symmetry"=>0, "charge"=>"0", "mult"=>"1",
#item(:line),
#-1, -1, -1,
# ------
- #item(:checkbox, :title=>"Include NBO instructions", :tag=>"include_nbo",
- # :action=>lambda { |it|
- # flag = (it[:value] != 0)
- # nbos.each { |nbo| set_attr(nbo, :enabled=>flag) }
- # }),
- #-1, -1, -1,
+ item(:checkbox, :title=>"Run JANPA after Psi4", :tag=>"run_janpa",
+ :action=>lambda { |it|
+ flag = (it[:value] != 0)
+ nbo_desc.each { |nbo| set_attr(nbo, :enabled=>flag) }
+ }),
+ -1, -1, -1,
# ------
- #item(:checkbox, :title=>"NAO", :tag=>"nao"),
- #item(:checkbox, :title=>"NBO", :tag=>"nbo"),
- #item(:checkbox, :title=>"NHO", :tag=>"nho"),
- #item(:checkbox, :title=>"NLMO", :tag=>"nlmo"),
+ item(:checkbox, :title=>"NAO", :tag=>"nao"),
+ item(:checkbox, :title=>"PNAO", :tag=>"pnao"),
+ item(:checkbox, :title=>"AHO", :tag=>"aho"),
+ item(:checkbox, :title=>"LHO", :tag=>"lho"),
# ------
- #item(:checkbox, :title=>"PNAO", :tag=>"pnao"),
- #item(:checkbox, :title=>"PNBO", :tag=>"pnbo"),
- #item(:checkbox, :title=>"PNHO", :tag=>"pnho"),
- #item(:checkbox, :title=>"PNLMO", :tag=>"pnlmo"),
+ item(:checkbox, :title=>"LPO", :tag=>"lpo"),
+ item(:checkbox, :title=>"CLPO", :tag=>"clpo"),
+ -1, -1,
# ------
item(:line),
-1, -1, -1,
end
# mol.set_mo_info should be set before calling this function
- def sub_load_molden(fp)
+ # Optional label is for importing JANPA output: "NAO" or "CPLO"
+ # If label is not nil, then returns a hash containing the following key/value pairs:
+ # :atoms => an array of [element_symbol, seq_num, atomic_num, x, y, z] (angstrom)
+ # :gto => an array of an array of [sym, [ex0, c0, ex1, c1, ...]]
+ # :moinfo => an array of [sym, energy, spin (0 or 1), occ]
+ # :mo => an array of [c0, c1, ...]
+ def sub_load_molden(fp, label = nil)
getline = lambda { @lineno += 1; return fp.gets }
bohr = 0.529177210903
errmsg = nil
ncomps = 0 # Number of components (AOs)
occ_alpha = 0 # Number of occupied alpha orbitals
occ_beta = 0 # Number of occupied beta orbitals
+ if label
+ hash = Hash.new
+ end
catch :ignore do
while line = getline.call
if line =~ /^\[Atoms\]/
if line =~ /^[A-Z]/
# element, index, atomic_number, x, y, z (in AU)
a = line.split(' ')
- if atoms[i].atomic_number != Integer(a[2]) ||
- (atoms[i].x - Float(a[3]) * bohr).abs > 1e-4 ||
- (atoms[i].y - Float(a[4]) * bohr).abs > 1e-4 ||
- (atoms[i].z - Float(a[5]) * bohr).abs > 1e-4
- errmsg = "The atom list does not match the current molecule."
- throw :ignore
+ if label
+ (hash[:atoms] ||= []).push([a[0], Integer(a[1]), Integer(a[2]), Float(a[3]) * bohr, Float(a[4]) * bohr, Float(a[5]) * bohr])
+ else
+ if atoms[i].atomic_number != Integer(a[2]) ||
+ (atoms[i].x - Float(a[3]) * bohr).abs > 1e-4 ||
+ (atoms[i].y - Float(a[4]) * bohr).abs > 1e-4 ||
+ (atoms[i].z - Float(a[5]) * bohr).abs > 1e-4
+ errmsg = "The atom list does not match the current molecule."
+ throw :ignore
+ end
end
i += 1
else
elsif line =~ /^\[GTO\]/
shell = 0
atom_index = 0
+ if label
+ gtos = []
+ hash[:gto] = []
+ end
while line = getline.call
# index, 0?
a = line.split(' ')
raise MolbyError, "Unknown gaussian shell type '#{a[0]}' at line #{@lineno} in MOLDEN file"
end
nprimitives = Integer(a[1])
+ if label
+ gtoline = [sym, []]
+ gtos.push(gtoline)
+ end
nprimitives.times { |i|
line = getline.call # exponent, contraction
b = line.split(' ')
+ if label
+ gtoline[1].push(Float(b[0]), Float(b[1]))
+ end
add_gaussian_primitive_coefficients(Float(b[0]), Float(b[1]), 0.0)
}
# end of one shell
- add_gaussian_orbital_shell(atom_index, sym, nprimitives)
+ if label == nil
+ add_gaussian_orbital_shell(atom_index, sym, nprimitives)
+ end
shell += 1
ncomps += n
end
# end of one atom
atom_index += 1
+ if label
+ hash[:gto].push(gtos)
+ end
end
redo # The next line will be the beginning of the next block
elsif line =~ /^\[MO\]/
m = []
idx_alpha = 1 # set_mo_coefficients() accepts 1-based index of MO
idx_beta = 1
+ if label
+ hash[:mo] = []
+ hash[:moinfo] = []
+ end
while true
# Loop for each MO
m.clear
occ_beta += 1
end
end
+ if label
+ hash[:moinfo].push([sym, ene, (spin == "Alpha" ? 0 : 1), occ])
+ end
elsif line =~ /^ *([0-9]+) +([-+.0-9e]+)/
m[i] = Float($2)
i += 1
idx_beta += 1
end
set_mo_coefficients(idx, ene, m)
+ if label
+ hash[:mo].push(m.dup)
+ end
break
end
else
end # end catch
if errmsg
message_box("The MOLDEN file was found but not imported. " + errmsg, "Psi4 import info", :ok)
- return false
+ return (label ? nil : false)
end
- return true
+ return (label ? hash : true)
end
-
+
+ # Import the JANPA log and related molden files
+ # Files: inppath.{NAO.molden,CLPO.molden,janpa.log}
+ def sub_load_janpa_log(inppath)
+ begin
+ fp = File.open(inppath + ".janpa.log", "rt") rescue fp = nil
+ if fp == nil
+ message_box("Cannot open JANPA log file #{inppath + '.janpa.log'}: " + $!.to_s)
+ return false
+ end
+ print("Importing #{inppath}.janpa.log.\n")
+ lineno = 0
+ getline = lambda { lineno += 1; return fp.gets }
+ h = Hash.new
+ mfiles = Hash.new
+ while line = getline.call
+ if line =~ /^NAO \#/
+ h["NAO"] = []
+ while line = getline.call
+ break if line !~ /^\s*[1-9]/
+ num = Integer(line[0, 5])
+ name = line[5, 21]
+ occ = Float(line[26, 11])
+ # like A1*: R1*s(0)
+ # atom_number, occupied?, shell_number, orb_sym, angular_number
+ name =~ /\s*[A-Z]+([0-9]+)(\*?):\s* R([0-9]+)\*([a-z]+)\(([-0-9]+)\)/
+ anum = Integer($1)
+ occupied = $2
+ shell_num = Integer($3)
+ orb_sym = $4
+ ang_num = Integer($5)
+ h["NAO"].push([num, anum, occupied, shell_num, orb_sym, ang_num, occ])
+ end
+ elsif line =~ /^\s*CLPO\s+D e s c r i p t i o n\s+Occupancy\s+Composition/
+ h["CLPO"] = []
+ while line = getline.call
+ break if line =~ /^\s*$/
+ num = Integer(line[0, 5])
+ label1 = line[5, 6].strip
+ desc = line[11, 30].strip
+ desc =~ /\s*([-A-Za-z0-9]+)(,\s*(.*$))?/
+ desc1 = $1
+ desc2 = ($3 || "")
+ if desc2 =~ /^(.*)*\(NB\)\s*$/ && label1 == ""
+ label1 = "(NB)"
+ desc2 = $1.strip
+ end
+ # like ["(BD)", "C1-H3", "Io = 0.2237"]
+ h["CLPO"][num - 1] = [label1, desc1, desc2]
+ end
+ elsif line =~ /^ -NAO_Molden_File: (\S*)/
+ mfiles["NAO"] = $1
+ elsif line =~ /^ -LHO_Molden_File: (\S*)/
+ mfiles["LHO"] = $1
+ elsif line =~ /^ -CLPO_Molden_File: (\S*)/
+ mfiles["CLPO"] = $1
+ elsif line =~ /^ -PNAO_Molden_File: (\S*)/
+ mfiles["PNAO"] = $1
+ elsif line =~ /^ -AHO_Molden_File: (\S*)/
+ mfiles["AHO"] = $1
+ elsif line =~ /^ -LPO_Molden_File: (\S*)/
+ mfiles["LPO"] = $1
+ end
+ end
+ fp.close
+ # Read molden files
+ mfiles.each { |key, value|
+ fp = Kernel.open(value, "rt") rescue fp = nil
+ if fp
+ print("Importing #{value}.\n")
+ res = sub_load_molden(fp, key)
+ if res
+ # Some kind of orbital based on AO
+ h["AO/#{key}"] = LAMatrix.new(res[:mo])
+ end
+ fp.close
+ end
+ }
+ @nbo = h
+ return true
+ rescue => e
+ $stderr.write(e.message + "\n")
+ $stderr.write(e.backtrace.inspect + "\n")
+ end
+ end
+
def loadout(filename)
retval = false
fp = open(filename, "rb")
retval = sub_load_psi4_log(fp)
if retval
# If .molden file exists, then try to read it
- mname = filename.gsub(/\.\w*$/, ".molden")
+ namepath = filename.gsub(/\.\w*$/, "")
+ mname = "#{namepath}.molden"
if File.exists?(mname)
fp2 = open(mname, "rb")
if fp2
flag = sub_load_molden(fp2)
fp2.close
+ status = (flag ? 0 : -1)
end
end
+ if File.exists?("#{namepath}.janpa.log")
+ flag = sub_load_janpa_log(namepath)
+ status = (flag ? 0 : -1)
+ end
end
break
end
E4059FDD28C46A6E0052B36B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4FC7A16183E51570064FB2E /* Foundation.framework */; };
E4059FDE28C46A6E0052B36B /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4FC7B58183E53710064FB2E /* WebKit.framework */; };
E4059FDF28C46A6E0052B36B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4FC7CAC183F953E0064FB2E /* AudioToolbox.framework */; };
+ E40C8B3328E85322003CE26E /* JANPA in Resources */ = {isa = PBXBuildFile; fileRef = E40C8B3228E8522F003CE26E /* JANPA */; };
+ E40C8B3428E85357003CE26E /* JANPA in Resources */ = {isa = PBXBuildFile; fileRef = E40C8B3228E8522F003CE26E /* JANPA */; };
E41251B828CD92A100E12983 /* MyListCtrl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41251B728CD92A100E12983 /* MyListCtrl.cpp */; };
E41A7F962307D61200C65830 /* bitmaps in Resources */ = {isa = PBXBuildFile; fileRef = E41A7F952307D61200C65830 /* bitmaps */; };
E420BDEF1885746700A2B983 /* ConsoleFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E420BDE81885746700A2B983 /* ConsoleFrame.cpp */; };
E403568828D0C8C4008E2C46 /* textctrl_msw.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = textctrl_msw.cpp; sourceTree = "<group>"; };
E4059FE428C46A6E0052B36B /* MolbyMacLegacy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MolbyMacLegacy.app; sourceTree = BUILT_PRODUCTS_DIR; };
E4059FE628C46B320052B36B /* Molby_MacLegacy-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Molby_MacLegacy-Info.plist"; sourceTree = "<group>"; };
+ E40C8B3228E8522F003CE26E /* JANPA */ = {isa = PBXFileReference; lastKnownFileType = folder; name = JANPA; path = ../JANPA; sourceTree = "<group>"; };
E41251B728CD92A100E12983 /* MyListCtrl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MyListCtrl.cpp; sourceTree = "<group>"; };
E41251BA28CD92AD00E12983 /* MyListCtrl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyListCtrl.h; sourceTree = "<group>"; };
E4196C65190B2FA500183E62 /* menu.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = menu.mm; sourceTree = "<group>"; };
E4ACACE418C6D32300F08B67 /* ortep3 */,
E4FC7C16183E54730064FB2E /* Molby-Info.plist */,
E4059FE628C46B320052B36B /* Molby_MacLegacy-Info.plist */,
+ E40C8B3228E8522F003CE26E /* JANPA */,
);
name = Resources;
sourceTree = "<group>";
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ E40C8B3328E85322003CE26E /* JANPA in Resources */,
E4FC7F821840C22B0064FB2E /* molby_icon.icns in Resources */,
E4FC77D7183E4FFE0064FB2E /* Scripts in Resources */,
E4FC7802183E503E0064FB2E /* amber11 in Resources */,
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ E40C8B3428E85357003CE26E /* JANPA in Resources */,
E4059F9B28C46A6E0052B36B /* molby_icon.icns in Resources */,
E4059F9C28C46A6E0052B36B /* Scripts in Resources */,
E4059F9D28C46A6E0052B36B /* amber11 in Resources */,
bool progress_panel = false;
char buf[256];
wxString cmdstr(cmdline, WX_DEFAULT_CONV);
- wxLongLong startTime;
+ wxLongLong startTime, lastTime, presentTime;
if (m_process != NULL)
return -1; // Another process is already running (CallSubProcess() allows only one subprocess)
ShowProgressPanel(buf);
progress_panel = true;
}
- startTime = wxGetUTCTimeMillis();
+ startTime = lastTime = wxGetUTCTimeMillis();
// Create log file in the document home directory
#if LOG_SUBPROCESS
wxString bufstr;
wxString buferrstr;
while (1) {
- int len1 = m_process->GetLine(bufstr);
- if (len1 > 0) {
+ int len1, len2;
+ lastTime = wxGetUTCTimeMillis();
+ while ((len1 = m_process->GetLine(bufstr)) > 0) {
#if LOG_SUBPROCESS
dateTime.SetToCurrent();
fprintf(fplog, "%s[STDOUT]%s", (const char *)(dateTime.FormatISOCombined(' ')), (const char *)bufstr);
MyAppCallback_setConsoleColor(0);
MyAppCallback_showScriptMessage("%s", (const char *)bufstr);
}
+ presentTime = wxGetUTCTimeMillis();
+ if (presentTime > lastTime + 25) {
+ presentTime = lastTime;
+ break;
+ }
}
- int len2 = m_process->GetErrorLine(buferrstr);
- if (len2 > 0) {
+ while ((len2 = m_process->GetErrorLine(buferrstr)) > 0) {
#if LOG_SUBPROCESS
dateTime.SetToCurrent();
fprintf(fplog, "%s[STDERR]%s", (const char *)(dateTime.FormatISOCombined(' ')), buf);
MyAppCallback_showScriptMessage("\n%s", (const char *)buferrstr);
MyAppCallback_setConsoleColor(0);
}
+ presentTime = wxGetUTCTimeMillis();
+ if (presentTime > lastTime + 25) {
+ presentTime = lastTime;
+ break;
+ }
}
-
if (len1 < 0 && len2 < 0) {
// The standard/error outputs are exhausted; the process should have terminated
// (Normally, this should be detected by wxBetterProcess::OnTerminate())
if (callback_result != 0)
interrupted = true;
}
+ ::wxSafeYield(); // This allows updating console and wxProcess status
if (progress_panel) {
SetProgressValue(-1);
if (IsInterrupted())
interrupted = true;
- } else {
- ::wxSafeYield(); // This allows updating console and wxProcess status
}
#if LOG_SUBPROCESS