=== modified file 'eeschema/block.cpp'
--- eeschema/block.cpp	2010-07-17 11:14:57 +0000
+++ eeschema/block.cpp	2010-08-30 06:30:30 +0000
@@ -21,6 +21,10 @@
 // Imported functions:
 void            MoveItemsInList( PICKED_ITEMS_LIST& aItemsList,
                                  const wxPoint      aMoveVector );
+void            RotateListOfItems( PICKED_ITEMS_LIST& aItemsList,
+                                   wxPoint&           Center );
+void            Mirror_X_ListOfItems( PICKED_ITEMS_LIST& aItemsList,
+                                   wxPoint& aMirrorPoint );
 void            MirrorListOfItems( PICKED_ITEMS_LIST& aItemsList,
                                    wxPoint&           Center );
 void            DeleteItemsInList( WinEDA_DrawPanel*  panel,
@@ -123,7 +127,9 @@
     case BLOCK_IDLE:
         err = TRUE;
         break;
-
+    case BLOCK_ROTATE:
+    case BLOCK_MIRROR_X:
+    case BLOCK_MIRROR_Y:
     case BLOCK_DRAG:        /* Drag */
     case BLOCK_MOVE:        /* Move */
         if( DrawPanel->ManageCurseur )
@@ -163,9 +169,6 @@
     case BLOCK_ZOOM:        // Handled by HandleBlockEnd()
     case BLOCK_DELETE:
     case BLOCK_SAVE:
-    case BLOCK_ROTATE:
-    case BLOCK_MIRROR_X:
-    case BLOCK_MIRROR_Y:
     case BLOCK_FLIP:
     case BLOCK_ABORT:
     case BLOCK_SELECT_ITEMS_ONLY:
@@ -240,6 +243,9 @@
         case BLOCK_DRAG:    /* Drag */
             BreakSegmentOnJunction( (SCH_SCREEN*) GetScreen() );
 
+        case BLOCK_ROTATE:
+        case BLOCK_MIRROR_X:
+        case BLOCK_MIRROR_Y:
         case BLOCK_MOVE:    /* Move */
         case BLOCK_COPY:    /* Copy */
             PickItemsInBlock( GetScreen()->m_BlockLocate, GetScreen() );
@@ -298,10 +304,6 @@
         case BLOCK_FLIP: /* pcbnew only! */
             break;
 
-        case BLOCK_ROTATE:
-        case BLOCK_MIRROR_X:
-        case BLOCK_MIRROR_Y:
-            break;
 
         case BLOCK_ZOOM: /* Window Zoom */
             zoom_command = TRUE;
@@ -425,15 +427,53 @@
 
 
     case BLOCK_ROTATE:
+	if( DrawPanel->ManageCurseur )
+            DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
+        if( block->GetCount() )
+        {
+            ii = 1;
+ 	/* Compute the rotation center and put it on grid */
+            wxPoint rotationPoint = block->Centre();
+            PutOnGrid( &rotationPoint );
+            SaveCopyInUndoList( block->m_ItemsSelection,
+                                UR_ROTATED,
+                                rotationPoint );
+            RotateListOfItems( block->m_ItemsSelection, rotationPoint );
+            OnModify( );
+        }
+        TestDanglingEnds( GetScreen()->EEDrawList, DC );
+        DrawPanel->Refresh();
+        block->m_State = STATE_BLOCK_MOVE;
+        block->m_Command=BLOCK_MOVE;//allows multiple rotate
         break;
 
     case BLOCK_MIRROR_X:
+        if( DrawPanel->ManageCurseur )
+            DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
+        if( block->GetCount() )
+        {
+            ii = 1;
+            /* Compute the mirror center and put it on grid */
+            wxPoint mirrorPoint = block->Centre();
+            PutOnGrid( &mirrorPoint );
+            SaveCopyInUndoList( block->m_ItemsSelection,
+                                UR_MIRRORED_X,
+                                mirrorPoint );
+            Mirror_X_ListOfItems( block->m_ItemsSelection, mirrorPoint );
+            OnModify( );
+            block->m_State = STATE_BLOCK_MOVE;
+            block->m_Command=BLOCK_MOVE;//allows multiple mirrors
+        }
+        TestDanglingEnds( GetScreen()->EEDrawList, DC );
+        DrawPanel->Refresh();
+        break;
     case BLOCK_MIRROR_Y:
         if( DrawPanel->ManageCurseur )
             DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
+            
         if( block->GetCount() )
         {
-            ii = -1;
+            ii = 1;
             /* Compute the mirror center and put it on grid */
             wxPoint mirrorPoint = block->Centre();
             PutOnGrid( &mirrorPoint );
@@ -442,6 +482,8 @@
                                 mirrorPoint );
             MirrorListOfItems( block->m_ItemsSelection, mirrorPoint );
             OnModify( );
+            block->m_State = STATE_BLOCK_MOVE;
+            block->m_Command=BLOCK_MOVE;//allows multiple mirrors
         }
         TestDanglingEnds( GetScreen()->EEDrawList, DC );
         DrawPanel->Refresh();

