Some code improvements

This commit is contained in:
Markus Gans 2015-09-30 22:39:02 +02:00
parent 15379c61fe
commit fa05774a13
18 changed files with 514 additions and 314 deletions

View File

@ -5,15 +5,15 @@ install:
- lsb_release -a - lsb_release -a
- uname -a - uname -a
- sudo apt-get update - sudo apt-get update
- sudo apt-get -y install libglib2.0-dev libncursesw5-dev libgpm-dev autoconf-archive - sudo apt-get -y install autotools-dev automake autoconf autoconf-archive libtool libglib2.0-dev libncurses5-dev libgpm-dev gperf
- git clone git://github.com/gansm/finalcut.git - git clone git://github.com/gansm/finalcut.git
- cd finalcut - cd finalcut
- autoreconf -v --install --force - autoreconf -v --install --force
- ./configure --prefix=/usr - ./configure --prefix=/usr
- make - make V=1 -j10
- sudo make install - sudo make install
- cd .. - cd ..
- rm -rf finalcut - rm -rf finalcut
script: script:
- autoreconf -v --install --force && ./configure --prefix=/usr && make && make check - autoreconf -v --install --force && ./configure --prefix=/usr && make -j10 && make check

View File

@ -1,3 +1,6 @@
2015-09-39 Markus Gans <guru.mail@muenster.de>
* Some code improvements
2015-09-27 Markus Gans <guru.mail@muenster.de> 2015-09-27 Markus Gans <guru.mail@muenster.de>
* Add methods getPos and setPos to FRect and FWidget * Add methods getPos and setPos to FRect and FWidget

View File

@ -1,4 +1,5 @@
The Final Cut [![Build Status](https://travis-ci.org/gansm/finalcut.svg?branch=master)](https://travis-ci.org/gansm/finalcut) The Final Cut [![Build Status](https://travis-ci.org/gansm/finalcut.svg?branch=master)](https://travis-ci.org/gansm/finalcut) [![Coverity Scan Status](https://scan.coverity.com/projects/6508/badge.svg)](https://scan.coverity.com/projects/6508)
============= =============
The Final Cut is a class library and widget toolkit with full mouse support for creating a text-based user interface. The library supports the programmer to develop an application for the text console. It allows the simultaneous handling of multiple windows on the screen. The Final Cut is a class library and widget toolkit with full mouse support for creating a text-based user interface. The library supports the programmer to develop an application for the text console. It allows the simultaneous handling of multiple windows on the screen.
The C++ class design was inspired by the Qt framework. It provides common controls like dialog windows, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on. The C++ class design was inspired by the Qt framework. It provides common controls like dialog windows, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on.

View File

@ -24,5 +24,5 @@ case "$1" in
;; ;;
esac esac
make make V=1 -j10
# make install # make install

View File

@ -37,7 +37,7 @@
: ┌────┤ FApplication │ : ┌────┤ FApplication │
: │ └──────────────┘ : │ └──────────────┘
: │ ┌─────────┐1 : │ ┌─────────┐1
: ├────┤ FButton ├-----------------------------. : ├────┤ FButton ├-----------------------------
: │ └─────────┘ : : │ └─────────┘ :
: │ ┌────────┐1 : : │ ┌────────┐1 :
: ├────┤ FLabel ├------------------------------: : ├────┤ FLabel ├------------------------------:
@ -52,11 +52,11 @@
└─────────┘ │└───┬─┬───┘ ├────┤ FToggleButton │◄─┼──┤ FCheckBox ├-----: └─────────┘ │└───┬─┬───┘ ├────┤ FToggleButton │◄─┼──┤ FCheckBox ├-----:
│ :1:1 │ └───────────────┘ │ └───────────┘ : │ :1:1 │ └───────────────┘ │ └───────────┘ :
┌───────┐ │ : : │ ┌──────────────┐ │ ┌─────────┐1 : ┌───────┐ │ : : │ ┌──────────────┐ │ ┌─────────┐1 :
│ FTerm │◄─┘ : : ├────┤ FProgressbar │ └──┤ FSwitch ├-------: *┌─────────┐ │ FTerm │◄─┘ : : ├────┤ FProgressbar │ └──┤ FSwitch ├-------:
└──┬─┬──┘ : : │ └──────────────┘ └─────────┘ :---┤ FString │ └──┬─┬──┘ : : │ └──────────────┘ └─────────┘ :
:1:1 : : │ ┌────────────┐ : └─────────┘ :1:1 : : │ ┌────────────┐ : *┌─────────┐
: └----------: : ├────┤ FScrollbar │ : : └----------: : ├────┤ FScrollbar │ ├---┤ FString │
:1 : : │ └────────────┘ : :1 : : │ └────────────┘ : └─────────┘
┌────┴──────┐ : : │ ┌───────────┐1 : ┌────┴──────┐ : : │ ┌───────────┐1 :
│ FOptiMove │ : : ├────┤ FTextView ├---------------------------: │ FOptiMove │ : : ├────┤ FTextView ├---------------------------:
└───────────┘ : : │ └───────────┘ : └───────────┘ : : │ └───────────┘ :
@ -70,16 +70,23 @@
: : │ ┌─────────────┐1 : : : │ ┌─────────────┐1 :
: : ┌───┴─────┐ ┌─────────┐ ┌──┤ FFileDialog ├----: : : ┌───┴─────┐ ┌─────────┐ ┌──┤ FFileDialog ├----:
: : │ FWindow │◄─┤ FDialog │◄──┤ └─────────────┘ : : : │ FWindow │◄─┤ FDialog │◄──┤ └─────────────┘ :
: : └─────────┘ └────┬────┘ │ ┌─────────────┐1 : : : └───┬─────┘ └────┬────┘ │ ┌─────────────┐1 :
: : : └──┤ FMessageBox ├----: : : ▲ 1: └──┤ FMessageBox ├----:
: : : └─────────────┘ : : : │ : └─────────────┘ :
: : 1└------------------------------: : : │ └------------------------------:
: : : : : └───────────────────┐ ┌──────────┐ :
: └---------------------------------------------------' : : │ ┌───┤ FMenuBar │ :
: : ├───┤ └──────────┘ :
: : ┌───────────┐ │ │ ┌───────┐ :
: : │ FMenuList │◄───┘ └───┤ FMenu │ :
: : └─────┬─────┘ └───────┘ :
: : : ┌───────────┐ :
: : └------------------┤ FMenuItem │ :
: : └───────────┘ :
: └---------------------------------------------------┘
: *┌────────┐ : *┌────────┐
:---┤ FPoint │ :---┤ FPoint │
: └────────┘ : └────────┘
: *┌───────┐ : *┌───────┐
└---┤ FRect │ └---┤ FRect │
└───────┘ └───────┘

View File

@ -81,8 +81,17 @@ uChar FButton::getHotkey()
length = int(text.getLength()); length = int(text.getLength());
for (int i=0; i < length; i++) for (int i=0; i < length; i++)
if ( (i+1 < length) && (text[uInt(i)] == '&') ) {
return uChar(text[uInt(++i)]); try
{
if ( (i+1 < length) && (text[uInt(i)] == '&') )
return uChar(text[uInt(++i)]);
}
catch (const std::out_of_range&)
{
return 0;;
}
}
return 0; return 0;
} }

View File

