/** * Yudit Unicode Editor Source File * * GNU Copyright (C) 1997-2006 Gaspar Sinai * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, * dated June 1991. See file COPYYING for details. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gui/SMessageBar.h" #include "gui/Main.h" #include "swidget/SIconFactory.h" #include "stoolkit/SCluster.h" #include "stoolkit/SCharClass.h" /** * a button panel is just a panel of labels. */ SMessageBar::SMessageBar (const SProperties props) { xmanagerCludge = true; SColor fg = SColor(props["yudit.label.foreground"]); SColor tfg = SColor(props["yudit.title.foreground"]); SString font = props["yudit.default.font"]; SString fontSizeString=props["yudit.default.fontsize"]; double fontSize=0; fontSizeString.append ((char)0); sscanf (fontSizeString.array(), "%lf", &fontSize); if (fontSize < 2.0) fontSize = 2.0; /* create the labels and set the preferred size */ SLabel *l; l = new SLabel (translate ("Glyph Info:")); l->setFont(font, fontSize); l->setForeground (tfg); labels[SS_GLYPH_TITLE] = l; l = new SLabel (""); l->setFont(font, fontSize); l->setForeground (fg); labels[SS_GLYPH_INFO] = l; l = new SLabel (translate ("Font Size:")); l->setFont(font, fontSize); l->setForeground (tfg); labels[SS_FONT_SIZE_TITLE] = l; l = new SLabel (""); l->setFont(font, fontSize); l->setForeground (fg); labels[SS_FONT_SIZE] = l; l = new SLabel (translate ("Line:")); l->setFont(font, fontSize); l->setForeground (tfg); labels[SS_ROW_TITLE] = l; l = new SLabel (""); l->setFont(font, fontSize); l->setForeground (fg); labels[SS_ROW] = l; l = new SLabel (translate ("Column:")); l->setFont(font, fontSize); l->setForeground (tfg); labels[SS_COLUMN_TITLE] = l; l = new SLabel (""); l->setFont(font, fontSize); l->setForeground (fg); labels[SS_COLUMN] = l; unsigned int p=0; unsigned int h=0; for (unsigned int i=0; i<(unsigned int) SS_MAX; i++) { unsigned int ww = 0; switch (i) { case SS_FONT_SIZE: ww = 50; break; case SS_ROW: ww = 50; break; case SS_COLUMN: ww = 50; break; case SS_GLYPH_INFO: ww = 600; break; default: ww = labels[i]->getPreferredSize().width; } unsigned int hh = labels[i]->getPreferredSize().height; labels[i]->resize(SDimension (ww, hh)); labels[i]->move(SLocation ((int)p, 0)); add (labels[i]); p+= ww +2; if (hh > h) h = hh; } preferredSize = SDimension (p, h); } /** * This routine was introduced to make this * usable on peecees with windows. * Seems like XManager has some bug that they don't * fix. On unix you could in fact get rid of this whole method. * The presiously set size got lost. I don't really know why XManager is so * popular.... */ void SMessageBar::resize(const SDimension& d) { SPanel::resize (d); /* we only need to do it once. */ if (!xmanagerCludge) { return; } xmanagerCludge = false; unsigned int p=0; unsigned int h=0; for (unsigned int i=0; i<(unsigned int) SS_MAX; i++) { unsigned int ww = 0; switch (i) { case SS_FONT_SIZE: ww = 50; break; case SS_ROW: ww = 50; break; case SS_COLUMN: ww = 50; break; case SS_GLYPH_INFO: ww = 600; break; default: ww = labels[i]->getPreferredSize().width; } unsigned int hh = labels[i]->getPreferredSize().height; labels[i]->resize(SDimension (ww, hh)); labels[i]->move(SLocation ((int)p, 0)); // Seems resize is enough to work around the bug. /* No need to labels[i]->move(SLocation ((int)p, 0)); */ p+= ww +2; if (hh > h) h = hh; } } SMessageBar::~SMessageBar () { } void SMessageBar::setRow (unsigned int row) { char a[64]; sprintf (a, "%u", row); SLabel* l = labels[SS_ROW]; l->setText (a); } void SMessageBar::setColumn (unsigned int column) { char a[64]; sprintf (a, "%u", column); SLabel* l = labels[SS_COLUMN]; l->setText (a); } void SMessageBar::setFontSize (double d) { char a[64]; sprintf (a, "%g", d); fontSize = d; SLabel* l = labels[SS_FONT_SIZE]; l->setText (a); } /** * This one draws a glyph info in the form of * compose [decomp1 decomp2] - if compose will be saved. * [compose] decomp1 decomp2 - if decomp1 decomp.. will be saved * above P:displayed is displayed presentation form is used. * @param g is the glyph * @encoded contains some extra info, when encoed with a keymap. */ void SMessageBar::setGlyphInfo (const SGlyph* g, const SString& encoded) { SUniMap shaper ("shape"); SLabel* l = labels[SS_GLYPH_INFO]; if (g==0) { l->setText(""); return; } bool savePrecomp = g->usePrecomp; SS_UCS4 precomp = g->getChar(); SS_UCS4 shape = g->getShapedChar(); SV_UCS4 decomp; SString trailer; unsigned int i; for (i=0; idecompSize(); i++) { decomp.append ((*g)[i]); } if (g->compSize()) { SV_UCS4 ca; for (i=0; icompSize(); i++) { ca.append (g->getCompArray()[i]); } trailer.append (" ; "); trailer.append (unicodeValueOf (ca)); } if (g->embedding > 0) { char a[10]; sprintf (a, "%u", (unsigned int) g->embedding); trailer.append (" e:"); trailer.append (a); if (g->getExplicitLevel()>0) { sprintf (a, "%u", g->getExplicitLevel()); trailer.append (g->isOverride() ? " xo:" : " xe:"); trailer.append (a); } } if (encoded.size()) { trailer.append (" |"); trailer.append (encoded); trailer.append ("|"); } SString compStr; if (precomp!=0) { unsigned int tp = g->getType(); /* too much info */ //if (tp < 0x1f && tp !=0) if (false) { compStr.append (ssCharClass[tp]); compStr.append (" "); } } SString decompStr; /* * shape:xxxx [decomp] * In this case we received the shape. We won't modify shape. * In this case the shape is * pre-determined and can not be changed */ if (savePrecomp && decomp.size() == 0 && precomp != 0 && shaper.isOK()) /* check if precomp can be a shape */ { SV_UCS4 ret; SV_UCS4 v; v.append (precomp); /* presentation form - get decomposition */ unsigned int n = shaper.lift (v, 0, true, &ret); if (ret.size() > 0) { decompStr.append ("["); decompStr.append (unicodeValueOf (ret)); decompStr.append ("]"); SV_UCS4 forms; n = shaper.lift (ret, 0, false, &forms); if (forms.size()==4) { for (unsigned int i=0; isetText(compStr); return; } } /* * [shape:xxxx] decomp * In this case the shape is * pre-determined and can not be changed */ if (g->currentShape!=SD_NOSHAPE && getLigatureScriptCode(shape)!= SD_BENGALI_BEGIN) { compStr.append ("["); compStr.append (getShapeCode ((unsigned int)g->currentShape)); /* shaped with presentation forms */ if (shape < 0x80000000) { compStr.append (":"); SV_UCS4 v;v.append (shape); compStr.append (unicodeValueOf (v)); } compStr.append ("]"); /* here shape can be a simgle comp or decomp */ if (savePrecomp) { SV_UCS4 v; v.append (precomp); /* decomposition is a signle char */ decompStr.append (unicodeValueOf (v)); /* precomposed glyph exists but and we use that, not compositon */ if (decomp.size() && ! (decomp.size()==1 && decomp[0] == precomp)) { decompStr.append (" ("); decompStr.append (unicodeValueOf (decomp)); decompStr.append (")"); } } else /* it is comp */ { /* precomposed glyph exists but we don't use it */ if (precomp && ! (decomp.size()==1 && decomp[0] == precomp)) { SV_UCS4 pc; pc.append (precomp); decompStr.append ("("); decompStr.append (unicodeValueOf (pc)); decompStr.append (") "); } decompStr.append (unicodeValueOf (decomp)); } compStr.append (" "); compStr.append (decompStr); compStr.append (trailer); l->setText(compStr); return; } /* * decomp .... * In this case the shape is * pre-determined and can not be changed */ if (precomp==0 && decomp.size() > 0) { if (g->getShapeArray()) { decompStr.append ("noshape:"); decompStr.append (unicodeValueOf (decomp)); } else if (g->isCluster()) { SV_UCS4 declust = g->getChars(); /* getChars returns the extra char */ if (g->compSize()) declust.truncate (declust.size()-g->compSize()); if (declust.size()==2 && declust[0] >= 0xd800 && declust[0] <= 0xdbff && declust[1] >= 0xdc00 && declust[0] <= 0xdfff) { decompStr.append ("[sgt:"); } else { decompStr.append ("[cluster:"); } decompStr.append (unicodeValueOf (decomp)); decompStr.append ("] "); decompStr.append (unicodeValueOf (declust)); } else /* xxxx xxxx */ { if (getLigatureScriptCode (decomp[0]) == SD_AS_LITERAL) { SV_UCS4 v; v.append (decomp[0] & 0xff); decompStr.append ("illegal:"); SString uv = unicodeValueOf (v); uv.remove (0); uv.remove (0); decompStr.append (uv); decomp.remove (0); decompStr.append (" ; "); } decompStr.append (unicodeValueOf (decomp)); } decompStr.append (trailer); l->setText(decompStr); return; } /** * [xxxx] decomp */ if (!savePrecomp) { compStr.append ("["); SS_UCS4 lig = precomp; if (g->isCluster()) { SString ligname ("ligature:"); const char* chr = getLigatureScript (precomp); if (chr) { ligname = SString(chr); if (getLigatureScriptCode (shape) == SD_BENGALI_BEGIN) { // for debugging bengali shaping // ligname.append ("-init"); } ligname.append (":"); lig = lig & 0xffff; } compStr.append (ligname); } SV_UCS4 v; v.append (lig); compStr.append (unicodeValueOf (v)); compStr.append ("] "); if (g->isCluster()) { // Too much info //compStr.append ("[cluster:"); //compStr.append (unicodeValueOf (decomp)); //compStr.append ("] "); /* getChars returns the extra char */ SV_UCS4 declust = g->getChars(); if (g->compSize()) declust.truncate (declust.size()-g->compSize()); compStr.append (unicodeValueOf (declust)); } else { compStr.append (unicodeValueOf (decomp)); } compStr.append (trailer); l->setText(compStr); return; } /** * xxxx [decomp] */ if (decomp.size() > 0) { if (g->getShapeArray()) decompStr.append ("noshape:"); SV_UCS4 v; v.append (precomp); compStr.append (unicodeValueOf (v)); decompStr.append ("["); decompStr.append (unicodeValueOf (decomp)); decompStr.append ("]"); compStr.append (" "); compStr.append (decompStr); compStr.append (trailer); l->setText(compStr); return; } /** * xxxx */ SV_UCS4 v; if (getLigatureScriptCode (precomp) == SD_AS_LITERAL) { v.append (precomp & 0xff); compStr.append ("illegal:"); SString uv = unicodeValueOf (v); uv.remove (0); uv.remove (0); compStr.append (uv); } else { v.append (precomp); compStr.append (unicodeValueOf (v)); } compStr.append (trailer); l->setText(compStr); return; }