=== modified file 'eeschema/class_drawsheet.cpp'
--- eeschema/class_drawsheet.cpp	2010-06-24 18:31:43 +0000
+++ eeschema/class_drawsheet.cpp	2010-08-30 19:27:33 +0000
@@ -16,6 +16,7 @@
 #include "class_drawpanel.h"
 #include "drawtxt.h"
 #include "confirm.h"
+#include "trigo.h"
 
 #include "program.h"
 #include "general.h"
@@ -741,6 +742,27 @@
 }
 
 
+void SCH_SHEET::Rotate(wxPoint rotationPoint)
+{
+    RotatePoint(&m_Pos,rotationPoint,900);
+    BOOST_FOREACH( SCH_SHEET_PIN& label, m_labels )
+    {
+        label.Rotate( rotationPoint );
+    }
+}
+void SCH_SHEET::Mirror_X( int aXaxis_position )
+{
+    m_Pos.y -= aXaxis_position;
+    NEGATE( m_Pos.y );
+    m_Pos.y += aXaxis_position;
+
+    m_Pos.y -= m_Size.y;
+
+    BOOST_FOREACH( SCH_SHEET_PIN& label, m_labels )
+    {
+        label.Mirror_X( aXaxis_position );
+    }
+}
 /** virtual function Mirror_Y
  * mirror item relative to an Y axis
  * @param aYaxis_position = the y axis position
@@ -817,3 +839,23 @@
 }
 
 #endif
+
+void SCH_SHEET_PIN::Rotate(wxPoint rotationPoint)
+{
+	RotatePoint(&m_Pos,rotationPoint,900);
+}
+void SCH_SHEET_PIN::Mirror_X( int aXaxis_position )
+{
+	m_Edge   = m_Edge ? 0 : 1;
+	m_Pos.y -= aXaxis_position;
+	NEGATE(  m_Pos.y );
+	m_Pos.y += aXaxis_position;
+}
+void SCH_SHEET_PIN::Mirror_Y( int aYaxis_position )
+{
+	m_Edge   = m_Edge ? 0 : 1;
+	m_Pos.x -= aYaxis_position;
+	NEGATE(  m_Pos.x );
+	m_Pos.x += aYaxis_position;
+}
+ 

=== modified file 'eeschema/class_drawsheet.h'
--- eeschema/class_drawsheet.h	2010-06-24 18:31:43 +0000
+++ eeschema/class_drawsheet.h	2010-08-30 19:29:19 +0000
@@ -137,13 +137,10 @@
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position
      */
-    virtual void Mirror_Y( int aYaxis_position )
-    {
-        m_Edge   = m_Edge ? 0 : 1;
-        m_Pos.x -= aYaxis_position;
-        NEGATE(  m_Pos.x );
-        m_Pos.x += aYaxis_position;
-    }
+    virtual void Mirror_Y( int aYaxis_position );
+	virtual void Rotate(wxPoint rotationPoint );
+	virtual void Mirror_X( int aXaxis_position );
+    
 
     /**
      * Compare schematic sheet entry (pin?) name against search string.
@@ -401,6 +398,8 @@
      * @param aYaxis_position = the y axis position
      */
     virtual void Mirror_Y( int aYaxis_position );
+    virtual void Mirror_X( int aXaxis_position );
+    virtual void Rotate(wxPoint rotationPoint);
 
     /**
      * Compare schematic sheet file and sheet name against search string.

=== modified file 'eeschema/class_marker_sch.cpp'
--- eeschema/class_marker_sch.cpp	2010-04-06 14:09:52 +0000
+++ eeschema/class_marker_sch.cpp	2010-08-30 06:50:55 +0000
@@ -8,6 +8,7 @@
 #include "common.h"
 #include "program.h"
 #include "general.h"
+#include "trigo.h"
 
 #include "class_marker_sch.h"
 #include "erc.h"
@@ -147,3 +148,20 @@
     aFrame->AppendMsgPanel( _( "Electronics rule check error" ),
                             GetReporter().GetErrorText(), DARKRED );
 }
+
+void SCH_MARKER::Rotate(wxPoint rotationPoint)
+{
+    RotatePoint(&m_Pos,rotationPoint,900);
+}
+void SCH_MARKER::Mirror_X(int aXaxis_position)
+{
+	m_Pos.y -= aXaxis_position;
+	m_Pos.y = - m_Pos.y;
+	m_Pos.y += aXaxis_position;
+}
+void SCH_MARKER::Mirror_Y(int aYaxis_position)
+{
+	m_Pos.x -= aYaxis_position;
+	m_Pos.x = - m_Pos.x;
+	m_Pos.x += aYaxis_position;
+}

=== modified file 'eeschema/class_marker_sch.h'
--- eeschema/class_marker_sch.h	2010-04-06 14:09:52 +0000
+++ eeschema/class_marker_sch.h	2010-08-30 19:17:22 +0000
@@ -92,13 +92,10 @@
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position
      */