@ -214,7 +214,7 @@ void FFileDialog::draw()
inline bool FFileDialog::pattern_match ( const char* pattern inline bool FFileDialog::pattern_match ( const char* pattern
, const char* fname ) , const char* fname )
{ {
char search[128]; char search[128] = {};
if ( show_hidden && fname[0] == '.' && fname[1] != '\0' ) // hidden files if ( show_hidden && fname[0] == '.' && fname[1] != '\0' ) // hidden files
{ {
search[0] = '.'; search[0] = '.';
@ -222,7 +222,7 @@ inline bool FFileDialog::pattern_match ( const char* pattern
strncat(search, pattern, sizeof(search) - strlen(search) - 1); strncat(search, pattern, sizeof(search) - strlen(search) - 1);
} }
else else
strncpy(search, pattern, sizeof(search)); strncpy(search, pattern, sizeof(search) - 1);
if ( fnmatch (search, fname, FNM_PERIOD) == 0 ) if ( fnmatch (search, fname, FNM_PERIOD) == 0 )
return true; return true;
@ -610,9 +610,9 @@ int FFileDialog::readDir()
if ( next->d_type == DT_LNK ) // symbolic link if ( next->d_type == DT_LNK ) // symbolic link
{ {
char resolved_path[MAXPATHLEN]; char resolved_path[MAXPATHLEN] = {};
char symLink[MAXPATHLEN]; char symLink[MAXPATHLEN] = {};
strncpy(symLink, dir, sizeof(symLink)); strncpy(symLink, dir, sizeof(symLink) - 1);
strncat(symLink, next->d_name, sizeof(symLink) - strlen(symLink) - 1); strncat(symLink, next->d_name, sizeof(symLink) - strlen(symLink) - 1);
if ( realpath(symLink, resolved_path) != 0 ) // follow link if ( realpath(symLink, resolved_path) != 0 ) // follow link

View File

@ -75,8 +75,17 @@ uChar FLabel::getHotkey()
length = text.getLength(); length = text.getLength();
for (uInt i=0; i < length; i++) for (uInt i=0; i < length; i++)
if ( (i+1 < length) && (text[i] == '&') ) {
return uChar(text[++i]); try
{
if ( (i+1 < length) && (text[i] == '&') )
return uChar(text[++i]);
}
catch (const std::out_of_range&)
{
return 0;;
}
}
return 0; return 0;
} }
@ -240,15 +249,13 @@ void FLabel::draw()
{ {
length = multiline_text[y].getLength(); length = multiline_text[y].getLength();
LabelText = new wchar_t[length+1]; LabelText = new wchar_t[length+1];
src = const_cast<wchar_t*>(multiline_text[y].wc_str());
dest = const_cast<wchar_t*>(LabelText);
if ( ! hotkey_printed ) if ( ! hotkey_printed )
{
src = const_cast<wchar_t*>(multiline_text[y].wc_str());
dest = const_cast<wchar_t*>(LabelText);
hotkeypos = getHotkeyPos(src, dest, length); hotkeypos = getHotkeyPos(src, dest, length);
}
else else
LabelText = const_cast<wchar_t*>(multiline_text[y].wc_str()); wcsncpy(dest, src, length);
gotoxy (xpos+xmin-1, ypos+ymin-1+int(y)); gotoxy (xpos+xmin-1, ypos+ymin-1+int(y));

View File

@ -12,9 +12,9 @@
FMenu::FMenu(FWidget* parent) FMenu::FMenu(FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(0) , item(0)
, selectedListItem(0)
, super_menu(0) , super_menu(0)
, maxItemWidth(0) , maxItemWidth(0)
, current(0)
, mouse_down(false) , mouse_down(false)
{ {
init(); init();
@ -24,9 +24,9 @@ FMenu::FMenu(FWidget* parent)
FMenu::FMenu (FString& txt, FWidget* parent) FMenu::FMenu (FString& txt, FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(0) , item(0)
, selectedListItem(0)
, super_menu(0) , super_menu(0)
, maxItemWidth(0) , maxItemWidth(0)
, current(0)
, mouse_down(false) , mouse_down(false)
{ {
item = new FMenuItem(txt, parent); item = new FMenuItem(txt, parent);
@ -37,9 +37,9 @@ FMenu::FMenu (FString& txt, FWidget* parent)
FMenu::FMenu (const std::string& txt, FWidget* parent) FMenu::FMenu (const std::string& txt, FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(0) , item(0)
, selectedListItem(0)
, super_menu(0) , super_menu(0)
, maxItemWidth(0) , maxItemWidth(0)
, current(0)
, mouse_down(false) , mouse_down(false)
{ {
item = new FMenuItem(txt, parent); item = new FMenuItem(txt, parent);
@ -50,9 +50,9 @@ FMenu::FMenu (const std::string& txt, FWidget* parent)
FMenu::FMenu (const char* txt, FWidget* parent) FMenu::FMenu (const char* txt, FWidget* parent)
: FWindow(parent) : FWindow(parent)
, item(0) , item(0)
, selectedListItem(0)
, super_menu(0) , super_menu(0)
, maxItemWidth(0) , maxItemWidth(0)
, current(0)
, mouse_down(false) , mouse_down(false)
{ {
item = new FMenuItem(txt, parent); item = new FMenuItem(txt, parent);
@ -101,17 +101,11 @@ void FMenu::init()
setGeometry (1, 1 , 10, 2, false); // initialize geometry values setGeometry (1, 1 , 10, 2, false); // initialize geometry values
window_object = true; window_object = true;
addWindow(this); addWindow(this);
hide();
foregroundColor = wc.menu_active_fg; foregroundColor = wc.menu_active_fg;
backgroundColor = wc.menu_active_bg; backgroundColor = wc.menu_active_bg;
FWidget* old_focus = FWidget::getFocusWidget();
if ( old_focus )
{
setFocus();
old_focus->redraw();
}
item->setMenu(this); item->setMenu(this);
} }
@ -195,25 +189,12 @@ int FMenu::getHotkeyPos (wchar_t*& src, wchar_t*& dest, uInt length)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::draw() void FMenu::draw()
{ {
if ( itemlist.empty() )
return;
if ( current < 1 )
{
current = 1;
itemlist[0]->setSelected();
}
menu_dimension();
// fill the background // fill the background
setColor (foregroundColor, backgroundColor); setColor (wc.menu_active_fg, wc.menu_active_bg);
setUpdateVTerm(false); setUpdateVTerm(false);
clrscr(); clrscr();
drawBorder(); drawBorder();
drawItems(); drawItems();
setUpdateVTerm(true); setUpdateVTerm(true);
} }
@ -393,6 +374,7 @@ void FMenu::onMouseDown (FMouseEvent* ev)
while ( iter != end ) while ( iter != end )
{ {
(*iter)->unsetSelected(); (*iter)->unsetSelected();
selectedListItem = 0;
++iter; ++iter;
} }
} }
@ -406,32 +388,36 @@ void FMenu::onMouseDown (FMouseEvent* ev)
if ( ! itemlist.empty() ) if ( ! itemlist.empty() )
{ {
std::vector<FMenuItem*>::const_iterator iter, end; std::vector<FMenuItem*>::const_iterator iter, end;
int X = 1; bool focus_changed = false;
iter = itemlist.begin(); iter = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
while ( iter != end ) while ( iter != end )
{ {
int x1, x2, mouse_x, mouse_y, txt_length; int x1, x2, y, mouse_x, mouse_y;
x1 = X; x1 = (*iter)->getX();
txt_length = int((*iter)->getText().getLength()); x2 = (*iter)->getX() + (*iter)->getWidth() - 1;
x2 = x1 + txt_length + 1; y = (*iter)->getY();
mouse_x = ev->getX(); mouse_x = ev->getX();
mouse_y = ev->getY(); mouse_y = ev->getY();
if ( mouse_x >= x1 if ( mouse_x >= x1
&& mouse_x <= x2 && mouse_x <= x2
&& mouse_y == 1 && mouse_y == y
&& ! (*iter)->isSelected() ) && ! (*iter)->isSelected() )
{ {
if ( hasSelectedListItem() )
unselectItemInList();
(*iter)->setSelected(); (*iter)->setSelected();
redraw(); selectedListItem = *iter;
focus_changed = true;
} }
X = x2 + 2;
++iter; ++iter;
} }
if ( focus_changed )
redraw();
} }
} }
@ -447,28 +433,36 @@ void FMenu::onMouseUp (FMouseEvent* ev)
if ( ! itemlist.empty() ) if ( ! itemlist.empty() )
{ {
std::vector<FMenuItem*>::const_iterator iter, end; std::vector<FMenuItem*>::const_iterator iter, end;
int X = 1; bool focus_changed = false;
iter = itemlist.begin(); iter = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
while ( iter != end ) while ( iter != end )
{ {
int x1 = X; int x1, x2, y;
int txt_length = int((*iter)->getText().getLength());
int x2 = x1 + txt_length + 1; x1 = (*iter)->getX();
x2 = (*iter)->getX() + (*iter)->getWidth() - 1;
y = (*iter)->getY();
if ( (*iter)->isSelected() ) if ( (*iter)->isSelected() )
{ {
int mouse_x = ev->getX(); int mouse_x = ev->getX();
int mouse_y = ev->getY(); int mouse_y = ev->getY();
if ( mouse_x < x1 || mouse_x > x2 || mouse_y != 1 )
(*iter)->unsetSelected(); if ( mouse_x >= x1
redraw(); && mouse_x <= x2
&& mouse_y == y )
{
(*iter)->processClicked();
redraw();
}
} }
X = x2 + 2;
++iter; ++iter;
} }
if ( focus_changed )
redraw();
} }
} }
} }
@ -483,38 +477,31 @@ void FMenu::onMouseMove (FMouseEvent* ev)
{ {
std::vector<FMenuItem*>::const_iterator iter, end; std::vector<FMenuItem*>::const_iterator iter, end;
bool focus_changed = false; bool focus_changed = false;
int X=1;
iter = itemlist.begin(); iter = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
while ( iter != end ) while ( iter != end )
{ {
int x1 = X; int x1, x2, y, mouse_x, mouse_y;
int txt_length = int((*iter)->getText().getLength());
int x2 = x1 + txt_length + 1; x1 = (*iter)->getX();
x2 = (*iter)->getX() + (*iter)->getWidth() - 1;
y = (*iter)->getY();
mouse_x = ev->getX();
mouse_y = ev->getY();
int mouse_x = ev->getX();
int mouse_y = ev->getY();
if ( mouse_x >= x1 if ( mouse_x >= x1
&& mouse_x <= x2 && mouse_x <= x2
&& mouse_y == 1 ) && mouse_y == y
&& ! (*iter)->isSelected() )
{ {
if ( ! (*iter)->isSelected() ) if ( hasSelectedListItem() )
{ unselectItemInList();
(*iter)->setSelected(); (*iter)->setSelected();
focus_changed = true; selectedListItem = *iter;
} focus_changed = true;
} }
else
{
if ( (*iter)->isSelected() )
{
(*iter)->unsetSelected();
focus_changed = true;
}
}
X = x2 + 2;
++iter; ++iter;
} }
if ( focus_changed ) if ( focus_changed )
@ -522,9 +509,31 @@ void FMenu::onMouseMove (FMouseEvent* ev)
} }
} }
//----------------------------------------------------------------------
void FMenu::show()
{
if ( ! isVisible() )
return;
FWindow::show();
// set the cursor to the focus widget
if ( FWidget::getFocusWidget()
&& FWidget::getFocusWidget()->isVisible()
&& FWidget::getFocusWidget()->hasVisibleCursor()
&& FWidget::getFocusWidget()->isCursorInside() )
{
FWidget::getFocusWidget()->setCursor();
showCursor();
flush_out();
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::hide() void FMenu::hide()
{ } {
FWindow::hide();
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::setGeometry (int xx, int yy, int ww, int hh, bool adjust) void FMenu::setGeometry (int xx, int yy, int ww, int hh, bool adjust)
@ -537,15 +546,25 @@ void FMenu::setGeometry (int xx, int yy, int ww, int hh, bool adjust)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::insert (FMenuItem* i) void FMenu::selectFirstItemInList()
{ {
FMenuList::insert(i); if ( itemlist.empty() )
return;
if ( ! hasSelectedListItem() )
{
// select the first item
itemlist[0]->setSelected();
selectedListItem = itemlist[0];
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenu::remove (FMenuItem* i) void FMenu::unselectItemInList()
{ {
FMenuList::remove(i); if ( hasSelectedListItem() )
selectedListItem->unsetSelected();
selectedListItem = 0;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -555,6 +574,17 @@ void FMenu::cb_menuitem_activated (FWidget* widget, void*)
if ( menuitem->hasMenu() ) if ( menuitem->hasMenu() )
{ {
beep(); //beep();
}
}
//----------------------------------------------------------------------
void FMenu::cb_menuitem_deactivated (FWidget* widget, void*)
{
FMenuItem* menuitem = static_cast<FMenuItem*>(widget);
if ( menuitem->hasMenu() )
{
//beep();
} }
} }

View File

@ -46,9 +46,9 @@ class FMenu : public FWindow, public FMenuList
{ {
private: private:
FMenuItem* item; FMenuItem* item;
FMenuItem* selectedListItem;
FMenuList* super_menu; FMenuList* super_menu;
uInt maxItemWidth; uInt maxItemWidth;
int current;
bool mouse_down; bool mouse_down;
private: private:
@ -57,7 +57,6 @@ class FMenu : public FWindow, public FMenuList
void init(); void init();
void menu_dimension(); void menu_dimension();
bool isMenuBar (FWidget*) const; bool isMenuBar (FWidget*) const;
FMenuList* superMenu() const; FMenuList* superMenu() const;
void setSuperMenu (FMenuList*); void setSuperMenu (FMenuList*);
int getHotkeyPos (wchar_t*&, wchar_t*&, uInt); int getHotkeyPos (wchar_t*&, wchar_t*&, uInt);
@ -77,6 +76,7 @@ class FMenu : public FWindow, public FMenuList
void onMouseDown (FMouseEvent*); void onMouseDown (FMouseEvent*);
void onMouseUp (FMouseEvent*); void onMouseUp (FMouseEvent*);
void onMouseMove (FMouseEvent*); void onMouseMove (FMouseEvent*);
void show();
void hide(); void hide();
// make every setGeometry from FWidget available // make every setGeometry from FWidget available
using FWidget::setGeometry; using FWidget::setGeometry;
@ -91,15 +91,20 @@ class FMenu : public FWindow, public FMenuList
void setSelected(); void setSelected();
void unsetSelected(); void unsetSelected();
bool isSelected() const; bool isSelected() const;
void selectFirstItemInList();
void unselectItemInList();
bool hasSelectedListItem() const;
bool hasHotkey() const; bool hasHotkey() const;
void setMenu (FMenu*); void setMenu (FMenu*);
bool hasMenu() const; bool hasMenu() const;
void setText (FString&); void setText (FString&);
void setText (const std::string&); void setText (const std::string&);
void setText (const char*); void setText (const char*);
void insert (FMenuItem*);
void remove (FMenuItem*);
void cb_menuitem_activated (FWidget*, void*); void cb_menuitem_activated (FWidget*, void*);
void cb_menuitem_deactivated (FWidget*, void*);
private:
friend class FMenuItem;
}; };
#pragma pack(pop) #pragma pack(pop)
@ -145,6 +150,10 @@ inline void FMenu::unsetSelected()
inline bool FMenu::isSelected() const inline bool FMenu::isSelected() const
{ return item->isSelected(); } { return item->isSelected(); }
//----------------------------------------------------------------------
inline bool FMenu::hasSelectedListItem() const
{ return selectedListItem; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenu::hasHotkey() const inline bool FMenu::hasHotkey() const
{ return item->hasHotkey(); } { return item->hasHotkey(); }

View File

@ -2,7 +2,7 @@
// Provides: class FMenuBar // Provides: class FMenuBar
#include "fmenubar.h" #include "fmenubar.h"
#include "fmessagebox.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// class FMenuBar // class FMenuBar
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -12,7 +12,6 @@
FMenuBar::FMenuBar(FWidget* parent) FMenuBar::FMenuBar(FWidget* parent)
: FWindow(parent) : FWindow(parent)
, mouse_down(false) , mouse_down(false)
, x(-1)
{ {
init(); init();
} }
@ -113,22 +112,16 @@ void FMenuBar::draw()
xmin = ymin = 1; xmin = ymin = 1;
height = 1; height = 1;
xpos = 1; xpos = 1;
menu_dimension();
drawItems(); drawItems();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuBar::drawItems() void FMenuBar::drawItems()
{ {
bool is_Active;
bool is_Selected;
bool is_NoUnderline;
std::vector<FMenuItem*>::const_iterator iter, end; std::vector<FMenuItem*>::const_iterator iter, end;
int screenWidth; int screenWidth;
x = 1; int x = 1;
screenWidth = getColumnNumber(); screenWidth = getColumnNumber();
width = screenWidth; width = screenWidth;
ypos = 1; ypos = 1;
@ -150,7 +143,7 @@ void FMenuBar::drawItems()
FString txt; FString txt;
uInt txt_length; uInt txt_length;
int hotkeypos, to_char; int hotkeypos, to_char;
bool is_Active, is_Selected, is_NoUnderline;
is_Active = (*iter)->isActivated(); is_Active = (*iter)->isActivated();
is_Selected = (*iter)->isSelected(); is_Selected = (*iter)->isSelected();
@ -229,7 +222,8 @@ void FMenuBar::drawItems()
x++; x++;
print (vmenubar, ' '); print (vmenubar, ' ');
} }
setColor (wc.menu_active_fg, wc.menu_active_bg);
if ( is_Active && is_Selected ) if ( is_Active && is_Selected )
setReverse(false); setReverse(false);
delete[] item_text; delete[] item_text;
@ -282,38 +276,52 @@ void FMenuBar::onMouseDown (FMouseEvent* ev)
if ( ! itemlist.empty() ) if ( ! itemlist.empty() )
{ {
std::vector<FMenuItem*>::const_iterator iter, end; std::vector<FMenuItem*>::const_iterator iter, end;
int X = 1; bool focus_changed = false;
iter = itemlist.begin(); iter = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
//FMessageBox::info (this, "Info", FString().sprintf("local(%d,%d) global(%d,%d)", ev->getX(),ev->getY(),ev->getGlobalX(), ev->getGlobalY())); // + #include //FMessageBox::info (this, "Info", FString().sprintf("local(%d,%d) global(%d,%d)", ev->getX(),ev->getY(),ev->getGlobalX(), ev->getGlobalY()));
// #include "fmessagebox.h"
while ( iter != end ) while ( iter != end )
{ {
int x1, x2, mouse_x, mouse_y, txt_length; int x1, x2, mouse_x, mouse_y;
x1 = X; x1 = (*iter)->getX();
txt_length = int((*iter)->getTextLength()); x2 = (*iter)->getX() + (*iter)->getWidth() - 1;
mouse_x = ev->getX();
x2 = x1 + txt_length + 1; mouse_y = ev->getY();
mouse_x = ev->getGlobalX();
mouse_y = ev->getGlobalY();
if ( mouse_x >= x1 if ( mouse_x >= x1
&& mouse_x <= x2 && mouse_x <= x2
&& mouse_y == 1 && mouse_y == 1 )
&& ! (*iter)->isSelected() )
{ {
(*iter)->setSelected(); if ( ! (*iter)->isSelected() )
redraw(); {
(*iter)->setSelected();
focus_changed = true;
}
if ( (*iter)->hasMenu() )
{
FMenu* menu = (*iter)->getMenu();
if ( menu->hasSelectedListItem() )
{
menu->unselectItemInList();
menu->redraw();
}
}
} }
else else
{ {
(*iter)->unsetSelected(); if ( mouse_y == 1 && (*iter)->isSelected() )
redraw(); {
(*iter)->unsetSelected();
focus_changed = true;
}
} }
X = x2 + 1;
++iter; ++iter;
} }
if ( focus_changed )
redraw();
} }
} }
@ -329,32 +337,40 @@ void FMenuBar::onMouseUp (FMouseEvent* ev)
if ( ! itemlist.empty() ) if ( ! itemlist.empty() )
{ {
std::vector<FMenuItem*>::const_iterator iter, end; std::vector<FMenuItem*>::const_iterator iter, end;
int X = 1;
iter = itemlist.begin(); iter = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
while ( iter != end ) while ( iter != end )
{ {
int x1, x2, txt_length; int x1, x2, mouse_x, mouse_y;
x1 = X; x1 = (*iter)->getX();
txt_length = int((*iter)->getTextLength()); x2 = (*iter)->getX() + (*iter)->getWidth() - 1;
x2 = x1 + txt_length + 1; mouse_x = ev->getX();
mouse_y = ev->getY();
if ( (*iter)->isSelected() ) if ( mouse_x >= x1
&& mouse_x <= x2
&& mouse_y == 1
&& (*iter)->isSelected() )
{ {
int mouse_x = ev->getGlobalX(); if ( (*iter)->hasMenu() )
int mouse_y = ev->getGlobalY(); {
if ( mouse_x < x1 || mouse_x > x2 || mouse_y != 1 ) FMenu* menu = (*iter)->getMenu();
(*iter)->unsetSelected(); if ( ! menu->hasSelectedListItem() )
{
menu->selectFirstItemInList();
menu->redraw();
}
}
else else
{ {
(*iter)->unsetSelected();
redraw();
(*iter)->processClicked(); (*iter)->processClicked();
} }
redraw();
} }
X = x2 + 1;
++iter; ++iter;
} }
} }
@ -371,40 +387,46 @@ void FMenuBar::onMouseMove (FMouseEvent* ev)
{ {
std::vector<FMenuItem*>::const_iterator iter, end; std::vector<FMenuItem*>::const_iterator iter, end;
bool focus_changed = false; bool focus_changed = false;
int X=1;
iter = itemlist.begin(); iter = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
while ( iter != end ) while ( iter != end )
{ {
int x1, x2, txt_length; int x1, x2, mouse_x, mouse_y;
x1 = X; x1 = (*iter)->getX();
txt_length = int((*iter)->getTextLength()); x2 = (*iter)->getX() + (*iter)->getWidth() - 1;
x2 = x1 + txt_length + 1; mouse_x = ev->getX();
mouse_y = ev->getY();
int mouse_x = ev->getGlobalX();
int mouse_y = ev->getGlobalY();
if ( mouse_x >= x1 if ( mouse_x >= x1
&& mouse_x <= x2 && mouse_x <= x2
&& mouse_y == 1 ) && mouse_y == 1 )
{ {
if ( ! (*iter)->isSelected() ) if ( ! (*iter)->isSelected() )
{ {
(*iter)->setSelected(); (*iter)->setSelected();
focus_changed = true; focus_changed = true;
} }
if ( (*iter)->hasMenu() )
{
FMenu* menu = (*iter)->getMenu();
if ( menu->hasSelectedListItem() )
{
menu->unselectItemInList();
menu->redraw();
}
}
} }
else else
{ {
if ( (*iter)->isSelected() ) if ( mouse_y == 1 && (*iter)->isSelected() )
{ {
(*iter)->unsetSelected(); (*iter)->unsetSelected();
focus_changed = true; focus_changed = true;
} }
} }
X = x2 + 1;
++iter; ++iter;
} }
if ( focus_changed ) if ( focus_changed )
@ -429,7 +451,7 @@ void FMenuBar::hide()
memset(blank, ' ', uLong(screenWidth)); memset(blank, ' ', uLong(screenWidth));
blank[screenWidth] = '\0'; blank[screenWidth] = '\0';
gotoxy (1, 1); gotoxy (1,1);
print (vmenubar, blank); print (vmenubar, blank);
delete[] blank; delete[] blank;
} }
@ -451,6 +473,36 @@ void FMenuBar::cb_item_activated (FWidget* widget, void*)
if ( menuitem->hasMenu() ) if ( menuitem->hasMenu() )
{ {
beep(); //beep();
FMenu* menu = menuitem->getMenu();
if ( ! menu->isVisible() )
{
menu->setVisible();
menu->show();
raiseWindow(menu);
menu->redraw();
}
updateTerminal();
flush_out();
}
}
//----------------------------------------------------------------------
void FMenuBar::cb_item_deactivated (FWidget* widget, void*)
{
FMenuItem* menuitem = static_cast<FMenuItem*>(widget);
if ( menuitem->hasMenu() )
{
//beep();
FMenu* menu = menuitem->getMenu();
if ( menu->isVisible() )
menu->hide();
restoreVTerm (menu->getGeometryGlobalShadow());
updateTerminal();
flush_out();
} }
} }

View File

@ -45,8 +45,7 @@
class FMenuBar : public FWindow, public FMenuList class FMenuBar : public FWindow, public FMenuList
{ {
private: private:
bool mouse_down; bool mouse_down;
int x;
private: private:
FMenuBar (const FMenuBar&); FMenuBar (const FMenuBar&);
@ -72,6 +71,7 @@ class FMenuBar : public FWindow, public FMenuList
using FWidget::setGeometry; using FWidget::setGeometry;
void setGeometry (int, int, int, int, bool = true); void setGeometry (int, int, int, int, bool = true);
void cb_item_activated (FWidget*, void*); void cb_item_activated (FWidget*, void*);
void cb_item_deactivated (FWidget*, void*);
private: private:
friend class FMenuItem; friend class FMenuItem;

View File

@ -100,7 +100,9 @@ void FMenuItem::init (FWidget* parent)
{ {
setSuperMenu( dynamic_cast<FMenuList*>(parent) ); setSuperMenu( dynamic_cast<FMenuList*>(parent) );
superMenu()->insert(this); superMenu()->insert(this);
dynamic_cast<FMenuBar*>(parent)->menu_dimension(); FMenuBar* menubar_ptr = dynamic_cast<FMenuBar*>(parent);
if ( menubar_ptr )
menubar_ptr->menu_dimension();
//addAccelerator (item->getKey(), item); //addAccelerator (item->getKey(), item);
@ -109,12 +111,19 @@ void FMenuItem::init (FWidget* parent)
"activate", "activate",
_METHOD_CALLBACK (superMenu(), &FMenuBar::cb_item_activated) _METHOD_CALLBACK (superMenu(), &FMenuBar::cb_item_activated)
); );
this->addCallback
(
"deactivate",
_METHOD_CALLBACK (superMenu(), &FMenuBar::cb_item_deactivated)
);
} }
else if ( isMenu(parent) ) // Parent is menu else if ( isMenu(parent) ) // Parent is menu
{ {
setSuperMenu( dynamic_cast<FMenuList*>(parent) ); setSuperMenu( dynamic_cast<FMenuList*>(parent) );
superMenu()->insert(this); superMenu()->insert(this);
FMenu* super_menu_ptr = dynamic_cast<FMenu*>(parent);
if ( super_menu_ptr )
super_menu_ptr->menu_dimension();
//addAccelerator (item->getKey(), item); //addAccelerator (item->getKey(), item);
@ -123,6 +132,11 @@ void FMenuItem::init (FWidget* parent)
"activate", "activate",
_METHOD_CALLBACK (superMenu(), &FMenu::cb_menuitem_activated) _METHOD_CALLBACK (superMenu(), &FMenu::cb_menuitem_activated)
); );
this->addCallback
(
"deactivate",
_METHOD_CALLBACK (superMenu(), &FMenu::cb_menuitem_deactivated)
);
} }
} }
} }
@ -138,15 +152,29 @@ uChar FMenuItem::getHotkey()
length = text.getLength(); length = text.getLength();
for (uInt i=0; i < length; i++) for (uInt i=0; i < length; i++)
if ( (i+1 < length) && (text[i] == '&') ) {
return uChar(text[++i]); try
{
if ( (i+1 < length) && (text[i] == '&') )
return uChar(text[++i]);
}
catch (const std::out_of_range&)
{
return 0;;
}
}
return 0; return 0;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenuItem::isMenuBar (FMenuList* ml) const bool FMenuItem::isMenuBar (FMenuList* ml) const
{ {
return isMenuBar (dynamic_cast<FWidget*>(ml)); FWidget* menubar_ptr = dynamic_cast<FWidget*>(ml);
if ( menubar_ptr )
return isMenuBar(menubar_ptr);
else
return false;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -159,7 +187,12 @@ bool FMenuItem::isMenuBar (FWidget* w) const
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool FMenuItem::isMenu (FMenuList* ml) const bool FMenuItem::isMenu (FMenuList* ml) const
{ {
return isMenu (dynamic_cast<FWidget*>(ml)); FWidget* super_menu_ptr = dynamic_cast<FWidget*>(ml);
if ( super_menu_ptr )
return isMenu(super_menu_ptr);
else
return false;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -187,6 +220,12 @@ void FMenuItem::processActivate()
emitCallback("activate"); emitCallback("activate");
} }
//----------------------------------------------------------------------
void FMenuItem::processDeactivate()
{
emitCallback("deactivate");
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FMenuItem::processClicked() void FMenuItem::processClicked()
{ {
@ -201,7 +240,7 @@ void FMenuItem::onAccel (FAccelEvent* ev)
{ {
unsetSelected(); unsetSelected();
FWidget* w = reinterpret_cast<FWidget*>(superMenu()); FWidget* w = reinterpret_cast<FWidget*>(superMenu());
if ( isMenuBar(w) ) if ( w && isMenuBar(w) )
w->redraw(); w->redraw();
ev->accept(); ev->accept();
} }
@ -216,12 +255,15 @@ void FMenuItem::onMouseDown (FMouseEvent* ev)
int b = ev->getButton(); int b = ev->getButton();
p2 = p1 + getPos() - FPoint(1,1); p2 = p1 + getPos() - FPoint(1,1);
ev = new FMouseEvent (MouseMove_Event, p2, g, b); ev = new FMouseEvent (MouseMove_Event, p2, g, b);
if ( isMenu(super_menu) )
dynamic_cast<FMenu*>(super_menu)->onMouseDown(ev);
if ( isMenuBar(super_menu) ) if ( super_menu )
dynamic_cast<FMenuBar*>(super_menu)->onMouseDown(ev); {
if ( isMenu(super_menu) )
dynamic_cast<FMenu*>(super_menu)->onMouseDown(ev);
if ( isMenuBar(super_menu) )
dynamic_cast<FMenuBar*>(super_menu)->onMouseDown(ev);
}
delete ev; delete ev;
} }
@ -236,11 +278,14 @@ void FMenuItem::onMouseUp (FMouseEvent* ev)
p2 = p1 + getPos() - FPoint(1,1); p2 = p1 + getPos() - FPoint(1,1);
ev = new FMouseEvent (MouseMove_Event, p2, g, b); ev = new FMouseEvent (MouseMove_Event, p2, g, b);
if ( isMenu(super_menu) ) if ( super_menu )
dynamic_cast<FMenu*>(super_menu)->onMouseUp(ev); {
if ( isMenu(super_menu) )
if ( isMenuBar(super_menu) ) dynamic_cast<FMenu*>(super_menu)->onMouseUp(ev);
dynamic_cast<FMenuBar*>(super_menu)->onMouseUp(ev);
if ( isMenuBar(super_menu) )
dynamic_cast<FMenuBar*>(super_menu)->onMouseUp(ev);
}
delete ev; delete ev;
} }
@ -255,11 +300,14 @@ void FMenuItem::onMouseMove (FMouseEvent* ev)
p2 = p1 + getPos() - FPoint(1,1); p2 = p1 + getPos() - FPoint(1,1);
ev = new FMouseEvent (MouseMove_Event, p2, g, b); ev = new FMouseEvent (MouseMove_Event, p2, g, b);
if ( isMenu(super_menu) ) if ( super_menu )
dynamic_cast<FMenu*>(super_menu)->onMouseMove(ev); {
if ( isMenu(super_menu) )
if ( isMenuBar(super_menu) ) dynamic_cast<FMenu*>(super_menu)->onMouseMove(ev);
dynamic_cast<FMenuBar*>(super_menu)->onMouseMove(ev);
if ( isMenuBar(super_menu) )
dynamic_cast<FMenuBar*>(super_menu)->onMouseMove(ev);
}
delete ev; delete ev;
} }
@ -275,7 +323,14 @@ void FMenuItem::setSelected()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenuItem::setText (FString& txt) void FMenuItem::unsetSelected()
{
selected = false;
processDeactivate();
}
//----------------------------------------------------------------------
void FMenuItem::setText (FString& txt)
{ {
text = txt; text = txt;
text_length = text.getLength(); text_length = text.getLength();
@ -288,21 +343,11 @@ inline void FMenuItem::setText (FString& txt)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenuItem::setText (const std::string& txt) inline void FMenuItem::setText (const std::string& txt)
{ {
text = txt; setText (FString(txt));
text_length = text.getLength();
hotkey = getHotkey();
if ( hotkey )
text_length--;
setWidth(text_length);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FMenuItem::setText (const char* txt) inline void FMenuItem::setText (const char* txt)
{ {
text = txt; setText (FString(txt));
text_length = text.getLength();
hotkey = getHotkey();
if ( hotkey )
text_length--;
setWidth(text_length);
} }

View File

@ -66,6 +66,7 @@ class FMenuItem : public FWidget
FMenuList* superMenu() const; FMenuList* superMenu() const;
void setSuperMenu (FMenuList*); void setSuperMenu (FMenuList*);
void processActivate(); void processActivate();
void processDeactivate();
void processClicked(); void processClicked();
public: public:
@ -104,6 +105,7 @@ class FMenuItem : public FWidget
private: private:
friend class FMenuList; friend class FMenuList;
friend class FMenuBar; friend class FMenuBar;
friend class FMenu;
}; };
#pragma pack(pop) #pragma pack(pop)
@ -125,10 +127,6 @@ inline void FMenuItem::unsetActive()
inline bool FMenuItem::isActivated() const inline bool FMenuItem::isActivated() const
{ return active; } { return active; }
//----------------------------------------------------------------------
inline void FMenuItem::unsetSelected()
{ selected = false; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FMenuItem::isSelected() const inline bool FMenuItem::isSelected() const
{ return selected; } { return selected; }

View File

@ -357,9 +357,8 @@ int FOptiMove::relative_move ( char*& move
if ( to_x != from_x ) // horizontal move if ( to_x != from_x ) // horizontal move
{ {
char str[sizeof(move_buf)]; char str[sizeof(move_buf)] = {};
char hmove[sizeof(move_buf)]; char hmove[sizeof(move_buf)] = {};
hmove[0] = '\0';
htime = LONG_DURATION; htime = LONG_DURATION;
if ( F_column_address.cap ) if ( F_column_address.cap )
@ -460,7 +459,7 @@ int FOptiMove::relative_move ( char*& move
if ( move ) if ( move )
strcat (move, hmove); strcat (move, hmove);
else else
move = hmove; strcpy (move, hmove);
} }
return (vtime + htime); return (vtime + htime);

View File

@ -155,8 +155,7 @@ FString::FString (const std::string& s)
if ( wc_string ) if ( wc_string )
{ {
_replace( wc_string ); _replace( wc_string );
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
} }
} }
} }
@ -174,8 +173,7 @@ FString::FString (const char* s)
if ( wc_string ) if ( wc_string )
{ {
_replace( wc_string ); _replace( wc_string );
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
} }
} }
@ -223,7 +221,7 @@ inline void FString::initLength (uInt len)
{ {
length = len; length = len;
bufsize = FWDBUFFER + len + 1; bufsize = FWDBUFFER + len + 1;
string = new wchar_t[bufsize]; string = new wchar_t[bufsize]();
wmemset(string, L'\0', bufsize); wmemset(string, L'\0', bufsize);
} }
} }
@ -239,7 +237,7 @@ inline void FString::_replace (const wchar_t* s)
try try
{ {
string = new wchar_t[bufsize]; string = new wchar_t[bufsize]();
} }
catch (const std::bad_alloc& ex) catch (const std::bad_alloc& ex)
{ {
@ -265,7 +263,7 @@ inline void FString::_insert (uInt pos, uInt len, const wchar_t* s)
bufsize = FWDBUFFER + length + 1; bufsize = FWDBUFFER + length + 1;
try try
{ {
string = new wchar_t[bufsize]; string = new wchar_t[bufsize]();
} }
catch (const std::bad_alloc& ex) catch (const std::bad_alloc& ex)
{ {
@ -296,7 +294,7 @@ inline void FString::_insert (uInt pos, uInt len, const wchar_t* s)
try try
{ {
sptr = new wchar_t[bufsize]; // generate new string sptr = new wchar_t[bufsize](); // generate new string
} }
catch (const std::bad_alloc& ex) catch (const std::bad_alloc& ex)
{ {
@ -334,7 +332,7 @@ inline void FString::_remove (uInt pos, uInt len)
try try
{ {
sptr = new wchar_t[bufsize]; // generate new string sptr = new wchar_t[bufsize](); // generate new string
} }
catch (const std::bad_alloc& ex) catch (const std::bad_alloc& ex)
{ {
@ -361,7 +359,19 @@ inline char* FString::wc_to_c_str (const wchar_t* s) const
if ( ! s ) // handle NULL string if ( ! s ) // handle NULL string
return 0; return 0;
if ( ! *s ) // handle empty string if ( ! *s ) // handle empty string
return const_cast<char*>(""); {
try
{
// Generate a empty string ("")
c_string = new char[1]();
}
catch (const std::bad_alloc& ex)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
return 0;
}
return c_string;
}
if ( c_string ) if ( c_string )
delete[](c_string); delete[](c_string);
@ -373,7 +383,7 @@ inline char* FString::wc_to_c_str (const wchar_t* s) const
try try
{ {
c_string = new char[dest_size]; c_string = new char[dest_size]();
// pre-initialiaze the whole string with '\0' // pre-initialiaze the whole string with '\0'
memset (c_string, '\0', size_t(dest_size)); memset (c_string, '\0', size_t(dest_size));
@ -405,7 +415,18 @@ inline wchar_t* FString::c_to_wc_str (const char* s) const
if ( ! s ) // handle NULL string if ( ! s ) // handle NULL string
return 0; return 0;
if ( ! *s ) // handle empty string if ( ! *s ) // handle empty string
return const_cast<wchar_t*>(L""); {
try
{
// Generate a empty wide string (L"")
return (new wchar_t[1]());
}
catch (const std::bad_alloc& ex)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
return 0;
}
}
size = int(strlen(s)) + 1; size = int(strlen(s)) + 1;
dest_size = size * int(CHAR_SIZE); dest_size = size * int(CHAR_SIZE);
@ -415,7 +436,7 @@ inline wchar_t* FString::c_to_wc_str (const char* s) const
try try
{ {
dest = new wchar_t[size]; dest = new wchar_t[size]();
// pre-initialiaze the whole string with '\0' // pre-initialiaze the whole string with '\0'
wmemset (dest, L'\0', size_t(size)); wmemset (dest, L'\0', size_t(size));
} }
@ -490,8 +511,7 @@ std::istream& operator >> (std::istream& instr, FString& s)
if ( wc_str ) if ( wc_str )
{ {
s._replace (wc_str); s._replace (wc_str);
if ( *wc_str ) delete[] wc_str;
delete[] wc_str;
} }
return (instr); return (instr);
} }
@ -550,8 +570,7 @@ FString& FString::operator = (const std::string& s)
if ( wc_string ) if ( wc_string )
{ {
_replace( wc_string ); _replace( wc_string );
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
} }
else else
length = bufsize = 0, string = 0; length = bufsize = 0, string = 0;
@ -565,8 +584,7 @@ const FString& FString::operator = (const char* s)
if ( wc_string ) if ( wc_string )
{ {
_replace( wc_string ); _replace( wc_string );
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
} }
else else
length = bufsize = 0, string = 0; length = bufsize = 0, string = 0;
@ -621,8 +639,7 @@ const FString& FString::operator += (const std::string& s)
if ( wc_string ) if ( wc_string )
{ {
_insert (length, uInt(s.length()), wc_string); _insert (length, uInt(s.length()), wc_string);
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
} }
return (*this); return (*this);
} }
@ -634,8 +651,7 @@ const FString& FString::operator += (const char* s)
if ( wc_string ) if ( wc_string )
{ {
_insert (length, uInt(strlen(s)), wc_string); _insert (length, uInt(strlen(s)), wc_string);
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
} }
return (*this); return (*this);
} }
@ -686,9 +702,9 @@ const FString FString::operator + (const std::string& s)
wchar_t* wc_string = c_to_wc_str(s.c_str()); wchar_t* wc_string = c_to_wc_str(s.c_str());
if ( ! wc_string ) if ( ! wc_string )
return (tmp); return (tmp);
tmp._insert (length, uInt(wcslen(wc_string)), wc_string); tmp._insert (length, uInt(wcslen(wc_string)), wc_string);
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
return (tmp); return (tmp);
} }
@ -700,8 +716,8 @@ const FString FString::operator + (const char* s)
if ( ! wc_string ) if ( ! wc_string )
return (tmp); return (tmp);
tmp._insert (length, uInt(wcslen(wc_string)), wc_string); tmp._insert (length, uInt(wcslen(wc_string)), wc_string);
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
return (tmp); return (tmp);
} }
@ -878,7 +894,7 @@ FString& FString::sprintf (const char* format, ...)
if ( len >= int(sizeof(buf)) ) if ( len >= int(sizeof(buf)) )
{ {
buffer = new char[len+1]; buffer = new char[len+1]();
va_start (args, format); va_start (args, format);
vsnprintf (buffer, uLong(len+1), format, args); vsnprintf (buffer, uLong(len+1), format, args);
va_end (args); va_end (args);
@ -888,8 +904,7 @@ FString& FString::sprintf (const char* format, ...)
if ( wc_string ) if ( wc_string )
{ {
_replace(wc_string); _replace(wc_string);
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
} }
if ( buffer != buf ) if ( buffer != buf )
delete[] buffer; delete[] buffer;
@ -1282,8 +1297,7 @@ FString& FString::setString (const char* s)
if ( wc_string ) if ( wc_string )
{ {
_replace (wc_string); _replace (wc_string);
if ( *wc_string ) delete[] wc_string;
delete[] wc_string;
} }
return (*this); return (*this);
} }

