Ejemplo n.º 1
0
BOOL CCrystalEditView::DoDropText(COleDataObject *pDataObject, const CPoint &ptClient)
{
	HGLOBAL hData = pDataObject->GetGlobalData(CF_TEXT);
	if (hData == NULL)
		return FALSE;

	CPoint ptDropPos = ClientToText(ptClient);
	if (IsDraggingText() && IsInsideSelection(ptDropPos))
	{
		SetAnchor(ptDropPos);
		SetSelection(ptDropPos, ptDropPos);
		SetCursorPos(ptDropPos);
		EnsureVisible(ptDropPos);
		return FALSE;
	}

	LPSTR pszText = (LPSTR) ::GlobalLock(hData);
	if (pszText == NULL)
		return FALSE;

	int x, y;
	USES_CONVERSION;
	m_pTextBuffer->InsertText(this, ptDropPos.y, ptDropPos.x, A2T(pszText), y, x, CE_ACTION_DRAGDROP); //	[JRT]
	CPoint ptCurPos(x, y);
	ASSERT_VALIDTEXTPOS(ptCurPos);
	SetAnchor(ptDropPos);
	SetSelection(ptDropPos, ptCurPos);
	SetCursorPos(ptCurPos);
	EnsureVisible(ptCurPos);

	::GlobalUnlock(hData);
	return TRUE;
}
Ejemplo n.º 2
0
/*virtual*/ void WBCompEldAnchor::HandleEvent( const WBEvent& Event )
{
	XTRACE_FUNCTION;

	Super::HandleEvent( Event );

	STATIC_HASHED_STRING( OnSpawnedQueued );
	STATIC_HASHED_STRING( OnWorldChanged );
	STATIC_HASHED_STRING( OnStaticCollisionChanged );
	STATIC_HASHED_STRING( Unanchor );

	const HashedString EventName = Event.GetEventName();
	if( EventName == sOnSpawnedQueued )
	{
		SetAnchor();
	}
	else if( EventName == sOnWorldChanged || EventName == sOnStaticCollisionChanged )
	{
		if( m_IsAnchored )
		{
			CheckAnchor();
		}
	}
	else if( EventName == sUnanchor )
	{
		if( m_IsAnchored )
		{
			// Forcibly unanchor the entity
			Unanchor();
		}
	}
}
Ejemplo n.º 3
0
void CCrystalEditView::Paste()
{
	if (! QueryEditable())
		return;
	if (m_pTextBuffer == NULL)
		return;

	if(m_pTextBuffer->m_bUndoGroup)
		m_pTextBuffer->FlushUndoGroup(this);

	m_pTextBuffer->BeginUndoGroup();

	DeleteCurrentSelection();

	CString text;
	if (GetFromClipboard(text))
	{
		CPoint ptCursorPos = GetCursorPos();
		ASSERT_VALIDTEXTPOS(ptCursorPos);
		int x, y;
		m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, text, y, x, CE_ACTION_PASTE); //	[JRT]
		ptCursorPos.x = x;
		ptCursorPos.y = y;
		ASSERT_VALIDTEXTPOS(ptCursorPos);
		SetAnchor(ptCursorPos);
		SetSelection(ptCursorPos, ptCursorPos);
		SetCursorPos(ptCursorPos);
		EnsureVisible(ptCursorPos);
	}

	m_pTextBuffer->FlushUndoGroup(this);
}
Ejemplo n.º 4
0
/* ---- Process text block keys for multiline text box ---- */
static void DoMultiLines(WINDOW wnd, int c, PARAM p2)
{
    if (isMultiLine(wnd) && !KeyBoardMarking)    {
        if ((int)p2 & (LEFTSHIFT | RIGHTSHIFT))    {
            switch (c)    {
                case HOME:
                case CTRL_HOME:
                case CTRL_BS:
                case PGUP:
                case CTRL_PGUP:
                case UP:
                case BS:
                case END:
                case CTRL_END:
                case PGDN:
                case CTRL_PGDN:
                case DN:
                case FWD:
                case CTRL_FWD:
                    KeyBoardMarking = TextMarking = TRUE;
                    SetAnchor(wnd, wnd->CurrCol, wnd->CurrLine);
                    break;
                default:
                    break;
            }
        }
    }
}
Ejemplo n.º 5
0
void CEditWnd::InsertText(LPCSTR text, int action)
{
	m_pTextBuffer->BeginUndoGroup();
    
	CPoint ptCursorPos;
  if (IsSelection ())
  {
		CPoint ptSelStart, ptSelEnd;
    GetSelection (ptSelStart, ptSelEnd);
    
    ptCursorPos = ptSelStart;
    
		m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_PASTE);
	}
  else ptCursorPos = GetCursorPos ();
	ASSERT_VALIDTEXTPOS (ptCursorPos);
      
  int x, y;
  m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, text, y, x, action);

  ptCursorPos.x = x;
  ptCursorPos.y = y;
  ASSERT_VALIDTEXTPOS (ptCursorPos);
  SetAnchor (ptCursorPos);
  SetSelection (ptCursorPos, ptCursorPos);
  SetCursorPos (ptCursorPos);
  EnsureVisible (ptCursorPos);
  m_pTextBuffer->FlushUndoGroup (this);
}
Ejemplo n.º 6
0
void CCrystalEditView::OnEditDelete() 
{
	if (! QueryEditable() || m_pTextBuffer == NULL)
		return;

	CPoint ptSelStart, ptSelEnd;
	GetSelection(ptSelStart, ptSelEnd);
	if (ptSelStart == ptSelEnd)
	{
		if (ptSelEnd.x == GetLineLength(ptSelEnd.y))
		{
			if (ptSelEnd.y == GetLineCount() - 1)
				return;
			ptSelEnd.y ++;
			ptSelEnd.x = 0;
		}
		else
			ptSelEnd.x ++;
	}

	CPoint ptCursorPos = ptSelStart;
	ASSERT_VALIDTEXTPOS(ptCursorPos);
	SetAnchor(ptCursorPos);
	SetSelection(ptCursorPos, ptCursorPos);
	SetCursorPos(ptCursorPos);
	EnsureVisible(ptCursorPos);

	m_pTextBuffer->DeleteText(this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELETE); // [JRT]
}
Ejemplo n.º 7
0
  void DisparityPlugin::LoadConfig(const YAML::Node& node, const std::string& path)
  {
    std::string topic;
    node["topic"] >> topic;
    ui_.topic->setText(topic.c_str());

    TopicEdited();

    std::string anchor;
    node["anchor"] >> anchor;
    ui_.anchor->setCurrentIndex(ui_.anchor->findText(anchor.c_str()));
    SetAnchor(anchor.c_str());

    std::string units;
    node["units"] >> units;
    ui_.units->setCurrentIndex(ui_.units->findText(units.c_str()));
    SetUnits(units.c_str());

    node["offset_x"] >> offset_x_;
    ui_.offsetx->setValue(offset_x_);

    node["offset_y"] >> offset_y_;
    ui_.offsety->setValue(offset_y_);

    node["width"] >> width_;
    ui_.width->setValue(width_);

    node["height"] >> height_;
    ui_.height->setValue(height_);
  }