-    virtual void Mirror_Y(int aYaxis_position)
-    {
-        m_Pos.x -= aYaxis_position;
-        m_Pos.x = - m_Pos.x;
-        m_Pos.x += aYaxis_position;
-    }
-
+    virtual void Mirror_Y(int aYaxis_position);
+    virtual void Rotate(wxPoint rotationPoint);
+    virtual void Mirror_X(int aXaxis_position);
+ 
     /**
      * Compare DRC marker main and auxiliary text against search string.
      *

=== modified file 'eeschema/class_sch_cmp_field.cpp'
--- eeschema/class_sch_cmp_field.cpp	2010-07-30 21:41:55 +0000
+++ eeschema/class_sch_cmp_field.cpp	2010-08-29 13:57:19 +0000
@@ -17,6 +17,7 @@
 #include "gr_basic.h"
 #include "drawtxt.h"
 #include "macros.h"
+#include "trigo.h"
 
 #include "program.h"
 #include "general.h"
@@ -420,3 +421,8 @@
 
     return SCH_ITEM::Matches( m_Text, aSearchData );
 }
+void SCH_FIELD::Rotate(wxPoint rotationPoint)
+{
+	RotatePoint(&m_Pos,rotationPoint,900);
+}
+

=== modified file 'eeschema/class_sch_cmp_field.h'
--- eeschema/class_sch_cmp_field.h	2010-07-30 21:41:55 +0000
+++ eeschema/class_sch_cmp_field.h	2010-08-30 19:07:27 +0000
@@ -111,6 +111,14 @@
         m_Pos += aMoveVector;
     }
 
+    virtual void Rotate(wxPoint rotationPoint);
+    virtual void Mirror_X(int aXaxis_position)
+    {
+        /* Do Nothing: fields are never mirrored alone.
+         * they are moved when the parent component is mirrored
+         * this function is only needed by the virtual pure function of the
+         * master class */
+    }
     /** virtual function Mirror_Y
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position

=== modified file 'eeschema/class_sch_component.cpp'
--- eeschema/class_sch_component.cpp	2010-08-03 05:11:05 +0000
+++ eeschema/class_sch_component.cpp	2010-08-29 20:59:06 +0000
@@ -7,6 +7,7 @@
 #include "class_drawpanel.h"
 #include "gr_basic.h"
 #include "common.h"
+#include "trigo.h"
 
 #include "program.h"
 #include "general.h"
@@ -1179,6 +1180,43 @@
     }
 }
 
+/** virtual function Mirror_X
+ * mirror item relative to an X axis
+ * @param aXaxis_position = the x axis position
+ */
+void SCH_COMPONENT::Mirror_X(int aXaxis_position)
+{
+    int dy = m_Pos.y;
+    SetOrientation( CMP_MIRROR_X );
+    m_Pos.y -= aXaxis_position;
+    NEGATE( m_Pos.y );
+    m_Pos.y += aXaxis_position;
+    dy -= m_Pos.y;     // dy,0 is the move vector for this transform
+
+    for( int ii = 0; ii < GetFieldCount(); ii++ )
+    {
+        /* move the fields to the new position because the component itself
+         * has moved */
+        GetField( ii )->m_Pos.y -= dy;
+    }
+}
+
+void SCH_COMPONENT::Rotate(wxPoint rotationPoint)
+{
+	wxPoint prev=m_Pos;
+    RotatePoint(&m_Pos,rotationPoint,900);
+    //SetOrientation( CMP_ROTATE_COUNTERCLOCKWISE );
+    SetOrientation( CMP_ROTATE_CLOCKWISE );
+
+    for( int ii = 0; ii < GetFieldCount(); ii++ )
+    {
+        /* move the fields to the new position because the component itself
+         * has moved */
+         GetField( ii )->m_Pos.x-=prev.x-m_Pos.x;
+        GetField( ii )->m_Pos.y-=prev.y-m_Pos.y;
+    }
+}
+
 
 bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void * aAuxData )
 {

=== modified file 'eeschema/class_sch_component.h'
--- eeschema/class_sch_component.h	2010-07-30 21:41:55 +0000
+++ eeschema/class_sch_component.h	2010-08-19 16:54:38 +0000
@@ -334,6 +334,9 @@
      * @param aYaxis_position = the y axis position
      */
     virtual void Mirror_Y(int aYaxis_position);
+    virtual void Mirror_X(int aXaxis_position);
+    virtual void Rotate(wxPoint rotationPoint);
+
 
     /**
      * Compare schematic component reference and value fields against search string.

=== modified file 'eeschema/class_schematic_items.cpp'
--- eeschema/class_schematic_items.cpp	2010-03-01 11:25:08 +0000
+++ eeschema/class_schematic_items.cpp	2010-08-30 19:31:43 +0000
@@ -5,7 +5,7 @@
 #include "fctsys.h"
 #include "gr_basic.h"
 #include "class_drawpanel.h"
-
+#include "trigo.h"
 #include "common.h"
 #include "program.h"
 #include "general.h"
@@ -141,6 +141,27 @@
 }
 
 
+void SCH_BUS_ENTRY::Mirror_X(int aXaxis_position)
+{
+	m_Pos.y -= aXaxis_position;
+	NEGATE(  m_Pos.y );
+	m_Pos.y += aXaxis_position;
+	NEGATE(  m_Size.y );
+}
+void SCH_BUS_ENTRY::Mirror_Y(int aYaxis_position)
+{
+	m_Pos.x -= aYaxis_position;
+	NEGATE(  m_Pos.x );
+	m_Pos.x += aYaxis_position;
+	NEGATE(  m_Size.x );
+}
+void SCH_BUS_ENTRY::Rotate(wxPoint rotationPoint)
+{
+	RotatePoint(&m_Pos,rotationPoint,900);
+	RotatePoint(&m_Size.x,&m_Size.y,900);
+	
+}
+
 /**********************/
 /* class SCH_JUNCTION */
 /**********************/
@@ -239,7 +260,22 @@
                     m_Pos.y + offset.y, (m_Size.x/2), 0, color,
                     color );
 }
