[med-svn] [seaview] 01/04: New upstream version 4.6.1.1

Andreas Tille tille at debian.org
Sat Sep 10 05:17:17 UTC 2016


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository seaview.

commit 8f55f487d8e5ff8d283891919ae62b057bf1fc65
Author: Andreas Tille <tille at debian.org>
Date:   Sat Sep 10 07:08:47 2016 +0200

    New upstream version 4.6.1.1
---
 align.cxx           |   2 +-
 csrc/misc_acnuc.c   |  16 ++++-
 csrc/raa_acnuc.c    |  48 +++++++++-----
 csrc/raa_acnuc.h    |   2 +
 load_seq.cxx        |  77 +++++++++++++---------
 macos_extras.mm     |   3 +
 pdf_or_ps.h         |  31 +++++++++
 seaview.appdata.xml |  14 +++-
 seaview.cxx         |  15 +++--
 seaview.h           |   3 +-
 seaview.html        |  31 +++++++--
 svg.h               |  34 ++++++++++
 treedraw.cxx        | 184 +++++++++++++++++++++++++++++++++++++++++++++-------
 treedraw.h          |  12 ++++
 trees.cxx           |   4 ++
 unrooted.cxx        |  42 +++++++-----
 unrooted.h          |   2 +
 17 files changed, 422 insertions(+), 98 deletions(-)

diff --git a/align.cxx b/align.cxx
index cc4e0ed..7f949aa 100644
--- a/align.cxx
+++ b/align.cxx
@@ -754,7 +754,7 @@ void cre_align_menu(SEA_VIEW *view)
   alignitems[clustalopt + MAX_MSA_ALGOS].label(strdup(options));
   alignitems[clustalopt + MAX_MSA_ALGOS].flags = attr;
   if (view->alignment_algorithm < 2) alignitems[clustalopt + MAX_MSA_ALGOS + 3].flags = FL_MENU_INACTIVE;
-  delete options;
+  delete[] options;
   view->menu_align = alignitems;
   view->menubar->add("Align", 0, NULL, (void*)view->menu_align, FL_SUBMENU_POINTER);
   if (view->count_msa_algos >= MAX_MSA_ALGOS) (alignitems + clustalopt + MAX_MSA_ALGOS + 2)->deactivate();
diff --git a/csrc/misc_acnuc.c b/csrc/misc_acnuc.c
index fc8b98b..062290d 100644
--- a/csrc/misc_acnuc.c
+++ b/csrc/misc_acnuc.c
@@ -1,3 +1,4 @@
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -52,7 +53,7 @@ for(i=(int)strlen(pname);i<length;i++) pname[i]=' ';
 }
 
 
-#define TOTCODES 19  /* nbre total de codes definis, 0 inclus */
+#define TOTCODES 20  /* nbre total de codes definis, 0 inclus */
 int totcodes=TOTCODES;
 
 char aminoacids[]="RLSTPAGVKNQHEDYCFIMW*X";
@@ -315,6 +316,19 @@ struct genetic_code_libel genetic_code[TOTCODES] =
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0} /* UUG */
   }