Ejemplo n.º 8
0
  DisparityPlugin::DisparityPlugin() :
    config_widget_(new QWidget()),
    anchor_(TOP_LEFT),
    units_(PIXELS),
    offset_x_(0),
    offset_y_(0),
    width_(320),
    height_(240),
    has_image_(false),
    last_width_(0),
    last_height_(0)
  {
    ui_.setupUi(config_widget_);

    // Set background white
    QPalette p(config_widget_->palette());
    p.setColor(QPalette::Background, Qt::white);
    config_widget_->setPalette(p);

    // Set status text red
    QPalette p3(ui_.status->palette());
    p3.setColor(QPalette::Text, Qt::red);
    ui_.status->setPalette(p3);

    QObject::connect(ui_.selecttopic, SIGNAL(clicked()), this, SLOT(SelectTopic()));
    QObject::connect(ui_.topic, SIGNAL(editingFinished()), this, SLOT(TopicEdited()));
    QObject::connect(ui_.anchor, SIGNAL(activated(QString)), this, SLOT(SetAnchor(QString)));
    QObject::connect(ui_.units, SIGNAL(activated(QString)), this, SLOT(SetUnits(QString)));
    QObject::connect(ui_.offsetx, SIGNAL(valueChanged(int)), this, SLOT(SetOffsetX(int)));
    QObject::connect(ui_.offsety, SIGNAL(valueChanged(int)), this, SLOT(SetOffsetY(int)));
    QObject::connect(ui_.width, SIGNAL(valueChanged(int)), this, SLOT(SetWidth(int)));
    QObject::connect(ui_.height, SIGNAL(valueChanged(int)), this, SLOT(SetHeight(int)));
  }