-
+void SCH_JUNCTION::Mirror_X(int aXaxis_position)
+{
+	m_Pos.y -= aXaxis_position;
+	NEGATE(  m_Pos.y );
+	m_Pos.y += aXaxis_position;
+}
+void SCH_JUNCTION::Mirror_Y(int aYaxis_position)
+{
+	m_Pos.x -= aYaxis_position;
+	NEGATE(  m_Pos.x );
+	m_Pos.x += aYaxis_position;
+}
+void SCH_JUNCTION::Rotate(wxPoint rotationPoint)
+{
+	RotatePoint(&m_Pos,rotationPoint,900);
+}
 
 #if defined(DEBUG)
 void SCH_JUNCTION::Show( int nestLevel, std::ostream& os )
@@ -359,6 +395,23 @@
             pY + delta, width, color );
 }
 
+void SCH_NO_CONNECT::Mirror_X(int aXaxis_position)
+{
+	m_Pos.y -= aXaxis_position;
+	NEGATE(  m_Pos.y );
+	m_Pos.y += aXaxis_position;
+}
+void SCH_NO_CONNECT::Mirror_Y(int aYaxis_position)
+{
+	m_Pos.x -= aYaxis_position;
+	NEGATE(  m_Pos.x );
+	m_Pos.x += aYaxis_position;
+}
+void SCH_NO_CONNECT::Rotate(wxPoint rotationPoint)
+{
+	RotatePoint(&m_Pos,rotationPoint,900);
+}
+
 
 /******************/
 /* Class SCH_LINE */
@@ -528,7 +581,29 @@
     if( m_EndIsDangling )
         DrawDanglingSymbol( panel, DC, m_End + offset, color );
 }
-
+void SCH_LINE::Mirror_X(int aXaxis_position)
+{
+	m_Start.y -= aXaxis_position;
+	NEGATE(  m_Start.y );
+	m_Start.y += aXaxis_position;
+	m_End.y -= aXaxis_position;
+	NEGATE(  m_End.y );
+	m_End.y += aXaxis_position;
+}
+void SCH_LINE::Mirror_Y(int aYaxis_position)
+{
+	m_Start.x -= aYaxis_position;
+	NEGATE(  m_Start.x );
+	m_Start.x += aYaxis_position;
+	m_End.x -= aYaxis_position;
+	NEGATE(  m_End.x );
+	m_End.x += aYaxis_position;
+}
+void SCH_LINE::Rotate(wxPoint rotationPoint)
+{
+	RotatePoint(&m_Start,rotationPoint,900);
+	RotatePoint(&m_End,rotationPoint,900);
+}
 
 /***********************/
 /* Class SCH_POLYLINE */