+  ,
+  { /* 19: Pachysolen tannophilus */
+    {"CUG=A"},
+/*ANN*/	{9,10,9,10,4,4,4,4,1,3,1,3,18,18,19,18,
+/*CNN*/	11,12,11,12,5,5,5,5,1,1,1,1,2,2,6,2,
+/*GNN*/	13,14,13,14,6,6,6,6,7,7,7,7,8,8,8,8,
+/*TNN*/	21,15,21,15,3,3,3,3,21,16,20,16,2,17,2,17,22},
+/*ncbi*/26,
+/*init*/{0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0, /* AUG */
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0, /* CUG */
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} /* UUG */
+  }
   
 
 /*       1         2
diff --git a/csrc/raa_acnuc.c b/csrc/raa_acnuc.c
index 0ae115d..938693a 100644
--- a/csrc/raa_acnuc.c
+++ b/csrc/raa_acnuc.c
@@ -377,6 +377,8 @@ raa_current_db->raa_sockfdw = fdopen(raa_snum,"a");
 
 
 extern void raa_MD5String (char *in_string, char out_digest[33]);
+#define default_raa_maxlists  50
+int raa_maxlists = default_raa_maxlists; // can be changed by caller of raa_opendb_pw() before the call
 
 int raa_opendb_pw(raa_db_access *raa_current_db, const char *db_name, void *ptr, char *(*getpasswordf)(void *) )
 /*
@@ -395,7 +397,8 @@ char *reponse, *code, *p, *challenge;
 int codret, totspecs, totkeys, i;
 
 if(raa_current_db == NULL) return nosocket;
- sock_printf(raa_current_db, "acnucopen&db=%s\n", db_name);
+ sock_printf(raa_current_db, "acnucopen&db=%s&maxlists=%d\n", db_name, raa_maxlists);
+ raa_maxlists = default_raa_maxlists; // reset to default in prevision of future raa_opendb_pw() calls
  reponse=read_sock(raa_current_db);
  if(reponse == NULL) return nosocket;
  rep=initreponse();
@@ -506,7 +509,9 @@ if (p != NULL) {
       raa_current_db->readshrt2_data[i]->point = 0;
       raa_current_db->readshrt2_data[i]->next = 0;
     }
-  
+p = val(rep,"version");
+if (p != NULL) { raa_current_db->version_string = p; }
+
 clear_reponse(rep);
 return 0;
 }
@@ -710,7 +715,8 @@ int raa_prep_acnuc_query(raa_db_access *raa_current_db) {
   int codret, i;
   Reponse *rep;
 
-if(raa_current_db == NULL) return -1;
+  if (raa_current_db == NULL) return -1;
+  if (raa_current_db->maxlists) return raa_current_db->maxlists;
   rep = initreponse();
 
   sock_fputs(raa_current_db, "countfreelists\n");
@@ -725,6 +731,7 @@ if(reponse == NULL) return -1;
   reponse=val(rep,"free");
   if(reponse != NULL) {
 	codret = atoi(reponse);
+        raa_current_db->maxlists = codret;
   	free(reponse);
   	}
 annotlines = val(rep, "annotlines");
@@ -736,8 +743,9 @@ if(annotlines != NULL) {
 		raa_current_db->tot_key_annots++;
 		}
 	while((p = strchr(p, '|')) != NULL);
-	raa_current_db->want_key_annots = (unsigned char *)malloc(raa_current_db->tot_key_annots * 
+	raa_current_db->want_key_annots = (unsigned char *)calloc(raa_current_db->tot_key_annots,
 		sizeof(unsigned char));
+        raa_current_db->want_key_annots[0] = TRUE;
 	raa_current_db->key_annots = (char **)malloc(raa_current_db->tot_key_annots * sizeof(char *));
 	raa_current_db->key_annots_min = (char **)malloc(raa_current_db->tot_key_annots * sizeof(char *));
 	p = annotlines;
@@ -3049,15 +3057,15 @@ return raa_current_db->sp_tree[rank]->name;
 }
 
 
-static char *raa_getattributes_both(raa_db_access *raa_current_db, const char *id, int rank,
-	int *prank, int *plength, int *pframe, int *pgc, char **pacc, char **pdesc, char **pspecies, char **pseq)
+char *raa_getattributes_both(raa_db_access *raa_current_db, const char *id, int rank,
+	int *prank, int *plength, int *pframe, int *pgc, char **pacc, char **pdesc, char **pspecies, char **pseq, char **pprot)
 /*
 for a sequence identified by name or acc. no. (id != NULL) or by rank
 returns rank, name, accession, length, frame, acnuc genetic code ID,
 one-line description, species, and full sequence.
 return value: NULL if not found or name (in private memory)
-pacc, pdesc, pspecies and pseq point to private memory upon return
-prank, plength, pframe, pgc, pacc, pdesc, pspecies, pseq can be NULL is no such information is needed
+pacc, pdesc, pspecies, pseq and pprot point to private memory upon return
+prank, plength, pframe, pgc, pacc, pdesc, pspecies, pseq, pprot can be NULL is no such information is needed
 */
 {
 Reponse *rep;
@@ -3065,8 +3073,8 @@ char *p, *reponse;
 int err;
 
 if(raa_current_db == NULL) return NULL;
-if(id != NULL) sock_printf(raa_current_db, "getattributes&id=%s&seq=%c\n", id, pseq == NULL ? 'F' : 'T');
-else sock_printf(raa_current_db, "getattributes&rank=%d&seq=%c\n", rank, pseq == NULL ? 'F' : 'T');
+if(id != NULL) sock_printf(raa_current_db, "getattributes&id=%s&seq=%c&prot=%c\n", id, pseq == NULL ? 'F' : 'T', pprot == NULL ? 'F' : 'T');
+else sock_printf(raa_current_db, "getattributes&rank=%d&seq=%c&prot=%c\n", rank, pseq == NULL ? 'F' : 'T', pprot == NULL ? 'F' : 'T');
 reponse = read_sock(raa_current_db);
 if(reponse == NULL) {
 	return NULL;
@@ -3126,10 +3134,18 @@ if(err == 0) {
 		free(p);
 		*pdesc = raa_current_db->descript;
 		}
-	if(pseq != NULL) {
-		*pseq = read_sock(raa_current_db); 
-		if(*pseq != NULL) {
-			*pseq += 4; /* seq=xxxx */
+	if(pseq != NULL || pprot != NULL) {
+		char *p = read_sock(raa_current_db);
+		char *q = strstr(p, "prot=");
+		if (q && q > p && *(q-1) == '&') *(q-1) = 0;
+		p = strstr(p, "seq=");
+		if (pseq != NULL) {
+			if (p) *pseq = p + 4; /* seq=xxxx */
+			else *pseq = "";
+			}
+		if (pprot != NULL) {
+			if (q) *pprot = q + 5; /* prot=xxxx */
+			else *pprot = "";
 			}
 		}
 	err = 0;
@@ -3142,14 +3158,14 @@ return (err ? NULL : raa_current_db->mnemo);
 char *raa_getattributes(raa_db_access *raa_current_db, const char *id,
 						int *prank, int *plength, int *pframe, int *pgc, char **pacc, char **pdesc, char **pspecies, char **pseq)
 {
-	return raa_getattributes_both(raa_current_db, id, 0, prank, plength, pframe, pgc, pacc, pdesc, pspecies, pseq);
+	return raa_getattributes_both(raa_current_db, id, 0, prank, plength, pframe, pgc, pacc, pdesc, pspecies, pseq, NULL);
 }
 
 
 char *raa_seqrank_attributes(raa_db_access *raa_current_db, int rank,
 							 int *plength, int *pframe, int *pgc, char **pacc, char **pdesc, char **pspecies, char **pseq)
 {
-	return raa_getattributes_both(raa_current_db, NULL, rank, NULL, plength, pframe, pgc, pacc, pdesc, pspecies, pseq);
+	return raa_getattributes_both(raa_current_db, NULL, rank, NULL, plength, pframe, pgc, pacc, pdesc, pspecies, pseq, NULL);
 }
 
 
diff --git a/csrc/raa_acnuc.h b/csrc/raa_acnuc.h
index f9fa72b..fab6f39 100644
--- a/csrc/raa_acnuc.h
+++ b/csrc/raa_acnuc.h
@@ -111,6 +111,8 @@ typedef struct _raa_db_access {
 	int genbank, embl, swissprot, nbrf;
 	int nseq, longa, maxa;
 	int L_MNEMO, WIDTH_SP, WIDTH_KW, WIDTH_SMJ, WIDTH_AUT, WIDTH_BIB, ACC_LENGTH, SUBINLNG, lrtxt, VALINSHRT2;
+	char *version_string;
+        int maxlists; /* max # of possible lists */
 	raa_node **sp_tree; /* NULL or the full taxonomy tree */
 	int max_tid; /* largest correct taxon ID value */
 	int *tid_to_rank; /* NULL or tid-to-rank table */
diff --git a/load_seq.cxx b/load_seq.cxx
index b828f08..c02263a 100644
--- a/load_seq.cxx
+++ b/load_seq.cxx
@@ -768,8 +768,43 @@ input->position(0);
 return FALSE;
 }
 
+static int *sort_f_transmit;
 
-char calc_site_consensus(int *freqs, int dernier, int threshold, char *residues, char unknown, int total, 
+static int sort_f(const void *v1, const void *v2) {
+  int i1 = *(int*)v1;
+  int i2 = *(int*)v2;
+  return sort_f_transmit[i2] - sort_f_transmit[i1];
+}
+
+char calc_iupac_consensus(int *freqs, float minval) {
+  // order for freqs[1-16]: ACGTUMRWSYKVHDBN
+  // code for nucleotide sets: 4 bits representing A,C,G,T=U
+  // then coded_set[i-1] is the integer value of the set of count freq[i]
+  static int coded_set[16] = {1,2,4,8,8,3,5,9,6,10,12,7,11,13,14,15};
+  static char set_to_iupac[18] = {".ACMGRSVTWYHKDBN"};
+  int sorted_freqs[16];
+  freqs[16] += freqs[0]; // add count of non-IUPAC characters to count of N
+  for (int i = 0; i < 16; i++) sorted_freqs[i] = i+1;
+  sort_f_transmit = freqs;
+  // sort residue counts in decreasing order
+  qsort(sorted_freqs, 16, sizeof(int), sort_f);
+  int cumul = 0;
+  int set = 0;
+  // walk through residue counts in decreasing order until cumulated counts exceeds minval
+  for (int rank = 0; rank < 16; rank++) {
+    int residue = sorted_freqs[rank]; // the next most frequent residue
+    cumul += freqs[residue]; // summed frequencies till here
+    set |= coded_set[residue - 1]; // the set of all counted residues till here
+    // residues of equal frequencies are pooled together
+    if (rank < 15 && freqs[residue] == freqs[sorted_freqs[rank+1]]) continue;
+    if (cumul >= minval ) break;
+  }
+  if (set == 8 && sorted_freqs[0] == 5) return 'U';
+  return set_to_iupac[set];
+}
+
+
+char calc_site_consensus(int *freqs, int dernier, int threshold, char *residues, char unknown, int total,
 						 int protein, int allowgaps, int iupac)
 {
 	char retval;
@@ -784,36 +819,20 @@ char calc_site_consensus(int *freqs, int dernier, int threshold, char *residues,
 			kind = num;
 			}
 		}
-	if(allowgaps && !protein) {
-		num = dernier - 1;//check if '-' has the highest freq
-		if(freqs[num] > maxi) {
-			maxi = freqs[num];
-			kind = num;
+  if (!protein && !iupac) {
+    total -= freqs[16];//DNA: don't count uninformative N's for frequency calculation
+    if(total == 0) return 'N';
+  }
+  float minval = total * (threshold / 100.);
+	if (allowgaps) {
+		num = dernier - 1; // check if '-' has the highest freq
+		if (freqs[num] > maxi) {
+                  return freqs[num] > minval ? '-' : unknown;
 		}
 	}
-	if(!protein) {
-	  total -= freqs[16];//DNA: don't count uninformative N's for frequency calculation
-	  if(total == 0) return 'N';
-	  }
-	float minval = total * (threshold / 100.);
-	if(iupac && !protein ) { // for DNA/RNA with IUPAC codes
-		if( maxi >= minval ) retval = residues[kind - 1];
-		else if(freqs[1] + freqs[2] + freqs[6] >= minval) retval = 'M';//AC
-		else if(freqs[1] + freqs[3] + freqs[7] >= minval) retval = 'R';//AG
-		else if(freqs[1] + freqs[4] + freqs[5] + freqs[8] >= minval) retval = 'W';//AT(U)
-		else if(freqs[2] + freqs[3] + freqs[9] >= minval) retval = 'S';//CG
-		else if(freqs[2] + freqs[4] + freqs[5] + freqs[10] >= minval) retval = 'Y';//CT(U)
-		else if(freqs[3] + freqs[4] + freqs[5] + freqs[11] >= minval) retval = 'K';//GT(U)
-		else if(freqs[1] + freqs[2] + freqs[3] + freqs[6] + 
-				freqs[9] + freqs[7] + freqs[12] >= minval) retval = 'V';//ACG
-		else if(freqs[1] + freqs[2] + freqs[4] + freqs[5] + 
-				freqs[6] + freqs[8] + freqs[10] + freqs[13] >= minval) retval = 'H';//ACT(U)
-		else if(freqs[1] + freqs[3] + freqs[4] + freqs[5] + 
-				freqs[7] + freqs[8] + freqs[11] + freqs[14] >= minval) retval = 'D';//AGT(U)
-		else if(freqs[2] + freqs[3] + freqs[4] + freqs[5] + 
-				freqs[9] + freqs[10] + freqs[11] + freqs[15] >= minval) retval = 'B';//CGT(U)
-		else retval = 'N';
-		}
+	if (iupac && !protein ) { // for DNA/RNA with IUPAC codes
+          retval = calc_iupac_consensus(freqs, minval);
+          }
 	else {
 		if( maxi >= minval )
 			retval = residues[kind - 1];
diff --git a/macos_extras.mm b/macos_extras.mm
index d4f9736..fdcf8b7 100644
--- a/macos_extras.mm
+++ b/macos_extras.mm
@@ -5,6 +5,9 @@
 #include <FL/x.H>
 #include <FL/Fl_Sys_Menu_Bar.H>
 #include <FL/Fl_Help_View.H>
+#if SEAVIEW_FLTK_VERSION >= 140
+#include <src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H>
+#endif
 #include <FL/filename.H>
 #include <FL/fl_draw.H>
 #include <sys/stat.h>
diff --git a/pdf_or_ps.h b/pdf_or_ps.h
index 9a4a30c..6dbd351 100644
--- a/pdf_or_ps.h
+++ b/pdf_or_ps.h
@@ -2,6 +2,9 @@
 #define PDF_OR_PS_H
 
 #include <FL/Fl_Paged_Device.H>
+#if SEAVIEW_FLTK_VERSION >= 140
+#include <FL/Fl_Graphics_Driver.H>
+#endif
 
 #if !(defined(__APPLE__) || defined(WIN32)) && 100*FL_MAJOR_VERSION + 10*FL_MINOR_VERSION  + FL_PATCH_VERSION == 130
 // for X11 under 1.3.0 only
@@ -88,6 +91,34 @@ public:
   int height() ;
   int descent() ;
   friend class Fl_PDF_File_Device;
+  
+#if SEAVIEW_FLTK_VERSION >= 140
+  virtual void point(int x, int y) {}
+  virtual void line(int x, int y, int x1, int y1, int x2, int y2) {}
+  virtual void xyline(int x, int y, int x1, int y2, int x3) {}
+  virtual void yxline(int x, int y, int y1, int x2, int y3) {}
+  virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2) {}
+  virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {}
+  virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2) {}
+  virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {}
+  virtual int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) {return 0;}
+  virtual int not_clipped(int x, int y, int w, int h) {return 0;}
+  virtual void push_no_clip() {}
+  virtual void begin_complex_polygon() {}
+  virtual void transformed_vertex(double xf, double yf) {}
+  virtual void vertex(double x, double y) {}
+  virtual void end_points() {}
+  virtual void end_line() {}
+  virtual void end_loop() {}
+  virtual void end_polygon() {}
+  virtual void end_complex_polygon() {}
+  virtual void gap() {}
+  virtual void circle(double x, double y, double r) {}
+  virtual void arc(int x, int y, int w, int h, double a1, double a2) {}
+  virtual void pie(int x, int y, int w, int h, double a1, double a2) {}
+  virtual Fl_Bitmask create_bitmask(int w, int h, const uchar *array) {return 0;}
+  virtual void delete_bitmask(Fl_Bitmask bm) {}
+#endif
 };
 
 class Fl_PDF_File_Device : public Fl_Paged_Device
diff --git a/seaview.appdata.xml b/seaview.appdata.xml
index 482795a..f06e6cc 100644
--- a/seaview.appdata.xml
+++ b/seaview.appdata.xml
@@ -38,4 +38,16 @@
  </screenshots>
  <url type="homepage">http://doua.prabi.fr/software/seaview</url>
  <updatecontact>manolo.gouy_at_univ-lyon1.fr</updatecontact>
-</component>
\ No newline at end of file
+ 
+ <developer_name>Manolo Gouy</developer_name>
+
+  <keywords>
+  <keyword>molecular phylogeny</keyword>
+  <keyword>phylogenetic tree</keyword>
+  <keyword>sequence alignment</keyword>
+  <keyword>parsimony</keyword>
+  <keyword>neighbor-joining/keyword>
+  <keyword>maximum likelihood</keyword>
+  </keywords>
+
+</component>
diff --git a/seaview.cxx b/seaview.cxx
index f947b52..ff882b3 100644
--- a/seaview.cxx
+++ b/seaview.cxx
@@ -361,6 +361,7 @@ int main(int argc, char *argv[])
 	    "               and name1-containing clade as ingroup\n"
 	    "-root_at_center   reroot the tree at its center\n"
 	    "-unroot       remove the root from the input tree, if any\n"
+            "-trim r       rule to trim long tree leaf names in output tree file (def=no trimming)\n"
 	    "-patristic_distances fname    write to named file patristic distances for leaves of input tree\n"
 	    "-remove_bootstrap    remove branch support values present in input tree\n"
 
@@ -384,6 +385,7 @@ int main(int argc, char *argv[])
 	    "-branch_width_as_support  draw plot with branches of increasing widths with increasing support\n"
 	    "-support_threshold_high f support above which a branch is drawn with maximal width (def=.95)\n"
 	    "-support_threshold_low f support below which a branch is drawn with minimal width (def=.8)\n"
+            "-trim r       rule to trim long tree leaf names (def=no trimming)\n"
 #endif
 	    , stdout);
     fputs("\nSee http://doua.prabi.fr/software/seaview_data/seaview#Program%20arguments for more details\n", stdout);
@@ -1237,8 +1239,9 @@ draw_header(ob, view);
 
 void draw_dna_seqs_inverted(Fl_Widget *ob, SEA_VIEW *view)
 {
-int nline, c, offset, x, y, l_line, xx, yy, firstline, lastline, use_region,
+int nline, c, offset, x, y, l_line, yy, firstline, lastline, use_region,
 	debut, fin, der_site;
+  float xx;
 int pos;
 list_segments *segment, *first_segment;
 int save_col0;
@@ -1536,7 +1539,7 @@ view->first_seq = view->first_site = 1;
 #endif
 fl_font(view->DNA_obj->labelfont(), view->DNA_obj->labelsize());
 view->line_height = (int)( LINE_HEIGHT_FACTOR * fl_height() );
-view->char_width = (int)(fl_width("W") + 0.5);
+view->char_width = fl_width("W");
 view->draw_names = -1;
 view->mod_cursor = FALSE;
 view->mod_seq = 0;
@@ -1746,8 +1749,8 @@ for(numset = 0; numset < view->numb_species_sets; numset++) {
 		new_tot_seqs * sizeof(int) );
 	}
 
-if(! view->cursor_in_comment) view->cursor_seq = 1;
-memset(view->sel_seqs, 0, new_tot_seqs * sizeof(int));
+if (! view->cursor_in_comment) view->cursor_seq = view->old_cursor_seq = 1;
+memset(view->sel_seqs, 0, view->tot_seqs * sizeof(int));
 view->tot_seqs = new_tot_seqs;
 select_deselect_seq(view, 0);
 if(view->menu_species != NULL) {
@@ -1859,7 +1862,7 @@ my_watch_cursor(view->dnawin);
 view->DNA_obj->labelsize(taille);
 fl_font( view->DNA_obj->labelfont(), view->DNA_obj->labelsize() );
 view->line_height = (int)( LINE_HEIGHT_FACTOR * fl_height() );
-view->char_width = (int)(fl_width("W") + 0.5);
+view->char_width = fl_width("W");
 compute_size_params(view, TRUE);
 view->DNA_obj->parent()->redraw();
 fl_reset_cursor(view->dnawin);
@@ -3597,7 +3600,7 @@ void help_callback(Fl_Widget *ob, void *unused)
 		help_viewer = new Fl_Help_Dialog();
 		if(help_viewer == NULL) return;
 #ifdef MICRO
-		help_viewer->resize(help_viewer->x(), help_viewer->y(), 695, 500);
+		help_viewer->resize(help_viewer->x(), help_viewer->y(), 700, 600);
 		help_viewer->textsize(14);
 #else
 		help_viewer->resize(help_viewer->x(), help_viewer->y(), 740, 500);
diff --git a/seaview.h b/seaview.h
index e1864de..da7358e 100644
--- a/seaview.h
+++ b/seaview.h
@@ -204,7 +204,8 @@ typedef struct _SEA_VIEW {
 		  0: normal; 
 		  >= 1: 1 seul seq ecrite */
   int mod_cursor; /* FALSE: cursor ancien ignore; TRUE: ancien efface */
-  int char_width, line_height; /* taille en pixels des caracteres */
+  float char_width; /* largeur en pixels des caracteres */
+  int line_height; /* hauteur en pixels des lignes */
   int cursor_seq, cursor_site; /* position courante du curseur */
   int old_cursor_seq, old_cursor_site; /* position precedente du curseur*/
   int tot_sel_seqs; /* nbre courant de seqs selectionnees */
diff --git a/seaview.html b/seaview.html
index a9748aa..a6eb016 100644
--- a/seaview.html
+++ b/seaview.html
@@ -44,7 +44,7 @@ Molecular Biology and Evolution 27(2):221-224.
 SEAVIEW and PHYLO_WIN: two graphic tools for sequence alignment and molecular phylogeny.</a> 
 Comput. Appl. Biosci., 12:543-548.
 <p>
-Version 4.6
+Version 4.6.1
 
 <p>Binaries and full source code available from <a href=http://doua.prabi.fr/software/seaview>http://doua.prabi.fr/software/seaview</a>
 
@@ -658,10 +658,11 @@ For trees without branch lengths, the computation is run as if all branch length
 were equal to 1, except the two branches that stem from the root of length taken as equal to 0.5.
 <br><u>Print:</u> prints displayed tree (see also 'Page count' below).
 <br><u>Save as PDF/PostScript:</u> saves displayed tree to PDF (or PostScript) local file (see Page Count).
-<br><u>Save as SVG:</u> saves displayed (sub)tree to a scalable vector graphics (SVG) local file suitable 
-to be edited using appropriate programs (e.g., Inkscape).
 <br><u>A4 - Letter:</u> controls the page format for PDF/PostScript operations.
+<br><u>Landscape:</u> controls the page layout for PDF/PostScript operations.
 <br><u>Page count>#:</u> controls the # of pages used for print/PDF/PostScript operations.
+<br><u>Save as SVG:</u> saves displayed (sub)tree to a scalable vector graphics (SVG) local file suitable
+to be edited using appropriate programs (e.g., Inkscape).
 <br><u>Reorder following tree:</u> reorders sequences of alignment window as in displayed tree.
 <br><u>Select in alignment:</u> selects in alignment window all members of subtree (active when only a subtree
 is plotted).
@@ -672,7 +673,7 @@ the file can contain several trees consecutively) or alignment file (any format)
 <br><u>Close window:</u> closes the displayed tree that gets lost unless it had been saved to Trees menu.
 
 <p>
-<b>Edit menu</b><p>
+<a name=TREE_EDIT><b>Edit menu</b><p></a>
 <br><u>Copy:</u> (Mac OS and MSWindows only) copies tree plot to clipboard for pasting to external programs.
 <br><u>Paste tree:</u> (only if window is empty) to paste a
 <a href=http://evolution.genetics.washington.edu/phylip/newicktree.html>Newick</a>-formatted
@@ -689,6 +690,9 @@ the tree without branch lengths. Clicking on a square selects a sequence group t
 It can be moved to another branch of tree by clicking on another square, or deleted ("Delete group" 
 button). "Select group" button allows to select another group for further move or delete operations.
 Complete edits by pressing "End edit" button, and, possibly, "File/Save to Trees menu".
+<br><u>Default name trimming rule</u>: allows to set and change the rule used to trim long
+sequence names when displaying trees. Use an empty rule not to trim sequence names.
+See <a href=#TRIM>Trim rule</a> for details about how trimming rules work.
 
 <p><u>Font menu:</u> to control font, style and size of all text in tree display.
 
@@ -700,6 +704,22 @@ circular plot convenient for unrooted trees, and cladogram which displays trees
 all branch lengths a multiple of a unit length and all leaves aligned at right. Cladogram is not
 available for branch length-free trees because it is equivalent to the squared display for them.
 
+<p><u>counter</u>:Appears when the loaded treefile contains several trees (e.g., after a bootstrap
+analysis in which the "Show bootstrap trees" option was selected), and allows to navigate around those trees.
+
+<a name=TRIM><p><u>Trim rule</u></a>: Allows to enter a rule for trimming long sequence names.
+Click on the white area. A dialog window allows to enter the desired sequence name <b>trimming rule</b>.
+<br><b>Trim by content</b>: enter one or more characters; each sequence name will be trimmed
+after all these characters have been found in the name.
+<br><b>Trim by length</b>: enter a number; each sequence name longer than this number will by cut.
+<br>Examples:
+<ul><li>rule '~' trims names at their first ~
+<li>rule '~@' trims names at the first @ located after a ~
+<li>rule '25'  trims names longer than 25 characters
+</ul>
+Use an empty trimming rule to go back to full sequence names.
+<p>The default trimming rule can be set with the <a href=#TREE_EDIT>Edit menu</a>.
+
 <p><u>Full:</u> normal, full tree display.
 <br><u>Swap:</u> to swap branches around a node. Click on relevant square that appears.
 <br><u>Re-root:</u> to set tree outgroup. Click on relevant square that appears.
@@ -885,6 +905,7 @@ as an extra character state)</td></tr>
                and <i>name1</i>-containing clade as ingroup</td></tr>
 <tr><td><tt>-root_at_center</tt></td><td>   reroot the tree at its center</td></tr>
 <tr><td><tt>-unroot</tt></td><td>       remove the root from the input tree, if any</td></tr>
+<tr><td><tt>-trim <i>trim_rule</i></tt></td><td>  trim long leaf names using the given <a href=#TRIM>trim rule</a></td></tr>
 <tr><td><tt>-patristic_distances</tt> <i>fname</i></td><td>    write to named file patristic distances between leaves of input tree</td></tr>
 <tr><td><tt>-remove_bootstrap</tt></td><td>  remove branch support values present in input tree</td></tr>
 
@@ -897,6 +918,7 @@ as an extra character state)</td></tr>
 <tr><td><tt>-unrooted</tt></td><td>     draw the input tree in unrooted (circular) form</td></tr>
 <tr><td><tt>-pagecount</tt> <i>n</i></td><td>  number of pages used for the tree plot (pdf only)</td></tr>
 <tr><td><tt>-letter</tt></td><td>       use letter-sized paper for the tree plot</td></tr>
+<tr><td><tt>-landscape</tt></td><td>    draw in landscape orientation</td></tr>
 <tr><td><tt>-fontsize</tt> <i>n</i></td><td>   font size used in the tree plot</td></tr>
 <tr><td><tt>-lengths</tt></td><td>      display branch lengths in the tree plot</td></tr>
 <tr><td><tt>-bootstrap</tt> </td><td>   display branch support values in the tree plot</td></tr>
@@ -907,6 +929,7 @@ as an extra character state)</td></tr>
 <tr><td><tt>-branch_width_as_support</tt></td><td>  draw plot with branches of increasing widths with increasing support</td></tr>
 <tr><td><tt>-support_threshold_high</tt> <i>f</i></td><td> support above which a branch is drawn with maximal width (def=.95)</td></tr>
 <tr><td><tt>-support_threshold_low</tt> <i>f</i></td><td> support below which a branch is drawn with minimal width (def=.8)</td></tr>
+<tr><td><tt>-trim <i>trim_rule</i></tt></td><td>  trim long leaf names using the given <a href=#TRIM>trim rule</a></td></tr>
 
 </table>
 
diff --git a/svg.h b/svg.h
index 41e3ddf..104ed21 100644
--- a/svg.h
+++ b/svg.h
@@ -42,6 +42,40 @@ protected:
   double width(const char*, int) ;
   int height() ;
   int descent() ;
+  
+#if SEAVIEW_FLTK_VERSION >= 140
+  void push_clip(int x, int y, int w, int h) {}
+  void pop_clip(){}
+  void xyline(int x, int y, int x1){}
+  void xyline(int x, int y, int x1, int y2){}
+  void yxline(int x, int y, int y1){}
+  void yxline(int x, int y, int y1, int x2){}
+  virtual void point(int x, int y) {}
+  virtual void line(int x, int y, int x1, int y1, int x2, int y2) {}
+  virtual void xyline(int x, int y, int x1, int y2, int x3) {}
+  virtual void yxline(int x, int y, int y1, int x2, int y3) {}
+  virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2) {}
+  virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {}
+  virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2) {}
+  virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {}
+  virtual int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) {return 0;}
+  virtual int not_clipped(int x, int y, int w, int h) {return 0;}
+  virtual void push_no_clip() {}
+  virtual void begin_complex_polygon() {}
+  virtual void transformed_vertex(double xf, double yf) {}
+  virtual void vertex(double x, double y) {}
+  virtual void end_points() {}
+  virtual void end_line() {}
+  virtual void end_loop() {}
+  virtual void end_polygon() {}
+  virtual void end_complex_polygon() {}
+  virtual void gap() {}
+  virtual void circle(double x, double y, double r) {}
+  virtual void arc(int x, int y, int w, int h, double a1, double a2) {}
+  virtual void pie(int x, int y, int w, int h, double a1, double a2) {}
+  virtual Fl_Bitmask create_bitmask(int w, int h, const uchar *array) {return 0;}
+  virtual void delete_bitmask(Fl_Bitmask bm) {}
+#endif
 };
 
 class Fl_SVG_File_Surface : public Fl_Surface_Device {
diff --git a/treedraw.cxx b/treedraw.cxx
index 2a2b88c..b56249e 100644
--- a/treedraw.cxx
+++ b/treedraw.cxx
@@ -32,8 +32,8 @@
 typedef enum { helvetica, courier, times} font_name;
 
 enum {save_to_trees_menu, remove_from_trees_menu, save_rooted, save_unrooted, save_all_trees,
-  save_patristic, print_tree, save_as_ps_pdf, save_as_svg, A4_format, letter_format, page_count};
-enum {reorder_align_following_tree = page_count + 14, select_seqs_in_alignment, open_tree_or_align,
+  save_patristic, print_tree, save_as_ps_pdf, A4_format, letter_format, landscape, page_count};
+enum {save_as_svg = page_count + 14, reorder_align_following_tree, select_seqs_in_alignment, open_tree_or_align,
   new_window, close_window};
 
 
@@ -121,6 +121,7 @@ void edit_tree_header(Fl_Widget *wgt, void *data);
 void set_win_size_callback(Fl_Widget *wgt, void *data);
 int compare_newick_with_names(const char *tree, char **names, int notu, char **pname);
 void edit_shape_callback(Fl_Widget *obj, void *data);
+void edit_trim_callback(Fl_Widget *obj, void *data);
 void select_clade_callback(Fl_Widget *obj, void *data);
 void delete_clade_callback(Fl_Widget *obj, void *data);
 void complete_edit_callback(Fl_Widget *obj, void *data);
@@ -147,6 +148,8 @@ extern void svg_tree_save(FD_nj_plot *fd_nj_plot, Fl_SVG_File_Surface *svg);
 extern int debut_arbre(const char *tree, FD_unrooted *fd_unrooted);
 extern int testbit(int *plist, int num);
 extern void bit1(int *plist, int num);
+extern char *get_res_value(const char *name, const char *def_value);
+extern int set_res_value(const char *name, const char *value);
 #ifdef __APPLE__
 extern int add_windowmenuitem(const char *name, Fl_Window *w);
 extern void rename_windowmenuitem(const char *name, int rank);
@@ -166,6 +169,7 @@ double maxx, maxy, nexty;
 int num_noeud, nextotu;
 char list_ps_font_name[3][15] = { "Helvetica", "Courier", "Times"};
 extern Fl_Paged_Device::Page_Format printout_pageformat;
+extern Fl_Paged_Device::Page_Layout printout_layout;
 // will contain the two end nodes of the root-containing branch
 static struct noeud *current_cote1=NULL, *current_cote2=NULL;
 static const char bad_tree[] = "Incorrect tree data.";
@@ -173,6 +177,113 @@ static char *outotu=0, *inotu=0;
 static char *target1=0, *target2=0, *target3=0; // for -outgroup option
 
 
+LeafNameTrimmer::LeafNameTrimmer(int x, int y, int w, int h) : Fl_Widget(x, y, w, h, "") {
+  copy_label(get_res_value("name_trimming_rule", ""));
+}
+
+void LeafNameTrimmer::draw() {
+  fl_color(FL_WHITE);
+  fl_rectf(x(), y(), w(), h());
+  fl_color(FL_BLACK);
+  fl_font(labelfont(), labelsize());
+  fl_draw(label(), x(), y(), w(), h(), FL_ALIGN_CENTER, NULL, 0);
+  fl_font(labelfont(), 11);
+  fl_draw("Trim rule:", x()-50, y(), 50, h(), FL_ALIGN_LEFT, NULL, 0);
+ }
+
+
+int LeafNameTrimmer::handle(int event) {
+  if (event == FL_PUSH) {
+    const char *limit = fl_input("Enter sequence name trimming rule.  Examples:\n"
+                                 " ~~  will cut names at their second ~\n"
+                                 " 25 will cut names longer than 25 characters\n"
+                                 "<empty> for full names", label());
+    if (limit) {
+      copy_label(limit);
+      redraw();
+      FD_nj_plot *fd_nj_plot = (FD_nj_plot*)user_data();
+      if (!fd_nj_plot->fd_unrooted) {
+        fd_nj_plot->need_runtree = TRUE;
+        fd_nj_plot->panel->parent()->redraw();
+      } else {
+        process_unrooted();
+        FD_unrooted *fd_unrooted = (FD_unrooted*)fd_nj_plot->fd_unrooted;
+        fd_unrooted->comp_phys_bounds = TRUE;
+        fd_unrooted->previous_w = 0;
+        fd_unrooted->previous_h = 0;
+        fd_unrooted->unrooted_plot->parent()->redraw();
+      }
+    }
+    return 1;
+  }
+  return 0;
+}
+
+#define MAX_TRIM_LENGTH 500
+
+static char* trim_after_chars(const char *in, const char *target) {
+  static char output[MAX_TRIM_LENGTH+1];
+  const char *t = target;
+  const char *p = in, *q = NULL;
+  while (*t) {
+    q = strchr(p, *t);
+    t++;
+    if (q) p = q + 1;
+  }
+  strncpy(output, in, MAX_TRIM_LENGTH);
+  if (q && q-in <= MAX_TRIM_LENGTH) output[q-in] = 0;
+  return output;
+}
+
+static char* trim_at_pos(const char *in, const int pos) {
+  static char output[MAX_TRIM_LENGTH+1];
+  memcpy(output, in, pos);
+  output[pos] = 0;
+  return output;
+}
+
+int LeafNameTrimmer::by_position() {
+  int pos = -1;
+  sscanf(label(), "%d", &pos);
+  if (pos > MAX_TRIM_LENGTH) pos = MAX_TRIM_LENGTH;
+  return pos > 0 ? pos : 0;
+}
+
+void LeafNameTrimmer::process() {
+  FD_nj_plot *fd_nj_plot = (FD_nj_plot *)user_data();
+  int pos = by_position();
+  for (int i = 0; i < fd_nj_plot->notu; i++) {
+    char *newname = pos ?
+        trim_at_pos(fd_nj_plot->labels[i], pos) : trim_after_chars(fd_nj_plot->labels[i], label());
+    strcat(fd_nj_plot->tabtax[i]->nom, newname);
+  }
+}
+
+void LeafNameTrimmer::process_to_labels() {
+  FD_nj_plot *fd_nj_plot = (FD_nj_plot *)user_data();
+  int pos = by_position();
+  for (int i = 0; i < fd_nj_plot->notu; i++) {
+    char *newname = pos ?
+      trim_at_pos(fd_nj_plot->labels[i], pos) : trim_after_chars(fd_nj_plot->labels[i], label());
+    strcpy(fd_nj_plot->labels[i], newname);
+  }
+}
+
+void LeafNameTrimmer::process_unrooted() {
+  FD_nj_plot *fd_nj_plot = (FD_nj_plot *)user_data();
+  FD_unrooted *fd_unrooted = (FD_unrooted*)fd_nj_plot->fd_unrooted;
+  int pos = by_position();
+  for (int i = 0; i < 2 * fd_nj_plot->notu - 3; i++) {
+    char *name = (fd_unrooted->branches+i)->nom;
+    if (!name) continue;
+    int rank = (fd_unrooted->branches+i)->rank;
+    const char *oldname = fd_unrooted->tabtax[rank]->nom;
+    char *p = pos ? trim_at_pos(oldname, pos) : trim_after_chars(oldname, label());
+    free(name);
+    (fd_unrooted->branches+i)->nom = strdup(p);
+  }
+}
+
 Fl_Window *treedraw(char *trees, SEA_VIEW *view, const char *name, int from_tree_menu, int tree_count)
 /* returns the created window or NULL if none created
  tree_count: optional # of input trees in string trees
@@ -194,9 +305,9 @@ Fl_Window *treedraw(char *trees, SEA_VIEW *view, const char *name, int from_tree
 	fd_nj_plot->choix = show_tree;
 	fd_nj_plot->need_runtree = FALSE;
 	
-	Fl_Window *w = new Fl_Window(530, 530);
+	Fl_Window *w = new Fl_Window(590, 530);
 	w->xclass(TREE_WINDOW);
-	Fl_Group *g = new Fl_Group(0, 0, 528, 50);
+	Fl_Group *g = new Fl_Group(0, 0, w->w()-2, 50);
   
   Fl_Menu_Bar* menubar = new Fl_Menu_Bar(3, 3, 130, 20);
   menubar->user_data(fd_nj_plot);
@@ -211,9 +322,9 @@ Fl_Window *treedraw(char *trees, SEA_VIEW *view, const char *name, int from_tree
     {"Save patristic distances", 0, patristic_callback, NULL, FL_MENU_DIVIDER},
     {"Print", FL_COMMAND | 'p', file_callback, NULL, 0},
     {"Save as "PDF_OR_PS"", 0, file_callback, NULL, 0},
-    {"Save as SVG", 0, file_callback, NULL, 0},
     {"A4", 0, file_callback, NULL, FL_MENU_RADIO | 0},
     {"Letter", 0, file_callback, NULL, FL_MENU_RADIO | 0},
+    {"Landscape", 0, file_callback, NULL, FL_MENU_TOGGLE},
     {"Page count", 0, NULL, NULL, FL_SUBMENU | FL_MENU_DIVIDER},
     {"1", 0, file_callback, NULL, FL_MENU_RADIO | FL_MENU_VALUE},
     {"2", 0, file_callback, NULL, FL_MENU_RADIO},
@@ -228,6 +339,7 @@ Fl_Window *treedraw(char *trees, SEA_VIEW *view, const char *name, int from_tree
     {"11", 0, file_callback, NULL, FL_MENU_RADIO},
     {"other value", 0, file_callback, NULL, 0},
     {0},
+    {"Save as SVG", 0, file_callback, NULL, FL_MENU_DIVIDER},
     {"Reorder following tree", 0, file_callback, NULL, 0},
     {"Select in alignment", 0, file_callback, NULL, FL_MENU_INACTIVE | FL_MENU_DIVIDER},
     {"Open tree or alignment", FL_COMMAND | 'o', file_callback, NULL, 0},
@@ -236,6 +348,7 @@ Fl_Window *treedraw(char *trees, SEA_VIEW *view, const char *name, int from_tree
   };
   fd_nj_plot->menu_file = new vlength_menu(menubar, "File", fileitems, sizeof(fileitems)/sizeof(Fl_Menu_Item));
   (fd_nj_plot->menu_file->get_menu() + (printout_pageformat == Fl_Paged_Device::A4 ? A4_format : letter_format))->setonly();
+  if (printout_layout == Fl_Paged_Device::LANDSCAPE) (fd_nj_plot->menu_file->get_menu() + landscape)->set();
     if(view == NULL || view->tot_seqs == 0) {
       (fd_nj_plot->menu_file->get_menu() + reorder_align_following_tree)->deactivate();
       fd_nj_plot->menu_file->get_menu()->deactivate();
@@ -259,7 +372,8 @@ Fl_Window *treedraw(char *trees, SEA_VIEW *view, const char *name, int from_tree
     {0},
     {"Root at tree center", 0, midpoint_callback, NULL, 0},
     {"Get or Set Window size", 0, set_win_size_callback, NULL, FL_MENU_DIVIDER},
-    {"Edit tree shape", 0, edit_shape_callback, NULL, 0},
+    {"Edit tree shape", 0, edit_shape_callback, NULL, FL_MENU_DIVIDER},
+    {"Default name trimming rule", 0, edit_trim_callback, NULL, 0},
   };
   fd_nj_plot->center_rank = 9;
   fd_nj_plot->edit_shape_rank = 11;
@@ -296,7 +410,7 @@ Fl_Window *treedraw(char *trees, SEA_VIEW *view, const char *name, int from_tree
 	fd_nj_plot->root_unroot->add("cladogram");
 	fd_nj_plot->root_unroot->value(0);
 	fd_nj_plot->root_unroot->clear_visible_focus();
-	Fl_Button *help_button = new Fl_Button(g->w() - 52,3,50, 20, "Help");
+	Fl_Button *help_button = new Fl_Button(g->w() - 52,26,50, 20, "Help");
 	help_button->callback(direct_help_callback, (void *)"Tree windows");
 
 	fd_nj_plot->full = new Fl_Round_Button(3,26,47, 20, "Full");
@@ -326,6 +440,9 @@ Fl_Window *treedraw(char *trees, SEA_VIEW *view, const char *name, int from_tree
   fd_nj_plot->change_tree->step(1);
   fd_nj_plot->change_tree->bounds(1, tree_count);
   fd_nj_plot->change_tree->callback(tree_counter_callback, fd_nj_plot);
+  fd_nj_plot->leaf_trimmer = new LeafNameTrimmer(g->w() - 52,
+                                                 fd_nj_plot->change_tree->y(), 50, 20);
+  fd_nj_plot->leaf_trimmer->user_data(fd_nj_plot);
   if (tree_count == 1) {
     fd_nj_plot->change_tree->hide();
     (fd_nj_plot->menu_file->get_menu() + save_all_trees)->deactivate();
@@ -739,6 +856,9 @@ static void file_callback(Fl_Widget *wgt, void *data)
 	else if(reponse == letter_format) {// Letter
 	  printout_pageformat = Fl_Paged_Device::LETTER;
 	}
+        else if(reponse == landscape) {// Landscape
+          printout_layout = (item + landscape)->value() ? Fl_Paged_Device::LANDSCAPE : Fl_Paged_Device::PORTRAIT;
+        }
 	else if(reponse >= page_count+1 && reponse <= page_count+12) {// page counts
 		if(reponse >= page_count+1 && reponse <= page_count+10) {// fixed page counts
 			fd_nj_plot->page_count = reponse - page_count;
@@ -977,23 +1097,24 @@ void operation_callback(Fl_Widget *wgt, void *data)
 	g->window()->redraw();
 }
 
-void select_clade(struct noeud *n, SEA_VIEW *view, int on)
+void select_clade(struct noeud *n, SEA_VIEW *view, int on, char **labels)
 /* select (on is true) or deselect (on is false) all seqs in alignment placed below node n in tree
  */
 {
   if (n == NULL) return;
-  select_clade(n->v1, view, on);
-  select_clade(n->v2, view, on);
-  char *p = n->nom;
+  select_clade(n->v1, view, on, labels);
+  select_clade(n->v2, view, on, labels);
+  char *p = labels[n->rank];
   if (n->v1 == NULL) { // a leaf
     int num;
     for ( num = 0; num < view->tot_seqs; num++) { // find what sequence it is in alignment
-      if (strcmp(p + 1, view->seqname[num]) == 0) {
+      if (strcmp(p, view->seqname[num]) == 0) {
 	if ((view->sel_seqs[num] && !on) || (!view->sel_seqs[num] && on)) select_deselect_seq(view, num+1, TRUE);
 	break;
 	}
       }
     }
+  p = n->nom;
   if (*p) *p = (on ? '(' : ')');
 }
 
@@ -1067,13 +1188,13 @@ void tree_click_proc(tree_panel *panel, int mx, int my)
 	  if (!view) return;
 	  if(node_num >= fd_nj_plot->notu && node_num <= 2*fd_nj_plot->notu - 2) {
 	    int on = fd_nj_plot->tabtax[node_num]->nom[0] == ')';
-	    select_clade(fd_nj_plot->tabtax[node_num], view, on);
+	    select_clade(fd_nj_plot->tabtax[node_num], view, on, fd_nj_plot->labels);
 	    view->DNA_obj->redraw();
 	    panel->window()->redraw();
 	    return;
 	    }
 	  for (int num = 0; num < view->tot_seqs; num++) {
-	    if (strcmp(fd_nj_plot->tabtax[node_num]->nom + 1, view->seqname[num]) == 0) {
+	    if (strcmp(fd_nj_plot->labels[node_num], view->seqname[num]) == 0) {
 	      select_deselect_seq(view, num+1, TRUE);
 	      fd_nj_plot->tabtax[node_num]->nom[0] = (view->sel_seqs[num] ? '(' : ')');
 	      extern void set_and_show_new_cursor_seq(SEA_VIEW *view, int new_pos);
@@ -2140,11 +2261,7 @@ else if(fd_nj_plot->choix == prune_clade_found) {
 	clear_squares_below(fd_nj_plot->prune_clade_node);//nor in clade
 	}
 
-for(i=0; i<fd_nj_plot->notu; i++) {
-	int j;
-	j = strlen(fd_nj_plot->tabtax[i]->nom);
-	strcpy(fd_nj_plot->tabtax[i]->nom + j, fd_nj_plot->labels[i]);
-	}
+if (fd_nj_plot->leaf_trimmer) fd_nj_plot->leaf_trimmer->process();
 fd_nj_plot->totnoms = fd_nj_plot->tottraits = fd_nj_plot->totpoints = -1;
 end_br_length = fd_nj_plot->br_length_txt;
 currx = 0.;
@@ -2492,7 +2609,7 @@ int l;
 char *p, *q;
 
 if(centre->v1==NULL && centre->v2==NULL) {
-	p = centre->nom;
+        p = fd_nj_plot->labels[centre->rank];
 	if(*p == ')' || *p == '(') p++;//skip square mark
 	l = strlen(p);
 	if(arbre+l>=finarbre) return NULL;	
@@ -2885,6 +3002,15 @@ else {
 }
 
 
+void edit_trim_callback(Fl_Widget *obj, void *data)
+{
+  const char *rep = fl_input("Enter desired sequence name trimming rule", get_res_value("name_trimming_rule", ""));
+  if (rep) {
+    set_res_value("name_trimming_rule", rep);
+  }
+}
+
+
 void select_clade_callback(Fl_Widget *obj, void *data)
 {
 	FD_nj_plot *fd_nj_plot = (FD_nj_plot *)data;
@@ -3053,9 +3179,9 @@ void print_plot(FD_nj_plot *fd_nj_plot, bool to_ps_file, const char *directname)
   if (to_ps_file) {
     myprinter = (Fl_Printer*)new Fl_PDF_or_PS_File_Device();
     if (directname) {
-      error = ((Fl_PDF_or_PS_File_Device*)myprinter)->begin_document(directname, printout_pageformat);
+      error = ((Fl_PDF_or_PS_File_Device*)myprinter)->begin_document(directname, printout_pageformat, printout_layout);
       }
-    else error = ((Fl_PDF_or_PS_File_Device*)myprinter)->start_job(fd_nj_plot->tree_name, printout_pageformat);
+    else error = ((Fl_PDF_or_PS_File_Device*)myprinter)->start_job(fd_nj_plot->tree_name, printout_pageformat, printout_layout);
     frompage = 1;
     topage = fd_nj_plot->page_count;
     }
@@ -3379,6 +3505,12 @@ void plotonly(int argc, char *argv[])
       if (target3) while (*target3 == ' ')  target3++;
       }
     }
+  
+  char *trim = argname(argc, argv, "-trim");
+    fd_nj_plot->leaf_trimmer = new LeafNameTrimmer(0, 0, 10, 20);
+    fd_nj_plot->leaf_trimmer->user_data(fd_nj_plot);
+    fd_nj_plot->leaf_trimmer->copy_label(trim ? trim : "");
+  
   if (preptree(fd_nj_plot)) {
     free(fd_nj_plot);
     return;
@@ -3400,6 +3532,7 @@ void plotonly(int argc, char *argv[])
       strcpy(p, ".tree");
       if (strcmp(fname, pdfname) == 0) strcat(pdfname, "_2");
     }
+    if (trim) fd_nj_plot->leaf_trimmer->process_to_labels();
     // we must call runtree() so the tree is correctly oriented from its new root
     // so we must have a graphics driver to compute string widths
     Fl_PDF_Graphics_Driver* pdf_driver = new Fl_PDF_Graphics_Driver;
@@ -3446,6 +3579,11 @@ void plotonly(int argc, char *argv[])
     if (!out) return;
     physx = Fl_Paged_Device::page_formats[printout_pageformat].width;
     physy = Fl_Paged_Device::page_formats[printout_pageformat].height;
+    if (isarg(argc, argv, "-landscape")) {
+      int tmp = physx;
+      physx = physy;
+      physy = tmp;
+    }
     if (isarg(argc, argv, "-size")) {
       sscanf(argname(argc, argv, "-size"), "%lfx%lf", &physx, &physy);
       }
@@ -3458,6 +3596,7 @@ void plotonly(int argc, char *argv[])
     fl_graphics_driver = pdf_driver;
     pdf_driver->pdf = PDF_new();
     PDF_begin_document(pdf_driver->pdf, "", 0, "");
+    if (isarg(argc, argv, "-landscape")) printout_layout = Fl_Paged_Device::LANDSCAPE;
   }
   fl_font(fd_nj_plot->font_family, fd_nj_plot->font_size);
   if (isarg(argc, argv, "-branch_width_as_support")) {
@@ -3479,6 +3618,7 @@ void plotonly(int argc, char *argv[])
     if ( debut_arbre(tree, fd_unrooted) ) return;
     free(tree);
     fd_unrooted->font_size = fd_nj_plot->font_size;
+    fd_nj_plot->leaf_trimmer->process_unrooted();
     }
 
   char *select, aux[500];
diff --git a/treedraw.h b/treedraw.h
index 3b35249..fa4924e 100644
--- a/treedraw.h
+++ b/treedraw.h
@@ -44,6 +44,17 @@ public:
 	}
 };
 
+class LeafNameTrimmer : public Fl_Widget {
+public:
+  LeafNameTrimmer(int x, int y, int w, int h);
+  int handle(int event);
+  void process();
+  void process_to_labels();
+  void process_unrooted();
+  void draw();
+  int by_position();
+};
+
 struct FD_nj_plot {
 	char *tree_name;
 	char *tree_label;
@@ -115,6 +126,7 @@ struct FD_nj_plot {
   bool branch_width_as_support;
   float support_threshold_high;
   float support_threshold_low;
+  LeafNameTrimmer *leaf_trimmer;
 };
 
 extern Fl_Window *treedraw(char *tree, SEA_VIEW *view, const char *name, int from_tree_menu, int count = 1);
diff --git a/trees.cxx b/trees.cxx
index 74ebada..ef0dd57 100644
--- a/trees.cxx
+++ b/trees.cxx
@@ -12,6 +12,9 @@
 #include <FL/Fl_Value_Slider.H>
 #include <FL/Fl.H>
 #include <FL/fl_ask.H>
+#ifdef __APPLE__
+#include <FL/x.H> // for fl_mac_os_version
+#endif
 
 extern "C" {
 #include "phyml_util.h"
@@ -1123,6 +1126,7 @@ void run_phyml_callback(Fl_Widget *ob, void *data)
   else if(nni_spr_b->value()) strcat(args, " -s BEST");
   if(!u_optimize->value()) { strcat(args, " -o lr"); user_tree = TRUE; }
   if (u_quiet->value()) strcat(args, " --quiet");
+  else                  strcat(args, " --no_memory_check");
   if(u_menutree->value()) {
 	   char *tree = view->trees[u_choice->value()];
 	   if(*tree == '[' && (p = strchr(tree, ']')) != NULL) { //remove tree header
diff --git a/unrooted.cxx b/unrooted.cxx
index 3566628..c836d25 100644
--- a/unrooted.cxx
+++ b/unrooted.cxx
@@ -78,6 +78,7 @@ extern void replace_with_new_tree(FD_nj_plot *fd_nj_plot, char *newtree);
 /* globals */
 static int nextotu, num_noeud;
 extern Fl_Paged_Device::Page_Format printout_pageformat;
+extern Fl_Paged_Device::Page_Layout printout_layout;
 
 
 void rooted_unrooted_callback(Fl_Widget *o, void *data)
@@ -212,6 +213,7 @@ void squared2circular(FD_nj_plot *fd_nj_plot, Fl_Choice *o)
 	fd_unrooted->current_font = fd_nj_plot->font_family;
 	fd_unrooted->font_size = fd_nj_plot->font_size;
 	fd_nj_plot->fd_unrooted = (void *)fd_unrooted;
+  fd_nj_plot->leaf_trimmer->process_unrooted();
 }
 
 void circular2squared(FD_nj_plot *fd_nj_plot)
@@ -434,9 +436,9 @@ void print_unrooted(FD_unrooted *fd_unrooted, const char *name, bool to_ps_file,
   if (to_ps_file) {
     myprinter = (Fl_Printer*)new Fl_PDF_or_PS_File_Device();
     if (directname) 
-      error = ((Fl_PDF_or_PS_File_Device*)myprinter)->begin_document(directname, printout_pageformat);
+      error = ((Fl_PDF_or_PS_File_Device*)myprinter)->begin_document(directname, printout_pageformat, printout_layout);
     else
-      error = ((Fl_PDF_or_PS_File_Device*)myprinter)->start_job(name, printout_pageformat) ;
+      error = ((Fl_PDF_or_PS_File_Device*)myprinter)->start_job(name, printout_pageformat, printout_layout) ;
     if (error) return;
     }
   else {
@@ -694,18 +696,22 @@ return *ascend + *descend ;
 
 void free_unrooted(FD_unrooted *data)
 {
-	int i;
-	if(data->notu == 0) return;
-	/* de-allocate all memory */
-	for(i=0; i<2*data->notu - 1; i++) {
-		if(data->tabtax[i]->nom != NULL) free(data->tabtax[i]->nom);
-		free(data->tabtax[i]);
-	}
-	free(data->tabtax);
-	if(data->branche_noeuds != NULL) free(data->branche_noeuds);
-	if(data->branches != NULL) free(data->branches);
-	data->notu = 0;
-	free(data);
+  int i;
+  if(data->notu == 0) return;
+  /* de-allocate all memory */
+  for(i=0; i<2*data->notu - 1; i++) {
+    if(data->tabtax[i]->nom != NULL) free(data->tabtax[i]->nom);
+    free(data->tabtax[i]);
+  }
+  free(data->tabtax);
+  if(data->branche_noeuds != NULL) free(data->branche_noeuds);
+  for (i = 0; i < 2*data->notu - 3; i++) {
+    char *p = (data->branches+i)->nom;
+    if (p) free(p);
+  }
+  if(data->branches != NULL) free(data->branches);
+  data->notu = 0;
+  free(data);
 }
 
 
@@ -967,6 +973,7 @@ bignoeud *cre_new_tree(struct noeud *debut, struct noeud *parent, bignoeud *bigp
 	nouveau->l2 = debut->l2;
 	nouveau->l3 = debut->l3;
 	nouveau->nom = debut->nom;
+  nouveau->rank = debut->rank;
 	return nouveau;
 }
 
@@ -1186,9 +1193,10 @@ unrooted_branch *calc_position_noeuds(bignoeud *debut, bignoeud *parent,
 
 void mem_line(cp_point *debut, cp_point *fin, bignoeud *noeud_term, unrooted_branch *br)
 {
-	br->debut = *debut;
-	br->fin = *fin;
-	br->nom = noeud_term->nom;
+  br->debut = *debut;
+  br->fin = *fin;
+  br->rank = noeud_term->rank;
+  br->nom = noeud_term->nom ? strdup(noeud_term->nom) : NULL;
 }
 
 
diff --git a/unrooted.h b/unrooted.h
index e72485d..8448673 100644
--- a/unrooted.h
+++ b/unrooted.h
@@ -28,6 +28,7 @@ typedef struct _unrooted_branch {
 	cp_point debut, fin;
 	int color;
 	char *nom;
+  int rank;
 } unrooted_branch;
 
 
@@ -42,6 +43,7 @@ typedef struct _bignoeud {
 	double l1, l2, l3;
 	cp_point position;
 	char *nom;
+  int rank;
 } bignoeud;
 
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/seaview.git



More information about the debian-med-commit mailing list