Ejemplo n.º 9
0
BOOL CEditWnd::ReplaceSelection (LPCTSTR pszNewText)
{
  if (!pszNewText)
    pszNewText = _T ("");

  CPoint ptCursorPos;
  if (IsSelection ())
	{
		CPoint ptSelStart, ptSelEnd;
		GetSelection (ptSelStart, ptSelEnd);
		ptCursorPos = ptSelStart;
		m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_REPLACE);
	}
  else ptCursorPos = GetCursorPos ();
  ASSERT_VALIDTEXTPOS (ptCursorPos);

  int x, y;
  m_pTextBuffer->InsertText (this, ptCursorPos.y, ptCursorPos.x, pszNewText, y, x, CE_ACTION_REPLACE);
  m_nLastReplaceLen = (int)_tcslen (pszNewText);
  CPoint ptEndOfBlock = CPoint (x, y);
  ASSERT_VALIDTEXTPOS (ptCursorPos);
  ASSERT_VALIDTEXTPOS (ptEndOfBlock);
  SetAnchor (ptEndOfBlock);
  SetSelection (ptCursorPos, ptEndOfBlock);
  SetCursorPos (ptEndOfBlock);
  EnsureVisible (ptEndOfBlock);
  return TRUE;
}
Ejemplo n.º 10
0
void CEditWnd::Cut()
{
  if (!QueryEditable ())
    return;
  if (m_pTextBuffer == NULL)
    return;
  if (!IsSelection ())
    return;

  CPoint ptSelStart, ptSelEnd;
  GetSelection (ptSelStart, ptSelEnd);
  string text;
  GetText (ptSelStart, ptSelEnd, text);
  PutToClipboard (text.c_str());

  CPoint ptCursorPos = ptSelStart;
  ASSERT_VALIDTEXTPOS (ptCursorPos);
  SetAnchor (ptCursorPos);
  SetSelection (ptCursorPos, ptCursorPos);
  SetCursorPos (ptCursorPos);
  EnsureVisible (ptCursorPos);

  m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_CUT);

}
Ejemplo n.º 11
0
bool CControl::OnPropertyChange( void* pVariableAddr, CSerializer* pSerializer )
{
    bool bRet = super::OnPropertyChange( pVariableAddr, pSerializer );
    if ( !bRet )
    {
        if ( &m_vec2AbsolutePosition == pVariableAddr )
        {
            CVec2 absolutePosition;
            DeserializeVariable( absolutePosition, pSerializer );
            SetAbsolutePosition( absolutePosition );
            bRet = true;
        }
        else if ( &m_vec2PercentPosition == pVariableAddr )
        {
            CVec2 percentPosition;
            DeserializeVariable( percentPosition, pSerializer );
            SetPercentPosition( percentPosition );
            bRet = true;
        }
        else if ( &m_vec2PercentSize == pVariableAddr )
        {
            CVec2 percentSize;
            DeserializeVariable( percentSize, pSerializer );
            SetPercentSize( percentSize );
            bRet = true;
        }
        else if( &m_vec2Size == pVariableAddr )
        {
            CVec2 size;
            DeserializeVariable( size, pSerializer );
            SetSize( size );
            bRet = true;
        }
        else if( &m_vec2Anchor == pVariableAddr )
        {
            CVec2 anchor;
            DeserializeVariable( anchor, pSerializer );
            SetAnchor( anchor );
            bRet = true;
        }
        else if( &m_color == pVariableAddr )
        {
            CColor color;
            DeserializeVariable( color, pSerializer );
            SetColor( color );
            bRet = true;
        }
        else if( &m_strPressAnimationName == pVariableAddr )
        {
            TString animationName;
            DeserializeVariable( animationName, pSerializer );
            SetAnimationName( animationName );
            bRet = true;
        }
    }
    return bRet;
}
Ejemplo n.º 12
0
//
//	[JRT]: Added Support For "Disable Backspace At Start Of Line"
//
void CCrystalEditView::OnEditDeleteBack() 
{
	if (IsSelection())
	{
		OnEditDelete();
		return;
	}

	if (! QueryEditable() || m_pTextBuffer == NULL)
		return;

	CPoint ptCursorPos = GetCursorPos();
	CPoint ptCurrentCursorPos = ptCursorPos;
	bool	bDeleted = false;

	if( !( ptCursorPos.x ) )							// If At Start Of Line
	{
		if( !m_bDisableBSAtSOL )						// If DBSASOL Is Disabled
		{
			if( ptCursorPos.y > 0 )						// If Previous Lines Available
			{
				ptCursorPos.y--;						// Decrement To Previous Line
				ptCursorPos.x = GetLineLength(
						ptCursorPos.y );				// Set Cursor To End Of Previous Line
				bDeleted = true;						// Set Deleted Flag
			}
		}
	}
	else												// If Caret Not At SOL
	{
		ptCursorPos.x--;								// Decrement Position
		bDeleted = true;								// Set Deleted Flag
	}
/*
	if (ptCursorPos.x == 0)
	{
		if (ptCursorPos.y == 0)
			return;
		ptCursorPos.y --;
		ptCursorPos.x = GetLineLength(ptCursorPos.y);
	}
	else
		ptCursorPos.x --;
*/
	ASSERT_VALIDTEXTPOS(ptCursorPos);
	SetAnchor(ptCursorPos);
	SetSelection(ptCursorPos, ptCursorPos);
	SetCursorPos(ptCursorPos);
	EnsureVisible(ptCursorPos);

	if (bDeleted)
	{
		m_pTextBuffer->DeleteText(this, ptCursorPos.y, ptCursorPos.x, ptCurrentCursorPos.y, ptCurrentCursorPos.x, CE_ACTION_BACKSPACE); // [JRT]
	}
	return;
}
Ejemplo n.º 13
0
void CEditWnd::Undo()
{
	if (!CanUndo()) return;
	CPoint ptCursorPos;
	if (m_pTextBuffer->Undo(ptCursorPos))
	{
		ASSERT_VALIDTEXTPOS(ptCursorPos);
		SetAnchor(ptCursorPos);
		SetSelection(ptCursorPos, ptCursorPos);
		SetCursorPos(ptCursorPos);
		EnsureVisible(ptCursorPos);
	}
}
Ejemplo n.º 14
0
static void AnchorD_DoCancel(AnchorDlg *a) {
    struct state *old;

    for ( old = a->orig_vals; old!=NULL; old=old->next ) {
	SetAnchor(old->sc,a->layer,old->ap_pt,&old->ap_vals.xadjust,&old->ap_vals.yadjust,&old->ap_vals.me);
	old->ap_pt->has_ttf_pt = old->ap_vals.has_ttf_pt;
	old->sc->changed = old->changed;	/* Must come after the charchangedupdate */
    }
    if ( a->orig_vals!=NULL ) {
	FVRefreshAll(a->sc->parent);
    }
	
    a->done = true;
}
Ejemplo n.º 15
0
void CCrystalEditView::OnEditRedo() 
{
	if (m_pTextBuffer != NULL && m_pTextBuffer->CanRedo())
	{
		CPoint ptCursorPos;
		if (m_pTextBuffer->Redo(ptCursorPos))
		{
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			SetAnchor(ptCursorPos);
			SetSelection(ptCursorPos, ptCursorPos);
			SetCursorPos(ptCursorPos);
			EnsureVisible(ptCursorPos);
		}
	}
}
Ejemplo n.º 16
0
void PythonCodeCtrl::OnCharAdded(wxScintillaEvent& ke)
{
    //User has pressed enter
    //if the cursor is at the end of a completed statement, submit the statement to the interpreter
    //otherwise, do auto-indentation
    if (ke.GetKey() == _T('\n'))
    {
        //int pos = GetCurrentPos();
        int line = LineFromPosition(GetCurrentPos());

        if(line>0)
        {
            wxString prevlinetext = GetLine(line-1).Trim();
            int indentation = GetLineIndentation(line-1);

            if((indentation==0) //submit a return pressed on an unindented line
                || (indentation>0 && prevlinetext==wxEmptyString)) // or an indented block where the previous line was empty
            {
                long rs,re;
                GetSelection(&rs,&re);
                //if(rs==re && GetLastPosition()==rs)
                if(rs==re && GetLength()==rs) // only submit if the cursor is at the end of the control (and there is no selection)
                {
                    m_pyctrl->DispatchCode(GetValue());
                    ke.Skip();
                }
            }

            // Otherwise indent the code if necessary
            if (GetLine(line-1).Trim().EndsWith(_T(":")))
            {
                if(GetStyleAt(GetLineEndPosition(line-1)-1) == wxSCI_P_OPERATOR)
                    indentation+=GetIndent();
            }
            if (indentation>0)
            {
                SetLineIndentation(line,indentation);
                SetCurrentPos(PositionFromLine(line)+indentation);
                SetAnchor(PositionFromLine(line)+indentation);
            }
        }
    }
    ke.Skip();
}
Ejemplo n.º 17
0
BOOL CEditWnd::DeleteCurrentSelection ()
{
  if (IsSelection ())
	{
		CPoint ptSelStart, ptSelEnd;
    GetSelection (ptSelStart, ptSelEnd);

    CPoint ptCursorPos = ptSelStart;
    ASSERT_VALIDTEXTPOS (ptCursorPos);
    SetAnchor (ptCursorPos);
    SetSelection (ptCursorPos, ptCursorPos);
    SetCursorPos (ptCursorPos);
    EnsureVisible (ptCursorPos);

    m_pTextBuffer->DeleteText (this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELSEL);
    return TRUE;
	}
  return FALSE;
}
Ejemplo n.º 18
0
BOOL CCrystalEditView::ReplaceSelection(LPCTSTR pszNewText)
{
	ASSERT(pszNewText != NULL);
	if (IsSelection())
		DeleteCurrentSelection();

	CPoint ptCursorPos = GetCursorPos();
	ASSERT_VALIDTEXTPOS(ptCursorPos);
	int x, y;
	m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszNewText, y, x, CE_ACTION_REPLACE); //	[JRT]
	CPoint ptEndOfBlock = CPoint(x, y);
	ASSERT_VALIDTEXTPOS(ptCursorPos);
	ASSERT_VALIDTEXTPOS(ptEndOfBlock);
	SetAnchor(ptEndOfBlock);
	SetSelection(ptCursorPos, ptEndOfBlock);
	SetCursorPos(ptEndOfBlock);
	EnsureVisible(ptEndOfBlock);
	return TRUE;
}
Ejemplo n.º 19
0
bool TestLayer::Initialize()
{
	RETURN_FALSE_IF_FALSE(ILayer::Initialize());

	auto dataSource = DataSourceFactory::Instance().CreateWStringList("MainList", mItems, true);


	ListBox* listBox = NodeFactory::Instance().CreateListBox();
	listBox->SetStretch(Medusa::Stretch::Fill);
	auto binding = listBox->BindTo<LabelTemplate>(dataSource,true);
	auto nodeTemplate = (LabelTemplate*)binding->GetTemplate(0);
	nodeTemplate->MutableFontId().Name="arial88.fnt";
	nodeTemplate->SetAlignment(Alignment::LeftBottom);
	nodeTemplate->SetDock(DockPoint::MiddleBottom);
	nodeTemplate->SetAnchor(AnchorPoint::MiddleBottom);

	AddChild(listBox);
	listBox->OnItemClicked+=Bind(&TestLayer::OnItemClicked,this);

	return true;
}
Ejemplo n.º 20
0
/* ----------- MOUSE_MOVED Message ---------- */
static int MouseMovedMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
    int MouseX = (int) p1 - GetClientLeft(wnd);
    int MouseY = (int) p2 - GetClientTop(wnd);
    RECT rc = ClientRect(wnd);
    if (!InsideRect(p1, p2, rc))
        return FALSE;
    if (MouseY > wnd->wlines-1)
        return FALSE;
    if (ButtonDown)    {
        SetAnchor(wnd, ButtonX+wnd->wleft, ButtonY+wnd->wtop);
        TextMarking = TRUE;
		rc = WindowRect(wnd);
        SendMessage(NULL,MOUSE_TRAVEL,(PARAM) &rc, 0);
        ButtonDown = FALSE;
    }
    if (TextMarking && !(WindowMoving || WindowSizing))    {
        ExtendBlock(wnd, MouseX, MouseY);
        return TRUE;
    }
    return FALSE;
}
Ejemplo n.º 21
0
void CCrystalEditView::OnEditOperation(int nAction, LPCTSTR pszText)
{
	m_bAutoIndent=1;
	if (m_bAutoIndent)
	{
		//	Analyse last action...
		if (nAction == CE_ACTION_TYPING && _tcscmp(pszText, _T("\r\n")) == 0 && ! m_bOvrMode)
		{
			//	Enter stroke!
			CPoint ptCursorPos = GetCursorPos();
			ASSERT(ptCursorPos.y > 0);

			//	Take indentation from the previos line
			int nLength = m_pTextBuffer->GetLineLength(ptCursorPos.y - 1);
			LPCTSTR pszLineChars = m_pTextBuffer->GetLineChars(ptCursorPos.y - 1);
			int nPos = 0;
			while (nPos < nLength && IsSpace2(pszLineChars[nPos]))
				nPos ++;

			if (nPos > 0)
			{
				//	Insert part of the previos line
				TCHAR *pszInsertStr = (TCHAR *) _alloca(sizeof(TCHAR) * (nLength + 1));
				_tcsncpy(pszInsertStr, pszLineChars, nPos);
				pszInsertStr[nPos] = 0;

				int x, y;
				m_pTextBuffer->InsertText(NULL, ptCursorPos.y, ptCursorPos.x,
															pszInsertStr, y, x, CE_ACTION_AUTOINDENT);
				CPoint pt(x, y);
				SetCursorPos(pt);
				SetSelection(pt, pt);
				SetAnchor(pt);
				EnsureVisible(pt);
			}
		}
	}
}
Ejemplo n.º 22
0
void CCrystalEditView::SetLowerWord(BOOL bSet)
{
	CPoint ptSelStart, ptSelEnd;
	GetSelection(ptSelStart, ptSelEnd);
	CString text;
	GetText(ptSelStart, ptSelEnd, text);

	if(bSet)
		text.MakeLower();
	else
		text.MakeUpper();


	m_pTextBuffer->BeginUndoGroup();
	int x,y;
	m_pTextBuffer->DeleteText(this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELSEL);
	m_pTextBuffer->InsertText(this, ptSelStart.y, ptSelStart.x,text,y,x, CE_ACTION_TYPING);
	SetAnchor(ptSelStart);
	SetSelection(ptSelStart, ptSelEnd);
	SetCursorPos(ptSelStart);
	m_pTextBuffer->FlushUndoGroup(this);

}
Ejemplo n.º 23
0
void OutputCtrl::AppendText( const wxString& text )
{
   SetReadOnly( false );

   bool scrollEnd = false;
   int pos = GetLength();
   if (  GetCurrentPos() == pos && 
         GetAnchor() == pos )
      scrollEnd = true;

   // For each line...
   const wxChar* ptr = text.c_str();
   const wxChar* const end = ptr + text.Length();
   const wxChar* next;

   wxString line;
   bool isError = false;
   bool isWarn = false;

   //wxTextAttr errorStyle( *wxRED, *wxWHITE ); 
   //wxTextAttr warnStyle( *wxRED, *wxWHITE ); //wxColour( 255, 128, 0 ), *wxWHITE ); 
   long lnumb;

   while( ptr != end )
   {
      wxASSERT( ptr < end );
      next = std::find( ptr, end, '\n' );
      if ( next != end ) ++next;
      line.assign( ptr, next );
      ptr = next;

      // Look for error lines and highlight them...
      //
      // TODO: I need to optimize the regex here... maybe i 
      // shouldn't use a regex, but use my own logic to spot
      // errors... could be much faster.
      //
      if ( m_ErrorExpr.Matches( line ) && m_ErrorExpr.GetMatchCount() > 3 )
         isError = true;
      else if ( m_WarnExpr.Matches( line ) && m_ErrorExpr.GetMatchCount() > 3 )
         isWarn = true;

      pos = GetLength();
      SetTargetStart( pos );
      SetTargetEnd( pos );
      ReplaceTarget( line );

      if ( isError ) 
      {
         StartStyling( pos, 0xFF );
         SetStyling( line.Len(), 2 );

         // TODO: SetStyle will screw with the current scroll position.  The
         // trick is to disable ECO_AUTOVSCROLL and ECO_AUTOHSCROLL before
         // changing the selection to change the style.  We need to submit this
         // fix back to wxWindows.
         //::SendMessage( GetHwnd(), EM_SETOPTIONS, ECOOP_XOR, ECO_AUTOVSCROLL | ECO_AUTOHSCROLL );
         //SetStyle( start, last, errorStyle );
         //::SendMessage( GetHwnd(), EM_SETOPTIONS, ECOOP_OR, ECO_AUTOVSCROLL | ECO_AUTOHSCROLL );

         // Add the error to the debugger state.
         m_ErrorExpr.GetMatch( line, 2 ).ToLong( &lnumb );

         ScriptError* error = new ScriptError;
         error->file = m_ErrorExpr.GetMatch( line, 1 );
         error->line = lnumb;
         error->start = pos;
         error->end = pos + line.Len();
         error->row = LineFromPosition( pos );
         error->error = m_ErrorExpr.GetMatch( line, 3 );
         error->error.Trim();
         error->warning = false;
         AddError( error );

         isError = false;
      } 
      else if ( isWarn ) 
      {
         StartStyling( pos, 0xFF );
         SetStyling( line.Len(), 2 );

         // TODO: SetStyle will screw with the current scroll position.  The
         // trick is to disable ECO_AUTOVSCROLL and ECO_AUTOHSCROLL before
         // changing the selection to change the style.  We need to submit this
         // fix back to wxWindows.
         //::SendMessage( GetHwnd(), EM_SETOPTIONS, ECOOP_XOR, ECO_AUTOVSCROLL | ECO_AUTOHSCROLL );
         //SetStyle( start, last, warnStyle );
         //::SendMessage( GetHwnd(), EM_SETOPTIONS, ECOOP_OR, ECO_AUTOVSCROLL | ECO_AUTOHSCROLL );

         // Add the error to the debugger state.
         m_WarnExpr.GetMatch( line, 2 ).ToLong( &lnumb );

         ScriptError* error = new ScriptError;
         error->file = m_WarnExpr.GetMatch( line, 1 );
         error->line = lnumb;
         error->start = pos;
         error->end = pos + line.Len();
         error->row = LineFromPosition( pos );
         error->error = m_WarnExpr.GetMatch( line, 3 );
         error->error.Trim();
         error->warning = true;
         AddError( error );

         isWarn = false;
      }
   }

   if ( scrollEnd )
   {
      const int endPos = GetLength();
      SetAnchor( endPos );
      SetCurrentPos( endPos );
      ShowLine( LineFromPosition( endPos ) );
   }

   EmptyUndoBuffer();

   SetReadOnly( true );
}
Ejemplo n.º 24
0
void CEditWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	CTextWnd::OnKeyDown(nChar, nRepCnt, nFlags);
	if (!QueryEditable() || m_pTextBuffer == NULL)
		return;

	bool isShift = (GetKeyState(VK_SHIFT) & 0xF0) != 0;
	bool isCtrl = (GetKeyState(VK_CONTROL) & 0xF0) != 0;

	if (nChar == VK_TAB)
	{
		BOOL bTabify = FALSE;
		CPoint ptSelStart, ptSelEnd;
		if (IsSelection())
		{	
			GetSelection(ptSelStart, ptSelEnd);
			bTabify = ptSelStart.y != ptSelEnd.y;
		}

		if (bTabify)
		{
			m_pTextBuffer->BeginUndoGroup();
	
			int nStartLine = ptSelStart.y;
			int nEndLine = ptSelEnd.y;
			ptSelStart.x = 0;
			if (ptSelEnd.x > 0)
			{
				if (ptSelEnd.y == GetLineCount() - 1)
				{
					ptSelEnd.x = GetLineLength(ptSelEnd.y);
				}
				else
				{
					ptSelEnd.x = 0;
					ptSelEnd.y ++;
				}
			}
			else
				nEndLine --;
			SetSelection(ptSelStart, ptSelEnd);
			SetCursorPos(ptSelEnd);
			EnsureVisible(ptSelEnd);

			//	Shift selection to right
			m_bHorzScrollBarLocked = TRUE;
			//static const TCHAR pszText[] = _T("\t");
			CString pszText;
			if (!m_bReplaceTabs) pszText = "\t";
			else 
			{
				CString tmp(' ', GetTabSize());
				pszText = tmp;
			}

			for (int L = nStartLine; L <= nEndLine; L ++)
			{
				int x, y;
				m_pTextBuffer->InsertText(this, L, 0, pszText, y, x, CE_ACTION_INDENT);
			}
			m_bHorzScrollBarLocked = FALSE;
			RecalcHorzScrollBar();

			m_pTextBuffer->FlushUndoGroup(this);
		}
		else
		{
			m_pTextBuffer->BeginUndoGroup();

			DeleteCurrentSelection();

			CPoint ptCursorPos = GetCursorPos();
			ASSERT_VALIDTEXTPOS(ptCursorPos);

			CString pszText;
			if (!m_bReplaceTabs) pszText = "\t";
			else 
			{
				CString tmp(' ', GetTabSize());
				pszText = tmp;
			}

			int x, y;
			m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING);
			ptCursorPos.x = x;
			ptCursorPos.y = y;
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			SetSelection(ptCursorPos, ptCursorPos);
			SetAnchor(ptCursorPos);
			SetCursorPos(ptCursorPos);
			EnsureVisible(ptCursorPos);

			m_pTextBuffer->FlushUndoGroup(this);
		}
	}

	if (nChar == VK_BACK && !IsSelection())
	{
		CPoint ptCursorPos = GetCursorPos();

		if (ptCursorPos.y > 0 || (ptCursorPos.x > 0 && ptCursorPos.y == 0))
		{
			CPoint ptCurrentCursorPos = ptCursorPos;
			bool	bDeleted = false;
			if(ptCursorPos.x == 0)					
			{
				ptCursorPos.y--;						
				ptCursorPos.x = GetLineLength(ptCursorPos.y);	
				bDeleted = true;	
			}
			else								
			{
				ptCursorPos.x--;	
				bDeleted = true;	
			}
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			SetAnchor(ptCursorPos);
			SetSelection(ptCursorPos, ptCursorPos);
			SetCursorPos(ptCursorPos); 
			EnsureVisible(ptCursorPos);

			if (bDeleted)
				m_pTextBuffer->DeleteText(this, ptCursorPos.y, ptCursorPos.x, 
					ptCurrentCursorPos.y, ptCurrentCursorPos.x, CE_ACTION_BACKSPACE); 
		}
	}

	if (nChar == VK_DELETE && !isShift) 
	{
		CPoint ptSelStart, ptSelEnd;
		GetSelection(ptSelStart, ptSelEnd);
		if (ptSelStart == ptSelEnd)
		{	
			if (ptSelEnd.x == GetLineLength(ptSelEnd.y))
			{
				if (ptSelEnd.y == GetLineCount() - 1)
					return;
				ptSelEnd.y++;
				ptSelEnd.x = 0;

				if (GetLineLength(ptSelStart.y) != 0)
				{
					LPCSTR chars = GetLineChars(ptSelEnd.y);
					for (int j = 0; j < QUOTE_LENGTH && j < GetLineLength(ptSelEnd.y); j++)
						if (chars[j] == '>') ptSelEnd.x = j + 1;
				
					while (ptSelEnd.x < GetLineLength(ptSelEnd.y) && 
						(chars[ptSelEnd.x] == ' ' || chars[ptSelEnd.x] == '\t'))
						ptSelEnd.x++;
				}
			}
			else ptSelEnd.x++;
		}

		CPoint ptCursorPos = ptSelStart;
		ASSERT_VALIDTEXTPOS(ptCursorPos);
		SetAnchor(ptCursorPos);
		SetSelection(ptCursorPos, ptCursorPos);
		SetCursorPos(ptCursorPos);
		EnsureVisible(ptCursorPos);

		m_pTextBuffer->DeleteText(this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELETE); 
	}

	if ((nChar == 'X' && isCtrl) || (nChar == VK_DELETE && isShift)) 
		Cut();

	if ((nChar == 'V' && isCtrl) || (nChar == VK_INSERT && isShift)) 
		Paste();
		
	if (nChar == 'Z' && isCtrl && isShift)
		Redo();
		
	if (nChar == 'Z' && isCtrl && !isShift)
		Undo();
}
Ejemplo n.º 25
0
void CEditWnd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	CTextWnd::OnChar(nChar, nRepCnt, nFlags);
	if (m_bOemCharset)	CharToOemBuff((char*)&nChar, (char*)&nChar, 1);
	if ((::GetAsyncKeyState(VK_LBUTTON) | ::GetAsyncKeyState(VK_RBUTTON)) & 0x8000)	return;

	BOOL bTranslated = FALSE;
	if (nChar == VK_RETURN)
	{
		m_pTextBuffer->BeginUndoGroup();

		if (QueryEditable() && m_pTextBuffer != NULL)
		{
			DeleteCurrentSelection();

			CPoint ptCursorPos = GetCursorPos();
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			int x, y;
			CString pszText = "\r\n";

			bool flag;
			if (ptCursorPos.x > 0)
			{
				LPCSTR chars1 = GetLineChars(ptCursorPos.y);
				char *p = 0;
				for (int j = 0; j < QUOTE_LENGTH && j < GetLineLength(ptCursorPos.y); j++)
					if (chars1[j] == '>') p = (char*)chars1 + j;

				flag = p != 0 && ptCursorPos.x < GetLineLength(ptCursorPos.y);
				//Вставим знаки квоты
				if (flag)
				{
					p++;
					while (isspace((unsigned char)*p)) p++;
					pszText += CString(chars1, (int)(p - chars1));
				}
				//Автоотступ
				else if (m_bAutoIndent) 
				{	
					LPCSTR chars = m_pTextBuffer->GetLineChars(ptCursorPos.y);
					int len = m_pTextBuffer->GetLineLength(ptCursorPos.y);
					for (int j = 0; j < len && isspace((unsigned char)chars[j]); j++) pszText += chars[j];
				}
			}
			else flag = false;
			m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING);
			ptCursorPos.x = flag ? 0 : x;
			ptCursorPos.y = y;
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			SetSelection(ptCursorPos, ptCursorPos);
			SetAnchor(ptCursorPos);
			SetCursorPos(ptCursorPos);
			EnsureVisible(ptCursorPos);
		}
		m_pTextBuffer->FlushUndoGroup(this);
		return;
	}
	else if (nChar > 31)
	{
		if (QueryEditable() && m_pTextBuffer != NULL)
		{
			m_pTextBuffer->BeginUndoGroup(nChar != _T(' '));

			CPoint ptSelStart, ptSelEnd;
			GetSelection(ptSelStart, ptSelEnd);
			CPoint ptCursorPos;
			if (ptSelStart != ptSelEnd)
			{
				ptCursorPos = ptSelStart;
				DeleteCurrentSelection();
			}
			else
				ptCursorPos = GetCursorPos();

			ASSERT_VALIDTEXTPOS(ptCursorPos);

			char pszText[2];
			pszText[0] = (char) nChar;
			pszText[1] = 0;

			int x, y;
			m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); // [JRT]
			ptCursorPos.x = x;
			ptCursorPos.y = y;
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			SetSelection(ptCursorPos, ptCursorPos);
			SetAnchor(ptCursorPos);
			SetCursorPos(ptCursorPos);
			EnsureVisible(ptCursorPos);

			m_pTextBuffer->FlushUndoGroup(this);
		}
	}
}
Ejemplo n.º 26
0
static int AnchorD_Apply(AnchorDlg *a) {
    SetAnchor(a->sc,a->layer,a->ap,&a->xadjust,&a->yadjust,&a->apos);
return( true );
}
Ejemplo n.º 27
0
void CCrystalEditView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	CCrystalTextView::OnChar(nChar, nRepCnt, nFlags);

	if ((::GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0 ||
			(::GetAsyncKeyState(VK_RBUTTON) & 0x8000) != 0)
		return;

	if (nChar ==32 || nChar == VK_RETURN)
	if(nCursorColor==COLORINDEX_NORMALTEXT||nCursorColor==COLORINDEX_KEYWORD)
	{//анализ на предмет использования шаблонов

		CPoint ptCursorPos = GetCursorPos();
		ASSERT_VALIDTEXTPOS(ptCursorPos);
		if(ptCursorPos.y>=0&&ptCursorPos.y<GetLineCount())
		{
			CString Str = GetLineChars(ptCursorPos.y);
			int nLength = GetLineLength(ptCursorPos.y);
			Str=Str.Left(min(ptCursorPos.x,nLength));
			
			CValue  vDeleteText;
			CValue vInsertText;
			extern 	int AfxCallInitProc(CString csName,CValue Param,CValue &vDeleteText,CValue &vInsertText);
			int nRet=AfxCallInitProc("ПриВыбореШаблона",String(Str),vDeleteText,vInsertText);

			if(nRet)
			{
				int nDeleteCount=vDeleteText.GetString().GetLength();
				int nStartPos=max(0,ptCursorPos.x-nDeleteCount);
				if(nDeleteCount>0)
					m_pTextBuffer->DeleteText(this, ptCursorPos.y, nStartPos, ptCursorPos.y, ptCursorPos.x, CE_ACTION_TYPING);


				int x, y;
				CString csStrInsert=vInsertText.GetString();
				m_pTextBuffer->InsertText(this, ptCursorPos.y, nStartPos, csStrInsert, y, x, CE_ACTION_TYPING);




				CPoint ptEnd;
				ptEnd.x=x;
				ptEnd.y=y;
				ptCursorPos.x=0;

				SetSelection(ptCursorPos, ptEnd);
				FormatSelection(0);

				ptEnd.y-=(csStrInsert.Replace("\r","\r")+1)/2;
				ptEnd.x=GetLineLength(ptEnd.y);
				SetSelection(ptEnd, ptEnd);
				SetAnchor(ptEnd);
				SetCursorPos(ptEnd);

				EnsureVisible(ptEnd);
				MoveEnd(0);
			}
		}
	}

	BOOL bTranslated = FALSE;
	if (nChar == VK_RETURN)
	{	
		
		if (m_bOvrMode)
		{
			CPoint ptCursorPos = GetCursorPos();
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			if (ptCursorPos.y < GetLineCount() - 1)
			{
				ptCursorPos.x = 0;
				ptCursorPos.y++;
				ASSERT_VALIDTEXTPOS(ptCursorPos);
				SetSelection(ptCursorPos, ptCursorPos);
				SetAnchor(ptCursorPos);
				SetCursorPos(ptCursorPos);
				EnsureVisible(ptCursorPos);
				return;
			}
		}

		m_pTextBuffer->BeginUndoGroup();

		if (QueryEditable() && m_pTextBuffer != NULL)
		{
			DeleteCurrentSelection();

			int x, y;
			CPoint ptCursorPos = GetCursorPos();
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			const static TCHAR pszText[3] = _T("\r\n");
			m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); //	[JRT]

			int nLenght = GetLineLength(ptCursorPos.y);
			CString	sLineBuf = GetLineChars(ptCursorPos.y);
			CString sBegin="";
			for(int i=0;i<=nLenght;i++)
			{
				char cChr;
				cChr = sLineBuf.GetAt(i);
				if(!IsLetter(cChr,1)) 
					sBegin+=cChr;
				else 
					break;
			}
			int nPos=ptCursorPos.x;

			m_pTextBuffer->InsertText(this,y,x, sBegin, y, x, CE_ACTION_TYPING); //	[JRT]
			ptCursorPos.x = x;
			ptCursorPos.y = y;
			ASSERT_VALIDTEXTPOS(ptCursorPos);

			SetSelection(ptCursorPos, ptCursorPos);
			SetAnchor(ptCursorPos);
			SetCursorPos(ptCursorPos);
			EnsureVisible(ptCursorPos);



/*			FormatSelection(-1);
			if(nPos>0)
			{
				MoveEnd(0);
			}
*/
		}

		m_pTextBuffer->FlushUndoGroup(this);
		return;
	}

	if (nChar > 31)
	{
		if (QueryEditable() && m_pTextBuffer != NULL)
		{
			BOOL bUndoBeginGroup=m_pTextBuffer->m_bUndoGroup;
			if(!bUndoBeginGroup)
				m_pTextBuffer->BeginUndoGroup(nChar != _T(' '));

			CPoint ptSelStart, ptSelEnd;
			GetSelection(ptSelStart, ptSelEnd);
			CPoint ptCursorPos;
			if (ptSelStart != ptSelEnd)
			{
				ptCursorPos = ptSelStart;
				DeleteCurrentSelection();
			}
			else
			{
				ptCursorPos = GetCursorPos();
				if (m_bOvrMode && ptCursorPos.x < GetLineLength(ptCursorPos.y))
					m_pTextBuffer->DeleteText(this, ptCursorPos.y, ptCursorPos.x, ptCursorPos.y, ptCursorPos.x + 1, CE_ACTION_TYPING); // [JRT]
			}

			ASSERT_VALIDTEXTPOS(ptCursorPos);

			char pszText[2];
			pszText[0] = (char) nChar;
			pszText[1] = 0;
			int x,y;
			USES_CONVERSION;
			m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, A2T(pszText), y, x, CE_ACTION_TYPING); // [JRT]

			ptCursorPos.x = x;
			ptCursorPos.y = y;
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			SetSelection(ptCursorPos, ptCursorPos);
			SetAnchor(ptCursorPos);
			SetCursorPos(ptCursorPos);
			EnsureVisible(ptCursorPos);

			if(!bUndoBeginGroup)
				m_pTextBuffer->FlushUndoGroup(this);
		}
	}
}
Ejemplo n.º 28
0
void CCrystalEditView::OnEditTab() 
{
	if (! QueryEditable() || m_pTextBuffer == NULL)
		return;

	BOOL bTabify = FALSE;
	CPoint ptSelStart, ptSelEnd;
	if (IsSelection())
	{
		GetSelection(ptSelStart, ptSelEnd);
		bTabify = ptSelStart.y != ptSelEnd.y;
	}

	if (bTabify)
	{
		m_pTextBuffer->BeginUndoGroup();

		int nStartLine = ptSelStart.y;
		int nEndLine = ptSelEnd.y;
		ptSelStart.x = 0;
		if (ptSelEnd.x > 0)
		{
			if (ptSelEnd.y == GetLineCount() - 1)
			{
				ptSelEnd.x = GetLineLength(ptSelEnd.y);
			}
			else
			{
				ptSelEnd.x = 0;
				ptSelEnd.y ++;
			}
		}
		else
			nEndLine --;
		SetSelection(ptSelStart, ptSelEnd);
		SetCursorPos(ptSelEnd);
		EnsureVisible(ptSelEnd);

		//	Shift selection to right
		m_bHorzScrollBarLocked = TRUE;
		static const TCHAR pszText[] = _T("\t");
		for (int L = nStartLine; L <= nEndLine; L ++)
		{
			int x, y;
			m_pTextBuffer->InsertText(this, L, 0, pszText, y, x, CE_ACTION_INDENT); //	[JRT]
		}
		m_bHorzScrollBarLocked = FALSE;
		RecalcHorzScrollBar();

		m_pTextBuffer->FlushUndoGroup(this);
		return;
	}

	if (m_bOvrMode)
	{
		CPoint ptCursorPos = GetCursorPos();
		ASSERT_VALIDTEXTPOS(ptCursorPos);

		int nLineLength = GetLineLength(ptCursorPos.y);
		LPCTSTR pszLineChars = GetLineChars(ptCursorPos.y);
		if (ptCursorPos.x < nLineLength)
		{
			int nTabSize = GetTabSize();
			int nChars = nTabSize - CalculateActualOffset(ptCursorPos.y, ptCursorPos.x) % nTabSize;
			ASSERT(nChars > 0 && nChars <= nTabSize);

			while (nChars > 0)
			{
				if (ptCursorPos.x == nLineLength)
					break;
				if (pszLineChars[ptCursorPos.x] == _T('\t'))
				{
					ptCursorPos.x ++;
					break;
				}
				ptCursorPos.x ++;
				nChars --;
			}
			ASSERT(ptCursorPos.x <= nLineLength);
			ASSERT_VALIDTEXTPOS(ptCursorPos);

			SetSelection(ptCursorPos, ptCursorPos);
			SetAnchor(ptCursorPos);
			SetCursorPos(ptCursorPos);
			EnsureVisible(ptCursorPos);
			return;
		}
	}

	m_pTextBuffer->BeginUndoGroup();

	DeleteCurrentSelection();

	CPoint ptCursorPos = GetCursorPos();
	ASSERT_VALIDTEXTPOS(ptCursorPos);

	static const TCHAR pszText[] = _T("\t");
	int x, y;
	m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); //	[JRT]
	ptCursorPos.x = x;
	ptCursorPos.y = y;
	ASSERT_VALIDTEXTPOS(ptCursorPos);
	SetSelection(ptCursorPos, ptCursorPos);
	SetAnchor(ptCursorPos);
	SetCursorPos(ptCursorPos);
	EnsureVisible(ptCursorPos);

	m_pTextBuffer->FlushUndoGroup(this);
}
Ejemplo n.º 29
0
void CCrystalEditView::OnEditUntab() 
{
	if (! QueryEditable() || m_pTextBuffer == NULL)
		return;

	BOOL bTabify = FALSE;
	CPoint ptSelStart, ptSelEnd;
	if (IsSelection())
	{
		GetSelection(ptSelStart, ptSelEnd);
		bTabify = ptSelStart.y != ptSelEnd.y;
	}

	if (bTabify)
	{
		m_pTextBuffer->BeginUndoGroup();

		CPoint ptSelStart, ptSelEnd;
		GetSelection(ptSelStart, ptSelEnd);
		int nStartLine = ptSelStart.y;
		int nEndLine = ptSelEnd.y;
		ptSelStart.x = 0;
		if (ptSelEnd.x > 0)
		{
			if (ptSelEnd.y == GetLineCount() - 1)
			{
				ptSelEnd.x = GetLineLength(ptSelEnd.y);
			}
			else
			{
				ptSelEnd.x = 0;
				ptSelEnd.y ++;
			}
		}
		else
			nEndLine --;
		SetSelection(ptSelStart, ptSelEnd);
		SetCursorPos(ptSelEnd);
		EnsureVisible(ptSelEnd);

		//	Shift selection to left
		m_bHorzScrollBarLocked = TRUE;
		for (int L = nStartLine; L <= nEndLine; L ++)
		{
			int nLength = GetLineLength(L);
			if (nLength > 0)
			{
				LPCTSTR pszChars = GetLineChars(L);
				int nPos = 0, nOffset = 0;
				while (nPos < nLength)
				{
					if (pszChars[nPos] == _T(' '))
					{
						nPos ++;
						if (++ nOffset >= GetTabSize())
							break;
					}
					else
					{
						if (pszChars[nPos] == _T('\t'))
							nPos ++;
						break;
					}
				}

				if (nPos > 0)
					m_pTextBuffer->DeleteText(this, L, 0, L, nPos, CE_ACTION_INDENT); // [JRT]
			}
		}
		m_bHorzScrollBarLocked = FALSE;
		RecalcHorzScrollBar();

		m_pTextBuffer->FlushUndoGroup(this);
	}
	else
	{
		CPoint ptCursorPos = GetCursorPos();
		ASSERT_VALIDTEXTPOS(ptCursorPos);
		if (ptCursorPos.x > 0)
		{
			int nTabSize = GetTabSize();
			int nOffset = CalculateActualOffset(ptCursorPos.y, ptCursorPos.x);
			int nNewOffset = nOffset / nTabSize * nTabSize;
			if (nOffset == nNewOffset && nNewOffset > 0)
				nNewOffset -= nTabSize;
			ASSERT(nNewOffset >= 0);

			LPCTSTR pszChars = GetLineChars(ptCursorPos.y);
			int nCurrentOffset = 0;
			int I = 0;
			while (nCurrentOffset < nNewOffset)
			{
				if (pszChars[I] == _T('\t'))
					nCurrentOffset = nCurrentOffset / nTabSize * nTabSize + nTabSize;
				else
					nCurrentOffset ++;
				I ++;
			}

			ASSERT(nCurrentOffset == nNewOffset);

			ptCursorPos.x = I;
			ASSERT_VALIDTEXTPOS(ptCursorPos);
			SetSelection(ptCursorPos, ptCursorPos);
			SetAnchor(ptCursorPos);
			SetCursorPos(ptCursorPos);
			EnsureVisible(ptCursorPos);
		}
	}
}