@@ -648,3 +723,28 @@
                       m_PolyPoints[i].y + offset.y, width, color );
     }
 }
+void SCH_POLYLINE::Mirror_X(int aXaxis_position)
+{
+	for( unsigned ii = 0; ii < GetCornerCount(); ii++ )
+	{
+		m_PolyPoints[ii].y -= aXaxis_position;
+		NEGATE(  m_PolyPoints[ii].y );
+		m_PolyPoints[ii].y = aXaxis_position;
+	}
+}
+void SCH_POLYLINE::Mirror_Y(int aYaxis_position)
+{
+	for( unsigned ii = 0; ii < GetCornerCount(); ii++ )
+	{
+		m_PolyPoints[ii].x -= aYaxis_position;
+		NEGATE(  m_PolyPoints[ii].x );
+		m_PolyPoints[ii].x = aYaxis_position;
+	}
+}
+void SCH_POLYLINE::Rotate(wxPoint rotationPoint)
+{
+	for( unsigned ii = 0; ii < GetCornerCount(); ii++ )
+	{
+		RotatePoint(&m_PolyPoints[ii],rotationPoint,900);
+	}
+}

=== modified file 'eeschema/class_schematic_items.h'
--- eeschema/class_schematic_items.h	2009-12-02 21:44:03 +0000
+++ eeschema/class_schematic_items.h	2010-08-30 19:26:41 +0000
@@ -90,16 +90,10 @@
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position
      */
-    virtual void Mirror_Y(int aYaxis_position)
-    {
-        m_Start.x -= aYaxis_position;
-        NEGATE(  m_Start.x );
-        m_Start.x += aYaxis_position;
-        m_End.x -= aYaxis_position;
-        NEGATE(  m_End.x );
-        m_End.x += aYaxis_position;
-    }
-
+    virtual void Mirror_X(int aXaxis_position);
+    virtual void Mirror_Y(int aYaxis_position);
+    virtual void Rotate(wxPoint rotationPoint);
+    
 #if defined(DEBUG)
     void         Show( int nestLevel, std::ostream& os );
 #endif
@@ -171,12 +165,10 @@
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position
      */
-    virtual void Mirror_Y(int aYaxis_position)
-    {
-        m_Pos.x -= aYaxis_position;
-        NEGATE(  m_Pos.x );
-        m_Pos.x += aYaxis_position;
-    }
+    virtual void Mirror_Y(int aYaxis_position);
+    virtual void Mirror_X(int aXaxis_position);
+    virtual void Rotate(wxPoint rotationPoint);
+   
 };
 
 
@@ -246,13 +238,9 @@
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position
      */
-    virtual void Mirror_Y(int aYaxis_position)
-    {
-        m_Pos.x -= aYaxis_position;
-        NEGATE(  m_Pos.x );
-        m_Pos.x += aYaxis_position;
-        NEGATE(  m_Size.x );
-    }
+    virtual void Mirror_Y(int aYaxis_position);
+    virtual void Mirror_X(int aXaxis_position);
+    virtual void Rotate(wxPoint rotationPoint);
 };
 
 class SCH_POLYLINE : public SCH_ITEM
@@ -318,15 +306,9 @@
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position
      */
-    virtual void Mirror_Y(int aYaxis_position)
-    {
-        for( unsigned ii = 0; ii < GetCornerCount(); ii++ )
-        {
-            m_PolyPoints[ii].x -= aYaxis_position;
-            NEGATE(  m_PolyPoints[ii].x );
-            m_PolyPoints[ii].x = aYaxis_position;
-        }
-    }
+    virtual void Mirror_Y(int aYaxis_position);
+    virtual void Mirror_X(int aXaxis_position);
+    virtual void Rotate(wxPoint rotationPoint);
 };
 
 
@@ -394,12 +376,9 @@
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position
      */
-    virtual void Mirror_Y(int aYaxis_position)
-    {
-        m_Pos.x -= aYaxis_position;
-        NEGATE(  m_Pos.x );
-        m_Pos.x += aYaxis_position;
-    }
+    virtual void Mirror_Y(int aYaxis_position);
+    virtual void Mirror_X(int aXaxis_position);
+    virtual void Rotate(wxPoint rotationPoint);
 
 #if defined(DEBUG)
     void         Show( int nestLevel, std::ostream& os );

