Compare commits

...

1 Commits

Author SHA1 Message Date
Bryan Petty
c5691153e4 This commit was manufactured by cvs2svn to create tag 'wxPy-2-1-4'.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/tags/wxPy-2-1-4@3889 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1999-10-07 23:40:33 +00:00
187 changed files with 4277 additions and 39882 deletions

View File

@@ -1,5 +1,5 @@
#
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 15:20, 1999/10/04
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE UNX.T!
#
@@ -526,7 +526,7 @@ GENERIC_HEADERS = \
generic/dirdlgg.h \
generic/filedlgg.h \
generic/fontdlgg.h \
generic/grid.h \
generic/gridg.h \
generic/helpext.h \
generic/helphtml.h \
generic/helpwxht.h \
@@ -577,7 +577,7 @@ GTK_GENERICOBJS = \
dcpsg.o \
dirdlgg.o \
filedlgg.o \
grid.o \
gridg.o \
helphtml.o \
helpwxht.o \
imaglist.o \
@@ -610,7 +610,7 @@ GTK_GENERICDEPS = \
dcpsg.d \
dirdlgg.d \
filedlgg.d \
grid.d \
gridg.d \
helphtml.d \
helpwxht.d \
imaglist.d \
@@ -935,7 +935,7 @@ MOTIF_GENERICOBJS = \
dcpsg.o \
dirdlgg.o \
fontdlgg.o \
grid.o \
gridg.o \
helphtml.o \
helpwxht.o \
helpxlp.o \
@@ -972,7 +972,7 @@ MOTIF_GENERICDEPS = \
dcpsg.d \
dirdlgg.d \
fontdlgg.d \
grid.d \
gridg.d \
helphtml.d \
helpwxht.d \
helpxlp.d \
@@ -1297,7 +1297,7 @@ MSW_GENERICOBJS = \
busyinfo.o \
choicdgg.o \
dirdlgg.o \
grid.o \
gridg.o \
laywin.o \
logg.o \
numdlgg.o \
@@ -1319,7 +1319,7 @@ MSW_GENERICDEPS = \
busyinfo.d \
choicdgg.d \
dirdlgg.d \
grid.d \
gridg.d \
laywin.d \
logg.d \
numdlgg.d \
@@ -1821,16 +1821,55 @@ JPEGOBJS = \
jquant2.o \
jdmerge.o
BASE_OBJS = \
dynarray.o \
event.o \
hash.o \
intl.o \
init.o \
file.o \
filefn.o \
list.o \
log.o \
object.o \
string.o \
utilscmn.o \
utilsunx.o
OBJECTS = $(@GUIOBJS@) $(@COMMONOBJS@) $(@GENERICOBJS@) $(@UNIXOBJS@) $(HTMLOBJS) \
$(JPEGOBJS) $(PNGOBJS) $(ZLIBOBJS)
BASE_DEPS = \
dynarray.d \
event.d \
hash.d \
intl.d \
init.d \
file.d \
filefn.d \
list.d \
log.d \
object.d \
string.d \
utilscmn.d \
utilsunx.d
DEPFILES = $(@GUIDEPS@) $(@COMMONDEPS@) $(@GENERICDEPS@) $(UNIXDEPS) $(HTMLDEPS)
BASE_HEADERS =
HEADERS = $(@GUIHEADERS@) $(HTML_HEADERS) $(UNIX_HEADERS) $(PROTOCOL_HEADERS) \
$(GENERIC_HEADERS) $(WX_HEADERS)
GUIOBJS = @GUIOBJS@
GUIDEPS = @GUIDEPS@
GUIHEADERS = @GUIHEADERS@
COMMONOBJS = @COMMONOBJS@
COMMONDEPS = @COMMONDEPS@
GENERICOBJS = @GENERICOBJS@
GENERICDEPS = @GENERICDEPS@
UNIXOBJS = @UNIXOBJS@
UNIXDEPS = @UNIXDEPS@
all: $(OBJECTS) @WX_TARGET_LIBRARY@ @WX_CREATE_LINKS@
OBJECTS = @ALL_OBJECTS@
DEPFILES = @ALL_DEPFILES@
HEADERS = @ALL_HEADERS@
all: @WX_CREATE_LINKS@
@WX_LIBRARY_NAME_STATIC@: $(OBJECTS)
@$(INSTALL) -d ./lib
@@ -1841,7 +1880,7 @@ all: $(OBJECTS) @WX_TARGET_LIBRARY@ @WX_CREATE_LINKS@
@$(INSTALL) -d ./lib
$(SHARED_LD) ./lib/$@ $(OBJECTS) $(EXTRALIBS)
CREATE_LINKS@: @WX_TARGET_LIBRARY@
CREATE_LINKS: @WX_TARGET_LIBRARY@
@$(RM) ./lib/@WX_LIBRARY_LINK1@
@$(RM) ./lib/@WX_LIBRARY_LINK2@
@$(RM) ./lib/@WX_LIBRARY_LINK3@
@@ -2198,10 +2237,6 @@ SAMPLES_DIST:
cp $(SAMPDIR)/minimal/Makefile.in $(DISTDIR)/samples/minimal
cp $(SAMPDIR)/minimal/*.cpp $(DISTDIR)/samples/minimal
cp $(SAMPDIR)/minimal/*.xpm $(DISTDIR)/samples/minimal
mkdir $(DISTDIR)/samples/newgrid
cp $(SAMPDIR)/newgrid/Makefile.in $(DISTDIR)/samples/newgrid
cp $(SAMPDIR)/newgrid/*.cpp $(DISTDIR)/samples/newgrid
cp $(SAMPDIR)/newgrid/*.h $(DISTDIR)/samples/newgrid
mkdir $(DISTDIR)/samples/notebook
cp $(SAMPDIR)/notebook/Makefile.in $(DISTDIR)/samples/notebook
cp $(SAMPDIR)/notebook/*.cpp $(DISTDIR)/samples/notebook

View File

@@ -723,7 +723,6 @@ if test $DEBUG_CONFIGURE = 1; then
DEFAULT_wxUSE_COMBOBOX=no
DEFAULT_wxUSE_GAUGE=no
DEFAULT_wxUSE_GRID=no
DEFAULT_wxUSE_NEW_GRID=no
DEFAULT_wxUSE_IMAGLIST=no
DEFAULT_wxUSE_LISTBOX=no
DEFAULT_wxUSE_LISTCTRL=no
@@ -835,7 +834,6 @@ else
DEFAULT_wxUSE_COMBOBOX=yes
DEFAULT_wxUSE_GAUGE=yes
DEFAULT_wxUSE_GRID=yes
DEFAULT_wxUSE_NEW_GRID=yes
DEFAULT_wxUSE_IMAGLIST=yes
DEFAULT_wxUSE_LISTBOX=yes
DEFAULT_wxUSE_LISTCTRL=yes
@@ -938,7 +936,6 @@ if test "$wxUSE_GUI" = "no"; then
DEFAULT_wxUSE_COMBOBOX=no
DEFAULT_wxUSE_GAUGE=no
DEFAULT_wxUSE_GRID=no
DEFAULT_wxUSE_NEW_GRID=no
DEFAULT_wxUSE_IMAGLIST=no
DEFAULT_wxUSE_LISTBOX=no
DEFAULT_wxUSE_LISTCTRL=no
@@ -1102,7 +1099,6 @@ if test "$wxUSE_CONTROLS" = "yes"; then
DEFAULT_wxUSE_CHOICE=yes
DEFAULT_wxUSE_GAUGE=yes
DEFAULT_wxUSE_GRID=yes
DEFAULT_wxUSE_NEW_GRID=yes
DEFAULT_wxUSE_IMAGLIST=yes
DEFAULT_wxUSE_LISTBOX=yes
DEFAULT_wxUSE_LISTCTRL=yes
@@ -1132,7 +1128,6 @@ elif test "$wxUSE_CONTROLS" = "no"; then
DEFAULT_wxUSE_CHOICE=no
DEFAULT_wxUSE_GAUGE=no
DEFAULT_wxUSE_GRID=no
DEFAULT_wxUSE_NEW_GRID=no
DEFAULT_wxUSE_IMAGLIST=no
DEFAULT_wxUSE_LISTBOX=no
DEFAULT_wxUSE_LISTCTRL=no
@@ -1163,7 +1158,6 @@ WX_ARG_ENABLE(choice, [ --enable-choice use wxChoice class], wxUSE
WX_ARG_ENABLE(combobox, [ --enable-combobox use wxComboBox classes], wxUSE_COMBOBOX)
WX_ARG_ENABLE(gauge, [ --enable-gauge use wxGauge class], wxUSE_GAUGE)
WX_ARG_ENABLE(grid, [ --enable-grid use wxGrid class], wxUSE_GRID)
WX_ARG_ENABLE(newgrid, [ --enable-newgrid use new wxGrid class], wxUSE_NEW_GRID)
WX_ARG_ENABLE(imaglist, [ --enable-imaglist use wxImageList class], wxUSE_IMAGLIST)
WX_ARG_ENABLE(listbox, [ --enable-listbox use wxListBox class], wxUSE_LISTBOX)
WX_ARG_ENABLE(listctrl, [ --enable-listctrl use wxListCtrl class], wxUSE_LISTCTRL)
@@ -2598,11 +2592,6 @@ if test "$wxUSE_GRID" = "yes"; then
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS grid"
fi
if test "$wxUSE_NEW_GRID" = "yes"; then
AC_DEFINE(wxUSE_NEW_GRID)
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS newgrid"
fi
if test "$wxUSE_IMAGLIST" = "yes"; then
AC_DEFINE(wxUSE_IMAGLIST)
fi
@@ -2935,7 +2924,6 @@ AC_OUTPUT([
samples/mdi/Makefile
samples/minifram/Makefile
samples/minimal/Makefile
samples/newgrid/Makefile
samples/notebook/Makefile
samples/printing/Makefile
samples/proplist/Makefile

View File

@@ -61,7 +61,7 @@ dcpsg.cpp G U
dirdlgg.cpp G 16
fontdlgg.cpp G G,R
filedlgg.cpp G U,X
grid.cpp G
gridg.cpp G
helphtml.cpp G G
helpwxht.cpp G G
helpxlp.cpp G G,R
@@ -849,7 +849,7 @@ dcpsg.h N
dirdlgg.h N
fontdlgg.h N
filedlgg.h N
grid.h N
gridg.h N
helpext.h N
helpwxht.h N
helphtml.h N

View File

@@ -484,7 +484,7 @@ DEPFILES = $(@GUIDEPS@) $(@COMMONDEPS@) $(@GENERICDEPS@) $(UNIXDEPS) $(HTMLDEPS)
HEADERS = $(@GUIHEADERS@) $(HTML_HEADERS) $(UNIX_HEADERS) $(PROTOCOL_HEADERS) \
$(GENERIC_HEADERS) $(WX_HEADERS)
all: $(OBJECTS) @WX_TARGET_LIBRARY@ @WX_CREATE_LINKS@
all: @WX_CREATE_LINKS@
@WX_LIBRARY_NAME_STATIC@: $(OBJECTS)
@$(INSTALL) -d ./lib
@@ -495,7 +495,7 @@ all: $(OBJECTS) @WX_TARGET_LIBRARY@ @WX_CREATE_LINKS@
@$(INSTALL) -d ./lib
$(SHARED_LD) ./lib/$@ $(OBJECTS) $(EXTRALIBS)
CREATE_LINKS@: @WX_TARGET_LIBRARY@
CREATE_LINKS: @WX_TARGET_LIBRARY@
@$(RM) ./lib/@WX_LIBRARY_LINK1@
@$(RM) ./lib/@WX_LIBRARY_LINK2@
@$(RM) ./lib/@WX_LIBRARY_LINK3@
@@ -852,10 +852,6 @@ SAMPLES_DIST:
cp $(SAMPDIR)/minimal/Makefile.in $(DISTDIR)/samples/minimal
cp $(SAMPDIR)/minimal/*.cpp $(DISTDIR)/samples/minimal
cp $(SAMPDIR)/minimal/*.xpm $(DISTDIR)/samples/minimal
mkdir $(DISTDIR)/samples/newgrid
cp $(SAMPDIR)/newgrid/Makefile.in $(DISTDIR)/samples/newgrid
cp $(SAMPDIR)/newgrid/*.cpp $(DISTDIR)/samples/newgrid
cp $(SAMPDIR)/newgrid/*.h $(DISTDIR)/samples/newgrid
mkdir $(DISTDIR)/samples/notebook
cp $(SAMPDIR)/notebook/Makefile.in $(DISTDIR)/samples/notebook
cp $(SAMPDIR)/notebook/*.cpp $(DISTDIR)/samples/notebook

View File

@@ -50,6 +50,7 @@ C++ portability guide</A> by David Williams.
<LI><A HREF="#no_stl">Don't use STL</A></LI>
<LI><A HREF="#no_fordecl">Don't declare variables inside <TT>for()</TT></A></LI>
<LI><A HREF="#no_nestedclasses">Don't use nested classes</A></LI>
<LI><A HREF="#no_ternarywithobjects">Use ternary operator ?: carefully</A></LI>
</OL>
<BR>
<LI>General recommendations</LI>
@@ -332,6 +333,25 @@ you can try the following:
<P>A nice side effect is that you don't need to recompile all the files
including the header if you change the PrivateLibClass declaration (it's
an example of a more general interface/implementation separation idea).
<P><LI><A NAME="no_ternarywithobjects"></A><B>Use ternary operator ?: carefully</B></LI><P>
The ternary operator <TT>?:</TT> shouldn't be used with objects (i.e. if any
of its operands are objects) because some compilers (notable Borland C++) fail
to compile such code.
<P><U>Workaround</U>: use <TT>if/else</TT> instead.
<PRE>
wxString s1, s2;
// Borland C++ won't compile the line below
wxString s = s1.Len() < s2.Len() ? s1 : s2;
// but any C++ compiler will compile this
wxString s;
if ( s1.Len() < s2.Len() )
s = s1;
else
s = s2;
</PRE>
</OL>
<BR>

View File

@@ -418,6 +418,9 @@ Gets the current pen (see \helpref{wxDC::SetPen}{wxdcsetpen}).
Sets {\it colour} to the colour at the specified location. Windows only; an X implementation
is being worked on. Not available for wxPostScriptDC or wxMetafileDC.
\pythonnote{For wxPython the wxColour value is returned and is not
required as a parameter.}
\membersection{wxDC::GetSize}\label{wxdcgetsize}
\func{void}{GetSize}{\param{long *}{width}, \param{long *}{height}}

View File

@@ -376,6 +376,10 @@ giving details in {\it flags}. {\it flags} will be a combination of the followin
wxLIST\_HITTEST\_ONITEMSTATEICON.}
\end{twocollist}
\pythonnote{A tuple of values is returned in the wxPython version of
thsi method. The first value is the item id and the second is the
flags value mentioned above.}
\membersection{wxListCtrl::InsertColumn}\label{wxlistctrlinsertcolumn}
\func{long}{InsertColumn}{\param{long }{col}, \param{wxListItem\& }{info}}

View File

@@ -52,6 +52,7 @@ empty, {\it HasPendingMessages()} is also provided which allows to explicitly
verify it.
\helpref{Flush}{wxlogflush}\\
\helpref{FlushActive}{wxlogflushactive}\\
\helpref{HasPendingMessages}{haspendingmessages}
\membersection{Customization}\label{wxlogcustomization}
@@ -142,6 +143,16 @@ currently. (Almost) for internal use only.
Shows all the messages currently in buffer and clears it. If the buffer
is already empty, nothing happens.
\membersection{wxLog::FlushActive}\label{wxlogflushactive}
\func{static void}{FlushActive}{\void}
Flushes the current log target if any, does nothing if there is none.
See also:
\helpref{Flush}{wxlogflush}
\membersection{wxLog::HasPendingMessages}\label{haspendingmessages}
\constfunc{bool}{HasPendingMessages}{\void}

View File

@@ -9,6 +9,7 @@ This chapter contains a selection of topic overviews.
\input tcontain.tex
\input tlog.tex
\input tconfig.tex
\input tunicode.tex
\input tbitmap.tex
\input tdialog.tex
\input tfont.tex

View File

@@ -365,10 +365,11 @@ as possible to the C++ spec over time.
\item \helpref{wxBitmapButton}{wxbitmapbutton}
\item \helpref{wxBitmap}{wxbitmap}
\item wxBMPHandler
\item \helpref{wxBoxSizer}{wxBoxSizer}
\item \helpref{wxBoxSizer}{wxboxsizer}
\item \helpref{wxBrush}{wxbrush}
\item \helpref{wxButton}{wxbutton}
\item \helpref{wxCalculateLayoutEvent}{wxcalculatelayoutevent}
\item wxCaret
\item \helpref{wxCheckBox}{wxcheckbox}
\item \helpref{wxCheckListBox}{wxchecklistbox}
\item \helpref{wxChoice}{wxchoice}
@@ -401,14 +402,14 @@ as possible to the C++ spec over time.
\item wxGridCell
\item wxGridEvent
\item \helpref{wxGrid}{wxgrid}
\item \helpref{wxHtmlCell}{wxHtmlCell}
\item \helpref{wxHtmlContainerCell}{wxHtmlContainerCell}
\item \helpref{wxHtmlParser}{wxHtmlParser}
\item \helpref{wxHtmlTagHandler}{wxHtmlTagHandler}
\item \helpref{wxHtmlTag}{wxHtmlTag}
\item \helpref{wxHtmlWinParser}{wxHtmlWinParser}
\item \helpref{wxHtmlWinTagHandler}{wxHtmlWinTagHandler}
\item \helpref{wxHtmlWindow}{wxHtmlWindow}
\item \helpref{wxHtmlCell}{wxhtmlcell}
\item \helpref{wxHtmlContainerCell}{wxhtmlcontainercell}
\item \helpref{wxHtmlParser}{wxhtmlparser}
\item \helpref{wxHtmlTagHandler}{wxhtmltaghandler}
\item \helpref{wxHtmlTag}{wxhtmltag}
\item \helpref{wxHtmlWinParser}{wxhtmlwinparser}
\item \helpref{wxHtmlWinTagHandler}{wxhtmlwintaghandler}
\item \helpref{wxHtmlWindow}{wxhtmlwindow}
\item wxIconizeEvent
\item \helpref{wxIcon}{wxicon}
\item \helpref{wxIdleEvent}{wxidleevent}
@@ -480,7 +481,7 @@ as possible to the C++ spec over time.
\item \helpref{wxSingleChoiceDialog}{wxsinglechoicedialog}
\item \helpref{wxSizeEvent}{wxsizeevent}
\item \helpref{wxSize}{wxsize}
\item \helpref{wxSizer}{wxSizer}
\item \helpref{wxSizer}{wxsizer}
\item wxSizerItem
\item \helpref{wxSlider}{wxslider}
\item \helpref{wxSpinButton}{wxspinbutton}
@@ -488,7 +489,7 @@ as possible to the C++ spec over time.
\item \helpref{wxSplitterWindow}{wxsplitterwindow}
\item \helpref{wxStaticBitmap}{wxstaticbitmap}
\item \helpref{wxStaticBox}{wxstaticbox}
\item \helpref{wxStaticBoxSizer}{wxStaticBoxSizer}
\item \helpref{wxStaticBoxSizer}{wxstaticboxsizer}
\item wxStaticLine
\item \helpref{wxStaticText}{wxstatictext}
\item \helpref{wxStatusBar}{wxstatusbar}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,11 @@
#ifndef _WX_GRID_H_BASE_
#define _WX_GRID_H_BASE_
#include "wx/generic/grid.h"
#include "wx/generic/gridg.h"
#ifndef wxGrid
#define wxGrid wxGenericGrid
#endif
#endif
// _WX_GRID_H_BASE_

View File

@@ -103,11 +103,6 @@
#define wxUSE_CARET 1
// Define 1 to use wxCaret class
#define wxUSE_NEW_GRID 1
// Define 1 to use the new wxGrid class
// (still under development, define 0 to
// use existing wxGrid class)
#define wxUSE_XPM_IN_MSW 1
// Define 1 to support the XPM package in wxBitmap.
#define wxUSE_IMAGE_LOADING_IN_MSW 1

View File

@@ -1,113 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: minimal.cpp
// Purpose: Dynamic events wxWindows sample
// Author: Julian Smart
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "minimal.cpp"
#pragma interface "minimal.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#ifdef __WXGTK__
#include "mondrian.xpm"
#endif
// Define a new application type
class MyApp: public wxApp
{ public:
bool OnInit(void);
};
// Define a new frame type
class MyFrame: public wxFrame
{ public:
MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
public:
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
bool OnClose(void) { return TRUE; }
};
// ID for the menu commands
#define MINIMAL_QUIT 1
#define MINIMAL_TEXT 101
#define MINIMAL_ABOUT 102
// Create a new application object
IMPLEMENT_APP (MyApp)
// `Main program' equivalent, creating windows and returning main app frame
bool MyApp::OnInit(void)
{
// Create the main frame window
MyFrame *frame = new MyFrame((wxFrame *) NULL, (char *) "Minimal wxWindows App", 50, 50, 450, 340);
frame->Connect( MINIMAL_QUIT, -1, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)MyFrame::OnQuit );
frame->Connect( MINIMAL_ABOUT, -1, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)MyFrame::OnAbout );
// Give it an icon
#ifdef __WXMSW__
frame->SetIcon(wxIcon("mondrian"));
#else
frame->SetIcon(wxIcon(mondrian_xpm));
#endif
// Make a menubar
wxMenu *file_menu = new wxMenu;
file_menu->Append(MINIMAL_ABOUT, "&About");
file_menu->Append(MINIMAL_QUIT, "E&xit");
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
frame->SetMenuBar(menu_bar);
// Make a panel with a message
wxPanel *panel = new wxPanel(frame, -1, wxPoint(0, 0), wxSize(400, 200), wxTAB_TRAVERSAL);
(void)new wxStaticText(panel, 311, "Hello!", wxPoint(10, 10), wxSize(-1, -1), 0);
// Show the frame
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
// My frame constructor
MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
{}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
{
Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
{
wxMessageDialog dialog(this, "This is a minimal sample\nA second line in the message box",
"About Minimal", wxYES_NO|wxCANCEL);
dialog.ShowModal();
}

View File

@@ -1,23 +0,0 @@
#
# File: makefile.unx
# Author: Julian Smart
# Created: 1998
# Updated:
# Copyright: (c) 1998 Julian Smart
#
# "%W% %G%"
#
# Makefile for new wxGrid example (UNIX).
top_srcdir = @top_srcdir@
top_builddir = ../..
program_dir = samples/newgrid
DATAFILES =
PROGRAM=griddemo
OBJECTS=$(PROGRAM).o
include ../../src/makeprog.env

View File

@@ -1,487 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: griddemo.cpp
// Purpose: Grid control wxWindows sample
// Author: Michael Bedward
// Modified by:
// RCS-ID: $Id$
// Copyright: (c) Michael Bedward, Julian Smart
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/colordlg.h"
#include "wx/grid.h"
#include "griddemo.h"
IMPLEMENT_APP( GridApp )
bool GridApp::OnInit()
{
GridFrame *frame = new GridFrame;
frame->Show( TRUE );
return TRUE;
}
BEGIN_EVENT_TABLE( GridFrame, wxFrame )
EVT_MENU( ID_TOGGLEROWLABELS, GridFrame::ToggleRowLabels )
EVT_MENU( ID_TOGGLECOLLABELS, GridFrame::ToggleColLabels )
EVT_MENU( ID_TOGGLECONTROLPANEL, GridFrame::ToggleControlPanel )
EVT_MENU( ID_TOGGLECELLEDIT, GridFrame::ToggleCellEdit )
EVT_MENU( ID_SETLABELCOLOUR, GridFrame::SetLabelColour )
EVT_MENU( ID_SETLABELTEXTCOLOUR, GridFrame::SetLabelTextColour )
EVT_MENU( ID_ROWLABELHORIZALIGN, GridFrame::SetRowLabelHorizAlignment )
EVT_MENU( ID_ROWLABELVERTALIGN, GridFrame::SetRowLabelVertAlignment )
EVT_MENU( ID_COLLABELHORIZALIGN, GridFrame::SetColLabelHorizAlignment )
EVT_MENU( ID_COLLABELVERTALIGN, GridFrame::SetColLabelVertAlignment )
EVT_MENU( ID_GRIDLINECOLOUR, GridFrame::SetGridLineColour )
EVT_MENU( ID_CLEARGRID, GridFrame::ClearGrid )
EVT_MENU( ID_ABOUT, GridFrame::About )
EVT_MENU( wxID_EXIT, GridFrame::OnQuit )
EVT_WXGRID_LABEL_LEFT_CLICK( GridFrame::OnLabelLeftClick )
EVT_WXGRID_CELL_LEFT_CLICK( GridFrame::OnCellLeftClick )
EVT_WXGRID_ROW_SIZE( GridFrame::OnRowSize )
EVT_WXGRID_COL_SIZE( GridFrame::OnColSize )
EVT_WXGRID_RANGE_SELECT( GridFrame::OnRangeSelected )
EVT_WXGRID_CELL_CHANGE( GridFrame::OnCellValueChanged )
END_EVENT_TABLE()
GridFrame::GridFrame()
: wxFrame( (wxFrame *)NULL, -1, "wxWindows grid class demo",
wxDefaultPosition,
wxDefaultSize )
{
int gridW = 600, gridH = 300;
int logW = gridW, logH = 80;
wxMenu *fileMenu = new wxMenu;
fileMenu->Append( wxID_EXIT, "E&xit" );
wxMenu *viewMenu = new wxMenu;
viewMenu->Append( ID_TOGGLEROWLABELS, "&Row labels", "", TRUE );
viewMenu->Append( ID_TOGGLECOLLABELS, "&Col labels", "", TRUE );
viewMenu->Append( ID_TOGGLECONTROLPANEL, "To&p controls", "", TRUE );
viewMenu->Append( ID_TOGGLECELLEDIT, "&In-place editing", "", TRUE );
viewMenu->Append( ID_SETLABELCOLOUR, "Set &label colour" );
viewMenu->Append( ID_SETLABELTEXTCOLOUR, "Set label &text colour" );
wxMenu *rowLabelMenu = new wxMenu;
viewMenu->Append( ID_ROWLABELALIGN, "R&ow label alignment",
rowLabelMenu,
"Change alignment of row labels" );
rowLabelMenu->Append( ID_ROWLABELHORIZALIGN, "&Horizontal" );
rowLabelMenu->Append( ID_ROWLABELVERTALIGN, "&Vertical" );
wxMenu *colLabelMenu = new wxMenu;
viewMenu->Append( ID_COLLABELALIGN, "Col l&abel alignment",
colLabelMenu,
"Change alignment of col labels" );
colLabelMenu->Append( ID_COLLABELHORIZALIGN, "&Horizontal" );
colLabelMenu->Append( ID_COLLABELVERTALIGN, "&Vertical" );
viewMenu->Append( ID_GRIDLINECOLOUR, "&Grid line colour" );
viewMenu->Append( ID_CLEARGRID, "Cl&ear grid cell contents" );
wxMenu *helpMenu = new wxMenu;
helpMenu->Append( ID_ABOUT, "&About wxGrid demo" );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( fileMenu, "&File" );
menuBar->Append( viewMenu, "&View" );
menuBar->Append( helpMenu, "&Help" );
SetMenuBar( menuBar );
grid = new wxGrid( this,
-1,
wxPoint( 0, 0 ),
wxSize( 400, 300 ) );
logWin = new wxTextCtrl( this,
-1,
wxEmptyString,
wxPoint( 0, gridH + 20 ),
wxSize( logW, logH ),
wxTE_MULTILINE );
logger = new wxLogTextCtrl( logWin );
logger->SetActiveTarget( logger );
logger->SetTimestamp( NULL );
// this will create a grid and, by default, an associated grid
// table for string data
//
grid->CreateGrid( 100, 100 );
grid->EnableTopEditControl( TRUE );
grid->SetRowSize( 0, 60 );
grid->SetCellValue( 0, 0, "Ctrl+Home\nwill go to\nthis cell" );
grid->SetCellValue( 0, 1, "Blah" );
grid->SetCellValue( 0, 2, "Blah" );
grid->SetCellValue( 0, 5, "Press\nCtrl+arrow\nto skip over\ncells" );
grid->SetRowSize( 99, 60 );
grid->SetCellValue( 99, 99, "Ctrl+End\nwill go to\nthis cell" );
wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
topSizer->Add( grid,
1,
wxEXPAND );
topSizer->Add( logWin,
0,
wxEXPAND );
SetAutoLayout( TRUE );
SetSizer( topSizer );
topSizer->Fit( this );
topSizer->SetSizeHints( this );
Centre();
SetDefaults();
}
GridFrame::~GridFrame()
{
}
void GridFrame::SetDefaults()
{
GetMenuBar()->Check( ID_TOGGLEROWLABELS, TRUE );
GetMenuBar()->Check( ID_TOGGLECOLLABELS, TRUE );
GetMenuBar()->Check( ID_TOGGLECONTROLPANEL, TRUE );
GetMenuBar()->Check( ID_TOGGLECELLEDIT, TRUE );
}
void GridFrame::ToggleRowLabels( wxCommandEvent& WXUNUSED(ev) )
{
if ( GetMenuBar()->IsChecked( ID_TOGGLEROWLABELS ) )
{
grid->SetRowLabelSize( grid->GetDefaultRowLabelSize() );
}
else
{
grid->SetRowLabelSize( 0 );
}
}
void GridFrame::ToggleColLabels( wxCommandEvent& WXUNUSED(ev) )
{
if ( GetMenuBar()->IsChecked( ID_TOGGLECOLLABELS ) )
{
grid->SetColLabelSize( grid->GetDefaultColLabelSize() );
}
else
{
grid->SetColLabelSize( 0 );
}
}
void GridFrame::ToggleControlPanel( wxCommandEvent& WXUNUSED(ev) )
{
grid->EnableTopEditControl(GetMenuBar()->IsChecked(ID_TOGGLECONTROLPANEL));
}
void GridFrame::ToggleCellEdit( wxCommandEvent& WXUNUSED(ev) )
{
grid->EnableCellEditControl(
GetMenuBar()->IsChecked( ID_TOGGLECELLEDIT ) );
}
void GridFrame::SetLabelColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColourDialog dlg( NULL );
if ( dlg.ShowModal() == wxID_OK )
{
wxColourData retData;
retData = dlg.GetColourData();
wxColour colour = retData.GetColour();
grid->SetLabelBackgroundColour( colour );
}
}
void GridFrame::SetLabelTextColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColourDialog dlg( NULL );
if ( dlg.ShowModal() == wxID_OK )
{
wxColourData retData;
retData = dlg.GetColourData();
wxColour colour = retData.GetColour();
grid->SetLabelTextColour( colour );
}
}
void GridFrame::SetRowLabelHorizAlignment( wxCommandEvent& WXUNUSED(ev) )
{
int horiz, vert;
grid->GetRowLabelAlignment( &horiz, &vert );
switch ( horiz )
{
case wxLEFT:
horiz = wxCENTRE;
break;
case wxCENTRE:
horiz = wxRIGHT;
break;
case wxRIGHT:
horiz = wxLEFT;
break;
}
grid->SetRowLabelAlignment( horiz, -1 );
}
void GridFrame::SetRowLabelVertAlignment( wxCommandEvent& WXUNUSED(ev) )
{
int horiz, vert;
grid->GetRowLabelAlignment( &horiz, &vert );
switch ( vert )
{
case wxTOP:
vert = wxCENTRE;
break;
case wxCENTRE:
vert = wxBOTTOM;
break;
case wxBOTTOM:
vert = wxTOP;
break;
}
grid->SetRowLabelAlignment( -1, vert );
}
void GridFrame::SetColLabelHorizAlignment( wxCommandEvent& WXUNUSED(ev) )
{
int horiz, vert;
grid->GetColLabelAlignment( &horiz, &vert );
switch ( horiz )
{
case wxLEFT:
horiz = wxCENTRE;
break;
case wxCENTRE:
horiz = wxRIGHT;
break;
case wxRIGHT:
horiz = wxLEFT;
break;
}
grid->SetColLabelAlignment( horiz, -1 );
}
void GridFrame::SetColLabelVertAlignment( wxCommandEvent& WXUNUSED(ev) )
{
int horiz, vert;
grid->GetColLabelAlignment( &horiz, &vert );
switch ( vert )
{
case wxTOP:
vert = wxCENTRE;
break;
case wxCENTRE:
vert = wxBOTTOM;
break;
case wxBOTTOM:
vert = wxTOP;
break;
}
grid->SetColLabelAlignment( -1, vert );
}
void GridFrame::SetGridLineColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColourDialog dlg( NULL );
if ( dlg.ShowModal() == wxID_OK )
{
wxColourData retData;
retData = dlg.GetColourData();
wxColour colour = retData.GetColour();
grid->SetGridLineColour( colour );
}
}
void GridFrame::ClearGrid( wxCommandEvent& WXUNUSED(ev) )
{
grid->ClearGrid();
}
void GridFrame::About( wxCommandEvent& WXUNUSED(ev) )
{
(void)wxMessageBox( "\n\nwxGrid demo \n\n"
"Michael Bedward \n"
"mbedward@ozemail.com.au \n\n",
"About",
wxOK );
}
void GridFrame::OnSize( wxSizeEvent& WXUNUSED(ev) )
{
if ( grid && logWin )
{
int cw, ch;
GetClientSize( &cw, &ch );
int gridH = ch - 90;
int logH = 80;
if ( gridH < 0 )
{
gridH = ch;
}
grid->SetSize( 0, 0, cw, gridH );
logWin->SetSize( 0, gridH + 10, cw, logH );
}
}
void GridFrame::OnQuit( wxCommandEvent& WXUNUSED(ev) )
{
Close( TRUE );
}
void GridFrame::OnLabelLeftClick( wxGridEvent& ev )
{
logBuf = "";
if ( ev.GetRow() != -1 )
{
logBuf << "row label " << ev.GetRow();
}
else if ( ev.GetCol() != -1 )
{
logBuf << "col label " << ev.GetCol();
}
else
{
logBuf << "corner label";
}
if ( ev.ShiftDown() ) logBuf << " (shift down)";
wxLogMessage( "%s", logBuf.c_str() );
ev.Skip();
}
void GridFrame::OnCellLeftClick( wxGridEvent& ev )
{
logBuf = "";
logBuf << "Cell at row " << ev.GetRow()
<< " col " << ev.GetCol();
wxLogMessage( "%s", logBuf.c_str() );
// you must call event skip if you want default grid processing
// (cell highlighting etc.)
//
ev.Skip();
}
void GridFrame::OnRowSize( wxGridSizeEvent& ev )
{
logBuf = "";
logBuf << "Resized row " << ev.GetRowOrCol();
wxLogMessage( "%s", logBuf.c_str() );
ev.Skip();
}
void GridFrame::OnColSize( wxGridSizeEvent& ev )
{
logBuf = "";
logBuf << "Resized col " << ev.GetRowOrCol();
wxLogMessage( "%s", logBuf.c_str() );
ev.Skip();
}
void GridFrame::OnRangeSelected( wxGridRangeSelectEvent& ev )
{
logBuf = "";
logBuf << "Selected cells from row " << ev.GetTopRow()
<< " col " << ev.GetLeftCol()
<< " to row " << ev.GetBottomRow()
<< " col " << ev.GetRightCol();
wxLogMessage( "%s", logBuf.c_str() );
ev.Skip();
}
void GridFrame::OnCellValueChanged( wxGridEvent& ev )
{
logBuf = "";
logBuf << "Value changed for cell at"
<< " row " << ev.GetRow()
<< " col " << ev.GetCol();
wxLogMessage( "%s", logBuf.c_str() );
ev.Skip();
}

View File

@@ -1,6 +0,0 @@
NAME GridDemo
DESCRIPTION 'wxGrid Demo'
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE

View File

@@ -1,85 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: griddemo.h
// Purpose: Grid control wxWindows sample
// Author: Michael Bedward
// Modified by:
// RCS-ID: $Id$
// Copyright: (c) Michael Bedward, Julian Smart
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef griddemo_h
#define griddemo_h
class wxGrid;
class GridApp : public wxApp
{
public:
bool OnInit();
};
class GridFrame : public wxFrame
{
wxGrid *grid;
wxTextCtrl *logWin;
wxLogTextCtrl *logger;
wxString logBuf;
void SetDefaults();
void ToggleRowLabels( wxCommandEvent& );
void ToggleColLabels( wxCommandEvent& );
void ToggleControlPanel( wxCommandEvent& );
void ToggleCellEdit( wxCommandEvent& );
void SetLabelColour( wxCommandEvent& );
void SetLabelTextColour( wxCommandEvent& );
void SetRowLabelHorizAlignment( wxCommandEvent& );
void SetRowLabelVertAlignment( wxCommandEvent& );
void SetColLabelHorizAlignment( wxCommandEvent& );
void SetColLabelVertAlignment( wxCommandEvent& );
void SetGridLineColour( wxCommandEvent& );
void ClearGrid( wxCommandEvent& );
void About( wxCommandEvent& );
void OnLabelLeftClick( wxGridEvent& );
void OnCellLeftClick( wxGridEvent& );
void OnRowSize( wxGridSizeEvent& );
void OnColSize( wxGridSizeEvent& );
void OnRangeSelected( wxGridRangeSelectEvent& );
void OnCellValueChanged( wxGridEvent& );
public:
GridFrame();
~GridFrame();
void OnSize( wxSizeEvent& );
void OnQuit( wxCommandEvent& );
enum { ID_TOGGLEROWLABELS = 100,
ID_TOGGLECOLLABELS,
ID_TOGGLECONTROLPANEL,
ID_TOGGLECELLEDIT,
ID_SETLABELCOLOUR,
ID_SETLABELTEXTCOLOUR,
ID_ROWLABELALIGN,
ID_ROWLABELHORIZALIGN,
ID_ROWLABELVERTALIGN,
ID_COLLABELALIGN,
ID_COLLABELHORIZALIGN,
ID_COLLABELVERTALIGN,
ID_GRIDLINECOLOUR,
ID_CLEARGRID,
ID_ABOUT,
ID_TESTFUNC };
DECLARE_EVENT_TABLE()
};
#endif

View File

@@ -1,2 +0,0 @@
#include "wx/msw/wx.rc"

View File

@@ -1,17 +0,0 @@
#
# File: makefile.b32
# Author: Michael Bedward
# Created: 1999
# Updated:
# Copyright:
#
# Makefile : Builds sample for 32-bit BC++
WXDIR = $(WXWIN)
TARGET=griddemo
OBJECTS = griddemo.obj
!include $(WXDIR)\src\makeprog.b32

View File

@@ -1,19 +0,0 @@
#
# File: makefile.bcc
# Author: Michael Bedward
# Created: 1999
# Updated:
#
# Builds a BC++ 16-bit sample
!if "$(WXWIN)" == ""
!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
!endif
WXDIR = $(WXWIN)
TARGET=griddemo
OBJECTS=$(TARGET).obj
!include $(WXDIR)\src\makeprog.bcc

View File

@@ -1,17 +0,0 @@
#
# File: makefile.dos
# Author: Michael Bedward
# Created: 1999
# Updated:
#
# Makefile : Builds 16-bit sample, VC++ 1.5
# Use FINAL=1 argument to nmake to build final version with no debugging
# info
WXDIR = $(WXWIN)
TARGET=griddemo
OBJECTS=$(TARGET).obj
!include $(WXDIR)\src\makeprog.msc

View File

@@ -1,15 +0,0 @@
#
# File: makefile.g95
# Author: Michael Bedward
# Created: 1999
# Updated:
#
# Makefile for wxWindows sample (Cygwin/Mingw32).
WXDIR = ../..
TARGET=griddemo
OBJECTS = $(TARGET).o
include $(WXDIR)\src\makeprog.g95

View File

@@ -1,36 +0,0 @@
# Symantec C++ makefile
WXDIR = $(WXWIN)
WXLIB = $(WXDIR)\lib\wx.lib
INCDIR = $(WXDIR)\include
INCLUDE=$(INCDIR)
TARGET=griddemo
include $(WXDIR)\src\makesc.env
griddemo.exe: griddemo.obj $(DEFFILE) griddemo.res
*$(CC) $(LDFLAGS) -o$@ $** $(LIBS)
*$(RC) -k griddemo.res
sc32.def:
echo EXETYPE NT > sc32.def
echo SUBSYSTEM WINDOWS >> sc32.def
sc16.def:
echo NAME $(TARGET) > sc16.def
echo EXETYPE WINDOWS >> sc16.def
echo STUB 'WINSTUB.EXE' >> sc16.def
echo CODE PRELOAD MOVEABLE DISCARDABLE >> sc16.def
echo DATA PRELOAD MOVEABLE MULTIPLE >> sc16.def
echo HEAPSIZE 1024 >> sc16.def
echo STACKSIZE 8192 >> sc16.def
clean:
-del *.obj
-del *.exe
-del *.res
-del *.map
-del *.rws
-del sc32.def
-del sc16.def

View File

@@ -1,17 +0,0 @@
#
# File: makefile.vc
# Author: Michael Bedward
# Created: 1999
# Updated:
#
# Makefile : Builds sample (VC++, WIN32)
# Use FINAL=1 argument to nmake to build final version with no debug info.
# Set WXDIR for your system
WXDIR = $(WXWIN)
PROGRAM=griddemo
OBJECTS = $(PROGRAM).obj
!include $(WXDIR)\src\makeprog.vc

View File

@@ -1,13 +0,0 @@
#
# Makefile for WATCOM
#
#
WXDIR = $(%WXWIN)
PROGRAM = griddemo
OBJECTS = $(PROGRAM).obj
!include $(WXDIR)\src\makeprog.wat

View File

@@ -212,11 +212,6 @@
/*
* Use this control
*/
#define wxUSE_NEW_GRID 0
/*
* Use the new prototype wxGrid classes
* (wxUSE_GRID must also be defined)
*/
#define wxUSE_IMAGLIST 0
/*
* Use this control

File diff suppressed because it is too large Load Diff

View File

@@ -122,9 +122,7 @@ const char *wxButtonBarNameStr = "buttonbar";
const char *wxEnhDialogNameStr = "Shell";
const char *wxToolBarNameStr = "toolbar";
const char *wxStatusLineNameStr = "status_line";
#if 0 // this is defined in string.cpp
const char *wxEmptyString = "";
#endif
const char *wxGetTextFromUserPromptStr = "Input Text";
const char *wxMessageBoxCaptionStr = "Message";
const char *wxFileSelectorPromptStr = "Select a file";

View File

@@ -1,6 +1,6 @@
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 20:06, 1999/10/02
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE B32.T!
#
@@ -78,7 +78,7 @@ DOCDIR = $(WXDIR)\docs
GENERICOBJS= $(MSWDIR)\busyinfo.obj \
$(MSWDIR)\choicdgg.obj \
$(MSWDIR)\grid.obj \
$(MSWDIR)\gridg.obj \
$(MSWDIR)\laywin.obj \
$(MSWDIR)\logg.obj \
$(MSWDIR)\numdlgg.obj \
@@ -706,7 +706,7 @@ $(MSWDIR)\busyinfo.obj: $(GENDIR)\busyinfo.$(SRCSUFF)
$(MSWDIR)\choicdgg.obj: $(GENDIR)\choicdgg.$(SRCSUFF)
$(MSWDIR)\grid.obj: $(GENDIR)\grid.$(SRCSUFF)
$(MSWDIR)\gridg.obj: $(GENDIR)\gridg.$(SRCSUFF)
$(MSWDIR)\laywin.obj: $(GENDIR)\laywin.$(SRCSUFF)

View File

@@ -1,6 +1,6 @@
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 20:06, 1999/10/02
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE BCC.T!
#
@@ -76,7 +76,7 @@ DOCDIR = $(WXDIR)\docs
GENERICOBJS= $(MSWDIR)\busyinfo.obj \
$(MSWDIR)\choicdgg.obj \
$(MSWDIR)\dirdlgg.obj \
$(MSWDIR)\grid.obj \
$(MSWDIR)\gridg.obj \
$(MSWDIR)\imaglist.obj \
$(MSWDIR)\laywin.obj \
$(MSWDIR)\listctrl.obj \
@@ -586,7 +586,7 @@ $(MSWDIR)\choicdgg.obj: $(GENDIR)\choicdgg.$(SRCSUFF)
$(MSWDIR)\dirdlgg.obj: $(GENDIR)\dirdlgg.$(SRCSUFF)
$(MSWDIR)\grid.obj: $(GENDIR)\grid.$(SRCSUFF)
$(MSWDIR)\gridg.obj: $(GENDIR)\gridg.$(SRCSUFF)
$(MSWDIR)\imaglist.obj: $(GENDIR)\imaglist.$(SRCSUFF)

View File

@@ -1,6 +1,6 @@
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 20:06, 1999/10/02
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE DOS.T!
#
@@ -62,7 +62,7 @@ MSWDIR=.
GENERICOBJS= $(GENDIR)\busyinfo.obj \
$(GENDIR)\choicdgg.obj \
$(GENDIR)\dirdlgg.obj \
$(GENDIR)\grid.obj \
$(GENDIR)\gridg.obj \
$(GENDIR)\imaglist.obj \
$(GENDIR)\laywin.obj \
$(GENDIR)\listctrl.obj \
@@ -1046,7 +1046,7 @@ $(GENDIR)/dirdlgg.obj: $*.$(SRCSUFF)
$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
<<
$(GENDIR)/grid.obj: $*.$(SRCSUFF)
$(GENDIR)/gridg.obj: $*.$(SRCSUFF)
cl @<<
$(CPPFLAGS) /Fo$@ /c /Tp $*.$(SRCSUFF)
<<

View File

@@ -1,5 +1,5 @@
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 13:53, 1999/09/14
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE G295.T!
#
@@ -39,9 +39,8 @@ DOCDIR = $(WXDIR)\docs
GENERICOBJS = \
$(GENDIR)/busyinfo.$(OBJSUFF) \
$(GENDIR)/choicdgg.$(OBJSUFF) \
$(GENDIR)/grid.$(OBJSUFF) \
$(GENDIR)/gridg.$(OBJSUFF) \
$(GENDIR)/laywin.$(OBJSUFF) \
$(GENDIR)/logg.$(OBJSUFF) \
$(GENDIR)/numdlgg.$(OBJSUFF) \
$(GENDIR)/panelg.$(OBJSUFF) \
$(GENDIR)/progdlgg.$(OBJSUFF) \
@@ -80,7 +79,6 @@ COMMONOBJS = \
$(COMMDIR)/fileconf.$(OBJSUFF) \
$(COMMDIR)/filefn.$(OBJSUFF) \
$(COMMDIR)/filesys.$(OBJSUFF) \
$(COMMDIR)/fontcmn.$(OBJSUFF) \
$(COMMDIR)/framecmn.$(OBJSUFF) \
$(COMMDIR)/fs_inet.$(OBJSUFF) \
$(COMMDIR)/fs_zip.$(OBJSUFF) \
@@ -90,7 +88,6 @@ COMMONOBJS = \
$(COMMDIR)/hash.$(OBJSUFF) \
$(COMMDIR)/helpbase.$(OBJSUFF) \
$(COMMDIR)/http.$(OBJSUFF) \
$(COMMDIR)/imagall.$(OBJSUFF) \
$(COMMDIR)/imagbmp.$(OBJSUFF) \
$(COMMDIR)/image.$(OBJSUFF) \
$(COMMDIR)/imaggif.$(OBJSUFF) \
@@ -119,7 +116,6 @@ COMMONOBJS = \
$(COMMDIR)/sckfile.$(OBJSUFF) \
$(COMMDIR)/sckipc.$(OBJSUFF) \
$(COMMDIR)/sckstrm.$(OBJSUFF) \
$(COMMDIR)/serbase.$(OBJSUFF) \
$(COMMDIR)/sizer.$(OBJSUFF) \
$(COMMDIR)/socket.$(OBJSUFF) \
$(COMMDIR)/strconv.$(OBJSUFF) \
@@ -152,20 +148,20 @@ HTMLOBJS = \
$(HTMLDIR)/helpdata.$(OBJSUFF) \
$(HTMLDIR)/helpfrm.$(OBJSUFF) \
$(HTMLDIR)/htmlcell.$(OBJSUFF) \
$(HTMLDIR)/htmlfilt.$(OBJSUFF) \
$(HTMLDIR)/htmlpars.$(OBJSUFF) \
$(HTMLDIR)/htmlfilter.$(OBJSUFF) \
$(HTMLDIR)/htmlparser.$(OBJSUFF) \
$(HTMLDIR)/htmltag.$(OBJSUFF) \
$(HTMLDIR)/htmlwin.$(OBJSUFF) \
$(HTMLDIR)/m_fonts.$(OBJSUFF) \
$(HTMLDIR)/m_hline.$(OBJSUFF) \
$(HTMLDIR)/m_image.$(OBJSUFF) \
$(HTMLDIR)/m_layout.$(OBJSUFF) \
$(HTMLDIR)/m_links.$(OBJSUFF) \
$(HTMLDIR)/m_list.$(OBJSUFF) \
$(HTMLDIR)/m_pre.$(OBJSUFF) \
$(HTMLDIR)/m_tables.$(OBJSUFF) \
$(HTMLDIR)/search.$(OBJSUFF) \
$(HTMLDIR)/winpars.$(OBJSUFF)
$(HTMLDIR)/htmlwinparser.$(OBJSUFF) \
$(HTMLDIR)/mod_fonts.$(OBJSUFF) \
$(HTMLDIR)/mod_hline.$(OBJSUFF) \
$(HTMLDIR)/mod_image.$(OBJSUFF) \
$(HTMLDIR)/mod_layout.$(OBJSUFF) \
$(HTMLDIR)/mod_links.$(OBJSUFF) \
$(HTMLDIR)/mod_list.$(OBJSUFF) \
$(HTMLDIR)/mod_pre.$(OBJSUFF) \
$(HTMLDIR)/mod_tables.$(OBJSUFF) \
$(HTMLDIR)/search.$(OBJSUFF)
MSWOBJS = \
$(MSWDIR)/accel.$(OBJSUFF) \

View File

@@ -1,5 +1,5 @@
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 20:06, 1999/10/02
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE G95.T!
#
@@ -40,7 +40,7 @@ GENERICOBJS = \
$(GENDIR)/busyinfo.$(OBJSUFF) \
$(GENDIR)/choicdgg.$(OBJSUFF) \
$(GENDIR)/dirdlgg.$(OBJSUFF) \
$(GENDIR)/grid.$(OBJSUFF) \
$(GENDIR)/gridg.$(OBJSUFF) \
$(GENDIR)/laywin.$(OBJSUFF) \
$(GENDIR)/logg.$(OBJSUFF) \
$(GENDIR)/numdlgg.$(OBJSUFF) \

View File

@@ -1,6 +1,6 @@
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 20:06, 1999/10/02
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE SC.T!
# Symantec C++ makefile for the msw objects
@@ -28,7 +28,7 @@ MSWDIR=$(WXDIR)\src\msw
GENERICOBJS= $(GENDIR)\busyinfo.obj \
$(GENDIR)\choicdgg.obj \
$(GENDIR)\grid.obj \
$(GENDIR)\gridg.obj \
$(GENDIR)\laywin.obj \
$(GENDIR)\logg.obj \
$(GENDIR)\numdlgg.obj \

View File

@@ -1,4 +1,4 @@
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 18:29, 1999/10/03
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE VC.T!
# File: makefile.vc
@@ -85,7 +85,7 @@ $(CPPFLAGS) /Fo$@ /c /Tp $<
GENERICOBJS= ..\generic\$D\busyinfo.obj \
..\generic\$D\choicdgg.obj \
..\generic\$D\grid.obj \
..\generic\$D\gridg.obj \
..\generic\$D\laywin.obj \
..\generic\$D\logg.obj \
..\generic\$D\numdlgg.obj \

View File

@@ -1,6 +1,6 @@
# This file was automatically generated by tmake at 13:22, 1999/10/06
# This file was automatically generated by tmake at 20:06, 1999/10/02
# DO NOT CHANGE THIS FILE, YOUR CHANGES WILL BE LOST! CHANGE WAT.T!
#!/binb/wmake.exe
@@ -34,7 +34,7 @@ DOCDIR = $(WXDIR)\docs
GENERICOBJS= busyinfo.obj &
choicdgg.obj &
grid.obj &
gridg.obj &
laywin.obj &
logg.obj &
numdlgg.obj &
@@ -833,7 +833,7 @@ busyinfo.obj: $(GENDIR)\busyinfo.cpp
choicdgg.obj: $(GENDIR)\choicdgg.cpp
*$(CCC) $(CPPFLAGS) $(IFLAGS) $<
grid.obj: $(GENDIR)\grid.cpp
gridg.obj: $(GENDIR)\gridg.cpp
*$(CCC) $(CPPFLAGS) $(IFLAGS) $<
laywin.obj: $(GENDIR)\laywin.cpp

View File

@@ -1,68 +0,0 @@
#
# File: makefile.nt
# Author: Julian Smart
# Created: 1993
# Updated:
# Copyright: (c) 1993, AIAI, University of Edinburgh
#
# "%W% %G%"
#
# Makefile : Builds winpng.lib library for Windows 3.1
# Change WXDIR or WXWIN to wherever wxWindows is found
WXDIR = $(WXWIN)
WXLIB = $(WXDIR)\lib\wx.lib
WXINC = $(WXDIR)\include
WINPNGDIR = ..\png
WINPNGINC = $(WINPNGDIR)
WINPNGLIB = ..\..\lib\winpng.lib
INC = /I..\zlib
FINAL=1
# Set this to nothing if your compiler is MS C++ 7
ZOPTION=
!ifndef FINAL
FINAL=0
!endif
PRECOMP=/YuWX.H
!if "$(FINAL)" == "0"
OPT = /Od
CPPFLAGS= /W4 /Zi /MD /GX- $(ZOPTION) $(OPT) /Dwx_msw $(INC) # $(PRECOMP) /Fp$(WXDIR)\src\msw\wx.pch
CFLAGS= /W4 /Zi /MD /GX- /Od /Dwx_msw $(INC)
LINKFLAGS=/NOD /CO /ONERROR:NOEXE
!else
# /Ox for real FINAL version
OPT = /O2
CPPFLAGS= /W4 /MD /GX- /Dwx_msw $(INC) # $(PRECOMP) /Fp$(WXDIR)\src\msw\wx.pch
CFLAGS= /W4 /MD /GX- /Dwx_msw $(INC)
LINKFLAGS=/NOD /ONERROR:NOEXE
!endif
OBJECTS = png.obj pngread.obj pngrtran.obj pngrutil.obj \
pngpread.obj pngtrans.obj pngwrite.obj pngwtran.obj pngwutil.obj \
pngerror.obj pngmem.obj pngwio.obj pngrio.obj pngget.obj pngset.obj
all: $(WINPNGLIB)
$(WINPNGLIB): $(OBJECTS)
erase $(WINPNGLIB)
lib @<<
-out:$(WINPNGLIB)
$(OBJECTS)
<<
.c.obj:
cl -DWIN32 $(OPT) $(CFLAGS) /c $*.c
clean:
erase *.obj
erase *.exe
erase *.lib
cleanall: clean

View File

@@ -1,20 +0,0 @@
Copyright 1992, 1993, 1994, 1997 Henry Spencer. All rights reserved.
This software is not subject to any license of the American Telephone
and Telegraph Company or of the Regents of the University of California.
Permission is granted to anyone to use this software for any purpose on
any computer system, and to alter it and redistribute it, subject
to the following restrictions:
1. The author is not responsible for the consequences of use of this
software, no matter how awful, even if they arise from flaws in it.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission. Since few users ever read sources,
credits must appear in the documentation.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software. Since few users
ever read sources, credits must appear in the documentation.
4. This notice may not be removed or altered.

View File

@@ -1,130 +0,0 @@
# You probably want to take -DREDEBUG out of CFLAGS, and put something like
# -O in, *after* testing (-DREDEBUG strengthens testing by enabling a lot of
# internal assertion checking and some debugging facilities).
# Put -Dconst= in for a pre-ANSI compiler.
# Do not take -DPOSIX_MISTAKE out.
# REGCFLAGS isn't important to you (it's for my use in some special contexts).
CFLAGS=-I. -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS)
# If you have a pre-ANSI compiler, put -o into MKHFLAGS. If you want
# the Berkeley __P macro, put -b in.
MKHFLAGS=
# Flags for linking but not compiling, if any.
LDFLAGS=
# Extra libraries for linking, if any.
LIBS=
# Internal stuff, should not need changing.
OBJPRODN=regcomp.o regexec.o regerror.o regfree.o
OBJS=$(OBJPRODN) split.o debug.o main.o
H=cclass.h cname.h regex2.h utils.h
REGSRC=regcomp.c regerror.c regexec.c regfree.c
ALLSRC=$(REGSRC) engine.c debug.c main.c split.c
# Stuff that matters only if you're trying to lint the package.
LINTFLAGS=-I. -Dstatic= -Dconst= -DREDEBUG
LINTC=regcomp.c regexec.c regerror.c regfree.c debug.c main.c
JUNKLINT=possible pointer alignment|null effect
# arrangements to build forward-reference header files
.SUFFIXES: .ih .h
.c.ih:
sh ./mkh $(MKHFLAGS) -p $< >$@
default: r
lib: purge $(OBJPRODN)
rm -f libregex.a
ar crv libregex.a $(OBJPRODN)
purge:
rm -f *.o
# stuff to build regex.h
REGEXH=regex.h
REGEXHSRC=regex2.h $(REGSRC)
$(REGEXH): $(REGEXHSRC) mkh
sh ./mkh $(MKHFLAGS) -i _REGEX_H_ $(REGEXHSRC) >regex.tmp
cmp -s regex.tmp regex.h 2>/dev/null || cp regex.tmp regex.h
rm -f regex.tmp
# dependencies
$(OBJPRODN) debug.o: utils.h regex.h regex2.h
regcomp.o: cclass.h cname.h regcomp.ih
regexec.o: engine.c engine.ih
regerror.o: regerror.ih
debug.o: debug.ih
main.o: main.ih
# tester
re: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
# regression test
r: re tests
./re <tests
./re -el <tests
./re -er <tests
# 57 variants, and other stuff, for development use -- not useful to you
ra: ./re tests
-./re <tests
-./re -el <tests
-./re -er <tests
rx: ./re tests
./re -x <tests
./re -x -el <tests
./re -x -er <tests
t: ./re tests
-time ./re <tests
-time ./re -cs <tests
-time ./re -el <tests
-time ./re -cs -el <tests
l: $(LINTC)
lint $(LINTFLAGS) -h $(LINTC) 2>&1 | egrep -v '$(JUNKLINT)' | tee lint
fullprint:
ti README WHATSNEW notes todo | list
ti *.h | list
list *.c
list regex.3 regex.7
print:
ti README WHATSNEW notes todo | list
ti *.h | list
list reg*.c engine.c
mf.tmp: Makefile
sed '/^REGEXH=/s/=.*/=regex.h/' Makefile | sed '/#DEL$$/d' >$@
DTRH=cclass.h cname.h regex2.h utils.h
PRE=COPYRIGHT README WHATSNEW
POST=mkh regex.3 regex.7 tests $(DTRH) $(ALLSRC) fake/*.[ch]
FILES=$(PRE) Makefile $(POST)
DTR=$(PRE) Makefile=mf.tmp $(POST)
dtr: $(FILES) mf.tmp
makedtr $(DTR) >$@
rm mf.tmp
cio: $(FILES)
cio $(FILES)
rdf: $(FILES)
rcsdiff -c $(FILES) 2>&1 | p
# various forms of cleanup
tidy:
rm -f junk* core core.* *.core dtr *.tmp lint
clean: tidy
rm -f *.o *.s *.ih re libregex.a
# don't do this one unless you know what you're doing
spotless: clean
rm -f mkh regex.h

View File

@@ -1,32 +0,0 @@
alpha3.8 release.
Tue Aug 10 15:51:48 EDT 1999
henry@spsystems.net (formerly henry@zoo.toronto.edu)
See WHATSNEW for change listing.
installation notes:
--------
Read the comments at the beginning of Makefile before running.
Utils.h contains some things that just might have to be modified on
some systems, as well as a nested include (ugh) of <assert.h>.
The "fake" directory contains quick-and-dirty fakes for some header
files and routines that old systems may not have. Note also that
-DUSEBCOPY will make utils.h substitute bcopy() for memmove().
After that, "make r" will build regcomp.o, regexec.o, regfree.o,
and regerror.o (the actual routines), bundle them together into a test
program, and run regression tests on them. No output is good output.
"make lib" builds just the .o files for the actual routines (when
you're happy with testing and have adjusted CFLAGS for production),
and puts them together into libregex.a. You can pick up either the
library or *.o ("make lib" makes sure there are no other .o files left
around to confuse things).
Main.c, debug.c, split.c are used for regression testing but are not part
of the RE routines themselves.
Regex.h goes in /usr/include. All other .h files are internal only.
--------

View File

@@ -1,108 +0,0 @@
New in alpha3.8: Bug fix for signed/unsigned mixup, found and fixed
by the FreeBSD folks.
New in alpha3.7: A bit of cleanup aimed at maximizing portability,
possibly at slight cost in efficiency. "ul" suffixes and "unsigned long"
no longer appear, in particular.
New in alpha3.6: A couple more portability glitches fixed.
New in alpha3.5: Active development of this code has been stopped --
I'm working on a complete reimplementation -- but folks have found some
minor portability glitches and the like, hence this release to fix them.
One penalty: slightly reduced compatibility with old compilers, because
the ANSI C `unsigned long' type and `ul' constant suffix are used in a
few places (I could avoid this but it would be considerably more work).
New in alpha3.4: The complex bug alluded to below has been fixed (in a
slightly kludgey temporary way that may hurt efficiency a bit; this is
another "get it out the door for 4.4" release). The tests at the end of
the tests file have accordingly been uncommented. The primary sign of
the bug was that something like a?b matching ab matched b rather than ab.
(The bug was essentially specific to this exact situation, else it would
have shown up earlier.)
New in alpha3.3: The definition of word boundaries has been altered
slightly, to more closely match the usual programming notion that "_"
is an alphabetic. Stuff used for pre-ANSI systems is now in a subdir,
and the makefile no longer alludes to it in mysterious ways. The
makefile has generally been cleaned up some. Fixes have been made
(again!) so that the regression test will run without -DREDEBUG, at
the cost of weaker checking. A workaround for a bug in some folks'
<assert.h> has been added. And some more things have been added to
tests, including a couple right at the end which are commented out
because the code currently flunks them (complex bug; fix coming).
Plus the usual minor cleanup.
New in alpha3.2: Assorted bits of cleanup and portability improvement
(the development base is now a BSDI system using GCC instead of an ancient
Sun system, and the newer compiler exposed some glitches). Fix for a
serious bug that affected REs using many [] (including REG_ICASE REs
because of the way they are implemented), *sometimes*, depending on
memory-allocation patterns. The header-file prototypes no longer name
the parameters, avoiding possible name conflicts. The possibility that
some clot has defined CHAR_MIN as (say) `-128' instead of `(-128)' is
now handled gracefully. "uchar" is no longer used as an internal type
name (too many people have the same idea). Still the same old lousy
performance, alas.
New in alpha3.1: Basically nothing, this release is just a bookkeeping
convenience. Stay tuned.
New in alpha3.0: Performance is no better, alas, but some fixes have been
made and some functionality has been added. (This is basically the "get
it out the door in time for 4.4" release.) One bug fix: regfree() didn't
free the main internal structure (how embarrassing). It is now possible
to put NULs in either the RE or the target string, using (resp.) a new
REG_PEND flag and the old REG_STARTEND flag. The REG_NOSPEC flag to
regcomp() makes all characters ordinary, so you can match a literal
string easily (this will become more useful when performance improves!).
There are now primitives to match beginnings and ends of words, although
the syntax is disgusting and so is the implementation. The REG_ATOI
debugging interface has changed a bit. And there has been considerable
internal cleanup of various kinds.
New in alpha2.3: Split change list out of README, and moved flags notes
into Makefile. Macro-ized the name of regex(7) in regex(3), since it has
to change for 4.4BSD. Cleanup work in engine.c, and some new regression
tests to catch tricky cases thereof.
New in alpha2.2: Out-of-date manpages updated. Regerror() acquires two
small extensions -- REG_ITOA and REG_ATOI -- which avoid debugging kludges
in my own test program and might be useful to others for similar purposes.
The regression test will now compile (and run) without REDEBUG. The
BRE \$ bug is fixed. Most uses of "uchar" are gone; it's all chars now.
Char/uchar parameters are now written int/unsigned, to avoid possible
portability problems with unpromoted parameters. Some unsigned casts have
been introduced to minimize portability problems with shifting into sign
bits.
New in alpha2.1: Lots of little stuff, cleanup and fixes. The one big
thing is that regex.h is now generated, using mkh, rather than being
supplied in the distribution; due to circularities in dependencies,
you have to build regex.h explicitly by "make h". The two known bugs
have been fixed (and the regression test now checks for them), as has a
problem with assertions not being suppressed in the absence of REDEBUG.
No performance work yet.
New in alpha2: Backslash-anything is an ordinary character, not an
error (except, of course, for the handful of backslashed metacharacters
in BREs), which should reduce script breakage. The regression test
checks *where* null strings are supposed to match, and has generally
been tightened up somewhat. Small bug fixes in parameter passing (not
harmful, but technically errors) and some other areas. Debugging
invoked by defining REDEBUG rather than not defining NDEBUG.
New in alpha+3: full prototyping for internal routines, using a little
helper program, mkh, which extracts prototypes given in stylized comments.
More minor cleanup. Buglet fix: it's CHAR_BIT, not CHAR_BITS. Simple
pre-screening of input when a literal string is known to be part of the
RE; this does wonders for performance.
New in alpha+2: minor bits of cleanup. Notably, the number "32" for the
word width isn't hardwired into regexec.c any more, the public header
file prototypes the functions if __STDC__ is defined, and some small typos
in the manpages have been fixed.
New in alpha+1: improvements to the manual pages, and an important
extension, the REG_STARTEND option to regexec().

View File

@@ -1,31 +0,0 @@
/* character-class table */
static struct cclass {
char *name;
char *chars;
char *multis;
} cclasses[] = {
"alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789", "",
"alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"",
"blank", " \t", "",
"cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
\25\26\27\30\31\32\33\34\35\36\37\177", "",
"digit", "0123456789", "",
"graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
"",
"lower", "abcdefghijklmnopqrstuvwxyz",
"",
"print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
"",
"punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
"",
"space", "\t\n\v\f\r ", "",
"upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"",
"xdigit", "0123456789ABCDEFabcdef",
"",
NULL, 0, ""
};

View File

@@ -1,102 +0,0 @@
/* character-name table */
static struct cname {
char *name;
char code;
} cnames[] = {
"NUL", '\0',
"SOH", '\001',
"STX", '\002',
"ETX", '\003',
"EOT", '\004',
"ENQ", '\005',
"ACK", '\006',
"BEL", '\007',
"alert", '\007',
"BS", '\010',
"backspace", '\b',
"HT", '\011',
"tab", '\t',
"LF", '\012',
"newline", '\n',
"VT", '\013',
"vertical-tab", '\v',
"FF", '\014',
"form-feed", '\f',
"CR", '\015',
"carriage-return", '\r',
"SO", '\016',
"SI", '\017',
"DLE", '\020',
"DC1", '\021',
"DC2", '\022',
"DC3", '\023',
"DC4", '\024',
"NAK", '\025',
"SYN", '\026',
"ETB", '\027',
"CAN", '\030',
"EM", '\031',
"SUB", '\032',
"ESC", '\033',
"IS4", '\034',
"FS", '\034',
"IS3", '\035',
"GS", '\035',
"IS2", '\036',
"RS", '\036',
"IS1", '\037',
"US", '\037',
"space", ' ',
"exclamation-mark", '!',
"quotation-mark", '"',
"number-sign", '#',
"dollar-sign", '$',
"percent-sign", '%',
"ampersand", '&',
"apostrophe", '\'',
"left-parenthesis", '(',
"right-parenthesis", ')',
"asterisk", '*',
"plus-sign", '+',
"comma", ',',
"hyphen", '-',
"hyphen-minus", '-',
"period", '.',
"full-stop", '.',
"slash", '/',
"solidus", '/',
"zero", '0',
"one", '1',
"two", '2',
"three", '3',
"four", '4',
"five", '5',
"six", '6',
"seven", '7',
"eight", '8',
"nine", '9',
"colon", ':',
"semicolon", ';',
"less-than-sign", '<',
"equals-sign", '=',
"greater-than-sign", '>',
"question-mark", '?',
"commercial-at", '@',
"left-square-bracket", '[',
"backslash", '\\',
"reverse-solidus", '\\',
"right-square-bracket", ']',
"circumflex", '^',
"circumflex-accent", '^',
"underscore", '_',
"low-line", '_',
"grave-accent", '`',
"left-brace", '{',
"left-curly-bracket", '{',
"vertical-line", '|',
"right-brace", '}',
"right-curly-bracket", '}',
"tilde", '~',
"DEL", '\177',
NULL, 0,
};

View File

@@ -1,76 +0,0 @@
#! /bin/sh
# mkh - pull headers out of C source
PATH=/bin:/usr/bin ; export PATH
# egrep pattern to pick out marked lines
egrep='^ =([ ]|$)'
# Sed program to process marked lines into lines for the header file.
# The markers have already been removed. Two things are done here: removal
# of backslashed newlines, and some fudging of comments. The first is done
# because -o needs to have prototypes on one line to strip them down.
# Getting comments into the output is tricky; we turn C++-style // comments
# into /* */ comments, after altering any existing */'s to avoid trouble.
peel=' /\\$/N
/\\\n[ ]*/s///g
/\/\//s;\*/;* /;g
/\/\//s;//\(.*\);/*\1 */;'
for a
do
case "$a" in
-o) # old (pre-function-prototype) compiler
# add code to comment out argument lists
peel="$peel
"'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1(/*\2*/);'
shift
;;
-b) # funny Berkeley __P macro
peel="$peel
"'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1 __P((\2));'
shift
;;
-s) # compiler doesn't like `static foo();'
# add code to get rid of the `static'
peel="$peel
"'/^static[ ][^\/]*[a-zA-Z0-9_)](.*)/s;static.;;'
shift
;;
-p) # private declarations
egrep='^ ==([ ]|$)'
shift
;;
-i) # wrap in #ifndef, argument is name
ifndef="$2"
shift ; shift
;;
*) break
;;
esac
done
if test " $ifndef" != " "
then
echo "#ifndef $ifndef"
echo "#define $ifndef /* never again */"
fi
echo "/* ========= begin header generated by $0 ========= */"
echo '#ifdef __cplusplus'
echo 'extern "C" {'
echo '#endif'
for f
do
echo
echo "/* === $f === */"
egrep "$egrep" $f | sed 's/^ ==*[ ]//;s/^ ==*$//' | sed "$peel"
echo
done
echo '#ifdef __cplusplus'
echo '}'
echo '#endif'
echo "/* ========= end header generated by $0 ========= */"
if test " $ifndef" != " "
then
echo "#endif"
fi
exit 0

View File

@@ -1,970 +0,0 @@
'\"
'\" Copyright (c) 1998 Sun Microsystems, Inc.
'\" Copyright (c) 1999 Scriptics Corporation
'\"
'\" This software is copyrighted by the Regents of the University of
'\" California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState
'\" Corporation and other parties. The following terms apply to all files
'\" associated with the software unless explicitly disclaimed in
'\" individual files.
'\"
'\" The authors hereby grant permission to use, copy, modify, distribute,
'\" and license this software and its documentation for any purpose, provided
'\" that existing copyright notices are retained in all copies and that this
'\" notice is included verbatim in any distributions. No written agreement,
'\" license, or royalty fee is required for any of the authorized uses.
'\" Modifications to this software may be copyrighted by their authors
'\" and need not follow the licensing terms described here, provided that
'\" the new terms are clearly indicated on the first page of each file where
'\" they apply.
'\"
'\" IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
'\" FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
'\" ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
'\" DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
'\" POSSIBILITY OF SUCH DAMAGE.
'\"
'\" THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
'\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
'\" FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
'\" IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
'\" NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
'\" MODIFICATIONS.
'\"
'\" GOVERNMENT USE: If you are acquiring this software on behalf of the
'\" U.S. government, the Government shall have only "Restricted Rights"
'\" in the software and related documentation as defined in the Federal
'\" Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
'\" are acquiring the software on behalf of the Department of Defense, the
'\" software shall be classified as "Commercial Computer Software" and the
'\" Government shall have only "Restricted Rights" as defined in Clause
'\" 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
'\" authors grant the U.S. Government and others acting in its behalf
'\" permission to use and distribute the software in accordance with the
'\" terms specified in this license.
'\"
'\" RCS: @(#) Id: re_syntax.n,v 1.3 1999/07/14 19:09:36 jpeek Exp
'\"
.so man.macros
.TH re_syntax n "8.1" Tcl "Tcl Built-In Commands"
.BS
.SH NAME
re_syntax \- Syntax of Tcl regular expressions.
.BE
.SH DESCRIPTION
.PP
A \fIregular expression\fR describes strings of characters.
It's a pattern that matches certain strings and doesn't match others.
.SH "DIFFERENT FLAVORS OF REs"
Regular expressions (``RE''s), as defined by POSIX, come in two
flavors: \fIextended\fR REs (``EREs'') and \fIbasic\fR REs (``BREs'').
EREs are roughly those of the traditional \fIegrep\fR, while BREs are
roughly those of the traditional \fIed\fR. This implementation adds
a third flavor, \fIadvanced\fR REs (``AREs''), basically EREs with
some significant extensions.
.PP
This manual page primarily describes AREs. BREs mostly exist for
backward compatibility in some old programs; they will be discussed at
the end. POSIX EREs are almost an exact subset of AREs. Features of
AREs that are not present in EREs will be indicated.
.SH "REGULAR EXPRESSION SYNTAX"
.PP
Tcl regular expressions are implemented using the package written by
Henry Spencer, based on the 1003.2 spec and some (not quite all) of
the Perl5 extensions (thanks, Henry!). Much of the description of
regular expressions below is copied verbatim from his manual entry.
.PP
An ARE is one or more \fIbranches\fR,
separated by `\fB|\fR',
matching anything that matches any of the branches.
.PP
A branch is zero or more \fIconstraints\fR or \fIquantified atoms\fR,
concatenated.
It matches a match for the first, followed by a match for the second, etc;
an empty branch matches the empty string.
.PP
A quantified atom is an \fIatom\fR possibly followed
by a single \fIquantifier\fR.
Without a quantifier, it matches a match for the atom.
The quantifiers,
and what a so-quantified atom matches, are:
.RS 2
.TP 6
\fB*\fR
a sequence of 0 or more matches of the atom
.TP
\fB+\fR
a sequence of 1 or more matches of the atom
.TP
\fB?\fR
a sequence of 0 or 1 matches of the atom
.TP
\fB{\fIm\fB}\fR
a sequence of exactly \fIm\fR matches of the atom
.TP
\fB{\fIm\fB,}\fR
a sequence of \fIm\fR or more matches of the atom
.TP
\fB{\fIm\fB,\fIn\fB}\fR
a sequence of \fIm\fR through \fIn\fR (inclusive) matches of the atom;
\fIm\fR may not exceed \fIn\fR
.TP
\fB*? +? ?? {\fIm\fB}? {\fIm\fB,}? {\fIm\fB,\fIn\fB}?\fR
\fInon-greedy\fR quantifiers,
which match the same possibilities,
but prefer the smallest number rather than the largest number
of matches (see MATCHING)
.RE
.PP
The forms using
\fB{\fR and \fB}\fR
are known as \fIbound\fRs.
The numbers
\fIm\fR and \fIn\fR are unsigned decimal integers
with permissible values from 0 to 255 inclusive.
.PP
An atom is one of:
.RS 2
.TP 6
\fB(\fIre\fB)\fR
(where \fIre\fR is any regular expression)
matches a match for
\fIre\fR, with the match noted for possible reporting
.TP
\fB(?:\fIre\fB)\fR
as previous,
but does no reporting
(a ``non-capturing'' set of parentheses)
.TP
\fB()\fR
matches an empty string,
noted for possible reporting
.TP
\fB(?:)\fR
matches an empty string,
without reporting
.TP
\fB[\fIchars\fB]\fR
a \fIbracket expression\fR,
matching any one of the \fIchars\fR (see BRACKET EXPRESSIONS for more detail)
.TP
\fB.\fR
matches any single character
.TP
\fB\e\fIk\fR
(where \fIk\fR is a non-alphanumeric character)
matches that character taken as an ordinary character,
e.g. \e\e matches a backslash character
.TP
\fB\e\fIc\fR
where \fIc\fR is alphanumeric
(possibly followed by other characters),
an \fIescape\fR (AREs only),
see ESCAPES below
.TP
\fB{\fR
when followed by a character other than a digit,
matches the left-brace character `\fB{\fR';
when followed by a digit, it is the beginning of a
\fIbound\fR (see above)
.TP
\fIx\fR
where \fIx\fR is
a single character with no other significance, matches that character.
.RE
.PP
A \fIconstraint\fR matches an empty string when specific conditions
are met.
A constraint may not be followed by a quantifier.
The simple constraints are as follows; some more constraints are
described later, under ESCAPES.
.RS 2
.TP 8
\fB^\fR
matches at the beginning of a line
.TP
\fB$\fR
matches at the end of a line
.TP
\fB(?=\fIre\fB)\fR
\fIpositive lookahead\fR (AREs only), matches at any point
where a substring matching \fIre\fR begins
.TP
\fB(?!\fIre\fB)\fR
\fInegative lookahead\fR (AREs only), matches at any point
where no substring matching \fIre\fR begins
.RE
.PP
The lookahead constraints may not contain back references (see later),
and all parentheses within them are considered non-capturing.
.PP
An RE may not end with `\fB\e\fR'.
.SH "BRACKET EXPRESSIONS"
A \fIbracket expression\fR is a list of characters enclosed in `\fB[\|]\fR'.
It normally matches any single character from the list (but see below).
If the list begins with `\fB^\fR',
it matches any single character
(but see below) \fInot\fR from the rest of the list.
.PP
If two characters in the list are separated by `\fB\-\fR',
this is shorthand
for the full \fIrange\fR of characters between those two (inclusive) in the
collating sequence,
e.g.
\fB[0\-9]\fR
in ASCII matches any decimal digit.
Two ranges may not share an
endpoint, so e.g.
\fBa\-c\-e\fR
is illegal.
Ranges are very collating-sequence-dependent,
and portable programs should avoid relying on them.
.PP
To include a literal
\fB]\fR
or
\fB\-\fR
in the list,
the simplest method is to
enclose it in
\fB[.\fR and \fB.]\fR
to make it a collating element (see below).
Alternatively,
make it the first character
(following a possible `\fB^\fR'),
or (AREs only) precede it with `\fB\e\fR'.
Alternatively, for `\fB\-\fR',
make it the last character,
or the second endpoint of a range.
To use a literal
\fB\-\fR
as the first endpoint of a range,
make it a collating element
or (AREs only) precede it with `\fB\e\fR'.
With the exception of these, some combinations using
\fB[\fR
(see next
paragraphs), and escapes,
all other special characters lose their
special significance within a bracket expression.
.PP
Within a bracket expression, a collating element (a character,
a multi-character sequence that collates as if it were a single character,
or a collating-sequence name for either)
enclosed in
\fB[.\fR and \fB.]\fR
stands for the
sequence of characters of that collating element.
The sequence is a single element of the bracket expression's list.
A bracket expression in a locale that has
multi-character collating elements
can thus match more than one character.
.VS 8.2
So (insidiously), a bracket expression that starts with \fB^\fR
can match multi-character collating elements even if none of them
appear in the bracket expression!
(\fINote:\fR Tcl currently has no multi-character collating elements.
This information is only for illustration.)
.PP
For example, assume the collating sequence includes a \fBch\fR
multi-character collating element.
Then the RE \fB[[.ch.]]*c\fR (zero or more \fBch\fP's followed by \fBc\fP)
matches the first five characters of `\fBchchcc\fR'.
Also, the RE \fB[^c]b\fR matches all of `\fBchb\fR'
(because \fB[^c]\fR matches the multi-character \fBch\fR).
.VE 8.2
.PP
Within a bracket expression, a collating element enclosed in
\fB[=\fR
and
\fB=]\fR
is an equivalence class, standing for the sequences of characters
of all collating elements equivalent to that one, including itself.
(If there are no other equivalent collating elements,
the treatment is as if the enclosing delimiters were `\fB[.\fR'\&
and `\fB.]\fR'.)
For example, if
\fBo\fR
and
\fB\o'o^'\fR
are the members of an equivalence class,
then `\fB[[=o=]]\fR', `\fB[[=\o'o^'=]]\fR',
and `\fB[o\o'o^']\fR'\&
are all synonymous.
An equivalence class may not be an endpoint
of a range.
.VS 8.2
(\fINote:\fR
Tcl currently implements only the Unicode locale.
It doesn't define any equivalence classes.
The examples above are just illustrations.)
.VE 8.2
.PP
Within a bracket expression, the name of a \fIcharacter class\fR enclosed
in
\fB[:\fR
and
\fB:]\fR
stands for the list of all characters
(not all collating elements!)
belonging to that
class.
Standard character classes are:
.PP
.RS
.ne 5
.nf
.ta 3c
\fBalpha\fR A letter.
\fBupper\fR An upper-case letter.
\fBlower\fR A lower-case letter.
\fBdigit\fR A decimal digit.
\fBxdigit\fR A hexadecimal digit.
\fBalnum\fR An alphanumeric (letter or digit).
\fBprint\fR An alphanumeric (same as alnum).
\fBblank\fR A space or tab character.
\fBspace\fR A character producing white space in displayed text.
\fBpunct\fR A punctuation character.
\fBgraph\fR A character with a visible representation.
\fBcntrl\fR A control character.
.fi
.RE
.PP
A locale may provide others.
.VS 8.2
(Note that the current Tcl implementation has only one locale:
the Unicode locale.)
.VE 8.2
A character class may not be used as an endpoint of a range.
.PP
There are two special cases of bracket expressions:
the bracket expressions
\fB[[:<:]]\fR
and
\fB[[:>:]]\fR
are constraints, matching empty strings at
the beginning and end of a word respectively.
'\" note, discussion of escapes below references this definition of word
A word is defined as a sequence of
word characters
that is neither preceded nor followed by
word characters.
A word character is an
\fIalnum\fR
character
or an underscore
(\fB_\fR).
These special bracket expressions are deprecated;
users of AREs should use constraint escapes instead (see below).
.SH ESCAPES
Escapes (AREs only), which begin with a
\fB\e\fR
followed by an alphanumeric character,
come in several varieties:
character entry, class shorthands, constraint escapes, and back references.
A
\fB\e\fR
followed by an alphanumeric character but not constituting
a valid escape is illegal in AREs.
In EREs, there are no escapes:
outside a bracket expression,
a
\fB\e\fR
followed by an alphanumeric character merely stands for that
character as an ordinary character,
and inside a bracket expression,
\fB\e\fR
is an ordinary character.
(The latter is the one actual incompatibility between EREs and AREs.)
.PP
Character-entry escapes (AREs only) exist to make it easier to specify
non-printing and otherwise inconvenient characters in REs:
.RS 2
.TP 5
\fB\ea\fR
alert (bell) character, as in C
.TP
\fB\eb\fR
backspace, as in C
.TP
\fB\eB\fR
synonym for
\fB\e\fR
to help reduce backslash doubling in some
applications where there are multiple levels of backslash processing
.TP
\fB\ec\fIX\fR
(where X is any character) the character whose
low-order 5 bits are the same as those of
\fIX\fR,
and whose other bits are all zero
.TP
\fB\ee\fR
the character whose collating-sequence name
is `\fBESC\fR',
or failing that, the character with octal value 033
.TP
\fB\ef\fR
formfeed, as in C
.TP
\fB\en\fR
newline, as in C
.TP
\fB\er\fR
carriage return, as in C
.TP
\fB\et\fR
horizontal tab, as in C
.TP
\fB\eu\fIwxyz\fR
(where
\fIwxyz\fR
is exactly four hexadecimal digits)
the Unicode character
\fBU+\fIwxyz\fR
in the local byte ordering
.TP
\fB\eU\fIstuvwxyz\fR
(where
\fIstuvwxyz\fR
is exactly eight hexadecimal digits)
reserved for a somewhat-hypothetical Unicode extension to 32 bits
.TP
\fB\ev\fR
vertical tab, as in C
are all available.
.TP
\fB\ex\fIhhh\fR
(where
\fIhhh\fR
is any sequence of hexadecimal digits)
the character whose hexadecimal value is
\fB0x\fIhhh\fR
(a single character no matter how many hexadecimal digits are used).
.TP
\fB\e0\fR
the character whose value is
\fB0\fR
.TP
\fB\e\fIxy\fR
(where
\fIxy\fR
is exactly two octal digits,
and is not a
\fIback reference\fR (see below))
the character whose octal value is
\fB0\fIxy\fR
.TP
\fB\e\fIxyz\fR
(where
\fIxyz\fR
is exactly three octal digits,
and is not a
back reference (see below))
the character whose octal value is
\fB0\fIxyz\fR
.RE
.PP
Hexadecimal digits are `\fB0\fR'-`\fB9\fR', `\fBa\fR'-`\fBf\fR',
and `\fBA\fR'-`\fBF\fR'.
Octal digits are `\fB0\fR'-`\fB7\fR'.
.PP
The character-entry escapes are always taken as ordinary characters.
For example,
\fB\e135\fR
is
\fB]\fR
in ASCII,
but
\fB\e135\fR
does not terminate a bracket expression.
Beware, however, that some applications (e.g., C compilers) interpret
such sequences themselves before the regular-expression package
gets to see them, which may require doubling (quadrupling, etc.) the `\fB\e\fR'.
.PP
Class-shorthand escapes (AREs only) provide shorthands for certain commonly-used
character classes:
.RS 2
.TP 10
\fB\ed\fR
\fB[[:digit:]]\fR
.TP
\fB\es\fR
\fB[[:space:]]\fR
.TP
\fB\ew\fR
\fB[[:alnum:]_]\fR
(note underscore)
.TP
\fB\eD\fR
\fB[^[:digit:]]\fR
.TP
\fB\eS\fR
\fB[^[:space:]]\fR
.TP
\fB\eW\fR
\fB[^[:alnum:]_]\fR
(note underscore)
.RE
.PP
Within bracket expressions, `\fB\ed\fR', `\fB\es\fR',
and `\fB\ew\fR'\&
lose their outer brackets,
and `\fB\eD\fR', `\fB\eS\fR',
and `\fB\eW\fR'\&
are illegal.
.VS 8.2
(So, for example, \fB[a-c\ed]\fR is equivalent to \fB[a-c[:digit:]]\fR.
Also, \fB[a-c\eD]\fR, which is equivalent to \fB[a-c^[:digit:]]\fR, is illegal.)
.VE 8.2
.PP
A constraint escape (AREs only) is a constraint,
matching the empty string if specific conditions are met,
written as an escape:
.RS 2
.TP 6
\fB\eA\fR
matches only at the beginning of the string
(see MATCHING, below, for how this differs from `\fB^\fR')
.TP
\fB\em\fR
matches only at the beginning of a word
.TP
\fB\eM\fR
matches only at the end of a word
.TP
\fB\ey\fR
matches only at the beginning or end of a word
.TP
\fB\eY\fR
matches only at a point that is not the beginning or end of a word
.TP
\fB\eZ\fR
matches only at the end of the string
(see MATCHING, below, for how this differs from `\fB$\fR')
.TP
\fB\e\fIm\fR
(where
\fIm\fR
is a nonzero digit) a \fIback reference\fR, see below
.TP
\fB\e\fImnn\fR
(where
\fIm\fR
is a nonzero digit, and
\fInn\fR
is some more digits,
and the decimal value
\fImnn\fR
is not greater than the number of closing capturing parentheses seen so far)
a \fIback reference\fR, see below
.RE
.PP
A word is defined as in the specification of
\fB[[:<:]]\fR
and
\fB[[:>:]]\fR
above.
Constraint escapes are illegal within bracket expressions.
.PP
A back reference (AREs only) matches the same string matched by the parenthesized
subexpression specified by the number,
so that (e.g.)
\fB([bc])\e1\fR
matches
\fBbb\fR
or
\fBcc\fR
but not `\fBbc\fR'.
The subexpression must entirely precede the back reference in the RE.
Subexpressions are numbered in the order of their leading parentheses.
Non-capturing parentheses do not define subexpressions.
.PP
There is an inherent historical ambiguity between octal character-entry
escapes and back references, which is resolved by heuristics,
as hinted at above.
A leading zero always indicates an octal escape.
A single non-zero digit, not followed by another digit,
is always taken as a back reference.
A multi-digit sequence not starting with a zero is taken as a back
reference if it comes after a suitable subexpression
(i.e. the number is in the legal range for a back reference),
and otherwise is taken as octal.
.SH "METASYNTAX"
In addition to the main syntax described above, there are some special
forms and miscellaneous syntactic facilities available.
.PP
Normally the flavor of RE being used is specified by
application-dependent means.
However, this can be overridden by a \fIdirector\fR.
If an RE of any flavor begins with `\fB***:\fR',
the rest of the RE is an ARE.
If an RE of any flavor begins with `\fB***=\fR',
the rest of the RE is taken to be a literal string,
with all characters considered ordinary characters.
.PP
An ARE may begin with \fIembedded options\fR:
a sequence
\fB(?\fIxyz\fB)\fR
(where
\fIxyz\fR
is one or more alphabetic characters)
specifies options affecting the rest of the RE.
These supplement, and can override,
any options specified by the application.
The available option letters are:
.RS 2
.TP 3
\fBb\fR
rest of RE is a BRE
.TP 3
\fBc\fR
case-sensitive matching (usual default)
.TP 3
\fBe\fR
rest of RE is an ERE
.TP 3
\fBi\fR
case-insensitive matching (see MATCHING, below)
.TP 3
\fBm\fR
historical synonym for
\fBn\fR
.TP 3
\fBn\fR
newline-sensitive matching (see MATCHING, below)
.TP 3
\fBp\fR
partial newline-sensitive matching (see MATCHING, below)
.TP 3
\fBq\fR
rest of RE is a literal (``quoted'') string, all ordinary characters
.TP 3
\fBs\fR
non-newline-sensitive matching (usual default)
.TP 3
\fBt\fR
tight syntax (usual default; see below)
.TP 3
\fBw\fR
inverse partial newline-sensitive (``weird'') matching (see MATCHING, below)
.TP 3
\fBx\fR
expanded syntax (see below)
.RE
.PP
Embedded options take effect at the
\fB)\fR
terminating the sequence.
They are available only at the start of an ARE,
and may not be used later within it.
.PP
In addition to the usual (\fItight\fR) RE syntax, in which all characters are
significant, there is an \fIexpanded\fR syntax,
available in all flavors of RE
with the \fB-expanded\fR switch, or in AREs with the embedded x option.
In the expanded syntax,
white-space characters are ignored
and all characters between a
\fB#\fR
and the following newline (or the end of the RE) are ignored,
permitting paragraphing and commenting a complex RE.
There are three exceptions to that basic rule:
.RS 2
.PP
a white-space character or `\fB#\fR' preceded by `\fB\e\fR' is retained
.PP
white space or `\fB#\fR' within a bracket expression is retained
.PP
white space and comments are illegal within multi-character symbols
like the ARE `\fB(?:\fR' or the BRE `\fB\e(\fR'
.RE
.PP
Expanded-syntax white-space characters are blank, tab, newline, and
.VS 8.2
any character that belongs to the \fIspace\fR character class.
.VE 8.2
.PP
Finally, in an ARE,
outside bracket expressions, the sequence `\fB(?#\fIttt\fB)\fR'
(where
\fIttt\fR
is any text not containing a `\fB)\fR')
is a comment,
completely ignored.
Again, this is not allowed between the characters of
multi-character symbols like `\fB(?:\fR'.
Such comments are more a historical artifact than a useful facility,
and their use is deprecated;
use the expanded syntax instead.
.PP
\fINone\fR of these metasyntax extensions is available if the application
(or an initial
\fB***=\fR
director)
has specified that the user's input be treated as a literal string
rather than as an RE.
.SH MATCHING
In the event that an RE could match more than one substring of a given
string,
the RE matches the one starting earliest in the string.
If the RE could match more than one substring starting at that point,
its choice is determined by its \fIpreference\fR:
either the longest substring, or the shortest.
.PP
Most atoms, and all constraints, have no preference.
A parenthesized RE has the same preference (possibly none) as the RE.
A quantified atom with quantifier
\fB{\fIm\fB}\fR
or
\fB{\fIm\fB}?\fR
has the same preference (possibly none) as the atom itself.
A quantified atom with other normal quantifiers (including
\fB{\fIm\fB,\fIn\fB}\fR
with
\fIm\fR
equal to
\fIn\fR)
prefers longest match.
A quantified atom with other non-greedy quantifiers (including
\fB{\fIm\fB,\fIn\fB}?\fR
with
\fIm\fR
equal to
\fIn\fR)
prefers shortest match.
A branch has the same preference as the first quantified atom in it
which has a preference.
An RE consisting of two or more branches connected by the
\fB|\fR
operator prefers longest match.
.PP
Subject to the constraints imposed by the rules for matching the whole RE,
subexpressions also match the longest or shortest possible substrings,
based on their preferences,
with subexpressions starting earlier in the RE taking priority over
ones starting later.
Note that outer subexpressions thus take priority over
their component subexpressions.
.PP
Note that the quantifiers
\fB{1,1}\fR
and
\fB{1,1}?\fR
can be used to force longest and shortest preference, respectively,
on a subexpression or a whole RE.
.PP
Match lengths are measured in characters, not collating elements.
An empty string is considered longer than no match at all.
For example,
\fBbb*\fR
matches the three middle characters of `\fBabbbc\fR',
\fB(week|wee)(night|knights)\fR
matches all ten characters of `\fBweeknights\fR',
when
\fB(.*).*\fR
is matched against
\fBabc\fR
the parenthesized subexpression
matches all three characters, and
when
\fB(a*)*\fR
is matched against
\fBbc\fR
both the whole RE and the parenthesized
subexpression match an empty string.
.PP
If case-independent matching is specified,
the effect is much as if all case distinctions had vanished from the
alphabet.
When an alphabetic that exists in multiple cases appears as an
ordinary character outside a bracket expression, it is effectively
transformed into a bracket expression containing both cases,
so that
\fBx\fR
becomes `\fB[xX]\fR'.
When it appears inside a bracket expression, all case counterparts
of it are added to the bracket expression, so that
\fB[x]\fR
becomes
\fB[xX]\fR
and
\fB[^x]\fR
becomes `\fB[^xX]\fR'.
.PP
If newline-sensitive matching is specified, \fB.\fR
and bracket expressions using
\fB^\fR
will never match the newline character
(so that matches will never cross newlines unless the RE
explicitly arranges it)
and
\fB^\fR
and
\fB$\fR
will match the empty string after and before a newline
respectively, in addition to matching at beginning and end of string
respectively.
ARE
\fB\eA\fR
and
\fB\eZ\fR
continue to match beginning or end of string \fIonly\fR.
.PP
If partial newline-sensitive matching is specified,
this affects \fB.\fR
and bracket expressions
as with newline-sensitive matching, but not
\fB^\fR
and `\fB$\fR'.
.PP
If inverse partial newline-sensitive matching is specified,
this affects
\fB^\fR
and
\fB$\fR
as with
newline-sensitive matching,
but not \fB.\fR
and bracket expressions.
This isn't very useful but is provided for symmetry.
.SH "LIMITS AND COMPATIBILITY"
No particular limit is imposed on the length of REs.
Programs intended to be highly portable should not employ REs longer
than 256 bytes,
as a POSIX-compliant implementation can refuse to accept such REs.
.PP
The only feature of AREs that is actually incompatible with
POSIX EREs is that
\fB\e\fR
does not lose its special
significance inside bracket expressions.
All other ARE features use syntax which is illegal or has
undefined or unspecified effects in POSIX EREs;
the
\fB***\fR
syntax of directors likewise is outside the POSIX
syntax for both BREs and EREs.
.PP
Many of the ARE extensions are borrowed from Perl, but some have
been changed to clean them up, and a few Perl extensions are not present.
Incompatibilities of note include `\fB\eb\fR', `\fB\eB\fR',
the lack of special treatment for a trailing newline,
the addition of complemented bracket expressions to the things
affected by newline-sensitive matching,
the restrictions on parentheses and back references in lookahead constraints,
and the longest/shortest-match (rather than first-match) matching semantics.
.PP
The matching rules for REs containing both normal and non-greedy quantifiers
have changed since early beta-test versions of this package.
(The new rules are much simpler and cleaner,
but don't work as hard at guessing the user's real intentions.)
.PP
Henry Spencer's original 1986 \fIregexp\fR package,
still in widespread use (e.g., in pre-8.1 releases of Tcl),
implemented an early version of today's EREs.
There are four incompatibilities between \fIregexp\fR's near-EREs
(`RREs' for short) and AREs.
In roughly increasing order of significance:
.PP
.RS
In AREs,
\fB\e\fR
followed by an alphanumeric character is either an
escape or an error,
while in RREs, it was just another way of writing the
alphanumeric.
This should not be a problem because there was no reason to write
such a sequence in RREs.
.PP
\fB{\fR
followed by a digit in an ARE is the beginning of a bound,
while in RREs,
\fB{\fR
was always an ordinary character.
Such sequences should be rare,
and will often result in an error because following characters
will not look like a valid bound.
.PP
In AREs,
\fB\e\fR
remains a special character within `\fB[\|]\fR',
so a literal
\fB\e\fR
within
\fB[\|]\fR
must be written `\fB\e\e\fR'.
\fB\e\e\fR
also gives a literal
\fB\e\fR
within
\fB[\|]\fR
in RREs,
but only truly paranoid programmers routinely doubled the backslash.
.PP
AREs report the longest/shortest match for the RE,
rather than the first found in a specified search order.
This may affect some RREs which were written in the expectation that
the first match would be reported.
(The careful crafting of RREs to optimize the search order for fast
matching is obsolete (AREs examine all possible matches
in parallel, and their performance is largely insensitive to their
complexity) but cases where the search order was exploited to deliberately
find a match which was \fInot\fR the longest/shortest will need rewriting.)
.RE
.SH "BASIC REGULAR EXPRESSIONS"
BREs differ from EREs in several respects. `\fB|\fR', `\fB+\fR',
and
\fB?\fR
are ordinary characters and there is no equivalent
for their functionality.
The delimiters for bounds are
\fB\e{\fR
and `\fB\e}\fR',
with
\fB{\fR
and
\fB}\fR
by themselves ordinary characters.
The parentheses for nested subexpressions are
\fB\e(\fR
and `\fB\e)\fR',
with
\fB(\fR
and
\fB)\fR
by themselves ordinary characters.
\fB^\fR
is an ordinary character except at the beginning of the
RE or the beginning of a parenthesized subexpression,
\fB$\fR
is an ordinary character except at the end of the
RE or the end of a parenthesized subexpression,
and
\fB*\fR
is an ordinary character if it appears at the beginning of the
RE or the beginning of a parenthesized subexpression
(after a possible leading `\fB^\fR').
Finally,
single-digit back references are available,
and
\fB\e<\fR
and
\fB\e>\fR
are synonyms for
\fB[[:<:]]\fR
and
\fB[[:>:]]\fR
respectively;
no other escapes are available.
.SH "SEE ALSO"
RegExp(3), regexp(n), regsub(n), lsearch(n), switch(n), text(n)
.SH KEYWORDS
match, regular expression, string

File diff suppressed because it is too large Load Diff

View File

@@ -1,699 +0,0 @@
/*
* DFA routines
* This file is #included by regexec.c.
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
*
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
* thanks all of them.
*
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
* I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Header$
*
*/
/*
* longest - longest-preferred matching engine
*/
static chr * /* endpoint, or NULL */
longest(struct vars * v, /* used only for debug and exec flags */
struct dfa * d,
chr *start, /* where the match should start */
chr *stop, /* match must end at or before here */
int *hitstopp) /* record whether hit v->stop, if non-NULL */
{
chr *cp;
chr *realstop = (stop == v->stop) ? stop : stop + 1;
color co;
struct sset *css;
struct sset *ss;
chr *post;
int i;
struct colormap *cm = d->cm;
/* initialize */
css = initialize(v, d, start);
cp = start;
if (hitstopp != NULL)
*hitstopp = 0;
/* startup */
FDEBUG(("+++ startup +++\n"));
if (cp == v->start)
{
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co));
}
else
{
co = GETCOLOR(cm, *(cp - 1));
FDEBUG(("char %c, color %ld\n", (char) *(cp - 1), (long) co));
}
css = miss(v, d, css, co, cp, start);
if (css == NULL)
return NULL;
css->lastseen = cp;
/* main loop */
if (v->eflags & REG_FTRACE)
while (cp < realstop)
{
FDEBUG(("+++ at c%d +++\n", css - d->ssets));
co = GETCOLOR(cm, *cp);
FDEBUG(("char %c, color %ld\n", (char) *cp, (long) co));
ss = css->outs[co];
if (ss == NULL)
{
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL)
break; /* NOTE BREAK OUT */
}
cp++;
ss->lastseen = cp;
css = ss;
}
else
while (cp < realstop)
{
co = GETCOLOR(cm, *cp);
ss = css->outs[co];
if (ss == NULL)
{
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL)
break; /* NOTE BREAK OUT */
}
cp++;
ss->lastseen = cp;
css = ss;
}
/* shutdown */
FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
if (cp == v->stop && stop == v->stop)
{
if (hitstopp != NULL)
*hitstopp = 1;
co = d->cnfa->eos[(v->eflags & REG_NOTEOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co));
ss = miss(v, d, css, co, cp, start);
/* special case: match ended at eol? */
if (ss != NULL && (ss->flags & POSTSTATE))
return cp;
else if (ss != NULL)
ss->lastseen = cp; /* to be tidy */
}
/* find last match, if any */
post = d->lastpost;
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
if ((ss->flags & POSTSTATE) && post != ss->lastseen &&
(post == NULL || post < ss->lastseen))
post = ss->lastseen;
if (post != NULL) /* found one */
return post - 1;
return NULL;
}
/*
* shortest - shortest-preferred matching engine
*/
static chr * /* endpoint, or NULL */
shortest(struct vars * v,
struct dfa * d,
chr *start, /* where the match should start */
chr *min, /* match must end at or after here */
chr *max, /* match must end at or before here */
chr **coldp, /* store coldstart pointer here, if
* nonNULL */
int *hitstopp) /* record whether hit v->stop, if non-NULL */
{
chr *cp;
chr *realmin = (min == v->stop) ? min : min + 1;
chr *realmax = (max == v->stop) ? max : max + 1;
color co;
struct sset *css;
struct sset *ss;
struct colormap *cm = d->cm;
/* initialize */
css = initialize(v, d, start);
cp = start;
if (hitstopp != NULL)
*hitstopp = 0;
/* startup */
FDEBUG(("--- startup ---\n"));
if (cp == v->start)
{
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co));
}
else
{
co = GETCOLOR(cm, *(cp - 1));
FDEBUG(("char %c, color %ld\n", (char) *(cp - 1), (long) co));
}
css = miss(v, d, css, co, cp, start);
if (css == NULL)
return NULL;
css->lastseen = cp;
ss = css;
/* main loop */
if (v->eflags & REG_FTRACE)
while (cp < realmax)
{
FDEBUG(("--- at c%d ---\n", css - d->ssets));
co = GETCOLOR(cm, *cp);
FDEBUG(("char %c, color %ld\n", (char) *cp, (long) co));
ss = css->outs[co];
if (ss == NULL)
{
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL)
break; /* NOTE BREAK OUT */
}
cp++;
ss->lastseen = cp;
css = ss;
if ((ss->flags & POSTSTATE) && cp >= realmin)
break; /* NOTE BREAK OUT */
}
else
while (cp < realmax)
{
co = GETCOLOR(cm, *cp);
ss = css->outs[co];
if (ss == NULL)
{
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL)
break; /* NOTE BREAK OUT */
}
cp++;
ss->lastseen = cp;
css = ss;
if ((ss->flags & POSTSTATE) && cp >= realmin)
break; /* NOTE BREAK OUT */
}
if (ss == NULL)
return NULL;
if (coldp != NULL) /* report last no-progress state set, if
* any */
*coldp = lastcold(v, d);
if ((ss->flags & POSTSTATE) && cp > min)
{
assert(cp >= realmin);
cp--;
}
else if (cp == v->stop && max == v->stop)
{
co = d->cnfa->eos[(v->eflags & REG_NOTEOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co));
ss = miss(v, d, css, co, cp, start);
/* match might have ended at eol */
if ((ss == NULL || !(ss->flags & POSTSTATE)) && hitstopp != NULL)
*hitstopp = 1;
}
if (ss == NULL || !(ss->flags & POSTSTATE))
return NULL;
return cp;
}
/*
* lastcold - determine last point at which no progress had been made
*/
static chr * /* endpoint, or NULL */
lastcold(struct vars * v,
struct dfa * d)
{
struct sset *ss;
chr *nopr;
int i;
nopr = d->lastnopr;
if (nopr == NULL)
nopr = v->start;
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
if ((ss->flags & NOPROGRESS) && nopr < ss->lastseen)
nopr = ss->lastseen;
return nopr;
}
/*
* newdfa - set up a fresh DFA
*/
static struct dfa *
newdfa(struct vars * v,
struct cnfa * cnfa,
struct colormap * cm,
struct smalldfa * small) /* preallocated space, may be NULL */
{
struct dfa *d;
size_t nss = cnfa->nstates * 2;
int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
struct smalldfa *smallwas = small;
assert(cnfa != NULL && cnfa->nstates != 0);
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS)
{
assert(wordsper == 1);
if (small == NULL)
{
small = (struct smalldfa *) MALLOC(
sizeof(struct smalldfa));
if (small == NULL)
{
ERR(REG_ESPACE);
return NULL;
}
}
d = &small->dfa;
d->ssets = small->ssets;
d->statesarea = small->statesarea;
d->work = &d->statesarea[nss];
d->outsarea = small->outsarea;
d->incarea = small->incarea;
d->cptsmalloced = 0;
d->mallocarea = (smallwas == NULL) ? (char *) small : NULL;
}
else
{
d = (struct dfa *) MALLOC(sizeof(struct dfa));
if (d == NULL)
{
ERR(REG_ESPACE);
return NULL;
}
d->ssets = (struct sset *) MALLOC(nss * sizeof(struct sset));
d->statesarea = (unsigned *) MALLOC((nss + WORK) * wordsper *
sizeof(unsigned));
d->work = &d->statesarea[nss * wordsper];
d->outsarea = (struct sset **) MALLOC(nss * cnfa->ncolors *
sizeof(struct sset *));
d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors *
sizeof(struct arcp));
d->cptsmalloced = 1;
d->mallocarea = (char *) d;
if (d->ssets == NULL || d->statesarea == NULL ||
d->outsarea == NULL || d->incarea == NULL)
{
freedfa(d);
ERR(REG_ESPACE);
return NULL;
}
}
d->nssets = (v->eflags & REG_SMALL) ? 7 : nss;
d->nssused = 0;
d->nstates = cnfa->nstates;
d->ncolors = cnfa->ncolors;
d->wordsper = wordsper;
d->cnfa = cnfa;
d->cm = cm;
d->lastpost = NULL;
d->lastnopr = NULL;
d->search = d->ssets;
/* initialization of sset fields is done as needed */
return d;
}
/*
* freedfa - free a DFA
*/
static void
freedfa(struct dfa * d)
{
if (d->cptsmalloced)
{
if (d->ssets != NULL)
FREE(d->ssets);
if (d->statesarea != NULL)
FREE(d->statesarea);
if (d->outsarea != NULL)
FREE(d->outsarea);
if (d->incarea != NULL)
FREE(d->incarea);
}
if (d->mallocarea != NULL)
FREE(d->mallocarea);
}
/*
* hash - construct a hash code for a bitvector
*
* There are probably better ways, but they're more expensive.
*/
static unsigned
hash(unsigned *uv,
int n)
{
int i;
unsigned h;
h = 0;
for (i = 0; i < n; i++)
h ^= uv[i];
return h;
}
/*
* initialize - hand-craft a cache entry for startup, otherwise get ready
*/
static struct sset *
initialize(struct vars * v, /* used only for debug flags */
struct dfa * d,
chr *start)
{
struct sset *ss;
int i;
/* is previous one still there? */
if (d->nssused > 0 && (d->ssets[0].flags & STARTER))
ss = &d->ssets[0];
else
{ /* no, must (re)build it */
ss = getvacant(v, d, start, start);
for (i = 0; i < d->wordsper; i++)
ss->states[i] = 0;
BSET(ss->states, d->cnfa->pre);
ss->hash = HASH(ss->states, d->wordsper);
assert(d->cnfa->pre != d->cnfa->post);
ss->flags = STARTER | LOCKED | NOPROGRESS;
/* lastseen dealt with below */
}
for (i = 0; i < d->nssused; i++)
d->ssets[i].lastseen = NULL;
ss->lastseen = start; /* maybe untrue, but harmless */
d->lastpost = NULL;
d->lastnopr = NULL;
return ss;
}
/*
* miss - handle a cache miss
*/
static struct sset * /* NULL if goes to empty set */
miss(struct vars * v, /* used only for debug flags */
struct dfa * d,
struct sset * css,
pcolor co,
chr *cp, /* next chr */
chr *start) /* where the attempt got started */
{
struct cnfa *cnfa = d->cnfa;
int i;
unsigned h;
struct carc *ca;
struct sset *p;
int ispost;
int noprogress;
int gotstate;
int dolacons;
int sawlacons;
/* for convenience, we can be called even if it might not be a miss */
if (css->outs[co] != NULL)
{
FDEBUG(("hit\n"));
return css->outs[co];
}
FDEBUG(("miss\n"));
/* first, what set of states would we end up in? */
for (i = 0; i < d->wordsper; i++)
d->work[i] = 0;
ispost = 0;
noprogress = 1;
gotstate = 0;
for (i = 0; i < d->nstates; i++)
if (ISBSET(css->states, i))
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS; ca++)
if (ca->co == co)
{
BSET(d->work, ca->to);
gotstate = 1;
if (ca->to == cnfa->post)
ispost = 1;
if (!cnfa->states[ca->to]->co)
noprogress = 0;
FDEBUG(("%d -> %d\n", i, ca->to));
}
dolacons = (gotstate) ? (cnfa->flags & HASLACONS) : 0;
sawlacons = 0;
while (dolacons)
{ /* transitive closure */
dolacons = 0;
for (i = 0; i < d->nstates; i++)
if (ISBSET(d->work, i))
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS;
ca++)
{
if (ca->co <= cnfa->ncolors)
continue; /* NOTE CONTINUE */
sawlacons = 1;
if (ISBSET(d->work, ca->to))
continue; /* NOTE CONTINUE */
if (!lacon(v, cnfa, cp, ca->co))
continue; /* NOTE CONTINUE */
BSET(d->work, ca->to);
dolacons = 1;
if (ca->to == cnfa->post)
ispost = 1;
if (!cnfa->states[ca->to]->co)
noprogress = 0;
FDEBUG(("%d :> %d\n", i, ca->to));
}
}
if (!gotstate)
return NULL;
h = HASH(d->work, d->wordsper);
/* next, is that in the cache? */
for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
if (HIT(h, d->work, p, d->wordsper))
{
FDEBUG(("cached c%d\n", p - d->ssets));
break; /* NOTE BREAK OUT */
}
if (i == 0)
{ /* nope, need a new cache entry */
p = getvacant(v, d, cp, start);
assert(p != css);
for (i = 0; i < d->wordsper; i++)
p->states[i] = d->work[i];
p->hash = h;
p->flags = (ispost) ? POSTSTATE : 0;
if (noprogress)
p->flags |= NOPROGRESS;
/* lastseen to be dealt with by caller */
}
if (!sawlacons)
{ /* lookahead conds. always cache miss */
FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
css->outs[co] = p;
css->inchain[co] = p->ins;
p->ins.ss = css;
p->ins.co = (color) co;
}
return p;
}
/*
* lacon - lookahead-constraint checker for miss()
*/
static int /* predicate: constraint satisfied? */
lacon(struct vars * v,
struct cnfa * pcnfa, /* parent cnfa */
chr *cp,
pcolor co) /* "color" of the lookahead constraint */
{
int n;
struct subre *sub;
struct dfa *d;
struct smalldfa sd;
chr *end;
n = co - pcnfa->ncolors;
assert(n < v->g->nlacons && v->g->lacons != NULL);
FDEBUG(("=== testing lacon %d\n", n));
sub = &v->g->lacons[n];
d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
if (d == NULL)
{
ERR(REG_ESPACE);
return 0;
}
end = longest(v, d, cp, v->stop, (int *) NULL);
freedfa(d);
FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
return (sub->subno) ? (end != NULL) : (end == NULL);
}
/*
* getvacant - get a vacant state set
* This routine clears out the inarcs and outarcs, but does not otherwise
* clear the innards of the state set -- that's up to the caller.
*/
static struct sset *
getvacant(struct vars * v, /* used only for debug flags */
struct dfa * d,
chr *cp,
chr *start)
{
int i;
struct sset *ss;
struct sset *p;
struct arcp ap;
struct arcp lastap;
color co;
ss = pickss(v, d, cp, start);
assert(!(ss->flags & LOCKED));
/* clear out its inarcs, including self-referential ones */
ap = ss->ins;
while ((p = ap.ss) != NULL)
{
co = ap.co;
FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long) co));
p->outs[co] = NULL;
ap = p->inchain[co];
p->inchain[co].ss = NULL; /* paranoia */
}
ss->ins.ss = NULL;
/* take it off the inarc chains of the ssets reached by its outarcs */
for (i = 0; i < d->ncolors; i++)
{
p = ss->outs[i];
assert(p != ss); /* not self-referential */
if (p == NULL)
continue; /* NOTE CONTINUE */
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
if (p->ins.ss == ss && p->ins.co == i)
p->ins = ss->inchain[i];
else
{
assert(p->ins.ss != NULL);
for (ap = p->ins; ap.ss != NULL &&
!(ap.ss == ss && ap.co == i);
ap = ap.ss->inchain[ap.co])
lastap = ap;
assert(ap.ss != NULL);
lastap.ss->inchain[lastap.co] = ss->inchain[i];
}
ss->outs[i] = NULL;
ss->inchain[i].ss = NULL;
}
/* if ss was a success state, may need to remember location */
if ((ss->flags & POSTSTATE) && ss->lastseen != d->lastpost &&
(d->lastpost == NULL || d->lastpost < ss->lastseen))
d->lastpost = ss->lastseen;
/* likewise for a no-progress state */
if ((ss->flags & NOPROGRESS) && ss->lastseen != d->lastnopr &&
(d->lastnopr == NULL || d->lastnopr < ss->lastseen))
d->lastnopr = ss->lastseen;
return ss;
}
/*
* pickss - pick the next stateset to be used
*/
static struct sset *
pickss(struct vars * v, /* used only for debug flags */
struct dfa * d,
chr *cp,
chr *start)
{
int i;
struct sset *ss;
struct sset *end;
chr *ancient;
/* shortcut for cases where cache isn't full */
if (d->nssused < d->nssets)
{
i = d->nssused;
d->nssused++;
ss = &d->ssets[i];
FDEBUG(("new c%d\n", i));
/* set up innards */
ss->states = &d->statesarea[i * d->wordsper];
ss->flags = 0;
ss->ins.ss = NULL;
ss->ins.co = WHITE; /* give it some value */
ss->outs = &d->outsarea[i * d->ncolors];
ss->inchain = &d->incarea[i * d->ncolors];
for (i = 0; i < d->ncolors; i++)
{
ss->outs[i] = NULL;
ss->inchain[i].ss = NULL;
}
return ss;
}
/* look for oldest, or old enough anyway */
if (cp - start > d->nssets * 2 / 3) /* oldest 33% are expendable */
ancient = cp - d->nssets * 2 / 3;
else
ancient = start;
for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
!(ss->flags & LOCKED))
{
d->search = ss + 1;
FDEBUG(("replacing c%d\n", ss - d->ssets));
return ss;
}
for (ss = d->ssets, end = d->search; ss < end; ss++)
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
!(ss->flags & LOCKED))
{
d->search = ss + 1;
FDEBUG(("replacing c%d\n", ss - d->ssets));
return ss;
}
/* nobody's old enough?!? -- something's really wrong */
FDEBUG(("can't find victim to replace!\n"));
assert(NOTREACHED);
ERR(REG_ASSERT);
return d->ssets;
}

View File

@@ -1,109 +0,0 @@
/*
* regerror - error-code expansion
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
*
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
* thanks all of them.
*
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
* I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "regguts.h"
/* unknown-error explanation */
static char unk[] = "*** unknown regex error code 0x%x ***";
/* struct to map among codes, code names, and explanations */
static struct rerr {
int code;
char *name;
char *explain;
} rerrs[] = {
/* the actual table is built from regex.h */
# include "regerrs.h"
{ -1, "", "oops" }, /* explanation special-cased in code */
};
/*
- regerror - the interface to error numbers
*/
/* ARGSUSED */
size_t /* actual space needed (including NUL) */
regerror(errcode, preg, errbuf, errbuf_size)
int errcode; /* error code, or REG_ATOI or REG_ITOA */
CONST regex_t *preg; /* associated regex_t (unused at present) */
char *errbuf; /* result buffer (unless errbuf_size==0) */
size_t errbuf_size; /* available space in errbuf, can be 0 */
{
struct rerr *r;
char *msg;
char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
size_t len;
int icode;
switch (errcode) {
case REG_ATOI: /* convert name to number */
for (r = rerrs; r->code >= 0; r++)
if (strcmp(r->name, errbuf) == 0)
break;
sprintf(convbuf, "%d", r->code); /* -1 for unknown */
msg = convbuf;
break;
case REG_ITOA: /* convert number to name */
icode = atoi(errbuf); /* not our problem if this fails */
for (r = rerrs; r->code >= 0; r++)
if (r->code == icode)
break;
if (r->code >= 0)
msg = r->name;
else { /* unknown; tell him the number */
sprintf(convbuf, "REG_%u", (unsigned)icode);
msg = convbuf;
}
break;
default: /* a real, normal error code */
for (r = rerrs; r->code >= 0; r++)
if (r->code == errcode)
break;
if (r->code >= 0)
msg = r->explain;
else { /* unknown; say so */
sprintf(convbuf, unk, errcode);
msg = convbuf;
}
break;
}
len = strlen(msg) + 1; /* space needed, including NUL */
if (errbuf_size > 0) {
if (errbuf_size > len)
strcpy(errbuf, msg);
else { /* truncate to fit */
strncpy(errbuf, msg, errbuf_size-1);
errbuf[errbuf_size-1] = '\0';
}
}
return len;
}

View File

@@ -1,509 +0,0 @@
.TH REGEX 3 "25 Sept 1997"
.BY "Henry Spencer"
.de ZR
.\" one other place knows this name: the SEE ALSO section
.IR regex (7) \\$1
..
.SH NAME
regcomp, regexec, regerror, regfree \- regular-expression library
.SH SYNOPSIS
.ft B
.\".na
#include <sys/types.h>
.br
#include <regex.h>
.HP 10
int regcomp(regex_t\ *preg, const\ char\ *pattern, int\ cflags);
.HP
int\ regexec(const\ regex_t\ *preg, const\ char\ *string,
size_t\ nmatch, regmatch_t\ pmatch[], int\ eflags);
.HP
size_t\ regerror(int\ errcode, const\ regex_t\ *preg,
char\ *errbuf, size_t\ errbuf_size);
.HP
void\ regfree(regex_t\ *preg);
.\".ad
.ft
.SH DESCRIPTION
These routines implement POSIX 1003.2 regular expressions (``RE''s);
see
.ZR .
.I Regcomp
compiles an RE written as a string into an internal form,
.I regexec
matches that internal form against a string and reports results,
.I regerror
transforms error codes from either into human-readable messages,
and
.I regfree
frees any dynamically-allocated storage used by the internal form
of an RE.
.PP
The header
.I <regex.h>
declares two structure types,
.I regex_t
and
.IR regmatch_t ,
the former for compiled internal forms and the latter for match reporting.
It also declares the four functions,
a type
.IR regoff_t ,
and a number of constants with names starting with ``REG_''.
.PP
.I Regcomp
compiles the regular expression contained in the
.I pattern
string,
subject to the flags in
.IR cflags ,
and places the results in the
.I regex_t
structure pointed to by
.IR preg .
.I Cflags
is the bitwise OR of zero or more of the following flags:
.IP REG_EXTENDED \w'REG_EXTENDED'u+2n
Compile modern (``extended'') REs,
rather than the obsolete (``basic'') REs that
are the default.
.IP REG_BASIC
This is a synonym for 0,
provided as a counterpart to REG_EXTENDED to improve readability.
This is an extension,
compatible with but not specified by POSIX 1003.2,
and should be used with
caution in software intended to be portable to other systems.
.IP REG_NOSPEC
Compile with recognition of all special characters turned off.
All characters are thus considered ordinary,
so the ``RE'' is a literal string.
This is an extension,
compatible with but not specified by POSIX 1003.2,
and should be used with
caution in software intended to be portable to other systems.
REG_EXTENDED and REG_NOSPEC may not be used
in the same call to
.IR regcomp .
.IP REG_ICASE
Compile for matching that ignores upper/lower case distinctions.
See
.ZR .
.IP REG_NOSUB
Compile for matching that need only report success or failure,
not what was matched.
.IP REG_NEWLINE
Compile for newline-sensitive matching.
By default, newline is a completely ordinary character with no special
meaning in either REs or strings.
With this flag,
`[^' bracket expressions and `.' never match newline,
a `^' anchor matches the null string after any newline in the string
in addition to its normal function,
and the `$' anchor matches the null string before any newline in the
string in addition to its normal function.
.IP REG_PEND
The regular expression ends,
not at the first NUL,
but just before the character pointed to by the
.I re_endp
member of the structure pointed to by
.IR preg .
The
.I re_endp
member is of type
.IR const\ char\ * .
This flag permits inclusion of NULs in the RE;
they are considered ordinary characters.
This is an extension,
compatible with but not specified by POSIX 1003.2,
and should be used with
caution in software intended to be portable to other systems.
.PP
When successful,
.I regcomp
returns 0 and fills in the structure pointed to by
.IR preg .
One member of that structure
(other than
.IR re_endp )
is publicized:
.IR re_nsub ,
of type
.IR size_t ,
contains the number of parenthesized subexpressions within the RE
(except that the value of this member is undefined if the
REG_NOSUB flag was used).
If
.I regcomp
fails, it returns a non-zero error code;
see DIAGNOSTICS.
.PP
.I Regexec
matches the compiled RE pointed to by
.I preg
against the
.IR string ,
subject to the flags in
.IR eflags ,
and reports results using
.IR nmatch ,
.IR pmatch ,
and the returned value.
The RE must have been compiled by a previous invocation of
.IR regcomp .
The compiled form is not altered during execution of
.IR regexec ,
so a single compiled RE can be used simultaneously by multiple threads.
.PP
By default,
the NUL-terminated string pointed to by
.I string
is considered to be the text of an entire line,
with the NUL indicating the end of the line.
(That is,
any other end-of-line marker is considered to have been removed
and replaced by the NUL.)
The
.I eflags
argument is the bitwise OR of zero or more of the following flags:
.IP REG_NOTBOL \w'REG_STARTEND'u+2n
The first character of
the string
is not the beginning of a line, so the `^' anchor should not match before it.
This does not affect the behavior of newlines under REG_NEWLINE.
.IP REG_NOTEOL
The NUL terminating
the string
does not end a line, so the `$' anchor should not match before it.
This does not affect the behavior of newlines under REG_NEWLINE.
.IP REG_STARTEND
The string is considered to start at
\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_so\fR
and to have a terminating NUL located at
\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_eo\fR
(there need not actually be a NUL at that location),
regardless of the value of
.IR nmatch .
See below for the definition of
.IR pmatch
and
.IR nmatch .
This is an extension,
compatible with but not specified by POSIX 1003.2,
and should be used with
caution in software intended to be portable to other systems.
Note that a non-zero \fIrm_so\fR does not imply REG_NOTBOL;
REG_STARTEND affects only the location of the string,
not how it is matched.
.PP
See
.ZR
for a discussion of what is matched in situations where an RE or a
portion thereof could match any of several substrings of
.IR string .
.PP
Normally,
.I regexec
returns 0 for success and the non-zero code REG_NOMATCH for failure.
Other non-zero error codes may be returned in exceptional situations;
see DIAGNOSTICS.
.PP
If REG_NOSUB was specified in the compilation of the RE,
or if
.I nmatch
is 0,
.I regexec
ignores the
.I pmatch
argument (but see below for the case where REG_STARTEND is specified).
Otherwise,
.I pmatch
points to an array of
.I nmatch
structures of type
.IR regmatch_t .
Such a structure has at least the members
.I rm_so
and
.IR rm_eo ,
both of type
.I regoff_t
(a signed arithmetic type at least as large as an
.I off_t
and a
.IR ssize_t ),
containing respectively the offset of the first character of a substring
and the offset of the first character after the end of the substring.
Offsets are measured from the beginning of the
.I string
argument given to
.IR regexec .
An empty substring is denoted by equal offsets,
both indicating the character following the empty substring.
.PP
The 0th member of the
.I pmatch
array is filled in to indicate what substring of
.I string
was matched by the entire RE.
Remaining members report what substring was matched by parenthesized
subexpressions within the RE;
member
.I i
reports subexpression
.IR i ,
with subexpressions counted (starting at 1) by the order of their opening
parentheses in the RE, left to right.
Unused entries in the array\(emcorresponding either to subexpressions that
did not participate in the match at all, or to subexpressions that do not
exist in the RE (that is, \fIi\fR\ > \fIpreg\fR\->\fIre_nsub\fR)\(emhave both
.I rm_so
and
.I rm_eo
set to \-1.
If a subexpression participated in the match several times,
the reported substring is the last one it matched.
(Note, as an example in particular, that when the RE `(b*)+' matches `bbb',
the parenthesized subexpression matches the three `b's and then
an infinite number of empty strings following the last `b',
so the reported substring is one of the empties.)
.PP
If REG_STARTEND is specified,
.I pmatch
must point to at least one
.I regmatch_t
(even if
.I nmatch
is 0 or REG_NOSUB was specified),
to hold the input offsets for REG_STARTEND.
Use for output is still entirely controlled by
.IR nmatch ;
if
.I nmatch
is 0 or REG_NOSUB was specified,
the value of
.IR pmatch [0]
will not be changed by a successful
.IR regexec .
.PP
.I Regerror
maps a non-zero
.I errcode
from either
.I regcomp
or
.I regexec
to a human-readable, printable message.
If
.I preg
is non-NULL,
the error code should have arisen from use of
the
.I regex_t
pointed to by
.IR preg ,
and if the error code came from
.IR regcomp ,
it should have been the result from the most recent
.I regcomp
using that
.IR regex_t .
.RI ( Regerror
may be able to supply a more detailed message using information
from the
.IR regex_t .)
.I Regerror
places the NUL-terminated message into the buffer pointed to by
.IR errbuf ,
limiting the length (including the NUL) to at most
.I errbuf_size
bytes.
If the whole message won't fit,
as much of it as will fit before the terminating NUL is supplied.
In any case,
the returned value is the size of buffer needed to hold the whole
message (including terminating NUL).
If
.I errbuf_size
is 0,
.I errbuf
is ignored but the return value is still correct.
.PP
If the
.I errcode
given to
.I regerror
is first ORed with REG_ITOA,
the ``message'' that results is the printable name of the error code,
e.g. ``REG_NOMATCH'',
rather than an explanation thereof.
If
.I errcode
is REG_ATOI,
then
.I preg
shall be non-NULL and the
.I re_endp
member of the structure it points to
must point to the printable name of an error code;
in this case, the result in
.I errbuf
is the decimal digits of
the numeric value of the error code
(0 if the name is not recognized).
REG_ITOA and REG_ATOI are intended primarily as debugging facilities;
they are extensions,
compatible with but not specified by POSIX 1003.2,
and should be used with
caution in software intended to be portable to other systems.
Be warned also that they are considered experimental and changes are possible.
.PP
.I Regfree
frees any dynamically-allocated storage associated with the compiled RE
pointed to by
.IR preg .
The remaining
.I regex_t
is no longer a valid compiled RE
and the effect of supplying it to
.I regexec
or
.I regerror
is undefined.
.PP
None of these functions references global variables except for tables
of constants;
all are safe for use from multiple threads if the arguments are safe.
.SH IMPLEMENTATION CHOICES
There are a number of decisions that 1003.2 leaves up to the implementor,
either by explicitly saying ``undefined'' or by virtue of them being
forbidden by the RE grammar.
This implementation treats them as follows.
.PP
See
.ZR
for a discussion of the definition of case-independent matching.
.PP
There is no particular limit on the length of REs,
except insofar as memory is limited.
Memory usage is approximately linear in RE size, and largely insensitive
to RE complexity, except for bounded repetitions.
See BUGS for one short RE using them
that will run almost any system out of memory.
.PP
A backslashed character other than one specifically given a magic meaning
by 1003.2 (such magic meanings occur only in obsolete [``basic''] REs)
is taken as an ordinary character.
.PP
Any unmatched [ is a REG_EBRACK error.
.PP
Equivalence classes cannot begin or end bracket-expression ranges.
The endpoint of one range cannot begin another.
.PP
RE_DUP_MAX, the limit on repetition counts in bounded repetitions, is 255.
.PP
A repetition operator (?, *, +, or bounds) cannot follow another
repetition operator.
A repetition operator cannot begin an expression or subexpression
or follow `^' or `|'.
.PP
`|' cannot appear first or last in a (sub)expression or after another `|',
i.e. an operand of `|' cannot be an empty subexpression.
An empty parenthesized subexpression, `()', is legal and matches an
empty (sub)string.
An empty string is not a legal RE.
.PP
A `{' followed by a digit is considered the beginning of bounds for a
bounded repetition, which must then follow the syntax for bounds.
A `{' \fInot\fR followed by a digit is considered an ordinary character.
.PP
`^' and `$' beginning and ending subexpressions in obsolete (``basic'')
REs are anchors, not ordinary characters.
.SH SEE ALSO
grep(1), regex(7)
.PP
POSIX 1003.2, sections 2.8 (Regular Expression Notation)
and
B.5 (C Binding for Regular Expression Matching).
.SH DIAGNOSTICS
Non-zero error codes from
.I regcomp
and
.I regexec
include the following:
.PP
.nf
.ta \w'REG_ECOLLATE'u+3n
REG_NOMATCH regexec() failed to match
REG_BADPAT invalid regular expression
REG_ECOLLATE invalid collating element
REG_ECTYPE invalid character class
REG_EESCAPE \e applied to unescapable character
REG_ESUBREG invalid backreference number
REG_EBRACK brackets [ ] not balanced
REG_EPAREN parentheses ( ) not balanced
REG_EBRACE braces { } not balanced
REG_BADBR invalid repetition count(s) in { }
REG_ERANGE invalid character range in [ ]
REG_ESPACE ran out of memory
REG_BADRPT ?, *, or + operand invalid
REG_EMPTY empty (sub)expression
REG_ASSERT ``can't happen''\(emyou found a bug
REG_INVARG invalid argument, e.g. negative-length string
.fi
.SH HISTORY
Written by Henry Spencer,
henry@zoo.toronto.edu.
.SH BUGS
This is an alpha release with known defects.
Please report problems.
.PP
There is one known functionality bug.
The implementation of internationalization is incomplete:
the locale is always assumed to be the default one of 1003.2,
and only the collating elements etc. of that locale are available.
.PP
The back-reference code is subtle and doubts linger about its correctness
in complex cases.
.PP
.I Regexec
performance is poor.
This will improve with later releases.
.I Nmatch
exceeding 0 is expensive;
.I nmatch
exceeding 1 is worse.
.I Regexec
is largely insensitive to RE complexity \fIexcept\fR that back
references are massively expensive.
RE length does matter; in particular, there is a strong speed bonus
for keeping RE length under about 30 characters,
with most special characters counting roughly double.
.PP
.I Regcomp
implements bounded repetitions by macro expansion,
which is costly in time and space if counts are large
or bounded repetitions are nested.
An RE like, say,
`((((a{1,100}){1,100}){1,100}){1,100}){1,100}'
will (eventually) run almost any existing machine out of swap space.
.PP
There are suspected problems with response to obscure error conditions.
Notably,
certain kinds of internal overflow,
produced only by truly enormous REs or by multiply nested bounded repetitions,
are probably not handled well.
.PP
Due to a mistake in 1003.2, things like `a)b' are legal REs because `)' is
a special character only in the presence of a previous unmatched `('.
This can't be fixed until the spec is fixed.
.PP
The standard's definition of back references is vague.
For example, does
`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?
Until the standard is clarified,
behavior in such cases should not be relied on.
.PP
The implementation of word-boundary matching is a bit of a kludge,
and bugs may lurk in combinations of word-boundary matching and anchoring.

View File

@@ -1,235 +0,0 @@
.TH REGEX 7 "25 Oct 1995"
.BY "Henry Spencer"
.SH NAME
regex \- POSIX 1003.2 regular expressions
.SH DESCRIPTION
Regular expressions (``RE''s),
as defined in POSIX 1003.2, come in two forms:
modern REs (roughly those of
.IR egrep ;
1003.2 calls these ``extended'' REs)
and obsolete REs (roughly those of
.IR ed ;
1003.2 ``basic'' REs).
Obsolete REs mostly exist for backward compatibility in some old programs;
they will be discussed at the end.
1003.2 leaves some aspects of RE syntax and semantics open;
`\(dg' marks decisions on these aspects that
may not be fully portable to other 1003.2 implementations.
.PP
A (modern) RE is one\(dg or more non-empty\(dg \fIbranches\fR,
separated by `|'.
It matches anything that matches one of the branches.
.PP
A branch is one\(dg or more \fIpieces\fR, concatenated.
It matches a match for the first, followed by a match for the second, etc.
.PP
A piece is an \fIatom\fR possibly followed
by a single\(dg `*', `+', `?', or \fIbound\fR.
An atom followed by `*' matches a sequence of 0 or more matches of the atom.
An atom followed by `+' matches a sequence of 1 or more matches of the atom.
An atom followed by `?' matches a sequence of 0 or 1 matches of the atom.
.PP
A \fIbound\fR is `{' followed by an unsigned decimal integer,
possibly followed by `,'
possibly followed by another unsigned decimal integer,
always followed by `}'.
The integers must lie between 0 and RE_DUP_MAX (255\(dg) inclusive,
and if there are two of them, the first may not exceed the second.
An atom followed by a bound containing one integer \fIi\fR
and no comma matches
a sequence of exactly \fIi\fR matches of the atom.
An atom followed by a bound
containing one integer \fIi\fR and a comma matches
a sequence of \fIi\fR or more matches of the atom.
An atom followed by a bound
containing two integers \fIi\fR and \fIj\fR matches
a sequence of \fIi\fR through \fIj\fR (inclusive) matches of the atom.
.PP
An atom is a regular expression enclosed in `()' (matching a match for the
regular expression),
an empty set of `()' (matching the null string)\(dg,
a \fIbracket expression\fR (see below), `.'
(matching any single character), `^' (matching the null string at the
beginning of a line), `$' (matching the null string at the
end of a line), a `\e' followed by one of the characters
`^.[$()|*+?{\e'
(matching that character taken as an ordinary character),
a `\e' followed by any other character\(dg
(matching that character taken as an ordinary character,
as if the `\e' had not been present\(dg),
or a single character with no other significance (matching that character).
A `{' followed by a character other than a digit is an ordinary
character, not the beginning of a bound\(dg.
It is illegal to end an RE with `\e'.
.PP
A \fIbracket expression\fR is a list of characters enclosed in `[]'.
It normally matches any single character from the list (but see below).
If the list begins with `^',
it matches any single character
(but see below) \fInot\fR from the rest of the list.
If two characters in the list are separated by `\-', this is shorthand
for the full \fIrange\fR of characters between those two (inclusive) in the
collating sequence,
e.g. `[0\-9]' in ASCII matches any decimal digit.
It is illegal\(dg for two ranges to share an
endpoint, e.g. `a\-c\-e'.
Ranges are very collating-sequence-dependent,
and portable programs should avoid relying on them.
.PP
To include a literal `]' in the list, make it the first character
(following a possible `^').
To include a literal `\-', make it the first or last character,
or the second endpoint of a range.
To use a literal `\-' as the first endpoint of a range,
enclose it in `[.' and `.]' to make it a collating element (see below).
With the exception of these and some combinations using `[' (see next
paragraphs), all other special characters, including `\e', lose their
special significance within a bracket expression.
.PP
Within a bracket expression, a collating element (a character,
a multi-character sequence that collates as if it were a single character,
or a collating-sequence name for either)
enclosed in `[.' and `.]' stands for the
sequence of characters of that collating element.
The sequence is a single element of the bracket expression's list.
A bracket expression containing a multi-character collating element
can thus match more than one character,
e.g. if the collating sequence includes a `ch' collating element,
then the RE `[[.ch.]]*c' matches the first five characters
of `chchcc'.
.PP
Within a bracket expression, a collating element enclosed in `[=' and
`=]' is an equivalence class, standing for the sequences of characters
of all collating elements equivalent to that one, including itself.
(If there are no other equivalent collating elements,
the treatment is as if the enclosing delimiters were `[.' and `.]'.)
For example, if o and \o'o^' are the members of an equivalence class,
then `[[=o=]]', `[[=\o'o^'=]]', and `[o\o'o^']' are all synonymous.
An equivalence class may not\(dg be an endpoint
of a range.
.PP
Within a bracket expression, the name of a \fIcharacter class\fR enclosed
in `[:' and `:]' stands for the list of all characters belonging to that
class.
Standard character class names are:
.PP
.RS
.nf
.ta 3c 6c 9c
alnum digit punct
alpha graph space
blank lower upper
cntrl print xdigit
.fi
.RE
.PP
These stand for the character classes defined in
.IR ctype (3).
A locale may provide others.
A character class may not be used as an endpoint of a range.
.PP
There are two special cases\(dg of bracket expressions:
the bracket expressions `[[:<:]]' and `[[:>:]]' match the null string at
the beginning and end of a word respectively.
A word is defined as a sequence of
word characters
which is neither preceded nor followed by
word characters.
A word character is an
.I alnum
character (as defined by
.IR ctype (3))
or an underscore.
This is an extension,
compatible with but not specified by POSIX 1003.2,
and should be used with
caution in software intended to be portable to other systems.
.PP
In the event that an RE could match more than one substring of a given
string,
the RE matches the one starting earliest in the string.
If the RE could match more than one substring starting at that point,
it matches the longest.
Subexpressions also match the longest possible substrings, subject to
the constraint that the whole match be as long as possible,
with subexpressions starting earlier in the RE taking priority over
ones starting later.
Note that higher-level subexpressions thus take priority over
their lower-level component subexpressions.
.PP
Match lengths are measured in characters, not collating elements.
A null string is considered longer than no match at all.
For example,
`bb*' matches the three middle characters of `abbbc',
`(wee|week)(knights|nights)' matches all ten characters of `weeknights',
when `(.*).*' is matched against `abc' the parenthesized subexpression
matches all three characters, and
when `(a*)*' is matched against `bc' both the whole RE and the parenthesized
subexpression match the null string.
.PP
If case-independent matching is specified,
the effect is much as if all case distinctions had vanished from the
alphabet.
When an alphabetic that exists in multiple cases appears as an
ordinary character outside a bracket expression, it is effectively
transformed into a bracket expression containing both cases,
e.g. `x' becomes `[xX]'.
When it appears inside a bracket expression, all case counterparts
of it are added to the bracket expression, so that (e.g.) `[x]'
becomes `[xX]' and `[^x]' becomes `[^xX]'.
.PP
No particular limit is imposed on the length of REs\(dg.
Programs intended to be portable should not employ REs longer
than 256 bytes,
as an implementation can refuse to accept such REs and remain
POSIX-compliant.
.PP
Obsolete (``basic'') regular expressions differ in several respects.
`|', `+', and `?' are ordinary characters and there is no equivalent
for their functionality.
The delimiters for bounds are `\e{' and `\e}',
with `{' and `}' by themselves ordinary characters.
The parentheses for nested subexpressions are `\e(' and `\e)',
with `(' and `)' by themselves ordinary characters.
`^' is an ordinary character except at the beginning of the
RE or\(dg the beginning of a parenthesized subexpression,
`$' is an ordinary character except at the end of the
RE or\(dg the end of a parenthesized subexpression,
and `*' is an ordinary character if it appears at the beginning of the
RE or the beginning of a parenthesized subexpression
(after a possible leading `^').
Finally, there is one new type of atom, a \fIback reference\fR:
`\e' followed by a non-zero decimal digit \fId\fR
matches the same sequence of characters
matched by the \fId\fRth parenthesized subexpression
(numbering subexpressions by the positions of their opening parentheses,
left to right),
so that (e.g.) `\e([bc]\e)\e1' matches `bb' or `cc' but not `bc'.
.SH SEE ALSO
regex(3)
.PP
POSIX 1003.2, section 2.8 (Regular Expression Notation).
.SH HISTORY
Written by Henry Spencer, based on the 1003.2 spec.
.SH BUGS
Having two kinds of REs is a botch.
.PP
The current 1003.2 spec says that `)' is an ordinary character in
the absence of an unmatched `(';
this was an unintentional result of a wording error,
and change is likely.
Avoid relying on it.
.PP
Back references are a dreadful botch,
posing major problems for efficient implementations.
They are also somewhat vaguely defined
(does
`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?).
Avoid using them.
.PP
1003.2's specification of case-independent matching is vague.
The ``one case implies all cases'' definition given above
is current consensus among implementors as to the right interpretation.
.PP
The syntax for word boundaries is incredibly ugly.

View File

@@ -1,53 +0,0 @@
/*
* regfree - free an RE
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
*
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
* thanks all of them.
*
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
* I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*
* You might think that this could be incorporated into regcomp.c, and
* that would be a reasonable idea... except that this is a generic
* function (with a generic name), applicable to all compiled REs
* regardless of the size of their characters, whereas the stuff in
* regcomp.c gets compiled once per character size.
*/
#include "regguts.h"
/*
- regfree - free an RE (generic function, punts to RE-specific function)
*
* Ignoring invocation with NULL is a convenience.
*/
VOID
regfree(re)
regex_t *re;
{
if (re == NULL)
return;
(*((struct fns *)re->re_fns)->free)(re);
}

View File

@@ -1,83 +0,0 @@
/*
* regcomp and regexec - front ends to re_ routines
*
* Mostly for implementation of backward-compatibility kludges. Note
* that these routines exist ONLY in char versions.
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
*
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
* thanks all of them.
*
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
* I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "regguts.h"
/*
- regcomp - compile regular expression
*/
int
regcomp(re, str, flags)
regex_t *re;
CONST char *str;
int flags;
{
size_t len;
int f = flags;
if (f&REG_PEND) {
len = re->re_endp - str;
f &= ~REG_PEND;
} else
len = strlen(str);
return re_comp(re, str, len, f);
}
/*
- regexec - execute regular expression
*/
int
regexec(re, str, nmatch, pmatch, flags)
regex_t *re;
CONST char *str;
size_t nmatch;
regmatch_t pmatch[];
int flags;
{
CONST char *start;
size_t len;
int f = flags;
if (f&REG_STARTEND) {
start = str + pmatch[0].rm_so;
len = pmatch[0].rm_eo - pmatch[0].rm_so;
f &= ~REG_STARTEND;
} else {
start = str;
len = strlen(str);
}
return re_exec(re, start, len, nmatch, pmatch, f);
}

View File

@@ -1,477 +0,0 @@
# regular expression test set
# Lines are at least three fields, separated by one or more tabs. "" stands
# for an empty field. First field is an RE. Second field is flags. If
# C flag given, regcomp() is expected to fail, and the third field is the
# error name (minus the leading REG_).
#
# Otherwise it is expected to succeed, and the third field is the string to
# try matching it against. If there is no fourth field, the match is
# expected to fail. If there is a fourth field, it is the substring that
# the RE is expected to match. If there is a fifth field, it is a comma-
# separated list of what the subexpressions should match, with - indicating
# no match for that one. In both the fourth and fifth fields, a (sub)field
# starting with @ indicates that the (sub)expression is expected to match
# a null string followed by the stuff after the @; this provides a way to
# test where null strings match. The character `N' in REs and strings
# is newline, `S' is space, `T' is tab, `Z' is NUL.
#
# The full list of flags:
# - placeholder, does nothing
# b RE is a BRE, not an ERE
# & try it as both an ERE and a BRE
# C regcomp() error expected, third field is error name
# i REG_ICASE
# m ("mundane") REG_NOSPEC
# s REG_NOSUB (not really testable)
# n REG_NEWLINE
# ^ REG_NOTBOL
# $ REG_NOTEOL
# # REG_STARTEND (see below)
# p REG_PEND
#
# For REG_STARTEND, the start/end offsets are those of the substring
# enclosed in ().
# basics
a & a a
abc & abc abc
abc|de - abc abc
a|b|c - abc a
# parentheses and perversions thereof
a(b)c - abc abc
a\(b\)c b abc abc
a( C EPAREN
a( b a( a(
a\( - a( a(
a\( bC EPAREN
a\(b bC EPAREN
a(b C EPAREN
a(b b a(b a(b
# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly)
a) - a) a)
) - ) )
# end gagging (in a just world, those *should* give EPAREN)
a) b a) a)
a\) bC EPAREN
\) bC EPAREN
a()b - ab ab
a\(\)b b ab ab
# anchoring and REG_NEWLINE
^abc$ & abc abc
a^b - a^b
a^b b a^b a^b
a$b - a$b
a$b b a$b a$b
^ & abc @abc
$ & abc @
^$ & "" @
$^ - "" @
\($\)\(^\) b "" @
# stop retching, those are legitimate (although disgusting)
^^ - "" @
$$ - "" @
b$ & abNc
b$ &n abNc b
^b$ & aNbNc
^b$ &n aNbNc b
^$ &n aNNb @Nb
^$ n abc
^$ n abcN @
$^ n aNNb @Nb
\($\)\(^\) bn aNNb @Nb
^^ n^ aNNb @Nb
$$ n aNNb @NN
^a ^ a
a$ $ a
^a ^n aNb
^b ^n aNb b
a$ $n bNa
b$ $n bNa b
a*(^b$)c* - b b
a*\(^b$\)c* b b b
# certain syntax errors and non-errors
| C EMPTY
| b | |
* C BADRPT
* b * *
+ C BADRPT
? C BADRPT
"" &C EMPTY
() - abc @abc
\(\) b abc @abc
a||b C EMPTY
|ab C EMPTY
ab| C EMPTY
(|a)b C EMPTY
(a|)b C EMPTY
(*a) C BADRPT
(+a) C BADRPT
(?a) C BADRPT
({1}a) C BADRPT
\(\{1\}a\) bC BADRPT
(a|*b) C BADRPT
(a|+b) C BADRPT
(a|?b) C BADRPT
(a|{1}b) C BADRPT
^* C BADRPT
^* b * *
^+ C BADRPT
^? C BADRPT
^{1} C BADRPT
^\{1\} bC BADRPT
# metacharacters, backslashes
a.c & abc abc
a[bc]d & abd abd
a\*c & a*c a*c
a\\b & a\b a\b
a\\\*b & a\*b a\*b
a\bc & abc abc
a\ &C EESCAPE
a\\bc & a\bc a\bc
\{ bC BADRPT
a\[b & a[b a[b
a[b &C EBRACK
# trailing $ is a peculiar special case for the BRE code
a$ & a a
a$ & a$
a\$ & a
a\$ & a$ a$
a\\$ & a
a\\$ & a$
a\\$ & a\$
a\\$ & a\ a\
# back references, ugh
a\(b\)\2c bC ESUBREG
a\(b\1\)c bC ESUBREG
a\(b*\)c\1d b abbcbbd abbcbbd bb
a\(b*\)c\1d b abbcbd
a\(b*\)c\1d b abbcbbbd
^\(.\)\1 b abc
a\([bc]\)\1d b abcdabbd abbd b
a\(\([bc]\)\2\)*d b abbccd abbccd
a\(\([bc]\)\2\)*d b abbcbd
# actually, this next one probably ought to fail, but the spec is unclear
a\(\(b\)*\2\)*d b abbbd abbbd
# here is a case that no NFA implementation does right
\(ab*\)[ab]*\1 b ababaaa ababaaa a
# check out normal matching in the presence of back refs
\(a\)\1bcd b aabcd aabcd
\(a\)\1bc*d b aabcd aabcd
\(a\)\1bc*d b aabd aabd
\(a\)\1bc*d b aabcccd aabcccd
\(a\)\1bc*[ce]d b aabcccd aabcccd
^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd
# ordinary repetitions
ab*c & abc abc
ab+c - abc abc
ab?c - abc abc
a\(*\)b b a*b a*b
a\(**\)b b ab ab
a\(***\)b bC BADRPT
*a b *a *a
**a b a a
***a bC BADRPT
# the dreaded bounded repetitions
{ & { {
{abc & {abc {abc
{1 C BADRPT
{1} C BADRPT
a{b & a{b a{b
a{1}b - ab ab
a\{1\}b b ab ab
a{1,}b - ab ab
a\{1,\}b b ab ab
a{1,2}b - aab aab
a\{1,2\}b b aab aab
a{1 C EBRACE
a\{1 bC EBRACE
a{1a C EBRACE
a\{1a bC EBRACE
a{1a} C BADBR
a\{1a\} bC BADBR
a{,2} - a{,2} a{,2}
a\{,2\} bC BADBR
a{,} - a{,} a{,}
a\{,\} bC BADBR
a{1,x} C BADBR
a\{1,x\} bC BADBR
a{1,x C EBRACE
a\{1,x bC EBRACE
a{300} C BADBR
a\{300\} bC BADBR
a{1,0} C BADBR
a\{1,0\} bC BADBR
ab{0,0}c - abcac ac
ab\{0,0\}c b abcac ac
ab{0,1}c - abcac abc
ab\{0,1\}c b abcac abc
ab{0,3}c - abbcac abbc
ab\{0,3\}c b abbcac abbc
ab{1,1}c - acabc abc
ab\{1,1\}c b acabc abc
ab{1,3}c - acabc abc
ab\{1,3\}c b acabc abc
ab{2,2}c - abcabbc abbc
ab\{2,2\}c b abcabbc abbc
ab{2,4}c - abcabbc abbc
ab\{2,4\}c b abcabbc abbc
((a{1,10}){1,10}){1,10} - a a a,a
# multiple repetitions
a** &C BADRPT
a++ C BADRPT
a?? C BADRPT
a*+ C BADRPT
a*? C BADRPT
a+* C BADRPT
a+? C BADRPT
a?* C BADRPT
a?+ C BADRPT
a{1}{1} C BADRPT
a*{1} C BADRPT
a+{1} C BADRPT
a?{1} C BADRPT
a{1}* C BADRPT
a{1}+ C BADRPT
a{1}? C BADRPT
a*{b} - a{b} a{b}
a\{1\}\{1\} bC BADRPT
a*\{1\} bC BADRPT
a\{1\}* bC BADRPT
# brackets, and numerous perversions thereof
a[b]c & abc abc
a[ab]c & abc abc
a[^ab]c & adc adc
a[]b]c & a]c a]c
a[[b]c & a[c a[c
a[-b]c & a-c a-c
a[^]b]c & adc adc
a[^-b]c & adc adc
a[b-]c & a-c a-c
a[b &C EBRACK
a[] &C EBRACK
a[1-3]c & a2c a2c
a[3-1]c &C ERANGE
a[1-3-5]c &C ERANGE
a[[.-.]--]c & a-c a-c
a[1- &C ERANGE
a[[. &C EBRACK
a[[.x &C EBRACK
a[[.x. &C EBRACK
a[[.x.] &C EBRACK
a[[.x.]] & ax ax
a[[.x,.]] &C ECOLLATE
a[[.one.]]b & a1b a1b
a[[.notdef.]]b &C ECOLLATE
a[[.].]]b & a]b a]b
a[[:alpha:]]c & abc abc
a[[:notdef:]]c &C ECTYPE
a[[: &C EBRACK
a[[:alpha &C EBRACK
a[[:alpha:] &C EBRACK
a[[:alpha,:] &C ECTYPE
a[[:]:]]b &C ECTYPE
a[[:-:]]b &C ECTYPE
a[[:alph:]] &C ECTYPE
a[[:alphabet:]] &C ECTYPE
[[:alnum:]]+ - -%@a0X- a0X
[[:alpha:]]+ - -%@aX0- aX
[[:blank:]]+ - aSSTb SST
[[:cntrl:]]+ - aNTb NT
[[:digit:]]+ - a019b 019
[[:graph:]]+ - Sa%bS a%b
[[:lower:]]+ - AabC ab
[[:print:]]+ - NaSbN aSb
[[:punct:]]+ - S%-&T %-&
[[:space:]]+ - aSNTb SNT
[[:upper:]]+ - aBCd BC
[[:xdigit:]]+ - p0f3Cq 0f3C
a[[=b=]]c & abc abc
a[[= &C EBRACK
a[[=b &C EBRACK
a[[=b= &C EBRACK
a[[=b=] &C EBRACK
a[[=b,=]] &C ECOLLATE
a[[=one=]]b & a1b a1b
# complexities
a(((b)))c - abc abc
a(b|(c))d - abd abd
a(b*|c)d - abbd abbd
# just gotta have one DFA-buster, of course
a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
# and an inline expansion in case somebody gets tricky
a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
# and in case somebody just slips in an NFA...
a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights
# fish for anomalies as the number of states passes 32
12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789
123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890
1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901
12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012
123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123
# and one really big one, beyond any plausible word width
1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890
# fish for problems as brackets go past 8
[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm
[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo
[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq
[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq
# subtleties of matching
abc & xabcy abc
a\(b\)?c\1d b acd
aBc i Abc Abc
a[Bc]*d i abBCcd abBCcd
0[[:upper:]]1 &i 0a1 0a1
0[[:lower:]]1 &i 0A1 0A1
a[^b]c &i abc
a[^b]c &i aBc
a[^b]c &i adc adc
[a]b[c] - abc abc
[a]b[a] - aba aba
[abc]b[abc] - abc abc
[abc]b[abd] - abd abd
a(b?c)+d - accd accd
(wee|week)(knights|night) - weeknights weeknights
(we|wee|week|frob)(knights|night|day) - weeknights weeknights
a[bc]d - xyzaaabcaababdacd abd
a[ab]c - aaabc abc
abc s abc abc
a* & b @b
# Let's have some fun -- try to match a C comment.
# first the obvious, which looks okay at first glance...
/\*.*\*/ - /*x*/ /*x*/
# but...
/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/
# okay, we must not match */ inside; try to do that...
/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/
/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/
# but...
/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/
# and a still fancier version, which does it right (I think)...
/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/
/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/
/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/
/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/
/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/
/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/
# subexpressions
.* - abc abc -
a(b)(c)d - abcd abcd b,c
a(((b)))c - abc abc b,b,b
a(b|(c))d - abd abd b,-
a(b*|c|e)d - abbd abbd bb
a(b*|c|e)d - acd acd c
a(b*|c|e)d - ad ad @d
a(b?)c - abc abc b
a(b?)c - ac ac @c
a(b+)c - abc abc b
a(b+)c - abbbc abbbc bbb
a(b*)c - ac ac @c
(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de
# the regression tester only asks for 9 subexpressions
a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j
a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k
a([bc]?)c - abc abc b
a([bc]?)c - ac ac @c
a([bc]+)c - abc abc b
a([bc]+)c - abcc abcc bc
a([bc]+)bc - abcbc abcbc bc
a(bb+|b)b - abb abb b
a(bbb+|bb+|b)b - abb abb b
a(bbb+|bb+|b)b - abbb abbb bb
a(bbb+|bb+|b)bb - abbb abbb b
(.*).* - abcdef abcdef abcdef
(a*)* - bc @b @b
# do we get the right subexpression when it is used more than once?
a(b|c)*d - ad ad -
a(b|c)*d - abcd abcd c
a(b|c)+d - abd abd b
a(b|c)+d - abcd abcd c
a(b|c?)+d - ad ad @d
a(b|c?)+d - abcd abcd @d
a(b|c){0,0}d - ad ad -
a(b|c){0,1}d - ad ad -
a(b|c){0,1}d - abd abd b
a(b|c){0,2}d - ad ad -
a(b|c){0,2}d - abcd abcd c
a(b|c){0,}d - ad ad -
a(b|c){0,}d - abcd abcd c
a(b|c){1,1}d - abd abd b
a(b|c){1,1}d - acd acd c
a(b|c){1,2}d - abd abd b
a(b|c){1,2}d - abcd abcd c
a(b|c){1,}d - abd abd b
a(b|c){1,}d - abcd abcd c
a(b|c){2,2}d - acbd acbd b
a(b|c){2,2}d - abcd abcd c
a(b|c){2,4}d - abcd abcd c
a(b|c){2,4}d - abcbd abcbd b
a(b|c){2,4}d - abcbcd abcbcd c
a(b|c){2,}d - abcd abcd c
a(b|c){2,}d - abcbd abcbd b
a(b+|((c)*))+d - abd abd @d,@d,-
a(b+|((c)*))+d - abcd abcd @d,@d,-
# check out the STARTEND option
[abc] &# a(b)c b
[abc] &# a(d)c
[abc] &# a(bc)d b
[abc] &# a(dc)d c
. &# a()c
b.*c &# b(bc)c bc
b.* &# b(bc)c bc
.*c &# b(bc)c bc
# plain strings, with the NOSPEC flag
abc m abc abc
abc m xabcy abc
abc m xyz
a*b m aba*b a*b
a*b m ab
"" mC EMPTY
# cases involving NULs
aZb & a a
aZb &p a
aZb &p# (aZb) aZb
aZ*b &p# (ab) ab
a.b &# (aZb) aZb
a.* &# (aZb)c aZb
# word boundaries (ick)
[[:<:]]a & a a
[[:<:]]a & ba
[[:<:]]a & -a a
a[[:>:]] & a a
a[[:>:]] & ab
a[[:>:]] & a- a
[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc
[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc
[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc
[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc
[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_
[[:<:]]a_b[[:>:]] & x_a_b
# past problems, and suspected problems
(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1
abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop
abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv
(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11
CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11
Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz
a?b - ab ab
-\{0,1\}[0-9]*$ b -5 -5
a*a*a*a*a*a*a* & aaaaaa aaaaaa

View File

@@ -1,422 +0,0 @@
// -*- c++ -*- ///////////////////////////////////////////////////////////////
// Name: unix/net.cpp
// Purpose: Network related wxWindows classes and functions
// Author: Karsten Ball<6C>der
// Modified by:
// Created: 03.10.99
// RCS-ID: $Id$
// Copyright: (c) Karsten Ball<6C>der
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/setup.h"
#if wxUSE_DIALUP_MANAGER
#ifndef WX_PRECOMP
# include "wx/defs.h"
#endif // !PCH
#include "wx/string.h"
#include "wx/event.h"
#include "wx/net.h"
#include "wx/timer.h"
#include "wx/filefn.h"
#include "wx/utils.h"
#include "wx/log.h"
#include "wx/file.h"
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#define __STRICT_ANSI__
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// ----------------------------------------------------------------------------
// A class which groups functions dealing with connecting to the network from a
// workstation using dial-up access to the net. There is at most one instance
// of this class in the program accessed via GetDialUpManager().
// ----------------------------------------------------------------------------
/* TODO
*
* 1. more configurability for Unix: i.e. how to initiate the connection, how
* to check for online status, &c.
* 2. add a "long Dial(long connectionId = -1)" function which asks the user
* about which connection to dial (this may be done using native dialogs
* under NT, need generic dialogs for all others) and returns the identifier
* of the selected connection (it's opaque to the application) - it may be
* reused later to dial the same connection later (or use strings instead of
* longs may be?)
* 3. add an async version of dialing functions which notify the caller about
* the progress (or may be even start another thread to monitor it)
* 4. the static creation/accessor functions are not MT-safe - but is this
* really crucial? I think we may suppose they're always called from the
* main thread?
*/
class WXDLLEXPORT wxDialUpManagerImpl : public wxDialUpManager
{
public:
wxDialUpManagerImpl()
{
m_IsOnline = -1; // unknown
m_timer = NULL;
m_CanUseIfconfig = -1; // unknown
m_BeaconHost = WXDIALUP_MANAGER_DEFAULT_BEACONHOST;
m_BeaconPort = 80;
}
/** Could the dialup manager be initialized correctly? If this function
returns FALSE, no other functions will work neither, so it's a good idea
to call this function and check its result before calling any other
wxDialUpManager methods.
*/
virtual bool IsOk() const
{ return TRUE; }
/** The simplest way to initiate a dial up: this function dials the given
ISP (exact meaning of the parameter depends on the platform), returns
TRUE on success or FALSE on failure and logs the appropriate error
message in the latter case.
@param nameOfISP optional paramater for dial program
@param username unused
@param password unused
*/
virtual bool Dial(const wxString& nameOfISP,
const wxString& WXUNUSED(username),
const wxString& WXUNUSED(password));
/// Hang up the currently active dial up connection.
virtual bool HangUp();
// returns TRUE if the computer is connected to the network: under Windows,
// this just means that a RAS connection exists, under Unix we check that
// the "well-known host" (as specified by SetWellKnownHost) is reachable
virtual bool IsOnline() const
{
if( (! m_timer) // we are not polling, so test now:
|| m_IsOnline == -1
)
CheckStatus();
return m_IsOnline != 0;
}
// sometimes the built-in logic for determining the online status may fail,
// so, in general, the user should be allowed to override it. This function
// allows to forcefully set the online status - whatever our internal
// algorithm may think about it.
virtual void SetOnlineStatus(bool isOnline = TRUE)
{ m_IsOnline = isOnline; }
// set misc wxDialUpManager options
// --------------------------------
// enable automatical checks for the connection status and sending of
// wxEVT_DIALUP_CONNECTED/wxEVT_DIALUP_DISCONNECTED events. The interval
// parameter is only for Unix where we do the check manually: under
// Windows, the notification about the change of connection status is
// instantenous.
//
// Returns FALSE if couldn't set up automatic check for online status.
virtual bool EnableAutoCheckOnlineStatus(size_t nSeconds);
// disable automatic check for connection status change - notice that the
// wxEVT_DIALUP_XXX events won't be sent any more neither.
virtual void DisableAutoCheckOnlineStatus();
// under Unix, the value of well-known host is used to check whether we're
// connected to the internet. It's unused under Windows, but this function
// is always safe to call. The default value is www.yahoo.com.
virtual void SetWellKnownHost(const wxString& hostname,
int portno = 80);
/** Sets the commands to start up the network and to hang up
again. Used by the Unix implementations only.
*/
virtual void SetConnectCommand(const wxString &command, const wxString &hupcmd)
{ m_ConnectCommand = command; m_HangUpCommand = hupcmd; }
private:
/// -1: don<6F>t know, 0 = no, 1 = yes
int m_IsOnline;
/// Can we use ifconfig to list active devices?
int m_CanUseIfconfig;
/// The path to ifconfig
wxString m_IfconfigPath;
/// beacon host:
wxString m_BeaconHost;
/// beacon host portnumber for connect:
int m_BeaconPort;
/// command to connect to network
wxString m_ConnectCommand;
/// command to hang up
wxString m_HangUpCommand;
/// name of ISP
wxString m_ISPname;
/// a timer for regular testing
class AutoCheckTimer *m_timer;
friend class AutoCheckTimer;
/// determine status
void CheckStatus(void) const;
/// real status check
void CheckStatusInternal(void);
};
class AutoCheckTimer : public wxTimer
{
public:
AutoCheckTimer(wxDialUpManagerImpl *dupman)
{
m_dupman = dupman;
m_started = FALSE;
}
virtual bool Start( int millisecs = -1 )
{ m_started = TRUE; return wxTimer::Start(millisecs, FALSE); }
virtual void Notify()
{ wxLogTrace("Checking dial up network status."); m_dupman->CheckStatus(); }
virtual void Stop()
{ if ( m_started ) wxTimer::Stop(); }
public:
bool m_started;
wxDialUpManagerImpl *m_dupman;
};
bool
wxDialUpManagerImpl::Dial(const wxString &isp,
const wxString & WXUNUSED(username),
const wxString & WXUNUSED(password))
{
if(m_IsOnline == 1)
return FALSE;
m_IsOnline = -1;
m_ISPname = isp;
wxString cmd;
if(m_ConnectCommand.Find("%s"))
cmd.Printf(m_ConnectCommand,m_ISPname.c_str());
else
cmd = m_ConnectCommand;
return wxExecute(cmd, /* sync */ TRUE) == 0;
}
bool
wxDialUpManagerImpl::HangUp(void)
{
if(m_IsOnline == 0)
return FALSE;
m_IsOnline = -1;
wxString cmd;
if(m_HangUpCommand.Find("%s"))
cmd.Printf(m_HangUpCommand,m_ISPname.c_str());
else
cmd = m_HangUpCommand;
return wxExecute(cmd, /* sync */ TRUE) == 0;
}
bool
wxDialUpManagerImpl::EnableAutoCheckOnlineStatus(size_t nSeconds)
{
wxASSERT(m_timer == NULL);
m_timer = new AutoCheckTimer(this);
bool rc = m_timer->Start(nSeconds*1000);
if(! rc)
{
delete m_timer;
m_timer = NULL;
}
return rc;
}
void
wxDialUpManagerImpl::DisableAutoCheckOnlineStatus()
{
wxASSERT(m_timer != NULL);
m_timer->Stop();
delete m_timer;
m_timer = NULL;
}
void
wxDialUpManagerImpl::SetWellKnownHost(const wxString& hostname, int portno)
{
/// does hostname contain a port number?
wxString port = hostname.After(':');
if(port.Length())
{
m_BeaconHost = hostname.Before(':');
m_BeaconPort = atoi(port);
}
else
{
m_BeaconHost = hostname;
m_BeaconPort = portno;
}
}
void
wxDialUpManagerImpl::CheckStatus(void) const
{
// This function calls the CheckStatusInternal() helper function
// which is OS - specific and then sends the events.
int oldIsOnline = m_IsOnline;
( /* non-const */ (wxDialUpManagerImpl *)this)->CheckStatusInternal();
// now send the events as appropriate:
if(m_IsOnline != oldIsOnline)
{
if(m_IsOnline)
; // send ev
else
; // send ev
}
}
/*
We have three methods that we can use:
1. test via /sbin/ifconfig and grep for "sl", "ppp", "pl"
--> should be fast enough for regular polling
2. test if we can reach the well known beacon host
--> too slow for polling
3. check /proc/net/dev on linux??
This method should be preferred, if possible. Need to do more
testing.
*/
void
wxDialUpManagerImpl::CheckStatusInternal(void)
{
m_IsOnline = -1;
// First time check for ifconfig location. We only use the variant
// which does not take arguments, a la GNU.
if(m_CanUseIfconfig == -1) // unknown
{
if(wxFileExists("/sbin/ifconfig"))
m_IfconfigPath = "/sbin/ifconfig";
else if(wxFileExists("/usr/sbin/ifconfig"))
m_IfconfigPath = "/usr/sbin/ifconfig";
}
wxLogNull ln; // suppress all error messages
// Let<65>s try the ifconfig method first, should be fastest:
if(m_CanUseIfconfig != 0) // unknown or yes
{
wxASSERT(m_IfconfigPath.length());
wxString tmpfile = wxGetTempFileName("_wxdialuptest");
wxString cmd = "/bin/sh -c \'";
cmd << m_IfconfigPath << " >" << tmpfile << '\'';
/* I tried to add an option to wxExecute() to not close stdout,
so we could let ifconfig write directly to the tmpfile, but
this does not work. That should be faster, as it doesn<73>t call
the shell first. I have no idea why. :-( (KB) */
#if 0
// temporarily redirect stdout/stderr:
int
new_stdout = dup(STDOUT_FILENO),
new_stderr = dup(STDERR_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
int
// new stdout:
output_fd = open(tmpfile, O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR),
// new stderr:
null_fd = open("/dev/null", O_CREAT, S_IRUSR|S_IWUSR);
// verify well behaved unix behaviour:
wxASSERT(output_fd == STDOUT_FILENO);
wxASSERT(null_fd == STDERR_FILENO);
int rc = wxExecute(m_IfconfigPath,TRUE /* sync */,NULL ,wxEXECUTE_DONT_CLOSE_FDS);
close(null_fd); close(output_fd);
// restore old stdout, stderr:
int test;
test = dup(new_stdout); close(new_stdout); wxASSERT(test == STDOUT_FILENO);
test = dup(new_stderr); close(new_stderr); wxASSERT(test == STDERR_FILENO);
if(rc == 0)
#endif
if(wxExecute(cmd,TRUE /* sync */) == 0)
{
m_CanUseIfconfig = 1;
wxFile file;
if( file.Open(tmpfile) )
{
char *output = new char [file.Length()+1];
output[file.Length()] = '\0';
if(file.Read(output,file.Length()) == file.Length())
{
if(strstr(output,"ppp") // ppp
|| strstr(output,"sl") // slip
|| strstr(output,"pl") // plip
)
m_IsOnline = 1;
else
m_IsOnline = 0;
}
file.Close();
delete [] output;
}
// else m_IsOnline remains -1 as we don't know for sure
}
else // could not run ifconfig correctly
m_CanUseIfconfig = 0; // don<6F>t try again
(void) wxRemoveFile(tmpfile);
if(m_IsOnline != -1) // we are done
return;
}
// second method: try to connect to well known host:
// This can be used under Win 9x, too!
struct hostent *hp;
struct sockaddr_in serv_addr;
int sockfd;
m_IsOnline = 0; // assume false
if((hp = gethostbyname(m_BeaconHost)) == NULL)
return; // no DNS no net
serv_addr.sin_family = hp->h_addrtype;
memcpy(&serv_addr.sin_addr,hp->h_addr, hp->h_length);
serv_addr.sin_port = htons(m_BeaconPort);
if( ( sockfd = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
{
// sys_error("cannot create socket for gw");
return;
}
if( connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
//sys_error("cannot connect to server");
return;
}
//connected!
close(sockfd);
}
/* static */
wxDialUpManager *
wxDialUpManager::wxDialUpManager::Create(void)
{
return new wxDialUpManagerImpl;
}
#endif // wxUSE_DIALUP_MANAGER

View File

@@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /c
# ADD CPP /nologo /MT /W3 /GX /O1 /Ob2 /I "../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /c
# ADD BASE RSC /l 0x809
# ADD RSC /l 0x809
BSC32=bscmake.exe
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Z7 /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /c
# ADD CPP /nologo /MT /W3 /GX /Z7 /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /c
# ADD BASE RSC /l 0x809
# ADD RSC /l 0x809
BSC32=bscmake.exe

View File

@@ -1,3 +0,0 @@
Linux
linux-gnu
linux

View File

@@ -1,21 +0,0 @@
#
# File: makefile.vc
# Author: J Russell Smyth
# Created: 1999
# Updated:
# Copyright:
#
# Makefile : Builds frame layout demo
# Use FINAL=1 argument to nmake to build final version with no debug info.
# Set WXDIR for your system
WXDIR = $(WXWIN)
EXTRAINC = -I..\..\src
EXTRALIBS = $(WXDIR)\lib\fl.lib
EXTRAFLAGS = /DwxDUMMY_OBJ_INCLUDED
PROGRAM=fl_demo
OBJECTS = $(PROGRAM).obj settingsdlg.obj wxinfo.obj
!include $(WXDIR)\src\makeprog.vc

File diff suppressed because it is too large Load Diff

View File

@@ -1,137 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 04/11/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __FLDEMO_G__
#define __FLDEMO_G__
// ID for the menu commands
#define MINIMAL_QUIT 1
#define MINIMAL_ABOUT 102
#define ID_LOAD 103
#define ID_STORE 104
#define ID_AUTOSAVE 105
#define ID_SETTINGS 106
#define ID_REMOVE 107
#define ID_REMOVEALL 108
#define ID_RECREATE 109
#define ID_ACTIVATE 110
#define ID_FIRST 111
#define ID_SECOND 112
#define ID_THIRD 113
#define ID_SAY_ITSOK 114
#define ID_BTN_YES 115
#define ID_BTN_NO 116
#define ID_BTN_ESC 117
#define MAX_LAYOUTS 3
#define FIRST_LAYOUT 0
#define SECOND_LAYOUT 1
#define THIRD_LAYOUT 2
class wxFrameLayout;
// FOR NOW::
typedef wxPanel MyTestPanel;
// Define a new application type
class MyApp: public wxApp
{
public:
bool OnInit(void);
};
// Define a new frame type
class MyFrame: public wxFrame
{
protected:
wxFrameLayout* mLayouts[MAX_LAYOUTS];
wxFrameLayout* mpNestedLayout;
wxFrameLayout* mpAboutBoxLayout;
int mActiveLayoutNo;
bool mAutoSave;
bool mSavedAlready;
// container windows:
wxTextCtrl* mpClntWindow;
wxPanel* mpInternalFrm;
wxImageList mImageList;
wxFrame mAboutBox;
// helpers for control-creation
wxTextCtrl* CreateTxtCtrl ( const wxString& txt = "wxTextCtrl", wxWindow* parent = NULL );
wxTreeCtrl* CreateTreeCtrl( const wxString& label = "TreeCtrl" );
wxChoice* CreateChoice ( const wxString& txt = "Choice1" );
wxButton* CreateButton ( const wxString& label = "wxButton",
wxWindow* pParent = NULL, long id = ID_SAY_ITSOK );
// helpers for layout-creation
void AddSearchToolbars( wxFrameLayout& layout, wxWindow* pParent );
wxWindow* CreateDevLayout( wxFrameLayout& layout, wxWindow* pParent );
void DropInSomeBars( int layoutNo );
void CreateLayout( int layoutNo );
void RemoveLayout( int layoutNo );
void DestroyEverything();
void InitAboutBox();
void ActivateLayout( int layoutNo );
public: /* public */
MyFrame(wxFrame *frame, char *title,
int x, int y, int w, int h);
~MyFrame();
void SyncMenuBarItems();
// event handlers
bool OnClose(void);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnSettings( wxCommandEvent& event );
void OnRemove( wxCommandEvent& event );
void OnRemoveAll( wxCommandEvent& event );
void OnRecreate( wxCommandEvent& event );
void OnFirst( wxCommandEvent& event );
void OnSecond( wxCommandEvent& event );
void OnThird( wxCommandEvent& event );
void OnSayItsOk( wxCommandEvent& event );
void OnBtnYes( wxCommandEvent& event );
void OnBtnNo( wxCommandEvent& event );
void OnBtnEsc( wxCommandEvent& event );
void OnChar( wxKeyEvent& event );
DECLARE_EVENT_TABLE()
};
#endif

View File

@@ -1,21 +0,0 @@
#include "wx/msw/wx.rc"
start95_pr_icon BITMAP "../bitmaps/start95_pr.bmp"
start95_dp_icon BITMAP "../bitmaps/start95_dp.bmp"
folder_icon BITMAP "../bitmaps/folder_icon.bmp"
class_icon1 BITMAP "../bitmaps/class_icon1.bmp"
class_icon BITMAP "../bitmaps/class_icon.bmp"
res_icon BITMAP "../bitmaps/res_icon.bmp"
file_icon BITMAP "../bitmaps/file_icon.bmp"
help_icon BITMAP "../bitmaps/help_icon.bmp"
search_icon BITMAP "../bitmaps/search.bmp"
bookmarks_icon BITMAP "../bitmaps/bookmarks.bmp"
nextmark_icon BITMAP "../bitmaps/nextmark.bmp"
prevmark_icon BITMAP "../bitmaps/prevmark.bmp"
open_icon BITMAP "../bitmaps/open.bmp"
save_icon BITMAP "../bitmaps/save.bmp"
saveall_icon BITMAP "../bitmaps/saveall.bmp"
cut_icon BITMAP "../bitmaps/cut.bmp"
new_icon BITMAP "../bitmaps/new.bmp"
copy_icon BITMAP "../bitmaps/copy.bmp"
paste_icon BITMAP "../bitmaps/paste.bmp"

View File

@@ -1,496 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: settingsdlg.cpp
// Purpose: Settings dialog for Frame Layout
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 05/11/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "settingsdlg.cpp"
#pragma interface "settingsdlg.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <stdlib.h>
#include "settingsdlg.h"
/***** Implementation for class SettingsDlg *****/
#define ID_NOTES ( wxEVT_FIRST + 1000 )
#define ID_HINTANIM_CHECK ( ID_NOTES + 1 )
#define ID_RTUPDATES_CHECK ( ID_NOTES + 2 )
BEGIN_EVENT_TABLE( SettingsDlg, wxDialog )
EVT_BUTTON( wxID_APPLY, SettingsDlg::OnApply )
EVT_BUTTON( ID_NOTES, SettingsDlg::OnNotes )
EVT_CHECKBOX( ID_HINTANIM_CHECK, SettingsDlg::OnHintAnimCheck )
EVT_CHECKBOX( ID_RTUPDATES_CHECK, SettingsDlg::OnRTUpdatesCheck )
END_EVENT_TABLE()
SettingsDlg::SettingsDlg( wxWindow* pParent )
: wxDialog( pParent, -1, "Active Layout Settings...",
wxDefaultPosition,
wxSize( 325,585),
wxDIALOG_MODAL | wxCAPTION )
{
int curY = 10;
int lMargin = 50;
int lBoxMargin = lMargin - 20;
int checkHeight = 20;
int labelHeight = 20;
int boxWidth = 260;
int interBoxGap = 10;
int lastItemGap = 10;
int topY = curY;
curY += labelHeight;
mpRTU_Check = new wxCheckBox( this, ID_RTUPDATES_CHECK,
"&Real-time updates",
wxPoint( lMargin, curY ) );
curY += checkHeight;
mpOPD_Check = new wxCheckBox( this, -1, "&Out of Pane drag",
wxPoint( lMargin, curY ) );
curY += checkHeight;
mpEDP_Check = new wxCheckBox( this, -1, "&Exact docking prediction",
wxPoint( lMargin, curY ) );
curY += checkHeight;
mpNDF_Check = new wxCheckBox( this, -1, "Non-destructive bar &friction",
wxPoint( lMargin, curY ) );
curY += checkHeight;
mpSPB_Check = new wxCheckBox( this, -1, "&Shaded pane borders",
wxPoint( lMargin, curY ) );
curY += checkHeight + lastItemGap;
wxStaticBox* pDNDBox = new wxStaticBox( this, -1, "Drag && Drop settings",
wxPoint( lBoxMargin, topY ),
wxSize( boxWidth, curY - topY ) );
curY += interBoxGap;
////////////////////////////////////////////////////////////////////
topY = curY;
curY += labelHeight;
mpHAP_Check = new wxCheckBox( this, ID_HINTANIM_CHECK,
"&Hint-Rect animation plugin",
wxPoint( lMargin, curY ) );
curY += checkHeight;
mpGCU_Check = new wxCheckBox( this, -1, "\"Garbage collecting\" &Updates-Mgr.",
wxPoint( lMargin, curY ) );
curY += checkHeight;
mpAFP_Check = new wxCheckBox( this, -1, "&Antiflicker plugin",
wxPoint( lMargin, curY ) );
curY += checkHeight;
mpCSP_Check = new wxCheckBox( this, -1, "C&ustomization plugin",
wxPoint( lMargin, curY ) );
curY += checkHeight + lastItemGap;
wxStaticBox* pPBox = new wxStaticBox( this, -1, "Plugins",
wxPoint( lBoxMargin, topY ),
wxSize( boxWidth, curY - topY ) );
curY += interBoxGap;
////////////////////////////////////////////////////////////////////
wxSize fieldSz( 30,20 );
int fieldHeight = 20;
int fieldCapMargin = lMargin + fieldSz.x + 5;
int fieldCapOfs = 4;
topY = curY;
curY += labelHeight;
mpRWInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpRWLabel = new wxStaticText ( this, -1, "Resizing sash width(height)",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight;
mpPTMInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpPTMLabel = new wxStaticText( this, -1, "Pene's top margin",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight;
mpPBMInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpPBMLabel = new wxStaticText( this, -1, "Pene's bottom margin",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight;
mpPLMInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpPLMLabel = new wxStaticText( this, -1, "Pane's left margin",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight;
mpPRMInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpPRMLabel = new wxStaticText( this, -1, "Pane's right margin",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight + lastItemGap;
wxStaticBox* pCPPBox = new wxStaticBox( this, -1, "Common Pane properties",
wxPoint( lBoxMargin, topY ),
wxSize( boxWidth, curY - topY ) );
curY += interBoxGap;
////////////////////////////////////////////////////////////////////
topY = curY;
curY += labelHeight;
fieldSz.x = 65;
fieldCapMargin = lMargin + fieldSz.x + 10;
mpDCInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpDCLabel = new wxStaticText ( this, -1, "Dark Color (hex-RGB)",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight;
mpLCInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpLCLabel = new wxStaticText ( this, -1, "Light Color (hex-RGB)",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight;
mpGCInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpGCLabel = new wxStaticText ( this, -1, "Gray Color (hex-RGB)",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight;
mpBCInput = new wxTextCtrl ( this, -1, "",
wxPoint( lMargin, curY ),
fieldSz );
mpBCLabel = new wxStaticText ( this, -1, "Pane border Color (hex-RGB)",
wxPoint( fieldCapMargin, curY + fieldCapOfs ) );
curY += fieldHeight + lastItemGap;
wxStaticBox* pCSPBox = new wxStaticBox( this, -1, "Coluor sheme properties",
wxPoint( lBoxMargin, topY ),
wxSize( boxWidth, curY - topY ) );
curY += interBoxGap; /*button ofs*/;
////////////////////////////////////////////////////////////////////////////////
int lBtnMargin = 35;
int btnGap = 20;
int btnHeight = 22;
int btnWidth = 70;
wxButton* mpApplyBtn = new wxButton( this, wxID_APPLY, "A&pply",
wxPoint( lBtnMargin, curY ),
wxSize( btnWidth, btnHeight ) );
wxButton* mpCancelBtn = new wxButton( this, wxID_CANCEL, "&Cancel",
wxPoint( lBtnMargin + btnWidth + btnGap, curY ),
wxSize( btnWidth, btnHeight ) );
wxButton* mpNotesBtn = new wxButton( this, ID_NOTES, "&Notes...",
wxPoint( lBtnMargin + 2*btnWidth + 2*btnGap, curY ),
wxSize( btnWidth, btnHeight ) );
mpApplyBtn->SetDefault();
mpApplyBtn->SetFocus();
Center( wxBOTH );
}
void SettingsDlg::ExchangeFields( bool toDialog )
{
mToDlg = toDialog;
ExchgCheck( mpRTU_Check, mRealTimeUpdatesOn );
ExchgCheck( mpOPD_Check, mOutOfPaneDragOn );
ExchgCheck( mpEDP_Check, mExactDockingPredictionOn );
ExchgCheck( mpNDF_Check, mNonDestructFrictionOn );
ExchgCheck( mpSPB_Check, m3DShadesOn );
ExchgCheck( mpHAP_Check, mHintRectAnimationOn );
ExchgCheck( mpGCU_Check, mGCUpdatesMgrOn );
ExchgCheck( mpAFP_Check, mAntiflickerPluginOn );
ExchgCheck( mpCSP_Check, mCustomizationPluginOn );
ExchgIntField( mpRWInput, mSashWidth );
ExchgIntField( mpPTMInput, mTopMargin );
ExchgIntField( mpPBMInput, mBottomMargin );
ExchgIntField( mpPLMInput, mLeftMargin );
ExchgIntField( mpPRMInput, mRightMargin );
ExchgColourField( mpDCInput, mDarkCol );
ExchgColourField( mpLCInput, mLightCol );
ExchgColourField( mpGCInput, mGrayCol );
ExchgColourField( mpBCInput, mBorderCol );
}
void SettingsDlg::OnApply( wxCommandEvent& event )
{
ExchangeFields( FALSE );
EndModal( wxID_APPLY );
}
void SettingsDlg::OnNotes( wxCommandEvent& event )
{
wxMessageBox("Notes go here...(TBD)");
}
void SettingsDlg::OnRTUpdatesCheck( wxCommandEvent& event )
{
if ( mpRTU_Check->GetValue() == TRUE )
{
// user probably wants to see how the real-time drag & drop
// works -- so we "let 'im know" that animation is N/A when
// real-time option is on
mpHAP_Check->SetValue(FALSE);
mpHAP_Check->Refresh();
}
}
void SettingsDlg::OnHintAnimCheck( wxCommandEvent& event )
{
if ( mpHAP_Check->GetValue() == TRUE )
{
// user probably wants to see some animation effects,
// but he/she forgot to turn off "real-time updates"
// setting -- so we do it for you :-)
mpRTU_Check->SetValue(FALSE);
mpRTU_Check->Refresh();
}
}
void SettingsDlg::ExchgCheck( wxCheckBox* pChk, bool& value )
{
if ( mToDlg ) pChk->SetValue( value );
else value = pChk->GetValue();
}
void SettingsDlg::ExchgIntField( wxTextCtrl* pFld, int& value )
{
if ( mToDlg )
{
char buf[32];
sprintf( buf, "%d", value );
pFld->SetValue( buf );
}
else
{
wxString txt = pFld->GetLineText( 0 );
value = atoi( txt );
}
}
void SettingsDlg::ExchgColourField( wxTextCtrl* pFld, wxColour& value )
{
int rgbVal;
if ( mToDlg )
{
rgbVal = ( value.Red() & 0x0000FF ) |
( (value.Green() << 8 ) & 0x00FF00 ) |
( (value.Blue() << 16 ) & 0xFF0000 );
char buf[32];
sprintf( buf, "0x%06X", rgbVal );
pFld->SetValue( buf );
}
else
{
wxString txt = pFld->GetLineText( 0 );
sscanf( txt, "0x%06X", &rgbVal );
value.Set( rgbVal & 0xFF,
( rgbVal >> 8 ) & 0xFF,
( rgbVal >> 16 ) & 0xFF );
}
}
bool SettingsDlg::TransferDataToWindow()
{
ExchangeFields( TRUE );
return TRUE;
}
bool SettingsDlg::TransferDataFromWindow()
{
ExchangeFields( FALSE );
return TRUE;
}
#include "controlbar.h"
#include "rowlayoutpl.h"
#include "antiflickpl.h"
#include "bardragpl.h"
#include "cbcustom.h"
#include "gcupdatesmgr.h"
#include "hintanimpl.h"
void SettingsDlg::ReadLayoutSettings( wxFrameLayout& fl )
{
cbDockPane& pane = *fl.GetPane( wxTOP );
cbCommonPaneProperties& props = pane.mProps;
mRealTimeUpdatesOn = props.mRealTimeUpdatesOn;
mOutOfPaneDragOn = props.mOutOfPaneDragOn;
mExactDockingPredictionOn = props.mExactDockPredictionOn;
mNonDestructFrictionOn = props.mNonDestructFirctionOn;
m3DShadesOn = props.mShow3DPaneBorderOn;
mHintRectAnimationOn = fl.FindPlugin( CLASSINFO( cbHintAnimationPlugin ) ) != NULL;
mAntiflickerPluginOn = fl.FindPlugin( CLASSINFO( cbAntiflickerPlugin ) ) != NULL;
mCustomizationPluginOn = fl.FindPlugin( CLASSINFO( cbSimpleCustomizationPlugin ) ) != NULL;
mGCUpdatesMgrOn = fl.GetUpdatesManager().GetClassInfo()
== CLASSINFO( cbGCUpdatesMgr );
mSashWidth = props.mResizeHandleSize;
mTopMargin = pane.mTopMargin;
mBottomMargin = pane.mBottomMargin;
mLeftMargin = pane.mLeftMargin;
mRightMargin = pane.mRightMargin;
mDarkCol = fl.mDarkPen.GetColour();
mLightCol = fl.mLightPen.GetColour();
mGrayCol = fl.mGrayPen.GetColour();
mBorderCol = fl.mBorderPen.GetColour();
}
void SettingsDlg::ApplyLayoutSettings( wxFrameLayout& fl )
{
cbCommonPaneProperties props;
props.mRealTimeUpdatesOn = mRealTimeUpdatesOn;
props.mOutOfPaneDragOn = mOutOfPaneDragOn;
props.mExactDockPredictionOn = mExactDockingPredictionOn;
props.mNonDestructFirctionOn = mNonDestructFrictionOn;
props.mShow3DPaneBorderOn = m3DShadesOn;
props.mResizeHandleSize = mSashWidth;
fl.SetPaneProperties( props, wxALL_PANES );
if ( mHintRectAnimationOn ) fl.AddPlugin ( CLASSINFO( cbHintAnimationPlugin ) );
else fl.RemovePlugin( CLASSINFO( cbHintAnimationPlugin ) );
if ( mAntiflickerPluginOn ) fl.AddPlugin ( CLASSINFO( cbAntiflickerPlugin ) );
else fl.RemovePlugin( CLASSINFO( cbAntiflickerPlugin ) );
if ( mCustomizationPluginOn ) fl.AddPlugin ( CLASSINFO( cbSimpleCustomizationPlugin ) );
else fl.RemovePlugin( CLASSINFO( cbSimpleCustomizationPlugin ) );
// FOR NOW:: unfortunatelly, currently pane marin-information is currently
// placed into cbDockPane, instead of cbCommonPaneProperties
fl.SetMargins( mTopMargin, mBottomMargin,
mLeftMargin, mRightMargin, wxALL_PANES );
fl.mDarkPen.SetColour( mDarkCol );
fl.mLightPen.SetColour( mLightCol );
fl.mGrayPen.SetColour( mGrayCol );
fl.mBorderPen.SetColour( mBorderCol );
fl.RecalcLayout( TRUE );
// NOTE:: currently it's bit tricky changing updates-manager
// in future, updates-manager will become a normal plugin
// and more convenient methods (Add/FindPlugin) will be used
if ( mGCUpdatesMgrOn &&
fl.GetUpdatesManager().GetClassInfo() != CLASSINFO( cbGCUpdatesMgr )
)
fl.SetUpdatesManager( new cbGCUpdatesMgr( &fl ) );
else
if ( !mGCUpdatesMgrOn &&
fl.GetUpdatesManager().GetClassInfo() == CLASSINFO( cbGCUpdatesMgr )
)
fl.SetUpdatesManager( new cbSimpleUpdatesMgr( &fl ) );
}

View File

@@ -1,99 +0,0 @@
#ifndef __SETTINGSDLG_G__
#define __SETTINGSDLG_G__
#include "wx/dialog.h"
class wxFrameLayout;
class SettingsDlg : public wxDialog
{
protected:
// "nice thing" about wxWindows:
wxCheckBox* mpRTU_Check;
wxCheckBox* mpOPD_Check;
wxCheckBox* mpEDP_Check;
wxCheckBox* mpNDF_Check;
wxCheckBox* mpSPB_Check;
wxCheckBox* mpHAP_Check;
wxCheckBox* mpGCU_Check;
wxCheckBox* mpAFP_Check;
wxCheckBox* mpCSP_Check;
wxTextCtrl* mpRWInput;
wxStaticText* mpRWLabel;
wxTextCtrl* mpPTMInput;
wxStaticText* mpPTMLabel;
wxTextCtrl* mpPBMInput;
wxStaticText* mpPBMLabel;
wxTextCtrl* mpPLMInput;
wxStaticText* mpPLMLabel;
wxTextCtrl* mpPRMInput;
wxStaticText* mpPRMLabel;
wxTextCtrl* mpDCInput;
wxStaticText* mpDCLabel;
wxTextCtrl* mpLCInput;
wxStaticText* mpLCLabel;
wxTextCtrl* mpGCInput;
wxStaticText* mpGCLabel;
wxTextCtrl* mpBCInput;
wxStaticText* mpBCLabel;
// fields/properties
bool mRealTimeUpdatesOn;
bool mOutOfPaneDragOn;
bool mExactDockingPredictionOn;
bool mNonDestructFrictionOn;
bool m3DShadesOn;
bool mHintRectAnimationOn;
bool mGCUpdatesMgrOn;
bool mAntiflickerPluginOn;
bool mCustomizationPluginOn;
int mSashWidth;
int mTopMargin;
int mBottomMargin;
int mLeftMargin;
int mRightMargin;
wxColour mDarkCol;
wxColour mLightCol;
wxColour mGrayCol;
wxColour mBorderCol;
protected:
bool mToDlg;
// helpers
void ExchgCheck( wxCheckBox* pChk, bool& value );
void ExchgIntField( wxTextCtrl* pFld, int& value );
void ExchgColourField( wxTextCtrl* pFld, wxColour& value );
virtual bool TransferDataToWindow();
virtual bool TransferDataFromWindow();
public:
SettingsDlg( wxWindow* pParent );
void ReadLayoutSettings( wxFrameLayout& fl );
void ApplyLayoutSettings( wxFrameLayout& fl );
void ExchangeFields( bool toDialog );
void OnApply( wxCommandEvent& event );
void OnNotes( wxCommandEvent& event );
void OnHintAnimCheck( wxCommandEvent& event );
void OnRTUpdatesCheck( wxCommandEvent& event );
DECLARE_EVENT_TABLE();
};
#endif

View File

@@ -1,138 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 23/11/98
// RCS-ID: $Id$
// Copyright: 1998 (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "wxinifo.cpp"
#pragma interface "wxinifo.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/hash.h"
#include "wxinfo.h"
inline static void expand_item( wxTreeCtrl* pTree, wxTreeItemId& itemId )
{
pTree->Expand( itemId );
}
void wxCreateClassInfoTree( wxTreeCtrl* pTree,
wxTreeItemId parentBranchId,
long classImageNo
)
{
expand_item( pTree, parentBranchId );
wxHashTable hash;
wxList lst;
// collect all classes into list
{
wxClassInfo* pCur = wxClassInfo::GetFirst();
wxClassInfo::InitializeClasses();
while( pCur )
{
lst.Append( (wxObject*)pCur );
pCur = pCur->GetNext();
}
}
wxClassInfo::InitializeClasses();
// reflect class-hierarchy into the tree nodes
int nHanged;
do
{
nHanged = 0;
wxNode* pCur = lst.First();
// repeat passes through class list, untill all of
// the class items are "hanged" onto their parent-items in the tree
while( pCur )
{
wxClassInfo& info = *((wxClassInfo*)pCur->Data());
if ( info.GetBaseClass1() == NULL )
{
// parentless classes are put into the root branch
wxTreeItemId* pId = new wxTreeItemId();
*pId = pTree->AppendItem( parentBranchId, info.GetClassName(), classImageNo );
expand_item( pTree, *pId );
// "remember" it
hash.Put( long(&info), (wxObject*)pId );
// class is "hanged", remove it from the list
wxNode* pTmp = pCur;
pCur = pCur->Next();
delete pTmp;
++nHanged;
}
else
{
wxTreeItemId* pParentId = (wxTreeItemId*)hash.Get( (long)info.GetBaseClass1() );
if ( pParentId != NULL )
{
wxTreeItemId* pId = new wxTreeItemId();
*pId = pTree->AppendItem( *pParentId, info.GetClassName(), classImageNo );
expand_item( pTree, *pId );
hash.Put( long(&info), (wxObject*)pId );
wxNode* pTmp = pCur;
pCur = pCur->Next();
// class is "hanged", remove it from the list
delete pTmp;
++nHanged;
}
else
{
// otherwise there's a parent, but it's not in the tree yet...
// hope to "hang" it in the subsequent passes
pCur = pCur->Next();
}
}
}
} while( nHanged != 0 );
}

View File

@@ -1,35 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 23/11/98
// RCS-ID: $Id$
// Copyright: 1998 (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __WXINFO_G__
#define __WXINFO_G__
#include "wx/object.h"
#include "wx/treectrl.h"
/*
* creates tree with hierarchically cauptured
* information about wxWindows dynamic classes (at "current run-time")
*/
void wxCreateClassInfoTree( wxTreeCtrl* pTree,
wxTreeItemId parentBranchId,
long classImageNo = -1
);
/*
* creates tree with information about
* serializer-classes (at current run-time)
* NOTE:: "objstore.cpp" should be compiled in
*/
#endif

View File

@@ -1,3 +0,0 @@
Linux
linux-gnu
linux

View File

@@ -1,21 +0,0 @@
#
# File: makefile.vc
# Author: J Russell Smyth
# Created: 1999
# Updated:
# Copyright:
#
# Makefile : Builds frame layout sample
# Use FINAL=1 argument to nmake to build final version with no debug info.
# Set WXDIR for your system
WXDIR = $(WXWIN)
EXTRAINC = -I..\..\src
EXTRALIBS = $(WXDIR)\lib\fl.lib
EXTRAFLAGS = /DwxDUMMY_OBJ_INCLUDED
PROGRAM=fl_sample
OBJECTS = $(PROGRAM).obj
!include $(WXDIR)\src\makeprog.vc

View File

@@ -1,235 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: main.cpp
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 24/11/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "fl_sample.cpp"
#pragma interface "fl_sample.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "controlbar.h"
// plugins used
#include "barhintspl.h"
#include "hintanimpl.h"
#include "wx/textctrl.h"
// ADDED by alex (linker complaints...):
#ifndef wxDUMMY_OBJ_INCLUDED
char wxDummyChar=0;
#endif
#define ID_LOAD 102
#define ID_STORE 103
#define ID_QUIT 104
#define LAYOUT_FILE "layouts.dat"
class MyApp: public wxApp
{
public:
bool OnInit(void);
};
class MyFrame: public wxFrame
{
protected:
wxFrameLayout* mpLayout;
wxWindow* mpClientWnd;
wxPanel* mpInternalFrm;
wxTextCtrl* CreateTextCtrl( const wxString& value );
public:
MyFrame( wxWindow* parent, char *title );
~MyFrame();
void OnQuit( wxCommandEvent& event );
bool OnClose(void) { return TRUE; }
DECLARE_EVENT_TABLE()
};
/***** Implementation for class MyApp *****/
IMPLEMENT_APP (MyApp)
bool MyApp::OnInit(void)
{
// wxWindows boiler-plate:
MyFrame *frame = new MyFrame(NULL, "wxFrameLayout sample");
wxMenu *file_menu = new wxMenu;
file_menu->Append( ID_LOAD, "&Load layout" );
file_menu->Append( ID_STORE, "&Store layout" );
file_menu->AppendSeparator();
file_menu->Append( ID_QUIT, "E&xit" );
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
frame->CreateStatusBar(3);
frame->SetMenuBar(menu_bar);
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
/***** Immlementation for class MyFrame *****/
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU( ID_QUIT, MyFrame::OnQuit )
END_EVENT_TABLE()
MyFrame::MyFrame( wxWindow* parent, char *title )
: wxFrame( parent, -1, "NewTest-II", wxDefaultPosition,
wxSize( 700, 500 ),
wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
wxTHICK_FRAME | wxSYSTEM_MENU | wxCAPTION,
"freimas" )
{
#ifdef __WXMSW__
mpInternalFrm = (wxPanel*)this;
#else
mpInternalFrm = new wxPanel( this, -1 );
#endif
mpClientWnd = CreateTextCtrl( "Client window" );
// btw, creation of internal frame is needed for wxGtk version
// to act correctly (since menu-bar is a separate window there..)
mpLayout = new wxFrameLayout( mpInternalFrm, mpClientWnd );
#ifdef __WXGTK__
// real-time dosn't work well under wxGtk yet
cbCommonPaneProperties props;
mpLayout->GetPaneProperties( props );
props.mRealTimeUpdatesOn = FALSE; // off
mpLayout->SetPaneProperties( props, wxALL_PANES );
#endif
mpLayout->PushDefaultPlugins();
mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for barso
//mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) );
cbDimInfo sizes( 80,65, // when docked horizontally
80,65, // when docked vertically
80,30, // when floated
TRUE, // the bar is fixed-size
5, // vertical gap (bar border)
5 // horizontal gap (bar border)
);
// drop-in 20 bars
for( int i = 1; i <= 10; ++i )
{
char buf[4];
sprintf( buf, "%d", i );
wxString name = wxString("Bar-");
name += buf;
sizes.mIsFixed = i % 5 > 0; // every fifth bar is not fixed-size
if ( !sizes.mIsFixed ) name += " (flexible)";
mpLayout->AddBar( CreateTextCtrl(name),// bar window
sizes, i % MAX_PANES,// alignment ( 0-top,1-bottom, etc)
0, // insert into 0th row (vert. position)
0, // offset from the start of row (in pixels)
name // name to refere in customization pop-ups
);
}
}
MyFrame::~MyFrame()
{
// layout is not a window, should be released manually
if ( mpLayout ) delete mpLayout;
}
wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value )
{
wxTextCtrl* pCtrl =
new wxTextCtrl( mpInternalFrm, -1, value,
wxPoint(0,0), wxSize(1,1), wxTE_MULTILINE );
pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) );
return pCtrl;
}
void MyFrame::OnQuit( wxCommandEvent& event )
{
Show( FALSE ); // TRICK:: hide it, to avoid flickered destruction
Close(TRUE);
}
#ifdef __HACK_MY_MSDEV40__
////////////// new 2.0-magic (linker errors...) ////////////////
wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
{
wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
"recreating toolbar in wxFrame" );
wxToolBar* toolBar = OnCreateToolBar(style, id, name);
if (toolBar)
{
SetToolBar(toolBar);
PositionToolBar();
return toolBar;
}
else
{
return NULL;
}
}
wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name)
{
return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name);
}
#endif

View File

@@ -1,2 +0,0 @@
#include "wx/msw/wx.rc"

View File

@@ -1,3 +0,0 @@
Linux
linux-gnu
linux

View File

@@ -1,21 +0,0 @@
#
# File: makefile.vc
# Author: Julian Smart
# Created: 1999
# Updated:
# Copyright: (c) Julian Smart
#
# Makefile : Builds sample (VC++, WIN32)
# Use FINAL=1 argument to nmake to build final version with no debug info.
# Set WXDIR for your system
WXDIR = $(WXWIN)
EXTRAINC = -I..\..\src
EXTRALIBS = $(WXDIR)\lib\fl.lib
EXTRAFLAGS = /DwxDUMMY_OBJ_INCLUDED
PROGRAM=fl_test
OBJECTS = $(PROGRAM).obj
!include $(WXDIR)\src\makeprog.vc

View File

@@ -1,242 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: minimal.cpp
// Purpose: Minimal wxWindows sample
// Author: Julian Smart
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "minimal.cpp"
#pragma interface "minimal.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
/*
#ifdef __BORLANDC__
#pragma hdrstop
#endif
*/
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/textctrl.h"
#include "controlbar.h" // core API
#include "fl_test.h"
// extra plugins
#include "barhintspl.h" // beveal for bars with "X"s and grooves
#include "rowdragpl.h" // NC-look with dragable rows
#include "cbcustom.h" // customization plugin
#include "hintanimpl.h"
// beuty-care
#include "gcupdatesmgr.h" // smooth d&d
#include "antiflickpl.h" // double-buffered repaint of decorations
#include "dyntbar.h" // auto-layouting toolbar
#include "dyntbarhnd.h" // control-bar dimension handler for it
// comment it out if it breaks, (this is my workaround for MSDev 4.0 linker)
#ifndef wxDUMMY_OBJ_INCLUDED
char wxDummyChar;
#endif
IMPLEMENT_APP (MyApp)
bool MyApp::OnInit(void)
{
MyFrame *frame = new MyFrame(NULL);
frame->SetBackgroundColour( wxColour(192,192,192) );
wxMenu *file_menu = new wxMenu;
file_menu->Append( NEW_TEST_EXIT, "E&xit" );
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
frame->SetMenuBar(menu_bar);
frame->CreateStatusBar(3);
frame->Show(TRUE);
frame->mpClientWnd->Refresh();
SetTopWindow(frame);
return TRUE;
/*
wxMessageBox("Hello, this demo has a bunch of yet-not-fixed-bugs and misssing functionality\n\
The ONLY purpose is to demostrate self-layouting toolbars,\n flat-bitmapped-buttons and 2-new FL-plugins\
(cbRowDragPlugin & cbBarHintsPlugin)\n\n\
BTW, disabled images and label-text are rendered at run-time" );
*/
return TRUE;
}
/***** Implementation for class MyFrame *****/
BEGIN_EVENT_TABLE( MyFrame, wxFrame )
// EVT_CHAR_HOOK(MyFrame::OnKeyDown)
// EVT_PAINT( MyFrame::OnPaint )
EVT_MENU( NEW_TEST_EXIT, MyFrame::OnExit )
END_EVENT_TABLE()
void MyFrame::OnExit( wxCommandEvent& event )
{
Destroy();
}
wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value )
{
wxTextCtrl* pCtrl =
new wxTextCtrl( mpInternalFrm, -1, value,
wxDefaultPosition, wxSize(0,0), wxTE_MULTILINE );
pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) );
return pCtrl;
}
MyFrame::MyFrame(wxFrame *frame)
: wxFrame( frame, -1, "wxWindows 2.0 wxFrameLayout Test Application", wxDefaultPosition,
wxSize( 700, 500 ),
wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
wxTHICK_FRAME | wxSYSTEM_MENU | wxCAPTION,
"freimas" )
{
mpInternalFrm = (wxPanel*)this;
mpClientWnd = CreateTextCtrl( "Client window" );
mpLayout = new wxFrameLayout( mpInternalFrm, mpClientWnd );
#ifdef __WXGTK__
cbCommonPaneProperties props;
mpLayout->GetPaneProperties( props );
props.mRealTimeUpdatesOn = FALSE; // real-time OFF!!!
mpLayout->SetPaneProperties( props, wxALL_PANES );
#endif
mpLayout->SetUpdatesManager( new cbGCUpdatesMgr() );
// this is now default...
//mpLayout->SetMargins( 1,1,1,1 ); // gaps for vertical/horizontal/right/left panes
// setup plugins for testing
mpLayout->PushDefaultPlugins();
mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for bars
mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) );
mpLayout->AddPlugin( CLASSINFO( cbRowDragPlugin ) );
mpLayout->AddPlugin( CLASSINFO( cbAntiflickerPlugin ) );
mpLayout->AddPlugin( CLASSINFO( cbSimpleCustomizationPlugin ) );
// drop in some bars
cbDimInfo sizes0(200,45, // when docked horizontally
200,85, // when docked vertically
175,35, // when floated
FALSE, // the bar is not fixed-size
4, // vertical gap (bar border)
4 // horizontal gap (bar border)
);
cbDimInfo sizes1(150,35, // when docked horizontally
150,85, // when docked vertically
175,35, // when floated
TRUE, // the bar is not fixed-size
4, // vertical gap (bar border)
4 // horizontal gap (bar border)
);
cbDimInfo sizes2(175,45, // when docked horizontally
175,37, // when docked vertically
170,35, // when floated
TRUE, // the bar is not fixed-size
4, // vertical gap (bar border)
4, // horizontal gap (bar border)
new cbDynToolBarDimHandler()
);
mpLayout->AddBar( CreateTextCtrl("Hello"), // bar window
sizes0, wxTOP, // alignment ( 0-top,1-bottom, etc)
0, // insert into 0th row (vert. position)
0, // offset from the start of row (in pixels)
"InfoViewer1", // name to refere in customization pop-ups
TRUE
);
mpLayout->AddBar( CreateTextCtrl("Bye"), // bar window
sizes0, wxTOP, // alignment ( 0-top,1-bottom, etc)
1, // insert into 0th row (vert. position)
0, // offset from the start of row (in pixels)
"InfoViewer2", // name to refere in customization pop-ups
TRUE
);
mpLayout->EnableFloating( FALSE ); // off, thinking bout wxGtk...
}
MyFrame::~MyFrame()
{
if ( mpLayout) delete mpLayout; // should be destroyed manually
}
#ifdef __HACK_MY_MSDEV40__
////////////// new 2.0-magic (linker errors...) ////////////////
wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
{
wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
"recreating toolbar in wxFrame" );
wxToolBar* toolBar = OnCreateToolBar(style, id, name);
if (toolBar)
{
SetToolBar(toolBar);
PositionToolBar();
return toolBar;
}
else
{
return NULL;
}
}
wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name)
{
return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name);
}
#endif

View File

@@ -1,35 +0,0 @@
#ifndef __NEW_TEST_G__
#define __NEW_TEST_G__
#include "wx/panel.h"
// Define a new application type
class MyApp: public wxApp
{ public:
bool OnInit(void);
};
class MyFrame: public wxFrame
{
public:
wxFrameLayout* mpLayout;
wxTextCtrl* mpClientWnd;
wxPanel* mpInternalFrm;
wxTextCtrl* CreateTextCtrl( const wxString& value );
public:
MyFrame(wxFrame *frame);
virtual ~MyFrame();
bool OnClose(void) { Show(FALSE); return TRUE; }
void OnExit( wxCommandEvent& event );
DECLARE_EVENT_TABLE()
};
#define NEW_TEST_EXIT 1101
#endif

View File

@@ -1,2 +0,0 @@
#include "wx/msw/wx.rc"

View File

@@ -1,3 +0,0 @@
Linux
linux-gnu
linux

View File

@@ -1,238 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas (@Lithuania)
// Modified by:
// Created: 23/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "antiflickpl.h"
// #pragma interface
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "antiflickpl.h"
/***** Implementation for class cbAntiflickerPlugin *****/
IMPLEMENT_DYNAMIC_CLASS( cbAntiflickerPlugin, cbPluginBase )
BEGIN_EVENT_TABLE( cbAntiflickerPlugin, cbPluginBase )
EVT_PL_START_DRAW_IN_AREA ( cbAntiflickerPlugin::OnStartDrawInArea )
EVT_PL_FINISH_DRAW_IN_AREA ( cbAntiflickerPlugin::OnFinishDrawInArea )
END_EVENT_TABLE()
// initialization of static members
int cbAntiflickerPlugin::mRefCount = 0;
wxBitmap* cbAntiflickerPlugin::mpVertBuf = 0;
wxBitmap* cbAntiflickerPlugin::mpHorizBuf = 0;
wxMemoryDC* cbAntiflickerPlugin::mpVertBufDc = 0;
wxMemoryDC* cbAntiflickerPlugin::mpHorizBufDc = 0;
// constructors
cbAntiflickerPlugin::cbAntiflickerPlugin(void)
: mpLRUBufDc ( NULL ),
mLRUArea ( -1,-1, -1,-1 )
{
++mRefCount;
}
cbAntiflickerPlugin::cbAntiflickerPlugin( wxFrameLayout* pPanel, int paneMask )
: cbPluginBase( pPanel, paneMask ),
mpLRUBufDc ( NULL ),
mLRUArea ( -1,-1, -1,-1 )
{
++mRefCount;
}
cbAntiflickerPlugin::~cbAntiflickerPlugin()
{
if ( --mRefCount == 0 )
{
if ( mpHorizBuf )
{
mpHorizBufDc->SelectObject( wxNullBitmap );
delete mpHorizBuf;
delete mpHorizBufDc;
mpHorizBuf = 0;
mpHorizBufDc = 0;
}
if ( mpVertBuf )
{
mpVertBufDc->SelectObject( wxNullBitmap );
delete mpVertBuf;
delete mpVertBufDc;
mpVertBuf = 0;
mpVertBufDc = 0;
}
}
}
wxDC* cbAntiflickerPlugin::FindSuitableBuffer( const wxRect& forArea )
{
if ( mpVertBuf )
{
if ( mpVertBuf->GetHeight() >= forArea.height &&
mpVertBuf->GetWidth() >= forArea.width )
return mpVertBufDc;
}
else
if ( mpHorizBuf )
{
if ( mpHorizBuf->GetHeight() >= forArea.height &&
mpHorizBuf->GetWidth() >= forArea.width )
return mpHorizBufDc;
}
return 0;
}
wxDC* cbAntiflickerPlugin::AllocNewBuffer( const wxRect& forArea )
{
// TBD:: preallocate bit larger bitmap at once, to avoid
// excessive realocations later
// check whether the given area is oriented horizontally
// or verticallya and choose correspoinding bitmap to create or
// recreate
wxBitmap* pBuf = 0;
if ( forArea.height > forArea.width )
{
wxSize prevDim( 0,0 );
if ( mpVertBuf )
{
prevDim.x = mpVertBuf->GetWidth();
prevDim.y = mpVertBuf->GetHeight();
mpVertBufDc->SelectObject( wxNullBitmap );
delete mpVertBuf;
}
else
mpVertBufDc = new wxMemoryDC();
mpVertBuf = new wxBitmap( int( wxMax(forArea.width, prevDim.x ) ),
int( wxMax(forArea.height, prevDim.y ) )
);
mpVertBufDc->SelectObject( *mpVertBuf );
return mpVertBufDc;
}
else
{
wxSize prevDim( 0,0 );
if ( mpHorizBuf )
{
prevDim.x = mpHorizBuf->GetWidth();
prevDim.y = mpHorizBuf->GetHeight();
mpHorizBufDc->SelectObject( wxNullBitmap );
delete mpHorizBuf;
}
else
mpHorizBufDc = new wxMemoryDC();
mpHorizBuf = new wxBitmap( int( wxMax(forArea.width, prevDim.x ) ),
int( wxMax(forArea.height, prevDim.y ) )
);
mpHorizBufDc->SelectObject( *mpHorizBuf );
return mpHorizBufDc;
}
}
void cbAntiflickerPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent& event )
{
wxASSERT( mpLRUBufDc == NULL ); // DBG:: see comments in OnFinishDrawInArea(..) method
// short-cut
wxRect& area = event.mArea;
if ( event.mArea.width < 0 ||
event.mArea.height < 0 ) return;
// memorize given area
mLRUArea.x = area.x;
mLRUArea.y = area.y;
mLRUArea.width = area.width;
mLRUArea.height = area.height;
wxDC* pBufDc = FindSuitableBuffer( area );
if ( !pBufDc )
pBufDc = AllocNewBuffer( area );
pBufDc->SetDeviceOrigin( -area.x, -area.y );
pBufDc->SetClippingRegion( area.x, area.y,
area.width, area.height );
wxClientDC clntDc( &mpLayout->GetParentFrame() );
(*event.mppDc) = pBufDc;
mpLRUBufDc = pBufDc; // memorize buffer, which will be flushed to screen
// upon "commiting" the drawing
/*
// OLD STUFF::
mpLRUBufDc->Blit( pos.x, pos.y, size.x, size.y,
&clntDc, pos.x, pos.y, wxCOPY );
*/
}
void cbAntiflickerPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent& event )
{
wxRect& area = event.mArea;
if ( event.mArea.width < 0 ||
event.mArea.height < 0 ) return;
wxASSERT( mpLRUBufDc ); // DBG:: OnStartDrawInArea should be called first
// FOR NOW:: OnStartDrawInArea(..) should be immediatelly followed
// by OnFinishDrawInArea(..) for the same area
wxASSERT( mLRUArea.x == area.x );
wxASSERT( mLRUArea.y == area.y );
wxASSERT( mLRUArea.width == area.width );
wxASSERT( mLRUArea.height == area.height );
wxClientDC clntDc( &mpLayout->GetParentFrame() );
// "commit" drawings in one-shot
clntDc.Blit( area.x, area.y, area.width, area.height,
mpLRUBufDc, area.x, area.y, wxCOPY );
mpLRUBufDc->DestroyClippingRegion();
mpLRUBufDc = 0;
}

View File

@@ -1,59 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas (@Lithuania)
// Modified by:
// Created: 23/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __ANTIFLICKPL_G__
#define __ANTIFLICKPL_G__
#include "controlbar.h"
class cbAntiflickerPlugin : public cbPluginBase
{
DECLARE_DYNAMIC_CLASS( cbAntiflickerPlugin )
protected:
// double-buffers are shared "resource" among all instances of
// antiflicker plugin within the application
//
// TODO:: locking should be implemented, for multithreaded GUIs
static wxBitmap* mpVertBuf;
static wxBitmap* mpHorizBuf;
static wxMemoryDC* mpVertBufDc;
static wxMemoryDC* mpHorizBufDc;
static int mRefCount;
wxDC* mpLRUBufDc; // last-reacently-used buffer
wxRect mLRUArea; // last-reacently-used area
protected:
// returns NULL, if sutable buffer is not present
wxDC* FindSuitableBuffer( const wxRect& forArea );
wxDC* AllocNewBuffer( const wxRect& forArea );
wxDC& GetWindowDC();
wxDC& GetClientDC();
public:
cbAntiflickerPlugin(void);
cbAntiflickerPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
virtual ~cbAntiflickerPlugin();
// handlers for plugin events
void OnStartDrawInArea ( cbStartDrawInAreaEvent& event );
void OnFinishDrawInArea( cbFinishDrawInAreaEvent& event );
DECLARE_EVENT_TABLE()
};
#endif

View File

@@ -1,929 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 23/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "bardragpl.h"
// #pragma interface
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "bardragpl.h"
#define POS_UNDEFINED -32768
// helpers, FOR NOW:: static
static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
{
if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
return TRUE;
return FALSE;
}
static inline bool rect_contains_point( const wxRect& rect, int x, int y )
{
return ( x >= rect.x &&
y >= rect.y &&
x < rect.x + rect.width &&
y < rect.y + rect.height );
}
/***** Implementation for class cbBarDragPlugin *****/
IMPLEMENT_DYNAMIC_CLASS( cbBarDragPlugin, cbPluginBase )
BEGIN_EVENT_TABLE( cbBarDragPlugin, cbPluginBase )
//EVT_PL_LEFT_DOWN ( cbBarDragPlugin::OnLButtonDown )
EVT_PL_LEFT_UP ( cbBarDragPlugin::OnLButtonUp )
EVT_PL_MOTION ( cbBarDragPlugin::OnMouseMove )
EVT_PL_DRAW_HINT_RECT ( cbBarDragPlugin::OnDrawHintRect )
EVT_PL_START_BAR_DRAGGING ( cbBarDragPlugin::OnStartBarDragging )
EVT_PL_LEFT_DCLICK ( cbBarDragPlugin::OnLDblClick )
END_EVENT_TABLE()
cbBarDragPlugin::cbBarDragPlugin(void)
: mBarDragStarted ( FALSE ),
mCanStick ( TRUE ),
mpDraggedBar ( NULL ),
mInClientHintBorder( 4 ),
mpScrDc ( NULL ),
mpCurCursor ( NULL )
{}
cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask )
: cbPluginBase( pPanel, paneMask ),
mBarDragStarted ( FALSE ),
mCanStick ( TRUE ),
mpDraggedBar ( NULL ),
mInClientHintBorder( 4 ),
mpScrDc ( NULL ),
mpCurCursor ( NULL )
{}
cbBarDragPlugin::~cbBarDragPlugin()
{
// nothing
}
// helper methods (protected)
// clips (top/bottom) or (right/left) edges against the frame's bounding rect.
void do_clip_edges( int len, long& rectPos, long& rectLen )
{
if ( rectPos < 0 )
{
rectLen += rectPos;
rectPos = 0;
if ( rectLen < 0 ) rectLen = 1;
}
else
if ( rectPos > len-1 )
{
rectPos = len-1;
rectLen = 1;
}
else
if ( rectPos + rectLen - 1 > len )
rectLen -= (rectPos + rectLen) - len + 1;
}
void cbBarDragPlugin::ClipRectInFrame( wxRect& rect )
{
int w, h;
mpLayout->GetParentFrame().GetClientSize( &w, &h );
do_clip_edges( w, rect.x, rect.width );
do_clip_edges( h, rect.y, rect.height );
}
void cbBarDragPlugin::ClipPosInFrame( wxPoint& pos )
{
int w, h;
mpLayout->GetParentFrame().GetClientSize( &w, &h );
if ( pos.x < 0 ) pos.x = 0;
if ( pos.y < 0 ) pos.y = 0;
if ( pos.x > w ) pos.x = w-1;
if ( pos.y > h ) pos.y = h-1;
}
void cbBarDragPlugin::AdjustHintRect( wxPoint& mousePos )
{
mHintRect.x = mousePos.x - mMouseInRectX;
mHintRect.y = mousePos.y - mMouseInRectY;
}
cbDockPane* cbBarDragPlugin::HitTestPanes( wxRect& rect )
{
//wxRect clipped = rect;
//ClipRectInFrame( clipped );
cbDockPane** pPanes = mpLayout->GetPanesArray();
for( int i = 0; i != MAX_PANES; ++i )
if ( rect_hits_rect( pPanes[i]->mBoundsInParent, rect ) )
return pPanes[i];
return NULL;
}
cbDockPane* cbBarDragPlugin::HitTestPanes( wxPoint& pos )
{
wxPoint clipped = pos;
//ClipPosInFrame( pos );
cbDockPane** pPanes = mpLayout->GetPanesArray();
for( int i = 0; i != MAX_PANES; ++i )
if ( rect_contains_point( pPanes[i]->mBoundsInParent, clipped.x, clipped.y ) )
return pPanes[i];
return NULL;
}
bool cbBarDragPlugin::HitsPane( cbDockPane* pPane, wxRect& rect )
{
return rect_hits_rect( pPane->mBoundsInParent, rect );
}
int cbBarDragPlugin::GetDistanceToPane( cbDockPane* pPane, wxPoint& mousePos )
{
wxRect& bounds = pPane->mBoundsInParent;
switch( pPane->mAlignment )
{
case wxTOP : return mousePos.y - ( bounds.y + bounds.height );
case wxBOTTOM : return bounds.y - mousePos.y;
case wxLEFT : return mousePos.x - ( bounds.x + bounds.width );
case wxRIGHT : return bounds.x - mousePos.x;
default : return 0; // never reached
}
return 0;
}
bool cbBarDragPlugin::IsInOtherPane( wxPoint& mousePos )
{
cbDockPane* pPane = HitTestPanes( mousePos );
if ( pPane && pPane != mpCurPane ) return TRUE;
else return FALSE;
}
bool cbBarDragPlugin::IsInClientArea( wxPoint& mousePos )
{
return ( HitTestPanes( mousePos ) == NULL );
}
bool cbBarDragPlugin::IsInClientArea( wxRect& rect )
{
return ( HitTestPanes( rect ) == NULL );
}
void cbBarDragPlugin::CalcOnScreenDims( wxRect& rect )
{
if ( !mpCurPane || mpDraggedBar->IsFixed() ) return;
wxRect inPane = rect;
mpCurPane->FrameToPane( &inPane );
int rowNo = mpCurPane->GetRowAt( inPane.y, inPane.y + inPane.height );
bool isMaximized = ( rowNo >= (int)mpCurPane->GetRowList().Count() || rowNo < 0 );
if ( isMaximized )
{
inPane.x = 0;
inPane.width = mpCurPane->mPaneWidth;
mpCurPane->PaneToFrame( &inPane );
rect = inPane;
}
}
// helpers
static inline void check_upper_overrun( long& pos, int width, int mousePos )
{
if ( mousePos >= pos + width )
pos = mousePos - width/2;
}
static inline void check_lower_overrun( long& pos, int width, int mousePos )
{
if ( mousePos <= pos )
pos = mousePos - width/2;
}
void cbBarDragPlugin::StickToPane( cbDockPane* pPane, wxPoint& mousePos )
{
int wInPane = GetBarWidthInPane ( pPane );
int hInPane = GetBarHeightInPane( pPane );
// adjsut hint-rect horizontally (in pane's orientation)
if ( pPane->IsHorizontal() )
{
mHintRect.width = wInPane;
mHintRect.height = hInPane;
}
else
{
mHintRect.height = wInPane;
mHintRect.width = hInPane;
}
// adjsut hint-rect vertically (in pane's orientation)
wxRect& bounds = pPane->mBoundsInParent;
// TRUE, if hint enters the pane through it's lower edge
bool fromLowerEdge = ( pPane->IsHorizontal() )
? mousePos.y > bounds.y
: mousePos.x > bounds.x;
// NOTE:: about all the below min/max things: they are ment to ensure
// that mouse pointer doesn't overrun (leave) the hint-rectangle
// when dimensions it's are recalculated upon sticking it to the pane
if ( pPane->IsHorizontal() && fromLowerEdge )
{
int paneBottomEdgeY = bounds.y + bounds.height;
mHintRect.y = wxMin( paneBottomEdgeY, mousePos.y );
check_lower_overrun( mHintRect.y, hInPane, mousePos.y );
}
else
if ( pPane->IsHorizontal() && !fromLowerEdge )
{
int paneTopEdgeY = bounds.y;
mHintRect.y = wxMax( paneTopEdgeY - hInPane, mousePos.y - hInPane );
check_upper_overrun( mHintRect.y, hInPane, mousePos.y );
}
else
if ( !pPane->IsHorizontal() && fromLowerEdge )
{
int paneRightEdgeX = bounds.x + bounds.width;
mHintRect.x = wxMin( paneRightEdgeX, mousePos.x );
check_lower_overrun( mHintRect.x, hInPane, mousePos.x );
}
else
if ( !pPane->IsHorizontal() && !fromLowerEdge )
{
int paneLeftEdgeX = bounds.x;
mHintRect.x = wxMax( paneLeftEdgeX - hInPane, mousePos.x - hInPane );
check_upper_overrun( mHintRect.x, hInPane, mousePos.x );
}
mMouseInRectX = mousePos.x - mHintRect.x;
mMouseInRectY = mousePos.y - mHintRect.y;
mpCurPane = pPane; // memorize pane to which the hint is currently sticked
}
void cbBarDragPlugin::UnstickFromPane( cbDockPane* pPane, wxPoint& mousePos )
{
// unsticking causes rectangle to get the shape, in which
// dragged control-bar would be when floated
int newWidth = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].x;
int newHeight = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].y;
wxRect& flBounds = mpDraggedBar->mDimInfo.mBounds[wxCBAR_FLOATING];
if ( flBounds.width != -1 )
{
newWidth = flBounds.width;
newHeight = flBounds.height;
}
mHintRect.width = newWidth;
mHintRect.height = newHeight;
wxRect& bounds = pPane->mBoundsInParent;
// TRUE, if hint leaves the pane through it's lower edge
bool fromLowerEdge = ( pPane->IsHorizontal() )
? mousePos.y > bounds.y
: mousePos.x > bounds.x;
// NOTE:: ...all the below min/max things - see comments about it in StickToPane(..)
if ( pPane->IsHorizontal() && fromLowerEdge )
{
bool fromLowerEdge = mousePos.y > bounds.y;
mHintRect.y = wxMax( bounds.y + bounds.height + 1, mousePos.y - newHeight );
check_upper_overrun( mHintRect.y, newHeight, mousePos.y );
// this is how MFC's hint behaves:
if ( mMouseInRectX > newWidth )
mHintRect.x = mousePos.x - ( newWidth / 2 );
}
else
if ( pPane->IsHorizontal() && !fromLowerEdge )
{
mHintRect.y = wxMin( bounds.y - newHeight - 1, mousePos.y );
// -/-
if ( mMouseInRectX > newWidth )
mHintRect.x = mousePos.x - ( newWidth / 2 );
check_lower_overrun( mHintRect.y, newHeight, mousePos.y );
}
else
if ( !pPane->IsHorizontal() && fromLowerEdge )
{
mHintRect.x = wxMax( bounds.x + bounds.width, mousePos.x - newWidth );
// -/-
if ( mMouseInRectY > newHeight )
mHintRect.y = mousePos.y - ( newHeight / 2 );
check_upper_overrun( mHintRect.x, newWidth, mousePos.x );
}
else
if ( !pPane->IsHorizontal() && !fromLowerEdge )
{
mHintRect.x = wxMin( bounds.x - newWidth - 1, mousePos.x );
// -/-
if ( mMouseInRectY > newHeight )
mHintRect.y = mousePos.y - ( newHeight / 2 );
check_lower_overrun( mHintRect.x, newWidth, mousePos.x );
}
mMouseInRectX = mousePos.x - mHintRect.x;
mMouseInRectY = mousePos.y - mHintRect.y;
mpCurPane = NULL;
}
int cbBarDragPlugin::GetBarWidthInPane( cbDockPane* pPane )
{
if ( pPane == mpSrcPane )
return mBarWidthInSrcPane;
// this is how MFC's bars behave:
if ( pPane->IsHorizontal() )
return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].x;
else
return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY ].x;
}
int cbBarDragPlugin::GetBarHeightInPane( cbDockPane* pPane )
{
if ( pPane->IsHorizontal() )
return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].y;
else
return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY ].y;
}
void cbBarDragPlugin::ShowHint( bool prevWasInClient )
{
bool wasDocked = FALSE;
if ( mpDraggedBar->mState != wxCBAR_FLOATING && !mpCurPane )
{
mpLayout->SetBarState( mpDraggedBar, wxCBAR_FLOATING, TRUE );
}
else
if ( mpDraggedBar->mState == wxCBAR_FLOATING && mpCurPane )
{
mpLayout->SetBarState( mpDraggedBar, wxCBAR_DOCKED_HORIZONTALLY, FALSE );
wasDocked = TRUE;
}
if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE )
{
// do hevy calculations first
wxRect actualRect = mHintRect; // will be adjusted depending on drag-settings
if ( mpSrcPane->mProps.mExactDockPredictionOn && mpCurPane )
{
bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
wxASSERT( success ); // DBG::
actualRect = mpDraggedBar->mBounds;
mpCurPane->PaneToFrame( &actualRect );
}
else
CalcOnScreenDims( actualRect );
// release previouse hint
if ( mPrevHintRect.x != POS_UNDEFINED )
{
// erase previouse rectangle
cbDrawHintRectEvent evt( mPrevHintRect, prevWasInClient, TRUE, FALSE );
mpLayout->FirePluginEvent( evt );
}
// draw new hint
cbDrawHintRectEvent evt( actualRect, mpCurPane == NULL, FALSE, FALSE );
mpLayout->FirePluginEvent( evt );
mPrevHintRect = actualRect;
}
else
{
// otherwise, if real-time updates option is ON
if ( mpCurPane )
{
mpLayout->GetUpdatesManager().OnStartChanges();
if ( wasDocked )
mpDraggedBar->mUMgrData.SetDirty( TRUE );
bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
wxASSERT( success ); // DBG ::
mpLayout->GetUpdatesManager().OnFinishChanges();
mpLayout->GetUpdatesManager().UpdateNow();
}
else
{
if ( mpLayout->mFloatingOn )
{
// move the top-most floated bar around as user drags the hint
mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mHintRect;
mpLayout->ApplyBarProperties( mpDraggedBar );
}
}
}
}
/*** event handlers ***/
void cbBarDragPlugin::OnMouseMove( cbMotionEvent& event )
{
// calculate postion in frame's coordiantes
if ( !mBarDragStarted )
{
event.Skip(); // pass event to the next plugin
return;
}
wxPoint mousePos = event.mPos;
event.mpPane->PaneToFrame( &mousePos.x, &mousePos.y );
wxRect prevRect = mHintRect;
bool prevIsInClient = ( mpCurPane == 0 );
AdjustHintRect( mousePos );
// if the hint-rect is not "tempted" to any pane yet
if ( mpCurPane == NULL )
{
cbDockPane* pPane = HitTestPanes( mHintRect );
if ( !pPane )
// enable sticking again, if we've left the pane completely
mCanStick = TRUE;
if ( mCanStick && pPane &&
GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) )
StickToPane( pPane, mousePos );
else
if ( pPane && HitTestPanes( mousePos ) == pPane && 0 ) // FOR NOW:: disabled
StickToPane( pPane, mousePos );
}
else
{
// otherwise, when rect is now sticked to some of the panes
// check if it should still remain in this pane
mCanStick = TRUE;
bool mouseInOther = IsInOtherPane( mousePos );
if ( mouseInOther )
{
cbDockPane* pPane = HitTestPanes( mousePos );
StickToPane( pPane, mousePos );
}
else
{
if ( IsInClientArea( mousePos ) )
{
cbDockPane* pPane = HitTestPanes( mHintRect );
if ( pPane &&
pPane != mpCurPane &&
GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) )
StickToPane( pPane, mousePos );
else
if ( !pPane )
{
UnstickFromPane( mpCurPane, mousePos );
// FOR NOW:: disabled, would cause some mess
//mCanStick = FALSE; // prevents from sticking to this
// pane again, flag is reset when hint-rect
// leaves the pane completely
}
else
if ( GetDistanceToPane( pPane, mousePos ) > GetBarHeightInPane( pPane ) )
{
if ( !HitsPane( mpCurPane, mHintRect ) )
{
UnstickFromPane( mpCurPane, mousePos );
// FOR NOW:: disabled, would cause some mess
//mCanStick = FALSE; // prevents from sticking to this
// pane again, flag is reset when hint-rect
// leaves the pane completely
}
}
}
else
{
}
}
}
ShowHint( prevIsInClient );
wxCursor* pPrevCurs = mpCurCursor;
if ( mpCurPane )
mpCurCursor = mpLayout->mpDragCursor;
else
{
if ( mpLayout->mFloatingOn && mpSrcPane->mProps.mRealTimeUpdatesOn )
mpCurCursor = mpLayout->mpDragCursor;
else
mpCurCursor = mpLayout->mpNECursor;
}
if ( pPrevCurs != mpCurCursor )
mpLayout->GetParentFrame().SetCursor( *mpCurCursor );
}
void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent& event )
{
if ( mBarDragStarted )
{
wxMessageBox("DblClick!");
}
event.Skip();
}
void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent& event )
{
if ( mBarDragStarted )
{
if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE )
{
// erase current rectangle, and finsih on-screen drawing session
cbDrawHintRectEvent evt( mPrevHintRect, mpCurPane == NULL, TRUE, TRUE );
mpLayout->FirePluginEvent( evt );
if ( mpCurPane != NULL )
{
if ( mpSrcPane->mProps.mExactDockPredictionOn )
{
mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
mpLayout->GetUpdatesManager().OnFinishChanges();
mpLayout->GetUpdatesManager().UpdateNow();
}
else
mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane );
}
}
mHintRect.width = -1;
mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
mpLayout->ReleaseEventsFromPane( event.mpPane );
mpLayout->ReleaseEventsFromPlugin( this );
mBarDragStarted = FALSE;
if ( mBarWasFloating && mpDraggedBar->mState != wxCBAR_FLOATING )
{
// save bar's floating position before it was docked
mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mFloatedBarBounds;
}
}
else
event.Skip(); // pass event to the next plugin
}
void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent& event )
{
if ( 1 )
{
cbBarInfo* pHittedBar;
cbRowInfo* pRow;
if ( event.mpPane->HitTestPaneItems( event.mPos, // in pane's coordiantes
&pRow,
&pHittedBar ) == CB_BAR_CONTENT_HITTED
)
{
mpLayout->SetBarState( pHittedBar, wxCBAR_FLOATING, TRUE );
mpLayout->RepositionFloatedBar( pHittedBar );
return; // event is "eaten" by this plugin
}
mBarDragStarted = FALSE;
event.Skip();
}
//wxMessageBox("Hi, dblclick arrived!");
}
void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent& event )
{
mpDraggedBar = event.mpBar;
mpSrcPane = event.mpPane;
mpLayout->CaptureEventsForPane( event.mpPane );
mpLayout->CaptureEventsForPlugin( this );
mpLayout->GetParentFrame().SetCursor( *mpLayout->mpDragCursor );
mBarDragStarted = TRUE;
wxRect inParent = mpDraggedBar->mBounds;
mBarWasFloating = mpDraggedBar->mState == wxCBAR_FLOATING;
if ( mBarWasFloating )
{
inParent = mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ];
mFloatedBarBounds = inParent;
}
else
event.mpPane->PaneToFrame( &inParent );
mHintRect.x = POS_UNDEFINED;
mHintRect.width = inParent.width;
mHintRect.height = inParent.height;
mMouseInRectX = event.mPos.x - inParent.x;
mMouseInRectY = event.mPos.y - inParent.y;
mpSrcPane = event.mpPane;
if ( mpDraggedBar->mState == wxCBAR_FLOATING )
mpCurPane = NULL;
else
mpCurPane = event.mpPane;
mPrevHintRect.x = POS_UNDEFINED;
mCanStick = FALSE; // we're not stuck into any pane now -
// there's nowhere to "stick-twice"
mBarWidthInSrcPane = mpDraggedBar->mDimInfo.mSizes[ mpDraggedBar->mState ].x;
if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE &&
mpSrcPane->mProps.mExactDockPredictionOn )
mpLayout->GetUpdatesManager().OnStartChanges(); // capture initial state of layout
// simulate the first mouse movement
long x = event.mPos.x, y = event.mPos.y;
mpSrcPane->FrameToPane( &x, &y );
cbMotionEvent motionEvt( wxPoint(x,y), event.mpPane );
this->OnMouseMove( motionEvt );
return; // event is "eaten" by this plugin
}
/*** on-screen hint-tracking related methods ***/
void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent& event )
{
if ( !mpScrDc ) StartTracking();
DoDrawHintRect( event.mRect, event.mIsInClient );
if ( event.mLastTime )
FinishTracking();
}
#define _A 0xAA
#define _B 0x00
#define _C 0x55
#define _D 0x00
// FOR NOW:: static
static const unsigned char _gCheckerImg[16] = { _A,_B,_C,_D,
_A,_B,_C,_D,
_A,_B,_C,_D,
_A,_B,_C,_D
};
void cbBarDragPlugin::StartTracking()
{
mpScrDc = new wxScreenDC;
wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
}
void cbBarDragPlugin::DoDrawHintRect( wxRect& rect, bool isInClientRect)
{
wxRect scrRect;
RectToScr( rect, scrRect );
int prevLF = mpScrDc->GetLogicalFunction();
mpScrDc->SetLogicalFunction( wxXOR );
if ( isInClientRect )
{
// BUG BUG BUG (wx):: somehow stippled brush works only
// when the bitmap created on stack, not
// as a member of the class
wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
wxBrush checkerBrush( checker );
mpScrDc->SetPen( mpLayout->mNullPen );
mpScrDc->SetBrush( checkerBrush );
int half = mInClientHintBorder / 2;
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y - half,
scrRect.width + 2*half, mInClientHintBorder );
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + scrRect.height - half,
scrRect.width + 2*half, mInClientHintBorder );
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + half - 1,
mInClientHintBorder, scrRect.height - 2*half + 2);
mpScrDc->DrawRectangle( scrRect.x + scrRect.width - half,
scrRect.y + half - 1,
mInClientHintBorder, scrRect.height - 2*half + 2);
mpScrDc->SetBrush( wxNullBrush );
}
else
{
mpScrDc->SetPen( mpLayout->mBlackPen );
mpScrDc->DrawLine( scrRect.x, scrRect.y,
scrRect.x + scrRect.width, scrRect.y );
mpScrDc->DrawLine( scrRect.x, scrRect.y + 1,
scrRect.x, scrRect.y + scrRect.height );
mpScrDc->DrawLine( scrRect.x+1, scrRect.y + scrRect.height,
scrRect.x + scrRect.width, scrRect.y + scrRect.height );
mpScrDc->DrawLine( scrRect.x + scrRect.width , scrRect.y,
scrRect.x + scrRect.width, scrRect.y + scrRect.height + 1);
}
mpScrDc->SetLogicalFunction( prevLF );
}
void cbBarDragPlugin::DrawHintRect ( wxRect& rect, bool isInClientRect)
{
DoDrawHintRect( rect, isInClientRect );
}
void cbBarDragPlugin::EraseHintRect( wxRect& rect, bool isInClientRect)
{
DoDrawHintRect( rect, isInClientRect );
}
void cbBarDragPlugin::FinishTracking()
{
wxScreenDC::EndDrawingOnTop();
delete mpScrDc;
mpScrDc = NULL;
}
void cbBarDragPlugin::RectToScr( wxRect& frameRect, wxRect& scrRect )
{
scrRect = frameRect;
int x = frameRect.x, y = frameRect.y;
mpLayout->GetParentFrame().ClientToScreen( &x, &y );
scrRect.x = x;
scrRect.y = y;
}

View File

@@ -1,117 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 23/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __BARDRAGPL_G__
#define __BARDRAGPL_G__
#include "controlbar.h"
#include "toolwnd.h"
class cbBarDragPlugin : public cbPluginBase
{
DECLARE_DYNAMIC_CLASS( cbBarDragPlugin )
protected:
// plugin is active only in bar-dragging state
bool mBarDragStarted;
bool mCanStick; // flag used to prevent "bouncing" of hint-rectangle
wxScreenDC* mpScrDc; // created while tracking hint-rect
wxCursor* mpCurCursor;
// rectnagle shows the position/dimensions of the bar,
// if it would be docked now
wxRect mPrevHintRect;
wxRect mHintRect;
int mMouseInRectX;
int mMouseInRectY;
cbDockPane* mpSrcPane; // pane, from which the bar was originally taken
int mBarWidthInSrcPane;
cbDockPane* mpCurPane;
cbBarInfo* mpDraggedBar; // bar, which is being dragged
bool mBarWasFloating;
wxRect mFloatedBarBounds;
public: /*** public properties ***/
int mInClientHintBorder; // when hint-rect moves within client window area,
// the thicker rectangle is drawn using hatched brush,
// the default border width for this rectangle is 8 pix.
protected:
void AdjustHintRect( wxPoint& mousePos );
void ClipRectInFrame( wxRect& rect );
void ClipPosInFrame( wxPoint& pos );
cbDockPane* HitTestPanes( wxRect& rect );
cbDockPane* HitTestPanes( wxPoint& pos );
bool HitsPane( cbDockPane* pPane, wxRect& rect );
void CalcOnScreenDims( wxRect& rect );
int GetDistanceToPane( cbDockPane* pPane, wxPoint& mousePos );
bool IsInOtherPane ( wxPoint& mousePos );
bool IsInClientArea( wxPoint& mousePos );
bool IsInClientArea( wxRect& rect );
void StickToPane( cbDockPane* pPane, wxPoint& mousePos );
void UnstickFromPane( cbDockPane* pPane, wxPoint& mousePos );
int GetBarWidthInPane( cbDockPane* pPane );
int GetBarHeightInPane( cbDockPane* pPane );
// on-screen hint-tracking related methods
void StartTracking();
void DrawHintRect ( wxRect& rect, bool isInClientRect);
void EraseHintRect( wxRect& rect, bool isInClientRect);
void FinishTracking();
void DoDrawHintRect( wxRect& rect, bool isInClientRect);
void RectToScr( wxRect& frameRect, wxRect& scrRect );
void ShowHint( bool prevWasInClient );
public:
cbBarDragPlugin(void);
cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
virtual ~cbBarDragPlugin();
// handlers for plugin events
void OnMouseMove( cbMotionEvent& event );
void OnLButtonUp( cbLeftUpEvent& event );
void OnLButtonDown( cbLeftDownEvent& event );
void OnLDblClick( cbLeftDClickEvent& event );
// handles event, which oriniates from itself
void OnDrawHintRect( cbDrawHintRectEvent& event );
void OnStartBarDragging( cbStartBarDraggingEvent& event );
DECLARE_EVENT_TABLE()
};
#endif

View File

@@ -1,535 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 30/11/98 (my 22th birthday :-)
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "rowlayoutpl.h"
// #pragma interface
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/utils.h"
#include "barhintspl.h"
// fixed settings
#define GROOVE_WIDTH 3 // left shade + middle line + right shade
#define GROOVE_TO_GROOVE_GAP 1
#define BOX_T_BOX_GAP 2
#define BOX_TO_GROOVE_GAP 3
#define BOXES_IN_HINT 2
#define CLOSE_BOX_IDX 0
#define COLLAPSE_BOX_IDX 1
// used interally
#define CLOSE_BOX_HITTED 1
#define COLLAPSE_BOX_HITTED 2
/***** Implementation fro class cbBarHintsPlugin *****/
IMPLEMENT_DYNAMIC_CLASS( cbBarHintsPlugin, cbPluginBase )
BEGIN_EVENT_TABLE( cbBarHintsPlugin, cbPluginBase )
EVT_PL_SIZE_BAR_WND ( cbBarHintsPlugin::OnSizeBarWindow )
EVT_PL_DRAW_BAR_DECOR( cbBarHintsPlugin::OnDrawBarDecorations )
EVT_PL_LEFT_DOWN( cbBarHintsPlugin::OnLeftDown )
EVT_PL_LEFT_UP ( cbBarHintsPlugin::OnLeftUp )
EVT_PL_MOTION ( cbBarHintsPlugin::OnMotion )
END_EVENT_TABLE()
cbBarHintsPlugin::cbBarHintsPlugin(void)
: mpPane( 0 ),
mCollapseBoxOn( TRUE ),
mCloseBoxOn ( TRUE ),
mBtnPressed ( FALSE ),
mGrooveCount ( 2 ),
mHintGap ( 4 ),
mXWeight ( 2 )
{}
cbBarHintsPlugin::cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask )
: cbPluginBase( pLayout, paneMask ),
mpPane( 0 ),
mCollapseBoxOn( TRUE ),
mCloseBoxOn ( TRUE ),
mBtnPressed ( FALSE ),
mGrooveCount ( 2 ),
mHintGap ( 5 ),
mXWeight ( 2 )
{}
void cbBarHintsPlugin::SetGrooveCount( int nGrooves )
{
mGrooveCount = nGrooves;
}
void cbBarHintsPlugin::CreateBoxes()
{
cbCloseBox* box1 = new cbCloseBox();
cbCollapseBox* box2 = new cbCollapseBox();
mBoxes[CLOSE_BOX_IDX] = box1;
mBoxes[COLLAPSE_BOX_IDX] = box2;
for( int i = 0; i != BOXES_IN_HINT; ++i )
{
mBoxes[i]->mpLayout = mpLayout;
mBoxes[i]->mpPlugin = this;
mBoxes[i]->mpWnd = NULL;
}
}
void cbBarHintsPlugin::Draw3DBox( wxDC& dc, const wxPoint& pos, bool pressed )
{
}
void cbBarHintsPlugin::DrawCloseBox( wxDC& dc, const wxPoint& pos, bool pressed )
{
}
void cbBarHintsPlugin::DrawCollapseBox( wxDC& dc, const wxPoint& pos,
bool atLeft, bool disabled, bool pressed )
{
}
void cbBarHintsPlugin::DrawGrooves( wxDC& dc, const wxPoint& pos, int length )
{
int ofs = 0;
for( int i = 0; i != mGrooveCount; ++i, ofs += ( GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP ) )
if ( mpPane->IsHorizontal() )
{
dc.SetPen( mpLayout->mLightPen );
dc.DrawLine( pos.x + ofs, pos.y, pos.x + ofs, pos.y + length - 1 );
dc.DrawPoint( pos.x + ofs + 1, pos.y );
dc.SetPen( mpLayout->mDarkPen );
dc.DrawLine( pos.x + ofs + 2, pos.y, pos.x + ofs + 2, pos.y + length );
dc.DrawPoint( pos.x + ofs + 1, pos.y + length - 1 );
dc.DrawPoint( pos.x + ofs, pos.y + length - 1 );
}
else
{
dc.SetPen( mpLayout->mLightPen );
dc.DrawLine( pos.x, pos.y + ofs, pos.x + length - 1, pos.y + ofs );
dc.DrawPoint( pos.x, pos.y + ofs + 1 );
dc.SetPen( mpLayout->mDarkPen );
dc.DrawLine( pos.x, pos.y + ofs + 2, pos.x + length, pos.y + ofs + 2 );
dc.DrawPoint( pos.x + length - 1, pos.y + ofs + 1 );
dc.DrawPoint( pos.x + length - 1, pos.y + ofs );
}
}
void cbBarHintsPlugin::ExcludeHints( wxRect& rect, cbBarInfo& info )
{
int boxHeight = BTN_BOX_HEIGHT;
// collapse and close box are not placed on fixed bars
if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) )
boxHeight = 0;
int height = wxMax( mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP)
- GROOVE_TO_GROOVE_GAP,
boxHeight
);
if ( mpPane->IsHorizontal() )
{
rect.x += ( mHintGap*2 + height );
rect.width -= (height + 2*mHintGap);
rect.x -= info.mDimInfo.mHorizGap + 2;
rect.width += info.mDimInfo.mHorizGap + 2;
}
else
{
rect.y += (mHintGap*2 + height);
rect.height -= (height + 2*mHintGap);
rect.y -= info.mDimInfo.mVertGap + 2;
rect.height += info.mDimInfo.mVertGap + 2;
}
}
void cbBarHintsPlugin::DoDrawHint( wxDC& dc, wxRect& rect,
int pos, int boxOfs, int grooveOfs,
bool isFixed )
{
if ( !isFixed )
{
if ( mpPane->IsHorizontal() )
{
if ( mCloseBoxOn )
mBoxes[CLOSE_BOX_IDX]->Draw( dc );
if ( mCollapseBoxOn )
mBoxes[COLLAPSE_BOX_IDX]->Draw( dc );
}
else
{
if ( mCloseBoxOn )
mBoxes[CLOSE_BOX_IDX]->Draw( dc );
if ( mCollapseBoxOn )
mBoxes[COLLAPSE_BOX_IDX]->Draw( dc );
}
}
if ( mpPane->IsHorizontal() )
DrawGrooves( dc, wxPoint( rect.x + mHintGap + grooveOfs, pos ),
rect.height - (pos - rect.y) - mHintGap );
else
DrawGrooves( dc, wxPoint( rect.x + mHintGap, rect.y + mHintGap + grooveOfs ),
(pos - rect.x) - mHintGap );
}
void cbBarHintsPlugin::GetHintsLayout( wxRect& rect, cbBarInfo& info,
int& boxOfs, int& grooveOfs, int& pos )
{
int boxHeight = BTN_BOX_HEIGHT;
int boxWidth = BTN_BOX_WIDTH + BOX_TO_GROOVE_GAP + BTN_BOX_WIDTH;
// collapse and close box are not placed on fixed bars
if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) )
{
boxHeight = 0;
boxWidth = 0;
}
else
if ( !mCloseBoxOn || !mCollapseBoxOn )
boxWidth = BTN_BOX_WIDTH;
int grooveHeight = mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP)
- GROOVE_TO_GROOVE_GAP;
int height = wxMax( grooveHeight, boxHeight );
// center boxs and groves with respect to each other
boxOfs = ( height - boxHeight ) / 2;
grooveOfs = ( height - grooveHeight ) / 2;
pos = ( mpPane->IsHorizontal() ) ? rect.y + mHintGap
: rect.x + rect.width - mHintGap;
// setup positions for boxes
if ( !info.IsFixed() )
{
// what direction "collapse-triangle" should look at?
bool& isAtLeft = ((cbCollapseBox*)(mBoxes[COLLAPSE_BOX_IDX]))->mIsAtLeft;
isAtLeft= info.mBounds.x <= mpPane->mPaneWidth - ( info.mBounds.x + info.mBounds.width );
if ( info.IsExpanded() )
{
isAtLeft = FALSE;
cbBarInfo* pCur = info.mpPrev;
while( pCur )
{
if ( !pCur->IsFixed() )
{
isAtLeft = TRUE; break;
}
pCur = pCur->mpPrev;
}
}
// collapse/expand works only when more not-fixed bars are present in the same row
mBoxes[COLLAPSE_BOX_IDX]->Enable( info.mpRow->mNotFixedBarsCnt > 1 );
for( int i = 0; i != BOXES_IN_HINT; ++i )
mBoxes[i]->mpPane = mpPane;
if ( mpPane->IsHorizontal() )
{
if ( mCloseBoxOn )
{
mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos );
pos += BTN_BOX_HEIGHT;
}
if ( mCollapseBoxOn )
{
if ( mCloseBoxOn ) pos += BOX_T_BOX_GAP;
mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos );
pos += BTN_BOX_HEIGHT;
pos += BOX_TO_GROOVE_GAP;
}
}
else
{
if ( mCloseBoxOn )
{
pos -= BTN_BOX_WIDTH;
mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( pos , rect.y + mHintGap + boxOfs );
}
if ( mCollapseBoxOn )
{
if ( mCloseBoxOn ) pos -= BOX_T_BOX_GAP;
pos -= BTN_BOX_WIDTH;
mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( pos, rect.y + mHintGap + boxOfs );
pos -= BOX_TO_GROOVE_GAP;
}
}
}
}
static inline bool is_in_box( const wxPoint& rectPos, const wxPoint& mousePos )
{
return ( mousePos.x >= rectPos.x &&
mousePos.y >= rectPos.y &&
mousePos.x < rectPos.x + BTN_BOX_WIDTH &&
mousePos.y < rectPos.y + BTN_BOX_HEIGHT );
}
int cbBarHintsPlugin::HitTestHints( cbBarInfo& info, const wxPoint& pos )
{
wxPoint inPane = pos;
mpPane->PaneToFrame( &inPane.x, &inPane.y );
wxRect& rect = info.mBoundsInParent;
if ( info.IsFixed() ) return FALSE;
int boxOfs, grooveOfs, coord;
GetHintsLayout( rect, info, boxOfs, grooveOfs, coord );
if ( mpPane->IsHorizontal() )
{
if ( mCloseBoxOn )
{
if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) )
return CLOSE_BOX_HITTED;
coord += BTN_BOX_HEIGHT;
}
if ( mCollapseBoxOn )
{
if ( mCloseBoxOn ) coord += BOX_T_BOX_GAP;
if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) )
return COLLAPSE_BOX_HITTED;
coord += BTN_BOX_HEIGHT;
}
}
else
{
if ( mCloseBoxOn )
{
coord -= BTN_BOX_WIDTH;
if ( is_in_box( wxPoint( coord , rect.y + mHintGap + boxOfs ), inPane ) )
return CLOSE_BOX_HITTED;
}
if ( mCollapseBoxOn )
{
if ( mCloseBoxOn ) coord -= BOX_T_BOX_GAP;
coord -= BTN_BOX_WIDTH;
if ( is_in_box( wxPoint( coord, rect.y + mHintGap + boxOfs ), inPane ) )
return COLLAPSE_BOX_HITTED;
}
}
return FALSE;
}
// handlers for plugin-events
void cbBarHintsPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event )
{
wxRect& rect = event.mBoundsInParent;
mpPane = event.mpPane;
ExcludeHints( rect, *event.mpBar );
event.Skip(); // pass event to the next plugin in the chain
}
void cbBarHintsPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent& event )
{
wxRect& rect = event.mBoundsInParent;
mpPane = event.mpPane;
int boxOfs, grooveOfs, pos;
GetHintsLayout( rect, *event.mpBar, boxOfs, grooveOfs, pos );
DoDrawHint( *event.mpDc, rect, pos, boxOfs, grooveOfs, event.mpBar->IsFixed() );
// let other plugins add on their decorations
event.Skip();
}
void cbBarHintsPlugin::OnLeftDown( cbLeftDownEvent& event )
{
mpPane = event.mpPane;
wxPoint inFrame = event.mPos;
mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
wxBarIterator iter( mpPane->GetRowList() );
mpClickedBar = NULL;
while ( iter.Next() )
{
cbBarInfo& bar = iter.BarInfo();
int boxOfs, grooveOfs, pos;
GetHintsLayout( bar.mBoundsInParent, bar, boxOfs, grooveOfs, pos );
if ( !bar.IsFixed() )
for( int i = 0; i != BOXES_IN_HINT; ++i )
{
mBoxes[i]->OnLeftDown( inFrame );
if ( mBoxes[i]->mPressed )
{
mBtnPressed = TRUE;
mpClickedBar = &bar;
return; // event handled
}
}
}
event.Skip();
}
void cbBarHintsPlugin::OnLeftUp( cbLeftUpEvent& event )
{
if ( mBtnPressed )
{
wxPoint inFrame = event.mPos;
mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
int boxOfs, grooveOfs, pos;
GetHintsLayout( mpClickedBar->mBoundsInParent, *mpClickedBar, boxOfs, grooveOfs, pos );
int result = HitTestHints( *mpClickedBar, event.mPos );
for( int i = 0; i != BOXES_IN_HINT; ++i )
{
mBoxes[i]->OnLeftUp( inFrame );
if ( mBoxes[i]->WasClicked() )
{
if ( i == 0 )
mpLayout->SetBarState( mpClickedBar, wxCBAR_HIDDEN, TRUE );
else
{
if ( mpClickedBar->IsExpanded() )
mpPane->ContractBar( mpClickedBar );
else
mpPane->ExpandBar( mpClickedBar );
}
}
}
mBtnPressed = FALSE;
return;
}
else
event.Skip();
}
void cbBarHintsPlugin::OnMotion( cbMotionEvent& event )
{
if ( mBtnPressed )
{
wxPoint inFrame = event.mPos;
mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
mpPane = event.mpPane;
for( int i = 0; i != BOXES_IN_HINT; ++i )
mBoxes[i]->OnMotion( inFrame );
}
else
event.Skip();
}
void cbBarHintsPlugin::OnInitPlugin()
{
cbPluginBase::OnInitPlugin();
cbDockPane** panes = mpLayout->GetPanesArray();
for( int i = 0; i != MAX_PANES; ++i )
if ( panes[i]->MatchesMask( mPaneMask ) )
{
panes[i]->mProps.mMinCBarDim.x = 25;
panes[i]->mProps.mMinCBarDim.y = 16;
}
CreateBoxes();
}

View File

@@ -1,89 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 30/11/98 (my 22th birthday :-)
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __DRAGHINTSPL_G__
#define __DRAGHINTSPL_G__
#include "controlbar.h"
#include "toolwnd.h"
/*
* Intercepts bar-decoration and sizing events, draws 3d-hints
* around fixed and flexible bars, similar to those in Microsoft DevStudio 6.x
*/
class cbBarHintsPlugin : public cbPluginBase
{
DECLARE_DYNAMIC_CLASS( cbBarHintsPlugin )
protected:
cbDockPane* mpPane; // is set up temorarely, while handling event
cbMiniButton* mBoxes[2];
bool mBtnPressed;
bool mClosePressed;
cbBarInfo* mpClickedBar;
bool mDepressed;
protected:
// drawing helpers
void Draw3DBox ( wxDC& dc, const wxPoint& pos, bool pressed );
void DrawCloseBox ( wxDC& dc, const wxPoint& pos, bool pressed );
void DrawCollapseBox( wxDC& dc, const wxPoint& pos,
bool atLeft, bool disabled, bool pressed );
void DrawGrooves ( wxDC& dc, const wxPoint& pos, int length );
void DoDrawHint( wxDC& dc, wxRect& rect, int pos, int boxOfs, int grooveOfs, bool isFixed );
void GetHintsLayout( wxRect& rect, cbBarInfo& info,
int& boxOfs, int& grooveOfs, int& pos );
int HitTestHints( cbBarInfo& info, const wxPoint& pos );
void ExcludeHints( wxRect& rect, cbBarInfo& info );
void CreateBoxes();
public:
/* public properties */
bool mCloseBoxOn; // default: ON
bool mCollapseBoxOn; // default: ON
int mGrooveCount; // default: 2 (two shaded bars)
int mHintGap; // default: 5 (pixels from above, below, right and left)
int mXWeight; // default: 2 (width in pixels of lines which used for drawing cross)
public:
cbBarHintsPlugin(void);
cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask = wxALL_PANES );
void SetGrooveCount( int nGrooves );
void OnInitPlugin();
// handlers of plugin-events
void OnSizeBarWindow( cbSizeBarWndEvent& event );
void OnDrawBarDecorations( cbDrawBarDecorEvent& event );
void OnLeftDown( cbLeftDownEvent& event );
void OnLeftUp ( cbLeftUpEvent& event );
void OnMotion ( cbMotionEvent& event );
DECLARE_EVENT_TABLE()
};
#endif

View File

@@ -1,203 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 06/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "cbcustom.h"
// #pragma interface
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "cbcustom.h"
// helper class to receive menu customization event
class cbContextMenuHandler : public wxEvtHandler
{
public:
cbSimpleCustomizationPlugin* mpBackRef;
public:
void OnMenuCommand( wxCommandEvent& evt );
void OnCommandEvents( wxCommandEvent& evt );
DECLARE_EVENT_TABLE();
};
// FIXME:: is this "safe" ?
#define CB_CUSTOMIZE_MENU_FIRST_ITEM_ID 17500
/***** Implementation for helper class cbContextMenuHandler *****/
BEGIN_EVENT_TABLE( cbContextMenuHandler, wxEvtHandler )
// FIXME:: what is the right range for these ids ? so that they
// would not collide with user commands?
EVT_COMMAND_RANGE( CB_CUSTOMIZE_MENU_FIRST_ITEM_ID,
CB_CUSTOMIZE_MENU_FIRST_ITEM_ID + 300,
wxEVT_COMMAND_MENU_SELECTED,
cbContextMenuHandler::OnCommandEvents )
END_EVENT_TABLE()
void cbContextMenuHandler::OnCommandEvents( wxCommandEvent& evt )
{
//wxMessageBox("Wowwwww, Yeah!");
mpBackRef->OnMenuItemSelected( evt );
}
/***** Implementation for class cbSimpleCustomizationPlugin *****/
IMPLEMENT_DYNAMIC_CLASS( cbSimpleCustomizationPlugin, cbPluginBase )
BEGIN_EVENT_TABLE( cbSimpleCustomizationPlugin, cbPluginBase )
EVT_PL_CUSTOMIZE_BAR ( cbSimpleCustomizationPlugin::OnCustomizeBar )
EVT_PL_CUSTOMIZE_LAYOUT( cbSimpleCustomizationPlugin::OnCustomizeLayout )
END_EVENT_TABLE()
cbSimpleCustomizationPlugin::cbSimpleCustomizationPlugin(void)
{}
cbSimpleCustomizationPlugin::cbSimpleCustomizationPlugin( wxFrameLayout* pPanel, int paneMask )
: cbPluginBase( pPanel, paneMask )
{}
void cbSimpleCustomizationPlugin::OnCustomizeBar( cbCustomizeBarEvent& event )
{
// ingnore bar customization, treat it
// as layout-customization...ugly, eh?
cbCustomizeLayoutEvent clEvt( event.mClickPos );
OnCustomizeLayout( clEvt );
}
void cbSimpleCustomizationPlugin::OnCustomizeLayout( cbCustomizeLayoutEvent& event )
{
wxString helpStr1 = "Select this item to show the corresponding control bar";
wxString helpStr2 = "Select this itme to hide the corresponding control bar";
int id = CB_CUSTOMIZE_MENU_FIRST_ITEM_ID;
wxMenu* pMenu = new wxMenu();
BarArrayT& bars = mpLayout->GetBars();
for( size_t i = 0; i != bars.GetCount(); ++i )
{
cbBarInfo& bar = *bars[i];
bool isHidden = ( bar.mState == wxCBAR_HIDDEN );
wxString* pHelpStr = ( isHidden ) ? &helpStr1 : &helpStr2;
pMenu->Append( id, bar.mName, *pHelpStr, TRUE );
pMenu->Check( id, (isHidden == FALSE) );
++id;
}
pMenu->AppendSeparator();
pMenu->Append( id, "Customize...", "Show layout customization dialog", FALSE );
mCustMenuItemId = id;
cbContextMenuHandler* pHandler = new cbContextMenuHandler();
pHandler->mpBackRef = this;
wxWindow* pFrm = &mpLayout->GetParentFrame();
// FOR NOW FOR NOW:: to work-around wxFrame's (MSW) nasty event-handling bugs!!!
wxWindow* pTmpWnd = new wxWindow( pFrm, -1, event.mClickPos, wxSize(0,0) );
pMenu->SetEventHandler( pHandler );
pTmpWnd->PopupMenu( pMenu, 0,0 );
pTmpWnd->Destroy();
delete pMenu;
delete pHandler;
// event is "eaten" by this plugin
}
void cbSimpleCustomizationPlugin::OnMenuItemSelected( wxCommandEvent& event )
{
if ( event.m_commandInt == mCustMenuItemId )
{
wxMessageBox("Customization dialog box is not supproted by this plugin yet");
return;
}
else
{
cbBarInfo* pBar = mpLayout->GetBars()[ event.m_commandInt -
CB_CUSTOMIZE_MENU_FIRST_ITEM_ID
];
wxASSERT( pBar ); // DBG::
// "inverse" bar-visibility of the selected bar
int newState = 0;
if ( pBar->mState == wxCBAR_HIDDEN )
{
if ( pBar->mAlignment == -1 )
{
pBar->mAlignment = 0; // just remove "-1" marking
newState = wxCBAR_FLOATING;
}
else
if ( pBar->mAlignment == wxTOP ||
pBar->mAlignment == wxBOTTOM )
newState = wxCBAR_DOCKED_HORIZONTALLY;
else
newState = wxCBAR_DOCKED_VERTICALLY;
}
else
{
newState = wxCBAR_HIDDEN;
if ( pBar->mState == wxCBAR_FLOATING )
pBar->mAlignment = -1;
}
mpLayout->SetBarState( pBar, newState, TRUE );
if ( newState == wxCBAR_FLOATING )
mpLayout->RepositionFloatedBar( pBar );
}
// menu-item-selected event is "eaten"
}

View File

@@ -1,46 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 28/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __CBCUSTOM_G__
#define __CBCUSTOM_G__
#ifdef __GNUG__
#pragma interface "cbcustom.h"
#endif
#include "controlbar.h"
class cbSimpleCustomizationPlugin : public cbPluginBase
{
public:
DECLARE_DYNAMIC_CLASS( cbSimpleCustomizationPlugin )
int mCustMenuItemId;
public:
cbSimpleCustomizationPlugin(void);
cbSimpleCustomizationPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
// plugin-event handlers
void OnCustomizeBar( cbCustomizeBarEvent& event );
void OnCustomizeLayout( cbCustomizeLayoutEvent& event );
// menu-event handler
void OnMenuItemSelected( wxCommandEvent& event );
DECLARE_EVENT_TABLE()
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,262 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 07/09/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __CONTROLAREA_G__
#define __CONTROLAREA_G__
#ifdef __GNUG__
#pragma interface "controlarea.h"
#endif
#include "wx/defs.h"
#include "wx/window.h"
#include "wx/string.h"
#define WXCONTROLAREA_VERSION 1.0
// layout types for title bars of the tabs
// (are selected up by evaluating the available free space )
class twTabInfo; // forward decl.
#define wxTITLE_IMG_AND_TEXT 0
#define wxTITLE_IMG_ONLY 1
#define wxTITLE_BORDER_ONLY 2
/*
* class manages and decorates contained "tab"-windows.
* Draws decorations similar to those in "Project Workplace"
* of Microsoft Developer Studio 4.xx
*/
class wxTabbedWindow : public wxPanel
{
DECLARE_DYNAMIC_CLASS( wxTabbedWindow )
public:
friend class wxTabbedWindowSerializer;
wxList mTabs;
int mActiveTab;
int mTitleHeight;
int mLayoutType;
void HideInactiveTabs( bool andRepaint );
// overrride,to provide different font for tab-labels
virtual wxFont GetLabelingFont();
// FOR NOW:: scrollbars are actually related to wxPaggedWindow
wxScrollBar* mpTabScroll;
wxScrollBar* mpHorizScroll;
wxScrollBar* mpVertScroll;
public:
// public properties (invoke ReclaclLayout(TRUE) to apply changes)
wxPen mWhitePen; // default: RGB(255,255,255)
wxPen mLightPen; // wxSYS_COLOUR_3DHIGHLIGHT
wxPen mGrayPen; // wxSYS_COLOUR_3DFACE
wxPen mDarkPen; // wxSYS_COLOUR_3DSHADOW
wxPen mBlackPen; // default: RGB( 0, 0, 0)
int mVertGap; // default: 3
int mHorizGap; // default: 5
int mTitleVertGap; // default: 3
int mTitleHorizGap; // default: 4
int mImageTextGap; // default: 2
int mFirstTitleGap; // default: 11
int mBorderOnlyWidth; // default: 8
// notifications (can be handled by derivatives)
virtual void OnTabAdded( twTabInfo* pInfo ) {}
virtual void SizeTabs(int x,int y, int width, int height, bool repant);
public:
wxTabbedWindow();
virtual ~wxTabbedWindow();
// tabs can be also added when the window is
// already displayed - "on the fly"
virtual void AddTab( wxWindow* pContent, // contained window
wxString tabText, // tab label
wxString imageFileName = "", // if "", only text label is displayed
long imageType = wxBITMAP_TYPE_BMP );
// NOTE:: if this AddTab(..) overload is called, the
// image bitmap will not be serialized (if performed),
// use the above method instead, so that images could
// be restored using the given file names
virtual void AddTab( wxWindow* pContent,
wxString tabText,
wxBitmap* pImage = NULL );
virtual void RemoveTab( int tabNo );
/* misc accessors */
virtual int GetTabCount();
virtual wxWindow* GetTab( int tabNo );
virtual wxWindow* GetActiveTab();
virtual void SetActiveTab( int tabNo );
void DrawShadedRect( int x, int y, int width, int height,
wxPen& upperPen, wxPen& lowerPen, wxDC& dc );
virtual void DrawDecorations( wxDC& dc );
// return -1, if non of the title bars was hitted,
// otherwise the index of the hitted tab title bar
virtual int HitTest( const wxPoint& pos );
// should be invoked to redisplay window with changed properties
virtual void RecalcLayout( bool andRepaint = TRUE );
// event handlers
void OnPaint( wxPaintEvent& event );
void OnSize ( wxSizeEvent& event );
void OnBkErase( wxEraseEvent& event );
void OnLButtonDown( wxMouseEvent& event );
DECLARE_EVENT_TABLE()
};
/*
* class manages and decorates contained "sheets" (or pages).
* Draws decorations similar to those in "Output window"
* of Microsoft Developer Studio 4.xx
*/
class wxPaggedWindow : public wxTabbedWindow
{
DECLARE_DYNAMIC_CLASS( wxPaggedWindow )
protected:
bool mScrollEventInProgress;
// drag&drop state variables
bool mIsDragged;
int mDagOrigin;
wxCursor mResizeCursor;
wxCursor mNormalCursor;
bool mCursorChanged;
int mOriginalTitleRowLen;
void DrawPaperBar( twTabInfo& tab, int x, int y,
wxBrush& brush, wxPen& pen, wxDC& dc );
int GetWholeTabRowLen();
// adjusts scorllbars to fit around tabs
virtual void OnTabAdded( twTabInfo* pInfo );
// sets smaller font for page-labels
virtual wxFont GetLabelingFont();
public:
int mTitleRowStart;
int mResizeNailGap;
int mTabTrianGap;
int mTitleRowLen; // actual title row length
int mAdjustableTitleRowLen; // setup by dragging mini-sash
// with the mosue pointer
int mCurentRowOfs;
wxBrush mGrayBrush;
wxBrush mWhiteBrush;
public:
wxPaggedWindow();
~wxPaggedWindow();
// NOTE:: use public methods of the base class
// to add "pages" to this window
/* misc accessors */
// below two methods should be called after
// the tabs were added (AddTab(..)). Set up
// these scrollbars to match the needs of the
// tabs added into this area
wxScrollBar& GetVerticalScrollBar();
wxScrollBar& GetHorizontalScrollBar();
virtual void DrawDecorations( wxDC& dc );
// return -1, if non of the title bars was hitted,
// otherwise the index of the hitted tab title bar
virtual int HitTest( const wxPoint& pos );
virtual void RecalcLayout( bool andRepaint = TRUE );
// event handlers
void OnPaint( wxPaintEvent& event );
void OnSize ( wxSizeEvent& event );
void OnLButtonDown( wxMouseEvent& event );
void OnLButtonUp ( wxMouseEvent& event );
void OnMouseMove ( wxMouseEvent& event );
void OnScroll ( wxScrollEvent& event );
DECLARE_EVENT_TABLE()
};
// helper structure of wxTabbedWindow
class twTabInfo : public wxObject
{
DECLARE_DYNAMIC_CLASS( twTabInfo )
public:
twTabInfo();
~twTabInfo();
int ImgWidth();
int ImgHeight();
int ImageToTxtGap( int prefGap );
bool HasImg();
wxBitmap& GetImg();
bool HasText();
wxString& GetText();
wxWindow& GetContent();
public:
wxWindow* mpContent;
wxBitmap mBitMap;
wxString mText;
wxSize mDims;
// used for serialization
wxString mImageFile;
long mImageType;
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 23/01/99
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __DYNBARHND_G__
#define __DYNBARHND_G__
#include "controlbar.h"
#include "
#endif

View File

@@ -1,454 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: ??/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "dyntbar.cpp"
#pragma interface "dyntbar.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
/*
#ifdef __BORLANDC__
#pragma hdrstop
#endif
*/
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/utils.h" // import wxMin,wxMax macros
#include "dyntbar.h"
#include "newbmpbtn.h"
IMPLEMENT_DYNAMIC_CLASS(wxDynamicToolBar, wxToolBarBase)
BEGIN_EVENT_TABLE( wxDynamicToolBar, wxToolBarBase )
EVT_SIZE ( wxDynamicToolBar::OnSize )
EVT_PAINT( wxDynamicToolBar::OnPaint )
//EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground )
END_EVENT_TABLE()
/***** Implementation for class wxDynToolInfo *****/
IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo, wxToolLayoutItem)
/***** Implementation for class wxDynamicToolBar *****/
wxDynamicToolBar::wxDynamicToolBar()
: mpLayoutMan( NULL ),
mSepartorSize( 8 ),
mVertGap ( 0 ),
mHorizGap( 0 )
{
}
wxDynamicToolBar::wxDynamicToolBar(wxWindow *parent, const wxWindowID id,
const wxPoint& pos, const wxSize& size,
const long style, const int orientation,
const int RowsOrColumns, const wxString& name )
: mpLayoutMan( NULL ),
mSepartorSize( 8 ),
mVertGap ( 0 ),
mHorizGap( 0 )
{
Create(parent, id, pos, size, style, orientation, RowsOrColumns, name);
SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE) );
}
bool wxDynamicToolBar::Create(wxWindow *parent, const wxWindowID id,
const wxPoint& pos,
const wxSize& size,
const long style,
const int orientation, const int RowsOrColumns,
const wxString& name)
{
// cut&pasted from wxtbatsmpl.h
if ( ! wxWindow::Create(parent, id, pos, size, style, name) )
return FALSE;
SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ));
return TRUE;
}
bool wxDynamicToolBar::Realize(void)
{
// FOR NOW:: nothing
return TRUE;
}
wxDynamicToolBar::~wxDynamicToolBar(void)
{
if ( mpLayoutMan ) delete mpLayoutMan;
for( size_t i = 0; i != mTools.Count(); ++i )
delete mTools[i];
}
void wxDynamicToolBar::AddTool( int toolIndex,
wxWindow* pToolWindow,
const wxSize& size
)
{
wxDynToolInfo* pInfo = new wxDynToolInfo();
pInfo->mpToolWnd = pToolWindow;
pInfo->mIndex = toolIndex;
pInfo->mIsSeparator = FALSE;
int x,y;
pToolWindow->GetSize( &x, &y );
pInfo->mRealSize.x = x;
pInfo->mRealSize.y = y;
pInfo->mRect.width = x;
pInfo->mRect.height = y;
mTools.Add( pInfo );
}
void wxDynamicToolBar::AddTool( int toolIndex,
const wxString& imageFileName,
int imageFileType,
const wxString& labelText, bool alignTextRight,
bool isFlat )
{
wxNewBitmapButton* pBtn =
new wxNewBitmapButton( imageFileName, imageFileType,
labelText,
( alignTextRight )
? NB_ALIGN_TEXT_RIGHT
: NB_ALIGN_TEXT_BOTTOM,
isFlat
);
pBtn->Create( this, toolIndex );
pBtn->Reshape();
AddTool( toolIndex, pBtn );
}
void wxDynamicToolBar::AddTool( int toolIndex, wxBitmap labelBmp,
const wxString& labelText, bool alignTextRight,
bool isFlat )
{
wxNewBitmapButton* pBtn =
new wxNewBitmapButton( labelBmp,
labelText,
( alignTextRight )
? NB_ALIGN_TEXT_RIGHT
: NB_ALIGN_TEXT_BOTTOM,
isFlat
);
pBtn->Create( this, toolIndex );
pBtn->Reshape();
AddTool( toolIndex, pBtn );
}
wxToolBarTool*
wxDynamicToolBar::AddTool(const int toolIndex, const wxBitmap& bitmap,
const wxBitmap& pushedBitmap,
const bool toggle, const long xPos,
const long yPos, wxObject *clientData,
const wxString& helpString1, const wxString& helpString2)
{
wxNewBitmapButton* pBmpBtn = new wxNewBitmapButton( bitmap );
pBmpBtn->Create( this, toolIndex );
pBmpBtn->Reshape();
AddTool( toolIndex, pBmpBtn );
return NULL;
}
wxDynToolInfo* wxDynamicToolBar::GetToolInfo( int toolIndex )
{
for( size_t i = 0; i != mTools.Count(); ++i )
if ( mTools[i]->mIndex == toolIndex ) return mTools[i];
return NULL;
}
void wxDynamicToolBar::RemveTool( int toolIndex )
{
for( size_t i = 0; i != mTools.Count(); ++i )
if ( mTools[i]->mIndex == toolIndex )
{
if ( mTools[i]->mpToolWnd )
mTools[i]->mpToolWnd->Destroy();
mTools.Remove( i );
Layout();
return;
}
// TODO:: if not found, should it be an assertion?
}
void wxDynamicToolBar::AddSeparator( wxWindow* pSepartorWnd )
{
wxDynToolInfo* pInfo = new wxDynToolInfo();
pInfo->mpToolWnd = pSepartorWnd;
pInfo->mIndex = -1;
pInfo->mIsSeparator = TRUE;
if ( pSepartorWnd )
{
pSepartorWnd->Create( this, -1 );
int x,y;
pSepartorWnd->GetSize( &x, &y );
pInfo->mRealSize.x = x;
pInfo->mRealSize.y = y;
pInfo->mRect.width = x;
pInfo->mRect.height = y;
}
else
{
pInfo->mRealSize.x = mSepartorSize;
pInfo->mRealSize.y = 0;
pInfo->mRect.width = mSepartorSize;
pInfo->mRect.height = 0;
}
mTools.Add( pInfo );
}
void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& event )
{
// FOR NOW:: nothing
}
void wxDynamicToolBar::OnSize( wxSizeEvent& event )
{
//SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ) );
Layout();
}
void wxDynamicToolBar::DrawSeparator( wxDynToolInfo& info, wxDC& dc )
{
// check the orientation of separator
if ( info.mRect.width < info.mRect.height )
{
int midX = info.mRect.x + info.mRect.width/2 - 1;
dc.SetPen( *wxGREY_PEN );
dc.DrawLine( midX, info.mRect.y,
midX, info.mRect.y + info.mRect.height+1 );
dc.SetPen( *wxWHITE_PEN );
dc.DrawLine( midX+1, info.mRect.y,
midX+1, info.mRect.y + info.mRect.height+1 );
}
else
{
int midY = info.mRect.y + info.mRect.height/2 - 1;
dc.SetPen( *wxGREY_PEN );
dc.DrawLine( info.mRect.x, midY,
info.mRect.x + info.mRect.width+1, midY );
dc.SetPen( *wxWHITE_PEN );
dc.DrawLine( info.mRect.x, midY + 1,
info.mRect.x + info.mRect.width+1, midY + 1 );
}
}
void wxDynamicToolBar::OnPaint( wxPaintEvent& event )
{
// draw separators if any
wxPaintDC dc(this);
for( size_t i = 0; i != mTools.Count(); ++i )
if ( mTools[i]->mIsSeparator )
{
// check if separator doesn't have it's own window
// if so, then draw it using built-in drawing method
if ( !mTools[i]->mpToolWnd )
DrawSeparator( *mTools[i], dc );
}
}
// FOR NOW:: quick fix
#include "wx/choice.h"
void wxDynamicToolBar::SizeToolWindows()
{
for( size_t i = 0; i != mTools.Count(); ++i )
{
wxDynToolInfo& info = *mTools[i];
if ( !info.mIsSeparator )
{
// center real rectangle within the rectangle
// provided by the layout manager
int x = info.mRect.x;
int y = info.mRect.y + (info.mRect.height - info.mRealSize.y)/2;
// FOR NOW FOR NOW:: quick & dirty fix
if ( info.mpToolWnd->IsKindOf( CLASSINFO( wxChoice ) ) )
{
info.mpToolWnd->SetSize( x,y,
info.mRealSize.x - 3,
info.mRealSize.y);
}
else
info.mpToolWnd->SetSize( x,y,
info.mRealSize.x,
info.mRealSize.y );
}
// TBD:: size separator window if present
}
}
bool wxDynamicToolBar::Layout()
{
if ( !mpLayoutMan ) mpLayoutMan = CreateDefaulLayout();
int x,y;
GetSize( &x, &y );
wxSize wndDim(x,y);
wxSize result;
wxLayoutItemArrayT items;
// safe conversion
for( size_t i = 0; i != mTools.Count(); ++i ) items.Add( mTools[i] );
mpLayoutMan->Layout( wndDim, result, items, mVertGap, mHorizGap );;
SizeToolWindows();
return TRUE;
}
void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim )
{
if ( !mpLayoutMan ) mpLayoutMan = CreateDefaulLayout();
wxLayoutItemArrayT items;
// safe conversion
for( size_t i = 0; i != mTools.Count(); ++i ) items.Add( mTools[i] );
mpLayoutMan->Layout( givenDim, prefDim, items, mVertGap, mHorizGap );;
}
void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout )
{
if ( mpLayoutMan ) delete mpLayoutMan;
mpLayoutMan = pLayout;
Layout();
}
void wxDynamicToolBar::EnableTool(const int toolIndex, const bool enable )
{
wxDynToolInfo* pInfo = GetToolInfo( toolIndex );
if ( !pInfo ) return;
if ( pInfo->mIsSeparator || !pInfo->mpToolWnd ) return;
pInfo->mpToolWnd->Enable( enable );
}
/***** Implementation for class BagLayout *****/
void BagLayout::Layout( const wxSize& parentDim,
wxSize& resultingDim,
wxLayoutItemArrayT& items,
int horizGap,
int vertGap
)
{
int maxWidth = 0;
int curY = 0;
int nRows = 0;
size_t i = 0;
while( i < items.Count() )
{
int curX = 0;
int height = 0;
int nItems = 0;
int firstItem = i;
int itemsInRow = 0;
if ( nRows > 0 ) curY += vertGap;
// step #1 - arrange horizontal positions of items in the row
do
{
if ( itemsInRow > 0 ) curX += horizGap;
wxRect& r = items[i]->mRect;
if ( curX + r.width > parentDim.x )
if ( itemsInRow > 0 ) break;
r.x = curX;
r.y = curY;
curX += r.width;
height = wxMax( height, r.height );
++itemsInRow;
++i;
} while( i < items.Count() );
curY += height;
maxWidth = wxMax( maxWidth, curX );
}
resultingDim.x = maxWidth;
resultingDim.y = curY;
}

View File

@@ -1,167 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: ??/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __DYNTBAR_G__
#define __DYNTBAR_G__
#include "wx/tbarbase.h"
#include "wx/dynarray.h"
// layout item
class wxToolLayoutItem : public wxObject
{
public:
wxRect mRect;
bool mIsSeparator;
};
class wxDynToolInfo;
typedef wxToolLayoutItem* wxToolLayoutItemPtrT;
typedef wxDynToolInfo* wxDynToolInfoPtrT;
WX_DEFINE_ARRAY( wxToolLayoutItemPtrT, wxLayoutItemArrayT );
WX_DEFINE_ARRAY( wxDynToolInfoPtrT, wxDynToolInfoArrayT );
// base class for layouting algorithm implementations
class LayoutManagerBase
{
public:
virtual void Layout( const wxSize& parentDim,
wxSize& resultingDim,
wxLayoutItemArrayT& items,
int horizGap,
int vertGap ) = 0;
virtual ~LayoutManagerBase() {}
};
// layouts items in left-to-right order from
// top towards bottom
class BagLayout : public LayoutManagerBase
{
public:
virtual void Layout( const wxSize& parentDim,
wxSize& resultingDim,
wxLayoutItemArrayT& items,
int horizGap,
int vertGap );
};
class wxDynToolInfo : public wxToolLayoutItem
{
DECLARE_DYNAMIC_CLASS(wxDynToolInfo)
public:
wxWindow* mpToolWnd;
int mIndex;
wxSize mRealSize;
};
// layouting orientations for tools
#define LO_HORIZONTAL 0
#define LO_VERTICAL 1
#define LO_FIT_TO_WINDOW 2
// class manages containment and layouting of tool-windows
class wxDynamicToolBar : public wxToolBarBase
{
DECLARE_DYNAMIC_CLASS(wxDynamicToolBar)
protected:
friend class wxDynamicToolBarSerializer;
wxDynToolInfoArrayT mTools;
LayoutManagerBase* mpLayoutMan;
protected:
virtual void SizeToolWindows();
public: /* public properties */
int mSepartorSize; // default: 8
int mVertGap; // default: 0
int mHorizGap; // default: 0
public:
wxDynamicToolBar();
wxDynamicToolBar(wxWindow *parent, const wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
const long style = wxNO_BORDER, const int orientation = wxVERTICAL,
const int RowsOrColumns = 1, const wxString& name = wxToolBarNameStr);
~wxDynamicToolBar(void);
bool Create(wxWindow *parent, const wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
const long style = wxNO_BORDER, const int orientation = wxVERTICAL, const int RowsOrColumns = 1, const wxString& name = wxToolBarNameStr);
// overridables
virtual void AddTool( int toolIndex,
wxWindow* pToolWindow,
const wxSize& size = wxDefaultSize );
virtual void AddTool( int toolIndex,
const wxString& imageFileName,
int imageFileType = wxBITMAP_TYPE_BMP,
const wxString& labelText = "", bool alignTextRight = FALSE,
bool isFlat = TRUE );
virtual void AddTool( int toolIndex, wxBitmap labelBmp,
const wxString& labelText = "", bool alignTextRight = FALSE,
bool isFlat = TRUE );
// method from wxToolBarBase (for compatibility), only
// first two arguments are valid
virtual wxToolBarTool *AddTool(const int toolIndex, const wxBitmap& bitmap, const wxBitmap& pushedBitmap = wxNullBitmap,
const bool toggle = FALSE, const long xPos = -1, const long yPos = -1, wxObject *clientData = NULL,
const wxString& helpString1 = "", const wxString& helpString2 = "");
virtual void AddSeparator( wxWindow* pSepartorWnd = NULL );
wxDynToolInfo* GetToolInfo( int toolIndex );
void RemveTool( int toolIndex );
// the default implementation draws shaded line
virtual void DrawSeparator( wxDynToolInfo& info, wxDC& dc );
// see definitions of orientation types
virtual bool Layout();
virtual void GetPreferredDim( const wxSize& givenDim, wxSize& prefDim );
virtual LayoutManagerBase* CreateDefaulLayout() { return new BagLayout(); }
virtual void SetLayout( LayoutManagerBase* pLayout );
virtual void EnableTool(const int toolIndex, const bool enable = TRUE);
// event handlers
void OnSize( wxSizeEvent& event );
void OnPaint( wxPaintEvent& event );
void OnEraseBackground( wxEraseEvent& event );
// overriden from wxToolBarBase
virtual bool Realize(void);
DECLARE_EVENT_TABLE()
};
#endif

View File

@@ -1,50 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 23/01/99
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "dyntbar.cpp"
#pragma interface "dyntbar.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
/*
#ifdef __BORLANDC__
#pragma hdrstop
#endif
*/
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "dyntbarhnd.h"
/***** Implementation for class cbDynToolBarDimHandler *****/
IMPLEMENT_DYNAMIC_CLASS( cbDynToolBarDimHandler, cbBarDimHandlerBase )
void cbDynToolBarDimHandler::OnChangeBarState(cbBarInfo* pBar, int newState )
{
// nothing
}
void cbDynToolBarDimHandler::OnResizeBar( cbBarInfo* pBar,
const wxSize& given,
wxSize& preferred )
{
wxASSERT( pBar->mpBarWnd ); // DBG:: should be present
wxDynamicToolBar* pTBar = (wxDynamicToolBar*)pBar->mpBarWnd;
pTBar->GetPreferredDim( given, preferred );
}

View File

@@ -1,26 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 23/01/99
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __DYNTBARHND_G__
#define __DYNTBARHND_G__
#include "controlbar.h"
#include "dyntbar.h"
class cbDynToolBarDimHandler : public cbBarDimHandlerBase
{
DECLARE_DYNAMIC_CLASS( cbDynToolBarDimHandler )
public:
void OnChangeBarState(cbBarInfo* pBar, int newState );
void OnResizeBar( cbBarInfo* pBar, const wxSize& given, wxSize& preferred );
};
#endif

View File

@@ -1,449 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 02/01/99
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "frmview.h"
// #pragma interface
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "frmview.h"
#include "wx/utils.h"
/***** Implementation for class wxFrameView *****/
BEGIN_EVENT_TABLE( wxFrameView, wxEvtHandler )
EVT_IDLE( wxFrameView::OnIdle )
END_EVENT_TABLE()
void wxFrameView::OnIdle( wxIdleEvent& event)
{
event.Skip();
if ( mDoToolUpdates )
{
int o;
++o;
// TBD::
}
}
/*** public methods ***/
wxFrameView::wxFrameView()
: mpLayout( NULL ),
mpFrameMgr( NULL )
{}
wxFrameView::~wxFrameView()
{
if ( mpLayout ) delete mpLayout;
}
wxFrame* wxFrameView::GetParentFrame()
{
return mpFrameMgr->GetParentFrame();
}
wxWindow* wxFrameView::GetClientWindow()
{
return mpFrameMgr->GetClientWindow();
}
void wxFrameView::Activate()
{
mpFrameMgr->ActivateView( this );
}
void wxFrameView::Deactivate()
{
mpFrameMgr->DeactivateCurrentView();
}
void wxFrameView::CreateLayout()
{
mpLayout = new wxFrameLayout( GetParentFrame(), mpFrameMgr->GetClientWindow(), FALSE );
}
wxFrameLayout* wxFrameView::GetLayout()
{
return mpLayout;
}
void wxFrameView::SetToolUpdates( bool doToolUpdates )
{
mDoToolUpdates = doToolUpdates;
}
void wxFrameView::SetLayout( wxFrameLayout* pLayout )
{
if ( mpLayout ) delete mpLayout;
mpLayout = pLayout;
}
wxFrameManager& wxFrameView::GetFrameManager()
{
return *mpFrameMgr;
}
void wxFrameView::RegisterMenu( const wxString& topMenuName )
{
mTopMenus.Add( topMenuName );
}
#if 0
/***** Implementation for class wxFrameViewSerializer *****/
// NOTE:: currently "stipple" property of the brush is not serialized
class wxFrameViewSerializer : public wxEvtHandlerSerializer
{
DECLARE_SERIALIZER_CLASS( wxFrameViewSerializer );
static void Serialize( wxObject* pObj, wxObjectStorage& store );
};
IMPLEMENT_SERIALIZER_CLASS( wxFrameView,
wxFrameViewSerializer,
wxFrameViewSerializer::Serialize,
NO_CLASS_INIT )
void wxFrameViewSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
{
// wxFrameViewSerializer is a kind of wxEvtHandler - peform serialization of
// the base class first
info.SerializeInherited( pObj, store );
wxFrameView* pView = (wxFrameView*)pObj;
store.XchgObjPtr( (wxObject**) &pView->mpFrameMgr );
store.XchgObjPtr( (wxObject**) &pView->mpLayout );
store.XchgBool ( pView->mDoToolUpdates );
// serialize members in derived classes
pView->OnSerialize( store );
}
#endif
/***** Implementation for class wxFrameManager *****/
void wxFrameManager::DoSerialize( wxObjectStorage& store )
{
#if 0
store.AddInitialRef( mpFrameWnd );
store.AddInitialRef( this );
if ( mpClientWnd ) store.AddInitialRef( mpClientWnd );
store.XchgObj( (wxObject*) &mViews );
store.XchgInt( mActiveViewNo );
store.Finalize(); // finish serialization
#endif
}
void wxFrameManager::DestroyViews()
{
DeactivateCurrentView();
wxNode* pNode = mViews.First();
while( pNode )
{
delete (wxFrameView*)pNode->Data();
pNode = pNode->Next();
}
if ( mActiveViewNo != -1 && GetParentFrame() )
GetParentFrame()->SetNextHandler( NULL );
}
int wxFrameManager::GetViewNo( wxFrameView* pView )
{
wxNode* pNode = mViews.First();
int n = 0;
while( pNode )
{
if ( (wxFrameView*)pNode->Data() == pView )
return n;
++n;
pNode = pNode->Next();
}
return -1;
}
void wxFrameManager::EnableMenusForView( wxFrameView* pView, bool enable )
{
wxMenuBar* pMenuBar = GetParentFrame()->GetMenuBar();
int count = pMenuBar->GetMenuCount();
if ( !pMenuBar ) return;
wxStringListNode* pNode = pView->mTopMenus.GetFirst();
while( pNode )
{
for( int i = 0; i != count; ++i )
{
if ( pMenuBar->GetMenu(i)->GetTitle() == pNode->GetData() )
pMenuBar->EnableTop( i, enable );
}
pNode = pNode->GetNext();
}
}
void wxFrameManager::SyncAllMenus()
{
wxNode* pNode = mViews.First();
int i = 0;
while( pNode )
{
if ( i != mActiveViewNo )
EnableMenusForView( (wxFrameView*)pNode->GetData(), FALSE );
pNode = pNode->Next();
}
EnableMenusForView( GetView( mActiveViewNo ), TRUE );
}
/*** public methods ***/
wxFrameManager::wxFrameManager()
: mpFrameWnd( NULL ),
mActiveViewNo( -1 ),
mpClientWnd( NULL )
{
}
wxFrameManager::~wxFrameManager()
{
SaveViewsNow();
DestroyViews();
}
void wxFrameManager::Init( wxWindow* pMainFrame, const wxString& settingsFile )
{
mSettingsFile = settingsFile;
mpFrameWnd = pMainFrame;
wxNode* pNode = mViews.First();
while( pNode )
{
wxFrameView* pView = (wxFrameView*)pNode->Data();
pView->OnInit();
pView->OnInitMenus();
pNode = pNode->Next();
}
if ( !ReloadViews() )
{
// if loading of settings file failed (e.g. was not found),
// do recreation of items in each view
pNode = mViews.First();
while( pNode )
{
wxFrameView* pView = (wxFrameView*)pNode->Data();
pView->OnRecreate();
pNode = pNode->Next();
}
}
if ( mActiveViewNo >= mViews.Number() )
mActiveViewNo = -1;
ActivateView( GetView( ( mActiveViewNo == -1 ) ? 0 : mActiveViewNo ) );
SyncAllMenus();
}
void wxFrameManager::AddView( wxFrameView* pFrmView )
{
mViews.Append( pFrmView );
pFrmView->mpFrameMgr = this; // back ref.
}
void wxFrameManager::RemoveView( wxFrameView* pFrmView )
{
// TBD::
wxASSERT(0);
}
int wxFrameManager::GetActiveViewNo()
{
return mActiveViewNo;
}
wxFrameView* wxFrameManager::GetActiveView()
{
wxNode* pNode = mViews.Nth( mActiveViewNo );
if ( pNode ) return (wxFrameView*)pNode->Data();
else return NULL;
}
wxNode* wxFrameManager::GetActiveViewNode()
{
return mViews.Nth( mActiveViewNo );
}
wxFrame* wxFrameManager::GetParentFrame()
{
return ((wxFrame*)mpFrameWnd);
}
wxWindow* wxFrameManager::GetParentWindow()
{
return mpFrameWnd;
}
wxFrameView* wxFrameManager::GetView( int viewNo )
{
wxNode* pNode = mViews.Nth( viewNo );
if ( pNode ) return (wxFrameView*)pNode->Data();
else return NULL;
}
void wxFrameManager::ActivateView( int viewNo )
{
ActivateView( GetView( viewNo ) );
}
void wxFrameManager::ActivateView( wxFrameView* pFrmView )
{
DeactivateCurrentView();
mActiveViewNo = GetViewNo( pFrmView );
if ( pFrmView->mpLayout )
pFrmView->mpLayout->Activate();
// FIXME:: we would have used PushEventHandler(),
// but wxFrame bypasses attached handlers when
// handling wxCommand events!
GetParentFrame()->PushEventHandler( pFrmView );
EnableMenusForView( pFrmView, TRUE );
}
void wxFrameManager::SetClinetWindow( wxWindow* pFrameClient )
{
if ( mpClientWnd ) mpClientWnd->Destroy();
mpClientWnd = pFrameClient;
}
wxWindow* wxFrameManager::GetClientWindow()
{
if ( !mpClientWnd )
mpClientWnd = new wxWindow( GetParentFrame(), -1 );
return mpClientWnd;
}
void wxFrameManager::DeactivateCurrentView()
{
if ( mActiveViewNo == -1 ) return;
wxFrameView* pView = GetActiveView();
// FOR NOW::
wxASSERT( GetParentFrame()->GetEventHandler() == pView );
GetParentFrame()->PopEventHandler();
if ( pView->mpLayout )
pView->mpLayout->Deactivate();
EnableMenusForView( pView, FALSE );
}
void wxFrameManager::SaveViewsNow()
{
#if 0
if ( mSettingsFile == "" ) return;
wxIOStreamWrapper stm;
stm.CreateForOutput( mSettingsFile );
mStore.SetDataStream( stm );
DoSerialize( mStore );
#endif
}
bool wxFrameManager::ReloadViews()
{
return FALSE;
#if 0
if ( mSettingsFile == "" || !wxFileExists( mSettingsFile ) )
return FALSE;
DestroyViews();
wxIOStreamWrapper stm;
stm.CreateForInput( mSettingsFile );
mStore.SetDataStream( stm );
DoSerialize( mStore );
#endif
return TRUE;
}
bool wxFrameManager::ViewsAreLoaded()
{
return ( mViews.Number() != 0 );
}

View File

@@ -1,135 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 02/01/99
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __FRMVIEW_G__
#define __FRMVIEW_G__
#include "wx/module.h"
#if 0
#include "objstore.h"
#endif
class wxObjectStorage;
#include "controlbar.h"
class wxFrameManager;
class wxFrameView : public wxEvtHandler
{
protected:
wxStringList mTopMenus;
wxFrameLayout* mpLayout;
wxFrameManager* mpFrameMgr;
bool mDoToolUpdates;
friend class wxFrameManager;
friend class wxFrameViewSerializer;
protected:
void OnIdle( wxIdleEvent& event);
public:
wxFrameView();
~wxFrameView();
virtual void Activate();
virtual void Deactivate();
wxFrame* GetParentFrame();
wxWindow* GetClientWindow();
wxFrameManager& GetFrameManager();
void RegisterMenu( const wxString& topMenuName );
void CreateLayout();
wxFrameLayout* GetLayout();
void SetLayout( wxFrameLayout* pLayout );
void SetToolUpdates( bool doToolUpdates = TRUE );
// hooks for specific frame-views
virtual void OnInit() {}
virtual void OnSerialize( wxObjectStorage& store ) {}
virtual void OnActiveate() {}
virtual void OnDeactivate() {}
// imp. is mandatory
virtual void OnRecreate() {}
virtual void OnInitMenus() {}
DECLARE_EVENT_TABLE()
};
class wxFrame;
class wxFrameManager : wxObject
{
protected:
wxList mViews;
wxWindow* mpFrameWnd;
int mActiveViewNo;
wxWindow* mpClientWnd;
#if 0
wxObjectStorage mStore;
#endif
wxString mSettingsFile;
protected:
void DoSerialize( wxObjectStorage& store );
void DestroyViews();
int GetViewNo( wxFrameView* pView );
void EnableMenusForView( wxFrameView* pView, bool enable );
void SyncAllMenus();
public:
wxFrameManager();
~wxFrameManager();
// if file name is empty, views are are not saved/loaded
virtual void Init( wxWindow* pMainFrame, const wxString& settingsFile = "" );
// synonyms
wxFrame* GetParentFrame();
wxWindow* GetParentWindow();
int GetActiveViewNo();
wxFrameView* GetActiveView();
wxNode* GetActiveViewNode();
wxFrameView* GetView( int viewNo );
void SetClinetWindow( wxWindow* pFrameClient );
wxWindow* GetClientWindow();
void AddView( wxFrameView* pFrmView );
void RemoveView( wxFrameView* pFrmView );
void ActivateView( int viewNo );
void ActivateView( wxFrameView* pFrmView );
void DeactivateCurrentView();
wxObjectStorage& GetObjectStore();
void SaveViewsNow();
bool ReloadViews();
bool ViewsAreLoaded();
};
#endif

View File

@@ -1,224 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 18/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "garbagec.cpp"
#pragma interface "garbagec.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
/*
#ifdef __BORLANDC__
#pragma hdrstop
#endif
*/
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "garbagec.h"
/***** Implementation for class GarbageCollector *****/
inline static GCItem& node_to_item( wxNode* pNode )
{
return *( (GCItem*)(pNode->Data()) );
}
GarbageCollector::~GarbageCollector()
{
Reset();
}
/*** GC alg. helpers ***/
void GarbageCollector::DestroyItemList( wxList& lst )
{
wxNode* pNode = lst.First();
while( pNode )
{
delete &node_to_item( pNode );
pNode = pNode->Next();
}
lst.Clear();
}
wxNode* GarbageCollector::FindItemNode( void* pForObj )
{
wxNode* pNode = mAllNodes.First();
while( pNode )
{
if ( node_to_item( pNode ).mpObj == pForObj )
return pNode;
pNode = pNode->Next();
}
wxASSERT(0); // DBG:: item should be presnet
return 0;
}
wxNode* GarbageCollector::FindRefernceFreeItemNode()
{
wxNode* pNode = mAllNodes.First();
while( pNode )
{
if ( node_to_item( pNode ).mRefs.Number() == 0 )
return pNode;
pNode = pNode->Next();
}
return 0;
}
void GarbageCollector::RemoveReferencesToNode( wxNode* pItemNode )
{
wxNode* pNode = mAllNodes.First();
while( pNode )
{
wxList& refLst = node_to_item( pNode ).mRefs;
wxNode* pRefNode = refLst.First();
while( pRefNode )
{
if ( pRefNode->Data() == (wxObject*)pItemNode )
{
wxNode* pNext = pRefNode->Next();
refLst.DeleteNode( pRefNode );
pRefNode = pNext;
continue;
}
else pRefNode = pRefNode->Next();
}
pNode = pNode->Next();
}
}
void GarbageCollector::ResolveReferences()
{
wxNode* pNode = mAllNodes.First();
while( pNode )
{
GCItem& item = node_to_item( pNode );
wxNode* pRefNode = item.mRefs.First();
while( pRefNode )
{
pRefNode->SetData( (wxObject*) FindItemNode( (void*)pRefNode->Data() ) );
pRefNode = pRefNode->Next();
}
pNode = pNode->Next();
}
}
void GarbageCollector::AddObject( void* pObj, int refCnt )
{
// FOR NOW:: inital ref-count is not used
GCItem* pItem = new GCItem();
pItem->mpObj = pObj;
mAllNodes.Append( (wxObject*) pItem );
}
void GarbageCollector::AddDependency( void* pObj, void* pDepnedsOnObj )
{
node_to_item( FindItemNode( pObj ) ).mRefs.Append( (wxObject*)pDepnedsOnObj );
}
/*** GC alg. implementation ***/
void GarbageCollector::ArrangeCollection()
{
ResolveReferences();
do
{
// find node, which does not depend on anything
wxNode* pItemNode = FindRefernceFreeItemNode();
if ( pItemNode )
{
// append it to the list, where items are contained
// in the increasing order of dependencies
mRegularLst.Append( pItemNode->Data() );
mAllNodes.DeleteNode( pItemNode );
// remove references to this current "least-dependent" node
// from reference lists of all the other nodes
RemoveReferencesToNode( pItemNode );
}
else
{
// otherwise, what is left - all nodes, which
// are involved into cycled chains (rings)
wxNode* pNode = mAllNodes.First();
while( pNode )
{
mCycledLst.Append( pNode->Data() );
pNode = pNode->Next();
}
break;
}
// continue search for "least-dependent" nodes
} while(1);
}
wxList& GarbageCollector::GetRegularObjects()
{
return mRegularLst;
}
wxList& GarbageCollector::GetCycledObjects()
{
return mCycledLst;
}
void GarbageCollector::Reset()
{
DestroyItemList( mAllNodes );
mRegularLst.Clear();
mCycledLst.Clear();
}

View File

@@ -1,69 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas (@Lithuania)
// Modified by:
// Created: ??/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __GARBAGEC_G__
#define __GARBAGEC_G__
#include "wx/list.h"
struct GCItem
{
void* mpObj;
wxList mRefs; // references to other nodes
};
inline void* gc_node_to_obj( wxNode* pGCNode )
{
return ( (GCItem*) (pGCNode->Data()) )->mpObj;
}
// class implements extreamly slow, but probably one of the most simple GC alogrithms
class GarbageCollector
{
protected:
wxList mAllNodes;
wxList mRegularLst;
wxList mCycledLst;
wxNode* FindItemNode( void* pForObj );
void ResolveReferences();
wxNode* FindRefernceFreeItemNode();
void RemoveReferencesToNode( wxNode* pItemNode );
void DestroyItemList( wxList& lst );
public:
GarbageCollector() {}
virtual ~GarbageCollector();
// prepare data for GC alg.
virtual void AddObject( void* pObj, int refCnt = 1 );
virtual void AddDependency( void* pObj, void* pDepnedsOnObj );
// executes GC alg.
virtual void ArrangeCollection();
// acces results of the alg.
wxList& GetRegularObjects();
wxList& GetCycledObjects();
// removes all date form GC
void Reset();
};
#endif

View File

@@ -1,409 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 19/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "updatesmgr.h"
// #pragma interface
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "gcupdatesmgr.h"
// helper function
static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
{
if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
return 1;
return 0;
}
// helper structure
struct cbRectInfo
{
cbBarInfo* mpBar;
cbDockPane* mpPane;
wxRect* mpCurBounds;
wxRect* mpPrevBounds;
};
static inline cbRectInfo& node_to_rect_info( wxNode* pNode )
{
return *( (cbRectInfo*) (pNode->Data()) );
}
/***** Implementation for class cbSimpleUpdatesMgr *****/
IMPLEMENT_DYNAMIC_CLASS( cbGCUpdatesMgr, cbSimpleUpdatesMgr )
cbGCUpdatesMgr::cbGCUpdatesMgr( wxFrameLayout* pPanel )
: cbSimpleUpdatesMgr( pPanel )
{}
void cbGCUpdatesMgr::AddItem( wxList& itemList,
cbBarInfo* pBar,
cbDockPane* pPane,
wxRect& curBounds,
wxRect& prevBounds )
{
cbRectInfo* pInfo = new cbRectInfo();
pInfo->mpBar = pBar;
pInfo->mpPane = pPane;
pInfo->mpCurBounds = &curBounds;
pInfo->mpPrevBounds = &prevBounds;
itemList.Append( (wxObject*) pInfo );
}
void cbGCUpdatesMgr::OnStartChanges()
{
// memorize states of ALL items in the layout -
// this is quite excessive, but OK for the decent
// implementation of updates manager
mpLayout->GetPrevClientRect() = mpLayout->GetClientRect();
cbDockPane** panes = mpLayout->GetPanesArray();
for( int n = 0; n != MAX_PANES; ++n )
{
cbDockPane& pane = *(panes[n]);
// store pane state
pane.mUMgrData.StoreItemState( pane.mBoundsInParent );
pane.mUMgrData.SetDirty( FALSE );
cbRowInfo* pRow = pane.GetFirstRow();
while ( pRow )
{
cbBarInfo* pBar = pRow->GetFirstBar();
// store row state
pRow->mUMgrData.StoreItemState( pRow->mBoundsInParent );
pRow->mUMgrData.SetDirty( FALSE );
while( pBar )
{
// store bar state
pBar->mUMgrData.StoreItemState( pBar->mBoundsInParent );
pBar->mUMgrData.SetDirty( FALSE );
pBar = pBar->mpNext;
}
pRow = pRow->mpNext;
}
}
}
void cbGCUpdatesMgr::UpdateNow()
{
cbDockPane** panes = mpLayout->GetPanesArray();
wxRect& r1 = mpLayout->GetClientRect();
wxRect& r2 = mpLayout->GetPrevClientRect();
// detect changes in client window's area
bool clientWindowChanged = ( r1.x != r2.x ||
r1.y != r2.y ||
r1.width != r2.width ||
r1.height != r2.height );
// step #1 - detect changes in each row of each pane,
// and repaint decorations around changed windows
wxList mBarsToResize;
for( int n = 0; n != MAX_PANES; ++n )
{
cbDockPane& pane = *(panes[n]);
bool paneChanged = WasChanged( pane.mUMgrData, pane.mBoundsInParent );
if ( paneChanged )
{
wxClientDC dc( &mpLayout->GetParentFrame() );
pane.PaintPaneBackground( dc );
}
wxRect realBounds;
cbRowInfo* pRow = pane.GetFirstRow();
while ( pRow )
{
wxDC* pDc = 0;
cbBarInfo* pBar = pRow->GetFirstBar();
bool rowChanged = FALSE;
bool rowBkPainted = FALSE;
// FIXME:: the below should not be fixed
cbBarInfo* barsToRepaint[128];
// number of bars, that were changed in the current row
int nBars = 0;
wxRect r1 = pRow->mUMgrData.mPrevBounds;
wxRect r2 = pRow->mBoundsInParent;
if ( WasChanged( pRow->mUMgrData, pRow->mBoundsInParent ) )
rowChanged = TRUE;
else
while( pBar )
{
if ( WasChanged( pBar->mUMgrData, pBar->mBoundsInParent ) )
barsToRepaint[nBars++] = pBar;
pBar = pBar->mpNext;
}
if ( nBars || rowChanged )
{
realBounds = pRow->mBoundsInParent;
// include 1-pixel thick shades around the row
realBounds.x -= 1;
realBounds.y -= 1;
realBounds.width += 2;
realBounds.height += 2;
pDc = pane.StartDrawInArea( realBounds );
}
if ( rowChanged )
{
// postphone the resizement and refreshing the changed
// bar windows
cbBarInfo* pCurBar = pRow->GetFirstBar();
while( pCurBar )
{
if ( WasChanged( pCurBar->mUMgrData,
pCurBar->mBoundsInParent ) )
AddItem( mBarsToResize, pCurBar, &pane,
pCurBar->mBoundsInParent,
pCurBar->mUMgrData.mPrevBounds );
pCurBar = pCurBar->mpNext;
}
// draw only their decorations now
pane.PaintRow( pRow, *pDc );
}
else
if ( nBars != 0 )
{
for( int i = 0; i != nBars; ++i )
// postphone the resizement and refreshing the changed
// bar windows
AddItem( mBarsToResize,
barsToRepaint[i],
&pane,
barsToRepaint[i]->mBoundsInParent,
barsToRepaint[i]->mUMgrData.mPrevBounds );
// redraw decorations of entire row, regardless of how much
// of the bars were changed
pane.PaintRow( pRow, *pDc );
}
if ( pDc )
pane.FinishDrawInArea( realBounds );
pRow = pRow->mpNext;
} // end of while
if ( paneChanged )
{
wxClientDC dc( &mpLayout->GetParentFrame() );
pane.PaintPaneDecorations( dc );
}
} // end of for
if ( clientWindowChanged && !mpLayout->mClientWndRefreshPending )
{
// ptr to client-window object is "marked" as NULL
AddItem( mBarsToResize, NULL, NULL,
mpLayout->GetClientRect(),
mpLayout->GetPrevClientRect() );
}
// step #2 - do ordered refreshing and resizing of bar window objects now
DoRepositionItems( mBarsToResize );
}
void cbGCUpdatesMgr::DoRepositionItems( wxList& items )
{
wxNode* pNode1 = items.First();
while( pNode1 )
{
cbRectInfo& info = node_to_rect_info( pNode1 );
wxNode* pNode2 = items.First();
// and node itself
mGC.AddObject( &info );
while( pNode2 )
{
if ( pNode2 != pNode1 ) // node should not depend on itself
{
// add references to objects, on which this object
// depends. Dependecy here indicates intersection of current
// bounds of this object with the initial bounds of the
// other object
cbRectInfo& otherInfo = node_to_rect_info( pNode2 );
if ( rect_hits_rect( *info.mpCurBounds, *otherInfo.mpPrevBounds ) )
// the node depends on node
mGC.AddDependency( &info, &otherInfo );
}
pNode2 = pNode2->Next();
}
pNode1 = pNode1->Next();
}
mGC.ArrangeCollection(); // order nodes according "least-dependency" rule,
// and find out cycled chains
// regular item nodes need to be resized, but not repainted (since
// they stand in linear (not cyclic) dependency with other
// regular nodes)
wxNode* pNode = mGC.GetRegularObjects().First();
while ( pNode )
{
cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode));
if ( info.mpBar == NULL )
mpLayout->PositionClientWindow();
else
info.mpPane->SizeBar( info.mpBar );
pNode = pNode->Next();
}
// cycled item nodes, need to be both resized and repainted
pNode = mGC.GetCycledObjects().First();
while ( pNode )
{
cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode));
if ( info.mpBar == NULL )
{
wxWindow* pClntWnd = mpLayout->GetFrameClient();
mpLayout->PositionClientWindow();
// FIXME FIXME:: excessive!
pClntWnd->Show( FALSE );
pClntWnd->Show( TRUE );
// OLD STUFF:: mpLayout->PositionClientWindow();
}
else
if ( info.mpBar->mpBarWnd )
{
wxWindow* pWnd = info.mpBar->mpBarWnd;
// resize
info.mpPane->SizeBar( info.mpBar );
// repaint
/* OLD STUFF:: bool isChoice = info.mpBar->IsKindOf( CLASSINFO( wxChoice ) );
//#ifdef __WINDOWS__
//int result = ::SendMessage( (HWND)pWnd->m_hWnd, WM_NCPAINT, 0, 0 );
//#endif
*/
// FIXME FIXME:: there's no other way to repaint non-client area of the wxWindow!!
// so we do *excessive* "hide 'n show"
pWnd->Show(FALSE);
pWnd->Show(TRUE);
pWnd->Refresh();
}
pNode = pNode->Next();
}
// release data prepared for GC alg.
pNode = items.First();
while( pNode )
{
cbRectInfo* pInfo = (cbRectInfo*)(pNode->Data());
delete pInfo;
pNode = pNode->Next();
}
mGC.Reset(); // reinit GC
// FIXME:: this is a dirty-workaround for messy client-area,
// as a result of docking bar out of floated-container window
if ( mpLayout->mClientWndRefreshPending )
{
mpLayout->PositionClientWindow();
mpLayout->GetFrameClient()->Refresh();
}
}

View File

@@ -1,118 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 19/10/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __GCUPDATESMGR_G__
#define __GCUPDATESMGR_G__
#include "controlbar.h"
#include "updatesmgr.h"
#include "garbagec.h"
/*
* class implements optimized logic for refreshing
* areas of frame layout - which actually need to be updated.
* Is used as default updates-manager by wxFrameLayout.
*
* it is called "Garbage Collecting" u.mgr for it's impelmentation
* tries to find out dependencies between bars, and to order
* them ito "hierarchy", this hierarchical sorting resembles
* impelmenation of heap-garbage collectors, which resolve
* dependencies between referencs.
*
* Example: there are situations where the order of moving
* the windows does matter:
*
* case 1)
* ------ ---
* | A | |B|
* ------ ---> | |
* --- --- ------
* |B| | A |
* | | ------
* ---
* (future)
* (past)
*
* past/future positions of A and B windows completely overlapp, i.e.
* depend on each other, and there is not solution for
* moving the windows witout refereshing both of them,
* -- we have cyclic dependency here. The gc. alg will
* find this cyclic dependecy and will force "refresh"
* after movement.
*
* case 2)
*
* ------
* | A |
* ------ --->
* ---
* |B| ------
* | | | A |
* --- ------
* ---
* |B|
* | |
* ---
*
* (future)
* (past)
*
* in this case past/future positions do not overlapp, thus
* it's enough only to move windows, without refreshing them.
* GC will "notice" it.
*
* there is also third case, when overlapping is partial
* in this case the refershing can be also avoided by
* moving windows in the order of "most-dependant" towards the
* "least-dependent". GC handles this automatically, by
* sorting windows by their dependency-level (or "hierarchy")
*
* See garbagec.h for more details of this method, garbagec.h/cpp
* implement sorting of generic-depenencies (does not deal
* with graphical objects directly)
*
* Summary: improves performance when complex/large windows are
* moved around, by reducing number of repaints. Also helps
* to avoid dirty non-client areas of moved windows
* in some sepcal cases of "overlapping anomalies"
*/
class cbGCUpdatesMgr : public cbSimpleUpdatesMgr
{
DECLARE_DYNAMIC_CLASS( cbGCUpdatesMgr )
protected:
GarbageCollector mGC;
void DoRepositionItems( wxList& items );
void AddItem( wxList& itemList,
cbBarInfo* pBar,
cbDockPane* pPane,
wxRect& curBounds,
wxRect& prevBounds );
public:
cbGCUpdatesMgr(void) {}
cbGCUpdatesMgr( wxFrameLayout* pPanel );
// notificiactions received from Frame Layout :
virtual void OnStartChanges();
// refreshes parts of the frame layout, which need an update
virtual void UpdateNow();
};
#endif

View File

@@ -1,406 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 9/11/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "bardragpl.h"
// #pragma interface
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "hintanimpl.h"
#define POS_UNDEFINED -32768
/***** Implementation for class cbHintAnimationPlugin *****/
// FIXME:: some of the below code should be eliminated by
// reusing parts of cbBarDragPlugin's implementation
IMPLEMENT_DYNAMIC_CLASS( cbHintAnimationPlugin, cbPluginBase )
BEGIN_EVENT_TABLE( cbHintAnimationPlugin, cbPluginBase )
EVT_PL_DRAW_HINT_RECT( cbHintAnimationPlugin::OnDrawHintRect )
END_EVENT_TABLE()
cbHintAnimationPlugin::cbHintAnimationPlugin(void)
: mpScrDc( NULL ),
mInClientHintBorder( 4 ),
mAnimStarted( FALSE ),
mpAnimTimer( 0 ),
mMorphDelay ( 5 ),
mMaxFrames ( 20 ),
mAccelerationOn( TRUE )
{}
cbHintAnimationPlugin::cbHintAnimationPlugin( wxFrameLayout* pPanel, int paneMask )
: cbPluginBase( pPanel, paneMask ),
mpScrDc( NULL ),
mInClientHintBorder( 4 ),
mAnimStarted( FALSE ),
mpAnimTimer( 0 ),
mMorphDelay ( 5 ),
mMaxFrames ( 20 ),
mAccelerationOn( TRUE )
{}
cbHintAnimationPlugin::~cbHintAnimationPlugin()
{
if ( mpScrDc ) delete mpScrDc;
}
/*** rect-tracking related methods ***/
void cbHintAnimationPlugin::OnDrawHintRect( cbDrawHintRectEvent& event )
{
if ( !mAnimStarted && !mpScrDc )
{
StartTracking();
mPrevInClient = event.mIsInClient;
mPrevRect = event.mRect;
mStopPending = FALSE;
}
if ( !event.mEraseRect )
{
// pass on current hint-rect info to the animation "thread", in
// order to make adjustments to the morph-target on-the-fly
mCurRect.x = event.mRect.x;
mCurRect.y = event.mRect.y;
mCurRect.width = event.mRect.width;
mCurRect.height = event.mRect.height;
}
// check the amount of change in the shape of hint,
// and start morph-effect if change is "sufficient"
int change = abs( mCurRect.width - mPrevRect.width ) +
abs( mCurRect.height - mPrevRect.height );
if ( change > 10 && !event.mLastTime && !event.mEraseRect )
{
if ( !mpAnimTimer )
mpAnimTimer = new cbHintAnimTimer();
// init the animation "thread", or reinit if already started
if ( mAnimStarted )
{
int o;
++o;
}
mpAnimTimer->Init( this, mAnimStarted );
mAnimStarted = TRUE;
}
else
if ( !mAnimStarted )
{
DoDrawHintRect( event.mRect, event.mIsInClient );
if ( event.mLastTime )
FinishTracking();
mPrevInClient = event.mIsInClient;
}
else
{
mCurInClient = event.mIsInClient;
if ( event.mLastTime && mpAnimTimer )
{
mStopPending = TRUE;
if ( mpAnimTimer->mPrevMorphed.x != POS_UNDEFINED )
// erase previouse rect
DoDrawHintRect( mpAnimTimer->mPrevMorphed, mPrevInClient );
}
}
mPrevRect = event.mRect;
}
#define _A 0xAA
#define _B 0x00
#define _C 0x55
#define _D 0x00
static const unsigned char _gCheckerImg[] = { _A,_B,_C,_D,
_A,_B,_C,_D,
_A,_B,_C,_D,
_A,_B,_C,_D
};
void cbHintAnimationPlugin::StartTracking()
{
mpScrDc = new wxScreenDC;
wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
}
void cbHintAnimationPlugin::DoDrawHintRect( wxRect& rect, bool isInClientRect)
{
wxRect scrRect;
RectToScr( rect, scrRect );
int prevLF = mpScrDc->GetLogicalFunction();
mpScrDc->SetLogicalFunction( wxXOR );
if ( isInClientRect )
{
// BUG BUG BUG (wx):: somehow stippled brush works only
// when the bitmap created on stack, not
// as a member of the class
wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
wxBrush checkerBrush( checker );
mpScrDc->SetPen( mpLayout->mNullPen );
mpScrDc->SetBrush( checkerBrush );
int half = mInClientHintBorder / 2;
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y - half,
scrRect.width + 2*half, mInClientHintBorder );
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + scrRect.height - half,
scrRect.width + 2*half, mInClientHintBorder );
mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + half - 1,
mInClientHintBorder, scrRect.height - 2*half + 2);
mpScrDc->DrawRectangle( scrRect.x + scrRect.width - half,
scrRect.y + half - 1,
mInClientHintBorder, scrRect.height - 2*half + 2);
mpScrDc->SetBrush( wxNullBrush );
}
else
{
// otherwise draw 1-pixel thin borders
mpScrDc->SetPen( mpLayout->mBlackPen );
mpScrDc->DrawLine( scrRect.x, scrRect.y,
scrRect.x + scrRect.width, scrRect.y );
mpScrDc->DrawLine( scrRect.x, scrRect.y + 1,
scrRect.x, scrRect.y + scrRect.height );
mpScrDc->DrawLine( scrRect.x+1, scrRect.y + scrRect.height,
scrRect.x + scrRect.width, scrRect.y + scrRect.height );
mpScrDc->DrawLine( scrRect.x + scrRect.width , scrRect.y,
scrRect.x + scrRect.width, scrRect.y + scrRect.height + 1);
}
mpScrDc->SetLogicalFunction( prevLF );
}
void cbHintAnimationPlugin::DrawHintRect ( wxRect& rect, bool isInClientRect)
{
DoDrawHintRect( rect, isInClientRect );
}
void cbHintAnimationPlugin::EraseHintRect( wxRect& rect, bool isInClientRect)
{
DoDrawHintRect( rect, isInClientRect );
}
void cbHintAnimationPlugin::FinishTracking()
{
wxScreenDC::EndDrawingOnTop();
delete mpScrDc;
mpScrDc = NULL;
}
void cbHintAnimationPlugin::RectToScr( wxRect& frameRect, wxRect& scrRect )
{
scrRect = frameRect;
int x = frameRect.x, y = frameRect.y;
mpLayout->GetParentFrame().ClientToScreen( &x, &y );
scrRect.x = x;
scrRect.y = y;
}
/***** Implementation for class cbHintAnimTimer *****/
cbHintAnimTimer::cbHintAnimTimer(void)
{
#ifdef __WINDOWS__
mLock = NULL;
#endif
mPrevMorphed.x = POS_UNDEFINED;
}
void cbHintAnimTimer::MorphPoint( wxPoint& origin, MorphInfoT& info, wxPoint& point )
{
// simulate lienar movement (FOR NOW:: without acceleration)
double k;
if ( mpPl->mAccelerationOn )
k = double( mCurIter*mCurIter ) /
double( (mpPl->mMaxFrames - 1)*(mpPl->mMaxFrames - 1) );
else
k = double( mCurIter ) / double( mpPl->mMaxFrames - 1 );
point.x = int ( double ( info.mFrom.x + double (info.mTill.x - info.mFrom.x) * k ) );
point.y = int ( double ( info.mFrom.y + double (info.mTill.y - info.mFrom.y) * k ) );
point.x += origin.x;
point.y += origin.y;
}
void cbHintAnimTimer::Notify(void)
{
// FIXME:: "clean" implementation should use mutex to sync
// between GUI and animation threads
if ( mpPl->mStopPending )
{
Stop(); // top timer
mpPl->FinishTracking();
mpPl->mStopPending = FALSE;
mpPl->mpAnimTimer = NULL;
mpPl->mAnimStarted = FALSE;
mPrevMorphed.x = POS_UNDEFINED;
delete this;
return;
}
wxPoint origin( mpPl->mCurRect.x, mpPl->mCurRect.y );
wxPoint curUpper, curLower;
MorphPoint( origin, mUpperLeft, curUpper );
MorphPoint( origin, mLowerRight, curLower );
if ( mPrevMorphed.x != POS_UNDEFINED )
// erase previouse rect
mpPl->DoDrawHintRect( mPrevMorphed, mpPl->mPrevInClient );
wxRect morphed( curUpper.x, curUpper.y,
curLower.x - curUpper.x,
curLower.y - curUpper.y );
// draw rect of current iteration
mpPl->DoDrawHintRect( morphed,
( mCurIter != mpPl->mMaxFrames - 1 )
? mpPl->mPrevInClient : mpPl->mCurInClient );
mPrevMorphed = morphed;
if ( mCurIter == mpPl->mMaxFrames - 1 )
{
Stop(); // top timer
mpPl->FinishTracking();
mpPl->mpAnimTimer = NULL;
mpPl->mAnimStarted = FALSE;
mPrevMorphed.x = POS_UNDEFINED;
delete this;
}
else
++mCurIter;
}
bool cbHintAnimTimer::Init( cbHintAnimationPlugin* pAnimPl, bool reinit )
{
mpPl = pAnimPl;
int o;
++o;
++o;
// morph-points are set up relatively to the upper-left corner
// of the current hint-rectangle
if ( !reinit )
{
mUpperLeft.mFrom.x = mpPl->mPrevRect.x - mpPl->mCurRect.x;
mUpperLeft.mFrom.y = mpPl->mPrevRect.y - mpPl->mCurRect.y;
mLowerRight.mFrom.x = ( mUpperLeft.mFrom.x + mpPl->mPrevRect.width );
mLowerRight.mFrom.y = ( mUpperLeft.mFrom.y + mpPl->mPrevRect.height );
}
else
{
wxPoint origin( mpPl->mPrevRect.x, mpPl->mPrevRect.y );
wxPoint curUpper, curLower;
MorphPoint( origin, mUpperLeft, curUpper );
MorphPoint( origin, mLowerRight, curLower );
mUpperLeft.mFrom.x = curUpper.x - mpPl->mCurRect.x;
mUpperLeft.mFrom.y = curUpper.y - mpPl->mCurRect.y;
mLowerRight.mFrom.x = ( mUpperLeft.mFrom.x + curLower.x - curUpper.x );
mLowerRight.mFrom.y = ( mUpperLeft.mFrom.y + curLower.y - curUpper.y );
}
mUpperLeft.mTill.x = 0;
mUpperLeft.mTill.y = 0;
mLowerRight.mTill.x = mpPl->mCurRect.width;
mLowerRight.mTill.y = mpPl->mCurRect.height;
mCurIter = 1;
if ( !reinit )
Start( mpPl->mMorphDelay );
return TRUE;
}

View File

@@ -1,115 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: No names yet.
// Purpose: Contrib. demo
// Author: Aleksandras Gluchovas
// Modified by:
// Created: 9/11/98
// RCS-ID: $Id$
// Copyright: (c) Aleksandras Gluchovas
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef __HINTANIMPL_G__
#define __HINTANIMPL_G__
#include "controlbar.h"
#include "wx/timer.h"
class cbHintAnimTimer;
class cbHintAnimationPlugin : public cbPluginBase
{
DECLARE_DYNAMIC_CLASS( cbHintAnimationPlugin )
protected:
friend class cbHintAnimTimer;
wxScreenDC* mpScrDc; // created while tracking hint-rect
cbHintAnimTimer* mpAnimTimer;
// FOR NOW:: try it without mutually exculisve locks
volatile wxRect mCurRect;
// state variables
bool mAnimStarted;
bool mStopPending;
bool mPrevInClient;
bool mCurInClient;
wxRect mPrevRect;
public:
int mMorphDelay; // delay between frames in miliseconds, default: 20
int mMaxFrames; // number of iterations for hint morphing, default: 30
// (morph duration = mMorphDelay * mMaxFrames msec)
int mInClientHintBorder; // default: 4 pixels
bool mAccelerationOn; // TRUE, if morph accelerates, otherwise morph
// speed is constant. Default: TRUE
// TBD:: get/set methods for above members
protected:
void StartTracking();
void DrawHintRect ( wxRect& rect, bool isInClientRect);
void EraseHintRect( wxRect& rect, bool isInClientRect);
void FinishTracking();
void DoDrawHintRect( wxRect& rect, bool isInClientRect);
void RectToScr( wxRect& frameRect, wxRect& scrRect );
public:
cbHintAnimationPlugin(void);
~cbHintAnimationPlugin();
cbHintAnimationPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
void OnDrawHintRect( cbDrawHintRectEvent& event );
DECLARE_EVENT_TABLE()
};
// helper classes
struct MorphInfoT
{
wxPoint mFrom;
wxPoint mTill;
};
class cbHintAnimTimer : public wxTimer
{
protected:
friend class cbHintAnimationPlugin;
wxRect mPrevMorphed;
MorphInfoT mUpperLeft;
MorphInfoT mLowerRight;
int mCurIter;
long mLock;
cbHintAnimationPlugin* mpPl;
void MorphPoint( wxPoint& origin, MorphInfoT& info, wxPoint& point );
public:
cbHintAnimTimer(void);
virtual void Notify(void);
virtual bool Init( cbHintAnimationPlugin* pAnimPl, bool reinit );
};
#endif

Some files were not shown because too many files have changed in this diff Show More