* contrib/hbide/resources/curlinehilight.png
+ contrib/hbide/resources/horzruler.png
* contrib/hbide/resources/togglelinenumber.png
* contrib/hbide/resources/toolsutilities.ui
* contrib/hbide/resources/toolsutilities.uic
* contrib/hbide/resources/setup.ui
* contrib/hbide/resources/setup.uic
* contrib/hbqt/qth/HBQPlainTextEdit.qth
* contrib/hbqt/qth/QTableWidget.qth
- contrib/hbqt/qth/HBQSyntaxHighLighter.qth
+ contrib/hbqt/qth/HBQSyntaxHighlighter.qth
* contrib/hbqt/doc/en/class_hbqplaintextedit.txt
* contrib/hbqt/doc/en/class_hbqsyntaxhighlighter.txt
* contrib/hbqt/qtgui/HBQPlainTextEdit.cpp
* contrib/hbqt/qtgui/QTableWidget.cpp
* contrib/hbqt/qtgui/THBQPlainTextEdit.prg
* contrib/hbqt/qtgui/HBQSyntaxHighlighter.cpp
* contrib/hbqt/qtgui/THBQSyntaxHighlighter.prg
* contrib/hbqt/hbqt_hbqplaintextedit.cpp
* contrib/hbqt/hbqt_hbqplaintextedit.h
* contrib/hbqt/hbqt_hbqsyntaxhighlighter.cpp
* contrib/hbqt/hbqt_hbqsyntaxhighlighter.h
* contrib/hbide/hbide.hbp
* contrib/hbide/hbide.ch
* contrib/hbide/hbide.prg
+ contrib/hbide/idedict.prg
* contrib/hbide/idedocks.prg
* contrib/hbide/ideedit.prg
* contrib/hbide/ideeditor.prg
* contrib/hbide/idemisc.prg
* contrib/hbide/ideobject.prg
* contrib/hbide/idesaveload.prg
* contrib/hbide/ideshortcuts.prg
* contrib/hbide/idestylesheets.prg
* contrib/hbide/idethemes.prg
* contrib/hbide/idetools.prg
% Widened padding for menubar prompts to show up at a proper distance.
+ Controlled "RETURN" keyword not to jump to first indentation place,
with env variable - HBIDE_RETURN_ATBEGINING=yes. Scheduled to be
included in "Setup" interface.
+ Allowed hbIDE execution with any text type file. It was accepting .PRG.CPP only.
+ Broadened the scope of keyword coloring for any case, mixed or absolute.
It was all lower or all upper previously.
+ Prepared ground for user defined keywords through user dictionaries.
+ Added new flags in "Setup" dialog ( yet not active ).
Please have a look into the contents of different pages and
let me know what else can qualify to be included therein.
+ More macro for Tools parameter - ${source_fullname_less_ext}
% Tools & Utilities dialog made modeless. At times it is desirable
to execute a tool multiple times and also to gather output logs.
+ Tools & Utilities dialog now remembers its last opened position.
+ Implemented: user-configurable 5 toolbars which can be populated
through Tool & Utilities interface. Invoke "Tools & Utilities"
interface and play with the toolbars. You will find it really
rewarding. I am also trying to find a way to hook
"Kayboard Mappings" macros to be included under this interface.
Your input is welcome. I will write the help in about a week,
but interface is straight enough to grab/grasp/use.
+ Implemented: to switch on/off horizontal ruler.
+ Implemented: to remember the last settings for next run for
Horizontal Ruler, Line Numbers display and Current Line highlighting.
2493 lines
70 KiB
C++
2493 lines
70 KiB
C++
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* Harbour-Qt wrapper generator.
|
|
*
|
|
* Copyright 2010 Pritpal Bedi <pritpal@vouchcac.com>
|
|
* Copyright 2009 Gancov Kostya <kossne@mail.ru>
|
|
* www - http://harbour-project.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this software; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
|
*
|
|
* As a special exception, the Harbour Project gives permission for
|
|
* additional uses of the text contained in its release of Harbour.
|
|
*
|
|
* The exception is that, if you link the Harbour libraries with other
|
|
* files to produce an executable, this does not by itself cause the
|
|
* resulting executable to be covered by the GNU General Public License.
|
|
* Your use of that executable is in no way restricted on account of
|
|
* linking the Harbour library code into it.
|
|
*
|
|
* This exception does not however invalidate any other reasons why
|
|
* the executable file might be covered by the GNU General Public License.
|
|
*
|
|
* This exception applies only to the code released by the Harbour
|
|
* Project under the name Harbour. If you copy code from other
|
|
* Harbour Project or Free Software Foundation releases into a copy of
|
|
* Harbour, as the General Public License permits, the exception does
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
* anyone as to the status of such modified files, you must delete
|
|
* this exception notice from them.
|
|
*
|
|
* If you write modifications of your own for Harbour, it is your choice
|
|
* whether to permit this exception to apply to your modifications.
|
|
* If you do not wish that, delete this exception notice.
|
|
*
|
|
*/
|
|
/*----------------------------------------------------------------------*/
|
|
/*
|
|
* The code below is puled from TextEdit.cpp of QWriter by Gancov Kotsya
|
|
*
|
|
* and adopted for Harbour's hbIDE interface. The code has been intensively
|
|
* formatted and changed to suit hbIDE and Harbour's wrappers for Qt.
|
|
* The special hilight for this adoption is <braces matching>, current line
|
|
* coloring and bookmarks.
|
|
*
|
|
* So a big thank you.
|
|
*
|
|
* Pritpal Bedi
|
|
*/
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
#include "hbqt.h"
|
|
|
|
#include "hbapiitm.h"
|
|
#include "hbthread.h"
|
|
#include "hbvm.h"
|
|
|
|
#if QT_VERSION >= 0x040500
|
|
|
|
#include "hbqt_hbqplaintextedit.h"
|
|
#include <QtGui/QApplication>
|
|
|
|
#define selectionState_off 0
|
|
#define selectionState_on 1
|
|
|
|
#define selectionMode_none 0
|
|
#define selectionMode_stream 1
|
|
#define selectionMode_column 2
|
|
#define selectionMode_line 3
|
|
|
|
#define selectionDisplay_none 0
|
|
#define selectionDisplay_qt 1
|
|
#define selectionDisplay_ide 2
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
HBQPlainTextEdit::HBQPlainTextEdit( QWidget * parent ) : QPlainTextEdit( parent )
|
|
{
|
|
m_currentLineColor.setNamedColor( "#e8e8ff" );
|
|
m_lineAreaBkColor.setNamedColor( "#e4e4e4" );
|
|
m_horzRulerBkColor.setNamedColor( "whitesmoke" );
|
|
m_matchBracesAll = false;
|
|
|
|
spaces = 3;
|
|
spacesTab = "";
|
|
styleHightlighter = "prg";
|
|
numberBlock = true;
|
|
lineNumberArea = new LineNumberArea( this );
|
|
isTipActive = false;
|
|
columnBegins = -1;
|
|
columnEnds = -1;
|
|
rowBegins = -1;
|
|
rowEnds = -1;
|
|
selectionState = selectionState_off;
|
|
selectionMode = selectionMode_stream;
|
|
selectionDisplay = selectionDisplay_none;
|
|
isColumnSelectionON = false;
|
|
isLineSelectionON = false;
|
|
horzRulerHeight = 20;
|
|
horzRuler = new HorzRuler( this );
|
|
caretState = 0;
|
|
isSelectionByApplication = false;
|
|
hitTestRow = -1;
|
|
hitTestColumn = -1;
|
|
highlight = QRect( -1, -1, -1, -1 );
|
|
isSelectionPersistent = false;
|
|
isShiftPressed = false;
|
|
|
|
connect( this, SIGNAL( blockCountChanged( int ) ) , this, SLOT( hbUpdateLineNumberAreaWidth( int ) ) );
|
|
connect( this, SIGNAL( updateRequest( const QRect &, int ) ), this, SLOT( hbUpdateLineNumberArea( const QRect &, int ) ) );
|
|
|
|
hbUpdateLineNumberAreaWidth( 0 );
|
|
|
|
connect( this, SIGNAL( cursorPositionChanged() ) , this, SLOT( hbSlotCursorPositionChanged() ) );
|
|
connect( this, SIGNAL( updateRequest( const QRect &, int ) ), this, SLOT( hbUpdateHorzRuler( const QRect &, int ) ) );
|
|
|
|
horzRuler->setFrameShape( QFrame::Panel );
|
|
horzRuler->setFrameShadow( QFrame::Sunken );
|
|
|
|
QPalette pl( QPlainTextEdit::palette() );
|
|
m_selectionColor = pl.color( QPalette::Highlight );
|
|
|
|
setContentsMargins( 0,0,0,0 );
|
|
|
|
#if 0
|
|
timer = new QTimer( this );
|
|
connect( timer, SIGNAL( timeout() ), this, SLOT( hbUpdateCaret() ) );
|
|
timer->start( 500 );
|
|
#endif
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
HBQPlainTextEdit::~HBQPlainTextEdit()
|
|
{
|
|
#if 0
|
|
if( timer )
|
|
timer->stop();
|
|
#endif
|
|
|
|
disconnect( this, SIGNAL( blockCountChanged( int ) ) );
|
|
disconnect( this, SIGNAL( updateRequest( const QRect &, int ) ) );
|
|
disconnect( this, SIGNAL( cursorPositionChanged() ) );
|
|
|
|
delete lineNumberArea;
|
|
|
|
if( block )
|
|
hb_itemRelease( block );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbSetEventBlock( PHB_ITEM pBlock )
|
|
{
|
|
if( pBlock )
|
|
block = hb_itemNew( pBlock );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbApplyKey( int key, Qt::KeyboardModifiers modifiers, const QString & txt )
|
|
{
|
|
QKeyEvent * ev = new QKeyEvent( QEvent::KeyPress, key, modifiers, txt );
|
|
QPlainTextEdit::keyPressEvent( ev );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbTogglePersistentSelection()
|
|
{
|
|
isSelectionPersistent = ! isSelectionPersistent;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbRefresh()
|
|
{
|
|
repaint();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbUpdateCaret()
|
|
{
|
|
if( caretState == 0 )
|
|
caretState = 1;
|
|
else
|
|
caretState = 0;
|
|
|
|
QRect r( cursorRect() );
|
|
r.setX( r.x() + 100 );
|
|
repaint( r );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbShowPrototype( const QString & tip )
|
|
{
|
|
if( tip == ( QString ) "" )
|
|
{
|
|
QToolTip::hideText();
|
|
isTipActive = false;
|
|
}
|
|
else
|
|
{
|
|
QRect r = HBQPlainTextEdit::cursorRect();
|
|
QToolTip::showText( mapToGlobal( QPoint( r.x(), r.y()+20 ) ), tip );
|
|
isTipActive = true;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
bool HBQPlainTextEdit::event( QEvent *event )
|
|
{
|
|
if( event->type() == QEvent::KeyPress )
|
|
{
|
|
QKeyEvent *keyEvent = ( QKeyEvent * ) event;
|
|
if( ( keyEvent->key() == Qt::Key_Tab ) && ( keyEvent->modifiers() & Qt::ControlModifier ) )
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if( ( keyEvent->key() == Qt::Key_Tab ) && !( keyEvent->modifiers() & Qt::ControlModifier & Qt::AltModifier & Qt::ShiftModifier ) )
|
|
{
|
|
this->hbInsertTab( 0 );
|
|
return true;
|
|
}
|
|
else if( ( keyEvent->key() == Qt::Key_Backtab ) && ( keyEvent->modifiers() & Qt::ShiftModifier ) )
|
|
{
|
|
this->hbInsertTab( 1 );
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
else if( event->type() == QEvent::ToolTip )
|
|
{
|
|
event->ignore();
|
|
#if 0
|
|
QHelpEvent * helpEvent = static_cast<QHelpEvent *>( event );
|
|
|
|
if( helpEvent && isTipActive )
|
|
{
|
|
event->ignore();
|
|
}
|
|
#endif
|
|
return false;//true;
|
|
}
|
|
|
|
return QPlainTextEdit::event( event );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbHighlightArea( int top, int left, int bottom, int right, int mode )
|
|
{
|
|
HB_SYMBOL_UNUSED( mode );
|
|
|
|
highlight.setTop( top );
|
|
highlight.setLeft( left );
|
|
highlight.setBottom( bottom );
|
|
highlight.setRight( right );
|
|
|
|
repaint();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbSetSelectionColor( const QColor & color )
|
|
{
|
|
m_selectionColor = color;
|
|
|
|
QPalette pl( QPlainTextEdit::palette() );
|
|
pl.setColor( QPalette::Highlight, m_selectionColor );
|
|
pl.setColor( QPalette::HighlightedText, QColor( 0,0,0 ) );
|
|
setPalette( pl );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
static bool isNavableKey( int k )
|
|
{
|
|
return ( k == Qt::Key_Right || k == Qt::Key_Left || k == Qt::Key_Up || k == Qt::Key_Down ||
|
|
k == Qt::Key_Home || k == Qt::Key_End || k == Qt::Key_PageUp || k == Qt::Key_PageDown );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
bool HBQPlainTextEdit::isCursorInSelection()
|
|
{
|
|
int cb = columnBegins <= columnEnds ? columnBegins : columnEnds;
|
|
int ce = columnBegins <= columnEnds ? columnEnds : columnBegins;
|
|
int rb = rowBegins <= rowEnds ? rowBegins : rowEnds;
|
|
int re = rowBegins <= rowEnds ? rowEnds : rowBegins;
|
|
|
|
QTextCursor c = textCursor();
|
|
int col = c.columnNumber();
|
|
int row = c.blockNumber();
|
|
|
|
return( col >= cb && col <= ce && row >= rb && row <= re );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbClearSelection()
|
|
{
|
|
setCursorWidth( 1 );
|
|
|
|
rowBegins = -1;
|
|
rowEnds = -1;
|
|
columnBegins = -1;
|
|
columnEnds = -1;
|
|
|
|
emit selectionChanged();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbHitTest( const QPoint & pt )
|
|
{
|
|
QTextCursor ct = cursorForPosition( QPoint( 2,2 ) );
|
|
int t = ct.blockNumber();
|
|
int c = ct.columnNumber();
|
|
|
|
hitTestRow = t + ( pt.y() / fontMetrics().height() );
|
|
hitTestColumn = c + ( pt.x() / fontMetrics().averageCharWidth() );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
int HBQPlainTextEdit::hbFirstVisibleColumn()
|
|
{
|
|
return ( horizontalScrollBar()->value() / fontMetrics().averageCharWidth() );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbGetViewportInfo()
|
|
{
|
|
if( block )
|
|
{
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, 21017 );
|
|
PHB_ITEM p2 = hb_itemNew( NULL );
|
|
|
|
hb_arrayNew( p2, 6 );
|
|
|
|
int t = firstVisibleBlock().blockNumber();
|
|
int c = hbFirstVisibleColumn();
|
|
int rows = viewport()->height() / fontMetrics().height();
|
|
int cols = viewport()->width() / fontMetrics().averageCharWidth();
|
|
|
|
hb_arraySetNI( p2, 1, t );
|
|
hb_arraySetNI( p2, 2, c );
|
|
hb_arraySetNI( p2, 3, rows );
|
|
hb_arraySetNI( p2, 4, cols );
|
|
hb_arraySetNI( p2, 5, textCursor().blockNumber() );
|
|
hb_arraySetNI( p2, 6, textCursor().columnNumber() );
|
|
|
|
hb_vmEvalBlockV( block, 2, p1, p2 );
|
|
hb_itemRelease( p1 );
|
|
hb_itemRelease( p2 );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbSetSelectionInfo( PHB_ITEM selectionInfo )
|
|
{
|
|
rowBegins = hb_arrayGetNI( selectionInfo, 1 );
|
|
columnBegins = hb_arrayGetNI( selectionInfo, 2 );
|
|
rowEnds = hb_arrayGetNI( selectionInfo, 3 );
|
|
columnEnds = hb_arrayGetNI( selectionInfo, 4 );
|
|
selectionMode = hb_arrayGetNI( selectionInfo, 5 );
|
|
|
|
emit selectionChanged();
|
|
|
|
update();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbGetSelectionInfo()
|
|
{
|
|
if( block )
|
|
{
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, 21000 );
|
|
PHB_ITEM p2 = hb_itemNew( NULL );
|
|
|
|
hb_arrayNew( p2, 6 );
|
|
|
|
hb_arraySetNI( p2, 1, rowBegins );
|
|
hb_arraySetNI( p2, 2, columnBegins );
|
|
hb_arraySetNI( p2, 3, rowEnds );
|
|
hb_arraySetNI( p2, 4, columnEnds );
|
|
hb_arraySetNI( p2, 5, selectionMode );
|
|
hb_arraySetNI( p2, 6, selectionState );
|
|
|
|
hb_vmEvalBlockV( block, 2, p1, p2 );
|
|
hb_itemRelease( p1 );
|
|
hb_itemRelease( p2 );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbSetSelectionMode( int mode, bool byApplication )
|
|
{
|
|
if( byApplication )
|
|
{
|
|
if( mode == 0 )
|
|
{
|
|
isSelectionByApplication = false;
|
|
isStreamSelectionON = false;
|
|
isColumnSelectionON = false;
|
|
isLineSelectionON = false;
|
|
hbClearSelection();
|
|
repaint();
|
|
return;
|
|
}
|
|
|
|
isSelectionByApplication = ! isSelectionByApplication;
|
|
|
|
if( ! isSelectionByApplication )
|
|
{
|
|
isStreamSelectionON = false;
|
|
isColumnSelectionON = false;
|
|
isLineSelectionON = false;
|
|
|
|
if( mode == selectionMode_column )
|
|
{
|
|
QTextCursor c( textCursor() );
|
|
c.movePosition( QTextCursor::EndOfLine );
|
|
if( c.columnNumber() > columnEnds )
|
|
{
|
|
c.movePosition( QTextCursor::StartOfLine );
|
|
c.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, columnEnds );
|
|
}
|
|
setTextCursor( c );
|
|
}
|
|
setCursorWidth( 1 );
|
|
}
|
|
else
|
|
{
|
|
switch( mode )
|
|
{
|
|
case selectionMode_stream:
|
|
{
|
|
setCursorWidth( 1 );
|
|
selectionMode = selectionMode_stream;
|
|
isStreamSelectionON = true;
|
|
isColumnSelectionON = false;
|
|
isLineSelectionON = false;
|
|
|
|
QTextCursor c( textCursor() );
|
|
|
|
rowBegins = c.blockNumber();
|
|
rowEnds = rowBegins;
|
|
columnBegins = c.columnNumber();
|
|
columnEnds = columnBegins;
|
|
break;
|
|
}
|
|
case selectionMode_column:
|
|
{
|
|
setCursorWidth( 0 );
|
|
|
|
selectionMode = selectionMode_column;
|
|
isStreamSelectionON = false;
|
|
isColumnSelectionON = true;
|
|
isLineSelectionON = false;
|
|
|
|
QTextCursor c( textCursor() );
|
|
|
|
rowBegins = c.blockNumber();
|
|
rowEnds = rowBegins;
|
|
columnBegins = c.columnNumber();
|
|
columnEnds = columnBegins;
|
|
|
|
break;
|
|
}
|
|
case selectionMode_line:
|
|
{
|
|
setCursorWidth( 1 );
|
|
selectionMode = selectionMode_line;
|
|
isStreamSelectionON = false;
|
|
isColumnSelectionON = false;
|
|
isLineSelectionON = true;
|
|
|
|
QTextCursor c( textCursor() );
|
|
|
|
rowBegins = c.blockNumber();
|
|
rowEnds = rowBegins;
|
|
columnBegins = 0;
|
|
columnEnds = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( ! isSelectionByApplication )
|
|
{
|
|
switch( mode )
|
|
{
|
|
case selectionMode_stream:
|
|
{
|
|
setCursorWidth( 1 );
|
|
if( columnBegins >= 0 )
|
|
{
|
|
hbToStream();
|
|
}
|
|
selectionMode = selectionMode_stream;
|
|
isColumnSelectionON = false;
|
|
isLineSelectionON = false;
|
|
break;
|
|
}
|
|
case selectionMode_column:
|
|
{
|
|
setCursorWidth( 0 );
|
|
selectionMode = selectionMode_column;
|
|
isColumnSelectionON = true;
|
|
isLineSelectionON = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
emit selectionChanged();
|
|
repaint();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbToStream()
|
|
{
|
|
int rb = rowBegins <= rowEnds ? rowBegins : rowEnds;
|
|
int re = rowBegins <= rowEnds ? rowEnds : rowBegins;
|
|
|
|
if( selectionMode == selectionMode_line )
|
|
{
|
|
QTextCursor c = textCursor();
|
|
|
|
c.movePosition( QTextCursor::Start );
|
|
c.movePosition( QTextCursor::Down , QTextCursor::MoveAnchor, rb );
|
|
c.movePosition( QTextCursor::Right , QTextCursor::MoveAnchor, columnBegins );
|
|
c.movePosition( QTextCursor::Down , QTextCursor::MoveAnchor, re - rb );
|
|
c.movePosition( QTextCursor::EndOfLine, QTextCursor::MoveAnchor );
|
|
int cce = c.columnNumber();
|
|
if( cce > columnEnds )
|
|
{
|
|
c.movePosition( QTextCursor::StartOfLine, QTextCursor::MoveAnchor );
|
|
c.movePosition( QTextCursor::Right , QTextCursor::MoveAnchor, columnEnds );
|
|
}
|
|
else
|
|
{
|
|
columnEnds = cce;
|
|
}
|
|
columnBegins = 0; rowBegins = rb; rowEnds = re;
|
|
setTextCursor( c );
|
|
}
|
|
else if( selectionMode == selectionMode_column )
|
|
{
|
|
QTextCursor c = textCursor();
|
|
|
|
c.movePosition( QTextCursor::Start );
|
|
c.movePosition( QTextCursor::Down , QTextCursor::MoveAnchor, re );
|
|
c.movePosition( QTextCursor::EndOfLine, QTextCursor::MoveAnchor );
|
|
if( c.columnNumber() > columnEnds )
|
|
{
|
|
c.movePosition( QTextCursor::StartOfLine, QTextCursor::MoveAnchor );
|
|
c.movePosition( QTextCursor::Right , QTextCursor::MoveAnchor, columnEnds );
|
|
}
|
|
columnEnds = c.columnNumber(); rowBegins = rb; rowEnds = re;
|
|
setTextCursor( c );
|
|
}
|
|
else if( selectionMode == selectionMode_stream )
|
|
{
|
|
QTextCursor c = textCursor();
|
|
rowBegins = c.blockNumber();
|
|
rowEnds = rowBegins;
|
|
columnBegins = c.columnNumber();
|
|
columnEnds = columnBegins;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbCut( int k )
|
|
{
|
|
if( block )
|
|
{
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, 21014 );
|
|
PHB_ITEM p2 = hb_itemNew( NULL );
|
|
|
|
hb_arrayNew( p2, 7 );
|
|
hb_arraySetNI( p2, 1, rowBegins );
|
|
hb_arraySetNI( p2, 2, columnBegins );
|
|
hb_arraySetNI( p2, 3, rowEnds );
|
|
hb_arraySetNI( p2, 4, columnEnds );
|
|
hb_arraySetNI( p2, 5, selectionMode );
|
|
hb_arraySetNI( p2, 6, selectionState );
|
|
hb_arraySetNI( p2, 7, k );
|
|
|
|
hb_vmEvalBlockV( block, 2, p1, p2 );
|
|
hb_itemRelease( p1 );
|
|
hb_itemRelease( p2 );
|
|
|
|
if( selectionMode == selectionMode_column ) //&& k == 0 )
|
|
columnEnds = columnBegins;
|
|
}
|
|
else
|
|
{
|
|
QPlainTextEdit::cut();
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbCopy()
|
|
{
|
|
if( block )
|
|
{
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, 21011 );
|
|
PHB_ITEM p2 = hb_itemNew( NULL );
|
|
|
|
hb_arrayNew( p2, 7 );
|
|
hb_arraySetNI( p2, 1, rowBegins );
|
|
hb_arraySetNI( p2, 2, columnBegins );
|
|
hb_arraySetNI( p2, 3, rowEnds );
|
|
hb_arraySetNI( p2, 4, columnEnds );
|
|
hb_arraySetNI( p2, 5, selectionMode );
|
|
hb_arraySetNI( p2, 6, selectionState );
|
|
hb_arraySetNI( p2, 7, 0 );
|
|
|
|
hb_vmEvalBlockV( block, 2, p1, p2 );
|
|
hb_itemRelease( p1 );
|
|
hb_itemRelease( p2 );
|
|
}
|
|
else
|
|
{
|
|
QPlainTextEdit::copy();
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbPaste()
|
|
{
|
|
if( block )
|
|
{
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, 21012 );
|
|
PHB_ITEM p2 = hb_itemPutNI( NULL, selectionMode );
|
|
hb_vmEvalBlockV( block, 1, p1, p2 );
|
|
hb_itemRelease( p1 );
|
|
hb_itemRelease( p2 );
|
|
|
|
if( ! isSelectionPersistent )
|
|
{
|
|
hbClearSelection();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QPlainTextEdit::paste();
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::mouseDoubleClickEvent( QMouseEvent *event )
|
|
{
|
|
QPlainTextEdit::mouseDoubleClickEvent( event );
|
|
|
|
QTextCursor c( textCursor() );
|
|
if( c.hasSelection() )
|
|
{
|
|
rowBegins = c.blockNumber();
|
|
rowEnds = rowBegins;
|
|
columnEnds = c.columnNumber();
|
|
columnBegins = columnEnds - ( c.selectionEnd() - c.selectionStart() );
|
|
selectionMode = selectionMode_stream;
|
|
emit selectionChanged();
|
|
repaint();
|
|
}
|
|
|
|
if( block )
|
|
{
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, QEvent::MouseButtonDblClick );
|
|
hb_vmEvalBlockV( block, 1, p1 );
|
|
hb_itemRelease( p1 );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::mousePressEvent( QMouseEvent *event )
|
|
{
|
|
if( isSelectionByApplication )
|
|
{
|
|
if( isColumnSelectionON )
|
|
{
|
|
event->accept();
|
|
}
|
|
else
|
|
{
|
|
QPlainTextEdit::mousePressEvent( event );
|
|
}
|
|
return;
|
|
}
|
|
|
|
if( event->modifiers() & Qt::ShiftModifier )
|
|
{
|
|
QTextCursor c( textCursor() );
|
|
rowBegins = c.blockNumber();
|
|
columnBegins = c.columnNumber();
|
|
|
|
QPlainTextEdit::mousePressEvent( event );
|
|
|
|
c = textCursor();
|
|
rowEnds = c.blockNumber();
|
|
columnEnds = c.columnNumber();
|
|
|
|
selectionState = 1;
|
|
setCursorWidth( 1 );
|
|
selectionMode = selectionMode_stream;
|
|
emit selectionChanged();
|
|
|
|
repaint();
|
|
}
|
|
else
|
|
{
|
|
setCursorWidth( 1 );
|
|
if( ! isSelectionPersistent )
|
|
{
|
|
selectionState = 0;
|
|
hbClearSelection();
|
|
}
|
|
else
|
|
{
|
|
selectionState = 1;
|
|
}
|
|
QPlainTextEdit::mousePressEvent( event );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::mouseReleaseEvent( QMouseEvent *event )
|
|
{
|
|
if( isSelectionByApplication )
|
|
{
|
|
if( isLineSelectionON )
|
|
{
|
|
QPlainTextEdit::mouseReleaseEvent( event );
|
|
rowEnds = textCursor().blockNumber();
|
|
}
|
|
else if( isColumnSelectionON )
|
|
{
|
|
event->accept();
|
|
hbHitTest( event->pos() );
|
|
rowEnds = hitTestRow;
|
|
columnEnds = hitTestColumn;
|
|
}
|
|
else if( isStreamSelectionON )
|
|
{
|
|
QPlainTextEdit::mouseReleaseEvent( event );
|
|
rowEnds = textCursor().blockNumber();
|
|
columnEnds = textCursor().columnNumber();
|
|
}
|
|
repaint();
|
|
return;
|
|
}
|
|
selectionState = 1;
|
|
setCursorWidth( 1 );
|
|
emit selectionChanged();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::mouseMoveEvent( QMouseEvent *event )
|
|
{
|
|
if( isSelectionByApplication )
|
|
{
|
|
event->accept();
|
|
return;
|
|
}
|
|
|
|
if( selectionMode == selectionMode_line )
|
|
selectionMode = selectionMode_stream;
|
|
|
|
if( event->buttons() & Qt::LeftButton )
|
|
{
|
|
if( selectionState == 1 )
|
|
{
|
|
selectionState = 2;
|
|
hbClearSelection();
|
|
}
|
|
|
|
if( columnBegins == -1 )
|
|
{
|
|
if( selectionMode == selectionMode_column )
|
|
setCursorWidth( 0 );
|
|
|
|
QTextCursor c( textCursor() );
|
|
|
|
rowBegins = c.blockNumber();
|
|
columnBegins = c.columnNumber();
|
|
rowEnds = rowBegins;
|
|
columnEnds = columnBegins;
|
|
|
|
emit selectionChanged();
|
|
QPlainTextEdit::mouseMoveEvent( event );
|
|
}
|
|
else
|
|
{
|
|
if( selectionMode == selectionMode_column )
|
|
{
|
|
QTextCursor c( cursorForPosition( QPoint( 1,1 ) ) );
|
|
rowEnds = c.blockNumber() + ( event->y() / fontMetrics().height() );
|
|
columnEnds = c.columnNumber() + ( event->x() / fontMetrics().averageCharWidth() );
|
|
}
|
|
QPlainTextEdit::mouseMoveEvent( event );
|
|
QTextCursor c = textCursor();
|
|
|
|
if( selectionMode != selectionMode_column )
|
|
{
|
|
rowEnds = c.blockNumber();
|
|
columnEnds = c.columnNumber();
|
|
}
|
|
c.clearSelection();
|
|
setTextCursor( c );
|
|
repaint();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::keyReleaseEvent( QKeyEvent * event )
|
|
{
|
|
QPlainTextEdit::keyReleaseEvent( event );
|
|
|
|
if( ( event->modifiers() & Qt::ControlModifier ) && event->text() == "" )
|
|
{
|
|
if( selectionState == 2 )
|
|
{
|
|
selectionState = 1;
|
|
emit selectionChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
bool HBQPlainTextEdit::hbKeyPressSelectionByApplication( QKeyEvent * event )
|
|
{
|
|
bool shift = event->modifiers() & Qt::ShiftModifier;
|
|
int k = event->key();
|
|
|
|
if( isNavableKey( k ) && shift )
|
|
{
|
|
event->accept();
|
|
QTextCursor c( textCursor() );
|
|
c.clearSelection();
|
|
setTextCursor( c );
|
|
QKeyEvent * ev = new QKeyEvent( event->type(), event->key(), Qt::NoModifier, event->text() );
|
|
keyPressEvent( ev );
|
|
return true;
|
|
}
|
|
|
|
if( isNavableKey( k ) )
|
|
{
|
|
if( selectionMode == selectionMode_stream )
|
|
{
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
|
|
QTextCursor c( textCursor() );
|
|
rowEnds = c.blockNumber();
|
|
columnEnds = c.columnNumber();
|
|
}
|
|
else if( selectionMode == selectionMode_column )
|
|
{
|
|
switch( k )
|
|
{
|
|
case Qt::Key_Right:
|
|
{
|
|
QTextCursor c( textCursor() );
|
|
c.movePosition( QTextCursor::EndOfLine );
|
|
if( c.columnNumber() <= columnEnds )
|
|
{
|
|
setTextCursor( c );
|
|
}
|
|
event->ignore();
|
|
columnEnds++;
|
|
break;
|
|
}
|
|
case Qt::Key_Left:
|
|
{
|
|
QTextCursor c( textCursor() );
|
|
int col = c.columnNumber();
|
|
if( col < columnEnds - 1 )
|
|
{
|
|
c.movePosition( QTextCursor::Left );
|
|
columnEnds--;
|
|
}
|
|
else if( columnEnds - 1 >= 0 )
|
|
{
|
|
columnEnds--;
|
|
}
|
|
event->ignore();
|
|
break;
|
|
}
|
|
case Qt::Key_Home:
|
|
{
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
columnEnds = textCursor().columnNumber();
|
|
break;
|
|
}
|
|
case Qt::Key_End:
|
|
{
|
|
QTextCursor c( textCursor() );
|
|
c.movePosition( QTextCursor::EndOfLine, QTextCursor::MoveAnchor );
|
|
if( c.columnNumber() <= columnEnds )
|
|
{
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
columnEnds = textCursor().columnNumber();;
|
|
}
|
|
else
|
|
{
|
|
event->ignore();
|
|
}
|
|
break;
|
|
}
|
|
case Qt::Key_Up:
|
|
case Qt::Key_PageUp:
|
|
case Qt::Key_Down:
|
|
case Qt::Key_PageDown:
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
rowEnds = textCursor().blockNumber();
|
|
break;
|
|
default:
|
|
event->ignore();
|
|
break;
|
|
}
|
|
}
|
|
else if( selectionMode == selectionMode_line )
|
|
{
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
QTextCursor c( textCursor() );
|
|
rowEnds = c.blockNumber();
|
|
}
|
|
repaint();
|
|
}
|
|
else
|
|
{
|
|
event->ignore();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
bool HBQPlainTextEdit::hbKeyPressSelection( QKeyEvent * event )
|
|
{
|
|
bool ctrl = event->modifiers() & Qt::ControlModifier;
|
|
bool shift = event->modifiers() & Qt::ShiftModifier;
|
|
if( ctrl && shift )
|
|
return false;
|
|
|
|
int k = event->key();
|
|
|
|
if( ctrl && event->text().isEmpty() )
|
|
{
|
|
#if 0
|
|
event->ignore();
|
|
return true;
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
if( ctrl && ( k == Qt::Key_C || k == Qt::Key_V || k == Qt::Key_X ||
|
|
k == Qt::Key_A || k == Qt::Key_Z || k == Qt::Key_Y ) )
|
|
{
|
|
event->ignore();
|
|
return true;
|
|
}
|
|
|
|
if( isSelectionByApplication )
|
|
{
|
|
return hbKeyPressSelectionByApplication( event );
|
|
}
|
|
|
|
bool bClear = false;
|
|
|
|
if( shift && isNavableKey( k ) )
|
|
{
|
|
if( selectionMode == selectionMode_line )
|
|
{
|
|
selectionMode = selectionMode_stream;
|
|
selectionState = 0;
|
|
}
|
|
|
|
if( selectionState == 0 )
|
|
{
|
|
hbClearSelection();
|
|
}
|
|
|
|
isShiftPressed = true;
|
|
event->accept();
|
|
QTextCursor c( textCursor() );
|
|
c.clearSelection();
|
|
setTextCursor( c );
|
|
|
|
if( columnBegins == -1 )
|
|
{
|
|
if( selectionMode == selectionMode_column )
|
|
setCursorWidth( 0 );
|
|
|
|
selectionState = 2;
|
|
rowBegins = c.blockNumber();
|
|
columnBegins = c.columnNumber();
|
|
rowEnds = rowBegins;
|
|
columnEnds = columnBegins;
|
|
emit selectionChanged();
|
|
repaint();
|
|
}
|
|
|
|
QKeyEvent * ev = new QKeyEvent( event->type(), event->key(), Qt::NoModifier, event->text() );
|
|
keyPressEvent( ev );
|
|
return true;
|
|
}
|
|
|
|
if( isShiftPressed && isNavableKey( k ) )
|
|
{
|
|
isShiftPressed = false;
|
|
|
|
if( selectionMode == selectionMode_stream )
|
|
{
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
|
|
rowEnds = textCursor().blockNumber();
|
|
columnEnds = textCursor().columnNumber();
|
|
}
|
|
else if( selectionMode == selectionMode_column )
|
|
{
|
|
switch( k )
|
|
{
|
|
case Qt::Key_Right:
|
|
{
|
|
QTextCursor c( textCursor() );
|
|
c.movePosition( QTextCursor::EndOfLine );
|
|
if( c.columnNumber() <= columnEnds ){
|
|
setTextCursor( c );
|
|
ensureCursorVisible();
|
|
}
|
|
else
|
|
{
|
|
#if 0 /* Tobe Matured */
|
|
int v = horizontalScrollBar()->value();
|
|
int m = horizontalScrollBar()->maximum();
|
|
int w = fontMetrics().averageCharWidth();
|
|
if( ( ( columnEnds + 1 ) * w ) > m ){
|
|
if( v == m )
|
|
horizontalScrollBar()->setMaximum( m + w );
|
|
}
|
|
horizontalScrollBar()->setValue( v + w );
|
|
#endif
|
|
}
|
|
event->ignore();
|
|
columnEnds++;
|
|
break;
|
|
}
|
|
case Qt::Key_Left:
|
|
{
|
|
QTextCursor c( textCursor() );
|
|
int col = c.columnNumber();
|
|
if( col < columnEnds - 1 ){
|
|
c.movePosition( QTextCursor::Left );
|
|
columnEnds--;
|
|
}
|
|
else if( columnEnds - 1 >= 0 ){
|
|
columnEnds--;
|
|
}
|
|
event->ignore();
|
|
break;
|
|
}
|
|
case Qt::Key_Home:
|
|
{
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
columnEnds = textCursor().columnNumber();
|
|
break;
|
|
}
|
|
case Qt::Key_End:
|
|
{
|
|
QTextCursor c( textCursor() );
|
|
c.movePosition( QTextCursor::EndOfLine, QTextCursor::MoveAnchor );
|
|
if( c.columnNumber() <= columnEnds ){
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
columnEnds = textCursor().columnNumber();;
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
break;
|
|
}
|
|
case Qt::Key_Up:
|
|
case Qt::Key_PageUp:
|
|
case Qt::Key_Down:
|
|
case Qt::Key_PageDown:
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
rowEnds = textCursor().blockNumber();
|
|
break;
|
|
default:
|
|
event->ignore();
|
|
break;
|
|
}
|
|
}
|
|
emit selectionChanged();
|
|
repaint();
|
|
return true;
|
|
}
|
|
else if( ! ctrl && k >= ' ' && k < 127 && columnBegins >= 0 && selectionMode == selectionMode_column )
|
|
{
|
|
if( ( columnBegins == columnEnds && selectionState > 0 ) || isCursorInSelection() )
|
|
{
|
|
if( block )
|
|
{
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, 21013 );
|
|
PHB_ITEM p2 = hb_itemNew( NULL );
|
|
hb_arrayNew( p2, 7 );
|
|
hb_arraySetNI( p2, 1, rowBegins );
|
|
hb_arraySetNI( p2, 2, columnBegins );
|
|
hb_arraySetNI( p2, 3, rowEnds );
|
|
hb_arraySetNI( p2, 4, columnEnds );
|
|
hb_arraySetNI( p2, 5, selectionMode );
|
|
hb_arraySetNI( p2, 6, selectionState );
|
|
hb_arraySetPtr( p2, 7, event );
|
|
hb_vmEvalBlockV( block, 2, p1, p2 );
|
|
hb_itemRelease( p1 );
|
|
hb_itemRelease( p2 );
|
|
|
|
if( columnBegins == columnEnds ){
|
|
columnBegins++;
|
|
columnEnds++;
|
|
}
|
|
repaint();
|
|
event->accept();
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
bClear = true;
|
|
}
|
|
else if( ! ctrl && ( k == Qt::Key_Backspace || k == Qt::Key_Delete ) && columnBegins >= 0 && selectionState > 0 && selectionMode == selectionMode_column )
|
|
{
|
|
hbCut( k );
|
|
if( k == Qt::Key_Backspace ){
|
|
columnBegins--;
|
|
columnEnds--;
|
|
}
|
|
else {
|
|
columnEnds = columnBegins;
|
|
}
|
|
repaint();
|
|
event->accept();
|
|
return true;
|
|
}
|
|
else if( ! ctrl && k == Qt::Key_Delete && columnBegins >= 0 && selectionState > 0 && ( selectionMode == selectionMode_stream || selectionMode == selectionMode_line ) )
|
|
{
|
|
hbCut( k );
|
|
repaint();
|
|
selectionState = 0;
|
|
event->accept();
|
|
return true;
|
|
}
|
|
else if( isNavableKey( k ) || ( k >= ' ' && k < 127 ) )
|
|
{
|
|
bClear = true;
|
|
}
|
|
|
|
if( bClear )
|
|
{
|
|
if( isSelectionPersistent )
|
|
{
|
|
if( selectionState > 0 )
|
|
{
|
|
emit selectionChanged();
|
|
setCursorWidth( 1 );
|
|
selectionState = 0;
|
|
if( columnEnds == columnBegins ){
|
|
hbClearSelection();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( selectionState > 0 )
|
|
{
|
|
emit selectionChanged();
|
|
setCursorWidth( 1 );
|
|
selectionState = 0;
|
|
hbClearSelection();
|
|
repaint();
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
|
|
#if 0
|
|
else if( selectionMode == selectionMode_line )
|
|
{
|
|
if( isLineSelectionON && isNavableKey( k ) )
|
|
{
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
QTextCursor c( textCursor() );
|
|
rowEnds = c.blockNumber();
|
|
repaint();
|
|
return true;
|
|
}
|
|
else if( ! isSelectionPersistent )
|
|
{
|
|
if( selectionState > 0 )
|
|
{
|
|
emit selectionChanged();
|
|
setCursorWidth( 1 );
|
|
selectionState = 0;
|
|
hbClearSelection();
|
|
repaint();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::keyPressEvent( QKeyEvent * event )
|
|
{
|
|
//HB_TRACE( HB_TR_ALWAYS, ( "keyPressEvent %i 000", event->key() ) );
|
|
if( hbKeyPressSelection( event ) )
|
|
{
|
|
QApplication::processEvents();
|
|
return;
|
|
}
|
|
//HB_TRACE( HB_TR_ALWAYS, ( "keyPressEvent %i", event->key() ) );
|
|
if( c && c->popup()->isVisible() )
|
|
{
|
|
// The following keys are forwarded by the completer to the widget
|
|
switch( event->key() )
|
|
{
|
|
case Qt::Key_Enter :
|
|
case Qt::Key_Return :
|
|
case Qt::Key_Escape :
|
|
case Qt::Key_Tab :
|
|
case Qt::Key_Backtab :
|
|
event->ignore();
|
|
return; // let the completer do default behavior
|
|
case Qt::Key_Space:
|
|
if( block ){
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, 21001 );
|
|
hb_vmEvalBlockV( block, 1, p1 );
|
|
hb_itemRelease( p1 );
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
QPlainTextEdit::keyPressEvent( event );
|
|
|
|
if( ! c )
|
|
return;
|
|
|
|
if( ( event->modifiers() & ( Qt::ControlModifier | Qt::AltModifier ) ) )
|
|
{
|
|
c->popup()->hide();
|
|
return;
|
|
}
|
|
|
|
const bool ctrlOrShift = event->modifiers() & ( Qt::ControlModifier | Qt::ShiftModifier );
|
|
if( ( ctrlOrShift && event->text().isEmpty() ) )
|
|
return;
|
|
|
|
static QString eow( " ~!@#$%^&*()+{}|:\"<>?,./;'[]\\-=" ); /* end of word */
|
|
bool hasModifier = ( event->modifiers() != Qt::NoModifier ) && !ctrlOrShift;
|
|
QString completionPrefix = hbTextUnderCursor();
|
|
|
|
if( ( hasModifier ||
|
|
event->text().isEmpty() ||
|
|
completionPrefix.length() < 3 ||
|
|
eow.contains( event->text().right( 1 ) ) ) )
|
|
{
|
|
c->popup()->hide();
|
|
return;
|
|
}
|
|
|
|
if( completionPrefix != c->completionPrefix() )
|
|
{
|
|
c->setCompletionPrefix( completionPrefix );
|
|
c->popup()->setCurrentIndex( c->completionModel()->index( 0, 0 ) );
|
|
}
|
|
QRect cr = cursorRect();
|
|
|
|
cr.setWidth( c->popup()->sizeHintForColumn( 0 ) + c->popup()->verticalScrollBar()->sizeHint().width() );
|
|
cr.setTop( cr.top() + 25 );
|
|
cr.setBottom( cr.bottom() + 25 );
|
|
|
|
c->complete( cr ); // popup it up!
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
QString HBQPlainTextEdit::hbTextUnderCursor()
|
|
{
|
|
QTextCursor tc = textCursor();
|
|
tc.select( QTextCursor::WordUnderCursor );
|
|
return tc.selectedText();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::resizeEvent( QResizeEvent *e )
|
|
{
|
|
setContentsMargins( 0,0,0,0 );
|
|
viewport()->setContentsMargins( 0,0,0,0 );
|
|
|
|
QPlainTextEdit::resizeEvent( e );
|
|
|
|
QRect cr = contentsRect();
|
|
lineNumberArea->setGeometry( QRect( cr.left(), cr.top() + horzRulerHeight, hbLineNumberAreaWidth(), cr.height() ) );
|
|
|
|
horzRuler->setGeometry( QRect( cr.left(), cr.top(), cr.width(), horzRulerHeight ) );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::focusInEvent( QFocusEvent * event )
|
|
{
|
|
if( c )
|
|
c->setWidget( this );
|
|
|
|
QPlainTextEdit::focusInEvent( event );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::paintEvent( QPaintEvent * event )
|
|
{
|
|
QPainter painter( viewport() );
|
|
|
|
int curBlock = textCursor().blockNumber();
|
|
|
|
QTextBlock tblock = firstVisibleBlock();
|
|
int blockNumber = tblock.blockNumber();
|
|
int height = ( int ) blockBoundingRect( tblock ).height();
|
|
int top = ( int ) blockBoundingGeometry( tblock ).translated( contentOffset() ).top();
|
|
int bottom = top + height;
|
|
|
|
while( tblock.isValid() && top <= event->rect().bottom() )
|
|
{
|
|
if( tblock.isVisible() && bottom >= event->rect().top() )
|
|
{
|
|
int index = bookMarksGoto.indexOf( blockNumber + 1 );
|
|
if( index != -1 )
|
|
{
|
|
QRect r( 0, top, viewport()->width(), height );
|
|
painter.fillRect( r, brushForBookmark( index ) );
|
|
}
|
|
else if( curBlock == blockNumber && m_currentLineColor.isValid() )
|
|
{
|
|
if( highlightCurLine == true )
|
|
{
|
|
QRect r = HBQPlainTextEdit::cursorRect();
|
|
r.setX( 0 );
|
|
r.setWidth( viewport()->width() );
|
|
painter.fillRect( r, QBrush( m_currentLineColor ) );
|
|
}
|
|
}
|
|
}
|
|
tblock = tblock.next();
|
|
top = bottom;
|
|
bottom = top + height;
|
|
++blockNumber;
|
|
}
|
|
this->hbPaintSelection( event );
|
|
this->hbPaintHighlight( event );
|
|
|
|
#if 0
|
|
{
|
|
QPainter p( viewport() );
|
|
caretState = caretState == 0 ? 1 : 0;
|
|
QRect r( cursorRect() );
|
|
r.setX( r.x() + 100 );
|
|
r.setWidth( 1 );
|
|
p.fillRect( r, QBrush( QColor( caretState == 1 ? Qt::red : Qt::white ) ) );
|
|
}
|
|
#endif
|
|
|
|
painter.end();
|
|
QPlainTextEdit::paintEvent( event );
|
|
|
|
#if 0
|
|
QPainter * painter = new QPainter( viewport() );
|
|
|
|
int curBlock = textCursor().blockNumber();
|
|
|
|
QTextBlock tblock = firstVisibleBlock();
|
|
int blockNumber = tblock.blockNumber();
|
|
int height = ( int ) blockBoundingRect( tblock ).height();
|
|
int top = ( int ) blockBoundingGeometry( tblock ).translated( contentOffset() ).top();
|
|
int bottom = top + height;
|
|
|
|
this->hbPaintSelection( event );
|
|
|
|
while( tblock.isValid() && top <= event->rect().bottom() )
|
|
{
|
|
if( tblock.isVisible() && bottom >= event->rect().top() )
|
|
{
|
|
int index = bookMarksGoto.indexOf( blockNumber + 1 );
|
|
if( index != -1 )
|
|
{
|
|
QRect r( 0, top, viewport()->width(), height );
|
|
painter->fillRect( r, brushForBookmark( index ) );
|
|
}
|
|
else if( curBlock == blockNumber && m_currentLineColor.isValid() )
|
|
{
|
|
if( highlightCurLine == true )
|
|
{
|
|
QRect r = HBQPlainTextEdit::cursorRect();
|
|
r.setX( 0 );
|
|
r.setWidth( viewport()->width() );
|
|
painter->fillRect( r, QBrush( m_currentLineColor ) );
|
|
}
|
|
}
|
|
}
|
|
tblock = tblock.next();
|
|
top = bottom;
|
|
bottom = top + height;
|
|
++blockNumber;
|
|
}
|
|
|
|
#if 0 /* A day wasted - I could not find how I can execute paiting from within prg code */
|
|
if( block )
|
|
{
|
|
PHB_ITEM p1 = hb_itemPutNI( NULL, QEvent::Paint );
|
|
PHB_ITEM p2 = hb_itemPutPtr( NULL, painter );
|
|
hb_vmEvalBlockV( block, 2, p1, p2 );
|
|
hb_itemRelease( p1 );
|
|
hb_itemRelease( p2 );
|
|
}
|
|
#endif
|
|
|
|
painter->end();
|
|
delete ( ( QPainter * ) painter );
|
|
QPlainTextEdit::paintEvent( event );
|
|
#endif
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::horzRulerPaintEvent( QPaintEvent *event )
|
|
{
|
|
int fontWidth = fontMetrics().averageCharWidth();
|
|
QRect cr = event->rect();
|
|
QPainter painter( horzRuler );
|
|
|
|
painter.fillRect( cr, m_horzRulerBkColor );
|
|
painter.setPen( Qt::gray );
|
|
painter.drawLine( cr.left(), cr.bottom(), cr.width(), cr.bottom() );
|
|
painter.setPen( Qt::black );
|
|
|
|
int left = cr.left() + ( fontWidth / 2 ) + ( lineNumberArea->isVisible() ? lineNumberArea->width() : 0 );
|
|
|
|
QRect rc( cursorRect( textCursor() ) );
|
|
QTextCursor cursor( cursorForPosition( QPoint( 1, rc.top() + 1 ) ) );
|
|
|
|
int i;
|
|
for( i = hbFirstVisibleColumn(); left < cr.width(); i++ )
|
|
{
|
|
if( i % 10 == 0 )
|
|
{
|
|
painter.drawLine( left, cr.bottom()-3, left, cr.bottom()-5 );
|
|
QString number = QString::number( i );
|
|
painter.drawText( left - fontWidth, cr.top()-2, fontWidth * 2, 17, Qt::AlignCenter, number );
|
|
}
|
|
else if( i % 5 == 0 )
|
|
{
|
|
painter.drawLine( left, cr.bottom()-3, left, cr.bottom()-5 );
|
|
}
|
|
else
|
|
{
|
|
painter.drawLine( left, cr.bottom()-3, left, cr.bottom()-4 );
|
|
}
|
|
if( i == textCursor().columnNumber() )
|
|
{
|
|
painter.fillRect( QRect( left, cr.top() + 2, fontWidth, 11 ), QColor( 100,100,100 ) );
|
|
}
|
|
left += fontWidth;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::lineNumberAreaPaintEvent( QPaintEvent *event )
|
|
{
|
|
QPainter painter( lineNumberArea );
|
|
painter.fillRect( event->rect(), m_lineAreaBkColor );
|
|
|
|
QTextBlock block = firstVisibleBlock();
|
|
int blockNumber = block.blockNumber();
|
|
int top = ( int ) blockBoundingGeometry( block ).translated( contentOffset() ).top();
|
|
int bottom = top +( int ) blockBoundingRect( block ).height();
|
|
int off = fontMetrics().height() / 4;
|
|
|
|
while( block.isValid() && top <= event->rect().bottom() )
|
|
{
|
|
if( block.isVisible() && bottom >= event->rect().top() )
|
|
{
|
|
QString number = QString::number( blockNumber + 1 );
|
|
painter.setPen( ( blockNumber + 1 ) % 10 == 0 ? Qt::red : Qt::black );
|
|
painter.drawText( 0, top, lineNumberArea->width()-2, fontMetrics().height(), Qt::AlignRight, number );
|
|
|
|
int index = bookMarksGoto.indexOf( number.toInt() );
|
|
if( index != -1 )
|
|
{
|
|
painter.setBrush( brushForBookmark( index ) );
|
|
painter.drawRect( 5, top + off, off * 2, off * 2 );
|
|
}
|
|
}
|
|
block = block.next();
|
|
top = bottom;
|
|
bottom = top +( int ) blockBoundingRect( block ).height();
|
|
++blockNumber;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbPaintHighlight( QPaintEvent * event )
|
|
{
|
|
HB_SYMBOL_UNUSED( event );
|
|
|
|
if( highlight.top() > -1 )
|
|
{
|
|
int fontHeight = fontMetrics().height();
|
|
int t = firstVisibleBlock().blockNumber();
|
|
int b = t + ( viewport()->height() / fontHeight ) + 1;
|
|
int rb = highlight.top();
|
|
int re = highlight.bottom();
|
|
|
|
if( re >= t && rb < b )
|
|
{
|
|
QPainter p( viewport() );
|
|
int top = ( ( rb <= t ) ? 0 : ( ( rb - t ) * fontHeight ) );
|
|
int btm = ( ( re - t + 1 ) * fontHeight ) - top;
|
|
|
|
btm = btm > viewport()->height() ? viewport()->height() : btm;
|
|
|
|
QRect r( 0, top, viewport()->width(), btm );
|
|
p.fillRect( r, QBrush( QColor( 255,255,0 ) ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbPaintSelection( QPaintEvent * event )
|
|
{
|
|
HB_SYMBOL_UNUSED( event );
|
|
|
|
if( rowBegins >= 0 && rowEnds >= 0 )
|
|
{
|
|
int cb = columnBegins <= columnEnds ? columnBegins : columnEnds;
|
|
int ce = columnBegins <= columnEnds ? columnEnds : columnBegins;
|
|
int rb = rowBegins <= rowEnds ? rowBegins : rowEnds;
|
|
int re = rowBegins <= rowEnds ? rowEnds : rowBegins;
|
|
|
|
int t = firstVisibleBlock().blockNumber();
|
|
int c = hbFirstVisibleColumn();
|
|
int fontHeight = fontMetrics().height();
|
|
int b = t + ( viewport()->height() / fontHeight ) + 1;
|
|
|
|
re = re > b ? b : re;
|
|
|
|
if( re >= t && rb < b )
|
|
{
|
|
QPainter p( viewport() );
|
|
|
|
int marginX = ( c > 0 ? 0 : contentsRect().left() ) + 2 ;
|
|
int fontWidth = fontMetrics().averageCharWidth();
|
|
|
|
int top = ( ( rb <= t ) ? 0 : ( ( rb - t ) * fontHeight ) );
|
|
int btm = ( ( re - t + 1 ) * fontHeight ) - top;
|
|
btm = btm > viewport()->height() ? viewport()->height() : btm;
|
|
|
|
if( selectionMode == selectionMode_column )
|
|
{
|
|
int x = ( ( cb - c ) * fontWidth ) + marginX;
|
|
int w = ( cb == ce ? 1 : ( ( ce - cb ) * fontWidth ) );
|
|
|
|
QRect r( x, top, w, btm );
|
|
p.fillRect( r, QBrush( m_selectionColor ) );
|
|
}
|
|
else if( selectionMode == selectionMode_stream )
|
|
{
|
|
int i;
|
|
int width = viewport()->width();
|
|
QRect r;
|
|
|
|
for( i = ( rb >= t ? rb : t ); i <= re; i++ )
|
|
{
|
|
if( rowBegins > rowEnds )
|
|
{
|
|
if( i == rowEnds )
|
|
{
|
|
if( rb == re )
|
|
{
|
|
int x = ( ( cb - c ) * fontWidth ) + marginX;
|
|
int w = ( ce - cb ) * fontWidth;
|
|
r = QRect( x, top, w, fontHeight );
|
|
}
|
|
else
|
|
{
|
|
int x = ( ( columnEnds - c ) * fontWidth ) + marginX;
|
|
r = QRect( x, top, width + abs( x ), fontHeight );
|
|
}
|
|
}
|
|
else if( i == rowBegins )
|
|
{
|
|
int x = ( ( columnBegins - c ) * fontWidth ) + marginX;
|
|
r = QRect( 0, top, x, fontHeight );
|
|
}
|
|
else
|
|
{
|
|
r = QRect( 0, top, width, fontHeight );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( i == rowBegins )
|
|
{
|
|
if( rb == re )
|
|
{
|
|
int x = ( ( cb - c ) * fontWidth ) + marginX;
|
|
int w = ( ce - cb ) * fontWidth;
|
|
r = QRect( x, top, w, fontHeight );
|
|
}
|
|
else
|
|
{
|
|
int x = ( ( columnBegins - c ) * fontWidth ) + marginX;
|
|
r = QRect( x, top, width + abs( x ), fontHeight );
|
|
}
|
|
}
|
|
else if( i == rowEnds )
|
|
{
|
|
int x = ( ( columnEnds - c ) * fontWidth ) + marginX;
|
|
r = QRect( 0, top, x, fontHeight );
|
|
}
|
|
else
|
|
{
|
|
r = QRect( 0, top, width, fontHeight );
|
|
}
|
|
}
|
|
p.fillRect( r, QBrush( m_selectionColor ) );
|
|
top += fontHeight;
|
|
}
|
|
}
|
|
else if( selectionMode == selectionMode_line )
|
|
{
|
|
QRect r( 0, top, viewport()->width(), btm );
|
|
p.fillRect( r, QBrush( m_selectionColor ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
QBrush HBQPlainTextEdit::brushForBookmark( int index )
|
|
{
|
|
QBrush br;
|
|
|
|
if( index == 0 )
|
|
br = QBrush( QColor( 255, 255, 127 ) );
|
|
else if( index == 1 )
|
|
br = QBrush( QColor( 175, 175, 255 ) );
|
|
else if( index == 2 )
|
|
br = QBrush( QColor( 255, 175, 175 ) );
|
|
else if( index == 3 )
|
|
br = QBrush( QColor( 175, 255, 175 ) );
|
|
else if( index == 4 )
|
|
br = QBrush( QColor( 255, 190, 125 ) );
|
|
else if( index == 5 )
|
|
br = QBrush( QColor( 175, 255, 255 ) );
|
|
else
|
|
br = QBrush( m_currentLineColor );
|
|
|
|
return br;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbBookmarks( int block )
|
|
{
|
|
int found = bookMark.indexOf( block );
|
|
if( found == -1 )
|
|
{
|
|
bookMark.push_back( block );
|
|
qSort( bookMark );
|
|
}
|
|
else
|
|
{
|
|
bookMark.remove( found );
|
|
}
|
|
|
|
found = -1;
|
|
int i = 0;
|
|
for( i = 0; i < bookMarksGoto.size(); i++ )
|
|
{
|
|
if( bookMarksGoto[ i ] == block )
|
|
{
|
|
bookMarksGoto.removeAt( i );
|
|
found = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( found == -1 )
|
|
{
|
|
bookMarksGoto.append( block );
|
|
}
|
|
|
|
hbUpdateLineNumberAreaWidth( 0 );
|
|
lineNumberArea->repaint();
|
|
update();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbGotoBookmark( int block )
|
|
{
|
|
if( bookMarksGoto.size() > 0 )
|
|
{
|
|
int i;
|
|
for( i = 0; i < bookMarksGoto.size(); i++ )
|
|
{
|
|
if( bookMarksGoto[ i ] == block )
|
|
{
|
|
QTextCursor cursor( document()->findBlockByNumber( block - 1 ) );
|
|
setTextCursor( cursor );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbNextBookmark( int block )
|
|
{
|
|
if( bookMark.count() > 0 )
|
|
{
|
|
QVector<int>::iterator i = qUpperBound( bookMark.begin(), bookMark.end(), block );
|
|
if( i != bookMark.end() )
|
|
{
|
|
QTextCursor cursor( document()->findBlockByNumber( *i - 1 ) );
|
|
setTextCursor( cursor );
|
|
}
|
|
else
|
|
{
|
|
QTextCursor cursor( document()->findBlockByNumber( *bookMark.begin() - 1 ) );
|
|
setTextCursor( cursor );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbPrevBookmark( int block )
|
|
{
|
|
if( bookMark.count() > 0 )
|
|
{
|
|
QVector<int>::iterator i = qUpperBound( bookMark.begin(), bookMark.end(), block );
|
|
i -= 2;
|
|
if( i >= bookMark.begin() )
|
|
{
|
|
QTextCursor cursor( document()->findBlockByNumber( *i - 1 ) );
|
|
setTextCursor( cursor );
|
|
}
|
|
else
|
|
{
|
|
QVector<int>::iterator it = bookMark.end();
|
|
--it;
|
|
QTextCursor cursor( document()->findBlockByNumber( *it - 1 ) );
|
|
setTextCursor( cursor );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbNumberBlockVisible( bool b )
|
|
{
|
|
numberBlock = b;
|
|
if( b )
|
|
{
|
|
lineNumberArea->show();
|
|
hbUpdateLineNumberAreaWidth( hbLineNumberAreaWidth() );
|
|
}
|
|
else
|
|
{
|
|
lineNumberArea->hide();
|
|
hbUpdateLineNumberAreaWidth( 0 );
|
|
}
|
|
update();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
bool HBQPlainTextEdit::hbNumberBlockVisible()
|
|
{
|
|
return numberBlock;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
int HBQPlainTextEdit::hbLineNumberAreaWidth()
|
|
{
|
|
int digits = 1;
|
|
int max = qMax( 1, blockCount() );
|
|
while( max >= 10 )
|
|
{
|
|
max /= 10;
|
|
++digits;
|
|
}
|
|
int width = fontMetrics().width( QLatin1Char( '9' ) );
|
|
int iM = fontMetrics().height() / 2;
|
|
int iMark = bookMarksGoto.size() > 0 ? ( 5 + iM + 2 ) : 0;
|
|
int space = iMark + ( width * digits ) + 2;
|
|
|
|
return space;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbUpdateHorzRulerHeight( int height )
|
|
{
|
|
horzRulerHeight = height;
|
|
setViewportMargins( hbLineNumberAreaWidth(), horzRulerHeight, 0, 0 );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbUpdateLineNumberAreaWidth( int )
|
|
{
|
|
if( numberBlock )
|
|
{
|
|
setViewportMargins( hbLineNumberAreaWidth(), horzRulerHeight, 0, 0 );
|
|
}
|
|
else
|
|
{
|
|
setViewportMargins( 0, horzRulerHeight, 0, 0 );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbUpdateHorzRuler( const QRect & rect, int dy )
|
|
{
|
|
HB_SYMBOL_UNUSED( rect );
|
|
|
|
setTabStopWidth( spaces * fontMetrics().averageCharWidth() );
|
|
|
|
if( dy == 0 )
|
|
horzRuler->update();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbUpdateLineNumberArea( const QRect &rect, int dy )
|
|
{
|
|
if( dy )
|
|
lineNumberArea->scroll( 0, dy );
|
|
else
|
|
lineNumberArea->update( 0, rect.y(), lineNumberArea->width(), rect.height() );
|
|
|
|
if( rect.contains( viewport()->rect() ) )
|
|
{
|
|
hbUpdateLineNumberAreaWidth( 0 );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbSetSpaces( int newSpaces )
|
|
{
|
|
spaces = newSpaces;
|
|
spacesTab = "";
|
|
|
|
if( spaces > 0 )
|
|
{
|
|
for( int i = 0; i < spaces; ++i )
|
|
spacesTab += " ";
|
|
}
|
|
else
|
|
{
|
|
if( spaces == -101 )
|
|
spacesTab = "\t";
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
int HBQPlainTextEdit::hbGetIndex( const QTextCursor &crQTextCursor )
|
|
{
|
|
QTextBlock b;
|
|
int column = 1;
|
|
b = crQTextCursor.block();
|
|
column = crQTextCursor.position() - b.position();
|
|
return column;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
int HBQPlainTextEdit::hbGetLine( const QTextCursor &crQTextCursor )
|
|
{
|
|
QTextBlock b,cb;
|
|
int line = 1;
|
|
cb = crQTextCursor.block();
|
|
for( b = document()->begin();b!=document()->end();b = b.next() )
|
|
{
|
|
if( b==cb )
|
|
return line;
|
|
line++;
|
|
}
|
|
return line;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbSlotCursorPositionChanged()
|
|
{
|
|
if( m_currentLineColor.isValid() )
|
|
viewport()->update();
|
|
|
|
if( styleHightlighter != "none" )
|
|
hbBraceHighlight();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbSetStyleHightlighter( const QString &style )
|
|
{
|
|
styleHightlighter = style;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbShowHighlighter( const QString &style, bool b )
|
|
{
|
|
if( b )
|
|
{
|
|
if( styleHightlighter != "none" )
|
|
{
|
|
delete highlighter;
|
|
highlighter = 0;
|
|
}
|
|
highlighter = new HBQSyntaxHighlighter( document() );
|
|
}
|
|
else
|
|
{
|
|
delete highlighter;
|
|
highlighter = 0;
|
|
}
|
|
styleHightlighter = style;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbEscapeQuotes()
|
|
{
|
|
QTextCursor cursor( textCursor() );
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
QString txt = selTxt.replace( QString( "'" ), QString( "\\\'" ) );
|
|
insertPlainText( txt );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbEscapeDQuotes()
|
|
{
|
|
QTextCursor cursor( textCursor() );
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
QString txt = selTxt.replace( QString( "\"" ), QString( "\\\"" ) );
|
|
insertPlainText( txt );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbUnescapeQuotes()
|
|
{
|
|
QTextCursor cursor( textCursor() );
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
QString txt = selTxt.replace( QString( "\\\'" ), QString( "'" ) );
|
|
insertPlainText( txt );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbUnescapeDQuotes()
|
|
{
|
|
QTextCursor cursor( textCursor() );
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
QString txt = selTxt.replace( QString( "\\\"" ), QString( "\"" ) );
|
|
insertPlainText( txt );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbCaseUpper()
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
int b = cursor.selectionStart();
|
|
int e = cursor.selectionEnd();
|
|
cursor.beginEditBlock();
|
|
|
|
insertPlainText( selTxt.toUpper() );
|
|
|
|
cursor.setPosition( b );
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, e-b );
|
|
cursor.endEditBlock();
|
|
setTextCursor( cursor );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbCaseLower()
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
int b = cursor.selectionStart();
|
|
int e = cursor.selectionEnd();
|
|
cursor.beginEditBlock();
|
|
|
|
insertPlainText( selTxt.toLower() );
|
|
|
|
cursor.setPosition( b );
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, e-b );
|
|
cursor.endEditBlock();
|
|
setTextCursor( cursor );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbConvertQuotes()
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
int b = cursor.selectionStart();
|
|
int e = cursor.selectionEnd();
|
|
cursor.beginEditBlock();
|
|
|
|
insertPlainText( selTxt.replace( QString( "\"" ), QString( "\'" ) ) );
|
|
|
|
cursor.setPosition( b );
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, e-b );
|
|
cursor.endEditBlock();
|
|
setTextCursor( cursor );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbConvertDQuotes()
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
int b = cursor.selectionStart();
|
|
int e = cursor.selectionEnd();
|
|
cursor.beginEditBlock();
|
|
|
|
insertPlainText( selTxt.replace( QString( "\'" ), QString( "\"" ) ) );
|
|
|
|
cursor.setPosition( b );
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, e-b );
|
|
cursor.endEditBlock();
|
|
setTextCursor( cursor );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbReplaceSelection( const QString & txt )
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
int b = cursor.selectionStart();
|
|
cursor.beginEditBlock();
|
|
|
|
insertPlainText( txt );
|
|
|
|
cursor.setPosition( b );
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, txt.length() );
|
|
cursor.endEditBlock();
|
|
setTextCursor( cursor );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbStreamComment()
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return;
|
|
|
|
int b = cursor.selectionStart();
|
|
int e = cursor.selectionEnd();
|
|
cursor.beginEditBlock();
|
|
|
|
insertPlainText( "/*" + selTxt + "*/" );
|
|
|
|
cursor.setPosition( b );
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor, e-b+4 );
|
|
cursor.endEditBlock();
|
|
setTextCursor( cursor );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
QString HBQPlainTextEdit::hbGetSelectedText()
|
|
{
|
|
QTextCursor cursor( textCursor() );
|
|
QString selTxt( cursor.selectedText() );
|
|
if( selTxt.isEmpty() )
|
|
return "";
|
|
|
|
QString txt = selTxt.replace( 0x2029, QString( "\n" ) );
|
|
return txt;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbInsertTab( int mode )
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QTextCursor c( cursor );
|
|
|
|
c.setPosition( cursor.position() );
|
|
setTextCursor( c );
|
|
|
|
if( mode == 0 )
|
|
{
|
|
insertPlainText( spacesTab );
|
|
}
|
|
else
|
|
{
|
|
int icol = c.columnNumber();
|
|
int ioff = qMin( icol, spaces );
|
|
c.setPosition( c.position() - ioff );
|
|
}
|
|
setTextCursor( c );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbMoveLine( int iDirection )
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QTextCursor c = cursor;
|
|
|
|
cursor.beginEditBlock();
|
|
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor );
|
|
QString textCurrentLine = cursor.selectedText();
|
|
|
|
if( iDirection == -1 && cursor.blockNumber() > 0 )
|
|
{
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
cursor.movePosition( QTextCursor::Up );
|
|
cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor );
|
|
QString textPrevLine = cursor.selectedText();
|
|
setTextCursor( cursor );
|
|
insertPlainText( textCurrentLine );
|
|
cursor.movePosition( QTextCursor::Down );
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor );
|
|
setTextCursor( cursor );
|
|
insertPlainText( textPrevLine );
|
|
c.movePosition( QTextCursor::Up );
|
|
}
|
|
else if( iDirection == 1 && cursor.blockNumber() < cursor.document()->blockCount() - 1 )
|
|
{
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
cursor.movePosition( QTextCursor::Down );
|
|
cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor );
|
|
QString textPrevLine = cursor.selectedText();
|
|
setTextCursor( cursor );
|
|
insertPlainText( textCurrentLine );
|
|
cursor.movePosition( QTextCursor::Up );
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor );
|
|
setTextCursor( cursor );
|
|
insertPlainText( textPrevLine );
|
|
c.movePosition( QTextCursor::Down );
|
|
}
|
|
cursor.endEditBlock();
|
|
setTextCursor( c );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbDeleteLine()
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QTextCursor c = cursor;
|
|
|
|
cursor.beginEditBlock();
|
|
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor );
|
|
cursor.movePosition( QTextCursor::Down, QTextCursor::KeepAnchor );
|
|
|
|
QString textUnderCursor = cursor.selectedText();
|
|
setTextCursor( cursor );
|
|
insertPlainText( "" );
|
|
cursor.endEditBlock();
|
|
|
|
setTextCursor( c );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbBlockIndent( int steps )
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
|
|
if( cursor.hasSelection() )
|
|
{
|
|
QTextCursor c = cursor;
|
|
QTextDocument * doc = c.document();
|
|
|
|
int bs = doc->findBlock( c.selectionStart() ).blockNumber();
|
|
int be = doc->findBlock( c.selectionEnd() ).blockNumber();
|
|
|
|
cursor.beginEditBlock();
|
|
|
|
cursor.movePosition( QTextCursor::Start );
|
|
cursor.movePosition( QTextCursor::NextBlock, QTextCursor::MoveAnchor, bs );
|
|
|
|
int s = abs( steps );
|
|
int i, j;
|
|
for( i = bs; i <= be; i++ )
|
|
{
|
|
setTextCursor( cursor );
|
|
for( j = 0; j < s; j++ )
|
|
{
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
|
|
if( steps < 0 )
|
|
{
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor );
|
|
QString textUnderCursor = cursor.selectedText();
|
|
if( textUnderCursor == " " )
|
|
{
|
|
setTextCursor( cursor );
|
|
insertPlainText( "" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
setTextCursor( cursor );
|
|
insertPlainText( " " );
|
|
}
|
|
}
|
|
cursor.movePosition( QTextCursor::NextBlock, QTextCursor::MoveAnchor, 1 );
|
|
}
|
|
cursor.endEditBlock();
|
|
|
|
setTextCursor( c );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbBlockComment()
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QTextCursor c = cursor;
|
|
QTextDocument * doc = c.document();
|
|
|
|
int bs = doc->findBlock( c.selectionStart() ).blockNumber();
|
|
int be = doc->findBlock( c.selectionEnd() ).blockNumber();
|
|
|
|
cursor.beginEditBlock();
|
|
|
|
cursor.movePosition( QTextCursor::Start );
|
|
cursor.movePosition( QTextCursor::NextBlock, QTextCursor::MoveAnchor, bs );
|
|
int i;
|
|
for( i = bs; i <= be; i++ )
|
|
{
|
|
setTextCursor( cursor );
|
|
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor );
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor );
|
|
QString textUnderCursor = cursor.selectedText();
|
|
if( textUnderCursor == "//" )
|
|
{
|
|
setTextCursor( cursor );
|
|
insertPlainText( "" );
|
|
}
|
|
else
|
|
{
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
insertPlainText( "//" );
|
|
}
|
|
cursor.movePosition( QTextCursor::NextBlock, QTextCursor::MoveAnchor, 1 );
|
|
}
|
|
cursor.endEditBlock();
|
|
setTextCursor( c );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbDuplicateLine()
|
|
{
|
|
QTextCursor cursor = textCursor();
|
|
QTextCursor c = cursor;
|
|
cursor.movePosition( QTextCursor::StartOfLine );
|
|
cursor.movePosition( QTextCursor::EndOfLine, QTextCursor::KeepAnchor );
|
|
QString textUnderCursor = cursor.selectedText();
|
|
cursor.movePosition( QTextCursor::EndOfLine );
|
|
setTextCursor( cursor );
|
|
insertPlainText( "\n" + textUnderCursor );
|
|
setTextCursor( c );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
void HBQPlainTextEdit::hbBraceHighlight()
|
|
{
|
|
QColor lineColor = QColor( Qt::yellow ).lighter( 160 );
|
|
|
|
QTextDocument *doc = document();
|
|
|
|
extraSelections.clear();
|
|
setExtraSelections( extraSelections );
|
|
selection.format.setBackground( lineColor );
|
|
|
|
QTextCursor cursor = textCursor();
|
|
|
|
cursor.movePosition( QTextCursor::NextCharacter, QTextCursor::KeepAnchor );
|
|
QString brace = cursor.selectedText();
|
|
|
|
if( ( brace != "{" ) && ( brace != "}" )
|
|
&& ( brace != "[" ) && ( brace != "]" )
|
|
&& ( brace != "(" ) && ( brace != ")" )
|
|
&& ( brace != "<" ) && ( brace != ">" ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
QString openBrace;
|
|
QString closeBrace;
|
|
|
|
if( ( brace == "{" ) || ( brace == "}" ) )
|
|
{
|
|
openBrace = "{";
|
|
closeBrace = "}";
|
|
}
|
|
if( ( brace == "[" ) || ( brace == "]" ) )
|
|
{
|
|
openBrace = "[";
|
|
closeBrace = "]";
|
|
}
|
|
if( ( brace == "(" ) || ( brace == ")" ) )
|
|
{
|
|
openBrace = "(";
|
|
closeBrace = ")";
|
|
}
|
|
if( ( brace == "<" ) || ( brace == ">" ) )
|
|
{
|
|
openBrace = "<";
|
|
closeBrace = ">";
|
|
}
|
|
|
|
QTextCursor cursor1;
|
|
QTextCursor cursor2;
|
|
QTextCursor matches;
|
|
|
|
if( brace == openBrace )
|
|
{
|
|
cursor1 = doc->find( closeBrace, cursor );
|
|
cursor2 = doc->find( openBrace, cursor );
|
|
if( cursor2.isNull() )
|
|
{
|
|
matches = cursor1;
|
|
}
|
|
else
|
|
{
|
|
while( cursor1.position() > cursor2.position() )
|
|
{
|
|
cursor1 = doc->find( closeBrace, cursor1 );
|
|
cursor2 = doc->find( openBrace, cursor2 );
|
|
if( cursor2.isNull() )
|
|
break;
|
|
}
|
|
matches = cursor1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( brace == closeBrace )
|
|
{
|
|
cursor1 = doc->find( openBrace, cursor, QTextDocument::FindBackward );
|
|
cursor2 = doc->find( closeBrace, cursor, QTextDocument::FindBackward );
|
|
if( cursor2.isNull() )
|
|
{
|
|
matches = cursor1;
|
|
}
|
|
else
|
|
{
|
|
while( cursor1.position() < cursor2.position() )
|
|
{
|
|
cursor1 = doc->find( openBrace, cursor1, QTextDocument::FindBackward );
|
|
cursor2 = doc->find( closeBrace, cursor2, QTextDocument::FindBackward );
|
|
if( cursor2.isNull() )
|
|
break;
|
|
}
|
|
matches = cursor1;
|
|
}
|
|
}
|
|
}
|
|
if( ! matches.isNull() )
|
|
{
|
|
if( m_matchBracesAll )
|
|
{
|
|
selection.cursor = cursor;
|
|
extraSelections.append( selection );
|
|
}
|
|
selection.cursor = cursor1;
|
|
extraSelections.append( selection );
|
|
setExtraSelections( extraSelections );
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
#endif
|