[Aptitude-svn-commit] r3508 - in branches/aptitude-0.3/aptitude: . src/vscreen
Daniel Burrows
dburrows@costa.debian.org
Wed, 29 Jun 2005 18:10:59 +0000
Author: dburrows
Date: Wed Jun 29 18:10:56 2005
New Revision: 3508
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.cc
branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.h
Log:
Properly handle wide characters in vs_menu. I hope.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Wed Jun 29 18:10:56 2005
@@ -1,5 +1,9 @@
2005-06-29 Daniel Burrows <dburrows@debian.org>
+ * src/vscreen/vs_menu.cc, src/vscreen/vs_menu.h:
+
+ Rewrote vs_menu to properly handle wide characters.
+
* src/vscreen/curses++.h, src/vscreen/vscreen_widget.h:
Get rid of the attribute argument, it seems to cause unexpected
Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.cc (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.cc Wed Jun 29 18:10:56 2005
@@ -51,13 +51,13 @@
{
}
-vs_menu_item::vs_menu_item(const string &_title, const string &_binding,
- const string &_description)
+vs_menu_item::vs_menu_item(const wstring &_title, const string &_binding,
+ const wstring &_description)
:title(_title), description(_description), binding(_binding),
hotkey((chtype) ERR)
{
- for(string::size_type i=0; i<title.size(); i++)
- if(title[i]=='^' && i+1<title.size())
+ for(wstring::size_type i=0; i<title.size(); i++)
+ if(title[i]==L'^' && i+1<title.size())
{
hotkey=title[i+1];
break;
@@ -95,9 +95,9 @@
assert(inf->item_name!=NULL);
{
- vs_menu_item *newitem=new vs_menu_item(inf->item_name,
+ vs_menu_item *newitem=new vs_menu_item(transcode(inf->item_name),
inf->item_binding?inf->item_binding:"",
- inf->item_description?inf->item_description:"");
+ transcode(inf->item_description?inf->item_description:""));
if(inf->item_slot)
newitem->selected.connect(*inf->item_slot);
@@ -130,19 +130,25 @@
items.push_back(newitem);
if(newitem)
{
- string::size_type shortcutsize=0;
- string::size_type menusize=0;
+ int shortcutwidth=0;
+ int menuwidth=0;
- for(string::size_type i=0; i<newitem->get_title().size(); ++i)
- if(newitem->get_title()[i]!='^')
- ++menusize;
+ const wstring &title=newitem->get_title();
+ const string &binding=newitem->get_binding();
- if(newitem->get_binding().empty())
- shortcutsize=0;
+ for(wstring::size_type i=0; i<title.size(); ++i)
+ if(title[i]!=L'^')
+ menuwidth+=wcwidth(title[i]);
+
+ if(binding.empty())
+ shortcutwidth=0;
else
- shortcutsize=global_bindings.readable_keyname(newitem->get_binding()).size()+1;
+ {
+ wstring keyname=global_bindings.readable_keyname(binding);
+ shortcutwidth=wcswidth(keyname.c_str(), keyname.size())+1;
+ }
- req_width=max<int>(menusize+2+shortcutsize,req_width);
+ req_width=max<int>(menuwidth+2+shortcutwidth,req_width);
}
if(get_visible())
@@ -175,6 +181,9 @@
vscreen_queuelayout();
}
+// Right now the width is cached; maybe it should be calculated
+// dynamically? At the moment it probably doesn't make a difference.
+// I guess.
int vs_menu::width_request()
{
return req_width;
@@ -369,12 +378,10 @@
getmaxyx(height, width);
apply_style(border_style);
- mvaddch(0, 0, ACS_ULCORNER);
+ mvadd_wch(0, 0, WACS_ULCORNER);
for(int i=1; i<width-1; i++)
- addch(ACS_HLINE);
- addch(ACS_URCORNER);
-
- string::size_type maxlen=width-2;
+ add_wch(WACS_HLINE);
+ add_wch(WACS_URCORNER);
// Make sure that whatever is selected is really selectable.
sanitize_cursor(true);
@@ -385,27 +392,31 @@
bool boldthis=false;
apply_style(border_style);
- mvaddch(1+i, 0, ACS_VLINE);
- mvaddch(1+i, width-1, ACS_VLINE);
+ mvadd_wch(1+i, 0, WACS_VLINE);
+ mvadd_wch(1+i, width-1, WACS_VLINE);
- string title=items[i]->get_title();
- // HACK, remove once vs_menu is properly widechar-safe.
- string righttext=transcode(items[i]->get_binding().empty()?L"":global_bindings.readable_keyname(items[i]->get_binding()));
+ wstring title=items[i]->get_title();
+ wstring righttext=items[i]->get_binding().empty()?L"":global_bindings.readable_keyname(items[i]->get_binding());
bool enabled=items[i]->is_enabled();
+ style textst;
if(i==cursorloc)
- apply_style(highlighted_style);
+ textst=highlighted_style;
else if(enabled)
- apply_style(entry_style);
+ textst=entry_style;
else
- apply_style(disabled_style);
+ textst=disabled_style;
+
+ apply_style(textst);
move(1+i, 1);
- string::size_type titleloc=0, rightloc=0;
+ wstring::size_type titleloc=0, rightloc=0;
+ int rightwidth=wcswidth(righttext.c_str(), righttext.size());
+ int curw=1;
- for(string::size_type j=0; j<maxlen; j++)
+ while(curw<width-1)
{
while(titleloc<title.size() && title[titleloc]=='^')
{
@@ -415,48 +426,76 @@
if(titleloc==title.size())
{
- addch(' ');
- titleloc++;
+ add_wch(L' ');
+ ++titleloc;
+ curw+=wcwidth(L' ');;
}
else if(titleloc>title.size())
{
- if(j<maxlen-righttext.size())
- addch(' ');
+ if(curw<width-1-rightwidth)
+ {
+ add_wch(L' ');
+ curw+=wcwidth(L' ');
+ }
else
- addch((unsigned char) righttext[rightloc++]);
+ {
+ wchar_t wch=righttext[rightloc];
+
+ add_wch(wch);
+ curw+=wcwidth(wch);
+ ++rightloc;
+ }
}
else if(boldthis)
{
- addch(((unsigned char) title[titleloc++])|A_BOLD);
+ wchar_t wch=title[titleloc];
+
+ apply_style(textst+style_attrs_on(A_BOLD));
+ add_wch(wch);
+ apply_style(textst);
boldthis=false;
+
+ curw+=wcwidth(wch);
+ ++titleloc;
}
else
- addch((unsigned char) title[titleloc++]);
+ {
+ wchar_t wch=title[titleloc];
+
+ add_wch(wch);
+ curw+=wcwidth(wch);
+ ++titleloc;
+ }
}
}
else
{
apply_style(border_style);
- mvaddch(1+i, 0, ACS_LTEE);
+ mvadd_wch(1+i, 0, WACS_LTEE);
for(int j=1; j<width-1; j++)
- addch(ACS_HLINE);
- addch(ACS_RTEE);
+ add_wch(WACS_HLINE);
+ add_wch(WACS_RTEE);
}
apply_style(border_style);
+
for(int i=items.size()+1; i<height-1; i++)
{
move(i, 0);
- addch(ACS_VLINE);
+ add_wch(WACS_VLINE);
+
+ apply_style(entry_style);
for(int j=0; j<width-2; j++)
- addch(' ');
- addch(ACS_VLINE);
+ add_wch(L' ');
+ apply_style(border_style);
+
+ add_wch(WACS_VLINE);
}
- mvaddch(height-1, 0, ACS_LLCORNER);
+ mvadd_wch(height-1, 0, WACS_LLCORNER);
for(int i=1; i<width-1; i++)
- addch(ACS_HLINE);
- addch(ACS_LRCORNER);
+ add_wch(WACS_HLINE);
+ add_wch(WACS_LRCORNER);
}
bool vs_menu::get_cursorvisible()
Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.h (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.h Wed Jun 29 18:10:56 2005
@@ -19,10 +19,10 @@
class vs_menu_item
{
// The text displayed in the menu entry
- std::string title;
+ std::wstring title;
// A string describing the item's function
- std::string description;
+ std::wstring description;
// The keybinding whose definition (in the GLOBAL bindings list) is
// displayed to the right of the menu entry.
@@ -32,12 +32,12 @@
chtype hotkey;
public:
// Infers the hotkey from the title
- vs_menu_item(const std::string &_title, const std::string &_binding,
- const std::string &_description);
+ vs_menu_item(const std::wstring &_title, const std::string &_binding,
+ const std::wstring &_description);
- std::string get_title() {return title;}
+ std::wstring get_title() {return title;}
std::string get_binding() {return binding;}
- std::string get_description() {return description;}
+ std::wstring get_description() {return description;}
chtype get_hotkey() {return hotkey;}
/** The canonical way to test whether an item is really enabled. */
@@ -66,6 +66,7 @@
// VS_MENU_END: the last item in this information block
enum item_types {VS_MENU_ITEM, VS_MENU_SEPARATOR, VS_MENU_END} item_type;
+ /** item_name and item_description are multibyte representations. */
const char *item_name, *item_binding, *item_description;
// How to communicate with the outside world..