Add wxOVERRIDE and use it in common and wxOSX code.
Make overriding virtual methods more explicit and enable additional checks provided by C++11 compilers when "override" is used. Closes #16100. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76173 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -212,7 +212,7 @@ public :
|
||||
Init( image , transform );
|
||||
}
|
||||
|
||||
virtual void Render( CGContextRef ctxRef )
|
||||
virtual void Render( CGContextRef ctxRef ) wxOVERRIDE
|
||||
{
|
||||
if (m_image != NULL)
|
||||
wxMacDrawCGImage( ctxRef, &m_imageBounds, m_image );
|
||||
@@ -260,7 +260,7 @@ public :
|
||||
CGContextStrokeLineSegments( ctxRef , pts , count );
|
||||
}
|
||||
|
||||
virtual void Render( CGContextRef ctxRef )
|
||||
virtual void Render( CGContextRef ctxRef ) wxOVERRIDE
|
||||
{
|
||||
switch ( m_hatch )
|
||||
{
|
||||
@@ -941,7 +941,7 @@ public:
|
||||
~wxMacCoreGraphicsBitmapData();
|
||||
|
||||
virtual CGImageRef GetBitmap() { return m_bitmap; }
|
||||
virtual void* GetNativeBitmap() const { return m_bitmap; }
|
||||
virtual void* GetNativeBitmap() const wxOVERRIDE { return m_bitmap; }
|
||||
bool IsMonochrome() { return m_monochrome; }
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
@@ -982,53 +982,53 @@ public :
|
||||
|
||||
virtual ~wxMacCoreGraphicsMatrixData() ;
|
||||
|
||||
virtual wxGraphicsObjectRefData *Clone() const ;
|
||||
virtual wxGraphicsObjectRefData *Clone() const wxOVERRIDE ;
|
||||
|
||||
// concatenates the matrix
|
||||
virtual void Concat( const wxGraphicsMatrixData *t );
|
||||
virtual void Concat( const wxGraphicsMatrixData *t ) wxOVERRIDE;
|
||||
|
||||
// sets the matrix to the respective values
|
||||
virtual void Set(wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0,
|
||||
wxDouble tx=0.0, wxDouble ty=0.0);
|
||||
wxDouble tx=0.0, wxDouble ty=0.0) wxOVERRIDE;
|
||||
|
||||
// gets the component valuess of the matrix
|
||||
virtual void Get(wxDouble* a=NULL, wxDouble* b=NULL, wxDouble* c=NULL,
|
||||
wxDouble* d=NULL, wxDouble* tx=NULL, wxDouble* ty=NULL) const;
|
||||
wxDouble* d=NULL, wxDouble* tx=NULL, wxDouble* ty=NULL) const wxOVERRIDE;
|
||||
|
||||
// makes this the inverse matrix
|
||||
virtual void Invert();
|
||||
virtual void Invert() wxOVERRIDE;
|
||||
|
||||
// returns true if the elements of the transformation matrix are equal ?
|
||||
virtual bool IsEqual( const wxGraphicsMatrixData* t) const ;
|
||||
virtual bool IsEqual( const wxGraphicsMatrixData* t) const wxOVERRIDE ;
|
||||
|
||||
// return true if this is the identity matrix
|
||||
virtual bool IsIdentity() const;
|
||||
virtual bool IsIdentity() const wxOVERRIDE;
|
||||
|
||||
//
|
||||
// transformation
|
||||
//
|
||||
|
||||
// add the translation to this matrix
|
||||
virtual void Translate( wxDouble dx , wxDouble dy );
|
||||
virtual void Translate( wxDouble dx , wxDouble dy ) wxOVERRIDE;
|
||||
|
||||
// add the scale to this matrix
|
||||
virtual void Scale( wxDouble xScale , wxDouble yScale );
|
||||
virtual void Scale( wxDouble xScale , wxDouble yScale ) wxOVERRIDE;
|
||||
|
||||
// add the rotation to this matrix (radians)
|
||||
virtual void Rotate( wxDouble angle );
|
||||
virtual void Rotate( wxDouble angle ) wxOVERRIDE;
|
||||
|
||||
//
|
||||
// apply the transforms
|
||||
//
|
||||
|
||||
// applies that matrix to the point
|
||||
virtual void TransformPoint( wxDouble *x, wxDouble *y ) const;
|
||||
virtual void TransformPoint( wxDouble *x, wxDouble *y ) const wxOVERRIDE;
|
||||
|
||||
// applies the matrix except for translations
|
||||
virtual void TransformDistance( wxDouble *dx, wxDouble *dy ) const;
|
||||
virtual void TransformDistance( wxDouble *dx, wxDouble *dy ) const wxOVERRIDE;
|
||||
|
||||
// returns the native representation
|
||||
virtual void * GetNativeMatrix() const;
|
||||
virtual void * GetNativeMatrix() const wxOVERRIDE;
|
||||
|
||||
private :
|
||||
CGAffineTransform m_matrix;
|
||||
@@ -1161,25 +1161,25 @@ public :
|
||||
|
||||
~wxMacCoreGraphicsPathData();
|
||||
|
||||
virtual wxGraphicsObjectRefData *Clone() const;
|
||||
virtual wxGraphicsObjectRefData *Clone() const wxOVERRIDE;
|
||||
|
||||
// begins a new subpath at (x,y)
|
||||
virtual void MoveToPoint( wxDouble x, wxDouble y );
|
||||
virtual void MoveToPoint( wxDouble x, wxDouble y ) wxOVERRIDE;
|
||||
|
||||
// adds a straight line from the current point to (x,y)
|
||||
virtual void AddLineToPoint( wxDouble x, wxDouble y );
|
||||
virtual void AddLineToPoint( wxDouble x, wxDouble y ) wxOVERRIDE;
|
||||
|
||||
// adds a cubic Bezier curve from the current point, using two control points and an end point
|
||||
virtual void AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y );
|
||||
virtual void AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y ) wxOVERRIDE;
|
||||
|
||||
// closes the current sub-path
|
||||
virtual void CloseSubpath();
|
||||
virtual void CloseSubpath() wxOVERRIDE;
|
||||
|
||||
// gets the last point of the current path, (0,0) if not yet set
|
||||
virtual void GetCurrentPoint( wxDouble* x, wxDouble* y) const;
|
||||
virtual void GetCurrentPoint( wxDouble* x, wxDouble* y) const wxOVERRIDE;
|
||||
|
||||
// adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle
|
||||
virtual void AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise );
|
||||
virtual void AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise ) wxOVERRIDE;
|
||||
|
||||
//
|
||||
// These are convenience functions which - if not available natively will be assembled
|
||||
@@ -1187,36 +1187,36 @@ public :
|
||||
//
|
||||
|
||||
// adds a quadratic Bezier curve from the current point, using a control point and an end point
|
||||
virtual void AddQuadCurveToPoint( wxDouble cx, wxDouble cy, wxDouble x, wxDouble y );
|
||||
virtual void AddQuadCurveToPoint( wxDouble cx, wxDouble cy, wxDouble x, wxDouble y ) wxOVERRIDE;
|
||||
|
||||
// appends a rectangle as a new closed subpath
|
||||
virtual void AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
|
||||
virtual void AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) wxOVERRIDE;
|
||||
|
||||
// appends a circle as a new closed subpath
|
||||
virtual void AddCircle( wxDouble x, wxDouble y, wxDouble r );
|
||||
virtual void AddCircle( wxDouble x, wxDouble y, wxDouble r ) wxOVERRIDE;
|
||||
|
||||
// appends an ellipsis as a new closed subpath fitting the passed rectangle
|
||||
virtual void AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h);
|
||||
virtual void AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h) wxOVERRIDE;
|
||||
|
||||
// draws a an arc to two tangents connecting (current) to (x1,y1) and (x1,y1) to (x2,y2), also a straight line from (current) to (x1,y1)
|
||||
virtual void AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r );
|
||||
virtual void AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r ) wxOVERRIDE;
|
||||
|
||||
// adds another path
|
||||
virtual void AddPath( const wxGraphicsPathData* path );
|
||||
virtual void AddPath( const wxGraphicsPathData* path ) wxOVERRIDE;
|
||||
|
||||
// returns the native path
|
||||
virtual void * GetNativePath() const { return m_path; }
|
||||
virtual void * GetNativePath() const wxOVERRIDE { return m_path; }
|
||||
|
||||
// give the native path returned by GetNativePath() back (there might be some deallocations necessary)
|
||||
virtual void UnGetNativePath(void *WXUNUSED(p)) const {}
|
||||
virtual void UnGetNativePath(void *WXUNUSED(p)) const wxOVERRIDE {}
|
||||
|
||||
// transforms each point of this path by the matrix
|
||||
virtual void Transform( const wxGraphicsMatrixData* matrix );
|
||||
virtual void Transform( const wxGraphicsMatrixData* matrix ) wxOVERRIDE;
|
||||
|
||||
// gets the bounding box enclosing all points (possibly including control points)
|
||||
virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const;
|
||||
virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const wxOVERRIDE;
|
||||
|
||||
virtual bool Contains( wxDouble x, wxDouble y, wxPolygonFillMode fillStyle = wxODDEVEN_RULE) const;
|
||||
virtual bool Contains( wxDouble x, wxDouble y, wxPolygonFillMode fillStyle = wxODDEVEN_RULE) const wxOVERRIDE;
|
||||
private :
|
||||
CGMutablePathRef m_path;
|
||||
};
|
||||
@@ -1362,74 +1362,74 @@ public:
|
||||
|
||||
void Init();
|
||||
|
||||
virtual void StartPage( wxDouble width, wxDouble height );
|
||||
virtual void StartPage( wxDouble width, wxDouble height ) wxOVERRIDE;
|
||||
|
||||
virtual void EndPage();
|
||||
virtual void EndPage() wxOVERRIDE;
|
||||
|
||||
virtual void Flush();
|
||||
virtual void Flush() wxOVERRIDE;
|
||||
|
||||
// push the current state of the context, ie the transformation matrix on a stack
|
||||
virtual void PushState();
|
||||
virtual void PushState() wxOVERRIDE;
|
||||
|
||||
// pops a stored state from the stack
|
||||
virtual void PopState();
|
||||
virtual void PopState() wxOVERRIDE;
|
||||
|
||||
// clips drawings to the region
|
||||
virtual void Clip( const wxRegion ®ion );
|
||||
virtual void Clip( const wxRegion ®ion ) wxOVERRIDE;
|
||||
|
||||
// clips drawings to the rect
|
||||
virtual void Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
|
||||
virtual void Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) wxOVERRIDE;
|
||||
|
||||
// resets the clipping to original extent
|
||||
virtual void ResetClip();
|
||||
virtual void ResetClip() wxOVERRIDE;
|
||||
|
||||
virtual void * GetNativeContext();
|
||||
virtual void * GetNativeContext() wxOVERRIDE;
|
||||
|
||||
virtual bool SetAntialiasMode(wxAntialiasMode antialias);
|
||||
virtual bool SetAntialiasMode(wxAntialiasMode antialias) wxOVERRIDE;
|
||||
|
||||
virtual bool SetInterpolationQuality(wxInterpolationQuality interpolation);
|
||||
virtual bool SetInterpolationQuality(wxInterpolationQuality interpolation) wxOVERRIDE;
|
||||
|
||||
virtual bool SetCompositionMode(wxCompositionMode op);
|
||||
virtual bool SetCompositionMode(wxCompositionMode op) wxOVERRIDE;
|
||||
|
||||
virtual void BeginLayer(wxDouble opacity);
|
||||
virtual void BeginLayer(wxDouble opacity) wxOVERRIDE;
|
||||
|
||||
virtual void EndLayer();
|
||||
virtual void EndLayer() wxOVERRIDE;
|
||||
|
||||
//
|
||||
// transformation
|
||||
//
|
||||
|
||||
// translate
|
||||
virtual void Translate( wxDouble dx , wxDouble dy );
|
||||
virtual void Translate( wxDouble dx , wxDouble dy ) wxOVERRIDE;
|
||||
|
||||
// scale
|
||||
virtual void Scale( wxDouble xScale , wxDouble yScale );
|
||||
virtual void Scale( wxDouble xScale , wxDouble yScale ) wxOVERRIDE;
|
||||
|
||||
// rotate (radians)
|
||||
virtual void Rotate( wxDouble angle );
|
||||
virtual void Rotate( wxDouble angle ) wxOVERRIDE;
|
||||
|
||||
// concatenates this transform with the current transform of this context
|
||||
virtual void ConcatTransform( const wxGraphicsMatrix& matrix );
|
||||
virtual void ConcatTransform( const wxGraphicsMatrix& matrix ) wxOVERRIDE;
|
||||
|
||||
// sets the transform of this context
|
||||
virtual void SetTransform( const wxGraphicsMatrix& matrix );
|
||||
virtual void SetTransform( const wxGraphicsMatrix& matrix ) wxOVERRIDE;
|
||||
|
||||
// gets the matrix of this context
|
||||
virtual wxGraphicsMatrix GetTransform() const;
|
||||
virtual wxGraphicsMatrix GetTransform() const wxOVERRIDE;
|
||||
//
|
||||
// setting the paint
|
||||
//
|
||||
|
||||
// strokes along a path with the current pen
|
||||
virtual void StrokePath( const wxGraphicsPath &path );
|
||||
virtual void StrokePath( const wxGraphicsPath &path ) wxOVERRIDE;
|
||||
|
||||
// fills a path with the current brush
|
||||
virtual void FillPath( const wxGraphicsPath &path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE );
|
||||
virtual void FillPath( const wxGraphicsPath &path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ) wxOVERRIDE;
|
||||
|
||||
// draws a path by first filling and then stroking
|
||||
virtual void DrawPath( const wxGraphicsPath &path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE );
|
||||
virtual void DrawPath( const wxGraphicsPath &path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ) wxOVERRIDE;
|
||||
|
||||
virtual bool ShouldOffset() const
|
||||
virtual bool ShouldOffset() const wxOVERRIDE
|
||||
{
|
||||
if ( !m_enableOffset )
|
||||
return false;
|
||||
@@ -1448,24 +1448,24 @@ public:
|
||||
//
|
||||
|
||||
virtual void GetTextExtent( const wxString &text, wxDouble *width, wxDouble *height,
|
||||
wxDouble *descent, wxDouble *externalLeading ) const;
|
||||
wxDouble *descent, wxDouble *externalLeading ) const wxOVERRIDE;
|
||||
|
||||
virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const;
|
||||
virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const wxOVERRIDE;
|
||||
|
||||
//
|
||||
// image support
|
||||
//
|
||||
|
||||
virtual void DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
|
||||
virtual void DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) wxOVERRIDE;
|
||||
|
||||
virtual void DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
|
||||
virtual void DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) wxOVERRIDE;
|
||||
|
||||
virtual void DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h );
|
||||
virtual void DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) wxOVERRIDE;
|
||||
|
||||
// fast convenience methods
|
||||
|
||||
|
||||
virtual void DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
|
||||
virtual void DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) wxOVERRIDE;
|
||||
|
||||
void SetNativeContext( CGContextRef cg );
|
||||
|
||||
@@ -1475,8 +1475,8 @@ private:
|
||||
bool EnsureIsValid();
|
||||
void CheckInvariants() const;
|
||||
|
||||
virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y );
|
||||
virtual void DoDrawRotatedText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle );
|
||||
virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y ) wxOVERRIDE;
|
||||
virtual void DoDrawRotatedText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle ) wxOVERRIDE;
|
||||
|
||||
CGContextRef m_cgContext;
|
||||
#if wxOSX_USE_CARBON
|
||||
@@ -2591,69 +2591,69 @@ public :
|
||||
|
||||
// Context
|
||||
|
||||
virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc);
|
||||
virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc);
|
||||
virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc) wxOVERRIDE;
|
||||
virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc) wxOVERRIDE;
|
||||
#if wxUSE_PRINTING_ARCHITECTURE
|
||||
virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc);
|
||||
virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc) wxOVERRIDE;
|
||||
#endif
|
||||
|
||||
virtual wxGraphicsContext * CreateContextFromNativeContext( void * context );
|
||||
virtual wxGraphicsContext * CreateContextFromNativeContext( void * context ) wxOVERRIDE;
|
||||
|
||||
virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window );
|
||||
virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window ) wxOVERRIDE;
|
||||
|
||||
virtual wxGraphicsContext * CreateContext( wxWindow* window );
|
||||
virtual wxGraphicsContext * CreateContext( wxWindow* window ) wxOVERRIDE;
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsContext * CreateContextFromImage(wxImage& image);
|
||||
virtual wxGraphicsContext * CreateContextFromImage(wxImage& image) wxOVERRIDE;
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
virtual wxGraphicsContext * CreateMeasuringContext();
|
||||
virtual wxGraphicsContext * CreateMeasuringContext() wxOVERRIDE;
|
||||
|
||||
// Path
|
||||
|
||||
virtual wxGraphicsPath CreatePath();
|
||||
virtual wxGraphicsPath CreatePath() wxOVERRIDE;
|
||||
|
||||
// Matrix
|
||||
|
||||
virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0,
|
||||
wxDouble tx=0.0, wxDouble ty=0.0);
|
||||
wxDouble tx=0.0, wxDouble ty=0.0) wxOVERRIDE;
|
||||
|
||||
|
||||
virtual wxGraphicsPen CreatePen(const wxPen& pen) ;
|
||||
virtual wxGraphicsPen CreatePen(const wxPen& pen) wxOVERRIDE ;
|
||||
|
||||
virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ;
|
||||
virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) wxOVERRIDE ;
|
||||
|
||||
virtual wxGraphicsBrush
|
||||
CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
|
||||
wxDouble x2, wxDouble y2,
|
||||
const wxGraphicsGradientStops& stops);
|
||||
const wxGraphicsGradientStops& stops) wxOVERRIDE;
|
||||
|
||||
virtual wxGraphicsBrush
|
||||
CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
|
||||
wxDouble xc, wxDouble yc,
|
||||
wxDouble radius,
|
||||
const wxGraphicsGradientStops& stops);
|
||||
const wxGraphicsGradientStops& stops) wxOVERRIDE;
|
||||
|
||||
// sets the font
|
||||
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ;
|
||||
virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) wxOVERRIDE ;
|
||||
virtual wxGraphicsFont CreateFont(double sizeInPixels,
|
||||
const wxString& facename,
|
||||
int flags = wxFONTFLAG_DEFAULT,
|
||||
const wxColour& col = *wxBLACK);
|
||||
const wxColour& col = *wxBLACK) wxOVERRIDE;
|
||||
|
||||
// create a native bitmap representation
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) ;
|
||||
virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) wxOVERRIDE ;
|
||||
|
||||
#if wxUSE_IMAGE
|
||||
virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image);
|
||||
virtual wxImage CreateImageFromBitmap(const wxGraphicsBitmap& bmp);
|
||||
virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image) wxOVERRIDE;
|
||||
virtual wxImage CreateImageFromBitmap(const wxGraphicsBitmap& bmp) wxOVERRIDE;
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// create a graphics bitmap from a native bitmap
|
||||
virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap );
|
||||
virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap ) wxOVERRIDE;
|
||||
|
||||
// create a native bitmap representation
|
||||
virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) ;
|
||||
virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) wxOVERRIDE ;
|
||||
private :
|
||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsRenderer)
|
||||
} ;
|
||||
|
Reference in New Issue
Block a user