=== modified file 'eeschema/class_text-label.cpp'
--- eeschema/class_text-label.cpp	2010-07-11 16:24:44 +0000
+++ eeschema/class_text-label.cpp	2010-08-30 16:25:52 +0000
@@ -217,10 +217,16 @@
     case 0:             /* horizontal text */
         dx = LenSize( m_Text ) / 2;
         break;
+    case 1: /* Vert Orientation UP */
+    	dx = - m_Size.x / 2; 
+        break;
 
     case 2:        /* invert horizontal text*/
         dx = -LenSize( m_Text ) / 2;
         break;
+    case 3: /*  Vert Orientation BOTTOM */
+    	dx = m_Size.x / 2; // how to calculate text height?
+        break;
 
     default:
         dx = 0;
@@ -234,7 +240,70 @@
     px -= dx;
     m_Pos.x = px;
 }
-
+/** virtual function Mirror_X
+ * mirror item relative to an X axis
+ * @param aXaxis_position = the x axis position
+ */
+void SCH_TEXT::Mirror_X( int aXaxis_position )
+{
+    // Text is NOT really mirrored; it is moved to a suitable position
+    // which is the closest position for a true mirrored text
+    // The center position is mirrored and the text is moved for half
+    // horizontal len
+    int py = m_Pos.y;
+    int dy;
+
+    switch( GetSchematicTextOrientation() )
+    {
+    case 0:             /* horizontal text */
+    	dy = - m_Size.y / 2; 
+        break;
+    case 1: /* Vert Orientation UP */
+        dy = -LenSize( m_Text ) / 2;
+        break;
+    case 2:        /* invert horizontal text*/
+    	dy =  m_Size.y / 2; // how to calculate text height?
+        break;
+    case 3: /*  Vert Orientation BOTTOM */
+        dy = LenSize( m_Text ) / 2;
+        break;
+    default:
+        dy = 0;
+        break;
+    }
+    py += dy;
+    py -= aXaxis_position;
+    NEGATE( py );
+    py += aXaxis_position;
+    py -= dy;
+    m_Pos.y = py;
+}
+
+void SCH_TEXT::Rotate(wxPoint rotationPoint)
+{
+    int dy;
+    RotatePoint(&m_Pos,rotationPoint,900);
+    SetSchematicTextOrientation((GetSchematicTextOrientation()+1) % 4 );
+    switch( GetSchematicTextOrientation() )
+    {
+    case 0:             /* horizontal text */
+    	dy = m_Size.y ; 
+        break;
+    case 1: /* Vert Orientation UP */
+        dy = 0;
+        break;
+    case 2:        /* invert horizontal text*/
+    	dy = m_Size.y ; 
+        break;
+    case 3: /*  Vert Orientation BOTTOM */
+        dy = 0;
+        break;
+    default:
+        dy = 0;
+        break;
+    }
+    m_Pos.y+=dy;
+}
 
 /** function GetSchematicTextOffset (virtual)
  * @return the offset between the SCH_TEXT position and the text itself
@@ -300,7 +369,28 @@
     NEGATE( m_Pos.x );
     m_Pos.x += aYaxis_position;
 }
-
+void SCH_HIERLABEL::Mirror_X( int aXaxis_position )
+{
+    switch( GetSchematicTextOrientation() )
+    {
+    case 1:             /* vertical text */
+        SetSchematicTextOrientation( 3 );
+        break;
+
+    case 3:        /* invert vertical text*/
+        SetSchematicTextOrientation( 1 );
+        break;
+    }
+
+    m_Pos.y -= aXaxis_position;
+    NEGATE( m_Pos.y );
+    m_Pos.y += aXaxis_position;
+}
+void SCH_HIERLABEL::Rotate(wxPoint rotationPoint)
+{
+    RotatePoint(&m_Pos,rotationPoint,900);
+    SetSchematicTextOrientation((GetSchematicTextOrientation()+3) % 4 );
+}
 
 /** virtual function Mirror_Y
  * mirror item relative to an Y axis
@@ -328,7 +418,26 @@
     NEGATE( m_Pos.x );
     m_Pos.x += aYaxis_position;
 }
-
+void SCH_GLOBALLABEL::Mirror_X( int aXaxis_position )
+{
+    switch( GetSchematicTextOrientation() )
+    {
+    case 1:             /* vertical text */
+        SetSchematicTextOrientation( 3 );
+        break;
+    case 3:        /* invert vertical text*/
+        SetSchematicTextOrientation( 1 );
+        break;
+    }
+    m_Pos.y -= aXaxis_position;
+    NEGATE( m_Pos.y );
+    m_Pos.y += aXaxis_position;
+}
+void SCH_GLOBALLABEL::Rotate(wxPoint rotationPoint)
+{
+    RotatePoint(&m_Pos,rotationPoint,900);
+    SetSchematicTextOrientation((GetSchematicTextOrientation()+3) % 4 );
+}
 
 /** function GetSchematicTextOffset (virtual)
  * @return the offset between the SCH_TEXT position and the text itself
@@ -715,7 +824,27 @@
     m_IsDangling = TRUE;
     m_MultilineAllowed = false;
 }
-
+/** virtual function Mirror_X
+ * mirror item relative to an X axis
+ * @param aXaxis_position = the x axis position
+ */
+void SCH_LABEL::Mirror_X( int aXaxis_position )
+{
+    // Text is NOT really mirrored; it is moved to a suitable position
+    // which is the closest position for a true mirrored text
+    // The center position is mirrored and the text is moved for half
+    // horizontal len
+    int py = m_Pos.y;
+    py -= aXaxis_position;
+    NEGATE( py );
+    py += aXaxis_position;
+    m_Pos.y = py;
+}
+void SCH_LABEL::Rotate(wxPoint rotationPoint)
+{
+    RotatePoint(&m_Pos,rotationPoint,900);
+    SetSchematicTextOrientation((GetSchematicTextOrientation()+1) % 4 );
+}
 
 /**
  * Function Save

=== modified file 'eeschema/class_text-label.h'
--- eeschema/class_text-label.h	2010-04-01 13:15:48 +0000
+++ eeschema/class_text-label.h	2010-08-30 19:22:15 +0000
@@ -143,7 +143,10 @@
      * mirror item relative to an Y axis
      * @param aYaxis_position = the y axis position
      */
