--- /dev/null
+From 9c4d46b8007f85fa4d7c6c285c1c64a766d4001e Mon Sep 17 00:00:00 2001
+From: W. Trevor King <wking@drexel.edu>
+Date: Tue, 21 Oct 2008 19:53:51 -0400
+Subject: [PATCH] Updated wxWindows code to compile on wx-2.8.
+
+Most of the difficulties were caused by wxString no longer being
+interchangable with c strings and stdlib strings. I also cleaned
+up the logging code a bit.
+---
+ src/fs_align_aspectrum.cpp | 19 ++--
+ src/fs_align_aspectrumvector.cpp | 15 +--
+ src/fs_align_clusterdriver.cpp | 24 +++---
+ src/fs_fit_fitfrontend.cpp | 18 ++--
+ src/fs_fit_model.cpp | 26 +++---
+ src/fs_fit_spectrum.cpp | 73 ++++++++------
+ src/fs_gui.wxg | 16 ++--
+ src/fs_gui_app.cpp | 3 +-
+ src/fs_gui_layout.cpp | 204 ++++++++++++++++++++------------------
+ src/fs_gui_layout.h | 14 ++-
+ src/fs_kit_driver.cpp | 73 +++++++++-----
+ src/fs_kit_options.cpp | 6 +-
+ src/fs_kit_options.h | 10 +--
+ 13 files changed, 272 insertions(+), 229 deletions(-)
+
+diff --git a/src/fs_align_aspectrum.cpp b/src/fs_align_aspectrum.cpp
+index 1528449..22f04e0 100644
+--- a/src/fs_align_aspectrum.cpp
++++ b/src/fs_align_aspectrum.cpp
+@@ -64,7 +64,8 @@ bool fs_align::ASpectrumFile::loadDataFromStream(string path, istream& list_inpu
+
+ if (list_filename.empty() || peaks.empty()) return false;
+
+- if (options.logLevel >= 4) { ostringstream log; log << "loading file " << path << filename << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 4)
++ *options.stdOut << "loading file " << path << filename << endl;
+
+ // load data into matrix
+ FILE* f = fopen( (path + filename).c_str(), "r");
+@@ -131,7 +132,8 @@ bool fs_align::ASpectrumFile::loadDataFromStream(string path, istream& list_inpu
+ string s, t;
+ double max_tss;
+ info_input >> s >> t >> min_tss >> max_tss;
+- if (options.logLevel >= 4) { ostringstream log; log << "reading peak info " << s << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 4)
++ *options.stdOut << "reading peak info " << s << endl;
+ info_input >> s;
+ while (s != "end") { info_input >> t >> max_tss >> s; }
+
+@@ -215,7 +217,8 @@ bool fs_align::ASpectrumFile::loadPeaksFromStream(istream& fit_input)
+ fit_input >> filename >> xname >> status;
+ }
+
+- if (options.logLevel >= 2) { ostringstream log; log << "reading peaks " << filename << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 2)
++ *options.stdOut << "reading peaks " << filename << endl;
+
+ // store baseline data
+ fit_input >> bl_sd >> bl_mintss >> bl_mintss_sd >> bl_a >> bl_a_sd >> bl_b >> bl_b_sd;
+@@ -340,12 +343,10 @@ fs_align::SpectrumDistance* fs_align::ASpectrum::overlaySpectrum(ASpectrum& s)
+ }
+
+ if (options.logLevel >= 5)
+- {
+- ostringstream log; log << "overlap: " << getName() << " and " << s.getName() <<
+- ": score " << maxscore / sqrt(1.0*nx*s.nx) << ", shift " <<
+- options.alignPointDistance * maxshift + min_tss - s.min_tss << endl;
+- *options.stdOut << log.str().c_str();
+- }
++ *options.stdOut << "overlap: " << getName() << " and " << s.getName()
++ << ": score " << maxscore / sqrt(1.0*nx*s.nx)
++ << ", shift " << options.alignPointDistance * maxshift + min_tss - s.min_tss
++ << endl;
+
+ SpectrumDistance* dist = new SpectrumDistance(this, &s, maxscore / sqrt(1.0*(nx*s.nx)), options.alignPointDistance * maxshift + min_tss - s.min_tss);
+
+diff --git a/src/fs_align_aspectrumvector.cpp b/src/fs_align_aspectrumvector.cpp
+index 887f350..7f2ff3a 100644
+--- a/src/fs_align_aspectrumvector.cpp
++++ b/src/fs_align_aspectrumvector.cpp
+@@ -13,21 +13,18 @@ fs_align::ASpectrumVector::ASpectrumVector(Options& options)
+ ifstream fit_input(fit_filename.c_str());
+ ifstream info_input(info_filename.c_str());
+
+- if (!list_input)
+- {
+- ostringstream log; log << "ERROR: Could not find file " << list_filename << endl; *options.stdOut << log.str().c_str();
++ if (!list_input) {
++ *options.stdOut << "ERROR: Could not find file " << list_filename << endl;
+ return;
+ }
+
+- if (!fit_input)
+- {
+- ostringstream log; log << "ERROR: Could not find file " << info_filename << endl; *options.stdOut << log.str().c_str();
++ if (!fit_input) {
++ *options.stdOut << "ERROR: Could not find file " << info_filename << endl;
+ return;
+ }
+
+- if (!info_input)
+- {
+- ostringstream log; log << "ERROR: Could not find file " << fit_filename << endl; *options.stdOut << log.str().c_str();
++ if (!info_input) {
++ *options.stdOut << "ERROR: Could not find file " << fit_filename << endl;
+ return;
+ }
+
+diff --git a/src/fs_align_clusterdriver.cpp b/src/fs_align_clusterdriver.cpp
+index 170edfa..48c323a 100644
+--- a/src/fs_align_clusterdriver.cpp
++++ b/src/fs_align_clusterdriver.cpp
+@@ -14,9 +14,7 @@ void fs_align::ClusterDriver::doClustering()
+ const int n_dist = ssv.size() * (ssv.size() - 1) / 2;
+
+ if (options.logLevel >= 1)
+- {
+- { ostringstream log; log << "computing " << n_dist << " pairwise distances" << endl; *options.stdOut << log.str().c_str(); }
+- }
++ *options.stdOut << "computing " << n_dist << " pairwise distances" << endl;
+
+ time_t start_time = time(0);
+ bool first = true;
+@@ -38,15 +36,13 @@ void fs_align::ClusterDriver::doClustering()
+ double dt = difftime(time(0), start_time);
+ const int f = (ssv.size() - 1);
+
+- { ostringstream log; log << "calculated " << f << " distances in " << dt << " seconds" << endl; *options.stdOut << log.str().c_str(); }
+- { ostringstream log; log << "est. remaining time for distance calculation: " << dt * n_dist / f << " seconds" << endl; *options.stdOut << log.str().c_str(); }
++ *options.stdOut << "calculated " << f << " distances in " << dt << " seconds" << endl;
++ *options.stdOut << "est. remaining time for distance calculation: " << dt * n_dist / f << " seconds" << endl;
+ }
+ }
+
+ if (options.logLevel >= 1)
+- {
+- { ostringstream log; log << "distances have been calculated; clustering..." << endl; *options.stdOut << log.str().c_str(); }
+- }
++ *options.stdOut << "distances have been calculated; clustering..." << endl;
+
+
+ dlist.sort(cmpSpectrumDistancePtr());
+@@ -62,7 +58,8 @@ void fs_align::ClusterDriver::doClustering()
+ ASpectrumCluster *nc = new ASpectrumCluster(lowest, options);
+ ssv.push_back(nc);
+
+- if (options.logLevel >= 4) { ostringstream log; log << "best overlap: " << lowest->oa->getName() << "\t" << lowest->ob->getName() << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 4)
++ *options.stdOut << "best overlap: " << lowest->oa->getName() << "\t" << lowest->ob->getName() << endl;
+
+ *tree << nc->getNumber() << " " << -lowest->score << endl;
+
+@@ -132,7 +129,8 @@ void fs_align::ClusterDriver::alignSpectra()
+
+ shift /= n;
+
+- if (options.logLevel >= 4) { ostringstream log; log << "shifting spectra by " << shift << " to center alignment" << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 4)
++ *options.stdOut << "shifting spectra by " << shift << " to center alignment" << endl;
+
+ // add average alignment shift to all spectra
+ // in result, average alignment shift is zero
+@@ -142,11 +140,13 @@ void fs_align::ClusterDriver::alignSpectra()
+ // as soon as we encounter a cluster, break loop
+ if (s->isCluster()) break;
+
+- if (options.logLevel >= 4) { ostringstream log; log << s->getShift(); *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 4)
++ *options.stdOut << s->getShift();
+
+ s->setShift(s->getShift() - shift);
+
+- if (options.logLevel >= 4) { ostringstream log; log << "\t" << s->getShift() << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 4)
++ *options.stdOut << "\t" << s->getShift() << endl;
+ }
+ }
+
+diff --git a/src/fs_fit_fitfrontend.cpp b/src/fs_fit_fitfrontend.cpp
+index b7a0db6..8931ebc 100644
+--- a/src/fs_fit_fitfrontend.cpp
++++ b/src/fs_fit_fitfrontend.cpp
+@@ -76,9 +76,11 @@ void fs_fit::FitFrontend::printHeader(ostream *o) {
+
+ Model *m = 0;
+ // model selection
+- if (options.model == "wlc") m = new wlcModel(max_peaks, options); else
+- if (options.model == "wlc_p") m = new wlcModel_p(max_peaks, options); else
+- ; // model not found but oh well
++ if (options.model == "wlc")
++ m = new wlcModel(max_peaks, options);
++ else if (options.model == "wlc_p")
++ m = new wlcModel_p(max_peaks, options);
++ // else // model not found but oh well
+
+ m->streamHeader(o);
+
+@@ -156,7 +158,7 @@ void fs_fit::FitFrontend::processSpectrum(string path, string filename, string x
+
+ *temp_output << "end" << endl;
+
+- { ostringstream log; log << "ERROR: " << filename << " -- " << e.getError() << endl; *options.stdOut << log.str().c_str(); }
++ *options.stdOut << "ERROR: " << filename << " -- " << e.getError() << endl;
+ }
+
+ string result = temp_output->str();
+@@ -190,7 +192,9 @@ void fs_fit::FitFrontend::processFit() try {
+ count++;
+ }
+
+- if (options.logLevel >= 1) { ostringstream log; log << "processed " << count << " spectra" << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 1) {
++ *options.stdOut << "processed " << count << " spectra" << endl;
++ }
+
+ printHeader(output_fitting);
+ for (list<string>::iterator it = output_buffer.begin(); it != output_buffer.end(); it++)
+@@ -202,9 +206,9 @@ void fs_fit::FitFrontend::processFit() try {
+
+ }
+ catch (fs_fitInitException& e) {
+- { ostringstream log; log << "ERROR: An error occured during initialization. No spectra are processed:" << endl << e.getError() << endl; *options.stdOut << log.str().c_str(); }
++ *options.stdOut << "ERROR: An error occured during initialization. No spectra are processed:" << endl << e.getError() << endl;
+ }
+ catch (fs_fitException& e) {
+- { ostringstream log; log << "ERROR: " << e.getError() << endl; *options.stdOut << log.str().c_str(); }
++ *options.stdOut << "ERROR: " << e.getError() << endl;
+ }
+
+diff --git a/src/fs_fit_model.cpp b/src/fs_fit_model.cpp
+index 1461c08..2d56f3d 100644
+--- a/src/fs_fit_model.cpp
++++ b/src/fs_fit_model.cpp
+@@ -156,16 +156,12 @@ void fs_fit::Model::printSolverState(int iter, gsl_multifit_fdfsolver *solver)
+ {
+ if (options.logLevel < 3) return;
+
+- { ostringstream log; log << "it: " << setw(3) << iter << " fit: "; *options.stdOut << log.str().c_str(); }
++ *options.stdOut << "it: " << setw(3) << iter << " fit: ";
+
+ for (size_t i = 0; i < getFitParams(); i++)
+- {
+- { ostringstream log; log << setw(8) << gsl_vector_get(solver->x, i); *options.stdOut << log.str().c_str(); }
+- }
+-
+- { ostringstream log; log << " |f(x)| = " << setw(8) << gsl_blas_dnrm2 (solver->f); *options.stdOut << log.str().c_str(); }
++ *options.stdOut << setw(8) << gsl_vector_get(solver->x, i);
+
+- { ostringstream log; log << endl; *options.stdOut << log.str().c_str(); }
++ *options.stdOut << " |f(x)| = " << setw(8) << gsl_blas_dnrm2 (solver->f) << endl;
+
+ }
+
+@@ -183,8 +179,8 @@ void fs_fit::Model::printFunction(gsl_multifit_fdfsolver *solver)
+ {
+ for (int pos = it->getStart(); pos < it->getEnd(); pos++)
+ {
+- { ostringstream log; log << setw(10) << gsl_vector_get(data->tss, pos) << "\t" << setw(10) << gsl_vector_get(data->force, pos) << setw(10) << "\t" << gsl_vector_get(solver->f, xpos) + gsl_vector_get(data->force, pos) << endl; *options.stdOut << log.str().c_str(); }
+- xpos++;
++ *options.stdOut << setw(10) << gsl_vector_get(data->tss, pos) << "\t" << setw(10) << gsl_vector_get(data->force, pos) << setw(10) << "\t" << gsl_vector_get(solver->f, xpos) + gsl_vector_get(data->force, pos) << endl;
++ xpos++;
+ }
+ mpos++;
+ }
+@@ -266,7 +262,8 @@ string fs_fit::Model::fitData(const double merge_threshold) throw(fs_fitExceptio
+ throw fs_fitFitException(s.str(),"sc_no_peaks");
+ }
+
+- if (delete_last > 0 && options.logLevel >= 3) { ostringstream log; log << "deleting last " << delete_last << "peak(s) with high countour length..." << endl; *options.stdOut << log.str().c_str(); }
++ if (delete_last > 0 && options.logLevel >= 3)
++ *options.stdOut << "deleting last " << delete_last << "peak(s) with high countour length..." << endl;
+
+ // check if peaks are too close to each other, if so, they will be merged
+ // (peaks will be merged pairwise)
+@@ -275,7 +272,8 @@ string fs_fit::Model::fitData(const double merge_threshold) throw(fs_fitExceptio
+ for (size_t i = getCommonParams(); i < getFitParams() - (delete_last + 1) * getPeakParams(); i += getPeakParams())
+ if (gsl_vector_get(solver->x,i+getPeakParams()) - gsl_vector_get(solver->x,i) < merge_threshold) { merge_peaks++; i += getPeakParams(); }
+
+- if (options.logLevel >= 3) { ostringstream log; log << "merging " << merge_peaks << " peaks..." << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << "merging " << merge_peaks << " peaks..." << endl;
+
+ if (merge_peaks > 0 || delete_last > 0)
+ {
+@@ -342,7 +340,8 @@ string fs_fit::Model::fitData(const double merge_threshold) throw(fs_fitExceptio
+ {
+ // no peaks to merge, therefore: finish fitting
+
+- if (options.logLevel >= 3) { ostringstream log; log << gsl_strerror(status) << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << gsl_strerror(status) << endl;
+
+ // determine covariance matrix, assign parameters and parameter standard deviation
+ gsl_matrix *covar = gsl_matrix_alloc(getFitParams(), getFitParams());
+@@ -356,7 +355,8 @@ string fs_fit::Model::fitData(const double merge_threshold) throw(fs_fitExceptio
+ for (size_t i=0; i<getFitParams(); i++)
+ {
+ gsl_vector_set(params_sd, i, sqrt(gsl_matrix_get(covar, i, i)));
+- if (options.logLevel >= 3) { ostringstream log; log << setw(10) << gsl_vector_get(solver->x, i) << setw(10) << gsl_vector_get(params_sd, i) << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << setw(10) << gsl_vector_get(solver->x, i) << setw(10) << gsl_vector_get(params_sd, i) << endl;
+ }
+
+ printFunction(solver);
+diff --git a/src/fs_fit_spectrum.cpp b/src/fs_fit_spectrum.cpp
+index 1e295b8..8cffd5e 100644
+--- a/src/fs_fit_spectrum.cpp
++++ b/src/fs_fit_spectrum.cpp
+@@ -75,7 +75,8 @@ void fs_fit::Spectrum::loadFromASCIIFile(string path, string filename, int datap
+ {
+ if (datapoints != -1) this->datapoints = datapoints;
+
+- if (options.logLevel >= 2) { ostringstream log; log << "loading file " << path << filename << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 2)
++ *options.stdOut << "loading file " << path << filename << endl;
+
+ rawpoints = getNumberOfFields(filename);
+
+@@ -142,7 +143,8 @@ void fs_fit::Spectrum::loadFromASCIIFile(string path, string filename, int datap
+
+ // cout << filename << "\t" << datapoints << "\t" << data->force << endl;
+
+- if (options.logLevel >= 3) { ostringstream log; log << rawpoints << " points have been read, tss moved by " << -data->bl_mintss << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << rawpoints << " points have been read, tss moved by " << -data->bl_mintss << endl;
+ }
+
+ void fs_fit::Spectrum::reducePoints(double min_tss, double max_tss)
+@@ -206,7 +208,8 @@ void fs_fit::Spectrum::reducePoints(double min_tss, double max_tss)
+ // cout << t_avg << "\t" << f_avg << "\t" << sqrt(sd / (n_smooth - 1)) << endl;
+ }
+
+- if (options.logLevel >= 3) { ostringstream log; log << rawpoints << " points have been reduced to " << points << " points"<< endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << rawpoints << " points have been reduced to " << points << " points"<< endl;
+ }
+
+ double fs_fit::Spectrum::fractionBaseline(double fraction)
+@@ -229,11 +232,11 @@ double fs_fit::Spectrum::fractionBaseline(double fraction)
+ data->bl_asd = sqrt(cov00);
+ data->bl_bsd = sqrt(cov11);
+
+- if (options.logLevel >= 3) { ostringstream log; log << "baseline fit: " << setw(5) << fraction
+- << " [" << gsl_vector_get(data->tss,start) << ", " << gsl_vector_get(data->tss,points-1) << "] "
+- << " -- y = " << data->bl_a << " + x * " << data->bl_b <<
+- " -- sd = " << data->bl_sd << endl;
+- *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << "baseline fit: " << setw(5) << fraction
++ << " [" << gsl_vector_get(data->tss,start) << ", " << gsl_vector_get(data->tss,points-1) << "] "
++ << " -- y = " << data->bl_a << " + x * " << data->bl_b
++ << " -- sd = " << data->bl_sd << endl;
+
+ return data->bl_sd;
+ }
+@@ -256,12 +259,14 @@ double fs_fit::Spectrum::fullSpectrumSD()
+
+ double bl_sd = sqrt(chisq/(n-1));
+
+- if (options.logLevel >= 3) { ostringstream log; log << "baseline fit to all points: "
+- << setw(5) << data->bl_fraction
+- << " [" << gsl_vector_get(data->rawtss,start) << ", " << gsl_vector_get(data->rawtss,rawpoints-1) << "] "
+- << " -- y = " << bl_a << " + x * " << bl_b <<
+- " -- sd = " << bl_sd << endl;
+- *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << "baseline fit to all points: "
++ << setw(5) << data->bl_fraction
++ << " [" << gsl_vector_get(data->rawtss,start)
++ << ", " << gsl_vector_get(data->rawtss,rawpoints-1)
++ << "] "
++ << " -- y = " << bl_a << " + x * " << bl_b
++ << " -- sd = " << bl_sd << endl;
+
+ data->full_sd = bl_sd;
+
+@@ -303,7 +308,8 @@ double fs_fit::Spectrum::iterativeBaseline(const double guess, const double incr
+ // check if baseline is too long
+ if (errorNotAttached()) { throw fs_fitFitException("no attachment","no_attachment"); }
+ if (warnNotAttached()) {
+- if (options.logLevel >= 2) { ostringstream log; log << "WARNING: over 50% of the spectrum are baseline" << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 2)
++ *options.stdOut << "WARNING: over 50% of the spectrum are baseline" << endl;
+ }
+
+ return sd;
+@@ -380,12 +386,12 @@ void fs_fit::Spectrum::refineBaseline(const double mintss)
+ /*data->bl_asd = sqrt(cov00);
+ data->bl_bsd = sqrt(cov11);
+ */
+- if (options.logLevel >= 3) { ostringstream log; log << "refining baseline: " << setw(5) << fitpoints << " -- y = " << p_a << " + x * " << p_b <<
++ if (options.logLevel >= 3) {
++ *options.stdOut << "refining baseline: " << setw(5) << fitpoints << " -- y = " << p_a << " + x * " << p_b <<
+ " -- sd = " << p_sd << endl;
+- *options.stdOut << log.str().c_str(); }
+- if (options.logLevel >= 3) { ostringstream log; log << " best: " << setw(5) << min_pts << " -- y = " << min_a << " + x * " << min_b <<
++ *options.stdOut << " best: " << setw(5) << min_pts << " -- y = " << min_a << " + x * " << min_b <<
+ " -- sd = " << min_sd << endl;
+- *options.stdOut << log.str().c_str(); }
++ }
+
+ gsl_vector_free(extbl_x);
+ gsl_vector_free(extbl_y);
+@@ -404,7 +410,8 @@ void fs_fit::Spectrum::subtractBaseline()
+ data->rawforce->data[i] -= data->bl_a + data->bl_b * data->rawtss->data[j];
+ }
+
+- if (options.logLevel >= 3) { ostringstream log; log << "baseline subtracted: y = " << data->bl_a << " + x * " << data->bl_b << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << "baseline subtracted: y = " << data->bl_a << " + x * " << data->bl_b << endl;
+ }
+
+ int fs_fit::Spectrum::initChunks(double sd_factor, double minforce, double mintss)
+@@ -416,9 +423,9 @@ int fs_fit::Spectrum::initChunks(double sd_factor, double minforce, double mints
+ // init number of condensed points -- is incremented by createChunk
+ data->fit_points = 0;
+
+- if (options.logLevel >= 3) { ostringstream log; log << "dividing spectrum in chunks, peak threshold: " << threshold <<
+- " pN, minimal peak force " << minforce << " pN, minimal tip-sample separation: " << mintss << " nm. " << endl;
+- *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << "dividing spectrum in chunks, peak threshold: " << threshold <<
++ " pN, minimal peak force " << minforce << " pN, minimal tip-sample separation: " << mintss << " nm. " << endl;
+
+ // skip non-specific interactions -- start scanning mintss nm after smallest tss
+ size_t start = 1;
+@@ -545,12 +552,14 @@ void fs_fit::Spectrum::createChunk(int start, int end, double minforce, double m
+ data->chunks.push_back(c);
+ data->fit_points += c.getPoints();
+
+- if (options.logLevel >= 3) { ostringstream log; log << "new chunk " << c.getFirst() << " -- " << c.getLast() << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << "new chunk " << c.getFirst() << " -- " << c.getLast() << endl;
+ }
+
+ void fs_fit::Spectrum::adjustZeroTSS() throw (fs_fitFitException)
+ {
+- if (options.logLevel >= 3) { ostringstream log; log << "Detecting contact point." << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << "Detecting contact point." << endl;
+
+ const double max_force = 2 * data->full_sd;
+ const double range = 1 * data->full_sd;
+@@ -609,17 +618,17 @@ void fs_fit::Spectrum::adjustZeroTSS() throw (fs_fitFitException)
+ data->bl_mintss += shift;
+ data->bl_mintss_sd = sd;
+
+- if (options.logLevel >= 3) { ostringstream log; log << "shifted by " << shift << " nm" << endl; *options.stdOut << log.str().c_str(); }
++ if (options.logLevel >= 3)
++ *options.stdOut << "shifted by " << shift << " nm" << endl;
+
+ gsl_vector_add_constant(data->rawtss, -shift);
+ }
+
+ void fs_fit::Spectrum::streamDataPoints(ostream* o)
+ {
+- for (size_t i = 0; i < points; i++)
+- { ostringstream log; log << gsl_vector_get(data->tss, i)
+- << "\t" << gsl_vector_get(data->force, i)
+- << "\t" << gsl_vector_get(data->force_sd, i)
+- << "\t" << gsl_vector_get(data->weight, i) << endl;
+- *options.stdOut << log.str().c_str(); }
++ for (size_t i = 0; i < points; i++)
++ *options.stdOut << gsl_vector_get(data->tss, i)
++ << "\t" << gsl_vector_get(data->force, i)
++ << "\t" << gsl_vector_get(data->force_sd, i)
++ << "\t" << gsl_vector_get(data->weight, i) << endl;
+ }
+diff --git a/src/fs_gui.wxg b/src/fs_gui.wxg
+index a8e6b17..4252552 100644
+--- a/src/fs_gui.wxg
++++ b/src/fs_gui.wxg
+@@ -1,7 +1,7 @@
+ <?xml version="1.0"?>
+-<!-- generated by wxGlade 0.3.1 on Mon Mar 22 12:06:10 2004 -->
++<!-- generated by wxGlade 0.6.3 on Tue Oct 21 14:05:03 2008 -->
+
+-<application path="D:\Micha\!afm\fskit\src\fs_gui_layout.h" name="" class="" option="0" language="C++" top_window="frame" encoding="ISO-8859-1" use_gettext="0" overwrite="0">
++<application path="fs_gui_layout.h" name="" class="" option="0" language="C++" top_window="frame" encoding="ISO-8859-1" use_gettext="0" overwrite="0" use_new_namespace="0" for_version="2.8" is_template="0">
+ <object class="guiFrame" name="frame" base="EditFrame">
+ <style>wxDEFAULT_FRAME_STYLE</style>
+ <title>fs_kit</title>
+@@ -99,10 +99,10 @@
+ <border>0</border>
+ <option>0</option>
+ <object class="wxButton" name="SettingsLoad" base="EditButton">
+- <tooltip>Load settings file</tooltip>
+ <label>Load...</label>
+- <focused>1</focused>
++ <tooltip>Load settings file</tooltip>
+ <id>ID_SET_OPEN</id>
++ <focused>1</focused>
+ </object>
+ </object>
+ <object class="sizeritem">
+@@ -184,8 +184,8 @@
+ <border>0</border>
+ <option>0</option>
+ <object class="wxButton" name="SpectraLoad" base="EditButton">
+- <tooltip>Load list of spectra filenames</tooltip>
+ <label>Load...</label>
++ <tooltip>Load list of spectra filenames</tooltip>
+ <id>ID_SPEC_OPEN</id>
+ </object>
+ </object>
+@@ -281,8 +281,8 @@
+ <border>0</border>
+ <option>0</option>
+ <object class="wxButton" name="SelectDir" base="EditButton">
+- <tooltip>Pick output directory</tooltip>
+ <label>Select...</label>
++ <tooltip>Pick output directory</tooltip>
+ <id>ID_SELECT_DIR</id>
+ </object>
+ </object>
+@@ -441,10 +441,10 @@
+ <border>0</border>
+ <option>0</option>
+ <object class="wxSpinCtrl" name="LogLevelCtrl" base="EditSpinCtrl">
+- <style>wxSP_ARROW_KEYS</style>
++ <style>wxSP_ARROW_KEYS|wxTE_AUTO_URL</style>
++ <id>ID_LOGLEVEL</id>
+ <range>-1, 5</range>
+ <value>0</value>
+- <id>ID_LOGLEVEL</id>
+ <size>40, -1</size>
+ </object>
+ </object>
+diff --git a/src/fs_gui_app.cpp b/src/fs_gui_app.cpp
+index b085cce..b83ebc6 100644
+--- a/src/fs_gui_app.cpp
++++ b/src/fs_gui_app.cpp
+@@ -27,8 +27,7 @@
+ bool BasicApplication::OnInit()
+ {
+ guiFrame *frame
+- = new guiFrame
+- (0, -1, "fs_gui");
++ = new guiFrame(0, -1, wxString("fs_gui", wxConvUTF8));
+
+ frame->Show(TRUE);
+ SetTopWindow(frame);
+diff --git a/src/fs_gui_layout.cpp b/src/fs_gui_layout.cpp
+index 3d928b7..a9dca2a 100644
+--- a/src/fs_gui_layout.cpp
++++ b/src/fs_gui_layout.cpp
+@@ -1,4 +1,4 @@
+-// -*- C++ -*- generated by wxGlade 0.3.1 on Sat Feb 14 18:44:55 2004
++// -*- C++ -*- generated by wxGlade 0.6.3 on Tue Oct 21 13:38:33 2008
+ // DO NOT EDIT BETWEEN "begin wxGlade" AND "end wxGlade"
+
+ /* fs_kit
+@@ -19,9 +19,10 @@
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+-
++
+ #ifdef fs_gui_wxwidgets
+
++#include "fs_kit_options.h"
+ #include "fs_gui_layout.h"
+
+ enum {
+@@ -54,61 +55,66 @@ BEGIN_EVENT_TABLE(guiFrame, wxFrame)
+ EVT_SPINCTRL (ID_LOGLEVEL, guiFrame::OnLogLevel)
+ END_EVENT_TABLE()
+
++// begin wxGlade: ::extracode
++// end wxGlade
++
++
++
+ guiFrame::guiFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
+ wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE)
+ {
+ // begin wxGlade: guiFrame::guiFrame
+- notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, 0);
+- notebook_pane_2 = new wxPanel(notebook, -1);
+- notebook_log = new wxPanel(notebook, -1);
+- borderpanel = new wxPanel(this, -1);
+- middlepanel = new wxPanel(this, -1);
+- toppanel = new wxPanel(this, -1);
++ notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
++ notebook_pane_2 = new wxPanel(notebook, wxID_ANY);
++ notebook_log = new wxPanel(notebook, wxID_ANY);
++ borderpanel = new wxPanel(this, wxID_ANY);
++ middlepanel = new wxPanel(this, wxID_ANY);
++ toppanel = new wxPanel(this, wxID_ANY);
+ frame_menubar = new wxMenuBar();
+- SetMenuBar(frame_menubar);
+ wxMenu* menu_file = new wxMenu();
+- menu_file->Append(wxNewId(), wxT("&Open settings"), wxT(""), wxITEM_NORMAL);
++ menu_file->Append(wxNewId(), wxT("&Open settings"), wxEmptyString, wxITEM_NORMAL);
+ menu_file->Append(ID_EXIT, wxT("E&xit"), wxT("Exit fs_gui"), wxITEM_NORMAL);
+ frame_menubar->Append(menu_file, wxT("File"));
+- frame_statusbar = CreateStatusBar(1);
+- lblSettings = new wxStaticText(toppanel, -1, wxT("Settings:"));
++ SetMenuBar(frame_menubar);
++ frame_statusbar = CreateStatusBar(1, 0);
++ lblSettings = new wxStaticText(toppanel, wxID_ANY, wxT("Settings:"));
+ const wxString SettingsCombo_choices[] = {
+- wxT("")
++ wxT("choice 1")
+ };
+- SettingsCombo = new wxComboBox(toppanel, -1, "", wxDefaultPosition, wxDefaultSize, 1, SettingsCombo_choices, wxCB_DROPDOWN);
++ SettingsCombo = new wxComboBox(toppanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 1, SettingsCombo_choices, wxCB_DROPDOWN);
+ SettingsLoad = new wxButton(toppanel, ID_SET_OPEN, wxT("Load..."));
+ SettingsSave = new wxButton(toppanel, ID_SET_SAVE , wxT("Save..."));
+ SettingsSaveAs = new wxButton(toppanel, ID_SET_SAVEAS, wxT("Save As..."));
+- lblSpectra = new wxStaticText(toppanel, -1, wxT("Spectra:"));
++ lblSpectra = new wxStaticText(toppanel, wxID_ANY, wxT("Spectra:"));
+ const wxString SpectraCombo_choices[] = {
+- wxT("")
++ wxT("choice 1")
+ };
+- SpectraCombo = new wxComboBox(toppanel, -1, "", wxDefaultPosition, wxDefaultSize, 1, SpectraCombo_choices, wxCB_DROPDOWN);
++ SpectraCombo = new wxComboBox(toppanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 1, SpectraCombo_choices, wxCB_DROPDOWN);
+ SpectraLoad = new wxButton(toppanel, ID_SPEC_OPEN, wxT("Load..."));
+- SpectraSave = new wxButton(toppanel, -1, wxT("Save..."));
+- SpectraSaveAs = new wxButton(toppanel, -1, wxT("Save As..."));
+- lblDirectory = new wxStaticText(toppanel, -1, wxT("Output directory:"));
++ SpectraSave = new wxButton(toppanel, wxID_ANY, wxT("Save..."));
++ SpectraSaveAs = new wxButton(toppanel, wxID_ANY, wxT("Save As..."));
++ lblDirectory = new wxStaticText(toppanel, wxID_ANY, wxT("Output directory:"));
+ const wxString OutputDirectoryCombo_choices[] = {
+- wxT("")
++ wxT("choice 1")
+ };
+- OutputDirectoryCombo = new wxComboBox(toppanel, -1, "", wxDefaultPosition, wxDefaultSize, 1, OutputDirectoryCombo_choices, wxCB_DROPDOWN);
++ OutputDirectoryCombo = new wxComboBox(toppanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 1, OutputDirectoryCombo_choices, wxCB_DROPDOWN);
+ SelectDir = new wxButton(toppanel, ID_SELECT_DIR, wxT("Select..."));
+- lblExpName = new wxStaticText(toppanel, -1, wxT("Experiment name:"));
++ lblExpName = new wxStaticText(toppanel, wxID_ANY, wxT("Experiment name:"));
+ const wxString ExperimentNameCombo_choices[] = {
+- wxT("")
++ wxT("choice 1")
+ };
+- ExperimentNameCombo = new wxComboBox(toppanel, -1, "", wxDefaultPosition, wxDefaultSize, 1, ExperimentNameCombo_choices, wxCB_DROPDOWN);
+- radioProcessSpectra = new wxRadioButton(toppanel, -1, wxT("Process Spectra:"));
+- chkFit = new wxCheckBox(toppanel, -1, wxT("Fit spectra"));
+- chkAlign = new wxCheckBox(toppanel, -1, wxT("Align spectra"));
+- chkSelect = new wxCheckBox(toppanel, -1, wxT("Select spectra"));
+- chkClassify = new wxCheckBox(toppanel, -1, wxT("Classify peaks"));
+- lblLogLevel = new wxStaticText(toppanel, -1, wxT("Log activty (-1 to 2 recommended):"));
+- LogLevelCtrl = new wxSpinCtrl(toppanel, ID_LOGLEVEL, "0", wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -1, 5);
+- LogLevelLbl = new wxStaticText(toppanel, -1, wxT("LogLevelLbl"));
++ ExperimentNameCombo = new wxComboBox(toppanel, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 1, ExperimentNameCombo_choices, wxCB_DROPDOWN);
++ radioProcessSpectra = new wxRadioButton(toppanel, wxID_ANY, wxT("Process Spectra:"));
++ chkFit = new wxCheckBox(toppanel, wxID_ANY, wxT("Fit spectra"));
++ chkAlign = new wxCheckBox(toppanel, wxID_ANY, wxT("Align spectra"));
++ chkSelect = new wxCheckBox(toppanel, wxID_ANY, wxT("Select spectra"));
++ chkClassify = new wxCheckBox(toppanel, wxID_ANY, wxT("Classify peaks"));
++ lblLogLevel = new wxStaticText(toppanel, wxID_ANY, wxT("Log activty (-1 to 2 recommended):"));
++ LogLevelCtrl = new wxSpinCtrl(toppanel, ID_LOGLEVEL, wxT("0"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxTE_AUTO_URL, -1, 5);
++ LogLevelLbl = new wxStaticText(toppanel, wxID_ANY, wxT("LogLevelLbl"));
+ Start = new wxButton(middlepanel, ID_START, wxT("Start"));
+- LogTextCtrl = new wxTextCtrl(notebook_log, ID_LOG_TEXTCTRL, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY);
+- label_1 = new wxStaticText(notebook_pane_2, -1, wxT("Currently, the following features are not implemented:\n\n- providing a history of previously selected settings, file names, etc\n- validating manual (keyboard) input \n"));
++ LogTextCtrl = new wxTextCtrl(notebook_log, ID_LOG_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY);
++ label_1 = new wxStaticText(notebook_pane_2, wxID_ANY, wxT("Currently, the following features are not implemented:\n\n- providing a history of previously selected settings, file names, etc\n- validating manual (keyboard) input \n"));
+
+ set_properties();
+ do_layout();
+@@ -120,8 +126,8 @@ guiFrame::guiFrame(wxWindow* parent, int id, const wxString& title, const wxPoin
+ SpectraCombo->Clear();
+ SettingsCombo->Clear();
+ OutputDirectoryCombo->Clear();
+-
+- wrapper = 0;
++
++ wrapper = 0;
+ }
+
+
+@@ -138,26 +144,26 @@ void guiFrame::set_properties()
+ for(int i = 0; i < frame_statusbar->GetFieldsCount(); ++i) {
+ frame_statusbar->SetStatusText(frame_statusbar_fields[i], i);
+ }
+- SettingsCombo->SetSize(wxSize(200, -1));
++ SettingsCombo->SetMinSize(wxSize(200, -1));
+ SettingsCombo->SetToolTip(wxT("Select settings file"));
+ SettingsCombo->SetSelection(0);
+ SettingsLoad->SetToolTip(wxT("Load settings file"));
+ SettingsLoad->SetFocus();
+- SpectraCombo->SetSize(wxSize(200, -1));
++ SpectraCombo->SetMinSize(wxSize(200, -1));
+ SpectraCombo->SetToolTip(wxT("Select list of spectra filenames"));
+ SpectraCombo->SetSelection(0);
+ SpectraLoad->SetToolTip(wxT("Load list of spectra filenames"));
+ SpectraSave->Enable(false);
+ SpectraSaveAs->Enable(false);
+- OutputDirectoryCombo->SetSize(wxSize(200, -1));
++ OutputDirectoryCombo->SetMinSize(wxSize(200, -1));
+ OutputDirectoryCombo->SetToolTip(wxT("Select output directory (empty: directory of settings file)"));
+ OutputDirectoryCombo->SetSelection(0);
+ SelectDir->SetToolTip(wxT("Pick output directory"));
+- ExperimentNameCombo->SetSize(wxSize(200, -1));
++ ExperimentNameCombo->SetMinSize(wxSize(200, -1));
+ ExperimentNameCombo->SetToolTip(wxT("Enter or select experiment name"));
+ ExperimentNameCombo->SetSelection(0);
+ radioProcessSpectra->SetValue(1);
+- LogLevelCtrl->SetSize(wxSize(40, -1));
++ LogLevelCtrl->SetMinSize(wxSize(40, -1));
+ Start->SetDefault();
+ // end wxGlade
+
+@@ -240,45 +246,30 @@ void guiFrame::do_layout()
+ topsizer->Add(20, 10, 0, 0, 0);
+ spacesizer->Add(topsizer, 0, wxEXPAND, 0);
+ spacesizer->Add(5, 20, 0, 0, 0);
+- toppanel->SetAutoLayout(true);
+ toppanel->SetSizer(spacesizer);
+- spacesizer->Fit(toppanel);
+- spacesizer->SetSizeHints(toppanel);
+ mainsizer->Add(toppanel, 0, wxEXPAND, 0);
+ middlesizer->Add(5, 20, 0, 0, 0);
+ middlesizer->Add(Start, 0, 0, 0);
+- middlepanel->SetAutoLayout(true);
+ middlepanel->SetSizer(middlesizer);
+- middlesizer->Fit(middlepanel);
+- middlesizer->SetSizeHints(middlepanel);
+ mainsizer->Add(middlepanel, 0, wxEXPAND, 0);
+ bordersizer->Add(20, 10, 0, 0, 0);
+- borderpanel->SetAutoLayout(true);
+ borderpanel->SetSizer(bordersizer);
+- bordersizer->Fit(borderpanel);
+- bordersizer->SetSizeHints(borderpanel);
+ mainsizer->Add(borderpanel, 0, wxEXPAND, 0);
+ sizer_1->Add(LogTextCtrl, 1, wxALL|wxEXPAND, 0);
+- notebook_log->SetAutoLayout(true);
+ notebook_log->SetSizer(sizer_1);
+- sizer_1->Fit(notebook_log);
+- sizer_1->SetSizeHints(notebook_log);
+ sizer_8->Add(label_1, 0, 0, 0);
+- notebook_pane_2->SetAutoLayout(true);
+ notebook_pane_2->SetSizer(sizer_8);
+- sizer_8->Fit(notebook_pane_2);
+- sizer_8->SetSizeHints(notebook_pane_2);
+ notebook->AddPage(notebook_log, wxT("Log"));
+ notebook->AddPage(notebook_pane_2, wxT("Read Me"));
+- mainsizer->Add(new wxNotebookSizer(notebook), 1, wxALL|wxEXPAND, 0);
+- SetAutoLayout(true);
++ mainsizer->Add(notebook, 1, wxALL|wxEXPAND, 0);
+ SetSizer(mainsizer);
+ mainsizer->Fit(this);
+- mainsizer->SetSizeHints(this);
+ Layout();
+ // end wxGlade
+ }
+
++
++
+ void guiFrame::OnLogFull(wxCommandEvent& event)
+ {
+ LogTextCtrl->Clear();
+@@ -286,7 +277,7 @@ void guiFrame::OnLogFull(wxCommandEvent& event)
+
+ wxString guiFrame::DescribeLogLevel(int level)
+ {
+- wxString s;
++ string s;
+
+ switch (level)
+ {
+@@ -329,7 +320,7 @@ wxString guiFrame::DescribeLogLevel(int level)
+
+ if (level > 3) s += " NOTE: Only use this when you process very few files. It's slow!";
+
+- return s;
++ return wxString(s.c_str(), wxConvUTF8);
+ }
+
+ void guiFrame::OnLogLevel(wxSpinEvent& event)
+@@ -351,14 +342,18 @@ void guiFrame::OnMenu(wxCommandEvent& event)
+ // load settings file
+ case ID_SET_OPEN:
+ {
+- wxFileDialog *fd = new wxFileDialog(this, "Choose a settings file",
+- "", "", "INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxOPEN);
++ wxFileDialog *fd = new wxFileDialog(this,
++ wxString("Choose a settings file", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxString("INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxConvUTF8),
++ wxOPEN);
+
+ if (fd->ShowModal() == wxID_OK)
+ {
+ SettingsCombo->SetValue(fd->GetPath());
+ readOptions();
+- LogTextCtrl->AppendText("Loaded settings file: " + fd->GetPath() + "\n");
++ LogTextCtrl->AppendText(wxString("Loaded settings file: ", wxConvUTF8) + fd->GetPath() + wxString("\n", wxConvUTF8));
+ }
+
+ delete fd;
+@@ -367,9 +362,13 @@ void guiFrame::OnMenu(wxCommandEvent& event)
+ // display save as dialog and fall through to actual saving
+ case ID_SET_SAVEAS:
+ {
+- wxFileDialog *fd = new wxFileDialog(this, "Save settings file as",
+- "", "", "INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxSAVE | wxOVERWRITE_PROMPT);
+-
++ wxFileDialog *fd = new wxFileDialog(this,
++ wxString("Save settings file as", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxString("INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxConvUTF8),
++ wxSAVE | wxOVERWRITE_PROMPT);
++
+ bool fall_through = false;
+ if (fd->ShowModal() == wxID_OK)
+ {
+@@ -384,10 +383,14 @@ void guiFrame::OnMenu(wxCommandEvent& event)
+ // save settings (fall through from above!)
+ case ID_SET_SAVE:
+ {
+- if (SettingsCombo->GetValue() == "") {
+-
+- wxFileDialog *fd = new wxFileDialog(this, "Save settings file as",
+- "", "", "INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxSAVE | wxOVERWRITE_PROMPT);
++ if (SettingsCombo->GetValue() == wxString("", wxConvUTF8)) {
++
++ wxFileDialog *fd = new wxFileDialog(this,
++ wxString("Save settings file as", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxString("INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxConvUTF8),
++ wxSAVE | wxOVERWRITE_PROMPT);
+
+ if (fd->ShowModal() == wxID_OK)
+ SettingsCombo->SetValue(fd->GetPath());
+@@ -395,27 +398,31 @@ void guiFrame::OnMenu(wxCommandEvent& event)
+ delete fd;
+ }
+
+- if (SettingsCombo->GetValue() == "") break;
++ if (SettingsCombo->GetValue() == wxString("", wxConvUTF8)) break;
+
+- ofstream out(SettingsCombo->GetValue());
+-
+- if (out) {
+- Options *options = new Options(encodeOptions(), LogTextCtrl);
+- options->printOptions(&out);
+- }
++ ofstream out(SettingsCombo->GetValue().mb_str());
+
++ if (out) {
++ Options *options = new Options(encodeOptions(), LogTextCtrl);
++ options->printOptions(&out);
++ }
++
+ break;
+ }
+ // load spectrum file
+ case ID_SPEC_OPEN:
+ {
+- wxFileDialog *fd = new wxFileDialog(this, "Choose a settings file",
+- "", "", "Filenames list (filenames.txt)|filenames.txt|Text files (*.txt)|*.txt|All files (*.*)|*.*", wxOPEN);
++ wxFileDialog *fd = new wxFileDialog(this,
++ wxString("Choose a settings file", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxString("INI Files (*.ini)|*.ini|All files (*.*)|*.*", wxConvUTF8),
++ wxOPEN);
+
+ if (fd->ShowModal() == wxID_OK)
+ {
+ SpectraCombo->SetValue(fd->GetPath());
+- LogTextCtrl->AppendText("Loaded filenames list: " + fd->GetPath() + "\n");
++ LogTextCtrl->AppendText(wxString("Loaded filenames list: ", wxConvUTF8) + fd->GetPath() + wxString("\n", wxConvUTF8));
+ }
+
+ delete fd;
+@@ -424,12 +431,15 @@ void guiFrame::OnMenu(wxCommandEvent& event)
+ // select output directory
+ case ID_SELECT_DIR:
+ {
+- wxDirDialog *dd = new wxDirDialog(this, "Choose an output directory", "", wxDD_NEW_DIR_BUTTON);
++ wxDirDialog *dd = new wxDirDialog(this,
++ wxString("Choose an output directory", wxConvUTF8),
++ wxString("", wxConvUTF8),
++ wxDD_NEW_DIR_BUTTON);
+
+ if (dd->ShowModal() == wxID_OK)
+ {
+ OutputDirectoryCombo->SetValue(dd->GetPath());
+- LogTextCtrl->AppendText("Selected output directory: " + dd->GetPath() + "\n");
++ LogTextCtrl->AppendText(wxString("Selected output directory: ", wxConvUTF8) + dd->GetPath() + wxString("\n", wxConvUTF8));
+ }
+
+ delete dd;
+@@ -440,15 +450,15 @@ void guiFrame::OnMenu(wxCommandEvent& event)
+ {
+ if (!wrapper)
+ {
+- Start->SetLabel("Stop");
++ Start->SetLabel(wxString("Stop", wxConvUTF8));
+ toppanel->Disable();
+- LogTextCtrl->AppendText("Started fs_kit computation\n");
++ LogTextCtrl->AppendText(wxString("Started fs_kit computation\n", wxConvUTF8));
+ wrapper = new GUIWrapper(encodeOptions(), LogTextCtrl);
+ wrapper->Run();
+ delete wrapper;
+ wrapper = 0;
+- LogTextCtrl->AppendText("Finished fs_kit computation\n");
+- Start->SetLabel("Start");
++ LogTextCtrl->AppendText(wxString("Finished fs_kit computation\n", wxConvUTF8));
++ Start->SetLabel(wxString("Start", wxConvUTF8));
+ toppanel->Enable();
+ }
+ else
+@@ -466,7 +476,7 @@ void guiFrame::readOptions()
+ {
+ // create options object
+ string o = "";
+- o += "-o \"" + SettingsCombo->GetValue() + "\"\n";
++ o += "-o \"" + std::string(SettingsCombo->GetValue().mb_str()) + "\"\n";
+ Options *options = new Options(o, LogTextCtrl);
+
+ chkAlign->SetValue(options->processAlign);
+@@ -474,13 +484,13 @@ void guiFrame::readOptions()
+ chkClassify->SetValue(options->processPC);
+ chkSelect->SetValue(options->processSelect);
+
+- SpectraCombo->SetValue(options->inputFileList.c_str());
++ SpectraCombo->SetValue(wxString(options->inputFileList.c_str(), wxConvUTF8));
+
+ LogLevelCtrl->SetValue(options->logLevel);
+ LogLevelLbl->SetLabel(DescribeLogLevel(LogLevelCtrl->GetValue()));
+
+ // split up experiment name into path and file name
+- wxFileName en = wxFileName(options->experimentName.c_str());
++ wxFileName en = wxFileName(wxString(options->experimentName.c_str(), wxConvUTF8));
+ OutputDirectoryCombo->SetValue(en.GetPath(wxPATH_GET_VOLUME));
+ ExperimentNameCombo->SetValue(en.GetName());
+
+@@ -492,7 +502,7 @@ string guiFrame::encodeOptions()
+ string o = "";
+
+ // settings file should be read at first, hence put it in front
+- o += "-o \"" + SettingsCombo->GetValue() + "\"\n";
++ o += "-o \"" + std::string(SettingsCombo->GetValue().mb_str()) + "\"\n";
+
+ // the following options will override those in the settings file
+ o += "-align " + string(chkAlign->IsChecked() ? "1" : "0") + "\n";
+@@ -502,19 +512,19 @@ string guiFrame::encodeOptions()
+
+ o += "-log_level " + Options::int2string(LogLevelCtrl->GetValue()) + "\n";
+
+- if (!SpectraCombo->GetValue().empty()) o += "-files_list \"" + SpectraCombo->GetValue() + "\"\n";
++ if (!SpectraCombo->GetValue().empty()) o += "-files_list \"" + std::string(SpectraCombo->GetValue().mb_str()) + "\"\n";
+ if (!ExperimentNameCombo->GetValue().empty())
+ {
+ o += "-experiment_name \"";
+
+ if (!OutputDirectoryCombo->GetValue().empty())
+ {
+- o += OutputDirectoryCombo->GetValue();
++ o += std::string(OutputDirectoryCombo->GetValue().mb_str());
+ if (OutputDirectoryCombo->GetValue().Last() != wxFileName::GetPathSeparator())
+ o += wxFileName::GetPathSeparator();
+- }
++ }
+
+- o += ExperimentNameCombo->GetValue() + "\"\n";
++ o += std::string(ExperimentNameCombo->GetValue().mb_str()) + "\"\n";
+ }
+
+ // "-log_level"
+@@ -525,5 +535,3 @@ string guiFrame::encodeOptions()
+ #endif // fs_gui_wxwidgets
+
+
+-
+-
+diff --git a/src/fs_gui_layout.h b/src/fs_gui_layout.h
+index b569bbc..c569ec0 100644
+--- a/src/fs_gui_layout.h
++++ b/src/fs_gui_layout.h
+@@ -1,4 +1,4 @@
+-// -*- C++ -*- generated by wxGlade 0.3.1 on Sat Feb 14 18:44:55 2004
++// -*- C++ -*- generated by wxGlade 0.6.3 on Tue Oct 21 13:38:33 2008
+ // DO NOT EDIT BETWEEN "begin wxGlade" AND "end wxGlade"
+
+ /* fs_kit
+@@ -31,11 +31,15 @@
+ #include <wx/notebook.h>
+ // end wxGlade
+
++
+ #ifndef FS_GUI_LAYOUT_H
+ #define FS_GUI_LAYOUT_H
+
+ #include "fs_gui_wrapper.h"
+
++// begin wxGlade: ::extracode
++// end wxGlade
++
+
+ class guiFrame: public wxFrame {
+ public:
+@@ -55,7 +59,7 @@ private:
+ void set_properties();
+ void do_layout();
+ // end wxGlade
+-
++
+ protected:
+ // begin wxGlade: guiFrame::attributes
+ wxMenuBar* frame_menubar;
+@@ -93,14 +97,14 @@ protected:
+ wxPanel* notebook_pane_2;
+ wxNotebook* notebook;
+ // end wxGlade
+-
++
+ GUIWrapper* wrapper;
+-
++
+ string encodeOptions();
+ void readOptions();
+
+ DECLARE_EVENT_TABLE()
+-};
++}; // wxGlade: end class
+
+
+ #endif // FS_GUI_LAYOUT_H
+diff --git a/src/fs_kit_driver.cpp b/src/fs_kit_driver.cpp
+index 1251e3e..d9df296 100644
+--- a/src/fs_kit_driver.cpp
++++ b/src/fs_kit_driver.cpp
+@@ -17,6 +17,7 @@
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
++#include "fs_kit_options.h" // logger
+ #include "fs_kit_driver.h"
+
+ int fs_driver::fsDriver::doRun () {
+@@ -30,60 +31,73 @@ int fs_driver::fsDriver::doRun () {
+ if (!options->processSP) {
+ if (options->processFit) {
+
+- if (options->logLevel >= 0) { ostringstream log; log << "process FIT ..."; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << "process FIT ...";
+
+ clock_t start = clock(), end;
+
+ fs_fit::FitFrontend fitfrontend(*options);
+ fitfrontend.processFit();
+-
++
+ end = clock();
+ const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
+- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl;
+ }
+
+ if (options->processAlign) {
+
+- if (options->logLevel >= 0) { ostringstream log; log << "process ALIGN ..."; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << "process ALIGN ...";
++
+
+ clock_t start = clock(), end;
+
+- if (options->logLevel >= 2) { ostringstream log; log << " initializing ..."; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 2)
++ *options->stdOut << " initializing ...";
+ fs_align::ClusterDriver acd(*options);
+- if (options->logLevel >= 2) { ostringstream log; log << " clustering spectra ..."; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 2)
++ *options->stdOut << " clustering spectra ...";
+ acd.doClustering();
+- if (options->logLevel >= 2) { ostringstream log; log << " aligning spectra ..."; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 2)
++ *options->stdOut << " aligning spectra ...";
+ acd.alignSpectra();
+- if (options->logLevel >= 2) { ostringstream log; log << " printing spectra ..."; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 2)
++ *options->stdOut << " printing spectra ...";
+ acd.printSpectra();
+
+ end = clock();
+ const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
+- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl;
+ }
+
+ // todo: the selection logic should be moved out to e.g. fs_select_driver
+ if (options->processSelect) {
+
+- if (options->logLevel >= 0) { ostringstream log; log << "process SELECT"; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << "process SELECT";
+
+ clock_t start = clock(), end;
+
+ fs_select::Tree t(*options);
+
+ double d = options->selectAvg * t.getAvg() + options->selectSD * t.getSD() + options->selectAbs;
+- if (options->logLevel >= 0) { ostringstream log; log << " (merge_distance: " << d << ") ..."; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << " (merge_distance: " << d << ") ...";
+
+ select_filenames = t.streamLeavesMaxD(t.getTop(), d);
+ select_filenames.push_front(options->getFileName(options->alignName, false));
+
+ end = clock();
+ const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
+- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl;
+
+ if (options->processPC) {
+
+- if (options->logLevel >= 0) { ostringstream log; log << "process PC ..."; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << "process PC ...";
+
+ clock_t start = clock(), end;
+
+@@ -91,7 +105,7 @@ int fs_driver::fsDriver::doRun () {
+
+ string current = *it;
+
+- { ostringstream log; log << endl << "\t" << current << " ..."; *options->stdOut << log.str().c_str(); }
++ *options->stdOut << endl << "\t" << current << " ...";
+
+ fs_pc::ClusterDriver pc(current, *options);
+
+@@ -108,7 +122,8 @@ int fs_driver::fsDriver::doRun () {
+
+ end = clock();
+ const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
+- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl;
+ }
+
+ } else {
+@@ -118,14 +133,15 @@ int fs_driver::fsDriver::doRun () {
+ clock_t start = clock(), end;
+
+ if (options->pcFile == "") {
+- if (options->logLevel >= 0) { ostringstream log; log << "ERROR: no file for classification specified" << endl; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << "ERROR: no file for classification specified" << endl;
+ return 1;
+ }
+
+- if (options->logLevel >= 0) { ostringstream log; log << "process PC ..."; *options->stdOut << log.str().c_str(); }
+-
+- if (options->logLevel >= 0) { ostringstream log; log << endl << "\t" << options->pcFile << " ..."; *options->stdOut << log.str().c_str(); }
+-
++ if (options->logLevel >= 0) {
++ *options->stdOut << "process PC ...";
++ *options->stdOut << endl << "\t" << options->pcFile << " ...";
++ }
+ fs_pc::ClusterDriver pc(options->pcFile, *options);
+
+ pc.doClustering();
+@@ -138,7 +154,8 @@ int fs_driver::fsDriver::doRun () {
+
+ end = clock();
+ const double elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
+- if (options->logLevel >= 0) { ostringstream log; log << " done in " << setw(5) << elapsed << " seconds" << endl; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << " done in " << setw(5) << elapsed << " seconds" << endl;
+ }
+
+ }
+@@ -147,18 +164,22 @@ int fs_driver::fsDriver::doRun () {
+ {
+ // options->processSP is set
+
+- if (options->logLevel >= 0) { ostringstream log; log << "process SELECT"; *options->stdOut << log.str().c_str(); }
+- if (options->logLevel >= 0) { ostringstream log; log << " (" << options->peakFile << " " << options->peakStr << ") ..."; *options->stdOut << log.str().c_str(); }
+-
++ if (options->logLevel >= 0)
++ *options->stdOut << "process SELECT";
++ if (options->logLevel >= 0)
++ *options->stdOut << " (" << options->peakFile << " " << options->peakStr << ") ...";
++
+ SelectPeak sp;
+ sp.init(*options);
+ sp.processFile(options->peakFile);
+
+- if (options->logLevel >= 0) { ostringstream log; log << " done" << endl; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << " done" << endl;
+
+ }
+
+- if (options->logLevel >= 0) { ostringstream log; log << endl << "fs_kit done" << endl << endl << flush; *options->stdOut << log.str().c_str(); }
++ if (options->logLevel >= 0)
++ *options->stdOut << endl << "fs_kit done" << endl << endl << flush;
+
+ return 0;
+
+diff --git a/src/fs_kit_options.cpp b/src/fs_kit_options.cpp
+index 12849df..2f61b26 100644
+--- a/src/fs_kit_options.cpp
++++ b/src/fs_kit_options.cpp
+@@ -1,8 +1,11 @@
+ #include "fs_kit_options.h"
+
+ #ifdef fs_gui_wxwidgets
++#if wxHAS_TEXT_WINDOW_STREAM == 0
++#error "Your compiler does not support wxTextCtrl streams"
++#endif
+ Options::Options(string opt, wxTextCtrl* log) {
+- stdOut = log;
++ stdOut = new ostream(log);
+ InitOptions(opt);
+ }
+ #endif
+@@ -156,6 +159,7 @@ void Options::defaultOptions() {
+ logLevel = 1;
+
+ commonFields = 10;
++
+ }
+
+ string Options::int2string(int num, int cntr) {
+diff --git a/src/fs_kit_options.h b/src/fs_kit_options.h
+index f75c555..4fd957f 100644
+--- a/src/fs_kit_options.h
++++ b/src/fs_kit_options.h
+@@ -3,8 +3,8 @@
+
+ #include <fstream>
+ #include <iostream>
+-#include <map>
+ #include <sstream>
++#include <map>
+ #include <string>
+
+ #ifdef fs_gui_wxwidgets
+@@ -33,12 +33,7 @@ class Options {
+
+ public:
+
+-// use TextCtrl if running in wxWindows to direct log output
+-#ifdef fs_gui_wxwidgets
+- wxTextCtrl *stdOut;
+-#else
+- ostream *stdOut;
+-#endif
++ ostream *stdOut;
+
+ static string int2string(int num, int cntr = 0);
+
+@@ -112,6 +107,7 @@ public:
+ void printOptions(ostream* out = 0, bool print_all = true, bool print_description = false);
+
+ void setStop(bool stop = true) { stopRequested = stop; }
++
+ };
+
+ #endif
+--
+1.5.4.3
+