View File

@ -330,7 +330,7 @@ int FTerm::setScreenFont (uChar* fontdata, uInt count,
font.data = fontdata; font.data = fontdata;
else else
{ {
const uInt bytes_per_line = uInt(ceil(font.width/8)); const uInt bytes_per_line = font.width / 8;
const size_t data_size = bytes_per_line * 32 * font.charcount; const size_t data_size = bytes_per_line * 32 * font.charcount;
try try
@ -776,8 +776,8 @@ int FTerm::parseKeyString ( char* buffer
// look for meta keys // look for meta keys
for (int i=0; Fmetakey[i].string[0] != 0; i++) for (int i=0; Fmetakey[i].string[0] != 0; i++)
{ {
char* kmeta = Fmetakey[i].string; char* kmeta = Fmetakey[i].string; // The string is never null
len = (kmeta) ? int(strlen(kmeta)) : 0; len = int(strlen(kmeta));
if ( kmeta && strncmp(kmeta, buffer, uInt(len)) == 0 ) // found if ( kmeta && strncmp(kmeta, buffer, uInt(len)) == 0 ) // found
{ {
if ( len == 2 && ( buffer[1] == 'O' if ( len == 2 && ( buffer[1] == 'O'
@ -805,7 +805,7 @@ int FTerm::parseKeyString ( char* buffer
if ( utf8_input && (firstchar & 0xc0) == 0xc0 ) if ( utf8_input && (firstchar & 0xc0) == 0xc0 )
{ {
char utf8char[4] = { '\0' }; // init array with '\0' char utf8char[4] = {}; // init array with '\0'
if ((firstchar & 0xe0) == 0xc0) if ((firstchar & 0xe0) == 0xc0)
len = 2; len = 2;
else if ((firstchar & 0xf0) == 0xe0) else if ((firstchar & 0xf0) == 0xe0)
@ -948,6 +948,8 @@ void FTerm::init()
stdin_no = fileno(stdin); stdin_no = fileno(stdin);
stdout_no = fileno(stdout); stdout_no = fileno(stdout);
stdin_status_flags = fcntl(stdin_no, F_GETFL); stdin_status_flags = fcntl(stdin_no, F_GETFL);
if ( stdin_status_flags == -1 )
std::abort();
term_name = ttyname(stdout_no); term_name = ttyname(stdout_no);
// look into /etc/ttytype for the type // look into /etc/ttytype for the type
@ -994,7 +996,7 @@ void FTerm::init()
background_color_erase = false; background_color_erase = false;
x11_button_state = 0x03; x11_button_state = 0x03;
termtype = getenv("TERM"); termtype = getenv(const_cast<char*>("TERM"));
if ( ! termtype ) if ( ! termtype )
termtype = const_cast<char*>("vt100"); termtype = const_cast<char*>("vt100");
locale_xterm = getenv("XTERM_LOCALE"); locale_xterm = getenv("XTERM_LOCALE");
@ -1112,80 +1114,90 @@ void FTerm::init()
FString temp = Sec_DA->right(Sec_DA->getLength() - 3); FString temp = Sec_DA->right(Sec_DA->getLength() - 3);
temp.remove(temp.getLength()-1, 1); temp.remove(temp.getLength()-1, 1);
std::vector<FString> Sec_DA_split = temp.split(';'); std::vector<FString> Sec_DA_split = temp.split(';');
FString* Sec_DA_components = &Sec_DA_split[0];
switch ( Sec_DA_components[0].toInt() ) if ( Sec_DA_split.size() >= 2 )
{ {
case 0: FString* Sec_DA_components = &Sec_DA_split[0];
if ( Sec_DA_components[1].toInt() == 136 )
putty_terminal = true; // PuTTY
break;
case 1: switch ( Sec_DA_components[0].toInt() )
// also used by apple terminal {
if ( strncmp(Sec_DA_components[1].c_str(), "2c", 2) == 0 ) case 0:
kterm_terminal = true; // kterm if ( Sec_DA_components[1]
else && Sec_DA_components[1].toInt() == 136 )
{ {
gnome_terminal = true; // vte / gnome terminal putty_terminal = true; // PuTTY
if ( color256 ) }
termtype = const_cast<char*>("gnome-256color"); break;
case 1:
// also used by apple terminal
if ( Sec_DA_components[1]
&& strncmp(Sec_DA_components[1].c_str(), "2c", 2) == 0 )
{
kterm_terminal = true; // kterm
}
else else
termtype = const_cast<char*>("gnome"); {
} gnome_terminal = true; // vte / gnome terminal
break; if ( color256 )
termtype = const_cast<char*>("gnome-256color");
case 32: // Tera Term else
tera_terminal = true; termtype = const_cast<char*>("gnome");
termtype = const_cast<char*>("teraterm"); }
break; break;
case 77: // mintty case 32: // Tera Term
mintty_terminal = true; tera_terminal = true;
termtype = const_cast<char*>("xterm-256color"); termtype = const_cast<char*>("teraterm");
// application escape key mode break;
tputs ("\033[?7727h", 1, putchar);
fflush(stdout); case 77: // mintty
break; mintty_terminal = true;
termtype = const_cast<char*>("xterm-256color");
case 83: // screen // application escape key mode
screen_terminal = true; tputs ("\033[?7727h", 1, putchar);
break; fflush(stdout);
break;
case 82: // rxvt
rxvt_terminal = true; case 83: // screen
force_vt100 = true; // this rxvt terminal support on utf-8 screen_terminal = true;
if ( strncmp(termtype, "rxvt-", 5) != 0 break;
|| strncmp(termtype, "rxvt-cygwin-native", 5) == 0 )
termtype = const_cast<char*>("rxvt-16color"); case 82: // rxvt
break; rxvt_terminal = true;
force_vt100 = true; // this rxvt terminal support on utf-8
case 85: // rxvt-unicode if ( strncmp(termtype, "rxvt-", 5) != 0
rxvt_terminal = true; || strncmp(termtype, "rxvt-cygwin-native", 5) == 0 )
urxvt_terminal = true; termtype = const_cast<char*>("rxvt-16color");
if ( strncmp(termtype, "rxvt-", 5) != 0 ) break;
{
if ( color256 ) case 85: // rxvt-unicode
termtype = const_cast<char*>("rxvt-256color"); rxvt_terminal = true;
else urxvt_terminal = true;
termtype = const_cast<char*>("rxvt"); if ( strncmp(termtype, "rxvt-", 5) != 0 )
} {
break; if ( color256 )
termtype = const_cast<char*>("rxvt-256color");
default: else
break; termtype = const_cast<char*>("rxvt");
}
break;
default:
break;
}
} }
} }
// end of terminal detection // end of terminal detection
if ( strncmp(termtype, "xterm", 5) == 0 if ( strncmp(termtype, const_cast<char*>("xterm"), 5) == 0
|| strncmp(termtype, "Eterm", 4) == 0 ) || strncmp(termtype, const_cast<char*>("Eterm"), 4) == 0 )
xterm = true; xterm = true;
else else
xterm = false; xterm = false;
if ( strncmp(termtype, "linux", 5) == 0 if ( strncmp(termtype, const_cast<char*>("linux"), 5) == 0
|| strncmp(termtype, "con", 3) == 0 ) || strncmp(termtype, const_cast<char*>("con"), 3) == 0 )
linux_terminal = true; linux_terminal = true;
else else
linux_terminal = false; linux_terminal = false;
@ -2549,7 +2561,7 @@ FString FTerm::getXTermFont()
if ( raw_mode && non_blocking_stdin ) if ( raw_mode && non_blocking_stdin )
{ {
int n; int n;
char temp[150] = { '\0' }; char temp[150] = {};
tputs("\033]50;?\07", 1, putchar); // get font tputs("\033]50;?\07", 1, putchar); // get font
fflush(stdout); fflush(stdout);
usleep(150000); // wait 150 ms usleep(150000); // wait 150 ms
@ -2557,8 +2569,11 @@ FString FTerm::getXTermFont()
n = int(read(fileno(stdin), &temp, sizeof(temp)-1)); n = int(read(fileno(stdin), &temp, sizeof(temp)-1));
// Esc \ = OSC String Terminator // Esc \ = OSC String Terminator
if ( n >= 2 && temp[n-1] == '\\' && temp[n-2] == 0x1b ) if ( n >= 2 && temp[n-1] == '\\' && temp[n-2] == 0x1b )
{
temp[n-2] = '\0'; temp[n-2] = '\0';
font = temp; font = temp;
}
if ( font.getLength() > 6 ) if ( font.getLength() > 6 )
font = font.mid(6, font.getLength()-1); font = font.mid(6, font.getLength()-1);
} }
@ -2576,7 +2591,7 @@ FString FTerm::getXTermTitle()
if ( raw_mode && non_blocking_stdin ) if ( raw_mode && non_blocking_stdin )
{ {
int n; int n;
char temp[512] = { '\0' }; char temp[512] = {};
tputs("\033[21t", 1, putchar); // get title tputs("\033[21t", 1, putchar); // get title
fflush(stdout); fflush(stdout);
usleep(150000); // wait 150 ms usleep(150000); // wait 150 ms
@ -2584,8 +2599,11 @@ FString FTerm::getXTermTitle()
n = int(read(fileno(stdin), &temp, sizeof(temp)-1)); n = int(read(fileno(stdin), &temp, sizeof(temp)-1));
// Esc \ = OSC String Terminator // Esc \ = OSC String Terminator
if ( n >= 2 && temp[n-1] == '\\' && temp[n-2] == 0x1b ) if ( n >= 2 && temp[n-1] == '\\' && temp[n-2] == 0x1b )
{
temp[n-2] = '\0'; temp[n-2] = '\0';
title = temp; title = temp;
}
if ( title.getLength() > 3 ) if ( title.getLength() > 3 )
title = title.right( title.getLength()-3 ); title = title.right( title.getLength()-3 );
} }
@ -3309,14 +3327,14 @@ bool FTerm::setNonBlockingInput(bool on)
if ( on ) // make stdin non-blocking if ( on ) // make stdin non-blocking
{ {
stdin_status_flags |= O_NONBLOCK; stdin_status_flags |= O_NONBLOCK;
fcntl (stdin_no, F_SETFL, stdin_status_flags); if ( fcntl (stdin_no, F_SETFL, stdin_status_flags) != -1 )
non_blocking_stdin = true; non_blocking_stdin = true;
} }
else else
{ {
stdin_status_flags &= ~O_NONBLOCK; stdin_status_flags &= ~O_NONBLOCK;
fcntl (stdin_no, F_SETFL, stdin_status_flags); if ( fcntl (stdin_no, F_SETFL, stdin_status_flags) != -1 )
non_blocking_stdin = false; non_blocking_stdin = false;
} }
return non_blocking_stdin; return non_blocking_stdin;
} }
@ -3425,7 +3443,7 @@ FString FTerm::getAnswerbackMsg()
if ( raw_mode ) if ( raw_mode )
{ {
char temp[10] = { '\0' }; char temp[10] = {};
putchar(0x05); // send enquiry character putchar(0x05); // send enquiry character
fflush(stdout); fflush(stdout);
usleep(150000); // wait 150 ms usleep(150000); // wait 150 ms
@ -3443,7 +3461,7 @@ FString FTerm::getSecDA()
if ( raw_mode ) if ( raw_mode )
{ {
char temp[16] = { '\0' }; char temp[16] = {};
// get the secondary device attributes // get the secondary device attributes
putchar(0x1b); // ESC putchar(0x1b); // ESC
putchar(0x5b); // [ putchar(0x5b); // [

View File

@ -149,8 +149,10 @@ int main (int, char**)
try try
{ {
double double_num = FString("2.7182818284590452353").toDouble(); double double_num = FString("2.7182818284590452353").toDouble();
std::ios_base::fmtflags save_flags = std::cout.flags();
std::cout << " toDouble: " << std::setprecision(11) std::cout << " toDouble: " << std::setprecision(11)
<< double_num << std::endl; << double_num << std::endl;
std::cout.flags(save_flags);
} }
catch (const std::invalid_argument& ex) catch (const std::invalid_argument& ex)
{ {
@ -210,10 +212,16 @@ int main (int, char**)
FString index(5); // a string with five characters FString index(5); // a string with five characters
index = "index"; index = "index";
index[0] = L'I'; // write a wide character at position 0 index[0] = L'I'; // write a wide character at position 0
printf ( " index: [0] = %c ; [4] = %c\n" try
, char(index[0]) {
, char(index[4]) ); printf ( " index: [0] = %c ; [4] = %c\n"
, char(index[0])
, char(index[4]) );
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
}
FString stringIterator = "iterator"; FString stringIterator = "iterator";
FString::iterator iter; FString::iterator iter;
iter = stringIterator.begin(); iter = stringIterator.begin();