-    virtual void Mirror_Y( int aYaxis_position );
+    virtual void 	Rotate(wxPoint rotationPoint);
+    virtual void 	Mirror_Y( int aYaxis_position );
+    virtual void 	Mirror_X( int aXaxis_position );
+
 
     /**
      * Compare schematic text entry against search string.
@@ -201,6 +204,8 @@
      * wire)
      */
     virtual wxPoint GetSchematicTextOffset();
+    virtual void    Mirror_X( int aXaxis_position );
+    virtual void    Rotate(wxPoint rotationPoint);
 
     /**
      * Function GetBoundingBox
@@ -300,6 +305,9 @@
      * @param aYaxis_position = the y axis position
      */
     virtual void    Mirror_Y( int aYaxis_position );
+    virtual void    Mirror_X( int aXaxis_position );
+    virtual void 	Rotate(wxPoint rotationPoint);
+
 };
 
 
@@ -381,6 +389,9 @@
      * @param aYaxis_position = the y axis position
      */
     virtual void    Mirror_Y( int aYaxis_position );
+    virtual void    Mirror_X( int aXaxis_position );
+    virtual void 	Rotate(wxPoint rotationPoint);
+
 };
 
 #endif /* CLASS_TEXT_LABEL_H */

=== modified file 'eeschema/hotkeys.cpp'
--- eeschema/hotkeys.cpp	2010-08-28 18:02:24 +0000
+++ eeschema/hotkeys.cpp	2010-08-30 20:23:14 +0000
@@ -435,7 +435,11 @@
         break;
 
     case HK_ROTATE:       // Component or other schematic item rotation
-
+		if ( screen->m_BlockLocate.m_State != STATE_NO_BLOCK)
+		{
+			HandleBlockEndByPopUp(BLOCK_ROTATE, DC );
+			break;
+		} 
         if( DrawStruct == NULL )
         {
             // Find the schematic object to rotate under the cursor
@@ -487,6 +491,11 @@
         break;
 
     case HK_MIRROR_Y_COMPONENT:     // Mirror Y (Component)
+        if ( screen->m_BlockLocate.m_State != STATE_NO_BLOCK)
+        {
+            HandleBlockEndByPopUp(BLOCK_MIRROR_Y, DC );
+            break;
+        } 
         if( DrawStruct == NULL )
             DrawStruct = LocateSmallestComponent( (SCH_SCREEN*) GetScreen() );
         if( DrawStruct )
@@ -501,6 +510,11 @@
         break;
 
     case HK_MIRROR_X_COMPONENT:     // Mirror X (Component)
+        if ( screen->m_BlockLocate.m_State != STATE_NO_BLOCK)
+		{
+            HandleBlockEndByPopUp(BLOCK_MIRROR_X, DC );
+            break;
+		} 
         if( DrawStruct == NULL )
             DrawStruct = LocateSmallestComponent( GetScreen() );
         if( DrawStruct )

=== modified file 'eeschema/onrightclick.cpp'
--- eeschema/onrightclick.cpp	2010-07-17 12:04:42 +0000
+++ eeschema/onrightclick.cpp	2010-08-26 19:58:30 +0000
@@ -650,6 +650,9 @@
         ADD_MENUITEM( PopMenu, ID_POPUP_DRAG_BLOCK, msg, move_xpm );
         ADD_MENUITEM( PopMenu, ID_POPUP_DELETE_BLOCK, _( "Delete Block" ), delete_xpm );
         ADD_MENUITEM( PopMenu, ID_POPUP_MIRROR_Y_BLOCK, _( "Mirror Block ||" ), mirror_H_xpm );
+        ADD_MENUITEM( PopMenu, ID_POPUP_MIRROR_X_BLOCK, _( "Mirror Block --" ), mirror_V_xpm );
+        ADD_MENUITEM( PopMenu, ID_POPUP_ROTATE_BLOCK, _( "Rotate Block ccw" ), rotate_pos_xpm );
+
 #if 0
   #ifdef __WINDOWS__
         ADD_MENUITEM( menu_other_block_commands, ID_GEN_COPY_BLOCK_TO_CLIPBOARD,

=== modified file 'eeschema/operations_on_items_lists.cpp'
--- eeschema/operations_on_items_lists.cpp	2010-03-24 18:26:04 +0000
+++ eeschema/operations_on_items_lists.cpp	2010-08-30 19:22:19 +0000
@@ -17,6 +17,16 @@
 
 void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector );
 void MirrorListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint );
