00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "kateviewhelpers.h"
00022
#include "kateviewhelpers.moc"
00023
00024
#include "kateview.h"
00025
#include "kateviewinternal.h"
00026
#include "katedocument.h"
00027
#include "katecodefoldinghelpers.h"
00028
#include "katerenderer.h"
00029
#include "kateattribute.h"
00030
#include "kateconfig.h"
00031
00032
#include <kglobalsettings.h>
00033
#include <klocale.h>
00034
00035
#include <qpainter.h>
00036
#include <qpopupmenu.h>
00037
#include <qcursor.h>
00038
#include <qstyle.h>
00039
#include <qtimer.h>
00040
00041
#include <math.h>
00042
00043
#include "kateview.h"
00044
#include "katefactory.h"
00045
00046
#include "../interfaces/katecmd.h"
00047
#include "../interfaces/document.h"
00048
00049
#include <klocale.h>
00050
00051
#include <qtimer.h>
00052
00053 KateCmdLine::KateCmdLine (KateView *view)
00054 :
KLineEdit (view)
00055 , m_view (view)
00056 , m_msgMode (false)
00057 {
00058 connect (
this, SIGNAL(returnPressed(
const QString &)),
00059
this, SLOT(slotReturnPressed(
const QString &)));
00060
00061 completionObject()->insertItems (KateCmd::self()->cmds());
00062 }
00063
00064 KateCmdLine::~KateCmdLine ()
00065 {
00066 }
00067
00068
void KateCmdLine::slotReturnPressed (
const QString& cmd )
00069 {
00070
if (cmd.length () > 0)
00071 {
00072
Kate::Command *p = KateCmd::self()->queryCommand (cmd);
00073
00074 m_oldText = cmd;
00075 m_msgMode =
true;
00076
00077
if (p)
00078 {
00079
QString msg;
00080
00081
if (p->
exec (m_view, cmd, msg))
00082 {
00083 completionObject()->addItem (cmd);
00084 m_oldText =
QString ();
00085
00086
if (msg.length() > 0)
00087 setText (i18n (
"Success: ") + msg);
00088
else
00089 setText (i18n (
"Success"));
00090 }
00091
else
00092 {
00093
if (msg.length() > 0)
00094 setText (i18n (
"Error: ") + msg);
00095
else
00096 setText (i18n (
"Command \"%1\" failed.").arg (cmd));
00097 }
00098 }
00099
else
00100 setText (i18n (
"No such command: \"%1\"").arg (cmd));
00101 }
00102
00103 m_view->setFocus ();
00104 QTimer::singleShot( 4000,
this, SLOT(hideMe()) );
00105 }
00106
00107
void KateCmdLine::hideMe ()
00108 {
00109 m_view->showCmdLine (
false);
00110 }
00111
00112
void KateCmdLine::focusInEvent (
QFocusEvent *ev )
00113 {
00114
if (m_msgMode)
00115 {
00116 m_msgMode =
false;
00117 setText (m_oldText);
00118 }
00119
00120 KLineEdit::focusInEvent (ev);
00121 }
00122
00123
void KateCmdLine::keyPressEvent(
QKeyEvent *ev )
00124 {
00125
if (ev->key() == Key_Escape)
00126 {
00127 m_view->setFocus ();
00128 m_view->showCmdLine (
false);
00129 }
00130
00131
return KLineEdit::keyPressEvent (ev);
00132 }
00133
00134
using namespace KTextEditor;
00135
00136
static const char*
const plus_xpm[] = {
00137
"11 11 3 1",
00138
" c None",
00139
". c #000000",
00140
"+ c #FFFFFF",
00141
"...........",
00142
".+++++++++.",
00143
".+++++++++.",
00144
".++++.++++.",
00145
".++++.++++.",
00146
".++.....++.",
00147
".++++.++++.",
00148
".++++.++++.",
00149
".+++++++++.",
00150
".+++++++++.",
00151
"..........."};
00152
00153
static const char*
const minus_xpm[] = {
00154
"11 11 3 1",
00155
" c None",
00156
". c #000000",
00157
"+ c #FFFFFF",
00158
"...........",
00159
".+++++++++.",
00160
".+++++++++.",
00161
".+++++++++.",
00162
".+++++++++.",
00163
".++.....++.",
00164
".+++++++++.",
00165
".+++++++++.",
00166
".+++++++++.",
00167
".+++++++++.",
00168
"..........."};
00169
00170
00171
static const char*
const bookmark_xpm[]={
00172
"12 12 4 1",
00173
"b c #808080",
00174
"a c #000080",
00175
"# c #0000ff",
00176
". c None",
00177
"........###.",
00178
".......#...a",
00179
"......#.##.a",
00180
".....#.#..aa",
00181
"....#.#...a.",
00182
"...#.#.a.a..",
00183
"..#.#.a.a...",
00184
".#.#.a.a....",
00185
"#.#.a.a.....",
00186
"#.#a.a...bbb",
00187
"#...a..bbb..",
00188
".aaa.bbb...."};
00189
00190
const int iconPaneWidth = 16;
00191
const int halfIPW = 8;
00192
00193
static QPixmap minus_px ((
const char**)minus_xpm);
00194
static QPixmap plus_px ((
const char**)plus_xpm);
00195
00196 KateIconBorder::KateIconBorder ( KateViewInternal* internalView,
QWidget *parent )
00197 :
QWidget(parent, "",
Qt::WStaticContents |
Qt::WRepaintNoErase |
Qt::WResizeNoErase )
00198 , m_view( internalView->m_view )
00199 , m_doc( internalView->m_doc )
00200 , m_viewInternal( internalView )
00201 , m_iconBorderOn( false )
00202 , m_lineNumbersOn( false )
00203 , m_foldingMarkersOn( false )
00204 , m_dynWrapIndicatorsOn( false )
00205 , m_dynWrapIndicators( 0 )
00206 , m_cachedLNWidth( 0 )
00207 , m_maxCharWidth( 0 )
00208 {
00209 setSizePolicy(
QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ) );
00210
00211 setBackgroundMode( NoBackground );
00212
00213 m_doc->setDescription( MarkInterface::markType01, i18n(
"Bookmark") );
00214 m_doc->setPixmap( MarkInterface::markType01,
QPixmap((
const char**)bookmark_xpm) );
00215
00216 updateFont();
00217 }
00218
00219
void KateIconBorder::setIconBorderOn(
bool enable )
00220 {
00221
if( enable == m_iconBorderOn )
00222
return;
00223
00224 m_iconBorderOn = enable;
00225
00226 updateGeometry();
00227
00228 QTimer::singleShot( 0,
this, SLOT(update()) );
00229 }
00230
00231
void KateIconBorder::setLineNumbersOn(
bool enable )
00232 {
00233
if( enable == m_lineNumbersOn )
00234
return;
00235
00236 m_lineNumbersOn = enable;
00237 m_dynWrapIndicatorsOn = (m_dynWrapIndicators == 1) ? enable : m_dynWrapIndicators;
00238
00239 updateGeometry();
00240
00241 QTimer::singleShot( 0,
this, SLOT(update()) );
00242 }
00243
00244
void KateIconBorder::setDynWrapIndicators(
int state )
00245 {
00246
if (state == m_dynWrapIndicators )
00247
return;
00248
00249 m_dynWrapIndicators = state;
00250 m_dynWrapIndicatorsOn = (state == 1) ? m_lineNumbersOn : state;
00251
00252 updateGeometry ();
00253
00254 QTimer::singleShot( 0,
this, SLOT(update()) );
00255 }
00256
00257
void KateIconBorder::setFoldingMarkersOn(
bool enable )
00258 {
00259
if( enable == m_foldingMarkersOn )
00260
return;
00261
00262 m_foldingMarkersOn = enable;
00263
00264 updateGeometry();
00265
00266 QTimer::singleShot( 0,
this, SLOT(update()) );
00267 }
00268
00269
QSize KateIconBorder::sizeHint()
const
00270
{
00271
int w = 0;
00272
00273
if (m_iconBorderOn)
00274 w += iconPaneWidth + 1;
00275
00276
if (m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn)) {
00277 w += lineNumberWidth();
00278 }
00279
00280
if (m_foldingMarkersOn)
00281 w += iconPaneWidth;
00282
00283 w += 4;
00284
00285
return QSize( w, 0 );
00286 }
00287
00288
00289
00290
void KateIconBorder::updateFont()
00291 {
00292
const QFontMetrics *fm = m_view->renderer()->config()->fontMetrics();
00293 m_maxCharWidth = 0;
00294
00295
00296
for (
int i = 48; i < 58; i++) {
00297
int charWidth = fm->width(
QChar(i) );
00298 m_maxCharWidth = QMAX(m_maxCharWidth, charWidth);
00299 }
00300 }
00301
00302
int KateIconBorder::lineNumberWidth()
const
00303
{
00304
int width = m_lineNumbersOn ? ((
int)log10((
double)(m_view->doc()->numLines())) + 1) * m_maxCharWidth + 4 : 0;
00305
00306
if (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) {
00307 width = QMAX(style().scrollBarExtent().width() + 4, width);
00308
00309
if (m_cachedLNWidth != width || m_oldBackgroundColor != *m_view->renderer()->config()->iconBarColor()) {
00310
int w = style().scrollBarExtent().width();
00311
int h = m_view->renderer()->config()->fontMetrics()->height();
00312
00313
QSize newSize(w, h);
00314
if ((m_arrow.size() != newSize || m_oldBackgroundColor != *m_view->renderer()->config()->iconBarColor()) && !newSize.isEmpty()) {
00315 m_arrow.resize(newSize);
00316
00317
QPainter p(&m_arrow);
00318 p.fillRect( 0, 0, w, h, *m_view->renderer()->config()->iconBarColor() );
00319
00320 h = m_view->renderer()->config()->fontMetrics()->ascent();
00321
00322 p.setPen(m_view->renderer()->attribute(0)->textColor());
00323 p.drawLine(w/2, h/2, w/2, 0);
00324
#if 1
00325
p.lineTo(w/4, h/4);
00326 p.lineTo(0, 0);
00327 p.lineTo(0, h/2);
00328 p.lineTo(w/2, h-1);
00329 p.lineTo(w*3/4, h-1);
00330 p.lineTo(w-1, h*3/4);
00331 p.lineTo(w*3/4, h/2);
00332 p.lineTo(0, h/2);
00333
#else
00334
p.lineTo(w*3/4, h/4);
00335 p.lineTo(w-1,0);
00336 p.lineTo(w-1, h/2);
00337 p.lineTo(w/2, h-1);
00338 p.lineTo(w/4,h-1);
00339 p.lineTo(0, h*3/4);
00340 p.lineTo(w/4, h/2);
00341 p.lineTo(w-1, h/2);
00342
#endif
00343
}
00344 }
00345 }
00346
00347
return width;
00348 }
00349
00350
void KateIconBorder::paintEvent(
QPaintEvent* e)
00351 {
00352 paintBorder(e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
00353 }
00354
00355
void KateIconBorder::paintBorder (
int ,
int y,
int ,
int height)
00356 {
00357 uint h = m_view->renderer()->config()->fontStruct()->fontHeight;
00358 uint startz = (y / h);
00359 uint endz = startz + 1 + (height / h);
00360 uint lineRangesSize = m_viewInternal->lineRanges.size();
00361
00362
00363
int m_px = (h - 11) / 2;
00364
if (m_px < 0)
00365 m_px = 0;
00366
00367
int lnWidth( 0 );
00368
if ( m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) )
00369 {
00370 lnWidth = lineNumberWidth();
00371
if ( lnWidth != m_cachedLNWidth || m_oldBackgroundColor != *m_view->renderer()->config()->iconBarColor() )
00372 {
00373
00374
00375
00376
00377 m_cachedLNWidth = lnWidth;
00378 m_oldBackgroundColor = *m_view->renderer()->config()->iconBarColor();
00379 updateGeometry();
00380 update ();
00381
return;
00382 }
00383 }
00384
00385
int w( this->width() );
00386
00387
QPainter p (
this );
00388 p.setFont ( *m_view->renderer()->config()->font() );
00389 p.setPen ( m_view->renderer()->attribute(0)->textColor() );
00390
00391 KateLineInfo oldInfo;
00392
if (startz < lineRangesSize)
00393 {
00394
if ((m_viewInternal->lineRanges[startz].line-1) < 0)
00395 oldInfo.topLevel =
true;
00396
else
00397 m_doc->lineInfo(&oldInfo,m_viewInternal->lineRanges[startz].line-1);
00398 }
00399
00400
for (uint z=startz; z <= endz; z++)
00401 {
00402
int y = h * z;
00403
int realLine = -1;
00404
00405
if (z < lineRangesSize)
00406 realLine = m_viewInternal->lineRanges[z].line;
00407
00408
int lnX ( 0 );
00409
00410 p.fillRect( 0, y, w-4, h, *m_view->renderer()->config()->iconBarColor() );
00411 p.fillRect( w-4, y, 4, h, *m_view->renderer()->config()->backgroundColor() );
00412
00413
00414
if( m_iconBorderOn )
00415 {
00416 p.drawLine(lnX+iconPaneWidth, y, lnX+iconPaneWidth, y+h);
00417
00418
if( (realLine > -1) && (m_viewInternal->lineRanges[z].startCol == 0) )
00419 {
00420 uint mrk ( m_doc->mark( realLine ) );
00421
00422
if ( mrk )
00423 {
00424
for( uint bit = 0; bit < 32; bit++ )
00425 {
00426 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes)(1<<bit);
00427
if( mrk & markType )
00428 {
00429
QPixmap *px_mark (m_doc->markPixmap( markType ));
00430
00431
if (px_mark)
00432 {
00433
00434
int x_px = (iconPaneWidth - px_mark->width()) / 2;
00435
if (x_px < 0)
00436 x_px = 0;
00437
00438
int y_px = (h - px_mark->height()) / 2;
00439
if (y_px < 0)
00440 y_px = 0;
00441
00442 p.drawPixmap( lnX+x_px, y+y_px, *px_mark);
00443 }
00444 }
00445 }
00446 }
00447 }
00448
00449 lnX += iconPaneWidth + 1;
00450 }
00451
00452
00453
if( m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) )
00454 {
00455 lnX +=2;
00456
00457
if (realLine > -1)
00458
if (m_viewInternal->lineRanges[z].startCol == 0) {
00459
if (m_lineNumbersOn)
00460 p.drawText( lnX + 1, y, lnWidth-4, h, Qt::AlignRight|Qt::AlignVCenter, QString(
"%1").arg( realLine + 1 ) );
00461 }
else if (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) {
00462 p.drawPixmap(lnX + lnWidth - m_arrow.width() - 4, y, m_arrow);
00463 }
00464
00465 lnX += lnWidth;
00466 }
00467
00468
00469
if( m_foldingMarkersOn )
00470 {
00471
if( realLine > -1 )
00472 {
00473 KateLineInfo info;
00474 m_doc->lineInfo(&info,realLine);
00475
00476
if (!info.topLevel)
00477 {
00478
if (info.startsVisibleBlock && (m_viewInternal->lineRanges[z].startCol == 0))
00479 {
00480
if (oldInfo.topLevel)
00481 p.drawLine(lnX+halfIPW,y+m_px,lnX+halfIPW,y+h-1);
00482
else
00483 p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
00484
00485 p.drawPixmap(lnX+3,y+m_px,minus_px);
00486 }
00487
else if (info.startsInVisibleBlock)
00488 {
00489
if (m_viewInternal->lineRanges[z].startCol == 0)
00490 {
00491
if (oldInfo.topLevel)
00492 p.drawLine(lnX+halfIPW,y+m_px,lnX+halfIPW,y+h-1);
00493
else
00494 p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
00495
00496 p.drawPixmap(lnX+3,y+m_px,plus_px);
00497 }
00498
else
00499 {
00500 p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
00501 }
00502
00503
if (!m_viewInternal->lineRanges[z].wrap)
00504 p.drawLine(lnX+halfIPW,y+h-1,lnX+iconPaneWidth-2,y+h-1);
00505 }
00506
else
00507 {
00508 p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
00509
00510
if (info.endsBlock && !m_viewInternal->lineRanges[z].wrap)
00511 p.drawLine(lnX+halfIPW,y+h-1,lnX+iconPaneWidth-2,y+h-1);
00512 }
00513 }
00514
00515 oldInfo = info;
00516 }
00517
00518 lnX += iconPaneWidth;
00519 }
00520 }
00521 }
00522
00523 KateIconBorder::BorderArea KateIconBorder::positionToArea(
const QPoint& p )
const
00524
{
00525
int x = 0;
00526
00527
if( m_iconBorderOn ) {
00528 x += iconPaneWidth;
00529
if( p.x() <= x )
00530
return IconBorder;
00531 }
00532
if( m_lineNumbersOn || m_dynWrapIndicators ) {
00533 x += lineNumberWidth();
00534
if( p.x() <= x )
00535
return LineNumbers;
00536 }
00537
if( m_foldingMarkersOn ) {
00538 x += iconPaneWidth;
00539
if( p.x() <= x )
00540
return FoldingMarkers;
00541 }
00542
return None;
00543 }
00544
00545
void KateIconBorder::mousePressEvent(
QMouseEvent* e )
00546 {
00547 m_lastClickedLine = m_viewInternal->yToLineRange(e->y()).line;
00548
00549
if ( positionToArea( e->pos() ) != IconBorder )
00550 {
00551
QMouseEvent forward( QEvent::MouseButtonPress,
00552
QPoint( 0, e->y() ), e->button(), e->state() );
00553 m_viewInternal->mousePressEvent( &forward );
00554 }
00555 e->accept();
00556 }
00557
00558
void KateIconBorder::mouseMoveEvent(
QMouseEvent* e )
00559 {
00560
QMouseEvent forward( QEvent::MouseMove,
00561
QPoint( 0, e->y() ), e->button(), e->state() );
00562 m_viewInternal->mouseMoveEvent( &forward );
00563 }
00564
00565
void KateIconBorder::mouseReleaseEvent(
QMouseEvent* e )
00566 {
00567 uint cursorOnLine = m_viewInternal->yToLineRange(e->y()).line;
00568
00569
if (cursorOnLine == m_lastClickedLine &&
00570 cursorOnLine <= m_doc->lastLine() )
00571 {
00572 BorderArea area = positionToArea( e->pos() );
00573
if( area == IconBorder) {
00574
if (e->button() == LeftButton) {
00575
if( m_doc->editableMarks() & KateViewConfig::global()->defaultMarkType() ) {
00576
if( m_doc->mark( cursorOnLine ) & KateViewConfig::global()->defaultMarkType() )
00577 m_doc->removeMark( cursorOnLine, KateViewConfig::global()->defaultMarkType() );
00578
else
00579 m_doc->addMark( cursorOnLine, KateViewConfig::global()->defaultMarkType() );
00580 }
else {
00581 showMarkMenu( cursorOnLine, QCursor::pos() );
00582 }
00583 }
00584
else
00585
if (e->button() == RightButton) {
00586 showMarkMenu( cursorOnLine, QCursor::pos() );
00587 }
00588 }
00589
00590
if ( area == FoldingMarkers) {
00591 KateLineInfo info;
00592 m_doc->lineInfo(&info,cursorOnLine);
00593
if ((info.startsVisibleBlock) || (info.startsInVisibleBlock)) {
00594 emit toggleRegionVisibility(cursorOnLine);
00595 }
00596 }
00597 }
00598
00599
QMouseEvent forward( QEvent::MouseButtonRelease,
00600
QPoint( 0, e->y() ), e->button(), e->state() );
00601 m_viewInternal->mouseReleaseEvent( &forward );
00602 }
00603
00604
void KateIconBorder::mouseDoubleClickEvent(
QMouseEvent* e )
00605 {
00606
QMouseEvent forward( QEvent::MouseButtonDblClick,
00607
QPoint( 0, e->y() ), e->button(), e->state() );
00608 m_viewInternal->mouseDoubleClickEvent( &forward );
00609 }
00610
00611
void KateIconBorder::showMarkMenu( uint line,
const QPoint& pos )
00612 {
00613
QPopupMenu markMenu;
00614
QPopupMenu selectDefaultMark;
00615
00616
typedef QValueVector<int> MarkTypeVector;
00617 MarkTypeVector vec( 33 );
00618
int i=1;
00619
00620
for( uint bit = 0; bit < 32; bit++ ) {
00621 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes)(1<<bit);
00622
if( !(m_doc->editableMarks() & markType) )
00623
continue;
00624
00625
if( !m_doc->markDescription( markType ).isEmpty() ) {
00626 markMenu.insertItem( m_doc->markDescription( markType ), i );
00627 selectDefaultMark.insertItem( m_doc->markDescription( markType ), i+100);
00628 }
else {
00629 markMenu.insertItem( i18n(
"Mark Type %1").arg( bit + 1 ), i );
00630 selectDefaultMark.insertItem( i18n(
"Mark Type %1").arg( bit + 1 ), i+100);
00631 }
00632
00633
if( m_doc->mark( line ) & markType )
00634 markMenu.setItemChecked( i,
true );
00635
00636
if( markType & KateViewConfig::global()->defaultMarkType() )
00637 selectDefaultMark.setItemChecked( i+100,
true );
00638
00639 vec[i++] = markType;
00640 }
00641
00642
if( markMenu.count() == 0 )
00643
return;
00644
00645
if( markMenu.count() > 1 )
00646 markMenu.insertItem( i18n(
"Set Default Mark Type" ), &selectDefaultMark);
00647
00648
int result = markMenu.exec( pos );
00649
if( result <= 0 )
00650
return;
00651
00652
if ( result > 100)
00653 KateViewConfig::global()->setDefaultMarkType (vec[result-100]);
00654
else
00655 {
00656 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes) vec[result];
00657
if( m_doc->mark( line ) & markType ) {
00658 m_doc->removeMark( line, markType );
00659 }
else {
00660 m_doc->addMark( line, markType );
00661 }
00662 }
00663 }
00664
00665