Compare commits
1 Commits
before_gtk
...
b4_big_upd
Author | SHA1 | Date | |
---|---|---|---|
|
0b2c8aadbb |
@@ -1,90 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/generic/scrolwin.h
|
||||
// Purpose: wxGenericScrolledWindow class
|
||||
// Author: Julian Smart
|
||||
// Modified by:
|
||||
// Created: 01/02/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Julian Smart
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_GENERIC_SCROLLWIN_H_
|
||||
#define _WX_GENERIC_SCROLLWIN_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers and constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "wx/window.h"
|
||||
#include "wx/panel.h"
|
||||
|
||||
extern WXDLLEXPORT_DATA(const wxChar*) wxPanelNameStr;
|
||||
|
||||
// default scrolled window style
|
||||
#ifndef wxScrolledWindowStyle
|
||||
#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGenericScrolledWindow
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxGenericScrolledWindow : public wxPanel,
|
||||
public wxScrollHelper
|
||||
{
|
||||
public:
|
||||
wxGenericScrolledWindow() : wxScrollHelper(this) { }
|
||||
wxGenericScrolledWindow(wxWindow *parent,
|
||||
wxWindowID winid = wxID_ANY,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxScrolledWindowStyle,
|
||||
const wxString& name = wxPanelNameStr)
|
||||
: wxScrollHelper(this)
|
||||
{
|
||||
Create(parent, winid, pos, size, style, name);
|
||||
}
|
||||
|
||||
virtual ~wxGenericScrolledWindow();
|
||||
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID winid,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxScrolledWindowStyle,
|
||||
const wxString& name = wxPanelNameStr);
|
||||
|
||||
virtual void PrepareDC(wxDC& dc) { DoPrepareDC(dc); }
|
||||
|
||||
// lay out the window and its children
|
||||
virtual bool Layout();
|
||||
|
||||
virtual void DoSetVirtualSize(int x, int y);
|
||||
|
||||
// wxWindow's GetBestVirtualSize returns the actual window size,
|
||||
// whereas we want to return the virtual size
|
||||
virtual wxSize GetBestVirtualSize() const;
|
||||
|
||||
// Return the size best suited for the current window
|
||||
// (this isn't a virtual size, this is a sensible size for the window)
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
|
||||
protected:
|
||||
// this is needed for wxEVT_PAINT processing hack described in
|
||||
// wxScrollHelperEvtHandler::ProcessEvent()
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
|
||||
// we need to return a special WM_GETDLGCODE value to process just the
|
||||
// arrows but let the other navigation characters through
|
||||
#ifdef __WXMSW__
|
||||
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
|
||||
#endif // __WXMSW__
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxGenericScrolledWindow)
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif // _WX_GENERIC_SCROLLWIN_H_
|
||||
|
@@ -1,193 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/gtk/scrolwin.h
|
||||
// Purpose: wxScrolledWindow class
|
||||
// Author: Robert Roebling
|
||||
// Modified by:
|
||||
// Created: 01/02/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Robert Roebling
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_GTK_SCROLLWIN_H_
|
||||
#define _WX_GTK_SCROLLWIN_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers and constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "wx/window.h"
|
||||
#include "wx/panel.h"
|
||||
|
||||
WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr;
|
||||
|
||||
// default scrolled window style
|
||||
#ifndef wxScrolledWindowStyle
|
||||
#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxScrolledWindow
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxScrolledWindow : public wxPanel
|
||||
{
|
||||
public:
|
||||
wxScrolledWindow()
|
||||
{ Init(); }
|
||||
|
||||
wxScrolledWindow(wxWindow *parent,
|
||||
wxWindowID id = -1,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxScrolledWindowStyle,
|
||||
const wxString& name = wxPanelNameStr)
|
||||
{ Create(parent, id, pos, size, style, name); }
|
||||
|
||||
void Init();
|
||||
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxScrolledWindowStyle,
|
||||
const wxString& name = wxPanelNameStr);
|
||||
|
||||
// Normally the wxScrolledWindow will scroll itself, but in
|
||||
// some rare occasions you might want it to scroll another
|
||||
// window (e.g. a child of it in order to scroll only a portion
|
||||
// the area between the scrollbars (spreadsheet: only cell area
|
||||
// will move).
|
||||
virtual void SetTargetWindow( wxWindow *target, bool pushEventHandler = FALSE );
|
||||
virtual wxWindow *GetTargetWindow() const;
|
||||
|
||||
// Set the scrolled area of the window.
|
||||
virtual void DoSetVirtualSize( int x, int y );
|
||||
|
||||
// wxWindow's GetBestVirtualSize returns the actual window size,
|
||||
// whereas we want to return the virtual size
|
||||
virtual wxSize GetBestVirtualSize() const;
|
||||
|
||||
// Return the size best suited for the current window
|
||||
// (this isn't a virtual size, this is a sensible size for the window)
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
|
||||
// Set the x, y scrolling increments.
|
||||
void SetScrollRate( int xstep, int ystep );
|
||||
|
||||
// Number of pixels per user unit (0 or -1 for no scrollbar)
|
||||
// Length of virtual canvas in user units
|
||||
// Length of page in user units
|
||||
// Default action is to set the virtual size and alter scrollbars
|
||||
// accordingly.
|
||||
virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
|
||||
int noUnitsX, int noUnitsY,
|
||||
int xPos = 0, int yPos = 0,
|
||||
bool noRefresh = FALSE );
|
||||
|
||||
// Physically scroll the window
|
||||
virtual void Scroll(int x_pos, int y_pos);
|
||||
|
||||
int GetScrollPageSize(int orient) const;
|
||||
void SetScrollPageSize(int orient, int pageSize);
|
||||
|
||||
virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const;
|
||||
|
||||
// Enable/disable Windows scrolling in either direction.
|
||||
// If TRUE, wxWidgets scrolls the canvas and only a bit of
|
||||
// the canvas is invalidated; no Clear() is necessary.
|
||||
// If FALSE, the whole canvas is invalidated and a Clear() is
|
||||
// necessary. Disable for when the scroll increment is used
|
||||
// to actually scroll a non-constant distance
|
||||
virtual void EnableScrolling(bool x_scrolling, bool y_scrolling);
|
||||
|
||||
// Get the view start
|
||||
virtual void GetViewStart(int *x, int *y) const;
|
||||
|
||||
// translate between scrolled and unscrolled coordinates
|
||||
void CalcScrolledPosition(int x, int y, int *xx, int *yy) const
|
||||
{ DoCalcScrolledPosition(x, y, xx, yy); }
|
||||
wxPoint CalcScrolledPosition(const wxPoint& pt) const
|
||||
{
|
||||
wxPoint p2;
|
||||
DoCalcScrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
|
||||
return p2;
|
||||
}
|
||||
|
||||
void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
|
||||
{ DoCalcUnscrolledPosition(x, y, xx, yy); }
|
||||
wxPoint CalcUnscrolledPosition(const wxPoint& pt) const
|
||||
{
|
||||
wxPoint p2;
|
||||
DoCalcUnscrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
|
||||
return p2;
|
||||
}
|
||||
|
||||
virtual void DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const;
|
||||
virtual void DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
|
||||
|
||||
// Override this function to draw the graphic (or just process EVT_PAINT)
|
||||
virtual void OnDraw(wxDC& WXUNUSED(dc)) {}
|
||||
|
||||
// Override this function if you don't want to have wxScrolledWindow
|
||||
// automatically change the origin according to the scroll position.
|
||||
void PrepareDC(wxDC& dc) { DoPrepareDC(dc); }
|
||||
|
||||
// lay out the window and its children
|
||||
virtual bool Layout();
|
||||
|
||||
// Adjust the scrollbars
|
||||
virtual void AdjustScrollbars();
|
||||
|
||||
// Set the scale factor, used in PrepareDC
|
||||
void SetScale(double xs, double ys) { m_scaleX = xs; m_scaleY = ys; }
|
||||
double GetScaleX() const { return m_scaleX; }
|
||||
double GetScaleY() const { return m_scaleY; }
|
||||
|
||||
// implementation from now on
|
||||
void OnScroll(wxScrollWinEvent& event);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnChar(wxKeyEvent& event);
|
||||
|
||||
void GtkVScroll( float value, unsigned int scroll_type );
|
||||
void GtkHScroll( float value, unsigned int scroll_type );
|
||||
void GtkVConnectEvent();
|
||||
void GtkHConnectEvent();
|
||||
void GtkVDisconnectEvent();
|
||||
void GtkHDisconnectEvent();
|
||||
|
||||
// Calculate scroll increment
|
||||
virtual int CalcScrollInc(wxScrollWinEvent& event);
|
||||
|
||||
// Overridden from wxWidgets due callback being static
|
||||
virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE );
|
||||
|
||||
virtual void DoPrepareDC(wxDC& dc);
|
||||
|
||||
protected:
|
||||
wxWindow *m_targetWindow;
|
||||
int m_xScrollPixelsPerLine;
|
||||
int m_yScrollPixelsPerLine;
|
||||
bool m_xScrollingEnabled;
|
||||
bool m_yScrollingEnabled;
|
||||
|
||||
// FIXME: these next four members are duplicated in the GtkAdjustment
|
||||
// members of wxWindow. Can they be safely removed from here?
|
||||
|
||||
int m_xScrollPosition;
|
||||
int m_yScrollPosition;
|
||||
int m_xScrollLinesPerPage;
|
||||
int m_yScrollLinesPerPage;
|
||||
|
||||
double m_scaleY,m_scaleX;
|
||||
|
||||
private:
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_DYNAMIC_CLASS(wxScrolledWindow)
|
||||
};
|
||||
|
||||
#endif
|
||||
// _WX_GTK_SCROLLWIN_H_
|
||||
|
||||
// vi:sts=4:sw=4:et
|
@@ -1,300 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/gtk/window.h
|
||||
// Purpose:
|
||||
// Author: Robert Roebling
|
||||
// Id: $Id$
|
||||
// Copyright: (c) 1998 Robert Roebling
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __GTKWINDOWH__
|
||||
#define __GTKWINDOWH__
|
||||
|
||||
// helper structure that holds class that holds GtkIMContext object and
|
||||
// some additional data needed for key events processing
|
||||
struct wxGtkIMData;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// callback definition for inserting a window (internal)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_CORE wxWindowGTK;
|
||||
typedef void (*wxInsertChildFunction)( wxWindowGTK*, wxWindowGTK* );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxWindowGTK
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_CORE wxWindowGTK : public wxWindowBase
|
||||
{
|
||||
public:
|
||||
// creating the window
|
||||
// -------------------
|
||||
wxWindowGTK();
|
||||
wxWindowGTK(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
const wxString& name = wxPanelNameStr);
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
const wxString& name = wxPanelNameStr);
|
||||
virtual ~wxWindowGTK();
|
||||
|
||||
// implement base class (pure) virtual methods
|
||||
// -------------------------------------------
|
||||
|
||||
virtual bool Destroy();
|
||||
|
||||
virtual void Raise();
|
||||
virtual void Lower();
|
||||
|
||||
virtual bool Show( bool show = TRUE );
|
||||
virtual bool Enable( bool enable = TRUE );
|
||||
|
||||
virtual bool IsRetained() const;
|
||||
|
||||
virtual void SetFocus();
|
||||
virtual bool AcceptsFocus() const;
|
||||
|
||||
virtual bool Reparent( wxWindowBase *newParent );
|
||||
|
||||
virtual void WarpPointer(int x, int y);
|
||||
|
||||
virtual void Refresh( bool eraseBackground = TRUE,
|
||||
const wxRect *rect = (const wxRect *) NULL );
|
||||
virtual void Update();
|
||||
virtual void ClearBackground();
|
||||
|
||||
virtual bool SetBackgroundColour( const wxColour &colour );
|
||||
virtual bool SetForegroundColour( const wxColour &colour );
|
||||
virtual bool SetCursor( const wxCursor &cursor );
|
||||
virtual bool SetFont( const wxFont &font );
|
||||
|
||||
virtual bool SetBackgroundStyle(wxBackgroundStyle style) ;
|
||||
|
||||
virtual int GetCharHeight() const;
|
||||
virtual int GetCharWidth() const;
|
||||
virtual void GetTextExtent(const wxString& string,
|
||||
int *x, int *y,
|
||||
int *descent = (int *) NULL,
|
||||
int *externalLeading = (int *) NULL,
|
||||
const wxFont *theFont = (const wxFont *) NULL)
|
||||
const;
|
||||
|
||||
#if wxUSE_MENUS_NATIVE
|
||||
virtual bool DoPopupMenu( wxMenu *menu, int x, int y );
|
||||
#endif // wxUSE_MENUS_NATIVE
|
||||
|
||||
virtual void SetScrollbar( int orient, int pos, int thumbVisible,
|
||||
int range, bool refresh = TRUE );
|
||||
virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE );
|
||||
virtual int GetScrollPos( int orient ) const;
|
||||
virtual int GetScrollThumb( int orient ) const;
|
||||
virtual int GetScrollRange( int orient ) const;
|
||||
virtual void ScrollWindow( int dx, int dy,
|
||||
const wxRect* rect = (wxRect *) NULL );
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
virtual void SetDropTarget( wxDropTarget *dropTarget );
|
||||
#endif // wxUSE_DRAG_AND_DROP
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
virtual void AddChild( wxWindowBase *child );
|
||||
virtual void RemoveChild( wxWindowBase *child );
|
||||
#endif
|
||||
|
||||
// implementation
|
||||
// --------------
|
||||
|
||||
virtual WXWidget GetHandle() const { return m_widget; }
|
||||
|
||||
// I don't want users to override what's done in idle so everything that
|
||||
// has to be done in idle time in order for wxGTK to work is done in
|
||||
// OnInternalIdle
|
||||
virtual void OnInternalIdle();
|
||||
|
||||
// Internal represention of Update()
|
||||
void GtkUpdate();
|
||||
|
||||
// For compatibility across platforms (not in event table)
|
||||
void OnIdle(wxIdleEvent& WXUNUSED(event)) {}
|
||||
|
||||
// wxGTK-specific: called recursively by Enable,
|
||||
// to give widgets an oppprtunity to correct their colours after they
|
||||
// have been changed by Enable
|
||||
virtual void OnParentEnable( bool WXUNUSED(enable) ) {}
|
||||
|
||||
// Used by all window classes in the widget creation process.
|
||||
bool PreCreation( wxWindowGTK *parent, const wxPoint &pos, const wxSize &size );
|
||||
void PostCreation();
|
||||
|
||||
// Internal addition of child windows. differs from class
|
||||
// to class not by using virtual functions but by using
|
||||
// the m_insertCallback.
|
||||
void DoAddChild(wxWindowGTK *child);
|
||||
|
||||
// This methods sends wxPaintEvents to the window. It reads the
|
||||
// update region, breaks it up into rects and sends an event
|
||||
// for each rect. It is also responsible for background erase
|
||||
// events and NC paint events. It is called from "draw" and
|
||||
// "expose" handlers as well as from ::Update()
|
||||
void GtkSendPaintEvents();
|
||||
|
||||
// The methods below are required because many native widgets
|
||||
// are composed of several subwidgets and setting a style for
|
||||
// the widget means setting it for all subwidgets as well.
|
||||
// also, it is nor clear, which native widget is the top
|
||||
// widget where (most of) the input goes. even tooltips have
|
||||
// to be applied to all subwidgets.
|
||||
virtual GtkWidget* GetConnectWidget();
|
||||
virtual bool IsOwnGtkWindow( GdkWindow *window );
|
||||
void ConnectWidget( GtkWidget *widget );
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
// Returns the default context which usually is anti-aliased
|
||||
PangoContext *GtkGetPangoDefaultContext();
|
||||
|
||||
// Returns the X11 context which renders on the X11 client
|
||||
// side (which can be remote) and which usually is not
|
||||
// anti-aliased and is thus faster
|
||||
// MR: Now returns the default pango_context for the widget as GtkGetPangoDefaultContext to
|
||||
// not depend on libpangox - which is completely deprecated.
|
||||
//BCI: Remove GtkGetPangoX11Context and m_x11Context completely when symbols may be removed
|
||||
PangoContext *GtkGetPangoX11Context();
|
||||
PangoContext *m_x11Context; // MR: Now unused
|
||||
#endif
|
||||
|
||||
#if wxUSE_TOOLTIPS
|
||||
virtual void ApplyToolTip( GtkTooltips *tips, const wxChar *tip );
|
||||
#endif // wxUSE_TOOLTIPS
|
||||
|
||||
// Called from GTK signales handlers. it indicates that
|
||||
// the layouting functions have to be called later on
|
||||
// (i.e. in idle time, implemented in OnInternalIdle() ).
|
||||
void GtkUpdateSize() { m_sizeSet = FALSE; }
|
||||
|
||||
// fix up the mouse event coords, used by wxListBox only so far
|
||||
virtual void FixUpMouseEvent(GtkWidget * WXUNUSED(widget),
|
||||
wxCoord& WXUNUSED(x),
|
||||
wxCoord& WXUNUSED(y)) { }
|
||||
|
||||
// is this window transparent for the mouse events (as wxStaticBox is)?
|
||||
virtual bool IsTransparentForMouse() const { return FALSE; }
|
||||
|
||||
// is this a radiobutton (used by radiobutton code itself only)?
|
||||
virtual bool IsRadioButton() const { return FALSE; }
|
||||
|
||||
// position and size of the window
|
||||
int m_x, m_y;
|
||||
int m_width, m_height;
|
||||
int m_oldClientWidth,m_oldClientHeight;
|
||||
|
||||
// see the docs in src/gtk/window.cpp
|
||||
GtkWidget *m_widget; // mostly the widget seen by the rest of GTK
|
||||
GtkWidget *m_wxwindow; // mostly the client area as per wxWidgets
|
||||
|
||||
// this widget will be queried for GTK's focus events
|
||||
GtkWidget *m_focusWidget;
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
wxGtkIMData *m_imData;
|
||||
#else // GTK 1
|
||||
#ifdef HAVE_XIM
|
||||
// XIM support for wxWidgets
|
||||
GdkIC *m_ic;
|
||||
GdkICAttr *m_icattr;
|
||||
#endif // HAVE_XIM
|
||||
#endif // GTK 2/1
|
||||
|
||||
#ifndef __WXGTK20__
|
||||
// The area to be cleared (and not just refreshed)
|
||||
// We cannot make this distinction under GTK 2.0.
|
||||
wxRegion m_clearRegion;
|
||||
#endif
|
||||
|
||||
// scrolling stuff
|
||||
GtkAdjustment *m_hAdjust,*m_vAdjust;
|
||||
float m_oldHorizontalPos;
|
||||
float m_oldVerticalPos;
|
||||
|
||||
// extra (wxGTK-specific) flags
|
||||
bool m_needParent:1; // ! wxFrame, wxDialog, wxNotebookPage ?
|
||||
bool m_noExpose:1; // wxGLCanvas has its own redrawing
|
||||
bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size"
|
||||
bool m_hasScrolling:1;
|
||||
bool m_hasVMT:1;
|
||||
bool m_sizeSet:1;
|
||||
bool m_resizing:1;
|
||||
bool m_acceptsFocus:1; // true if not static
|
||||
bool m_hasFocus:1; // true if == FindFocus()
|
||||
bool m_isScrolling:1; // dragging scrollbar thumb?
|
||||
bool m_clipPaintRegion:1; // TRUE after ScrollWindow()
|
||||
#ifdef __WXGTK20__
|
||||
bool m_dirtyTabOrder:1; // tab order changed, GTK focus
|
||||
// chain needs update
|
||||
#endif
|
||||
bool m_needsStyleChange:1; // May not be able to change
|
||||
// background style until OnIdle
|
||||
|
||||
// C++ has no virtual methods in the constrcutor of any class but we need
|
||||
// different methods of inserting a child window into a wxFrame,
|
||||
// wxMDIFrame, wxNotebook etc. this is the callback that will get used.
|
||||
wxInsertChildFunction m_insertCallback;
|
||||
|
||||
// implement the base class pure virtuals
|
||||
virtual void DoClientToScreen( int *x, int *y ) const;
|
||||
virtual void DoScreenToClient( int *x, int *y ) const;
|
||||
virtual void DoGetPosition( int *x, int *y ) const;
|
||||
virtual void DoGetSize( int *width, int *height ) const;
|
||||
virtual void DoGetClientSize( int *width, int *height ) const;
|
||||
virtual void DoSetSize(int x, int y,
|
||||
int width, int height,
|
||||
int sizeFlags = wxSIZE_AUTO);
|
||||
virtual void DoSetClientSize(int width, int height);
|
||||
virtual void DoMoveWindow(int x, int y, int width, int height);
|
||||
|
||||
virtual void DoCaptureMouse();
|
||||
virtual void DoReleaseMouse();
|
||||
|
||||
#if wxUSE_TOOLTIPS
|
||||
virtual void DoSetToolTip( wxToolTip *tip );
|
||||
#endif // wxUSE_TOOLTIPS
|
||||
|
||||
protected:
|
||||
// common part of all ctors (not virtual because called from ctor)
|
||||
void Init();
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
virtual void DoMoveInTabOrder(wxWindow *win, MoveKind move);
|
||||
|
||||
// Copies m_children tab order to GTK focus chain:
|
||||
void RealizeTabOrder();
|
||||
#endif
|
||||
|
||||
// Called by ApplyWidgetStyle (which is called by SetFont() and
|
||||
// SetXXXColour etc to apply style changed to native widgets) to create
|
||||
// modified GTK style with non-standard attributes. If forceStyle=true,
|
||||
// creates empty GtkRcStyle if there are no modifications, otherwise
|
||||
// returns NULL in such case.
|
||||
GtkRcStyle *CreateWidgetStyle(bool forceStyle = false);
|
||||
|
||||
// Overridden in many GTK widgets who have to handle subwidgets
|
||||
virtual void ApplyWidgetStyle(bool forceStyle = false);
|
||||
|
||||
// helper function to ease native widgets wrapping, called by
|
||||
// ApplyWidgetStyle -- override this, not ApplyWidgetStyle
|
||||
virtual void DoApplyWidgetStyle(GtkRcStyle *style);
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS(wxWindowGTK)
|
||||
DECLARE_NO_COPY_CLASS(wxWindowGTK)
|
||||
};
|
||||
|
||||
extern WXDLLIMPEXP_CORE wxWindow *wxFindFocusedChild(wxWindowGTK *win);
|
||||
|
||||
#endif // __GTKWINDOWH__
|
@@ -1,193 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/gtk/scrolwin.h
|
||||
// Purpose: wxScrolledWindow class
|
||||
// Author: Robert Roebling
|
||||
// Modified by:
|
||||
// Created: 01/02/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Robert Roebling
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_GTK_SCROLLWIN_H_
|
||||
#define _WX_GTK_SCROLLWIN_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers and constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "wx/window.h"
|
||||
#include "wx/panel.h"
|
||||
|
||||
WXDLLEXPORT_DATA(extern const wxChar*) wxPanelNameStr;
|
||||
|
||||
// default scrolled window style
|
||||
#ifndef wxScrolledWindowStyle
|
||||
#define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxScrolledWindow
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxScrolledWindow : public wxPanel
|
||||
{
|
||||
public:
|
||||
wxScrolledWindow()
|
||||
{ Init(); }
|
||||
|
||||
wxScrolledWindow(wxWindow *parent,
|
||||
wxWindowID id = -1,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxScrolledWindowStyle,
|
||||
const wxString& name = wxPanelNameStr)
|
||||
{ Create(parent, id, pos, size, style, name); }
|
||||
|
||||
void Init();
|
||||
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxScrolledWindowStyle,
|
||||
const wxString& name = wxPanelNameStr);
|
||||
|
||||
// Normally the wxScrolledWindow will scroll itself, but in
|
||||
// some rare occasions you might want it to scroll another
|
||||
// window (e.g. a child of it in order to scroll only a portion
|
||||
// the area between the scrollbars (spreadsheet: only cell area
|
||||
// will move).
|
||||
virtual void SetTargetWindow( wxWindow *target, bool pushEventHandler = FALSE );
|
||||
virtual wxWindow *GetTargetWindow() const;
|
||||
|
||||
// Set the scrolled area of the window.
|
||||
virtual void DoSetVirtualSize( int x, int y );
|
||||
|
||||
// wxWindow's GetBestVirtualSize returns the actual window size,
|
||||
// whereas we want to return the virtual size
|
||||
virtual wxSize GetBestVirtualSize() const;
|
||||
|
||||
// Return the size best suited for the current window
|
||||
// (this isn't a virtual size, this is a sensible size for the window)
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
|
||||
// Set the x, y scrolling increments.
|
||||
void SetScrollRate( int xstep, int ystep );
|
||||
|
||||
// Number of pixels per user unit (0 or -1 for no scrollbar)
|
||||
// Length of virtual canvas in user units
|
||||
// Length of page in user units
|
||||
// Default action is to set the virtual size and alter scrollbars
|
||||
// accordingly.
|
||||
virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
|
||||
int noUnitsX, int noUnitsY,
|
||||
int xPos = 0, int yPos = 0,
|
||||
bool noRefresh = FALSE );
|
||||
|
||||
// Physically scroll the window
|
||||
virtual void Scroll(int x_pos, int y_pos);
|
||||
|
||||
int GetScrollPageSize(int orient) const;
|
||||
void SetScrollPageSize(int orient, int pageSize);
|
||||
|
||||
virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const;
|
||||
|
||||
// Enable/disable Windows scrolling in either direction.
|
||||
// If TRUE, wxWidgets scrolls the canvas and only a bit of
|
||||
// the canvas is invalidated; no Clear() is necessary.
|
||||
// If FALSE, the whole canvas is invalidated and a Clear() is
|
||||
// necessary. Disable for when the scroll increment is used
|
||||
// to actually scroll a non-constant distance
|
||||
virtual void EnableScrolling(bool x_scrolling, bool y_scrolling);
|
||||
|
||||
// Get the view start
|
||||
virtual void GetViewStart(int *x, int *y) const;
|
||||
|
||||
// translate between scrolled and unscrolled coordinates
|
||||
void CalcScrolledPosition(int x, int y, int *xx, int *yy) const
|
||||
{ DoCalcScrolledPosition(x, y, xx, yy); }
|
||||
wxPoint CalcScrolledPosition(const wxPoint& pt) const
|
||||
{
|
||||
wxPoint p2;
|
||||
DoCalcScrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
|
||||
return p2;
|
||||
}
|
||||
|
||||
void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
|
||||
{ DoCalcUnscrolledPosition(x, y, xx, yy); }
|
||||
wxPoint CalcUnscrolledPosition(const wxPoint& pt) const
|
||||
{
|
||||
wxPoint p2;
|
||||
DoCalcUnscrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
|
||||
return p2;
|
||||
}
|
||||
|
||||
virtual void DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const;
|
||||
virtual void DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
|
||||
|
||||
// Override this function to draw the graphic (or just process EVT_PAINT)
|
||||
virtual void OnDraw(wxDC& WXUNUSED(dc)) {}
|
||||
|
||||
// Override this function if you don't want to have wxScrolledWindow
|
||||
// automatically change the origin according to the scroll position.
|
||||
void PrepareDC(wxDC& dc) { DoPrepareDC(dc); }
|
||||
|
||||
// lay out the window and its children
|
||||
virtual bool Layout();
|
||||
|
||||
// Adjust the scrollbars
|
||||
virtual void AdjustScrollbars();
|
||||
|
||||
// Set the scale factor, used in PrepareDC
|
||||
void SetScale(double xs, double ys) { m_scaleX = xs; m_scaleY = ys; }
|
||||
double GetScaleX() const { return m_scaleX; }
|
||||
double GetScaleY() const { return m_scaleY; }
|
||||
|
||||
// implementation from now on
|
||||
void OnScroll(wxScrollWinEvent& event);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void OnChar(wxKeyEvent& event);
|
||||
|
||||
void GtkVScroll( float value, unsigned int scroll_type );
|
||||
void GtkHScroll( float value, unsigned int scroll_type );
|
||||
void GtkVConnectEvent();
|
||||
void GtkHConnectEvent();
|
||||
void GtkVDisconnectEvent();
|
||||
void GtkHDisconnectEvent();
|
||||
|
||||
// Calculate scroll increment
|
||||
virtual int CalcScrollInc(wxScrollWinEvent& event);
|
||||
|
||||
// Overridden from wxWidgets due callback being static
|
||||
virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE );
|
||||
|
||||
virtual void DoPrepareDC(wxDC& dc);
|
||||
|
||||
protected:
|
||||
wxWindow *m_targetWindow;
|
||||
int m_xScrollPixelsPerLine;
|
||||
int m_yScrollPixelsPerLine;
|
||||
bool m_xScrollingEnabled;
|
||||
bool m_yScrollingEnabled;
|
||||
|
||||
// FIXME: these next four members are duplicated in the GtkAdjustment
|
||||
// members of wxWindow. Can they be safely removed from here?
|
||||
|
||||
int m_xScrollPosition;
|
||||
int m_yScrollPosition;
|
||||
int m_xScrollLinesPerPage;
|
||||
int m_yScrollLinesPerPage;
|
||||
|
||||
double m_scaleY,m_scaleX;
|
||||
|
||||
private:
|
||||
DECLARE_EVENT_TABLE()
|
||||
DECLARE_DYNAMIC_CLASS(wxScrolledWindow)
|
||||
};
|
||||
|
||||
#endif
|
||||
// _WX_GTK_SCROLLWIN_H_
|
||||
|
||||
// vi:sts=4:sw=4:et
|
@@ -1,300 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/gtk/window.h
|
||||
// Purpose:
|
||||
// Author: Robert Roebling
|
||||
// Id: $Id$
|
||||
// Copyright: (c) 1998 Robert Roebling
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __GTKWINDOWH__
|
||||
#define __GTKWINDOWH__
|
||||
|
||||
// helper structure that holds class that holds GtkIMContext object and
|
||||
// some additional data needed for key events processing
|
||||
struct wxGtkIMData;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// callback definition for inserting a window (internal)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_CORE wxWindowGTK;
|
||||
typedef void (*wxInsertChildFunction)( wxWindowGTK*, wxWindowGTK* );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxWindowGTK
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_CORE wxWindowGTK : public wxWindowBase
|
||||
{
|
||||
public:
|
||||
// creating the window
|
||||
// -------------------
|
||||
wxWindowGTK();
|
||||
wxWindowGTK(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
const wxString& name = wxPanelNameStr);
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
const wxString& name = wxPanelNameStr);
|
||||
virtual ~wxWindowGTK();
|
||||
|
||||
// implement base class (pure) virtual methods
|
||||
// -------------------------------------------
|
||||
|
||||
virtual bool Destroy();
|
||||
|
||||
virtual void Raise();
|
||||
virtual void Lower();
|
||||
|
||||
virtual bool Show( bool show = TRUE );
|
||||
virtual bool Enable( bool enable = TRUE );
|
||||
|
||||
virtual bool IsRetained() const;
|
||||
|
||||
virtual void SetFocus();
|
||||
virtual bool AcceptsFocus() const;
|
||||
|
||||
virtual bool Reparent( wxWindowBase *newParent );
|
||||
|
||||
virtual void WarpPointer(int x, int y);
|
||||
|
||||
virtual void Refresh( bool eraseBackground = TRUE,
|
||||
const wxRect *rect = (const wxRect *) NULL );
|
||||
virtual void Update();
|
||||
virtual void ClearBackground();
|
||||
|
||||
virtual bool SetBackgroundColour( const wxColour &colour );
|
||||
virtual bool SetForegroundColour( const wxColour &colour );
|
||||
virtual bool SetCursor( const wxCursor &cursor );
|
||||
virtual bool SetFont( const wxFont &font );
|
||||
|
||||
virtual bool SetBackgroundStyle(wxBackgroundStyle style) ;
|
||||
|
||||
virtual int GetCharHeight() const;
|
||||
virtual int GetCharWidth() const;
|
||||
virtual void GetTextExtent(const wxString& string,
|
||||
int *x, int *y,
|
||||
int *descent = (int *) NULL,
|
||||
int *externalLeading = (int *) NULL,
|
||||
const wxFont *theFont = (const wxFont *) NULL)
|
||||
const;
|
||||
|
||||
#if wxUSE_MENUS_NATIVE
|
||||
virtual bool DoPopupMenu( wxMenu *menu, int x, int y );
|
||||
#endif // wxUSE_MENUS_NATIVE
|
||||
|
||||
virtual void SetScrollbar( int orient, int pos, int thumbVisible,
|
||||
int range, bool refresh = TRUE );
|
||||
virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE );
|
||||
virtual int GetScrollPos( int orient ) const;
|
||||
virtual int GetScrollThumb( int orient ) const;
|
||||
virtual int GetScrollRange( int orient ) const;
|
||||
virtual void ScrollWindow( int dx, int dy,
|
||||
const wxRect* rect = (wxRect *) NULL );
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
virtual void SetDropTarget( wxDropTarget *dropTarget );
|
||||
#endif // wxUSE_DRAG_AND_DROP
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
virtual void AddChild( wxWindowBase *child );
|
||||
virtual void RemoveChild( wxWindowBase *child );
|
||||
#endif
|
||||
|
||||
// implementation
|
||||
// --------------
|
||||
|
||||
virtual WXWidget GetHandle() const { return m_widget; }
|
||||
|
||||
// I don't want users to override what's done in idle so everything that
|
||||
// has to be done in idle time in order for wxGTK to work is done in
|
||||
// OnInternalIdle
|
||||
virtual void OnInternalIdle();
|
||||
|
||||
// Internal represention of Update()
|
||||
void GtkUpdate();
|
||||
|
||||
// For compatibility across platforms (not in event table)
|
||||
void OnIdle(wxIdleEvent& WXUNUSED(event)) {}
|
||||
|
||||
// wxGTK-specific: called recursively by Enable,
|
||||
// to give widgets an oppprtunity to correct their colours after they
|
||||
// have been changed by Enable
|
||||
virtual void OnParentEnable( bool WXUNUSED(enable) ) {}
|
||||
|
||||
// Used by all window classes in the widget creation process.
|
||||
bool PreCreation( wxWindowGTK *parent, const wxPoint &pos, const wxSize &size );
|
||||
void PostCreation();
|
||||
|
||||
// Internal addition of child windows. differs from class
|
||||
// to class not by using virtual functions but by using
|
||||
// the m_insertCallback.
|
||||
void DoAddChild(wxWindowGTK *child);
|
||||
|
||||
// This methods sends wxPaintEvents to the window. It reads the
|
||||
// update region, breaks it up into rects and sends an event
|
||||
// for each rect. It is also responsible for background erase
|
||||
// events and NC paint events. It is called from "draw" and
|
||||
// "expose" handlers as well as from ::Update()
|
||||
void GtkSendPaintEvents();
|
||||
|
||||
// The methods below are required because many native widgets
|
||||
// are composed of several subwidgets and setting a style for
|
||||
// the widget means setting it for all subwidgets as well.
|
||||
// also, it is nor clear, which native widget is the top
|
||||
// widget where (most of) the input goes. even tooltips have
|
||||
// to be applied to all subwidgets.
|
||||
virtual GtkWidget* GetConnectWidget();
|
||||
virtual bool IsOwnGtkWindow( GdkWindow *window );
|
||||
void ConnectWidget( GtkWidget *widget );
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
// Returns the default context which usually is anti-aliased
|
||||
PangoContext *GtkGetPangoDefaultContext();
|
||||
|
||||
// Returns the X11 context which renders on the X11 client
|
||||
// side (which can be remote) and which usually is not
|
||||
// anti-aliased and is thus faster
|
||||
// MR: Now returns the default pango_context for the widget as GtkGetPangoDefaultContext to
|
||||
// not depend on libpangox - which is completely deprecated.
|
||||
//BCI: Remove GtkGetPangoX11Context and m_x11Context completely when symbols may be removed
|
||||
PangoContext *GtkGetPangoX11Context();
|
||||
PangoContext *m_x11Context; // MR: Now unused
|
||||
#endif
|
||||
|
||||
#if wxUSE_TOOLTIPS
|
||||
virtual void ApplyToolTip( GtkTooltips *tips, const wxChar *tip );
|
||||
#endif // wxUSE_TOOLTIPS
|
||||
|
||||
// Called from GTK signales handlers. it indicates that
|
||||
// the layouting functions have to be called later on
|
||||
// (i.e. in idle time, implemented in OnInternalIdle() ).
|
||||
void GtkUpdateSize() { m_sizeSet = FALSE; }
|
||||
|
||||
// fix up the mouse event coords, used by wxListBox only so far
|
||||
virtual void FixUpMouseEvent(GtkWidget * WXUNUSED(widget),
|
||||
wxCoord& WXUNUSED(x),
|
||||
wxCoord& WXUNUSED(y)) { }
|
||||
|
||||
// is this window transparent for the mouse events (as wxStaticBox is)?
|
||||
virtual bool IsTransparentForMouse() const { return FALSE; }
|
||||
|
||||
// is this a radiobutton (used by radiobutton code itself only)?
|
||||
virtual bool IsRadioButton() const { return FALSE; }
|
||||
|
||||
// position and size of the window
|
||||
int m_x, m_y;
|
||||
int m_width, m_height;
|
||||
int m_oldClientWidth,m_oldClientHeight;
|
||||
|
||||
// see the docs in src/gtk/window.cpp
|
||||
GtkWidget *m_widget; // mostly the widget seen by the rest of GTK
|
||||
GtkWidget *m_wxwindow; // mostly the client area as per wxWidgets
|
||||
|
||||
// this widget will be queried for GTK's focus events
|
||||
GtkWidget *m_focusWidget;
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
wxGtkIMData *m_imData;
|
||||
#else // GTK 1
|
||||
#ifdef HAVE_XIM
|
||||
// XIM support for wxWidgets
|
||||
GdkIC *m_ic;
|
||||
GdkICAttr *m_icattr;
|
||||
#endif // HAVE_XIM
|
||||
#endif // GTK 2/1
|
||||
|
||||
#ifndef __WXGTK20__
|
||||
// The area to be cleared (and not just refreshed)
|
||||
// We cannot make this distinction under GTK 2.0.
|
||||
wxRegion m_clearRegion;
|
||||
#endif
|
||||
|
||||
// scrolling stuff
|
||||
GtkAdjustment *m_hAdjust,*m_vAdjust;
|
||||
float m_oldHorizontalPos;
|
||||
float m_oldVerticalPos;
|
||||
|
||||
// extra (wxGTK-specific) flags
|
||||
bool m_needParent:1; // ! wxFrame, wxDialog, wxNotebookPage ?
|
||||
bool m_noExpose:1; // wxGLCanvas has its own redrawing
|
||||
bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size"
|
||||
bool m_hasScrolling:1;
|
||||
bool m_hasVMT:1;
|
||||
bool m_sizeSet:1;
|
||||
bool m_resizing:1;
|
||||
bool m_acceptsFocus:1; // true if not static
|
||||
bool m_hasFocus:1; // true if == FindFocus()
|
||||
bool m_isScrolling:1; // dragging scrollbar thumb?
|
||||
bool m_clipPaintRegion:1; // TRUE after ScrollWindow()
|
||||
#ifdef __WXGTK20__
|
||||
bool m_dirtyTabOrder:1; // tab order changed, GTK focus
|
||||
// chain needs update
|
||||
#endif
|
||||
bool m_needsStyleChange:1; // May not be able to change
|
||||
// background style until OnIdle
|
||||
|
||||
// C++ has no virtual methods in the constrcutor of any class but we need
|
||||
// different methods of inserting a child window into a wxFrame,
|
||||
// wxMDIFrame, wxNotebook etc. this is the callback that will get used.
|
||||
wxInsertChildFunction m_insertCallback;
|
||||
|
||||
// implement the base class pure virtuals
|
||||
virtual void DoClientToScreen( int *x, int *y ) const;
|
||||
virtual void DoScreenToClient( int *x, int *y ) const;
|
||||
virtual void DoGetPosition( int *x, int *y ) const;
|
||||
virtual void DoGetSize( int *width, int *height ) const;
|
||||
virtual void DoGetClientSize( int *width, int *height ) const;
|
||||
virtual void DoSetSize(int x, int y,
|
||||
int width, int height,
|
||||
int sizeFlags = wxSIZE_AUTO);
|
||||
virtual void DoSetClientSize(int width, int height);
|
||||
virtual void DoMoveWindow(int x, int y, int width, int height);
|
||||
|
||||
virtual void DoCaptureMouse();
|
||||
virtual void DoReleaseMouse();
|
||||
|
||||
#if wxUSE_TOOLTIPS
|
||||
virtual void DoSetToolTip( wxToolTip *tip );
|
||||
#endif // wxUSE_TOOLTIPS
|
||||
|
||||
protected:
|
||||
// common part of all ctors (not virtual because called from ctor)
|
||||
void Init();
|
||||
|
||||
#ifdef __WXGTK20__
|
||||
virtual void DoMoveInTabOrder(wxWindow *win, MoveKind move);
|
||||
|
||||
// Copies m_children tab order to GTK focus chain:
|
||||
void RealizeTabOrder();
|
||||
#endif
|
||||
|
||||
// Called by ApplyWidgetStyle (which is called by SetFont() and
|
||||
// SetXXXColour etc to apply style changed to native widgets) to create
|
||||
// modified GTK style with non-standard attributes. If forceStyle=true,
|
||||
// creates empty GtkRcStyle if there are no modifications, otherwise
|
||||
// returns NULL in such case.
|
||||
GtkRcStyle *CreateWidgetStyle(bool forceStyle = false);
|
||||
|
||||
// Overridden in many GTK widgets who have to handle subwidgets
|
||||
virtual void ApplyWidgetStyle(bool forceStyle = false);
|
||||
|
||||
// helper function to ease native widgets wrapping, called by
|
||||
// ApplyWidgetStyle -- override this, not ApplyWidgetStyle
|
||||
virtual void DoApplyWidgetStyle(GtkRcStyle *style);
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS(wxWindowGTK)
|
||||
DECLARE_NO_COPY_CLASS(wxWindowGTK)
|
||||
};
|
||||
|
||||
extern WXDLLIMPEXP_CORE wxWindow *wxFindFocusedChild(wxWindowGTK *win);
|
||||
|
||||
#endif // __GTKWINDOWH__
|
@@ -1,238 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: include/wx/scrolwin.h
|
||||
// Purpose: wxScrolledWindow, wxScrolledControl and wxScrollHelper
|
||||
// Author: Vadim Zeitlin
|
||||
// Modified by:
|
||||
// Created: 30.08.00
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_SCROLWIN_H_BASE_
|
||||
#define _WX_SCROLWIN_H_BASE_
|
||||
|
||||
#include "wx/window.h"
|
||||
|
||||
class WXDLLEXPORT wxScrollHelperEvtHandler;
|
||||
class WXDLLEXPORT wxTimer;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxScrollHelper: this class implements the scrolling logic which is used by
|
||||
// wxScrolledWindow and wxScrolledControl. It is a mix-in: just derive from it
|
||||
// to implement scrolling in your class.
|
||||
// ----------------------------------------------------------------------------
|
||||
#if !defined(__WXGTK__) || defined(__WXUNIVERSAL__)
|
||||
|
||||
class WXDLLEXPORT wxScrollHelper
|
||||
{
|
||||
public:
|
||||
// ctor and dtor
|
||||
wxScrollHelper(wxWindow *winToScroll = (wxWindow *)NULL);
|
||||
void SetWindow(wxWindow *winToScroll);
|
||||
virtual ~wxScrollHelper();
|
||||
|
||||
// configure the scrolling
|
||||
virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
|
||||
int noUnitsX, int noUnitsY,
|
||||
int xPos = 0, int yPos = 0,
|
||||
bool noRefresh = false );
|
||||
|
||||
// scroll to the given (in logical coords) position
|
||||
virtual void Scroll(int x, int y);
|
||||
|
||||
// get/set the page size for this orientation (wxVERTICAL/wxHORIZONTAL)
|
||||
int GetScrollPageSize(int orient) const;
|
||||
void SetScrollPageSize(int orient, int pageSize);
|
||||
|
||||
// Set the x, y scrolling increments.
|
||||
void SetScrollRate( int xstep, int ystep );
|
||||
|
||||
// get the size of one logical unit in physical ones
|
||||
virtual void GetScrollPixelsPerUnit(int *pixelsPerUnitX,
|
||||
int *pixelsPerUnitY) const;
|
||||
|
||||
// Enable/disable Windows scrolling in either direction. If true, wxWidgets
|
||||
// scrolls the canvas and only a bit of the canvas is invalidated; no
|
||||
// Clear() is necessary. If false, the whole canvas is invalidated and a
|
||||
// Clear() is necessary. Disable for when the scroll increment is used to
|
||||
// actually scroll a non-constant distance
|
||||
virtual void EnableScrolling(bool x_scrolling, bool y_scrolling);
|
||||
|
||||
// Get the view start
|
||||
virtual void GetViewStart(int *x, int *y) const;
|
||||
|
||||
// Set the scale factor, used in PrepareDC
|
||||
void SetScale(double xs, double ys) { m_scaleX = xs; m_scaleY = ys; }
|
||||
double GetScaleX() const { return m_scaleX; }
|
||||
double GetScaleY() const { return m_scaleY; }
|
||||
|
||||
// translate between scrolled and unscrolled coordinates
|
||||
void CalcScrolledPosition(int x, int y, int *xx, int *yy) const
|
||||
{ DoCalcScrolledPosition(x, y, xx, yy); }
|
||||
wxPoint CalcScrolledPosition(const wxPoint& pt) const
|
||||
{
|
||||
wxPoint p2;
|
||||
DoCalcScrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
|
||||
return p2;
|
||||
}
|
||||
|
||||
void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
|
||||
{ DoCalcUnscrolledPosition(x, y, xx, yy); }
|
||||
wxPoint CalcUnscrolledPosition(const wxPoint& pt) const
|
||||
{
|
||||
wxPoint p2;
|
||||
DoCalcUnscrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
|
||||
return p2;
|
||||
}
|
||||
|
||||
virtual void DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const;
|
||||
virtual void DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
|
||||
|
||||
// Adjust the scrollbars
|
||||
virtual void AdjustScrollbars(void);
|
||||
|
||||
// Calculate scroll increment
|
||||
virtual int CalcScrollInc(wxScrollWinEvent& event);
|
||||
|
||||
// Normally the wxScrolledWindow will scroll itself, but in some rare
|
||||
// occasions you might want it to scroll [part of] another window (e.g. a
|
||||
// child of it in order to scroll only a portion the area between the
|
||||
// scrollbars (spreadsheet: only cell area will move).
|
||||
virtual void SetTargetWindow(wxWindow *target);
|
||||
virtual wxWindow *GetTargetWindow() const;
|
||||
|
||||
void SetTargetRect(const wxRect& rect) { m_rectToScroll = rect; }
|
||||
wxRect GetTargetRect() const { return m_rectToScroll; }
|
||||
|
||||
// Override this function to draw the graphic (or just process EVT_PAINT)
|
||||
virtual void OnDraw(wxDC& WXUNUSED(dc)) { }
|
||||
|
||||
// change the DC origin according to the scroll position.
|
||||
virtual void DoPrepareDC(wxDC& dc);
|
||||
|
||||
// are we generating the autoscroll events?
|
||||
bool IsAutoScrolling() const { return m_timerAutoScroll != NULL; }
|
||||
|
||||
// stop generating the scroll events when mouse is held outside the window
|
||||
void StopAutoScrolling();
|
||||
|
||||
// this method can be overridden in a derived class to forbid sending the
|
||||
// auto scroll events - note that unlike StopAutoScrolling() it doesn't
|
||||
// stop the timer, so it will be called repeatedly and will typically
|
||||
// return different values depending on the current mouse position
|
||||
//
|
||||
// the base class version just returns true
|
||||
virtual bool SendAutoScrollEvents(wxScrollWinEvent& event) const;
|
||||
|
||||
// the methods to be called from the window event handlers
|
||||
void HandleOnScroll(wxScrollWinEvent& event);
|
||||
void HandleOnSize(wxSizeEvent& event);
|
||||
void HandleOnPaint(wxPaintEvent& event);
|
||||
void HandleOnChar(wxKeyEvent& event);
|
||||
void HandleOnMouseEnter(wxMouseEvent& event);
|
||||
void HandleOnMouseLeave(wxMouseEvent& event);
|
||||
#if wxUSE_MOUSEWHEEL
|
||||
void HandleOnMouseWheel(wxMouseEvent& event);
|
||||
#endif // wxUSE_MOUSEWHEEL
|
||||
|
||||
// FIXME: this is needed for now for wxPlot compilation, should be removed
|
||||
// once it is fixed!
|
||||
void OnScroll(wxScrollWinEvent& event) { HandleOnScroll(event); }
|
||||
|
||||
protected:
|
||||
// get pointer to our scroll rect if we use it or NULL
|
||||
const wxRect *GetScrollRect() const
|
||||
{
|
||||
return m_rectToScroll.width != 0 ? &m_rectToScroll : NULL;
|
||||
}
|
||||
|
||||
// get the size of the target window
|
||||
wxSize GetTargetSize() const
|
||||
{
|
||||
return m_rectToScroll.width != 0 ? m_rectToScroll.GetSize()
|
||||
: m_targetWindow->GetClientSize();
|
||||
}
|
||||
|
||||
void GetTargetSize(int *w, int *h)
|
||||
{
|
||||
wxSize size = GetTargetSize();
|
||||
if ( w )
|
||||
*w = size.x;
|
||||
if ( h )
|
||||
*h = size.y;
|
||||
}
|
||||
|
||||
// change just the target window (unlike SetWindow which changes m_win as
|
||||
// well)
|
||||
void DoSetTargetWindow(wxWindow *target);
|
||||
|
||||
// delete the event handler we installed
|
||||
void DeleteEvtHandler();
|
||||
|
||||
double m_scaleX;
|
||||
double m_scaleY;
|
||||
|
||||
wxWindow *m_win,
|
||||
*m_targetWindow;
|
||||
|
||||
wxRect m_rectToScroll;
|
||||
|
||||
wxTimer *m_timerAutoScroll;
|
||||
|
||||
int m_xScrollPixelsPerLine;
|
||||
int m_yScrollPixelsPerLine;
|
||||
int m_xScrollPosition;
|
||||
int m_yScrollPosition;
|
||||
int m_xScrollLines;
|
||||
int m_yScrollLines;
|
||||
int m_xScrollLinesPerPage;
|
||||
int m_yScrollLinesPerPage;
|
||||
|
||||
bool m_xScrollingEnabled;
|
||||
bool m_yScrollingEnabled;
|
||||
|
||||
#if wxUSE_MOUSEWHEEL
|
||||
int m_wheelRotation;
|
||||
#endif // wxUSE_MOUSEWHEEL
|
||||
|
||||
wxScrollHelperEvtHandler *m_handler;
|
||||
|
||||
DECLARE_NO_COPY_CLASS(wxScrollHelper)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxScrolledWindow: a wxWindow which knows how to scroll
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
|
||||
#include "wx/gtk/scrolwin.h"
|
||||
#else // !wxGTK
|
||||
#include "wx/generic/scrolwin.h"
|
||||
|
||||
class WXDLLEXPORT wxScrolledWindow : public wxGenericScrolledWindow
|
||||
{
|
||||
public:
|
||||
wxScrolledWindow() { }
|
||||
wxScrolledWindow(wxWindow *parent,
|
||||
wxWindowID winid = wxID_ANY,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = wxScrolledWindowStyle,
|
||||
const wxString& name = wxPanelNameStr)
|
||||
: wxGenericScrolledWindow(parent, winid, pos, size, style, name)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxScrolledWindow)
|
||||
};
|
||||
|
||||
#define wxSCROLLED_WINDOW_IS_GENERIC 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
// _WX_SCROLWIN_H_BASE_
|
||||
|
1533
include/wx/window.h
1533
include/wx/window.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1044
src/gtk/scrolwin.cpp
1044
src/gtk/scrolwin.cpp
File diff suppressed because it is too large
Load Diff
4904
src/gtk/window.cpp
4904
src/gtk/window.cpp
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4904
src/gtk1/window.cpp
4904
src/gtk1/window.cpp
File diff suppressed because it is too large
Load Diff
617
wxPython/wx/py/CHANGES.txt
Normal file
617
wxPython/wx/py/CHANGES.txt
Normal file
@@ -0,0 +1,617 @@
|
||||
0.9.4 (1/25/2004 to //2004)
|
||||
------------------------------
|
||||
|
||||
Removed wxd decorators in favor of new SWIG-generated docstrings.
|
||||
|
||||
Removed docs tabs from crust interface:
|
||||
* wxPython Docs
|
||||
* wxSTC Docs
|
||||
|
||||
Fixed Calltip tab refresh problem on Windows.
|
||||
|
||||
shell.autoCompleteAutoHide added with default of False.
|
||||
|
||||
Changed default namespace of Shell to __main__.__dict__, instead of an
|
||||
empty dictionary.
|
||||
|
||||
|
||||
0.9.3 (9/25/2003 to 1/24/2004)
|
||||
------------------------------
|
||||
|
||||
Fun and games with dynamic renaming. Details of any other changes
|
||||
were lost in the confusion. I'll try to do better in the future.
|
||||
|
||||
|
||||
0.9.2 (5/3/2003 to 9/25/2003)
|
||||
-----------------------------
|
||||
|
||||
Changed to the new prefix-less "wx" package::
|
||||
|
||||
import wx
|
||||
|
||||
instead of::
|
||||
|
||||
from wxPython import wx
|
||||
|
||||
Fixed typo in ``PyWrap.py``::
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
|
||||
should have been::
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Added pretty-print Display tab to Crust, based on suggestion from
|
||||
Jason Whitlark.
|
||||
|
||||
Improved ``Can*`` checks in ``EditWindow``, since STC is too lenient,
|
||||
particularly when it is set to read-only but returns True for
|
||||
CanPaste() (seems like an STC bug to me)::
|
||||
|
||||
def CanCopy(self):
|
||||
"""Return True if text is selected and can be copied."""
|
||||
return self.GetSelectionStart() != self.GetSelectionEnd()
|
||||
|
||||
def CanCut(self):
|
||||
"""Return True if text is selected and can be cut."""
|
||||
return self.CanCopy() and self.CanEdit()
|
||||
|
||||
def CanEdit(self):
|
||||
"""Return True if editing should succeed."""
|
||||
return not self.GetReadOnly()
|
||||
|
||||
def CanPaste(self):
|
||||
"""Return True if pasting should succeed."""
|
||||
return stc.StyledTextCtrl.CanPaste(self) and self.CanEdit()
|
||||
|
||||
|
||||
0.9.1 (3/21/2003 to 5/2/2003)
|
||||
-----------------------------
|
||||
|
||||
PyCrust is dead! Long live Py!
|
||||
|
||||
* Renamed ``PyCrust`` package to ``py``.
|
||||
* Moved code to wxPython's CVS repository.
|
||||
|
||||
Fixed bug in ``introspect.py`` on introspecting objects occurring
|
||||
immediately after a secondary prompt, like this::
|
||||
|
||||
>>> l = [1, 2, 3]
|
||||
>>> for n in range(3):
|
||||
... l. <-- failed to popup autocomplete list
|
||||
|
||||
Added documentation files:
|
||||
|
||||
* PyManual.txt
|
||||
* wxPythonManual.txt
|
||||
* wxPythonPackage.txt
|
||||
* wxPythonExamples.txt
|
||||
|
||||
Added PyAlaMode and PyAlaCarte code editors.
|
||||
|
||||
Major refactoring to support ``editor`` and ``shell`` from the same
|
||||
base.
|
||||
|
||||
Renamed program files:
|
||||
|
||||
* ``PyCrustApp.py`` to ``PyCrust.py``
|
||||
* ``PyFillingApp.py`` to ``PyFilling.py``
|
||||
* ``PyShellApp.py`` to ``PyShell.py``
|
||||
* ``wrap.py`` to ``PyWrap.py``
|
||||
|
||||
Removed disabling of autocomplete for lists of 2000 items or more.
|
||||
The current implementation of wxSTC can now handle lists this big.
|
||||
|
||||
Improved handling of ``sys.path`` to mimic the standard Python shell.
|
||||
|
||||
|
||||
0.9 (2/27/2003 to 3/20/2003)
|
||||
----------------------------
|
||||
|
||||
Added fontIncrease, fontDecrease, fontDefault signals, receivers and
|
||||
keybindings::
|
||||
|
||||
Ctrl+] Increase font size.
|
||||
Ctrl+[ Decrease font size.
|
||||
Ctrl+= Default font size.
|
||||
|
||||
Continued enhancement of the decorator capability to provide better
|
||||
documentation and docstrings for wxPython classes and functions.
|
||||
|
||||
Introduced new tabbed interface:
|
||||
|
||||
* Namespace
|
||||
* Calltip
|
||||
* Session
|
||||
* Dispatcher
|
||||
* wxPython Docs
|
||||
* wxSTC Docs
|
||||
|
||||
``Filling.tree`` now expands tuples as well as lists. (It should have
|
||||
done this all along, I just never noticed this omission before.)
|
||||
|
||||
Added this True/False test to all modules::
|
||||
|
||||
try:
|
||||
True
|
||||
except NameError:
|
||||
True = 1==1
|
||||
False = 1==0
|
||||
|
||||
Added ``wxd`` directory with decoration classes.
|
||||
|
||||
|
||||
0.8.2 (1/5/2003 to 2/26/2003)
|
||||
-----------------------------
|
||||
|
||||
Wrapped ``sys.ps1``, ``sys.ps2``, and ``sys.ps3`` in ``str()``.
|
||||
(Thanks, Kieran Holland.)
|
||||
|
||||
Fixed minor things found by PyChecker.
|
||||
|
||||
Changed locals to use ``__main__.__dict__`` and added code to clean up
|
||||
the namespace, making it as close to the regular Python environment as
|
||||
possible. This solves the problem of pickling and unpickling
|
||||
instances of classes defined in the shell.
|
||||
|
||||
Made ``shell.PasteAndRun()`` a little more forgiving when it finds a
|
||||
ps2 prompt line with no trailing space, such when you copy code from a
|
||||
web page.
|
||||
|
||||
Improved autocomplete behavior by adding these to shell::
|
||||
|
||||
self.AutoCompSetAutoHide(False)
|
||||
self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`')
|
||||
|
||||
Added ``decor`` directory, ``decorator.py``, ``stcDecor.py``, and
|
||||
``stcConstants.py``. These all serve the purpose of adding docstrings
|
||||
to existing wxPython classes, in particular the ``wxStyledTextCtrl``.
|
||||
|
||||
Added ``wrap.py``, a command line utility for running a wxPython app
|
||||
with additional runtime-tools loaded, such as PyCrust (the only tool
|
||||
at this point).
|
||||
|
||||
Flushed the clipboard Cut/Copy operations so that selections will
|
||||
exist in the clipboard even after PyCrust has been closed.
|
||||
|
||||
Improved the suppression of docstrings for simple data types appearing
|
||||
in the namespace viewer.
|
||||
|
||||
Better handling of autocompletion with numeric types; no
|
||||
autocompletion when typing a dot after an integer. If the
|
||||
autocompletion is desired, type a space before the dot::
|
||||
|
||||
func = 3 .
|
||||
|
||||
More Filling!!! The namespace tree is now dynamically updated.
|
||||
|
||||
|
||||
0.8.1 (12/20/2002 to 12/25/2002)
|
||||
--------------------------------
|
||||
|
||||
Improved keyboard handling with Autocomplete active. You can now use
|
||||
Enter as well as Tab to select an item from the list.
|
||||
|
||||
Disabled autocomplete for lists of 2000 items or more. The current
|
||||
implementation of wxSTC can't handle lists this big.
|
||||
|
||||
Changed ``filling`` to always display docstrings for objects. This is
|
||||
useful for objects whose docstrings have been decorated, rather than
|
||||
coming directly from the source code. (Hmmm. Sounds like someone is
|
||||
doing some decorating. I wonder where that would be helpful? <wink>)
|
||||
|
||||
Fixed handling of icon. Added ``images.py`` file.
|
||||
|
||||
|
||||
0.8 (10/29/2002 to 12/16/2002)
|
||||
------------------------------
|
||||
|
||||
Added "help" to startup banner info.
|
||||
|
||||
Made all ``wx`` and ``stc`` imports explicit. No more ``import *``.
|
||||
|
||||
Replaced use of the ``wx`` module's ``true`` and ``false`` with
|
||||
Python's ``True`` and ``False``.
|
||||
|
||||
Changed ``introspect.getRoot()`` to use ``tokenize`` module. This
|
||||
does a slightly better job than the previous parsing routine and the
|
||||
code is clearer.
|
||||
|
||||
Improved handling of whitespace and empty types during introspection.
|
||||
|
||||
Fixed cut/copy clipboard problem under Linux. (Robin Dunn rocks!!!)
|
||||
|
||||
Added shell.about() which works like this::
|
||||
|
||||
>>> shell.about()
|
||||
PyCrust Version: 0.8
|
||||
Shell Revision: 1.80
|
||||
Interpreter Revision: 1.15
|
||||
Python Version: 2.2.2
|
||||
wxPython Version: 2.3.3.1
|
||||
Platform: linux2
|
||||
|
||||
Added copy plus and paste plus to shell menu.
|
||||
|
||||
Moved shell menu from ``shell.py`` to ``shellmenu.py``.
|
||||
|
||||
Added ``sys.stdin.readlines()`` support.
|
||||
|
||||
Added ``time.sleep()`` in ``readline()`` and ``OnIdle()`` event
|
||||
handler to free up the CPU.
|
||||
|
||||
|
||||
0.7.2 (2/22/2002 to 8/27/2002)
|
||||
------------------------------
|
||||
|
||||
Tweaked ``getAttributeNames()`` to pick up a few more attributes::
|
||||
|
||||
'__bases__', '__class__', '__dict__', '__name__', 'func_closure',
|
||||
'func_code', 'func_defaults', 'func_dict', 'func_doc',
|
||||
'func_globals', 'func_name'
|
||||
|
||||
Added a tests directory and unit tests.
|
||||
|
||||
Improved support for empty types in the shell: ``[]``, ``()`` and
|
||||
``{}`` as far as when call tips and autocompletion are available.
|
||||
|
||||
Added support for the other triple string - ``''''''``.
|
||||
|
||||
Refactored ``introspect.py`` to improve testability.
|
||||
|
||||
Improved call tips for unbound methods by leaving the "self"
|
||||
parameter, since unbound methods require an instance be passed.
|
||||
|
||||
Fixed call tip bug where a tip was displayed when a "(" was typed
|
||||
after an object that wasn't callable.
|
||||
|
||||
Fixed ``getAllAttributeNames`` when ``str(object)`` fails.
|
||||
|
||||
Added brace highlighting. (Thank you, Kevin Altis.)
|
||||
|
||||
Fixed problem displaying unicode objects in ``PyFilling``.
|
||||
|
||||
Changed how ``filling.py`` checks for expandable objects. Lists are
|
||||
now expandable objects.
|
||||
|
||||
Made the key handling more robust when there is an active text
|
||||
selection that includes text prior to the last primary prompt. Thanks
|
||||
to Raul Cota for pointing this out.
|
||||
|
||||
Fixed wxSTC problem with brace highlighting and non-us keyboards.
|
||||
(Thank you for the patch, Jean-Michel Fauth.)
|
||||
|
||||
Added ``busy = wxBusyCursor()`` to key points in ``shell`` and
|
||||
``filling``.
|
||||
|
||||
Added ``OnCloseWindow`` handler to ``ShellFrame`` and ``CrustFrame``.
|
||||
|
||||
Default to ``SetWrapMode(1)`` for shell and namespace viewer.
|
||||
|
||||
Added ``shell.wrap()`` and ``shell.zoom()``.
|
||||
|
||||
Added autoCompleteKeys hooks for Raul Cota.
|
||||
|
||||
Cleaned up various little key handling bugs.
|
||||
|
||||
Changed input methods to get values from shell, rather than dialog
|
||||
boxes. Renamed ``readIn`` to ``readline`` and ``readRaw`` to
|
||||
``raw_input``.
|
||||
|
||||
|
||||
0.7.1 (12/12/2001 to 2/21/2002)
|
||||
-------------------------------
|
||||
|
||||
Fixed ``OnChar()`` issues effecting European keyboards, as reported by
|
||||
Jean-Michel Fauth.
|
||||
|
||||
Fixed ``introspect.py`` issue with xmlrpc objects reported by Kevin
|
||||
Altis.
|
||||
|
||||
Fixed some introspect/PyFilling issues with regard to Python 2.2.
|
||||
|
||||
Fixed font background color as reported by Keith J. Farmer. (Thanks)
|
||||
|
||||
Fixed problem with call tips and autocompletion inside multiline
|
||||
commands as report by Kevin Altis.
|
||||
|
||||
Improved ``OnKeyDown`` handling of cut/copy/paste operations based on
|
||||
feedback from Syver Enstad. (Thanks)
|
||||
|
||||
Added a ``shell.help()`` method to display some help info.
|
||||
|
||||
Changed sort of items in the namespace viewer to case insensitive.
|
||||
|
||||
Changed ``attributes.sort(lambda x, y: cmp(x.upper(), y.upper()))`` in
|
||||
advance of an upcoming fix to an autocompletion matching bug in wxSTC.
|
||||
|
||||
Improved support for ZODB by allowing namespace drilldown into BTrees.
|
||||
|
||||
Added ``shell.PasteAndRun()`` to support pasting multiple commands into
|
||||
the shell from the clipboard. Ctrl+Shift+V or v.
|
||||
|
||||
Enter now always processes a command (or copies down a previous one.)
|
||||
To insert a line break, press Ctrl+Enter.
|
||||
|
||||
Escape key clears the current, unexecuted command.
|
||||
|
||||
History retrieval changed to replace current command. Added new keys
|
||||
to insert from history - Shift+Up and Shift+Down.
|
||||
|
||||
Better call tips on objects with ``__call__`` methods.
|
||||
|
||||
Improved call tip positioning calculation.
|
||||
|
||||
|
||||
0.7 (10/15/2001 to 12/11/2001)
|
||||
------------------------------
|
||||
|
||||
Changed how command history retrieval functions work. Added Alt-P,
|
||||
Alt-N as keybindings for Retrieve-Previous, Retrieve-Next.
|
||||
|
||||
Added full support for multi-line commands, similar to IDLE.
|
||||
|
||||
Changed ``introspect.getAttributeNames()`` to do a case insensitive
|
||||
sort.
|
||||
|
||||
Changed Cut/Copy/Paste to deal with prompts intelligently. Cut and
|
||||
Copy remove all prompts. Paste can handle prompted or not-prompted
|
||||
text.
|
||||
|
||||
Added ``CopyWithPrompts()`` method attached to Ctrl-Shift-C for those
|
||||
times when you really do want all the prompts left intact.
|
||||
|
||||
Improved handling of the shell's read-only zone.
|
||||
|
||||
Changed ``CrustFrame.__init__`` parameter spec to include all
|
||||
parameters allowed by a ``wxFrame``.
|
||||
|
||||
Changed ``FillingText`` to be read-only.
|
||||
|
||||
Renamed ``PyCrust.py`` to ``PyCrustApp.py`` to eliminate
|
||||
package/module name conflicts that kept you from doing ``from PyCrust
|
||||
import shell`` inside files located in the ``PyCrust`` directory.
|
||||
|
||||
Renamed ``PyFilling.py`` to ``PyFillingApp.py`` and ``PyShell.py`` to
|
||||
``PyShellApp.py`` to maintain consistency.
|
||||
|
||||
Removed the ``__date__`` property from all modules.
|
||||
|
||||
Fixed bug in ``introspect.getCallTip()``, reported by Kevin Altis.
|
||||
|
||||
|
||||
0.6.1 (9/19/2001 to 10/12/2001)
|
||||
-------------------------------
|
||||
|
||||
Changed ``Shell.run()`` to always position to the end of existing
|
||||
text, as suggested by Raul Cota.
|
||||
|
||||
Changed ``introspect.getAllAttributeNames()`` to break circular
|
||||
references in ``object.__class__``, which occurs in Zope/ZODB
|
||||
extension classes.
|
||||
|
||||
Changed ``filling.FillingTree.getChildren()`` to introspect extension
|
||||
classes.
|
||||
|
||||
Fixed minor bugs in ``introspect.getCallTip()`` that were interfering
|
||||
with call tips for Zope/ZODB extension class methods.
|
||||
|
||||
In preparation for wxPython 2.3.2, added code to fix a font sizing
|
||||
problem. Versions of wxPython prior to 2.3.2 had a sizing bug on Win
|
||||
platform where the font was 2 points larger than what was specified.
|
||||
|
||||
Added a hack to ``introspect.getAllAttributeNames()`` to "wake up"
|
||||
ZODB objects that are asleep - in a "ghost" state. Otherwise it
|
||||
returns incomplete info.
|
||||
|
||||
|
||||
0.6 (8/21/2001 to 9/12/2001)
|
||||
----------------------------
|
||||
|
||||
Added ``PyFilling.py`` and ``filling.py``.
|
||||
|
||||
``PyShell.py`` and ``PyFilling.py`` can now be run standalone, as well
|
||||
as ``PyCrust.py``.
|
||||
|
||||
Added ``crust.py`` and moved some code from ``PyCrust.py`` to it.
|
||||
|
||||
Added command history retrieval features submitted by Richie Hindle.
|
||||
|
||||
Changed ``shell.write()`` to replace line endings with OS-specific
|
||||
endings. Changed ``shell.py`` and ``interpreter.py`` to use
|
||||
``os.linesep`` in strings having hardcoded line endings.
|
||||
|
||||
Added ``shell.redirectStdin()``, ``shell.redirectStdout()`` and
|
||||
``shell.redirectStderr()`` to allow the surrounding app to toggle
|
||||
requests that the specified ``sys.std*`` be redirected to the shell.
|
||||
These can also be run from within the shell itself, of course.
|
||||
|
||||
The shell now adds the current working directory "." to the search
|
||||
path::
|
||||
|
||||
sys.path.insert(0, os.curdir)
|
||||
|
||||
Added support for distutils installations.
|
||||
|
||||
|
||||
0.5.4 (8/17/2001 to 8/20/2001)
|
||||
------------------------------
|
||||
|
||||
Changed default font size under Linux to::
|
||||
|
||||
'size' : 12,
|
||||
'lnsize' : 10,
|
||||
|
||||
Changed ``Shell`` to expect a parameter referencing an Interpreter
|
||||
class, rather than an intepreter instance, to facilitate subclassing
|
||||
of Interpreter, which effectively broke when the Editor class was
|
||||
eliminated.
|
||||
|
||||
Fixed ``PyCrustAlaCarte.py``, which had been broken by previous
|
||||
changes.
|
||||
|
||||
Created ``InterpreterAlaCarte`` class as an example for use in the
|
||||
demo.
|
||||
|
||||
Split ``PyCrust.py`` into ``PyCrust.py`` and ``PyShell.py`` in
|
||||
anticipation of ``PyFilling.py``.
|
||||
|
||||
|
||||
0.5.3 (8/16/2001)
|
||||
-----------------
|
||||
|
||||
Added patch to ``PyCrust.py`` to fix wxPython bug::
|
||||
|
||||
wxID_SELECTALL = NewId() # This *should* be defined by wxPython.
|
||||
|
||||
|
||||
0.5.2 (8/14/2001 to 8/15/2001)
|
||||
------------------------------
|
||||
|
||||
Shortened module names by dropping "PyCrust" as a prefix.
|
||||
|
||||
Changed ``version`` to ``VERSION`` in ``version`` module.
|
||||
|
||||
Added Options menu to PyCrust application.
|
||||
|
||||
Eliminated the Editor class (and editor module) by merging with Shell.
|
||||
This means that Shell "is a" wxStyledTextCtrl rather than "has a".
|
||||
There just wasn't enough non-gui code to justify the separation.
|
||||
Plus, Shell will be much easier for gui toolkits/designers to deal
|
||||
with now.
|
||||
|
||||
|
||||
0.5.1 (8/10/2001 to 8/14/2001)
|
||||
------------------------------
|
||||
|
||||
Added ``introspect`` module.
|
||||
|
||||
Moved some functionality from ``PyCrustInterp`` to ``introspect``.
|
||||
|
||||
Changed ``introspect.getRoot()`` to no longer remove whitespace from
|
||||
the command. This was a remnant of a previous approach that, when
|
||||
left as part of the current approach, turned out to be a really bad
|
||||
thing.
|
||||
|
||||
Changed ``introspect.getRoot()`` to allow commands of ``''``, ``""``,
|
||||
``""""""``, ``[]``, ``()``, and ``{}`` to pass through. This allows
|
||||
you to type them, followed by a dot, and get autocomplete options on
|
||||
them.
|
||||
|
||||
Changed ``introspect.getRoot()`` to identify some situations where
|
||||
strings shouldn't be considered roots. For example::
|
||||
|
||||
>>> import PyCrust # To illustrate the potential problem.
|
||||
>>> len('PyCrust.py')
|
||||
|
||||
Typing the dot at the end of "PyCrust" in the second line above should
|
||||
NOT result in an autocompletion list because "PyCrust" is part of a
|
||||
string in this context, not a reference to the PyCrust module object.
|
||||
Similar reasoning applies to call tips. For example::
|
||||
|
||||
>>> len('dir(')
|
||||
|
||||
Typing the left paren at the end of "dir" should NOT result in a call
|
||||
tip.
|
||||
|
||||
Both features now behave properly in the examples given. However,
|
||||
there is still the case where whitespace precedes the potential root
|
||||
and that is NOT handled properly. For example::
|
||||
|
||||
>>> len('this is a dir(')
|
||||
|
||||
and::
|
||||
|
||||
>>> len('This is PyCrust.py')
|
||||
|
||||
More code needs to be written to handle more complex situations.
|
||||
|
||||
Added ``locals=None`` parameter to ``Shell.__init__()``.
|
||||
|
||||
Added support for magic attribute retrieval. Users can change this
|
||||
with::
|
||||
|
||||
>>> shell.editor.autoCompleteIncludeMagic = 0
|
||||
|
||||
Added the ability to set filters on auto completion to exclude
|
||||
attributes prefixed with a single or double underscore. Users can
|
||||
exclude one or the other or both with::
|
||||
|
||||
>>> shell.editor.autoCompleteExcludeSingle = 1
|
||||
>>> shell.editor.autoCompleteExcludeDouble = 1
|
||||
|
||||
|
||||
0.5 (8/8/2001)
|
||||
--------------
|
||||
|
||||
Mostly just a final version change before creating a release.
|
||||
|
||||
|
||||
0.4 (8/4/2001 to 8/7/2001)
|
||||
--------------------------
|
||||
|
||||
Changed version/revision handling.
|
||||
|
||||
Fixed bugs.
|
||||
|
||||
|
||||
0.3 (8/2/2001 to 8/3/2001)
|
||||
--------------------------
|
||||
|
||||
Removed lots of cruft.
|
||||
|
||||
Added lots of docstrings.
|
||||
|
||||
Imported to CVS repository at SourceForge.
|
||||
|
||||
Added call tips.
|
||||
|
||||
|
||||
0.2 (7/30/2001 to 8/2/2001)
|
||||
---------------------------
|
||||
|
||||
Renamed several files.
|
||||
|
||||
Added command autocompletion.
|
||||
|
||||
Added menus to PyCrust.py: File, Edit and Help.
|
||||
|
||||
Added sample applications: ``PyCrustAlaCarte.py``,
|
||||
``PyCrustAlaMode.py``, and ``PyCrustMinimus.py``.
|
||||
|
||||
|
||||
0.1 (7/1/2001 to 7/19/2001)
|
||||
---------------------------
|
||||
|
||||
Added basic syntax coloring much like Boa.
|
||||
|
||||
Added read-only logging much like IDLE.
|
||||
|
||||
Can retrieve a previous command by putting the cursor back on that
|
||||
line and hitting enter.
|
||||
|
||||
Stdin and raw_input operate properly so you can now do ``help()`` and
|
||||
``license()`` without hanging.
|
||||
|
||||
Redefined "quit", "exit", and "close" to display a better-than-nothing
|
||||
response.
|
||||
|
||||
Home key honors the prompt.
|
||||
|
||||
Created SourceForge account, but nothing was posted.
|
||||
|
||||
|
||||
In the beginning, there was pie... (7/1/2001)
|
||||
---------------------------------------------
|
||||
|
||||
Blame it all on IDLE, Boa and PythonWin. I was using all three, got
|
||||
frustrated with their dissimilarities, and began to let everyone know
|
||||
how I felt. At the same time, Scintilla looked like an interesting
|
||||
tool to build a shell around. And while I didn't receive much in the
|
||||
way of positive feedback, let alone encouragement, I just couldn't let
|
||||
go of the idea of a Scintilla-based Python shell. Then the PythonCard
|
||||
project got to the point where they were talking about including a
|
||||
shell in their development environment. That was all the incentive I
|
||||
needed. PyCrust had to happen...
|
BIN
wxPython/wx/py/Py.ico
Normal file
BIN
wxPython/wx/py/Py.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
36
wxPython/wx/py/PyAlaCarte.py
Normal file
36
wxPython/wx/py/PyAlaCarte.py
Normal file
@@ -0,0 +1,36 @@
|
||||
"""PyAlaCarte is a simple programmer's editor."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
from wx import py
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
class App(wx.App):
|
||||
"""PyAlaCarte standalone application."""
|
||||
|
||||
def __init__(self, filename=None):
|
||||
self.filename = filename
|
||||
wx.App.__init__(self, redirect=False)
|
||||
|
||||
def OnInit(self):
|
||||
wx.InitAllImageHandlers()
|
||||
self.frame = py.editor.EditorFrame(filename=self.filename)
|
||||
self.frame.Show()
|
||||
self.SetTopWindow(self.frame)
|
||||
return True
|
||||
|
||||
def main(filename=None):
|
||||
if not filename and len(sys.argv) > 1:
|
||||
filename = sys.argv[1]
|
||||
if filename:
|
||||
filename = os.path.realpath(filename)
|
||||
app = App(filename)
|
||||
app.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
36
wxPython/wx/py/PyAlaMode.py
Normal file
36
wxPython/wx/py/PyAlaMode.py
Normal file
@@ -0,0 +1,36 @@
|
||||
"""PyAlaMode is a programmer's editor."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
from wx import py
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
class App(wx.App):
|
||||
"""PyAlaMode standalone application."""
|
||||
|
||||
def __init__(self, filename=None):
|
||||
self.filename = filename
|
||||
wx.App.__init__(self, redirect=False)
|
||||
|
||||
def OnInit(self):
|
||||
wx.InitAllImageHandlers()
|
||||
self.frame = py.editor.EditorNotebookFrame(filename=self.filename)
|
||||
self.frame.Show()
|
||||
self.SetTopWindow(self.frame)
|
||||
return True
|
||||
|
||||
def main(filename=None):
|
||||
if not filename and len(sys.argv) > 1:
|
||||
filename = sys.argv[1]
|
||||
if filename:
|
||||
filename = os.path.realpath(filename)
|
||||
app = App(filename)
|
||||
app.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
35
wxPython/wx/py/PyAlaModeTest.py
Executable file
35
wxPython/wx/py/PyAlaModeTest.py
Executable file
@@ -0,0 +1,35 @@
|
||||
"""PyAlaModeTest is a programmer's editor."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
from wx import py
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
class App(wx.App):
|
||||
"""PyAlaModeTest standalone application."""
|
||||
|
||||
def __init__(self, filename=None):
|
||||
self.filename = filename
|
||||
wx.App.__init__(self, redirect=False)
|
||||
|
||||
def OnInit(self):
|
||||
wx.InitAllImageHandlers()
|
||||
self.frame = py.editor.EditorShellNotebookFrame(filename=self.filename)
|
||||
self.frame.Show()
|
||||
self.SetTopWindow(self.frame)
|
||||
return True
|
||||
|
||||
def main(filename=None):
|
||||
app = App(filename)
|
||||
app.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
filename = None
|
||||
if len(sys.argv) > 1:
|
||||
filename = os.path.realpath(sys.argv[1])
|
||||
main(filename)
|
BIN
wxPython/wx/py/PyCrust.ico
Normal file
BIN
wxPython/wx/py/PyCrust.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
70
wxPython/wx/py/PyCrust.py
Normal file
70
wxPython/wx/py/PyCrust.py
Normal file
@@ -0,0 +1,70 @@
|
||||
"""PyCrust is a python shell and namespace browser application."""
|
||||
|
||||
# The next two lines, and the other code below that makes use of
|
||||
# ``__main__`` and ``original``, serve the purpose of cleaning up the
|
||||
# main namespace to look as much as possible like the regular Python
|
||||
# shell environment.
|
||||
import __main__
|
||||
original = __main__.__dict__.keys()
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
|
||||
class App(wx.App):
|
||||
"""PyCrust standalone application."""
|
||||
|
||||
def OnInit(self):
|
||||
import wx
|
||||
from wx import py
|
||||
wx.InitAllImageHandlers()
|
||||
self.frame = py.crust.CrustFrame()
|
||||
self.frame.SetSize((800, 600))
|
||||
self.frame.Show()
|
||||
self.SetTopWindow(self.frame)
|
||||
return True
|
||||
|
||||
'''
|
||||
The main() function needs to handle being imported, such as with the
|
||||
pycrust script that wxPython installs:
|
||||
|
||||
#!/usr/bin/env python
|
||||
|
||||
from wx.py.PyCrust import main
|
||||
main()
|
||||
'''
|
||||
|
||||
def main():
|
||||
"""The main function for the PyCrust program."""
|
||||
# Cleanup the main namespace, leaving the App class.
|
||||
import __main__
|
||||
md = __main__.__dict__
|
||||
keepers = original
|
||||
keepers.append('App')
|
||||
for key in md.keys():
|
||||
if key not in keepers:
|
||||
del md[key]
|
||||
# Create an application instance.
|
||||
app = App(0)
|
||||
# Mimic the contents of the standard Python shell's sys.path.
|
||||
import sys
|
||||
if sys.path[0]:
|
||||
sys.path[0] = ''
|
||||
# Add the application object to the sys module's namespace.
|
||||
# This allows a shell user to do:
|
||||
# >>> import sys
|
||||
# >>> sys.app.whatever
|
||||
sys.app = app
|
||||
del sys
|
||||
# Cleanup the main namespace some more.
|
||||
if md.has_key('App') and md['App'] is App:
|
||||
del md['App']
|
||||
if md.has_key('__main__') and md['__main__'] is __main__:
|
||||
del md['__main__']
|
||||
# Start the wxPython event loop.
|
||||
app.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
BIN
wxPython/wx/py/PyCrust_16.png
Normal file
BIN
wxPython/wx/py/PyCrust_16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 706 B |
BIN
wxPython/wx/py/PyCrust_32.png
Normal file
BIN
wxPython/wx/py/PyCrust_32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
35
wxPython/wx/py/PyFilling.py
Normal file
35
wxPython/wx/py/PyFilling.py
Normal file
@@ -0,0 +1,35 @@
|
||||
"""PyFilling is a python namespace inspection application."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
# We use this object to get more introspection when run standalone.
|
||||
app = None
|
||||
|
||||
import filling
|
||||
|
||||
# These are imported just to have something interesting to inspect.
|
||||
import crust
|
||||
import interpreter
|
||||
import introspect
|
||||
import pseudo
|
||||
import shell
|
||||
import sys
|
||||
import wx
|
||||
|
||||
class App(filling.App):
|
||||
def OnInit(self):
|
||||
filling.App.OnInit(self)
|
||||
self.root = self.fillingFrame.filling.tree.root
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""Create and run the application."""
|
||||
global app
|
||||
app = App(0)
|
||||
app.fillingFrame.filling.tree.Expand(app.root)
|
||||
app.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
71
wxPython/wx/py/PyShell.py
Normal file
71
wxPython/wx/py/PyShell.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""PyShell is a python shell application."""
|
||||
|
||||
# The next two lines, and the other code below that makes use of
|
||||
# ``__main__`` and ``original``, serve the purpose of cleaning up the
|
||||
# main namespace to look as much as possible like the regular Python
|
||||
# shell environment.
|
||||
import __main__
|
||||
original = __main__.__dict__.keys()
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
|
||||
class App(wx.App):
|
||||
"""PyShell standalone application."""
|
||||
|
||||
def OnInit(self):
|
||||
import wx
|
||||
from wx import py
|
||||
wx.InitAllImageHandlers()
|
||||
self.frame = py.shell.ShellFrame()
|
||||
self.frame.SetSize((750, 525))
|
||||
self.frame.Show()
|
||||
self.SetTopWindow(self.frame)
|
||||
self.frame.shell.SetFocus()
|
||||
return True
|
||||
|
||||
'''
|
||||
The main() function needs to handle being imported, such as with the
|
||||
pyshell script that wxPython installs:
|
||||
|
||||
#!/usr/bin/env python
|
||||
|
||||
from wx.py.PyShell import main
|
||||
main()
|
||||
'''
|
||||
|
||||
def main():
|
||||
"""The main function for the PyShell program."""
|
||||
# Cleanup the main namespace, leaving the App class.
|
||||
import __main__
|
||||
md = __main__.__dict__
|
||||
keepers = original
|
||||
keepers.append('App')
|
||||
for key in md.keys():
|
||||
if key not in keepers:
|
||||
del md[key]
|
||||
# Create an application instance.
|
||||
app = App(0)
|
||||
# Cleanup the main namespace some more.
|
||||
if md.has_key('App') and md['App'] is App:
|
||||
del md['App']
|
||||
if md.has_key('__main__') and md['__main__'] is __main__:
|
||||
del md['__main__']
|
||||
# Mimic the contents of the standard Python shell's sys.path.
|
||||
import sys
|
||||
if sys.path[0]:
|
||||
sys.path[0] = ''
|
||||
# Add the application object to the sys module's namespace.
|
||||
# This allows a shell user to do:
|
||||
# >>> import sys
|
||||
# >>> sys.app.whatever
|
||||
sys.app = app
|
||||
del sys
|
||||
# Start the wxPython event loop.
|
||||
app.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
48
wxPython/wx/py/PyWrap.py
Normal file
48
wxPython/wx/py/PyWrap.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""PyWrap is a command line utility that runs a wxPython program with
|
||||
additional runtime-tools, such as PyCrust."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
from wx import py
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
def wrap(app):
|
||||
wx.InitAllImageHandlers()
|
||||
frame = py.crust.CrustFrame()
|
||||
frame.SetSize((750, 525))
|
||||
frame.Show(True)
|
||||
frame.shell.interp.locals['app'] = app
|
||||
app.MainLoop()
|
||||
|
||||
def main(modulename=None):
|
||||
sys.path.insert(0, os.curdir)
|
||||
if not modulename:
|
||||
if len(sys.argv) < 2:
|
||||
print "Please specify a module name."
|
||||
raise SystemExit
|
||||
modulename = sys.argv[1]
|
||||
if modulename.endswith('.py'):
|
||||
modulename = modulename[:-3]
|
||||
module = __import__(modulename)
|
||||
# Find the App class.
|
||||
App = None
|
||||
d = module.__dict__
|
||||
for item in d.keys():
|
||||
try:
|
||||
if issubclass(d[item], wx.App):
|
||||
App = d[item]
|
||||
except (NameError, TypeError):
|
||||
pass
|
||||
if App is None:
|
||||
print "No App class was found."
|
||||
raise SystemExit
|
||||
app = App()
|
||||
wrap(app)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
83
wxPython/wx/py/README.txt
Normal file
83
wxPython/wx/py/README.txt
Normal file
@@ -0,0 +1,83 @@
|
||||
=====================================
|
||||
PyCrust - The Flakiest Python Shell
|
||||
=====================================
|
||||
|
||||
Half-baked by Patrick K. O'Brien (pobrien@orbtech.com)
|
||||
|
||||
Orbtech - "Your source for Python programming expertise."
|
||||
Sample all our half-baked Python goods at www.orbtech.com.
|
||||
|
||||
|
||||
What is PyCrust?
|
||||
----------------
|
||||
|
||||
PyCrust is an interactive Python environment written in Python.
|
||||
PyCrust components can run standalone or be integrated into other
|
||||
development environments and/or other Python applications.
|
||||
|
||||
PyCrust comes with an interactive Python shell (PyShell), an
|
||||
interactive namespace/object tree control (PyFilling) and an
|
||||
integrated, split-window combination of the two (PyCrust).
|
||||
|
||||
|
||||
What is PyCrust good for?
|
||||
-------------------------
|
||||
|
||||
Have you ever tried to bake a pie without one? Well, you shouldn't
|
||||
build a Python program without a PyCrust either.
|
||||
|
||||
|
||||
What else do I need to use PyCrust?
|
||||
-----------------------------------
|
||||
|
||||
PyCrust requires Python 2.2 or later, and wxPython 2.4 or later.
|
||||
PyCrust uses wxPython and the Scintilla wrapper (wxStyledTextCtrl).
|
||||
Python is available at http://www.python.org/. wxPython is available
|
||||
at http://www.wxpython.org/.
|
||||
|
||||
|
||||
Where can I get the latest version of PyCrust?
|
||||
----------------------------------------------
|
||||
|
||||
The latest production version ships with wxPython. The latest
|
||||
developer version is available in the wxWindows CVS at:
|
||||
http://cvs.wxwindows.org/viewcvs.cgi/
|
||||
|
||||
|
||||
Where is the PyCrust project hosted?
|
||||
------------------------------------
|
||||
|
||||
The old answer was "At SourceForge, of course." The SourceForge
|
||||
summary page is still available at:
|
||||
http://sourceforge.net/projects/pycrust/
|
||||
|
||||
The new answer is that there is no longer a need for a separate
|
||||
project. Simply install wxPython and you'll have everything you need.
|
||||
|
||||
|
||||
I found a bug in PyCrust, what do I do with it?
|
||||
-----------------------------------------------
|
||||
|
||||
You can send it to me at pobrien@orbtech.com.
|
||||
|
||||
|
||||
I want a new feature added to PyCrust. Will you do it?
|
||||
------------------------------------------------------
|
||||
|
||||
Flattery and money will get you anything. Short of that, you can send
|
||||
me a request and I'll see what I can do.
|
||||
|
||||
|
||||
Does PyCrust have a mailing list full of wonderful people?
|
||||
----------------------------------------------------------
|
||||
|
||||
As a matter of fact, we do. Join the PyCrust mailing lists at:
|
||||
http://sourceforge.net/mail/?group_id=31263
|
||||
|
||||
|
||||
What is the CVS information for this README file?
|
||||
-------------------------------------------------
|
||||
|
||||
$Date$
|
||||
$Revision$
|
||||
$Id$
|
20
wxPython/wx/py/__init__.py
Normal file
20
wxPython/wx/py/__init__.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""The py package, formerly the PyCrust package."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import buffer
|
||||
import crust
|
||||
import dispatcher
|
||||
import document
|
||||
import editor
|
||||
import editwindow
|
||||
import filling
|
||||
import frame
|
||||
import images
|
||||
import interpreter
|
||||
import introspect
|
||||
import pseudo
|
||||
import shell
|
||||
import version
|
138
wxPython/wx/py/buffer.py
Normal file
138
wxPython/wx/py/buffer.py
Normal file
@@ -0,0 +1,138 @@
|
||||
"""Buffer class."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from interpreter import Interpreter
|
||||
import imp
|
||||
import os
|
||||
import sys
|
||||
|
||||
import document
|
||||
|
||||
|
||||
class Buffer:
|
||||
"""Buffer class."""
|
||||
|
||||
id = 0
|
||||
|
||||
def __init__(self, filename=None):
|
||||
"""Create a Buffer instance."""
|
||||
Buffer.id += 1
|
||||
self.id = Buffer.id
|
||||
self.interp = Interpreter(locals={})
|
||||
self.name = ''
|
||||
self.editors = {}
|
||||
self.editor = None
|
||||
self.modules = sys.modules.keys()
|
||||
self.syspath = sys.path[:]
|
||||
while True:
|
||||
try:
|
||||
self.syspath.remove('')
|
||||
except ValueError:
|
||||
break
|
||||
while True:
|
||||
try:
|
||||
self.syspath.remove('.')
|
||||
except ValueError:
|
||||
break
|
||||
self.open(filename)
|
||||
|
||||
def addEditor(self, editor):
|
||||
"""Add an editor."""
|
||||
self.editor = editor
|
||||
self.editors[editor.id] = editor
|
||||
|
||||
def hasChanged(self):
|
||||
"""Return True if text in editor has changed since last save."""
|
||||
if self.editor:
|
||||
return self.editor.hasChanged()
|
||||
else:
|
||||
return False
|
||||
|
||||
def new(self, filepath):
|
||||
"""New empty buffer."""
|
||||
if not filepath:
|
||||
return
|
||||
if os.path.exists(filepath):
|
||||
self.confirmed = self.overwriteConfirm(filepath)
|
||||
else:
|
||||
self.confirmed = True
|
||||
|
||||
def open(self, filename):
|
||||
"""Open file into buffer."""
|
||||
self.doc = document.Document(filename)
|
||||
self.name = self.doc.filename or ('Untitled:' + str(self.id))
|
||||
self.modulename = self.doc.filebase
|
||||
# XXX This should really make sure filedir is first item in syspath.
|
||||
# XXX Or maybe this should be moved to the update namespace method.
|
||||
if self.doc.filedir and self.doc.filedir not in self.syspath:
|
||||
# To create the proper context for updateNamespace.
|
||||
self.syspath.insert(0, self.doc.filedir)
|
||||
if self.doc.filepath and os.path.exists(self.doc.filepath):
|
||||
self.confirmed = True
|
||||
if self.editor:
|
||||
text = self.doc.read()
|
||||
self.editor._setBuffer(buffer=self, text=text)
|
||||
|
||||
def overwriteConfirm(filepath):
|
||||
"""Confirm overwriting an existing file."""
|
||||
return False
|
||||
|
||||
def save(self):
|
||||
"""Save buffer."""
|
||||
filepath = self.doc.filepath
|
||||
if not filepath:
|
||||
return # XXX Get filename
|
||||
if not os.path.exists(filepath):
|
||||
self.confirmed = True
|
||||
if not self.confirmed:
|
||||
self.confirmed = self.overwriteConfirm(filepath)
|
||||
if self.confirmed:
|
||||
self.doc.write(self.editor.getText())
|
||||
if self.editor:
|
||||
self.editor.setSavePoint()
|
||||
|
||||
def saveAs(self, filename):
|
||||
"""Save buffer."""
|
||||
self.doc = document.Document(filename)
|
||||
self.name = self.doc.filename
|
||||
self.modulename = self.doc.filebase
|
||||
self.save()
|
||||
|
||||
def updateNamespace(self):
|
||||
"""Update the namespace for autocompletion and calltips.
|
||||
|
||||
Return True if updated, False if there was an error."""
|
||||
if not self.interp or not hasattr(self.editor, 'getText'):
|
||||
return False
|
||||
syspath = sys.path
|
||||
sys.path = self.syspath
|
||||
text = self.editor.getText()
|
||||
text = text.replace('\r\n', '\n')
|
||||
text = text.replace('\r', '\n')
|
||||
name = self.modulename or self.name
|
||||
module = imp.new_module(name)
|
||||
newspace = module.__dict__.copy()
|
||||
try:
|
||||
try:
|
||||
code = compile(text, name, 'exec')
|
||||
except:
|
||||
raise
|
||||
# return False
|
||||
try:
|
||||
exec code in newspace
|
||||
except:
|
||||
raise
|
||||
# return False
|
||||
else:
|
||||
# No problems, so update the namespace.
|
||||
self.interp.locals.clear()
|
||||
self.interp.locals.update(newspace)
|
||||
return True
|
||||
finally:
|
||||
sys.path = syspath
|
||||
for m in sys.modules.keys():
|
||||
if m not in self.modules:
|
||||
del sys.modules[m]
|
218
wxPython/wx/py/crust.py
Normal file
218
wxPython/wx/py/crust.py
Normal file
@@ -0,0 +1,218 @@
|
||||
"""Crust combines the shell and filling into one control."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
|
||||
import os
|
||||
import pprint
|
||||
import sys
|
||||
|
||||
import dispatcher
|
||||
import editwindow
|
||||
from filling import Filling
|
||||
import frame
|
||||
from shell import Shell
|
||||
from version import VERSION
|
||||
|
||||
|
||||
class Crust(wx.SplitterWindow):
|
||||
"""Crust based on SplitterWindow."""
|
||||
|
||||
name = 'Crust'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize, style=wx.SP_3D,
|
||||
name='Crust Window', rootObject=None, rootLabel=None,
|
||||
rootIsNamespace=True, intro='', locals=None,
|
||||
InterpClass=None, *args, **kwds):
|
||||
"""Create Crust instance."""
|
||||
wx.SplitterWindow.__init__(self, parent, id, pos, size, style, name)
|
||||
self.shell = Shell(parent=self, introText=intro,
|
||||
locals=locals, InterpClass=InterpClass,
|
||||
*args, **kwds)
|
||||
self.editor = self.shell
|
||||
if rootObject is None:
|
||||
rootObject = self.shell.interp.locals
|
||||
self.notebook = wx.Notebook(parent=self, id=-1)
|
||||
self.shell.interp.locals['notebook'] = self.notebook
|
||||
self.filling = Filling(parent=self.notebook,
|
||||
rootObject=rootObject,
|
||||
rootLabel=rootLabel,
|
||||
rootIsNamespace=rootIsNamespace)
|
||||
# Add 'filling' to the interpreter's locals.
|
||||
self.shell.interp.locals['filling'] = self.filling
|
||||
self.notebook.AddPage(page=self.filling, text='Namespace', select=True)
|
||||
self.display = Display(parent=self.notebook)
|
||||
self.notebook.AddPage(page=self.display, text='Display')
|
||||
# Add 'pp' (pretty print) to the interpreter's locals.
|
||||
self.shell.interp.locals['pp'] = self.display.setItem
|
||||
self.calltip = Calltip(parent=self.notebook)
|
||||
self.notebook.AddPage(page=self.calltip, text='Calltip')
|
||||
self.sessionlisting = SessionListing(parent=self.notebook)
|
||||
self.notebook.AddPage(page=self.sessionlisting, text='Session')
|
||||
self.dispatcherlisting = DispatcherListing(parent=self.notebook)
|
||||
self.notebook.AddPage(page=self.dispatcherlisting, text='Dispatcher')
|
||||
## from wxd import wx_
|
||||
## self.wxdocs = Filling(parent=self.notebook,
|
||||
## rootObject=wx_,
|
||||
## rootLabel='wx',
|
||||
## rootIsNamespace=False,
|
||||
## static=True)
|
||||
## self.notebook.AddPage(page=self.wxdocs, text='wxPython Docs')
|
||||
## from wxd import stc_
|
||||
## self.stcdocs = Filling(parent=self.notebook,
|
||||
## rootObject=stc_.StyledTextCtrl,
|
||||
## rootLabel='StyledTextCtrl',
|
||||
## rootIsNamespace=False,
|
||||
## static=True)
|
||||
## self.notebook.AddPage(page=self.stcdocs, text='StyledTextCtrl Docs')
|
||||
self.SplitHorizontally(self.shell, self.notebook, 300)
|
||||
self.SetMinimumPaneSize(1)
|
||||
|
||||
|
||||
class Display(editwindow.EditWindow):
|
||||
"""STC used to display an object using Pretty Print."""
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize,
|
||||
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER,
|
||||
static=False):
|
||||
"""Create Display instance."""
|
||||
editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
|
||||
# Configure various defaults and user preferences.
|
||||
self.SetReadOnly(True)
|
||||
self.SetWrapMode(False)
|
||||
if not static:
|
||||
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
|
||||
|
||||
def push(self, command, more):
|
||||
"""Receiver for Interpreter.push signal."""
|
||||
self.Refresh()
|
||||
|
||||
def Refresh(self):
|
||||
if not hasattr(self, "item"):
|
||||
return
|
||||
self.SetReadOnly(False)
|
||||
text = pprint.pformat(self.item)
|
||||
self.SetText(text)
|
||||
self.SetReadOnly(True)
|
||||
|
||||
def setItem(self, item):
|
||||
"""Set item to pretty print in the notebook Display tab."""
|
||||
self.item = item
|
||||
self.Refresh()
|
||||
|
||||
|
||||
class Calltip(wx.TextCtrl):
|
||||
"""Text control containing the most recent shell calltip."""
|
||||
|
||||
def __init__(self, parent=None, id=-1):
|
||||
style = (wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2)
|
||||
wx.TextCtrl.__init__(self, parent, id, style=style)
|
||||
self.SetBackgroundColour(wx.Colour(255, 255, 232))
|
||||
dispatcher.connect(receiver=self.display, signal='Shell.calltip')
|
||||
|
||||
def display(self, calltip):
|
||||
"""Receiver for Shell.calltip signal."""
|
||||
## self.SetValue(calltip) # Caused refresh problem on Windows.
|
||||
self.Clear()
|
||||
self.AppendText(calltip)
|
||||
|
||||
|
||||
class SessionListing(wx.TextCtrl):
|
||||
"""Text control containing all commands for session."""
|
||||
|
||||
def __init__(self, parent=None, id=-1):
|
||||
style = (wx.TE_MULTILINE | wx.TE_READONLY |
|
||||
wx.TE_RICH2 | wx.TE_DONTWRAP)
|
||||
wx.TextCtrl.__init__(self, parent, id, style=style)
|
||||
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
|
||||
|
||||
def push(self, command, more):
|
||||
"""Receiver for Interpreter.push signal."""
|
||||
if command and not more:
|
||||
self.SetInsertionPointEnd()
|
||||
start, end = self.GetSelection()
|
||||
if start != end:
|
||||
self.SetSelection(0, 0)
|
||||
self.AppendText(command + '\n')
|
||||
|
||||
|
||||
class DispatcherListing(wx.TextCtrl):
|
||||
"""Text control containing all dispatches for session."""
|
||||
|
||||
def __init__(self, parent=None, id=-1):
|
||||
style = (wx.TE_MULTILINE | wx.TE_READONLY |
|
||||
wx.TE_RICH2 | wx.TE_DONTWRAP)
|
||||
wx.TextCtrl.__init__(self, parent, id, style=style)
|
||||
dispatcher.connect(receiver=self.spy)
|
||||
|
||||
def spy(self, signal, sender):
|
||||
"""Receiver for Any signal from Any sender."""
|
||||
text = '%r from %s' % (signal, sender)
|
||||
self.SetInsertionPointEnd()
|
||||
start, end = self.GetSelection()
|
||||
if start != end:
|
||||
self.SetSelection(0, 0)
|
||||
self.AppendText(text + '\n')
|
||||
|
||||
|
||||
class CrustFrame(frame.Frame):
|
||||
"""Frame containing all the PyCrust components."""
|
||||
|
||||
name = 'CrustFrame'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyCrust',
|
||||
pos=wx.DefaultPosition, size=wx.DefaultSize,
|
||||
style=wx.DEFAULT_FRAME_STYLE,
|
||||
rootObject=None, rootLabel=None, rootIsNamespace=True,
|
||||
locals=None, InterpClass=None, *args, **kwds):
|
||||
"""Create CrustFrame instance."""
|
||||
frame.Frame.__init__(self, parent, id, title, pos, size, style)
|
||||
intro = 'PyCrust %s - The Flakiest Python Shell' % VERSION
|
||||
intro += '\nSponsored by Orbtech - '
|
||||
intro += 'Your source for Python programming expertise.'
|
||||
self.SetStatusText(intro.replace('\n', ', '))
|
||||
self.crust = Crust(parent=self, intro=intro,
|
||||
rootObject=rootObject,
|
||||
rootLabel=rootLabel,
|
||||
rootIsNamespace=rootIsNamespace,
|
||||
locals=locals,
|
||||
InterpClass=InterpClass, *args, **kwds)
|
||||
self.shell = self.crust.shell
|
||||
# Override the filling so that status messages go to the status bar.
|
||||
self.crust.filling.tree.setStatusText = self.SetStatusText
|
||||
# Override the shell so that status messages go to the status bar.
|
||||
self.shell.setStatusText = self.SetStatusText
|
||||
# Fix a problem with the sash shrinking to nothing.
|
||||
self.crust.filling.SetSashPosition(200)
|
||||
# Set focus to the shell editor.
|
||||
self.shell.SetFocus()
|
||||
|
||||
def OnClose(self, event):
|
||||
"""Event handler for closing."""
|
||||
self.crust.shell.destroy()
|
||||
self.Destroy()
|
||||
|
||||
def OnAbout(self, event):
|
||||
"""Display an About window."""
|
||||
title = 'About PyCrust'
|
||||
text = 'PyCrust %s\n\n' % VERSION + \
|
||||
'Yet another Python shell, only flakier.\n\n' + \
|
||||
'Half-baked by Patrick K. O\'Brien,\n' + \
|
||||
'the other half is still in the oven.\n\n' + \
|
||||
'Shell Revision: %s\n' % self.shell.revision + \
|
||||
'Interpreter Revision: %s\n\n' % self.shell.interp.revision + \
|
||||
'Platform: %s\n' % sys.platform + \
|
||||
'Python Version: %s\n' % sys.version.split()[0] + \
|
||||
'wxPython Version: %s\n' % wx.VERSION_STRING + \
|
||||
('\t(%s)\n' % ", ".join(wx.PlatformInfo[1:]))
|
||||
dialog = wx.MessageDialog(self, text, title,
|
||||
wx.OK | wx.ICON_INFORMATION)
|
||||
dialog.ShowModal()
|
||||
dialog.Destroy()
|
260
wxPython/wx/py/dispatcher.py
Normal file
260
wxPython/wx/py/dispatcher.py
Normal file
@@ -0,0 +1,260 @@
|
||||
"""Provides global signal dispatching services."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import exceptions
|
||||
import types
|
||||
import weakref
|
||||
|
||||
|
||||
class DispatcherError(exceptions.Exception):
|
||||
def __init__(self, args=None):
|
||||
self.args = args
|
||||
|
||||
|
||||
class Parameter:
|
||||
"""Used to represent default parameter values."""
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
class Any(Parameter): pass
|
||||
Any = Any()
|
||||
|
||||
class Anonymous(Parameter): pass
|
||||
Anonymous = Anonymous()
|
||||
|
||||
|
||||
connections = {}
|
||||
senders = {}
|
||||
_boundMethods = weakref.WeakKeyDictionary()
|
||||
|
||||
|
||||
def connect(receiver, signal=Any, sender=Any, weak=True):
|
||||
"""Connect receiver to sender for signal.
|
||||
|
||||
If sender is Any, receiver will receive signal from any sender.
|
||||
If signal is Any, receiver will receive any signal from sender.
|
||||
If sender is None, receiver will receive signal from Anonymous.
|
||||
If signal is Any and sender is None, receiver will receive any
|
||||
signal from Anonymous.
|
||||
If signal is Any and sender is Any, receiver will receive any
|
||||
signal from any sender.
|
||||
If weak is true, weak references will be used."""
|
||||
if signal is None:
|
||||
raise DispatcherError, 'signal cannot be None'
|
||||
if weak:
|
||||
receiver = safeRef(receiver)
|
||||
senderkey = id(sender)
|
||||
signals = {}
|
||||
if connections.has_key(senderkey):
|
||||
signals = connections[senderkey]
|
||||
else:
|
||||
connections[senderkey] = signals
|
||||
# Keep track of senders for cleanup.
|
||||
if sender not in (None, Any):
|
||||
def remove(object, senderkey=senderkey):
|
||||
_removeSender(senderkey=senderkey)
|
||||
# Skip objects that can not be weakly referenced, which means
|
||||
# they won't be automatically cleaned up, but that's too bad.
|
||||
try:
|
||||
weakSender = weakref.ref(sender, remove)
|
||||
senders[senderkey] = weakSender
|
||||
except:
|
||||
pass
|
||||
receivers = []
|
||||
if signals.has_key(signal):
|
||||
receivers = signals[signal]
|
||||
else:
|
||||
signals[signal] = receivers
|
||||
try:
|
||||
receivers.remove(receiver)
|
||||
except ValueError:
|
||||
pass
|
||||
receivers.append(receiver)
|
||||
|
||||
def disconnect(receiver, signal=Any, sender=Any, weak=True):
|
||||
"""Disconnect receiver from sender for signal.
|
||||
|
||||
Disconnecting is not required. The use of disconnect is the same as for
|
||||
connect, only in reverse. Think of it as undoing a previous connection."""
|
||||
if signal is None:
|
||||
raise DispatcherError, 'signal cannot be None'
|
||||
if weak:
|
||||
receiver = safeRef(receiver)
|
||||
senderkey = id(sender)
|
||||
try:
|
||||
receivers = connections[senderkey][signal]
|
||||
except KeyError:
|
||||
raise DispatcherError, \
|
||||
'No receivers for signal %r from sender %s' % (signal, sender)
|
||||
try:
|
||||
receivers.remove(receiver)
|
||||
except ValueError:
|
||||
raise DispatcherError, \
|
||||
'No connection to receiver %s for signal %r from sender %s' % \
|
||||
(receiver, signal, sender)
|
||||
_cleanupConnections(senderkey, signal)
|
||||
|
||||
def send(signal, sender=Anonymous, **kwds):
|
||||
"""Send signal from sender to all connected receivers.
|
||||
|
||||
Return a list of tuple pairs [(receiver, response), ... ].
|
||||
If sender is not specified, signal is sent anonymously."""
|
||||
senderkey = id(sender)
|
||||
anykey = id(Any)
|
||||
# Get receivers that receive *this* signal from *this* sender.
|
||||
receivers = []
|
||||
try:
|
||||
receivers.extend(connections[senderkey][signal])
|
||||
except KeyError:
|
||||
pass
|
||||
# Add receivers that receive *any* signal from *this* sender.
|
||||
anyreceivers = []
|
||||
try:
|
||||
anyreceivers = connections[senderkey][Any]
|
||||
except KeyError:
|
||||
pass
|
||||
for receiver in anyreceivers:
|
||||
if receivers.count(receiver) == 0:
|
||||
receivers.append(receiver)
|
||||
# Add receivers that receive *this* signal from *any* sender.
|
||||
anyreceivers = []
|
||||
try:
|
||||
anyreceivers = connections[anykey][signal]
|
||||
except KeyError:
|
||||
pass
|
||||
for receiver in anyreceivers:
|
||||
if receivers.count(receiver) == 0:
|
||||
receivers.append(receiver)
|
||||
# Add receivers that receive *any* signal from *any* sender.
|
||||
anyreceivers = []
|
||||
try:
|
||||
anyreceivers = connections[anykey][Any]
|
||||
except KeyError:
|
||||
pass
|
||||
for receiver in anyreceivers:
|
||||
if receivers.count(receiver) == 0:
|
||||
receivers.append(receiver)
|
||||
# Call each receiver with whatever arguments it can accept.
|
||||
# Return a list of tuple pairs [(receiver, response), ... ].
|
||||
responses = []
|
||||
for receiver in receivers:
|
||||
if type(receiver) is weakref.ReferenceType \
|
||||
or isinstance(receiver, BoundMethodWeakref):
|
||||
# Dereference the weak reference.
|
||||
receiver = receiver()
|
||||
if receiver is None:
|
||||
# This receiver is dead, so skip it.
|
||||
continue
|
||||
response = _call(receiver, signal=signal, sender=sender, **kwds)
|
||||
responses += [(receiver, response)]
|
||||
return responses
|
||||
|
||||
def _call(receiver, **kwds):
|
||||
"""Call receiver with only arguments it can accept."""
|
||||
## if type(receiver) is types.InstanceType:
|
||||
if hasattr(receiver, '__call__') and \
|
||||
(hasattr(receiver.__call__, 'im_func') or hasattr(receiver.__call__, 'im_code')):
|
||||
# receiver is a class instance; assume it is callable.
|
||||
# Reassign receiver to the actual method that will be called.
|
||||
receiver = receiver.__call__
|
||||
if hasattr(receiver, 'im_func'):
|
||||
# receiver is a method. Drop the first argument, usually 'self'.
|
||||
fc = receiver.im_func.func_code
|
||||
acceptable = fc.co_varnames[1:fc.co_argcount]
|
||||
elif hasattr(receiver, 'func_code'):
|
||||
# receiver is a function.
|
||||
fc = receiver.func_code
|
||||
acceptable = fc.co_varnames[0:fc.co_argcount]
|
||||
else:
|
||||
raise DispatcherError, 'Unknown receiver %s of type %s' % (receiver, type(receiver))
|
||||
if not (fc.co_flags & 8):
|
||||
# fc does not have a **kwds type parameter, therefore
|
||||
# remove unacceptable arguments.
|
||||
for arg in kwds.keys():
|
||||
if arg not in acceptable:
|
||||
del kwds[arg]
|
||||
return receiver(**kwds)
|
||||
|
||||
|
||||
def safeRef(object):
|
||||
"""Return a *safe* weak reference to a callable object."""
|
||||
if hasattr(object, 'im_self'):
|
||||
if object.im_self is not None:
|
||||
# Turn a bound method into a BoundMethodWeakref instance.
|
||||
# Keep track of these instances for lookup by disconnect().
|
||||
selfkey = object.im_self
|
||||
funckey = object.im_func
|
||||
if not _boundMethods.has_key(selfkey):
|
||||
_boundMethods[selfkey] = weakref.WeakKeyDictionary()
|
||||
if not _boundMethods[selfkey].has_key(funckey):
|
||||
_boundMethods[selfkey][funckey] = \
|
||||
BoundMethodWeakref(boundMethod=object)
|
||||
return _boundMethods[selfkey][funckey]
|
||||
return weakref.ref(object, _removeReceiver)
|
||||
|
||||
|
||||
class BoundMethodWeakref:
|
||||
"""BoundMethodWeakref class."""
|
||||
|
||||
def __init__(self, boundMethod):
|
||||
"""Return a weak-reference-like instance for a bound method."""
|
||||
self.isDead = 0
|
||||
def remove(object, self=self):
|
||||
"""Set self.isDead to true when method or instance is destroyed."""
|
||||
self.isDead = 1
|
||||
_removeReceiver(receiver=self)
|
||||
self.weakSelf = weakref.ref(boundMethod.im_self, remove)
|
||||
self.weakFunc = weakref.ref(boundMethod.im_func, remove)
|
||||
|
||||
def __repr__(self):
|
||||
"""Return the closest representation."""
|
||||
return '<bound method weakref for %s.%s>' % (self.weakSelf, self.weakFunc)
|
||||
|
||||
def __call__(self):
|
||||
"""Return a strong reference to the bound method."""
|
||||
if self.isDead:
|
||||
return None
|
||||
else:
|
||||
object = self.weakSelf()
|
||||
method = self.weakFunc().__name__
|
||||
try: # wxPython hack to handle wxDead objects.
|
||||
return getattr(object, method)
|
||||
except AttributeError:
|
||||
## _removeReceiver(receiver=self)
|
||||
return None
|
||||
|
||||
|
||||
def _removeReceiver(receiver):
|
||||
"""Remove receiver from connections."""
|
||||
for senderkey in connections.keys():
|
||||
for signal in connections[senderkey].keys():
|
||||
receivers = connections[senderkey][signal]
|
||||
try:
|
||||
receivers.remove(receiver)
|
||||
except:
|
||||
pass
|
||||
_cleanupConnections(senderkey, signal)
|
||||
|
||||
def _cleanupConnections(senderkey, signal):
|
||||
"""Delete any empty signals for senderkey. Delete senderkey if empty."""
|
||||
receivers = connections[senderkey][signal]
|
||||
if not receivers:
|
||||
# No more connected receivers. Therefore, remove the signal.
|
||||
signals = connections[senderkey]
|
||||
del signals[signal]
|
||||
if not signals:
|
||||
# No more signal connections. Therefore, remove the sender.
|
||||
_removeSender(senderkey)
|
||||
|
||||
def _removeSender(senderkey):
|
||||
"""Remove senderkey from connections."""
|
||||
del connections[senderkey]
|
||||
# Senderkey will only be in senders dictionary if sender
|
||||
# could be weakly referenced.
|
||||
try:
|
||||
del senders[senderkey]
|
||||
except:
|
||||
pass
|
43
wxPython/wx/py/document.py
Normal file
43
wxPython/wx/py/document.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""Document class."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class Document:
|
||||
"""Document class."""
|
||||
|
||||
def __init__(self, filename=None):
|
||||
"""Create a Document instance."""
|
||||
self.filename = filename
|
||||
self.filepath = None
|
||||
self.filedir = None
|
||||
self.filebase = None
|
||||
self.fileext = None
|
||||
if self.filename:
|
||||
self.filepath = os.path.realpath(self.filename)
|
||||
self.filedir, self.filename = os.path.split(self.filepath)
|
||||
self.filebase, self.fileext = os.path.splitext(self.filename)
|
||||
|
||||
def read(self):
|
||||
"""Return contents of file."""
|
||||
if self.filepath and os.path.exists(self.filepath):
|
||||
f = file(self.filepath, 'rb')
|
||||
try:
|
||||
return f.read()
|
||||
finally:
|
||||
f.close()
|
||||
else:
|
||||
return ''
|
||||
|
||||
def write(self, text):
|
||||
"""Write text to file."""
|
||||
try:
|
||||
f = file(self.filepath, 'wb')
|
||||
f.write(text)
|
||||
finally:
|
||||
if f:
|
||||
f.close()
|
843
wxPython/wx/py/editor.py
Normal file
843
wxPython/wx/py/editor.py
Normal file
@@ -0,0 +1,843 @@
|
||||
"""PyAlaCarte and PyAlaMode editors."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
|
||||
from buffer import Buffer
|
||||
import crust
|
||||
import dispatcher
|
||||
import editwindow
|
||||
import frame
|
||||
from shell import Shell
|
||||
import version
|
||||
|
||||
|
||||
class EditorFrame(frame.Frame):
|
||||
"""Frame containing one editor."""
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyAlaCarte',
|
||||
pos=wx.DefaultPosition, size=(800, 600),
|
||||
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE,
|
||||
filename=None):
|
||||
"""Create EditorFrame instance."""
|
||||
frame.Frame.__init__(self, parent, id, title, pos, size, style)
|
||||
self.buffers = {}
|
||||
self.buffer = None # Current buffer.
|
||||
self.editor = None
|
||||
self._defaultText = title + ' - the tastiest Python editor.'
|
||||
self._statusText = self._defaultText
|
||||
self.SetStatusText(self._statusText)
|
||||
wx.EVT_IDLE(self, self.OnIdle)
|
||||
self._setup()
|
||||
if filename:
|
||||
self.bufferCreate(filename)
|
||||
|
||||
def _setup(self):
|
||||
"""Setup prior to first buffer creation.
|
||||
|
||||
Useful for subclasses."""
|
||||
pass
|
||||
|
||||
def setEditor(self, editor):
|
||||
self.editor = editor
|
||||
self.buffer = self.editor.buffer
|
||||
self.buffers[self.buffer.id] = self.buffer
|
||||
|
||||
def OnAbout(self, event):
|
||||
"""Display an About window."""
|
||||
title = 'About PyAlaCarte'
|
||||
text = 'Another fine, flaky program.'
|
||||
dialog = wx.MessageDialog(self, text, title,
|
||||
wx.OK | wx.ICON_INFORMATION)
|
||||
dialog.ShowModal()
|
||||
dialog.Destroy()
|
||||
|
||||
def OnClose(self, event):
|
||||
"""Event handler for closing."""
|
||||
for buffer in self.buffers.values():
|
||||
self.buffer = buffer
|
||||
if buffer.hasChanged():
|
||||
cancel = self.bufferSuggestSave()
|
||||
if cancel and event.CanVeto():
|
||||
event.Veto()
|
||||
return
|
||||
self.Destroy()
|
||||
|
||||
def OnIdle(self, event):
|
||||
"""Event handler for idle time."""
|
||||
self._updateStatus()
|
||||
if hasattr(self, 'notebook'):
|
||||
self._updateTabText()
|
||||
self._updateTitle()
|
||||
event.Skip()
|
||||
|
||||
def _updateStatus(self):
|
||||
"""Show current status information."""
|
||||
if self.editor and hasattr(self.editor, 'getStatus'):
|
||||
status = self.editor.getStatus()
|
||||
text = 'File: %s | Line: %d | Column: %d' % status
|
||||
else:
|
||||
text = self._defaultText
|
||||
if text != self._statusText:
|
||||
self.SetStatusText(text)
|
||||
self._statusText = text
|
||||
|
||||
def _updateTabText(self):
|
||||
"""Show current buffer information on notebook tab."""
|
||||
## suffix = ' **'
|
||||
## notebook = self.notebook
|
||||
## selection = notebook.GetSelection()
|
||||
## if selection == -1:
|
||||
## return
|
||||
## text = notebook.GetPageText(selection)
|
||||
## window = notebook.GetPage(selection)
|
||||
## if window.editor and window.editor.buffer.hasChanged():
|
||||
## if text.endswith(suffix):
|
||||
## pass
|
||||
## else:
|
||||
## notebook.SetPageText(selection, text + suffix)
|
||||
## else:
|
||||
## if text.endswith(suffix):
|
||||
## notebook.SetPageText(selection, text[:len(suffix)])
|
||||
|
||||
def _updateTitle(self):
|
||||
"""Show current title information."""
|
||||
title = self.GetTitle()
|
||||
if self.bufferHasChanged():
|
||||
if title.startswith('* '):
|
||||
pass
|
||||
else:
|
||||
self.SetTitle('* ' + title)
|
||||
else:
|
||||
if title.startswith('* '):
|
||||
self.SetTitle(title[2:])
|
||||
|
||||
def hasBuffer(self):
|
||||
"""Return True if there is a current buffer."""
|
||||
if self.buffer:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def bufferClose(self):
|
||||
"""Close buffer."""
|
||||
if self.bufferHasChanged():
|
||||
cancel = self.bufferSuggestSave()
|
||||
if cancel:
|
||||
return cancel
|
||||
self.bufferDestroy()
|
||||
cancel = False
|
||||
return cancel
|
||||
|
||||
def bufferCreate(self, filename=None):
|
||||
"""Create new buffer."""
|
||||
self.bufferDestroy()
|
||||
buffer = Buffer()
|
||||
self.panel = panel = wx.Panel(parent=self, id=-1)
|
||||
wx.EVT_ERASE_BACKGROUND(panel, lambda x: x)
|
||||
editor = Editor(parent=panel)
|
||||
panel.editor = editor
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(editor.window, 1, wx.EXPAND)
|
||||
panel.SetSizer(sizer)
|
||||
panel.SetAutoLayout(True)
|
||||
sizer.Layout()
|
||||
buffer.addEditor(editor)
|
||||
buffer.open(filename)
|
||||
self.setEditor(editor)
|
||||
self.editor.setFocus()
|
||||
self.SendSizeEvent()
|
||||
|
||||
|
||||
def bufferDestroy(self):
|
||||
"""Destroy the current buffer."""
|
||||
if self.buffer:
|
||||
for editor in self.buffer.editors.values():
|
||||
editor.destroy()
|
||||
self.editor = None
|
||||
del self.buffers[self.buffer.id]
|
||||
self.buffer = None
|
||||
self.panel.Destroy()
|
||||
|
||||
|
||||
def bufferHasChanged(self):
|
||||
"""Return True if buffer has changed since last save."""
|
||||
if self.buffer:
|
||||
return self.buffer.hasChanged()
|
||||
else:
|
||||
return False
|
||||
|
||||
def bufferNew(self):
|
||||
"""Create new buffer."""
|
||||
if self.bufferHasChanged():
|
||||
cancel = self.bufferSuggestSave()
|
||||
if cancel:
|
||||
return cancel
|
||||
self.bufferCreate()
|
||||
cancel = False
|
||||
return cancel
|
||||
|
||||
def bufferOpen(self):
|
||||
"""Open file in buffer."""
|
||||
if self.bufferHasChanged():
|
||||
cancel = self.bufferSuggestSave()
|
||||
if cancel:
|
||||
return cancel
|
||||
filedir = ''
|
||||
if self.buffer and self.buffer.doc.filedir:
|
||||
filedir = self.buffer.doc.filedir
|
||||
result = openSingle(directory=filedir)
|
||||
if result.path:
|
||||
self.bufferCreate(result.path)
|
||||
cancel = False
|
||||
return cancel
|
||||
|
||||
## def bufferPrint(self):
|
||||
## """Print buffer."""
|
||||
## pass
|
||||
|
||||
## def bufferRevert(self):
|
||||
## """Revert buffer to version of file on disk."""
|
||||
## pass
|
||||
|
||||
def bufferSave(self):
|
||||
"""Save buffer to its file."""
|
||||
if self.buffer.doc.filepath:
|
||||
self.buffer.save()
|
||||
cancel = False
|
||||
else:
|
||||
cancel = self.bufferSaveAs()
|
||||
return cancel
|
||||
|
||||
def bufferSaveAs(self):
|
||||
"""Save buffer to a new filename."""
|
||||
if self.bufferHasChanged() and self.buffer.doc.filepath:
|
||||
cancel = self.bufferSuggestSave()
|
||||
if cancel:
|
||||
return cancel
|
||||
filedir = ''
|
||||
if self.buffer and self.buffer.doc.filedir:
|
||||
filedir = self.buffer.doc.filedir
|
||||
result = saveSingle(directory=filedir)
|
||||
if result.path:
|
||||
self.buffer.saveAs(result.path)
|
||||
cancel = False
|
||||
else:
|
||||
cancel = True
|
||||
return cancel
|
||||
|
||||
def bufferSuggestSave(self):
|
||||
"""Suggest saving changes. Return True if user selected Cancel."""
|
||||
result = messageDialog(parent=None,
|
||||
message='%s has changed.\n'
|
||||
'Would you like to save it first'
|
||||
'?' % self.buffer.name,
|
||||
title='Save current file?')
|
||||
if result.positive:
|
||||
cancel = self.bufferSave()
|
||||
else:
|
||||
cancel = result.text == 'Cancel'
|
||||
return cancel
|
||||
|
||||
def updateNamespace(self):
|
||||
"""Update the buffer namespace for autocompletion and calltips."""
|
||||
if self.buffer.updateNamespace():
|
||||
self.SetStatusText('Namespace updated')
|
||||
else:
|
||||
self.SetStatusText('Error executing, unable to update namespace')
|
||||
|
||||
|
||||
class EditorNotebookFrame(EditorFrame):
|
||||
"""Frame containing one or more editors in a notebook."""
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyAlaMode',
|
||||
pos=wx.DefaultPosition, size=(800, 600),
|
||||
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE,
|
||||
filename=None):
|
||||
"""Create EditorNotebookFrame instance."""
|
||||
self.notebook = None
|
||||
EditorFrame.__init__(self, parent, id, title, pos,
|
||||
size, style, filename)
|
||||
if self.notebook:
|
||||
dispatcher.connect(receiver=self._editorChange,
|
||||
signal='EditorChange', sender=self.notebook)
|
||||
|
||||
def _setup(self):
|
||||
"""Setup prior to first buffer creation.
|
||||
|
||||
Called automatically by base class during init."""
|
||||
self.notebook = EditorNotebook(parent=self)
|
||||
intro = 'Py %s' % version.VERSION
|
||||
import imp
|
||||
module = imp.new_module('__main__')
|
||||
import __builtin__
|
||||
module.__dict__['__builtins__'] = __builtin__
|
||||
namespace = module.__dict__.copy()
|
||||
self.crust = crust.Crust(parent=self.notebook, intro=intro, locals=namespace)
|
||||
self.shell = self.crust.shell
|
||||
# Override the filling so that status messages go to the status bar.
|
||||
self.crust.filling.tree.setStatusText = self.SetStatusText
|
||||
# Override the shell so that status messages go to the status bar.
|
||||
self.shell.setStatusText = self.SetStatusText
|
||||
# Fix a problem with the sash shrinking to nothing.
|
||||
self.crust.filling.SetSashPosition(200)
|
||||
self.notebook.AddPage(page=self.crust, text='*Shell*', select=True)
|
||||
self.setEditor(self.crust.editor)
|
||||
self.crust.editor.SetFocus()
|
||||
|
||||
def _editorChange(self, editor):
|
||||
"""Editor change signal receiver."""
|
||||
self.setEditor(editor)
|
||||
|
||||
def OnAbout(self, event):
|
||||
"""Display an About window."""
|
||||
title = 'About PyAlaMode'
|
||||
text = 'Another fine, flaky program.'
|
||||
dialog = wx.MessageDialog(self, text, title,
|
||||
wx.OK | wx.ICON_INFORMATION)
|
||||
dialog.ShowModal()
|
||||
dialog.Destroy()
|
||||
|
||||
def _updateTitle(self):
|
||||
"""Show current title information."""
|
||||
pass
|
||||
## title = self.GetTitle()
|
||||
## if self.bufferHasChanged():
|
||||
## if title.startswith('* '):
|
||||
## pass
|
||||
## else:
|
||||
## self.SetTitle('* ' + title)
|
||||
## else:
|
||||
## if title.startswith('* '):
|
||||
## self.SetTitle(title[2:])
|
||||
|
||||
def bufferCreate(self, filename=None):
|
||||
"""Create new buffer."""
|
||||
buffer = Buffer()
|
||||
panel = wx.Panel(parent=self.notebook, id=-1)
|
||||
wx.EVT_ERASE_BACKGROUND(panel, lambda x: x)
|
||||
editor = Editor(parent=panel)
|
||||
panel.editor = editor
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(editor.window, 1, wx.EXPAND)
|
||||
panel.SetSizer(sizer)
|
||||
panel.SetAutoLayout(True)
|
||||
sizer.Layout()
|
||||
buffer.addEditor(editor)
|
||||
buffer.open(filename)
|
||||
self.setEditor(editor)
|
||||
self.notebook.AddPage(page=panel, text=self.buffer.name, select=True)
|
||||
self.editor.setFocus()
|
||||
|
||||
def bufferDestroy(self):
|
||||
"""Destroy the current buffer."""
|
||||
selection = self.notebook.GetSelection()
|
||||
## print "Destroy Selection:", selection
|
||||
if selection > 0: # Don't destroy the PyCrust tab.
|
||||
if self.buffer:
|
||||
del self.buffers[self.buffer.id]
|
||||
self.buffer = None # Do this before DeletePage().
|
||||
self.notebook.DeletePage(selection)
|
||||
|
||||
def bufferNew(self):
|
||||
"""Create new buffer."""
|
||||
self.bufferCreate()
|
||||
cancel = False
|
||||
return cancel
|
||||
|
||||
def bufferOpen(self):
|
||||
"""Open file in buffer."""
|
||||
filedir = ''
|
||||
if self.buffer and self.buffer.doc.filedir:
|
||||
filedir = self.buffer.doc.filedir
|
||||
result = openMultiple(directory=filedir)
|
||||
for path in result.paths:
|
||||
self.bufferCreate(path)
|
||||
cancel = False
|
||||
return cancel
|
||||
|
||||
|
||||
class EditorNotebook(wx.Notebook):
|
||||
"""A notebook containing a page for each editor."""
|
||||
|
||||
def __init__(self, parent):
|
||||
"""Create EditorNotebook instance."""
|
||||
wx.Notebook.__init__(self, parent, id=-1, style=wx.CLIP_CHILDREN)
|
||||
wx.EVT_NOTEBOOK_PAGE_CHANGING(self, self.GetId(),
|
||||
self.OnPageChanging)
|
||||
wx.EVT_NOTEBOOK_PAGE_CHANGED(self, self.GetId(),
|
||||
self.OnPageChanged)
|
||||
wx.EVT_IDLE(self, self.OnIdle)
|
||||
|
||||
def OnIdle(self, event):
|
||||
"""Event handler for idle time."""
|
||||
self._updateTabText()
|
||||
event.Skip()
|
||||
|
||||
def _updateTabText(self):
|
||||
"""Show current buffer display name on all but first tab."""
|
||||
size = 3
|
||||
changed = ' **'
|
||||
unchanged = ' --'
|
||||
selection = self.GetSelection()
|
||||
if selection < 1:
|
||||
return
|
||||
text = self.GetPageText(selection)
|
||||
window = self.GetPage(selection)
|
||||
if not window.editor:
|
||||
return
|
||||
if text.endswith(changed) or text.endswith(unchanged):
|
||||
name = text[:-size]
|
||||
else:
|
||||
name = text
|
||||
if name != window.editor.buffer.name:
|
||||
text = window.editor.buffer.name
|
||||
if window.editor.buffer.hasChanged():
|
||||
if text.endswith(changed):
|
||||
text = None
|
||||
elif text.endswith(unchanged):
|
||||
text = text[:-size] + changed
|
||||
else:
|
||||
text += changed
|
||||
else:
|
||||
if text.endswith(changed):
|
||||
text = text[:-size] + unchanged
|
||||
elif text.endswith(unchanged):
|
||||
text = None
|
||||
else:
|
||||
text += unchanged
|
||||
if text is not None:
|
||||
self.SetPageText(selection, text)
|
||||
self.Refresh() # Needed on Win98.
|
||||
|
||||
def OnPageChanging(self, event):
|
||||
"""Page changing event handler."""
|
||||
event.Skip()
|
||||
|
||||
def OnPageChanged(self, event):
|
||||
"""Page changed event handler."""
|
||||
new = event.GetSelection()
|
||||
window = self.GetPage(new)
|
||||
dispatcher.send(signal='EditorChange', sender=self,
|
||||
editor=window.editor)
|
||||
window.SetFocus()
|
||||
event.Skip()
|
||||
|
||||
|
||||
class EditorShellNotebookFrame(EditorNotebookFrame):
|
||||
"""Frame containing a notebook containing EditorShellNotebooks."""
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyAlaModeTest',
|
||||
pos=wx.DefaultPosition, size=(600, 400),
|
||||
style=wx.DEFAULT_FRAME_STYLE,
|
||||
filename=None, singlefile=False):
|
||||
"""Create EditorShellNotebookFrame instance."""
|
||||
self._singlefile = singlefile
|
||||
EditorNotebookFrame.__init__(self, parent, id, title, pos,
|
||||
size, style, filename)
|
||||
|
||||
def _setup(self):
|
||||
"""Setup prior to first buffer creation.
|
||||
|
||||
Called automatically by base class during init."""
|
||||
if not self._singlefile:
|
||||
self.notebook = EditorNotebook(parent=self)
|
||||
|
||||
def OnAbout(self, event):
|
||||
"""Display an About window."""
|
||||
title = 'About PyAlaModePlus'
|
||||
text = 'Another fine, flaky program.'
|
||||
dialog = wx.MessageDialog(self, text, title,
|
||||
wx.OK | wx.ICON_INFORMATION)
|
||||
dialog.ShowModal()
|
||||
dialog.Destroy()
|
||||
|
||||
def bufferCreate(self, filename=None):
|
||||
"""Create new buffer."""
|
||||
if self._singlefile:
|
||||
self.bufferDestroy()
|
||||
notebook = EditorShellNotebook(parent=self,
|
||||
filename=filename)
|
||||
self.notebook = notebook
|
||||
else:
|
||||
notebook = EditorShellNotebook(parent=self.notebook,
|
||||
filename=filename)
|
||||
self.setEditor(notebook.editor)
|
||||
if not self._singlefile:
|
||||
self.notebook.AddPage(page=notebook, text=self.buffer.name,
|
||||
select=True)
|
||||
self.editor.setFocus()
|
||||
|
||||
def bufferDestroy(self):
|
||||
"""Destroy the current buffer."""
|
||||
if self.buffer:
|
||||
self.editor = None
|
||||
del self.buffers[self.buffer.id]
|
||||
self.buffer = None # Do this before DeletePage().
|
||||
if self._singlefile:
|
||||
self.notebook.Destroy()
|
||||
self.notebook = None
|
||||
else:
|
||||
selection = self.notebook.GetSelection()
|
||||
## print "Destroy Selection:", selection
|
||||
self.notebook.DeletePage(selection)
|
||||
|
||||
def bufferNew(self):
|
||||
"""Create new buffer."""
|
||||
if self._singlefile and self.bufferHasChanged():
|
||||
cancel = self.bufferSuggestSave()
|
||||
if cancel:
|
||||
return cancel
|
||||
self.bufferCreate()
|
||||
cancel = False
|
||||
return cancel
|
||||
|
||||
def bufferOpen(self):
|
||||
"""Open file in buffer."""
|
||||
if self._singlefile and self.bufferHasChanged():
|
||||
cancel = self.bufferSuggestSave()
|
||||
if cancel:
|
||||
return cancel
|
||||
filedir = ''
|
||||
if self.buffer and self.buffer.doc.filedir:
|
||||
filedir = self.buffer.doc.filedir
|
||||
if self._singlefile:
|
||||
result = openSingle(directory=filedir)
|
||||
if result.path:
|
||||
self.bufferCreate(result.path)
|
||||
else:
|
||||
result = openMultiple(directory=filedir)
|
||||
for path in result.paths:
|
||||
self.bufferCreate(path)
|
||||
cancel = False
|
||||
return cancel
|
||||
|
||||
|
||||
class EditorShellNotebook(wx.Notebook):
|
||||
"""A notebook containing an editor page and a shell page."""
|
||||
|
||||
def __init__(self, parent, filename=None):
|
||||
"""Create EditorShellNotebook instance."""
|
||||
wx.Notebook.__init__(self, parent, id=-1)
|
||||
usePanels = True
|
||||
if usePanels:
|
||||
editorparent = editorpanel = wx.Panel(self, -1)
|
||||
shellparent = shellpanel = wx.Panel(self, -1)
|
||||
else:
|
||||
editorparent = self
|
||||
shellparent = self
|
||||
self.buffer = Buffer()
|
||||
self.editor = Editor(parent=editorparent)
|
||||
self.buffer.addEditor(self.editor)
|
||||
self.buffer.open(filename)
|
||||
self.shell = Shell(parent=shellparent, locals=self.buffer.interp.locals,
|
||||
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER)
|
||||
self.buffer.interp.locals.clear()
|
||||
if usePanels:
|
||||
self.AddPage(page=editorpanel, text='Editor', select=True)
|
||||
self.AddPage(page=shellpanel, text='Shell')
|
||||
# Setup sizers
|
||||
editorsizer = wx.BoxSizer(wx.VERTICAL)
|
||||
editorsizer.Add(self.editor.window, 1, wx.EXPAND)
|
||||
editorpanel.SetSizer(editorsizer)
|
||||
editorpanel.SetAutoLayout(True)
|
||||
shellsizer = wx.BoxSizer(wx.VERTICAL)
|
||||
shellsizer.Add(self.shell, 1, wx.EXPAND)
|
||||
shellpanel.SetSizer(shellsizer)
|
||||
shellpanel.SetAutoLayout(True)
|
||||
else:
|
||||
self.AddPage(page=self.editor.window, text='Editor', select=True)
|
||||
self.AddPage(page=self.shell, text='Shell')
|
||||
self.editor.setFocus()
|
||||
wx.EVT_NOTEBOOK_PAGE_CHANGED(self, self.GetId(), self.OnPageChanged)
|
||||
|
||||
def OnPageChanged(self, event):
|
||||
"""Page changed event handler."""
|
||||
selection = event.GetSelection()
|
||||
if selection == 0:
|
||||
self.editor.setFocus()
|
||||
else:
|
||||
self.shell.SetFocus()
|
||||
event.Skip()
|
||||
|
||||
def SetFocus(self):
|
||||
wx.Notebook.SetFocus(self)
|
||||
selection = self.GetSelection()
|
||||
if selection == 0:
|
||||
self.editor.setFocus()
|
||||
else:
|
||||
self.shell.SetFocus()
|
||||
|
||||
|
||||
class Editor:
|
||||
"""Editor having an EditWindow."""
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize,
|
||||
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
|
||||
"""Create Editor instance."""
|
||||
self.window = EditWindow(self, parent, id, pos, size, style)
|
||||
self.id = self.window.GetId()
|
||||
self.buffer = None
|
||||
# Assign handlers for keyboard events.
|
||||
wx.EVT_CHAR(self.window, self.OnChar)
|
||||
wx.EVT_KEY_DOWN(self.window, self.OnKeyDown)
|
||||
|
||||
def _setBuffer(self, buffer, text):
|
||||
"""Set the editor to a buffer. Private callback called by buffer."""
|
||||
self.buffer = buffer
|
||||
self.autoCompleteKeys = buffer.interp.getAutoCompleteKeys()
|
||||
self.clearAll()
|
||||
self.setText(text)
|
||||
self.emptyUndoBuffer()
|
||||
self.setSavePoint()
|
||||
|
||||
def destroy(self):
|
||||
"""Destroy all editor objects."""
|
||||
self.window.Destroy()
|
||||
|
||||
def clearAll(self):
|
||||
self.window.ClearAll()
|
||||
|
||||
def emptyUndoBuffer(self):
|
||||
self.window.EmptyUndoBuffer()
|
||||
|
||||
def getStatus(self):
|
||||
"""Return (filepath, line, column) status tuple."""
|
||||
if self.window:
|
||||
pos = self.window.GetCurrentPos()
|
||||
line = self.window.LineFromPosition(pos) + 1
|
||||
col = self.window.GetColumn(pos)
|
||||
if self.buffer:
|
||||
name = self.buffer.doc.filepath or self.buffer.name
|
||||
else:
|
||||
name = ''
|
||||
status = (name, line, col)
|
||||
return status
|
||||
else:
|
||||
return ('', 0, 0)
|
||||
|
||||
def getText(self):
|
||||
"""Return contents of editor."""
|
||||
return self.window.GetText()
|
||||
|
||||
def hasChanged(self):
|
||||
"""Return True if contents have changed."""
|
||||
return self.window.GetModify()
|
||||
|
||||
def setFocus(self):
|
||||
"""Set the input focus to the editor window."""
|
||||
self.window.SetFocus()
|
||||
|
||||
def setSavePoint(self):
|
||||
self.window.SetSavePoint()
|
||||
|
||||
def setText(self, text):
|
||||
"""Set contents of editor."""
|
||||
self.window.SetText(text)
|
||||
|
||||
def OnChar(self, event):
|
||||
"""Keypress event handler.
|
||||
|
||||
Only receives an event if OnKeyDown calls event.Skip() for the
|
||||
corresponding event."""
|
||||
|
||||
key = event.KeyCode()
|
||||
if key in self.autoCompleteKeys:
|
||||
# Usually the dot (period) key activates auto completion.
|
||||
if self.window.AutoCompActive():
|
||||
self.window.AutoCompCancel()
|
||||
self.window.ReplaceSelection('')
|
||||
self.window.AddText(chr(key))
|
||||
text, pos = self.window.GetCurLine()
|
||||
text = text[:pos]
|
||||
if self.window.autoComplete:
|
||||
self.autoCompleteShow(text)
|
||||
elif key == ord('('):
|
||||
# The left paren activates a call tip and cancels an
|
||||
# active auto completion.
|
||||
if self.window.AutoCompActive():
|
||||
self.window.AutoCompCancel()
|
||||
self.window.ReplaceSelection('')
|
||||
self.window.AddText('(')
|
||||
text, pos = self.window.GetCurLine()
|
||||
text = text[:pos]
|
||||
self.autoCallTipShow(text)
|
||||
else:
|
||||
# Allow the normal event handling to take place.
|
||||
event.Skip()
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
"""Key down event handler."""
|
||||
|
||||
key = event.KeyCode()
|
||||
# If the auto-complete window is up let it do its thing.
|
||||
if self.window.AutoCompActive():
|
||||
event.Skip()
|
||||
return
|
||||
controlDown = event.ControlDown()
|
||||
altDown = event.AltDown()
|
||||
shiftDown = event.ShiftDown()
|
||||
# Let Ctrl-Alt-* get handled normally.
|
||||
if controlDown and altDown:
|
||||
event.Skip()
|
||||
# Increase font size.
|
||||
elif controlDown and key in (ord(']'),):
|
||||
dispatcher.send(signal='FontIncrease')
|
||||
# Decrease font size.
|
||||
elif controlDown and key in (ord('['),):
|
||||
dispatcher.send(signal='FontDecrease')
|
||||
# Default font size.
|
||||
elif controlDown and key in (ord('='),):
|
||||
dispatcher.send(signal='FontDefault')
|
||||
else:
|
||||
event.Skip()
|
||||
|
||||
def autoCompleteShow(self, command):
|
||||
"""Display auto-completion popup list."""
|
||||
list = self.buffer.interp.getAutoCompleteList(command,
|
||||
includeMagic=self.window.autoCompleteIncludeMagic,
|
||||
includeSingle=self.window.autoCompleteIncludeSingle,
|
||||
includeDouble=self.window.autoCompleteIncludeDouble)
|
||||
if list:
|
||||
options = ' '.join(list)
|
||||
offset = 0
|
||||
self.window.AutoCompShow(offset, options)
|
||||
|
||||
def autoCallTipShow(self, command):
|
||||
"""Display argument spec and docstring in a popup window."""
|
||||
if self.window.CallTipActive():
|
||||
self.window.CallTipCancel()
|
||||
(name, argspec, tip) = self.buffer.interp.getCallTip(command)
|
||||
if tip:
|
||||
dispatcher.send(signal='Shell.calltip', sender=self, calltip=tip)
|
||||
if not self.window.autoCallTip:
|
||||
return
|
||||
if argspec:
|
||||
startpos = self.window.GetCurrentPos()
|
||||
self.window.AddText(argspec + ')')
|
||||
endpos = self.window.GetCurrentPos()
|
||||
self.window.SetSelection(endpos, startpos)
|
||||
if tip:
|
||||
curpos = self.window.GetCurrentPos()
|
||||
size = len(name)
|
||||
tippos = curpos - (size + 1)
|
||||
fallback = curpos - self.window.GetColumn(curpos)
|
||||
# In case there isn't enough room, only go back to the
|
||||
# fallback.
|
||||
tippos = max(tippos, fallback)
|
||||
self.window.CallTipShow(tippos, tip)
|
||||
self.window.CallTipSetHighlight(0, size)
|
||||
|
||||
|
||||
class EditWindow(editwindow.EditWindow):
|
||||
"""EditWindow based on StyledTextCtrl."""
|
||||
|
||||
def __init__(self, editor, parent, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize,
|
||||
style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
|
||||
"""Create EditWindow instance."""
|
||||
editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
|
||||
self.editor = editor
|
||||
|
||||
|
||||
class DialogResults:
|
||||
"""DialogResults class."""
|
||||
|
||||
def __init__(self, returned):
|
||||
"""Create wrapper for results returned by dialog."""
|
||||
self.returned = returned
|
||||
self.positive = returned in (wx.ID_OK, wx.ID_YES)
|
||||
self.text = self._asString()
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.__dict__)
|
||||
|
||||
def _asString(self):
|
||||
returned = self.returned
|
||||
if returned == wx.ID_OK:
|
||||
return "Ok"
|
||||
elif returned == wx.ID_CANCEL:
|
||||
return "Cancel"
|
||||
elif returned == wx.ID_YES:
|
||||
return "Yes"
|
||||
elif returned == wx.ID_NO:
|
||||
return "No"
|
||||
|
||||
|
||||
def fileDialog(parent=None, title='Open', directory='', filename='',
|
||||
wildcard='All Files (*.*)|*.*',
|
||||
style=wx.OPEN | wx.MULTIPLE):
|
||||
"""File dialog wrapper function."""
|
||||
dialog = wx.FileDialog(parent, title, directory, filename,
|
||||
wildcard, style)
|
||||
result = DialogResults(dialog.ShowModal())
|
||||
if result.positive:
|
||||
result.paths = dialog.GetPaths()
|
||||
else:
|
||||
result.paths = []
|
||||
dialog.Destroy()
|
||||
return result
|
||||
|
||||
|
||||
def openSingle(parent=None, title='Open', directory='', filename='',
|
||||
wildcard='All Files (*.*)|*.*', style=wx.OPEN):
|
||||
"""File dialog wrapper function."""
|
||||
dialog = wx.FileDialog(parent, title, directory, filename,
|
||||
wildcard, style)
|
||||
result = DialogResults(dialog.ShowModal())
|
||||
if result.positive:
|
||||
result.path = dialog.GetPath()
|
||||
else:
|
||||
result.path = None
|
||||
dialog.Destroy()
|
||||
return result
|
||||
|
||||
|
||||
def openMultiple(parent=None, title='Open', directory='', filename='',
|
||||
wildcard='All Files (*.*)|*.*',
|
||||
style=wx.OPEN | wx.MULTIPLE):
|
||||
"""File dialog wrapper function."""
|
||||
return fileDialog(parent, title, directory, filename, wildcard, style)
|
||||
|
||||
|
||||
def saveSingle(parent=None, title='Save', directory='', filename='',
|
||||
wildcard='All Files (*.*)|*.*',
|
||||
style=wx.SAVE | wx.HIDE_READONLY | wx.OVERWRITE_PROMPT):
|
||||
"""File dialog wrapper function."""
|
||||
dialog = wx.FileDialog(parent, title, directory, filename,
|
||||
wildcard, style)
|
||||
result = DialogResults(dialog.ShowModal())
|
||||
if result.positive:
|
||||
result.path = dialog.GetPath()
|
||||
else:
|
||||
result.path = None
|
||||
dialog.Destroy()
|
||||
return result
|
||||
|
||||
|
||||
def directory(parent=None, message='Choose a directory', path='', style=0,
|
||||
pos=wx.DefaultPosition, size=wx.DefaultSize):
|
||||
"""Dir dialog wrapper function."""
|
||||
dialog = wx.DirDialog(parent, message, path, style, pos, size)
|
||||
result = DialogResults(dialog.ShowModal())
|
||||
if result.positive:
|
||||
result.path = dialog.GetPath()
|
||||
else:
|
||||
result.path = None
|
||||
dialog.Destroy()
|
||||
return result
|
||||
|
||||
|
||||
def messageDialog(parent=None, message='', title='Message box',
|
||||
style=wx.YES_NO | wx.CANCEL | wx.CENTRE | wx.ICON_QUESTION,
|
||||
pos=wx.DefaultPosition):
|
||||
"""Message dialog wrapper function."""
|
||||
dialog = wx.MessageDialog(parent, message, title, style, pos)
|
||||
result = DialogResults(dialog.ShowModal())
|
||||
dialog.Destroy()
|
||||
return result
|
225
wxPython/wx/py/editwindow.py
Normal file
225
wxPython/wx/py/editwindow.py
Normal file
@@ -0,0 +1,225 @@
|
||||
"""EditWindow class."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
from wx import stc
|
||||
|
||||
import keyword
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import dispatcher
|
||||
from version import VERSION
|
||||
|
||||
|
||||
if 'wxMSW' in wx.PlatformInfo:
|
||||
FACES = { 'times' : 'Times New Roman',
|
||||
'mono' : 'Courier New',
|
||||
'helv' : 'Arial',
|
||||
'lucida' : 'Lucida Console',
|
||||
'other' : 'Comic Sans MS',
|
||||
'size' : 10,
|
||||
'lnsize' : 8,
|
||||
'backcol' : '#FFFFFF',
|
||||
'calltipbg' : '#FFFFB8',
|
||||
'calltipfg' : '#404040',
|
||||
}
|
||||
|
||||
elif 'wxGTK' in wx.PlatformInfo and 'gtk2' in wx.PlatformInfo:
|
||||
FACES = { 'times' : 'Serif',
|
||||
'mono' : 'Monospace',
|
||||
'helv' : 'Sans',
|
||||
'other' : 'new century schoolbook',
|
||||
'size' : 10,
|
||||
'lnsize' : 9,
|
||||
'backcol' : '#FFFFFF',
|
||||
'calltipbg' : '#FFFFB8',
|
||||
'calltipfg' : '#404040',
|
||||
}
|
||||
|
||||
elif 'wxMac' in wx.PlatformInfo:
|
||||
FACES = { 'times' : 'Lucida Grande',
|
||||
'mono' : 'Courier New',
|
||||
'helv' : 'Geneva',
|
||||
'other' : 'new century schoolbook',
|
||||
'size' : 13,
|
||||
'lnsize' : 10,
|
||||
'backcol' : '#FFFFFF',
|
||||
'calltipbg' : '#FFFFB8',
|
||||
'calltipfg' : '#404040',
|
||||
}
|
||||
|
||||
else: # GTK1, etc.
|
||||
FACES = { 'times' : 'Times',
|
||||
'mono' : 'Courier',
|
||||
'helv' : 'Helvetica',
|
||||
'other' : 'new century schoolbook',
|
||||
'size' : 12,
|
||||
'lnsize' : 10,
|
||||
'backcol' : '#FFFFFF',
|
||||
'calltipbg' : '#FFFFB8',
|
||||
'calltipfg' : '#404040',
|
||||
}
|
||||
|
||||
|
||||
class EditWindow(stc.StyledTextCtrl):
|
||||
"""EditWindow based on StyledTextCtrl."""
|
||||
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize, style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
|
||||
"""Create EditWindow instance."""
|
||||
stc.StyledTextCtrl.__init__(self, parent, id, pos, size, style)
|
||||
self.__config()
|
||||
stc.EVT_STC_UPDATEUI(self, id, self.OnUpdateUI)
|
||||
dispatcher.connect(receiver=self._fontsizer, signal='FontIncrease')
|
||||
dispatcher.connect(receiver=self._fontsizer, signal='FontDecrease')
|
||||
dispatcher.connect(receiver=self._fontsizer, signal='FontDefault')
|
||||
|
||||
def _fontsizer(self, signal):
|
||||
"""Receiver for Font* signals."""
|
||||
size = self.GetZoom()
|
||||
if signal == 'FontIncrease':
|
||||
size += 1
|
||||
elif signal == 'FontDecrease':
|
||||
size -= 1
|
||||
elif signal == 'FontDefault':
|
||||
size = 0
|
||||
self.SetZoom(size)
|
||||
|
||||
def __config(self):
|
||||
"""Configure shell based on user preferences."""
|
||||
self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
|
||||
self.SetMarginWidth(1, 40)
|
||||
|
||||
self.SetLexer(stc.STC_LEX_PYTHON)
|
||||
self.SetKeyWords(0, ' '.join(keyword.kwlist))
|
||||
|
||||
self.setStyles(FACES)
|
||||
self.SetViewWhiteSpace(False)
|
||||
self.SetTabWidth(4)
|
||||
self.SetUseTabs(False)
|
||||
# Do we want to automatically pop up command completion options?
|
||||
self.autoComplete = True
|
||||
self.autoCompleteIncludeMagic = True
|
||||
self.autoCompleteIncludeSingle = True
|
||||
self.autoCompleteIncludeDouble = True
|
||||
self.autoCompleteCaseInsensitive = True
|
||||
self.AutoCompSetIgnoreCase(self.autoCompleteCaseInsensitive)
|
||||
self.autoCompleteAutoHide = False
|
||||
self.AutoCompSetAutoHide(self.autoCompleteAutoHide)
|
||||
self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`')
|
||||
# Do we want to automatically pop up command argument help?
|
||||
self.autoCallTip = True
|
||||
self.CallTipSetBackground(FACES['calltipbg'])
|
||||
self.CallTipSetForeground(FACES['calltipfg'])
|
||||
self.SetWrapMode(False)
|
||||
try:
|
||||
self.SetEndAtLastLine(False)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def setStyles(self, faces):
|
||||
"""Configure font size, typeface and color for lexer."""
|
||||
|
||||
# Default style
|
||||
self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
|
||||
"face:%(mono)s,size:%(size)d,back:%(backcol)s" % \
|
||||
faces)
|
||||
|
||||
self.StyleClearAll()
|
||||
|
||||
# Built in styles
|
||||
self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,
|
||||
"back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
|
||||
self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR,
|
||||
"face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
|
||||
"fore:#0000FF,back:#FFFF88")
|
||||
self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
|
||||
"fore:#FF0000,back:#FFFF88")
|
||||
|
||||
# Python styles
|
||||
self.StyleSetSpec(stc.STC_P_DEFAULT,
|
||||
"face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.STC_P_COMMENTLINE,
|
||||
"fore:#007F00,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.STC_P_NUMBER,
|
||||
"")
|
||||
self.StyleSetSpec(stc.STC_P_STRING,
|
||||
"fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.STC_P_CHARACTER,
|
||||
"fore:#7F007F,face:%(mono)s" % faces)
|
||||
self.StyleSetSpec(stc.STC_P_WORD,
|
||||
"fore:#00007F,bold")
|
||||
self.StyleSetSpec(stc.STC_P_TRIPLE,
|
||||
"fore:#7F0000")
|
||||
self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE,
|
||||
"fore:#000033,back:#FFFFE8")
|
||||
self.StyleSetSpec(stc.STC_P_CLASSNAME,
|
||||
"fore:#0000FF,bold")
|
||||
self.StyleSetSpec(stc.STC_P_DEFNAME,
|
||||
"fore:#007F7F,bold")
|
||||
self.StyleSetSpec(stc.STC_P_OPERATOR,
|
||||
"")
|
||||
self.StyleSetSpec(stc.STC_P_IDENTIFIER,
|
||||
"")
|
||||
self.StyleSetSpec(stc.STC_P_COMMENTBLOCK,
|
||||
"fore:#7F7F7F")
|
||||
self.StyleSetSpec(stc.STC_P_STRINGEOL,
|
||||
"fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
|
||||
|
||||
def OnUpdateUI(self, event):
|
||||
"""Check for matching braces."""
|
||||
# If the auto-complete window is up let it do its thing.
|
||||
if self.AutoCompActive() or self.CallTipActive():
|
||||
return
|
||||
braceAtCaret = -1
|
||||
braceOpposite = -1
|
||||
charBefore = None
|
||||
caretPos = self.GetCurrentPos()
|
||||
if caretPos > 0:
|
||||
charBefore = self.GetCharAt(caretPos - 1)
|
||||
styleBefore = self.GetStyleAt(caretPos - 1)
|
||||
|
||||
# Check before.
|
||||
if charBefore and chr(charBefore) in '[]{}()' \
|
||||
and styleBefore == stc.STC_P_OPERATOR:
|
||||
braceAtCaret = caretPos - 1
|
||||
|
||||
# Check after.
|
||||
if braceAtCaret < 0:
|
||||
charAfter = self.GetCharAt(caretPos)
|
||||
styleAfter = self.GetStyleAt(caretPos)
|
||||
if charAfter and chr(charAfter) in '[]{}()' \
|
||||
and styleAfter == stc.STC_P_OPERATOR:
|
||||
braceAtCaret = caretPos
|
||||
|
||||
if braceAtCaret >= 0:
|
||||
braceOpposite = self.BraceMatch(braceAtCaret)
|
||||
|
||||
if braceAtCaret != -1 and braceOpposite == -1:
|
||||
self.BraceBadLight(braceAtCaret)
|
||||
else:
|
||||
self.BraceHighlight(braceAtCaret, braceOpposite)
|
||||
|
||||
def CanCopy(self):
|
||||
"""Return True if text is selected and can be copied."""
|
||||
return self.GetSelectionStart() != self.GetSelectionEnd()
|
||||
|
||||
def CanCut(self):
|
||||
"""Return True if text is selected and can be cut."""
|
||||
return self.CanCopy() and self.CanEdit()
|
||||
|
||||
def CanEdit(self):
|
||||
"""Return True if editing should succeed."""
|
||||
return not self.GetReadOnly()
|
||||
|
||||
def CanPaste(self):
|
||||
"""Return True if pasting should succeed."""
|
||||
return stc.StyledTextCtrl.CanPaste(self) and self.CanEdit()
|
332
wxPython/wx/py/filling.py
Normal file
332
wxPython/wx/py/filling.py
Normal file
@@ -0,0 +1,332 @@
|
||||
"""Filling is the gui tree control through which a user can navigate
|
||||
the local namespace or any object."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
|
||||
import dispatcher
|
||||
import editwindow
|
||||
import inspect
|
||||
import introspect
|
||||
import keyword
|
||||
import sys
|
||||
import types
|
||||
from version import VERSION
|
||||
|
||||
|
||||
COMMONTYPES = [getattr(types, t) for t in dir(types) \
|
||||
if not t.startswith('_') \
|
||||
and t not in ('ClassType', 'InstanceType', 'ModuleType')]
|
||||
|
||||
DOCTYPES = ('BuiltinFunctionType', 'BuiltinMethodType', 'ClassType',
|
||||
'FunctionType', 'GeneratorType', 'InstanceType',
|
||||
'LambdaType', 'MethodType', 'ModuleType',
|
||||
'UnboundMethodType', 'method-wrapper')
|
||||
|
||||
SIMPLETYPES = [getattr(types, t) for t in dir(types) \
|
||||
if not t.startswith('_') and t not in DOCTYPES]
|
||||
|
||||
del t
|
||||
|
||||
try:
|
||||
COMMONTYPES.append(type(''.__repr__)) # Method-wrapper in version 2.2.x.
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
class FillingTree(wx.TreeCtrl):
|
||||
"""FillingTree based on TreeCtrl."""
|
||||
|
||||
name = 'Filling Tree'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize, style=wx.TR_DEFAULT_STYLE,
|
||||
rootObject=None, rootLabel=None, rootIsNamespace=False,
|
||||
static=False):
|
||||
"""Create FillingTree instance."""
|
||||
wx.TreeCtrl.__init__(self, parent, id, pos, size, style)
|
||||
self.rootIsNamespace = rootIsNamespace
|
||||
import __main__
|
||||
if rootObject is None:
|
||||
rootObject = __main__.__dict__
|
||||
self.rootIsNamespace = True
|
||||
if rootObject is __main__.__dict__ and rootLabel is None:
|
||||
rootLabel = 'locals()'
|
||||
if not rootLabel:
|
||||
rootLabel = 'Ingredients'
|
||||
rootData = wx.TreeItemData(rootObject)
|
||||
self.item = self.root = self.AddRoot(rootLabel, -1, -1, rootData)
|
||||
self.SetItemHasChildren(self.root, self.objHasChildren(rootObject))
|
||||
wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding)
|
||||
wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
|
||||
wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
|
||||
wx.EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated)
|
||||
if not static:
|
||||
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
|
||||
|
||||
def push(self, command, more):
|
||||
"""Receiver for Interpreter.push signal."""
|
||||
self.display()
|
||||
|
||||
def OnItemExpanding(self, event):
|
||||
"""Add children to the item."""
|
||||
busy = wx.BusyCursor()
|
||||
item = event.GetItem()
|
||||
if self.IsExpanded(item):
|
||||
return
|
||||
self.addChildren(item)
|
||||
# self.SelectItem(item)
|
||||
|
||||
def OnItemCollapsed(self, event):
|
||||
"""Remove all children from the item."""
|
||||
busy = wx.BusyCursor()
|
||||
item = event.GetItem()
|
||||
# self.CollapseAndReset(item)
|
||||
# self.DeleteChildren(item)
|
||||
# self.SelectItem(item)
|
||||
|
||||
def OnSelChanged(self, event):
|
||||
"""Display information about the item."""
|
||||
busy = wx.BusyCursor()
|
||||
self.item = event.GetItem()
|
||||
self.display()
|
||||
|
||||
def OnItemActivated(self, event):
|
||||
"""Launch a DirFrame."""
|
||||
item = event.GetItem()
|
||||
text = self.getFullName(item)
|
||||
obj = self.GetPyData(item)
|
||||
frame = FillingFrame(parent=self, size=(600, 100), rootObject=obj,
|
||||
rootLabel=text, rootIsNamespace=False)
|
||||
frame.Show()
|
||||
|
||||
def objHasChildren(self, obj):
|
||||
"""Return true if object has children."""
|
||||
if self.objGetChildren(obj):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def objGetChildren(self, obj):
|
||||
"""Return dictionary with attributes or contents of object."""
|
||||
busy = wx.BusyCursor()
|
||||
otype = type(obj)
|
||||
if otype is types.DictType \
|
||||
or str(otype)[17:23] == 'BTrees' and hasattr(obj, 'keys'):
|
||||
return obj
|
||||
d = {}
|
||||
if otype is types.ListType or otype is types.TupleType:
|
||||
for n in range(len(obj)):
|
||||
key = '[' + str(n) + ']'
|
||||
d[key] = obj[n]
|
||||
if otype not in COMMONTYPES:
|
||||
for key in introspect.getAttributeNames(obj):
|
||||
# Believe it or not, some attributes can disappear,
|
||||
# such as the exc_traceback attribute of the sys
|
||||
# module. So this is nested in a try block.
|
||||
try:
|
||||
d[key] = getattr(obj, key)
|
||||
except:
|
||||
pass
|
||||
return d
|
||||
|
||||
def addChildren(self, item):
|
||||
self.DeleteChildren(item)
|
||||
obj = self.GetPyData(item)
|
||||
children = self.objGetChildren(obj)
|
||||
if not children:
|
||||
return
|
||||
keys = children.keys()
|
||||
keys.sort(lambda x, y: cmp(str(x).lower(), str(y).lower()))
|
||||
for key in keys:
|
||||
itemtext = str(key)
|
||||
# Show string dictionary items with single quotes, except
|
||||
# for the first level of items, if they represent a
|
||||
# namespace.
|
||||
if type(obj) is types.DictType \
|
||||
and type(key) is types.StringType \
|
||||
and (item != self.root \
|
||||
or (item == self.root and not self.rootIsNamespace)):
|
||||
itemtext = repr(key)
|
||||
child = children[key]
|
||||
data = wx.TreeItemData(child)
|
||||
branch = self.AppendItem(parent=item, text=itemtext, data=data)
|
||||
self.SetItemHasChildren(branch, self.objHasChildren(child))
|
||||
|
||||
def display(self):
|
||||
item = self.item
|
||||
if self.IsExpanded(item):
|
||||
self.addChildren(item)
|
||||
self.setText('')
|
||||
obj = self.GetPyData(item)
|
||||
if wx.Platform == '__WXMSW__':
|
||||
if obj is None: # Windows bug fix.
|
||||
return
|
||||
self.SetItemHasChildren(item, self.objHasChildren(obj))
|
||||
otype = type(obj)
|
||||
text = ''
|
||||
text += self.getFullName(item)
|
||||
text += '\n\nType: ' + str(otype)
|
||||
try:
|
||||
value = str(obj)
|
||||
except:
|
||||
value = ''
|
||||
if otype is types.StringType or otype is types.UnicodeType:
|
||||
value = repr(obj)
|
||||
text += '\n\nValue: ' + value
|
||||
if otype not in SIMPLETYPES:
|
||||
try:
|
||||
text += '\n\nDocstring:\n\n"""' + \
|
||||
inspect.getdoc(obj).strip() + '"""'
|
||||
except:
|
||||
pass
|
||||
if otype is types.InstanceType:
|
||||
try:
|
||||
text += '\n\nClass Definition:\n\n' + \
|
||||
inspect.getsource(obj.__class__)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
text += '\n\nSource Code:\n\n' + \
|
||||
inspect.getsource(obj)
|
||||
except:
|
||||
pass
|
||||
self.setText(text)
|
||||
|
||||
def getFullName(self, item, partial=''):
|
||||
"""Return a syntactically proper name for item."""
|
||||
name = self.GetItemText(item)
|
||||
parent = None
|
||||
obj = None
|
||||
if item != self.root:
|
||||
parent = self.GetItemParent(item)
|
||||
obj = self.GetPyData(parent)
|
||||
# Apply dictionary syntax to dictionary items, except the root
|
||||
# and first level children of a namepace.
|
||||
if (type(obj) is types.DictType \
|
||||
or str(type(obj))[17:23] == 'BTrees' \
|
||||
and hasattr(obj, 'keys')) \
|
||||
and ((item != self.root and parent != self.root) \
|
||||
or (parent == self.root and not self.rootIsNamespace)):
|
||||
name = '[' + name + ']'
|
||||
# Apply dot syntax to multipart names.
|
||||
if partial:
|
||||
if partial[0] == '[':
|
||||
name += partial
|
||||
else:
|
||||
name += '.' + partial
|
||||
# Repeat for everything but the root item
|
||||
# and first level children of a namespace.
|
||||
if (item != self.root and parent != self.root) \
|
||||
or (parent == self.root and not self.rootIsNamespace):
|
||||
name = self.getFullName(parent, partial=name)
|
||||
return name
|
||||
|
||||
def setText(self, text):
|
||||
"""Display information about the current selection."""
|
||||
|
||||
# This method will likely be replaced by the enclosing app to
|
||||
# do something more interesting, like write to a text control.
|
||||
print text
|
||||
|
||||
def setStatusText(self, text):
|
||||
"""Display status information."""
|
||||
|
||||
# This method will likely be replaced by the enclosing app to
|
||||
# do something more interesting, like write to a status bar.
|
||||
print text
|
||||
|
||||
|
||||
class FillingText(editwindow.EditWindow):
|
||||
"""FillingText based on StyledTextCtrl."""
|
||||
|
||||
name = 'Filling Text'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize, style=wx.CLIP_CHILDREN,
|
||||
static=False):
|
||||
"""Create FillingText instance."""
|
||||
editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
|
||||
# Configure various defaults and user preferences.
|
||||
self.SetReadOnly(True)
|
||||
self.SetWrapMode(True)
|
||||
self.SetMarginWidth(1, 0)
|
||||
if not static:
|
||||
dispatcher.connect(receiver=self.push, signal='Interpreter.push')
|
||||
|
||||
def push(self, command, more):
|
||||
"""Receiver for Interpreter.push signal."""
|
||||
self.Refresh()
|
||||
|
||||
def SetText(self, *args, **kwds):
|
||||
self.SetReadOnly(False)
|
||||
editwindow.EditWindow.SetText(self, *args, **kwds)
|
||||
self.SetReadOnly(True)
|
||||
|
||||
|
||||
class Filling(wx.SplitterWindow):
|
||||
"""Filling based on wxSplitterWindow."""
|
||||
|
||||
name = 'Filling'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
|
||||
size=wx.DefaultSize, style=wx.SP_3D,
|
||||
name='Filling Window', rootObject=None,
|
||||
rootLabel=None, rootIsNamespace=False, static=False):
|
||||
"""Create a Filling instance."""
|
||||
wx.SplitterWindow.__init__(self, parent, id, pos, size, style, name)
|
||||
self.tree = FillingTree(parent=self, rootObject=rootObject,
|
||||
rootLabel=rootLabel,
|
||||
rootIsNamespace=rootIsNamespace,
|
||||
static=static)
|
||||
self.text = FillingText(parent=self, static=static)
|
||||
self.SplitVertically(self.tree, self.text, 130)
|
||||
self.SetMinimumPaneSize(1)
|
||||
# Override the filling so that descriptions go to FillingText.
|
||||
self.tree.setText = self.text.SetText
|
||||
# Display the root item.
|
||||
## self.tree.SelectItem(self.tree.root)
|
||||
self.tree.display()
|
||||
|
||||
|
||||
class FillingFrame(wx.Frame):
|
||||
"""Frame containing the namespace tree component."""
|
||||
|
||||
name = 'Filling Frame'
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='PyFilling',
|
||||
pos=wx.DefaultPosition, size=(600, 400),
|
||||
style=wx.DEFAULT_FRAME_STYLE, rootObject=None,
|
||||
rootLabel=None, rootIsNamespace=False, static=False):
|
||||
"""Create FillingFrame instance."""
|
||||
wx.Frame.__init__(self, parent, id, title, pos, size, style)
|
||||
intro = 'PyFilling - The Tastiest Namespace Inspector'
|
||||
self.CreateStatusBar()
|
||||
self.SetStatusText(intro)
|
||||
import images
|
||||
self.SetIcon(images.getPyIcon())
|
||||
self.filling = Filling(parent=self, rootObject=rootObject,
|
||||
rootLabel=rootLabel,
|
||||
rootIsNamespace=rootIsNamespace,
|
||||
static=static)
|
||||
# Override so that status messages go to the status bar.
|
||||
self.filling.tree.setStatusText = self.SetStatusText
|
||||
|
||||
|
||||
class App(wx.App):
|
||||
"""PyFilling standalone application."""
|
||||
|
||||
def OnInit(self):
|
||||
wx.InitAllImageHandlers()
|
||||
self.fillingFrame = FillingFrame()
|
||||
self.fillingFrame.Show(True)
|
||||
self.SetTopWindow(self.fillingFrame)
|
||||
return True
|
362
wxPython/wx/py/frame.py
Normal file
362
wxPython/wx/py/frame.py
Normal file
@@ -0,0 +1,362 @@
|
||||
"""Base frame with menu."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
from version import VERSION
|
||||
|
||||
|
||||
ID_NEW = wx.ID_NEW
|
||||
ID_OPEN = wx.ID_OPEN
|
||||
ID_REVERT = wx.ID_REVERT
|
||||
ID_CLOSE = wx.ID_CLOSE
|
||||
ID_SAVE = wx.ID_SAVE
|
||||
ID_SAVEAS = wx.ID_SAVEAS
|
||||
ID_PRINT = wx.ID_PRINT
|
||||
ID_EXIT = wx.ID_EXIT
|
||||
ID_UNDO = wx.ID_UNDO
|
||||
ID_REDO = wx.ID_REDO
|
||||
ID_CUT = wx.ID_CUT
|
||||
ID_COPY = wx.ID_COPY
|
||||
ID_PASTE = wx.ID_PASTE
|
||||
ID_CLEAR = wx.ID_CLEAR
|
||||
ID_SELECTALL = wx.ID_SELECTALL
|
||||
ID_ABOUT = wx.ID_ABOUT
|
||||
ID_AUTOCOMP = wx.NewId()
|
||||
ID_AUTOCOMP_SHOW = wx.NewId()
|
||||
ID_AUTOCOMP_MAGIC = wx.NewId()
|
||||
ID_AUTOCOMP_SINGLE = wx.NewId()
|
||||
ID_AUTOCOMP_DOUBLE = wx.NewId()
|
||||
ID_CALLTIPS = wx.NewId()
|
||||
ID_CALLTIPS_SHOW = wx.NewId()
|
||||
ID_COPY_PLUS = wx.NewId()
|
||||
ID_NAMESPACE = wx.NewId()
|
||||
ID_PASTE_PLUS = wx.NewId()
|
||||
ID_WRAP = wx.NewId()
|
||||
ID_USEAA = wx.NewId()
|
||||
|
||||
|
||||
class Frame(wx.Frame):
|
||||
"""Frame with standard menu items."""
|
||||
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, parent=None, id=-1, title='Editor',
|
||||
pos=wx.DefaultPosition, size=wx.DefaultSize,
|
||||
style=wx.DEFAULT_FRAME_STYLE):
|
||||
"""Create a Frame instance."""
|
||||
wx.Frame.__init__(self, parent, id, title, pos, size, style)
|
||||
self.CreateStatusBar()
|
||||
self.SetStatusText('Frame')
|
||||
import images
|
||||
self.SetIcon(images.getPyIcon())
|
||||
self.__createMenus()
|
||||
wx.EVT_CLOSE(self, self.OnClose)
|
||||
|
||||
def OnClose(self, event):
|
||||
"""Event handler for closing."""
|
||||
self.Destroy()
|
||||
|
||||
def __createMenus(self):
|
||||
m = self.fileMenu = wx.Menu()
|
||||
m.Append(ID_NEW, '&New \tCtrl+N',
|
||||
'New file')
|
||||
m.Append(ID_OPEN, '&Open... \tCtrl+O',
|
||||
'Open file')
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_REVERT, '&Revert \tCtrl+R',
|
||||
'Revert to last saved version')
|
||||
m.Append(ID_CLOSE, '&Close \tCtrl+W',
|
||||
'Close file')
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_SAVE, '&Save... \tCtrl+S',
|
||||
'Save file')
|
||||
m.Append(ID_SAVEAS, 'Save &As \tShift+Ctrl+S',
|
||||
'Save file with new name')
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_PRINT, '&Print... \tCtrl+P',
|
||||
'Print file')
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_NAMESPACE, '&Update Namespace \tShift+Ctrl+N',
|
||||
'Update namespace for autocompletion and calltips')
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_EXIT, 'E&xit', 'Exit Program')
|
||||
|
||||
m = self.editMenu = wx.Menu()
|
||||
m.Append(ID_UNDO, '&Undo \tCtrl+Z',
|
||||
'Undo the last action')
|
||||
m.Append(ID_REDO, '&Redo \tCtrl+Y',
|
||||
'Redo the last undone action')
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_CUT, 'Cu&t \tCtrl+X',
|
||||
'Cut the selection')
|
||||
m.Append(ID_COPY, '&Copy \tCtrl+C',
|
||||
'Copy the selection')
|
||||
m.Append(ID_COPY_PLUS, 'Cop&y Plus \tShift+Ctrl+C',
|
||||
'Copy the selection - retaining prompts')
|
||||
m.Append(ID_PASTE, '&Paste \tCtrl+V', 'Paste from clipboard')
|
||||
m.Append(ID_PASTE_PLUS, 'Past&e Plus \tShift+Ctrl+V',
|
||||
'Paste and run commands')
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_CLEAR, 'Cle&ar',
|
||||
'Delete the selection')
|
||||
m.Append(ID_SELECTALL, 'Select A&ll \tCtrl+A',
|
||||
'Select all text')
|
||||
|
||||
m = self.autocompMenu = wx.Menu()
|
||||
m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion',
|
||||
'Show auto completion list', wx.ITEM_CHECK)
|
||||
m.Append(ID_AUTOCOMP_MAGIC, 'Include Magic Attributes',
|
||||
'Include attributes visible to __getattr__ and __setattr__',
|
||||
wx.ITEM_CHECK)
|
||||
m.Append(ID_AUTOCOMP_SINGLE, 'Include Single Underscores',
|
||||
'Include attibutes prefixed by a single underscore', wx.ITEM_CHECK)
|
||||
m.Append(ID_AUTOCOMP_DOUBLE, 'Include Double Underscores',
|
||||
'Include attibutes prefixed by a double underscore', wx.ITEM_CHECK)
|
||||
|
||||
m = self.calltipsMenu = wx.Menu()
|
||||
m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips',
|
||||
'Show call tips with argument signature and docstring', wx.ITEM_CHECK)
|
||||
|
||||
m = self.optionsMenu = wx.Menu()
|
||||
m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu,
|
||||
'Auto Completion Options')
|
||||
m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu,
|
||||
'Call Tip Options')
|
||||
m.Append(ID_WRAP, '&Wrap Lines',
|
||||
'Wrap lines at right edge', wx.ITEM_CHECK)
|
||||
if wx.Platform == "__WXMAC__":
|
||||
m.Append(ID_USEAA, '&Use AntiAliasing',
|
||||
'Use anti-aliased fonts', wx.ITEM_CHECK)
|
||||
|
||||
m = self.helpMenu = wx.Menu()
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_ABOUT, '&About...', 'About this program')
|
||||
|
||||
b = self.menuBar = wx.MenuBar()
|
||||
b.Append(self.fileMenu, '&File')
|
||||
b.Append(self.editMenu, '&Edit')
|
||||
b.Append(self.optionsMenu, '&Options')
|
||||
b.Append(self.helpMenu, '&Help')
|
||||
self.SetMenuBar(b)
|
||||
|
||||
wx.EVT_MENU(self, ID_NEW, self.OnFileNew)
|
||||
wx.EVT_MENU(self, ID_OPEN, self.OnFileOpen)
|
||||
wx.EVT_MENU(self, ID_REVERT, self.OnFileRevert)
|
||||
wx.EVT_MENU(self, ID_CLOSE, self.OnFileClose)
|
||||
wx.EVT_MENU(self, ID_SAVE, self.OnFileSave)
|
||||
wx.EVT_MENU(self, ID_SAVEAS, self.OnFileSaveAs)
|
||||
wx.EVT_MENU(self, ID_NAMESPACE, self.OnFileUpdateNamespace)
|
||||
wx.EVT_MENU(self, ID_PRINT, self.OnFilePrint)
|
||||
wx.EVT_MENU(self, ID_EXIT, self.OnExit)
|
||||
wx.EVT_MENU(self, ID_UNDO, self.OnUndo)
|
||||
wx.EVT_MENU(self, ID_REDO, self.OnRedo)
|
||||
wx.EVT_MENU(self, ID_CUT, self.OnCut)
|
||||
wx.EVT_MENU(self, ID_COPY, self.OnCopy)
|
||||
wx.EVT_MENU(self, ID_COPY_PLUS, self.OnCopyPlus)
|
||||
wx.EVT_MENU(self, ID_PASTE, self.OnPaste)
|
||||
wx.EVT_MENU(self, ID_PASTE_PLUS, self.OnPastePlus)
|
||||
wx.EVT_MENU(self, ID_CLEAR, self.OnClear)
|
||||
wx.EVT_MENU(self, ID_SELECTALL, self.OnSelectAll)
|
||||
wx.EVT_MENU(self, ID_ABOUT, self.OnAbout)
|
||||
wx.EVT_MENU(self, ID_AUTOCOMP_SHOW, self.OnAutoCompleteShow)
|
||||
wx.EVT_MENU(self, ID_AUTOCOMP_MAGIC, self.OnAutoCompleteMagic)
|
||||
wx.EVT_MENU(self, ID_AUTOCOMP_SINGLE, self.OnAutoCompleteSingle)
|
||||
wx.EVT_MENU(self, ID_AUTOCOMP_DOUBLE, self.OnAutoCompleteDouble)
|
||||
wx.EVT_MENU(self, ID_CALLTIPS_SHOW, self.OnCallTipsShow)
|
||||
wx.EVT_MENU(self, ID_WRAP, self.OnWrap)
|
||||
wx.EVT_MENU(self, ID_USEAA, self.OnUseAA)
|
||||
|
||||
wx.EVT_UPDATE_UI(self, ID_NEW, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_OPEN, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_REVERT, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_CLOSE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_SAVE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_SAVEAS, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_NAMESPACE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_PRINT, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_UNDO, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_REDO, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_CUT, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_COPY, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_COPY_PLUS, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_PASTE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_PASTE_PLUS, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_CLEAR, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_SELECTALL, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_MAGIC, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_SINGLE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_DOUBLE, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_WRAP, self.OnUpdateMenu)
|
||||
wx.EVT_UPDATE_UI(self, ID_USEAA, self.OnUpdateMenu)
|
||||
|
||||
def OnFileNew(self, event):
|
||||
self.bufferNew()
|
||||
|
||||
def OnFileOpen(self, event):
|
||||
self.bufferOpen()
|
||||
|
||||
def OnFileRevert(self, event):
|
||||
self.bufferRevert()
|
||||
|
||||
def OnFileClose(self, event):
|
||||
self.bufferClose()
|
||||
|
||||
def OnFileSave(self, event):
|
||||
self.bufferSave()
|
||||
|
||||
def OnFileSaveAs(self, event):
|
||||
self.bufferSaveAs()
|
||||
|
||||
def OnFileUpdateNamespace(self, event):
|
||||
self.updateNamespace()
|
||||
|
||||
def OnFilePrint(self, event):
|
||||
self.bufferPrint()
|
||||
|
||||
def OnExit(self, event):
|
||||
self.Close(False)
|
||||
|
||||
def OnUndo(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.Undo()
|
||||
|
||||
def OnRedo(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.Redo()
|
||||
|
||||
def OnCut(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.Cut()
|
||||
|
||||
def OnCopy(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.Copy()
|
||||
|
||||
def OnCopyPlus(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.CopyWithPrompts()
|
||||
|
||||
def OnPaste(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.Paste()
|
||||
|
||||
def OnPastePlus(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.PasteAndRun()
|
||||
|
||||
def OnClear(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.Clear()
|
||||
|
||||
def OnSelectAll(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.SelectAll()
|
||||
|
||||
def OnAbout(self, event):
|
||||
"""Display an About window."""
|
||||
title = 'About'
|
||||
text = 'Your message here.'
|
||||
dialog = wx.MessageDialog(self, text, title,
|
||||
wx.OK | wx.ICON_INFORMATION)
|
||||
dialog.ShowModal()
|
||||
dialog.Destroy()
|
||||
|
||||
def OnAutoCompleteShow(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.autoComplete = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteMagic(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.autoCompleteIncludeMagic = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteSingle(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.autoCompleteIncludeSingle = event.IsChecked()
|
||||
|
||||
def OnAutoCompleteDouble(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.autoCompleteIncludeDouble = event.IsChecked()
|
||||
|
||||
def OnCallTipsShow(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.autoCallTip = event.IsChecked()
|
||||
|
||||
def OnWrap(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.SetWrapMode(event.IsChecked())
|
||||
|
||||
def OnUseAA(self, event):
|
||||
win = wx.Window_FindFocus()
|
||||
win.SetUseAntiAliasing(event.IsChecked())
|
||||
|
||||
|
||||
def OnUpdateMenu(self, event):
|
||||
"""Update menu items based on current status and context."""
|
||||
win = wx.Window_FindFocus()
|
||||
id = event.GetId()
|
||||
event.Enable(True)
|
||||
try:
|
||||
if id == ID_NEW:
|
||||
event.Enable(hasattr(self, 'bufferNew'))
|
||||
elif id == ID_OPEN:
|
||||
event.Enable(hasattr(self, 'bufferOpen'))
|
||||
elif id == ID_REVERT:
|
||||
event.Enable(hasattr(self, 'bufferRevert')
|
||||
and self.hasBuffer())
|
||||
elif id == ID_CLOSE:
|
||||
event.Enable(hasattr(self, 'bufferClose')
|
||||
and self.hasBuffer())
|
||||
elif id == ID_SAVE:
|
||||
event.Enable(hasattr(self, 'bufferSave')
|
||||
and self.bufferHasChanged())
|
||||
elif id == ID_SAVEAS:
|
||||
event.Enable(hasattr(self, 'bufferSaveAs')
|
||||
and self.hasBuffer())
|
||||
elif id == ID_NAMESPACE:
|
||||
event.Enable(hasattr(self, 'updateNamespace')
|
||||
and self.hasBuffer())
|
||||
elif id == ID_PRINT:
|
||||
event.Enable(hasattr(self, 'bufferPrint')
|
||||
and self.hasBuffer())
|
||||
elif id == ID_UNDO:
|
||||
event.Enable(win.CanUndo())
|
||||
elif id == ID_REDO:
|
||||
event.Enable(win.CanRedo())
|
||||
elif id == ID_CUT:
|
||||
event.Enable(win.CanCut())
|
||||
elif id == ID_COPY:
|
||||
event.Enable(win.CanCopy())
|
||||
elif id == ID_COPY_PLUS:
|
||||
event.Enable(win.CanCopy() and hasattr(win, 'CopyWithPrompts'))
|
||||
elif id == ID_PASTE:
|
||||
event.Enable(win.CanPaste())
|
||||
elif id == ID_PASTE_PLUS:
|
||||
event.Enable(win.CanPaste() and hasattr(win, 'PasteAndRun'))
|
||||
elif id == ID_CLEAR:
|
||||
event.Enable(win.CanCut())
|
||||
elif id == ID_SELECTALL:
|
||||
event.Enable(hasattr(win, 'SelectAll'))
|
||||
elif id == ID_AUTOCOMP_SHOW:
|
||||
event.Check(win.autoComplete)
|
||||
elif id == ID_AUTOCOMP_MAGIC:
|
||||
event.Check(win.autoCompleteIncludeMagic)
|
||||
elif id == ID_AUTOCOMP_SINGLE:
|
||||
event.Check(win.autoCompleteIncludeSingle)
|
||||
elif id == ID_AUTOCOMP_DOUBLE:
|
||||
event.Check(win.autoCompleteIncludeDouble)
|
||||
elif id == ID_CALLTIPS_SHOW:
|
||||
event.Check(win.autoCallTip)
|
||||
elif id == ID_WRAP:
|
||||
event.Check(win.GetWrapMode())
|
||||
elif id == ID_USEAA:
|
||||
event.Check(win.GetUseAntiAliasing())
|
||||
else:
|
||||
event.Enable(False)
|
||||
except AttributeError:
|
||||
# This menu option is not supported in the current context.
|
||||
event.Enable(False)
|
72
wxPython/wx/py/images.py
Normal file
72
wxPython/wx/py/images.py
Normal file
@@ -0,0 +1,72 @@
|
||||
"""Support for icons."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import wx
|
||||
import cStringIO
|
||||
|
||||
|
||||
def getPyIcon():
|
||||
icon = wx.EmptyIcon()
|
||||
icon.CopyFromBitmap(getPyBitmap())
|
||||
return icon
|
||||
|
||||
def getPyBitmap():
|
||||
return wx.BitmapFromImage(getPyImage())
|
||||
|
||||
def getPyImage():
|
||||
stream = cStringIO.StringIO(getPyData())
|
||||
return wx.ImageFromStream(stream)
|
||||
|
||||
def getPyData():
|
||||
return \
|
||||
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\
|
||||
\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x04\
|
||||
\x95IDATx\x9c\xed\x97?lSG\x1c\xc7?\x97\x98\xd8Q\xa3\xdeY\xa2j\x06\xa4\xf7"QJ\
|
||||
\xbb<3@\x01\xa9\xc2\x0c\xa8!\x1d\x1c6\xcaB\xa8D[uI2\xf4\x8f\xe8\x103\xb4\xa2\
|
||||
,5\x0b\x03\x032C\xab\xc0\x92dh:t\xc0)*E\xcd@<Q\x01Rl\t\xd4D\xaa\xe4{R\xd0{&\
|
||||
\xa5\xd7\xe1\xfc\xec\xe7\xfciR\x08e\xe9O\xb2\xee|\xfe\xbd\xfb}~\xdf\xdf\xbd\
|
||||
\xbb\xb3PJ\xf1"\xad\xe3\x85F\xff\x1f\xe0y\x03h\xad\xcdA\xc7~\xb4\xd6f-\x9f\
|
||||
\xc4\xf3\x0c>Y\x1c#\x97\xddCUk\xf4B\x8d3\x9f\x8d\x9a\x9bU%\xe2~b\xab\xdf\x82\
|
||||
\x83N+\xd3\xe92\\\x1f\xcf\x93\xdd\x9f\xa1\xaa5\x95\xf9\n\xe7\xf3y\xe2\x10[V\
|
||||
\x82H\xe6\xd3G\x1dN\xf7\xc3\xa7\xc7a\xc0\x83\xc3\xc7\xf3\xcc\xcc\xcd\xe3(\
|
||||
\x85\xdb\xe7\xf2\xc9\xe8X\x1b\xe43+\x10\xd5\xb6\x94\x87Z\xe8\x90NU\x91I@\x00\
|
||||
\x06\xbe\x18\xb7J\x98\xca$`\x98\xb9]&{,\x8fRV\x85\xa7V@k\x9bq)o\x83+\t\xe9T\
|
||||
\xd5f\x95\x02\x91\xb4~_\r\xd9\xb6\xbaP\x03\x04n\x9f\xcbDa\xb8\t\xfe\xaf\x17a\
|
||||
<\xe3\xc8\x94lo\x9b\xd6\xa8\xf4\x80\x07\xb7o\xcd\xe0\x0c\x0e\xa2R\x8a\xb4\
|
||||
\x93n\xbal\x1a`e\xe0U\xc1\xd6\xb0\xb8\n\x99\x91"\x93\xaf\xba\xe4\x0ed\xda|6,\
|
||||
\x81\xd6\xda\x9c|\xab]\xea\xcd\x04\x8f\x9b\t\xad\nz\xa1\x02\x80\xdb\xe7R\x1a\
|
||||
\xcf\xa3\xb56\xeb\x02D5\x9e\xf8\xdc\xe1T\xff\xd3\x05\x8e\x82\x83U\xe1Z\xb1\
|
||||
\x18\x9b\xbf\x06\xacQ\x82H\xea\x01/Z@Ut\x08R\xb4$}\x16\xd3\x81A&%\xde\xee\
|
||||
\xbev\x80x\xe0]{\xb2\x1cR\xa5\xe6C*\xb5\xf1\xc4Q\xa6"e\xfbQ\x1b\x8dE\xe6\x87\
|
||||
>\xaa[Q\xadi\x0b\xb0r\x8f\x9e.\xc3t\xb9\xc4]\xaf5\xf6\xfe\xdb\xddt&\x02\xfa\
|
||||
\x9c\xf5\x01\xe2A\xa2\xbeX\x01>]ntR\x12\xe3[\x00\x01\x98\x89\x11[_\xed\xafn\
|
||||
\xab\x81U\xa0\xe7I7\x00\x97o\x04\xcd\x89\x06<;\xe9\x80\x07]i\x97\xc17\x1f\
|
||||
\xd2\xd3\x91`\xe9\xaf?\x01p^Y\x06Z\n\xfau8?a\xfb]i\x97\xec\xa1\x8c\x05(|\xd8\
|
||||
N\xba\xb3\xab\x87\xfb\x8f\x97\xd8\xd9\xd5\x03\xc0\xfd\xc7K\xec\xd8\xd6\xdd\
|
||||
\xfc\xfd\xc1r\xd0\xf4\x01\xda~\x03H\xf4\x04\xd4j :\xb75\xc7\xae\xfd\xbcLW\
|
||||
\xda\xa5\xf0M\x1e\t\xcc\xcc\xcdq\xa9P@\x8c\xf5fL\xdaHF\x16g\x9a\x19\xad\xcc\
|
||||
\xee\xcb\xa3\n\xad\xa1\xda\xf1\x08\xef\xe5\x97x\xf8\xc8f\xf8\xc7\x93:\xdb;\
|
||||
\x93M\xc8\x08j\xc7\xb6n\x1e,\x07m`\x97o\x04|;>\xd1T\xc4\x17\x8a\x13\xb9\xc3\
|
||||
\x88\x01\x0fs\xa4\x9cc}\xf3A\x190\x82\x1f\xddR{-\x1bV\xfc\xd8f\xba\xbd3\xd9\
|
||||
\x06\x15\x07\xbb\xf8\xd3\x12\xdf]-"\x93\xb2\xb1C*\xde\xcd\x1d\xde\xccN(\xc1\
|
||||
\xae\x17"\xd0#+<j\x17m{\xcd\x9bj\x00.\xaf\xf0Xb\xb8\xdfA\xa6\x14\x18\x03\x06\
|
||||
\xb4o\xcf\x8d\xc4\xbervc\x86M\xdaz\x80\x00\x95T\x19?\xd0 @&%~c\xbc\xe3W\xaf\
|
||||
\xb4e\x00\xffh\xc6@\xbd\x11\xbc\xde\x1a\xfe\xef.\xa5\xa2q4\n0\x81\xad\xe9\
|
||||
\xae7<\x12\xaf\xf5\xc2hy\xaa\xe97\x9cS\\\x98\xb2\x0e\x03\xb1\xcdhW\xdaC\x1a\
|
||||
\xa0\xa2\xa0\x0e"\x14`\xb0Y\x85\x1b\x1f\x12\xaa7\x03)\xd9\x84\xa8\xccW\xb8{\
|
||||
\xa7L\xe2\xde\x02\x94\xc6Gp_\xcf\x80\x90\x98\xd0g\xf4\xac\x82Pc\x82\x1a\xd5\
|
||||
\x10\x08}&\xa7J\xcc\xde.1]m\x80\xf6+\xee\xfd\xae\x9bo\xc4\xf0;\x80\xef\x90\
|
||||
\x0e\x04\x06`Q!\x02\x05\xc2 \xb5\xc2\x95\x15d\xb4C&[\xf7\xd2\x04\x80\xbb\xdb\
|
||||
\x9e\xd1\x8e\x02\x90\xd8\xd4$ I\x87\x80\xf1\xf1\xdc!4\xc3\x88\x94}\xd8,TH\
|
||||
\xbb.5m\xf0C\x9f3\x1f\r\x01\x96.\x82\x1a9\xe9Q\xb8\xd2\xf8\xf25\x0c\xbe\xe7#\
|
||||
\x92\x12\x1d[\x03\t\x00E\xf4\xa6\t\xaaZ7`$\x18\x90\xf8\xf8\x80JK\x94\xa1\x01\
|
||||
\x07\xb8\x0e~X\xc3\xed\x16\xf8)\xf8~j\x12B\rI\x89_\xf7!0 \x04\xf9Q\xc0\x18\
|
||||
\x0c\xd1i\xea\x13\xb7\x04\xc0\x89\x93C\xabj\xb6\xf7@\x96\xd9_J|0:\x86R\n\xb7\
|
||||
\xd7@\xaa%\x9d\xa3$\xba.\x90RA]\xe3\x87\x1a\x89\xdd\xefeR\xc2\x1a\'\xa8\x1f\
|
||||
\x82\x0e-@m\xd1\xde\x076\xbc\x15\x97~(\x9a\x89b\x9e\xd9[s\xab!\xf7g\xd6\x1c\
|
||||
\x8f\xdb\xbel\x8e\xa1S\xc7\xda\xc6\xe6\xee\xccs\xe9\xdcYnV\x95\xd8\xf2?&q+\
|
||||
\x9c\x1b1\xf3\xbf\xcd3{\xfdJ\xdb\xf8\xde\xfd\x19.\\\xad\x08\x80\xbf\x01\xd1\
|
||||
\x86\xfa\x8b\xc7\xc0\xc8\xb7\x00\x00\x00\x00IEND\xaeB`\x82'
|
126
wxPython/wx/py/interpreter.py
Normal file
126
wxPython/wx/py/interpreter.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""Interpreter executes Python commands."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import os
|
||||
import sys
|
||||
from code import InteractiveInterpreter
|
||||
import dispatcher
|
||||
import introspect
|
||||
import wx
|
||||
|
||||
class Interpreter(InteractiveInterpreter):
|
||||
"""Interpreter based on code.InteractiveInterpreter."""
|
||||
|
||||
revision = __revision__
|
||||
|
||||
def __init__(self, locals=None, rawin=None,
|
||||
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):
|
||||
"""Create an interactive interpreter object."""
|
||||
InteractiveInterpreter.__init__(self, locals=locals)
|
||||
self.stdin = stdin
|
||||
self.stdout = stdout
|
||||
self.stderr = stderr
|
||||
if rawin:
|
||||
import __builtin__
|
||||
__builtin__.raw_input = rawin
|
||||
del __builtin__
|
||||
copyright = 'Type "help", "copyright", "credits" or "license"'
|
||||
copyright += ' for more information.'
|
||||
self.introText = 'Python %s on %s%s%s' % \
|
||||
(sys.version, sys.platform, os.linesep, copyright)
|
||||
try:
|
||||
sys.ps1
|
||||
except AttributeError:
|
||||
sys.ps1 = '>>> '
|
||||
try:
|
||||
sys.ps2
|
||||
except AttributeError:
|
||||
sys.ps2 = '... '
|
||||
self.more = 0
|
||||
# List of lists to support recursive push().
|
||||
self.commandBuffer = []
|
||||
self.startupScript = os.environ.get('PYTHONSTARTUP')
|
||||
|
||||
def push(self, command):
|
||||
"""Send command to the interpreter to be executed.
|
||||
|
||||
Because this may be called recursively, we append a new list
|
||||
onto the commandBuffer list and then append commands into
|
||||
that. If the passed in command is part of a multi-line
|
||||
command we keep appending the pieces to the last list in
|
||||
commandBuffer until we have a complete command. If not, we
|
||||
delete that last list."""
|
||||
|
||||
# In case the command is unicode try encoding it
|
||||
if type(command) == unicode:
|
||||
try:
|
||||
command = command.encode(wx.GetDefaultPyEncoding())
|
||||
except UnicodeEncodeError:
|
||||
pass # otherwise leave it alone
|
||||
|
||||
if not self.more:
|
||||
try: del self.commandBuffer[-1]
|
||||
except IndexError: pass
|
||||
if not self.more: self.commandBuffer.append([])
|
||||
self.commandBuffer[-1].append(command)
|
||||
source = '\n'.join(self.commandBuffer[-1])
|
||||
more = self.more = self.runsource(source)
|
||||
dispatcher.send(signal='Interpreter.push', sender=self,
|
||||
command=command, more=more, source=source)
|
||||
return more
|
||||
|
||||
def runsource(self, source):
|
||||
"""Compile and run source code in the interpreter."""
|
||||
stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr
|
||||
sys.stdin, sys.stdout, sys.stderr = \
|
||||
self.stdin, self.stdout, self.stderr
|
||||
more = InteractiveInterpreter.runsource(self, source)
|
||||
# If sys.std* is still what we set it to, then restore it.
|
||||
# But, if the executed source changed sys.std*, assume it was
|
||||
# meant to be changed and leave it. Power to the people.
|
||||
if sys.stdin == self.stdin:
|
||||
sys.stdin = stdin
|
||||
if sys.stdout == self.stdout:
|
||||
sys.stdout = stdout
|
||||
if sys.stderr == self.stderr:
|
||||
sys.stderr = stderr
|
||||
return more
|
||||
|
||||
def getAutoCompleteKeys(self):
|
||||
"""Return list of auto-completion keycodes."""
|
||||
return [ord('.')]
|
||||
|
||||
def getAutoCompleteList(self, command='', *args, **kwds):
|
||||
"""Return list of auto-completion options for a command.
|
||||
|
||||
The list of options will be based on the locals namespace."""
|
||||
stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr
|
||||
sys.stdin, sys.stdout, sys.stderr = \
|
||||
self.stdin, self.stdout, self.stderr
|
||||
l = introspect.getAutoCompleteList(command, self.locals,
|
||||
*args, **kwds)
|
||||
sys.stdin, sys.stdout, sys.stderr = stdin, stdout, stderr
|
||||
return l
|
||||
|
||||
def getCallTip(self, command='', *args, **kwds):
|
||||
"""Return call tip text for a command.
|
||||
|
||||
Call tip information will be based on the locals namespace."""
|
||||
return introspect.getCallTip(command, self.locals, *args, **kwds)
|
||||
|
||||
|
||||
class InterpreterAlaCarte(Interpreter):
|
||||
"""Demo Interpreter."""
|
||||
|
||||
def __init__(self, locals, rawin, stdin, stdout, stderr,
|
||||
ps1='main prompt', ps2='continuation prompt'):
|
||||
"""Create an interactive interpreter object."""
|
||||
Interpreter.__init__(self, locals=locals, rawin=rawin,
|
||||
stdin=stdin, stdout=stdout, stderr=stderr)
|
||||
sys.ps1 = ps1
|
||||
sys.ps2 = ps2
|
||||
|
||||
|
382
wxPython/wx/py/introspect.py
Normal file
382
wxPython/wx/py/introspect.py
Normal file
@@ -0,0 +1,382 @@
|
||||
"""Provides a variety of introspective-type support functions for
|
||||
things like call tips and command auto completion."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
from __future__ import nested_scopes
|
||||
|
||||
import cStringIO
|
||||
import inspect
|
||||
import sys
|
||||
import tokenize
|
||||
import types
|
||||
import wx
|
||||
|
||||
def getAutoCompleteList(command='', locals=None, includeMagic=1,
|
||||
includeSingle=1, includeDouble=1):
|
||||
"""Return list of auto-completion options for command.
|
||||
|
||||
The list of options will be based on the locals namespace."""
|
||||
attributes = []
|
||||
# Get the proper chunk of code from the command.
|
||||
root = getRoot(command, terminator='.')
|
||||
try:
|
||||
if locals is not None:
|
||||
object = eval(root, locals)
|
||||
else:
|
||||
object = eval(root)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
attributes = getAttributeNames(object, includeMagic,
|
||||
includeSingle, includeDouble)
|
||||
return attributes
|
||||
|
||||
def getAttributeNames(object, includeMagic=1, includeSingle=1,
|
||||
includeDouble=1):
|
||||
"""Return list of unique attributes, including inherited, for object."""
|
||||
attributes = []
|
||||
dict = {}
|
||||
if not hasattrAlwaysReturnsTrue(object):
|
||||
# Add some attributes that don't always get picked up.
|
||||
special_attrs = ['__bases__', '__class__', '__dict__', '__name__',
|
||||
'func_closure', 'func_code', 'func_defaults',
|
||||
'func_dict', 'func_doc', 'func_globals', 'func_name']
|
||||
attributes += [attr for attr in special_attrs \
|
||||
if hasattr(object, attr)]
|
||||
if includeMagic:
|
||||
try: attributes += object._getAttributeNames()
|
||||
except: pass
|
||||
# Get all attribute names.
|
||||
str_type = str(type(object))
|
||||
if str_type == "<type 'array'>":
|
||||
attributes += dir(object)
|
||||
else:
|
||||
attrdict = getAllAttributeNames(object)
|
||||
# Store the object's dir.
|
||||
object_dir = dir(object)
|
||||
for (obj_type_name, technique, count), attrlist in attrdict.items():
|
||||
# This complexity is necessary to avoid accessing all the
|
||||
# attributes of the object. This is very handy for objects
|
||||
# whose attributes are lazily evaluated.
|
||||
if type(object).__name__ == obj_type_name and technique == 'dir':
|
||||
attributes += attrlist
|
||||
else:
|
||||
attributes += [attr for attr in attrlist \
|
||||
if attr not in object_dir and hasattr(object, attr)]
|
||||
|
||||
# Remove duplicates from the attribute list.
|
||||
for item in attributes:
|
||||
dict[item] = None
|
||||
attributes = dict.keys()
|
||||
# new-style swig wrappings can result in non-string attributes
|
||||
# e.g. ITK http://www.itk.org/
|
||||
attributes = [attribute for attribute in attributes \
|
||||
if type(attribute) == str]
|
||||
attributes.sort(lambda x, y: cmp(x.upper(), y.upper()))
|
||||
if not includeSingle:
|
||||
attributes = filter(lambda item: item[0]!='_' \
|
||||
or item[1]=='_', attributes)
|
||||
if not includeDouble:
|
||||
attributes = filter(lambda item: item[:2]!='__', attributes)
|
||||
return attributes
|
||||
|
||||
def hasattrAlwaysReturnsTrue(object):
|
||||
return hasattr(object, 'bogu5_123_aTTri8ute')
|
||||
|
||||
def getAllAttributeNames(object):
|
||||
"""Return dict of all attributes, including inherited, for an object.
|
||||
|
||||
Recursively walk through a class and all base classes.
|
||||
"""
|
||||
attrdict = {} # (object, technique, count): [list of attributes]
|
||||
# !!!
|
||||
# Do Not use hasattr() as a test anywhere in this function,
|
||||
# because it is unreliable with remote objects: xmlrpc, soap, etc.
|
||||
# They always return true for hasattr().
|
||||
# !!!
|
||||
try:
|
||||
# This could(?) fail if the type is poorly defined without
|
||||
# even a name.
|
||||
key = type(object).__name__
|
||||
except:
|
||||
key = 'anonymous'
|
||||
# Wake up sleepy objects - a hack for ZODB objects in "ghost" state.
|
||||
wakeupcall = dir(object)
|
||||
del wakeupcall
|
||||
# Get attributes available through the normal convention.
|
||||
attributes = dir(object)
|
||||
attrdict[(key, 'dir', len(attributes))] = attributes
|
||||
# Get attributes from the object's dictionary, if it has one.
|
||||
try:
|
||||
attributes = object.__dict__.keys()
|
||||
attributes.sort()
|
||||
except: # Must catch all because object might have __getattr__.
|
||||
pass
|
||||
else:
|
||||
attrdict[(key, '__dict__', len(attributes))] = attributes
|
||||
# For a class instance, get the attributes for the class.
|
||||
try:
|
||||
klass = object.__class__
|
||||
except: # Must catch all because object might have __getattr__.
|
||||
pass
|
||||
else:
|
||||
if klass is object:
|
||||
# Break a circular reference. This happens with extension
|
||||
# classes.
|
||||
pass
|
||||
else:
|
||||
attrdict.update(getAllAttributeNames(klass))
|
||||
# Also get attributes from any and all parent classes.
|
||||
try:
|
||||
bases = object.__bases__
|
||||
except: # Must catch all because object might have __getattr__.
|
||||
pass
|
||||
else:
|
||||
if isinstance(bases, types.TupleType):
|
||||
for base in bases:
|
||||
if type(base) is types.TypeType:
|
||||
# Break a circular reference. Happens in Python 2.2.
|
||||
pass
|
||||
else:
|
||||
attrdict.update(getAllAttributeNames(base))
|
||||
return attrdict
|
||||
|
||||
def getCallTip(command='', locals=None):
|
||||
"""For a command, return a tuple of object name, argspec, tip text.
|
||||
|
||||
The call tip information will be based on the locals namespace."""
|
||||
calltip = ('', '', '') # object name, argspec, tip text.
|
||||
# Get the proper chunk of code from the command.
|
||||
root = getRoot(command, terminator='(')
|
||||
try:
|
||||
if locals is not None:
|
||||
object = eval(root, locals)
|
||||
else:
|
||||
object = eval(root)
|
||||
except:
|
||||
return calltip
|
||||
name = ''
|
||||
object, dropSelf = getBaseObject(object)
|
||||
try:
|
||||
name = object.__name__
|
||||
except AttributeError:
|
||||
pass
|
||||
tip1 = ''
|
||||
argspec = ''
|
||||
if inspect.isbuiltin(object):
|
||||
# Builtin functions don't have an argspec that we can get.
|
||||
pass
|
||||
elif inspect.isfunction(object):
|
||||
# tip1 is a string like: "getCallTip(command='', locals=None)"
|
||||
argspec = apply(inspect.formatargspec, inspect.getargspec(object))
|
||||
if dropSelf:
|
||||
# The first parameter to a method is a reference to an
|
||||
# instance, usually coded as "self", and is usually passed
|
||||
# automatically by Python; therefore we want to drop it.
|
||||
temp = argspec.split(',')
|
||||
if len(temp) == 1: # No other arguments.
|
||||
argspec = '()'
|
||||
elif temp[0][:2] == '(*': # first param is like *args, not self
|
||||
pass
|
||||
else: # Drop the first argument.
|
||||
argspec = '(' + ','.join(temp[1:]).lstrip()
|
||||
tip1 = name + argspec
|
||||
doc = ''
|
||||
if callable(object):
|
||||
try:
|
||||
doc = inspect.getdoc(object)
|
||||
except:
|
||||
pass
|
||||
if doc:
|
||||
# tip2 is the first separated line of the docstring, like:
|
||||
# "Return call tip text for a command."
|
||||
# tip3 is the rest of the docstring, like:
|
||||
# "The call tip information will be based on ... <snip>
|
||||
firstline = doc.split('\n')[0].lstrip()
|
||||
if tip1 == firstline or firstline[:len(name)+1] == name+'(':
|
||||
tip1 = ''
|
||||
else:
|
||||
tip1 += '\n\n'
|
||||
docpieces = doc.split('\n\n')
|
||||
tip2 = docpieces[0]
|
||||
tip3 = '\n\n'.join(docpieces[1:])
|
||||
tip = '%s%s\n\n%s' % (tip1, tip2, tip3)
|
||||
else:
|
||||
tip = tip1
|
||||
calltip = (name, argspec[1:-1], tip.strip())
|
||||
return calltip
|
||||
|
||||
def getRoot(command, terminator=None):
|
||||
"""Return the rightmost root portion of an arbitrary Python command.
|
||||
|
||||
Return only the root portion that can be eval()'d without side
|
||||
effects. The command would normally terminate with a '(' or
|
||||
'.'. The terminator and anything after the terminator will be
|
||||
dropped."""
|
||||
command = command.split('\n')[-1]
|
||||
if command.startswith(sys.ps2):
|
||||
command = command[len(sys.ps2):]
|
||||
command = command.lstrip()
|
||||
command = rtrimTerminus(command, terminator)
|
||||
tokens = getTokens(command)
|
||||
if not tokens:
|
||||
return ''
|
||||
if tokens[-1][0] is tokenize.ENDMARKER:
|
||||
# Remove the end marker.
|
||||
del tokens[-1]
|
||||
if not tokens:
|
||||
return ''
|
||||
if terminator == '.' and \
|
||||
(tokens[-1][1] <> '.' or tokens[-1][0] is not tokenize.OP):
|
||||
# Trap decimals in numbers, versus the dot operator.
|
||||
return ''
|
||||
else:
|
||||
# Strip off the terminator.
|
||||
if terminator and command.endswith(terminator):
|
||||
size = 0 - len(terminator)
|
||||
command = command[:size]
|
||||
command = command.rstrip()
|
||||
tokens = getTokens(command)
|
||||
tokens.reverse()
|
||||
line = ''
|
||||
start = None
|
||||
prefix = ''
|
||||
laststring = '.'
|
||||
emptyTypes = ('[]', '()', '{}')
|
||||
for token in tokens:
|
||||
tokentype = token[0]
|
||||
tokenstring = token[1]
|
||||
line = token[4]
|
||||
if tokentype is tokenize.ENDMARKER:
|
||||
continue
|
||||
if tokentype in (tokenize.NAME, tokenize.STRING, tokenize.NUMBER) \
|
||||
and laststring != '.':
|
||||
# We've reached something that's not part of the root.
|
||||
if prefix and line[token[3][1]] != ' ':
|
||||
# If it doesn't have a space after it, remove the prefix.
|
||||
prefix = ''
|
||||
break
|
||||
if tokentype in (tokenize.NAME, tokenize.STRING, tokenize.NUMBER) \
|
||||
or (tokentype is tokenize.OP and tokenstring == '.'):
|
||||
if prefix:
|
||||
# The prefix isn't valid because it comes after a dot.
|
||||
prefix = ''
|
||||
break
|
||||
else:
|
||||
# start represents the last known good point in the line.
|
||||
start = token[2][1]
|
||||
elif len(tokenstring) == 1 and tokenstring in ('[({])}'):
|
||||
# Remember, we're working backwords.
|
||||
# So prefix += tokenstring would be wrong.
|
||||
if prefix in emptyTypes and tokenstring in ('[({'):
|
||||
# We've already got an empty type identified so now we
|
||||
# are in a nested situation and we can break out with
|
||||
# what we've got.
|
||||
break
|
||||
else:
|
||||
prefix = tokenstring + prefix
|
||||
else:
|
||||
# We've reached something that's not part of the root.
|
||||
break
|
||||
laststring = tokenstring
|
||||
if start is None:
|
||||
start = len(line)
|
||||
root = line[start:]
|
||||
if prefix in emptyTypes:
|
||||
# Empty types are safe to be eval()'d and introspected.
|
||||
root = prefix + root
|
||||
return root
|
||||
|
||||
def getTokens(command):
|
||||
"""Return list of token tuples for command."""
|
||||
|
||||
# In case the command is unicode try encoding it
|
||||
if type(command) == unicode:
|
||||
try:
|
||||
command = command.encode(wx.GetDefaultPyEncoding())
|
||||
except UnicodeEncodeError:
|
||||
pass # otherwise leave it alone
|
||||
|
||||
f = cStringIO.StringIO(command)
|
||||
# tokens is a list of token tuples, each looking like:
|
||||
# (type, string, (srow, scol), (erow, ecol), line)
|
||||
tokens = []
|
||||
# Can't use list comprehension:
|
||||
# tokens = [token for token in tokenize.generate_tokens(f.readline)]
|
||||
# because of need to append as much as possible before TokenError.
|
||||
try:
|
||||
## This code wasn't backward compatible with Python 2.1.3.
|
||||
##
|
||||
## for token in tokenize.generate_tokens(f.readline):
|
||||
## tokens.append(token)
|
||||
|
||||
# This works with Python 2.1.3 (with nested_scopes).
|
||||
def eater(*args):
|
||||
tokens.append(args)
|
||||
tokenize.tokenize_loop(f.readline, eater)
|
||||
except tokenize.TokenError:
|
||||
# This is due to a premature EOF, which we expect since we are
|
||||
# feeding in fragments of Python code.
|
||||
pass
|
||||
return tokens
|
||||
|
||||
def rtrimTerminus(command, terminator=None):
|
||||
"""Return command minus anything that follows the final terminator."""
|
||||
if terminator:
|
||||
pieces = command.split(terminator)
|
||||
if len(pieces) > 1:
|
||||
command = terminator.join(pieces[:-1]) + terminator
|
||||
return command
|
||||
|
||||
def getBaseObject(object):
|
||||
"""Return base object and dropSelf indicator for an object."""
|
||||
if inspect.isbuiltin(object):
|
||||
# Builtin functions don't have an argspec that we can get.
|
||||
dropSelf = 0
|
||||
elif inspect.ismethod(object):
|
||||
# Get the function from the object otherwise
|
||||
# inspect.getargspec() complains that the object isn't a
|
||||
# Python function.
|
||||
try:
|
||||
if object.im_self is None:
|
||||
# This is an unbound method so we do not drop self
|
||||
# from the argspec, since an instance must be passed
|
||||
# as the first arg.
|
||||
dropSelf = 0
|
||||
else:
|
||||
dropSelf = 1
|
||||
object = object.im_func
|
||||
except AttributeError:
|
||||
dropSelf = 0
|
||||
elif inspect.isclass(object):
|
||||
# Get the __init__ method function for the class.
|
||||
constructor = getConstructor(object)
|
||||
if constructor is not None:
|
||||
object = constructor
|
||||
dropSelf = 1
|
||||
else:
|
||||
dropSelf = 0
|
||||
elif callable(object):
|
||||
# Get the __call__ method instead.
|
||||
try:
|
||||
object = object.__call__.im_func
|
||||
dropSelf = 1
|
||||
except AttributeError:
|
||||
dropSelf = 0
|
||||
else:
|
||||
dropSelf = 0
|
||||
return object, dropSelf
|
||||
|
||||
def getConstructor(object):
|
||||
"""Return constructor for class object, or None if there isn't one."""
|
||||
try:
|
||||
return object.__init__.im_func
|
||||
except AttributeError:
|
||||
for base in object.__bases__:
|
||||
constructor = getConstructor(base)
|
||||
if constructor is not None:
|
||||
return constructor
|
||||
return None
|
101
wxPython/wx/py/pseudo.py
Normal file
101
wxPython/wx/py/pseudo.py
Normal file
@@ -0,0 +1,101 @@
|
||||
"""Provides a variety of classes to create pseudo keywords and pseudo files."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
|
||||
class PseudoKeyword:
|
||||
"""A callable class that calls a method passed as a parameter.
|
||||
|
||||
Good for creating a pseudo keyword in the python runtime
|
||||
environment. The keyword is really an object that has a repr()
|
||||
that calls itself which calls the method that was passed in the
|
||||
init of the object. All this just to avoid having to type in the
|
||||
closing parens on a method. So, for example:
|
||||
|
||||
>>> quit = PseudoKeyword(SomeObject.someMethod)
|
||||
>>> quit
|
||||
|
||||
SomeObject.someMethod gets executed as if it had been called
|
||||
directly and the user didn't have to type the parens, like
|
||||
'quit()'. This technique is most applicable for pseudo keywords
|
||||
like quit, exit and help.
|
||||
|
||||
If SomeObject.someMethod can take parameters, they can still be
|
||||
passed by using the keyword in the traditional way with parens."""
|
||||
|
||||
def __init__(self, method):
|
||||
"""Create a callable object that executes method when called."""
|
||||
|
||||
if callable(method):
|
||||
self.method = method
|
||||
else:
|
||||
raise ValueError, 'method must be callable'
|
||||
|
||||
def __call__(self, *args, **kwds):
|
||||
self.method(*args, **kwds)
|
||||
|
||||
def __repr__(self):
|
||||
self()
|
||||
return ''
|
||||
|
||||
|
||||
class PseudoFile:
|
||||
|
||||
def __init__(self):
|
||||
"""Create a file-like object."""
|
||||
pass
|
||||
|
||||
def readline(self):
|
||||
pass
|
||||
|
||||
def write(self, s):
|
||||
pass
|
||||
|
||||
def writelines(self, l):
|
||||
map(self.write, l)
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def isatty(self):
|
||||
pass
|
||||
|
||||
|
||||
class PseudoFileIn(PseudoFile):
|
||||
|
||||
def __init__(self, readline, readlines=None):
|
||||
if callable(readline):
|
||||
self.readline = readline
|
||||
else:
|
||||
raise ValueError, 'readline must be callable'
|
||||
if callable(readlines):
|
||||
self.readlines = readlines
|
||||
|
||||
def isatty(self):
|
||||
return 1
|
||||
|
||||
|
||||
class PseudoFileOut(PseudoFile):
|
||||
|
||||
def __init__(self, write):
|
||||
if callable(write):
|
||||
self.write = write
|
||||
else:
|
||||
raise ValueError, 'write must be callable'
|
||||
|
||||
def isatty(self):
|
||||
return 1
|
||||
|
||||
|
||||
class PseudoFileErr(PseudoFile):
|
||||
|
||||
def __init__(self, write):
|
||||
if callable(write):
|
||||
self.write = write
|
||||
else:
|
||||
raise ValueError, 'write must be callable'
|
||||
|
||||
def isatty(self):
|
||||
return 1
|
1036
wxPython/wx/py/shell.py
Normal file
1036
wxPython/wx/py/shell.py
Normal file
File diff suppressed because it is too large
Load Diff
82
wxPython/wx/py/tests/test_interpreter.py
Normal file
82
wxPython/wx/py/tests/test_interpreter.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import unittest
|
||||
|
||||
# Import from this module's parent directory.
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.pardir)
|
||||
import interpreter
|
||||
del sys.path[0]
|
||||
del sys
|
||||
del os
|
||||
|
||||
|
||||
"""
|
||||
These unittest methods are preferred:
|
||||
-------------------------------------
|
||||
self.assert_(expr, msg=None)
|
||||
self.assertEqual(first, second, msg=None)
|
||||
self.assertRaises(excClass, callableObj, *args, **kwargs)
|
||||
self.fail(msg=None)
|
||||
self.failIf(expr, msg=None)
|
||||
"""
|
||||
|
||||
|
||||
class ModuleTestCase(unittest.TestCase):
|
||||
|
||||
def test_module(self):
|
||||
module = interpreter
|
||||
self.assert_(module.__author__)
|
||||
self.assert_(module.__cvsid__)
|
||||
self.assert_(module.__revision__)
|
||||
self.assert_(module.Interpreter)
|
||||
self.assert_(module.Interpreter.push)
|
||||
self.assert_(module.Interpreter.runsource)
|
||||
self.assert_(module.Interpreter.getAutoCompleteList)
|
||||
self.assert_(module.Interpreter.getCallTip)
|
||||
self.assert_(module.InterpreterAlaCarte)
|
||||
|
||||
|
||||
class InterpreterTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.output = ''
|
||||
self.i = interpreter.Interpreter(stdout=self)
|
||||
|
||||
def write(self, text):
|
||||
"""Capture output from self.i.push()."""
|
||||
self.output += text
|
||||
|
||||
def tearDown(self):
|
||||
self.output = ''
|
||||
self.i = None
|
||||
del self.i
|
||||
|
||||
def test_more(self):
|
||||
self.assertEqual(self.i.push('dir()'), 0)
|
||||
self.assertEqual(self.i.push('for n in range(3):'), 1)
|
||||
|
||||
def test_push(self):
|
||||
values = (
|
||||
('dir', '<built-in function dir>'),
|
||||
('dir()', "['__builtins__', '__doc__', '__name__']"),
|
||||
('2 + 2', '4'),
|
||||
('d = {}', ''),
|
||||
('d', '{}'),
|
||||
('del d', ''),
|
||||
('len([4,5,6])', '3'),
|
||||
)
|
||||
for input, output in values:
|
||||
if output: output += '\n'
|
||||
self.i.push(input)
|
||||
self.assertEqual(self.output, output)
|
||||
self.output = ''
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
862
wxPython/wx/py/tests/test_introspect.py
Normal file
862
wxPython/wx/py/tests/test_introspect.py
Normal file
@@ -0,0 +1,862 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import unittest
|
||||
|
||||
# Import from this module's parent directory.
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.pardir)
|
||||
import introspect
|
||||
del sys.path[0]
|
||||
del sys
|
||||
del os
|
||||
|
||||
|
||||
"""
|
||||
These unittest methods are preferred:
|
||||
-------------------------------------
|
||||
self.assert_(expr, msg=None)
|
||||
self.assertEqual(first, second, msg=None)
|
||||
self.assertRaises(excClass, callableObj, *args, **kwargs)
|
||||
self.fail(msg=None)
|
||||
self.failIf(expr, msg=None)
|
||||
"""
|
||||
|
||||
|
||||
class ModuleTestCase(unittest.TestCase):
|
||||
|
||||
def test_module(self):
|
||||
module = introspect
|
||||
self.assert_(module.__author__)
|
||||
self.assert_(module.__cvsid__)
|
||||
self.assert_(module.__revision__)
|
||||
self.assert_(module.getAllAttributeNames)
|
||||
self.assert_(module.getAttributeNames)
|
||||
self.assert_(module.getAutoCompleteList)
|
||||
self.assert_(module.getBaseObject)
|
||||
self.assert_(module.getCallTip)
|
||||
self.assert_(module.getConstructor)
|
||||
self.assert_(module.getRoot)
|
||||
self.assert_(module.rtrimTerminus)
|
||||
|
||||
|
||||
class RtrimTerminusTestCase(unittest.TestCase):
|
||||
|
||||
def test_rtrimTerminus(self):
|
||||
values = (
|
||||
('', '', ''),
|
||||
('', None, ''),
|
||||
('', '.', ''),
|
||||
('', '(', ''),
|
||||
|
||||
('.', '', '.'),
|
||||
('.', None, '.'),
|
||||
('.', '.', '.'),
|
||||
('.', '(', '.'),
|
||||
|
||||
('(', '', '('),
|
||||
('(', None, '('),
|
||||
('(', '.', '('),
|
||||
('(', '(', '('),
|
||||
|
||||
('spam', '', 'spam'),
|
||||
('spam', None, 'spam'),
|
||||
('spam', '.', 'spam'),
|
||||
('spam', '(', 'spam'),
|
||||
|
||||
('spam.', '', 'spam.'),
|
||||
('spam.', None, 'spam.'),
|
||||
('spam.', '.', 'spam.'),
|
||||
('spam.', '(', 'spam.'),
|
||||
|
||||
('spam(', '', 'spam('),
|
||||
('spam(', None, 'spam('),
|
||||
('spam(', '.', 'spam('),
|
||||
('spam(', '(', 'spam('),
|
||||
|
||||
('spam.eggs', '.', 'spam.'),
|
||||
('spam.eggs.', '.', 'spam.eggs.'),
|
||||
('spam.eggs(', '(', 'spam.eggs('),
|
||||
('spam.eggs.', '(', 'spam.eggs.'),
|
||||
('spam.eggs(', '.', 'spam.'),
|
||||
|
||||
('x = spam.', '.', 'x = spam.'),
|
||||
('x = spam.eggs', '.', 'x = spam.'),
|
||||
('x = spam.eggs.', '.', 'x = spam.eggs.'),
|
||||
('x = spam.eggs(', '(', 'x = spam.eggs('),
|
||||
)
|
||||
for input, terminator, output in values:
|
||||
result = introspect.rtrimTerminus(input, terminator)
|
||||
self.assertEqual(result, output,
|
||||
':in: %r :t: %r :out: %r :result: %r' %
|
||||
(input, terminator, output, result))
|
||||
|
||||
|
||||
class GetRootTestCase(unittest.TestCase):
|
||||
|
||||
def _checkRoot(self, input, terminator, output):
|
||||
root = introspect.getRoot(command=input, terminator=terminator)
|
||||
self.assertEqual(root, output,
|
||||
':in: %r :t: %r :out: %r :root: %r' %
|
||||
(input, terminator, output, root))
|
||||
|
||||
def test_getRoot(self):
|
||||
values = (
|
||||
('', '', ''),
|
||||
('', None, ''),
|
||||
('', '.', ''),
|
||||
('', '(', ''),
|
||||
|
||||
('.', '', '.'),
|
||||
('.', None, '.'),
|
||||
('.', '.', ''),
|
||||
('.', '(', '.'),
|
||||
|
||||
('(', '', ''),
|
||||
('(', None, ''),
|
||||
('(', '.', ''),
|
||||
('(', '(', ''),
|
||||
|
||||
('spam', '', 'spam'),
|
||||
('spam', None, 'spam'),
|
||||
('spam', '.', ''),
|
||||
('spam', '(', 'spam'),
|
||||
|
||||
('spam.', '', 'spam.'),
|
||||
('spam.', None, 'spam.'),
|
||||
('spam.', '.', 'spam'),
|
||||
('spam.', '(', 'spam.'),
|
||||
|
||||
('spam(', '', ''),
|
||||
('spam(', None, ''),
|
||||
('spam(', '.', ''),
|
||||
('spam(', '(', 'spam'),
|
||||
|
||||
('spam.eggs', '.', 'spam'),
|
||||
('spam.eggs.', '.', 'spam.eggs'),
|
||||
('spam.eggs(', '(', 'spam.eggs'),
|
||||
('spam.eggs.', '(', 'spam.eggs.'),
|
||||
('spam.eggs(', '.', 'spam'),
|
||||
|
||||
('x = spam.', '.', 'spam'),
|
||||
('x = spam.eggs', '.', 'spam'),
|
||||
('x = spam.eggs.', '.', 'spam.eggs'),
|
||||
('x = spam.eggs(', '(', 'spam.eggs'),
|
||||
|
||||
('for n in range(3):\n d.', '.', 'd'),
|
||||
('for n in range(3):\n... d.', '.', 'd'),
|
||||
)
|
||||
for input, terminator, output in values:
|
||||
self._checkRoot(input, terminator, output)
|
||||
|
||||
def test_getRoot_Advanced(self):
|
||||
values = (
|
||||
('spam_', '', 'spam_'),
|
||||
('spam_', None, 'spam_'),
|
||||
('spam_', '.', ''),
|
||||
('spam_', '(', 'spam_'),
|
||||
|
||||
('_spam', '', '_spam'),
|
||||
('_spam', None, '_spam'),
|
||||
('_spam', '.', ''),
|
||||
('_spam', '(', '_spam'),
|
||||
|
||||
('spam_eggs', '', 'spam_eggs'),
|
||||
('spam_eggs', None, 'spam_eggs'),
|
||||
('spam_eggs', '.', ''),
|
||||
('spam_eggs', '(', 'spam_eggs'),
|
||||
|
||||
('spam123', '', 'spam123'),
|
||||
('spam123', None, 'spam123'),
|
||||
('spam123', '.', ''),
|
||||
('spam123', '(', 'spam123'),
|
||||
|
||||
('spam_123', '', 'spam_123'),
|
||||
('spam_123', None, 'spam_123'),
|
||||
('spam_123', '.', ''),
|
||||
('spam_123', '(', 'spam_123'),
|
||||
)
|
||||
for input, terminator, output in values:
|
||||
self._checkRoot(input, terminator, output)
|
||||
|
||||
## The original intent was to detect when we were inside a string.
|
||||
## That has proven to be very difficult, for little benefit.
|
||||
## The fact that autocomplete or calltips might be triggered inside
|
||||
## a string is not a big deal. Sometimes it is even helpful.
|
||||
|
||||
## def test_getRoot_InsideStrings(self):
|
||||
## values = (
|
||||
## ('x = ".', '.', ''),
|
||||
## ("x = '.", '.', ''),
|
||||
## ('x = """.', '.', ''),
|
||||
## ("x = '''.", '.', ''),
|
||||
##
|
||||
## ('x = "(', '(', ''),
|
||||
## ("x = '(", '(', ''),
|
||||
## ('x = """(', '(', ''),
|
||||
## ("x = '''(", '(', ''),
|
||||
##
|
||||
## ('x = "spam', '.', ''),
|
||||
## ('x = "spam.', '.', ''),
|
||||
## ("x = 'spam.", '.', ''),
|
||||
## ('x = """spam.', '.', ''),
|
||||
## ("x = '''spam.", '.', ''),
|
||||
##
|
||||
## ('x = "spam', '(', ''),
|
||||
## ('x = "spam(', '(', ''),
|
||||
## ("x = 'spam(", '(', ''),
|
||||
## ('x = """spam(', '(', ''),
|
||||
## ("x = '''spam(", '(', ''),
|
||||
##
|
||||
## ('x = "spam.eggs.', '.', ''),
|
||||
## ("x = 'spam.eggs.", '.', ''),
|
||||
## ('x = """spam.eggs.', '.', ''),
|
||||
## ("x = '''spam.eggs.", '.', ''),
|
||||
##
|
||||
## ('x = "spam.eggs(', '(', ''),
|
||||
## ("x = 'spam.eggs(", '(', ''),
|
||||
## ('x = """spam.eggs(', '(', ''),
|
||||
## ("x = '''spam.eggs(", '(', ''),
|
||||
## )
|
||||
## for input, terminator, output in values:
|
||||
## self._checkRoot(input, terminator, output)
|
||||
|
||||
def test_getRoot_EmptyTypes(self):
|
||||
values = (
|
||||
("''.", '.', "''"),
|
||||
('"".', '.', '""'),
|
||||
('"""""".', '.', '""""""'),
|
||||
("''''''.", '.', "''''''"),
|
||||
|
||||
('[].', '.', '[]'),
|
||||
('().', '.', '()'),
|
||||
('{}.', '.', '{}'),
|
||||
|
||||
('[](', '(', '[]'),
|
||||
('()(', '(', '()'),
|
||||
('{}(', '(', '{}'),
|
||||
|
||||
("x = ''.", '.', "''"),
|
||||
('x = "".', '.', '""'),
|
||||
('x = """""".', '.', '""""""'),
|
||||
("x = ''''''.", '.', "''''''"),
|
||||
|
||||
('x = [].', '.', '[]'),
|
||||
('x = ().', '.', '()'),
|
||||
('x = {}.', '.', '{}'),
|
||||
|
||||
('x = [](', '(', '[]'),
|
||||
('x = ()(', '(', '()'),
|
||||
('x = {}(', '(', '{}'),
|
||||
|
||||
('print [].', '.', '[]'),
|
||||
('print ().', '.', '()'),
|
||||
('print {}.', '.', '{}'),
|
||||
|
||||
('print [](', '(', '[]'),
|
||||
('print ()(', '(', '()'),
|
||||
('print {}(', '(', '{}'),
|
||||
|
||||
("''.attr.", '.', "''.attr"),
|
||||
('"".attr.', '.', '"".attr'),
|
||||
('"""""".attr.', '.', '"""""".attr'),
|
||||
("''''''.attr.", '.', "''''''.attr"),
|
||||
|
||||
('[].attr.', '.', '[].attr'),
|
||||
('().attr.', '.', '().attr'),
|
||||
('{}.attr.', '.', '{}.attr'),
|
||||
|
||||
('[].attr(', '(', '[].attr'),
|
||||
('().attr(', '(', '().attr'),
|
||||
('{}.attr(', '(', '{}.attr'),
|
||||
|
||||
('spam().', '.', ''),
|
||||
('spam_().', '.', ''),
|
||||
('spam5().', '.', ''),
|
||||
('spam[]().', '.', ''),
|
||||
('spam()[].', '.', ''),
|
||||
('spam[]{}.', '.', ''),
|
||||
|
||||
("spam(''.", '.', "''"),
|
||||
('spam("".', '.', '""'),
|
||||
('spam("""""".', '.', '""""""'),
|
||||
("spam(''''''.", '.', "''''''"),
|
||||
|
||||
('spam([].', '.', '[]'),
|
||||
('spam(().', '.', '()'),
|
||||
('spam({}.', '.', '{}'),
|
||||
('spam[[].', '.', '[]'),
|
||||
('spam[().', '.', '()'),
|
||||
('spam[{}.', '.', '{}'),
|
||||
('x = {[].', '.', '[]'),
|
||||
('x = {().', '.', '()'),
|
||||
('x = {{}.', '.', '{}'),
|
||||
|
||||
('spam,[].', '.', '[]'),
|
||||
('spam+[].', '.', '[]'),
|
||||
('spam-[].', '.', '[]'),
|
||||
('spam*[].', '.', '[]'),
|
||||
('spam/[].', '.', '[]'),
|
||||
('spam=[].', '.', '[]'),
|
||||
('spam%[].', '.', '[]'),
|
||||
('spam<[].', '.', '[]'),
|
||||
('spam>[].', '.', '[]'),
|
||||
('spam&[].', '.', '[]'),
|
||||
('spam|[].', '.', '[]'),
|
||||
('spam^[].', '.', '[]'),
|
||||
('spam~[].', '.', '[]'),
|
||||
('spam:[].', '.', '[]'),
|
||||
|
||||
('spam,().', '.', '()'),
|
||||
('spam+().', '.', '()'),
|
||||
('spam-().', '.', '()'),
|
||||
('spam*().', '.', '()'),
|
||||
('spam/().', '.', '()'),
|
||||
('spam=().', '.', '()'),
|
||||
('spam%().', '.', '()'),
|
||||
('spam<().', '.', '()'),
|
||||
('spam>().', '.', '()'),
|
||||
('spam&().', '.', '()'),
|
||||
('spam|().', '.', '()'),
|
||||
('spam^().', '.', '()'),
|
||||
('spam~().', '.', '()'),
|
||||
('spam:().', '.', '()'),
|
||||
|
||||
('spam,{}.', '.', '{}'),
|
||||
('spam+{}.', '.', '{}'),
|
||||
('spam-{}.', '.', '{}'),
|
||||
('spam*{}.', '.', '{}'),
|
||||
('spam/{}.', '.', '{}'),
|
||||
('spam={}.', '.', '{}'),
|
||||
('spam%{}.', '.', '{}'),
|
||||
('spam<{}.', '.', '{}'),
|
||||
('spam>{}.', '.', '{}'),
|
||||
('spam&{}.', '.', '{}'),
|
||||
('spam|{}.', '.', '{}'),
|
||||
('spam^{}.', '.', '{}'),
|
||||
('spam~{}.', '.', '{}'),
|
||||
('spam:{}.', '.', '{}'),
|
||||
)
|
||||
for input, terminator, output in values:
|
||||
self._checkRoot(input, terminator, output)
|
||||
|
||||
|
||||
# Support for GetBaseObjectTestCase and GetAttributeNamesTestCase.
|
||||
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
def _private(self):
|
||||
pass
|
||||
|
||||
class Bar:
|
||||
pass
|
||||
|
||||
class Spam:
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
def foo(self):
|
||||
pass
|
||||
|
||||
def bar(spam):
|
||||
# It shouldn't matter what we call "self".
|
||||
pass
|
||||
|
||||
def eggs(self):
|
||||
pass
|
||||
|
||||
def ham(eggs):
|
||||
pass
|
||||
|
||||
class GetBaseObjectTestCase(unittest.TestCase):
|
||||
|
||||
def test_getBaseObject(self):
|
||||
spam = Spam()
|
||||
eggs = Spam.eggs
|
||||
listappend = [].append
|
||||
spamda = lambda: None
|
||||
values = (
|
||||
('spam', 'spam', 0),
|
||||
(123, 123, 0),
|
||||
(12.3, 12.3, 0),
|
||||
([], [], 0),
|
||||
((), (), 0),
|
||||
({}, {}, 0),
|
||||
# Builtin function.
|
||||
(len, len, 0),
|
||||
# Builtin method.
|
||||
(listappend, listappend, 0),
|
||||
# User function.
|
||||
(ham, ham, 0),
|
||||
# Byte-compiled code.
|
||||
(ham.func_code, ham.func_code, 0),
|
||||
# Lambda.
|
||||
(spamda, spamda, 0),
|
||||
# Class with init.
|
||||
(Foo, Foo.__init__.im_func, 1),
|
||||
# Class with no init.
|
||||
(Bar, Bar, 0),
|
||||
# Bound method.
|
||||
(spam.foo, spam.foo.im_func, 1),
|
||||
# Bound method with self named something else (spam).
|
||||
(spam.bar, spam.bar.im_func, 1),
|
||||
# Unbound method. (Do not drop the self argument.)
|
||||
(eggs, eggs.im_func, 0),
|
||||
# Callable instance.
|
||||
(spam, spam.__call__.im_func, 1),
|
||||
)
|
||||
for object, baseObject, dropSelf in values:
|
||||
result = introspect.getBaseObject(object)
|
||||
self.assertEqual(result, (baseObject, dropSelf))
|
||||
|
||||
|
||||
class GetAttributeTestCase(unittest.TestCase):
|
||||
"""Base class for other test case classes."""
|
||||
|
||||
def setUp(self):
|
||||
self.values = (
|
||||
'__abs__',
|
||||
'__add__',
|
||||
'__and__',
|
||||
'__base__',
|
||||
'__bases__',
|
||||
'__basicsize__',
|
||||
'__builtins__',
|
||||
'__call__',
|
||||
'__class__',
|
||||
'__cmp__',
|
||||
'__coerce__',
|
||||
'__contains__',
|
||||
'__del__',
|
||||
'__delattr__',
|
||||
'__delitem__',
|
||||
'__delslice__',
|
||||
'__dict__',
|
||||
'__dictoffset__',
|
||||
'__div__',
|
||||
'__divmod__',
|
||||
'__doc__',
|
||||
'__eq__',
|
||||
'__file__',
|
||||
'__flags__',
|
||||
'__float__',
|
||||
'__floordiv__',
|
||||
'__ge__',
|
||||
'__get__',
|
||||
'__getattr__',
|
||||
'__getattribute__',
|
||||
'__getitem__',
|
||||
'__getslice__',
|
||||
'__gt__',
|
||||
'__hash__',
|
||||
'__hex__',
|
||||
'__iadd__',
|
||||
'__imul__',
|
||||
'__init__',
|
||||
'__int__',
|
||||
'__invert__',
|
||||
'__itemsize__',
|
||||
'__iter__',
|
||||
'__le__',
|
||||
'__len__',
|
||||
'__long__',
|
||||
'__lshift__',
|
||||
'__lt__',
|
||||
'__mod__',
|
||||
'__module__',
|
||||
'__mro__',
|
||||
'__mul__',
|
||||
'__name__',
|
||||
'__ne__',
|
||||
'__neg__',
|
||||
'__new__',
|
||||
'__nonzero__',
|
||||
'__oct__',
|
||||
'__or__',
|
||||
'__path__',
|
||||
'__pos__',
|
||||
'__pow__',
|
||||
'__radd__',
|
||||
'__rand__',
|
||||
'__rdiv__',
|
||||
'__rdivmod__',
|
||||
'__reduce__',
|
||||
'__repr__',
|
||||
'__rfloordiv__',
|
||||
'__rlshift__',
|
||||
'__rmod__',
|
||||
'__rmul__',
|
||||
'__ror__',
|
||||
'__rpow__',
|
||||
'__rrshift__',
|
||||
'__rshift__',
|
||||
'__rsub__',
|
||||
'__rtruediv__',
|
||||
'__rxor__',
|
||||
'__self__',
|
||||
'__setattr__',
|
||||
'__setitem__',
|
||||
'__setslice__',
|
||||
'__str__',
|
||||
'__sub__',
|
||||
'__subclasses__',
|
||||
'__truediv__',
|
||||
'__warningregistry__',
|
||||
'__weakrefoffset__',
|
||||
'__xor__',
|
||||
'append',
|
||||
'capitalize',
|
||||
'center',
|
||||
'clear',
|
||||
'close',
|
||||
'closed',
|
||||
'co_argcount',
|
||||
'co_cellvars',
|
||||
'co_code',
|
||||
'co_consts',
|
||||
'co_filename',
|
||||
'co_firstlineno',
|
||||
'co_flags',
|
||||
'co_freevars',
|
||||
'co_lnotab',
|
||||
'co_name',
|
||||
'co_names',
|
||||
'co_nlocals',
|
||||
'co_stacksize',
|
||||
'co_varnames',
|
||||
'conjugate',
|
||||
'copy',
|
||||
'count',
|
||||
'decode',
|
||||
'encode',
|
||||
'endswith',
|
||||
'expandtabs',
|
||||
'extend',
|
||||
'fileno',
|
||||
'find',
|
||||
'flush',
|
||||
'func_closure',
|
||||
'func_code',
|
||||
'func_defaults',
|
||||
'func_dict',
|
||||
'func_doc',
|
||||
'func_globals',
|
||||
'func_name',
|
||||
'get',
|
||||
'has_key',
|
||||
'im_class',
|
||||
'im_func',
|
||||
'im_self',
|
||||
'imag',
|
||||
'index',
|
||||
'insert',
|
||||
'isalnum',
|
||||
'isalpha',
|
||||
'isatty',
|
||||
'isdigit',
|
||||
'islower',
|
||||
'isspace',
|
||||
'istitle',
|
||||
'isupper',
|
||||
'items',
|
||||
'iteritems',
|
||||
'iterkeys',
|
||||
'itervalues',
|
||||
'join',
|
||||
'keys',
|
||||
'ljust',
|
||||
'lower',
|
||||
'lstrip',
|
||||
'mode',
|
||||
'mro',
|
||||
'name',
|
||||
'pop',
|
||||
'popitem',
|
||||
'real',
|
||||
'read',
|
||||
'readinto',
|
||||
'readline',
|
||||
'readlines',
|
||||
'remove',
|
||||
'replace',
|
||||
'reverse',
|
||||
'rfind',
|
||||
'rindex',
|
||||
'rjust',
|
||||
'rstrip',
|
||||
'seek',
|
||||
'setdefault',
|
||||
'softspace',
|
||||
'sort',
|
||||
'split',
|
||||
'splitlines',
|
||||
'start',
|
||||
'startswith',
|
||||
'step',
|
||||
'stop',
|
||||
'strip',
|
||||
'swapcase',
|
||||
'tell',
|
||||
'title',
|
||||
'tolist',
|
||||
'translate',
|
||||
'truncate',
|
||||
'update',
|
||||
'upper',
|
||||
'values',
|
||||
'write',
|
||||
'writelines',
|
||||
'xreadlines',
|
||||
)
|
||||
|
||||
# Since getAllAttributeNames() calls str(object),
|
||||
# we need to test for a broken __str__ method.
|
||||
class BrokenStr:
|
||||
def __str__(self):
|
||||
raise Exception
|
||||
|
||||
brokenStr = BrokenStr()
|
||||
|
||||
class GetAttributeNamesTestCase(GetAttributeTestCase):
|
||||
|
||||
def setUp(self):
|
||||
GetAttributeTestCase.setUp(self)
|
||||
from wx import py
|
||||
spam = Spam()
|
||||
self.f = open('test_introspect.py')
|
||||
self.items = (
|
||||
None,
|
||||
int(123),
|
||||
long(123),
|
||||
float(123),
|
||||
complex(123),
|
||||
"",
|
||||
unicode(""),
|
||||
[],
|
||||
(),
|
||||
xrange(0),
|
||||
{},
|
||||
# Builtin function.
|
||||
len,
|
||||
# Builtin method.
|
||||
[].append,
|
||||
# User function.
|
||||
ham,
|
||||
# Byte-compiled code.
|
||||
ham.func_code,
|
||||
# Lambda.
|
||||
lambda: None,
|
||||
# Class with no init.
|
||||
Bar,
|
||||
# Instance with no init.
|
||||
Bar(),
|
||||
# Class with init and del.
|
||||
Foo,
|
||||
# Instance with init and del.
|
||||
Foo(),
|
||||
# Bound method.
|
||||
spam.foo,
|
||||
# Unbound method.
|
||||
Spam.eggs,
|
||||
# Callable instance.
|
||||
spam,
|
||||
# Module.
|
||||
introspect,
|
||||
# Package.
|
||||
py,
|
||||
# Buffer.
|
||||
buffer(''),
|
||||
# File.
|
||||
self.f,
|
||||
# Slice.
|
||||
slice(0),
|
||||
# Ellipsis.
|
||||
Ellipsis,
|
||||
# BrokenStr class.
|
||||
BrokenStr,
|
||||
# BrokenStr instance.
|
||||
brokenStr,
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
self.items = None
|
||||
self.f.close()
|
||||
|
||||
def test_getAttributeNames(self):
|
||||
for item in self.items:
|
||||
self._checkAttributeNames(item)
|
||||
if __builtins__.has_key('object'):
|
||||
self._checkAttributeNames(object)
|
||||
|
||||
def test_getAttributeNames_NoSingle(self):
|
||||
for item in self.items:
|
||||
result = introspect.getAttributeNames(item, includeSingle=0)
|
||||
attributes = [attribute for attribute in result \
|
||||
if attribute[0] != '_' or attribute[:2] == '__']
|
||||
self.assertEqual(result, attributes,
|
||||
':item: %r' % (item,))
|
||||
|
||||
def test_getAttributeNames_NoDouble(self):
|
||||
for item in self.items:
|
||||
result = introspect.getAttributeNames(item, includeDouble=0)
|
||||
attributes = [attribute for attribute in result \
|
||||
if attribute[:2] != '__']
|
||||
self.assertEqual(result, attributes,
|
||||
':item: %r' % (item,))
|
||||
|
||||
def test_getAttributeNames_NoSingleOrDouble(self):
|
||||
for item in self.items:
|
||||
result = introspect.getAttributeNames(item, includeSingle=0,
|
||||
includeDouble=0)
|
||||
attributes = [attribute for attribute in result \
|
||||
if attribute[0] != '_']
|
||||
self.assertEqual(result, attributes,
|
||||
':item: %r' % (item,))
|
||||
|
||||
def _checkAttributeNames(self, item):
|
||||
result = introspect.getAttributeNames(item)
|
||||
attributes = [attribute for attribute in self.values \
|
||||
if hasattr(item, attribute)]
|
||||
for attribute in attributes:
|
||||
self.assert_(attribute in result,
|
||||
':item: %r :attribute: %r' % (item, attribute))
|
||||
|
||||
|
||||
class GetAutoCompleteListTestCase(GetAttributeTestCase):
|
||||
|
||||
def setUp(self):
|
||||
GetAttributeTestCase.setUp(self)
|
||||
self.items = (
|
||||
'None.',
|
||||
'123 .',
|
||||
'"".',
|
||||
'[].',
|
||||
'().',
|
||||
'{}.',
|
||||
# Builtin function.
|
||||
'len.',
|
||||
# Builtin method.
|
||||
'[].append.',
|
||||
)
|
||||
|
||||
def test_getAutoCompleteList(self):
|
||||
for item in self.items:
|
||||
result = introspect.getAutoCompleteList(item)
|
||||
object = eval(item[:-1])
|
||||
attributes = [attribute for attribute in self.values \
|
||||
if hasattr(object, attribute)]
|
||||
for attribute in attributes:
|
||||
self.assert_(attribute in result,
|
||||
':item: %r :attribute: %r' % (item, attribute))
|
||||
|
||||
def test_getAutoCompleteList_NoSingle(self):
|
||||
for item in self.items:
|
||||
result = introspect.getAutoCompleteList(item, includeSingle=0)
|
||||
attributes = [attribute for attribute in result \
|
||||
if attribute[0] != '_' or attribute[:2] == '__']
|
||||
self.assertEqual(result, attributes,
|
||||
':item: %r' % (item,))
|
||||
|
||||
def test_getAutoCompleteList_NoDouble(self):
|
||||
for item in self.items:
|
||||
result = introspect.getAutoCompleteList(item, includeDouble=0)
|
||||
attributes = [attribute for attribute in result \
|
||||
if attribute[:2] != '__']
|
||||
self.assertEqual(result, attributes,
|
||||
':item: %r' % (item,))
|
||||
|
||||
def test_getAutoCompleteList_NoSingleOrDouble(self):
|
||||
for item in self.items:
|
||||
result = introspect.getAutoCompleteList(item, includeSingle=0,
|
||||
includeDouble=0)
|
||||
attributes = [attribute for attribute in result \
|
||||
if attribute[0] != '_']
|
||||
self.assertEqual(result, attributes,
|
||||
':item: %r' % (item,))
|
||||
|
||||
|
||||
# Support for GetConstructorTestCase.
|
||||
|
||||
class A1:
|
||||
def __init__(self, a):
|
||||
self.a = a
|
||||
|
||||
class B1(A1):
|
||||
def __init__(self, b):
|
||||
self.b = b
|
||||
|
||||
class C1(A1):
|
||||
pass
|
||||
|
||||
class D1(C1, B1):
|
||||
pass
|
||||
|
||||
if __builtins__.has_key('object'):
|
||||
class A2(object):
|
||||
def __init__(self, a):
|
||||
self.a = a
|
||||
|
||||
class B2(A2):
|
||||
def __init__(self, b):
|
||||
self.b = b
|
||||
|
||||
class C2(A2):
|
||||
pass
|
||||
|
||||
class D2(C2, B2):
|
||||
pass
|
||||
|
||||
class N:
|
||||
pass
|
||||
|
||||
class O:
|
||||
def __init__(self, a, b=2, *args, **kwargs):
|
||||
pass
|
||||
|
||||
class P(O):
|
||||
pass
|
||||
|
||||
class Q(P):
|
||||
def __init__(self, c, d=4):
|
||||
pass
|
||||
|
||||
class GetConstructorTestCase(unittest.TestCase):
|
||||
|
||||
def test_getConstructor(self):
|
||||
args = ('self', 'a', 'b', 'args', 'kwargs')
|
||||
varnames = introspect.getConstructor(O).func_code.co_varnames
|
||||
self.assertEqual(varnames, args)
|
||||
varnames = introspect.getConstructor(P).func_code.co_varnames
|
||||
self.assertEqual(varnames, args)
|
||||
args = ('self', 'c', 'd')
|
||||
varnames = introspect.getConstructor(Q).func_code.co_varnames
|
||||
self.assertEqual(varnames, args)
|
||||
|
||||
def test_getConstructor_None(self):
|
||||
values = (N, 1, 'spam', {}, [], (), dir)
|
||||
for value in values:
|
||||
self.assertEqual(introspect.getConstructor(N), None)
|
||||
|
||||
def test_getConstructor_MultipleInheritance(self):
|
||||
# Test old style inheritance rules.
|
||||
args = ('self', 'a')
|
||||
varnames = introspect.getConstructor(D1).func_code.co_varnames
|
||||
self.assertEqual(varnames, args)
|
||||
if __builtins__.has_key('object'):
|
||||
# Test new style inheritance rules as well.
|
||||
args = ('self', 'b')
|
||||
varnames = introspect.getConstructor(D2).func_code.co_varnames
|
||||
self.assertEqual(varnames, args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
81
wxPython/wx/py/tests/test_pseudo.py
Normal file
81
wxPython/wx/py/tests/test_pseudo.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import unittest
|
||||
|
||||
# Import from this module's parent directory.
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.pardir)
|
||||
import pseudo
|
||||
del sys.path[0]
|
||||
del sys
|
||||
del os
|
||||
|
||||
|
||||
"""
|
||||
These unittest methods are preferred:
|
||||
-------------------------------------
|
||||
self.assert_(expr, msg=None)
|
||||
self.assertEqual(first, second, msg=None)
|
||||
self.assertRaises(excClass, callableObj, *args, **kwargs)
|
||||
self.fail(msg=None)
|
||||
self.failIf(expr, msg=None)
|
||||
"""
|
||||
|
||||
|
||||
class ModuleTestCase(unittest.TestCase):
|
||||
|
||||
def test_module(self):
|
||||
module = pseudo
|
||||
self.assert_(module.__author__)
|
||||
self.assert_(module.__cvsid__)
|
||||
self.assert_(module.__revision__)
|
||||
self.assert_(module.PseudoFile)
|
||||
self.assert_(module.PseudoFileErr)
|
||||
self.assert_(module.PseudoFileIn)
|
||||
self.assert_(module.PseudoFileOut)
|
||||
self.assert_(module.PseudoKeyword)
|
||||
|
||||
|
||||
class PseudoTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
|
||||
class PseudoFileTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
|
||||
class PseudoFileOutTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def _write(self):
|
||||
pass
|
||||
|
||||
def test_PseudoFileOut_goodInit(self):
|
||||
self.assert_(pseudo.PseudoFileOut(write=self._write))
|
||||
|
||||
def test_PseudoFileOut_badInit(self):
|
||||
self.assertRaises(ValueError, pseudo.PseudoFileOut, write='bad')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
49
wxPython/wx/py/tests/test_version.py
Normal file
49
wxPython/wx/py/tests/test_version.py
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
import unittest
|
||||
|
||||
import types
|
||||
|
||||
# Import from this module's parent directory.
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.pardir)
|
||||
import version
|
||||
del sys.path[0]
|
||||
del sys
|
||||
del os
|
||||
|
||||
|
||||
"""
|
||||
These unittest methods are preferred:
|
||||
-------------------------------------
|
||||
self.assert_(expr, msg=None)
|
||||
self.assertEqual(first, second, msg=None)
|
||||
self.assertRaises(excClass, callableObj, *args, **kwargs)
|
||||
self.fail(msg=None)
|
||||
self.failIf(expr, msg=None)
|
||||
"""
|
||||
|
||||
|
||||
class ModuleTestCase(unittest.TestCase):
|
||||
|
||||
def test_module(self):
|
||||
module = version
|
||||
self.assert_(module.__author__)
|
||||
self.assert_(module.__cvsid__)
|
||||
self.assert_(module.__revision__)
|
||||
self.assert_(module.VERSION)
|
||||
|
||||
|
||||
class VersionTestCase(unittest.TestCase):
|
||||
|
||||
def test_VERSION(self):
|
||||
self.assert_(type(version.VERSION) is types.StringType)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
25
wxPython/wx/py/tests/testall.py
Normal file
25
wxPython/wx/py/tests/testall.py
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
|
||||
import unittest
|
||||
import glob
|
||||
import os
|
||||
|
||||
|
||||
def suite():
|
||||
"""Return a test suite containing all test cases in all test modules.
|
||||
Searches the current directory for any modules matching test_*.py."""
|
||||
suite = unittest.TestSuite()
|
||||
for filename in glob.glob('test_*.py'):
|
||||
module = __import__(os.path.splitext(filename)[0])
|
||||
suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(module))
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='suite')
|
||||
|
9
wxPython/wx/py/version.py
Normal file
9
wxPython/wx/py/version.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""Provides an object representing the current 'version' or 'release'
|
||||
of Py as a whole. Individual classes, such as the shell, filling and
|
||||
interpreter, each have a revision property based on the CVS Revision."""
|
||||
|
||||
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
|
||||
__cvsid__ = "$Id$"
|
||||
__revision__ = "$Revision$"[11:-2]
|
||||
|
||||
VERSION = '0.9.4'
|
Reference in New Issue
Block a user