+void Mirror_X_ListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint );
+void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList,  wxPoint& rotationPoint )
+{
+    for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+    {
+        SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
+        item->Rotate( rotationPoint );      // Place it in its new position.
+        item->m_Flags = 0;
+    }
+}
 void DeleteItemsInList( WinEDA_DrawPanel*  panel,
                         PICKED_ITEMS_LIST& aItemsList );
 void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
@@ -33,6 +43,15 @@
     }
 }
 
+void Mirror_X_ListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
+{
+    for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
+    {
+        SCH_ITEM* item = (SCH_ITEM*) aItemsList.GetPickedItem( ii );
+        item->Mirror_X( aMirrorPoint.y );      // Place it in its new position.
+        item->m_Flags = 0;
+    }
+}
 
 /** Function MoveItemsInList
  *  Move a list of items to a given move vector

=== modified file 'eeschema/schedit.cpp'
--- eeschema/schedit.cpp	2010-07-17 11:14:57 +0000
+++ eeschema/schedit.cpp	2010-08-18 21:28:36 +0000
@@ -686,6 +686,9 @@
         break;
 
     case ID_POPUP_MIRROR_X_BLOCK:
+        DrawPanel->MouseToCursorSchema();
+        HandleBlockEndByPopUp( BLOCK_MIRROR_X, &dc );
+        break;
     case ID_POPUP_MIRROR_Y_BLOCK:
         DrawPanel->MouseToCursorSchema();
         HandleBlockEndByPopUp( BLOCK_MIRROR_Y, &dc );

=== modified file 'eeschema/schematic_undo_redo.cpp'
--- eeschema/schematic_undo_redo.cpp	2010-03-24 18:26:04 +0000
+++ eeschema/schematic_undo_redo.cpp	2010-08-30 19:51:26 +0000
@@ -307,6 +307,8 @@
 
         case UR_MOVED:
         case UR_MIRRORED_Y:
+        case UR_MIRRORED_X:
+        case UR_ROTATED:
         case UR_NEW:
         case UR_DELETED:
             break;
@@ -389,6 +391,22 @@
         }
             break;
 
+        case UR_MIRRORED_X:
+        {
+            wxPoint mirrorPoint = aList->m_TransformPoint;
+            item->Mirror_X( mirrorPoint.y );
+        }
+            break;
+
+        case UR_ROTATED:
+        {
+            wxPoint RotationPoint = aList->m_TransformPoint;
+            item->Rotate( RotationPoint );
+            item->Rotate( RotationPoint );
+            item->Rotate( RotationPoint );
+        }
+            break;
+
         case UR_WIRE_IMAGE:
             /* Exchange the current wires and the old wires */
             alt_item = GetScreen()->ExtractWires( false );

=== modified file 'include/sch_item_struct.h'
--- include/sch_item_struct.h	2010-04-01 13:15:48 +0000
+++ include/sch_item_struct.h	2010-08-19 21:38:46 +0000
@@ -79,6 +79,9 @@
      * @param aYaxis_position = the y axis position
      */
     virtual void Mirror_Y(int aYaxis_position) = 0;
+    virtual void Mirror_X(int aXaxis_position) = 0;
+    virtual void Rotate(wxPoint rotationPoint) = 0;
+
 
     /**
      * Function Save
