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 "../interfaces/document.h"
00025 #include "../interfaces/katecmd.h"
00026 #include "kateattribute.h"
00027 #include "katecodefoldinghelpers.h"
00028 #include "kateconfig.h"
00029 #include "katedocument.h"
00030 #include "katefactory.h"
00031 #include "katerenderer.h"
00032 #include "kateview.h"
00033 #include "kateviewinternal.h"
00034
00035 #include <kapplication.h>
00036 #include <kglobalsettings.h>
00037 #include <klocale.h>
00038 #include <knotifyclient.h>
00039 #include <kglobal.h>
00040 #include <kcharsets.h>
00041 #include <kpopupmenu.h>
00042
00043 #include <qcursor.h>
00044 #include <qpainter.h>
00045 #include <qpopupmenu.h>
00046 #include <qstyle.h>
00047 #include <qtimer.h>
00048 #include <qwhatsthis.h>
00049 #include <qregexp.h>
00050 #include <qtextcodec.h>
00051
00052 #include <math.h>
00053
00054 #include <kdebug.h>
00055
00056
00057 class KateCmdLnWhatsThis : public QWhatsThis
00058 {
00059 public:
00060 KateCmdLnWhatsThis( KateCmdLine *parent )
00061 : QWhatsThis( parent )
00062 , m_parent( parent ) {;}
00063
00064 QString text( const QPoint & )
00065 {
00066 QString beg = "<qt background=\"white\"><div><table width=\"100%\"><tr><td bgcolor=\"brown\"><font color=\"white\"><b>Help: <big>";
00067 QString mid = "</big></b></font></td></tr><tr><td>";
00068 QString end = "</td></tr></table></div><qt>";
00069
00070 QString t = m_parent->text();
00071 QRegExp re( "\\s*help\\s+(.*)" );
00072 if ( re.search( t ) > -1 )
00073 {
00074 QString s;
00075
00076 QString name = re.cap( 1 );
00077 if ( name == "list" )
00078 {
00079 return beg + i18n("Available Commands") + mid
00080 + KateCmd::self()->cmds().join(" ")
00081 + i18n("<p>For help on individual commands, do <code>'help <command>'</code></p>")
00082 + end;
00083 }
00084 else if ( ! name.isEmpty() )
00085 {
00086 Kate::Command *cmd = KateCmd::self()->queryCommand( name );
00087 if ( cmd )
00088 {
00089 if ( cmd->help( (Kate::View*)m_parent->parentWidget(), name, s ) )
00090 return beg + name + mid + s + end;
00091 else
00092 return beg + name + mid + i18n("No help for '%1'").arg( name ) + end;
00093 }
00094 else
00095 return beg + mid + i18n("No such command <b>%1</b>").arg(name) + end;
00096 }
00097 }
00098
00099 return beg + mid + i18n(
00100 "<p>This is the Katepart <b>command line</b>.<br>"
00101 "Syntax: <code><b>command [ arguments ]</b></code><br>"
00102 "For a list of available commands, enter <code><b>help list</b></code><br>"
00103 "For help for individual commands, enter <code><b>help <command></b></code></p>")
00104 + end;
00105 }
00106
00107 private:
00108 KateCmdLine *m_parent;
00109 };
00110
00111
00112
00117 class KateCmdLineFlagCompletion : public KCompletion
00118 {
00119 public:
00120 KateCmdLineFlagCompletion() {;}
00121
00122 QString makeCompletion( const QString & s )
00123 {
00124 return QString::null;
00125 }
00126
00127 };
00128
00129
00130
00131 KateCmdLine::KateCmdLine (KateView *view)
00132 : KLineEdit (view)
00133 , m_view (view)
00134 , m_msgMode (false)
00135 , m_histpos( 0 )
00136 , m_cmdend( 0 )
00137 , m_command( 0L )
00138 , m_oldCompletionObject( 0L )
00139 {
00140 connect (this, SIGNAL(returnPressed(const QString &)),
00141 this, SLOT(slotReturnPressed(const QString &)));
00142
00143 completionObject()->insertItems (KateCmd::self()->cmds());
00144 setAutoDeleteCompletionObject( false );
00145 m_help = new KateCmdLnWhatsThis( this );
00146 }
00147
00148 void KateCmdLine::slotReturnPressed ( const QString& text )
00149 {
00150
00151
00152 uint n = 0;
00153 while( text[n].isSpace() )
00154 n++;
00155
00156 QString cmd = text.mid( n );
00157
00158
00159 if ( cmd.startsWith( "help" ) )
00160 {
00161 m_help->display( m_help->text( QPoint() ), mapToGlobal(QPoint(0,0)) );
00162 clear();
00163 KateCmd::self()->appendHistory( cmd );
00164 m_histpos = KateCmd::self()->historyLength();
00165 m_oldText = QString ();
00166 return;
00167 }
00168
00169 if (cmd.length () > 0)
00170 {
00171 Kate::Command *p = KateCmd::self()->queryCommand (cmd);
00172
00173 m_oldText = cmd;
00174 m_msgMode = true;
00175
00176 if (p)
00177 {
00178 QString msg;
00179
00180 if (p->exec (m_view, cmd, msg))
00181 {
00182 KateCmd::self()->appendHistory( cmd );
00183 m_histpos = KateCmd::self()->historyLength();
00184 m_oldText = QString ();
00185
00186 if (msg.length() > 0)
00187 setText (i18n ("Success: ") + msg);
00188 else
00189 setText (i18n ("Success"));
00190 }
00191 else
00192 {
00193 if (msg.length() > 0)
00194 setText (i18n ("Error: ") + msg);
00195 else
00196 setText (i18n ("Command \"%1\" failed.").arg (cmd));
00197 KNotifyClient::beep();
00198 }
00199 }
00200 else
00201 {
00202 setText (i18n ("No such command: \"%1\"").arg (cmd));
00203 KNotifyClient::beep();
00204 }
00205 }
00206
00207
00208 if ( m_oldCompletionObject )
00209 {
00210 KCompletion *c = completionObject();
00211 setCompletionObject( m_oldCompletionObject );
00212 m_oldCompletionObject = 0;
00213 delete c;
00214 c = 0;
00215 }
00216 m_command = 0;
00217 m_cmdend = 0;
00218
00219 m_view->setFocus ();
00220 QTimer::singleShot( 4000, this, SLOT(hideMe()) );
00221 }
00222
00223 void KateCmdLine::hideMe ()
00224 {
00225 if ( isVisibleTo(parentWidget()) && ! hasFocus() ) {
00226 m_view->toggleCmdLine ();
00227 }
00228 }
00229
00230 void KateCmdLine::focusInEvent ( QFocusEvent *ev )
00231 {
00232 if (m_msgMode)
00233 {
00234 m_msgMode = false;
00235 setText (m_oldText);
00236 selectAll();
00237 }
00238
00239 KLineEdit::focusInEvent (ev);
00240 }
00241
00242 void KateCmdLine::keyPressEvent( QKeyEvent *ev )
00243 {
00244 if (ev->key() == Key_Escape)
00245 {
00246 m_view->setFocus ();
00247 hideMe();
00248 }
00249 else if ( ev->key() == Key_Up )
00250 fromHistory( true );
00251 else if ( ev->key() == Key_Down )
00252 fromHistory( false );
00253
00254 uint cursorpos = cursorPosition();
00255 KLineEdit::keyPressEvent (ev);
00256
00257
00258 if ( ! m_cmdend || cursorpos <= m_cmdend )
00259 {
00260 QChar c;
00261 if ( ! ev->text().isEmpty() )
00262 c = ev->text()[0];
00263
00264 if ( ! m_cmdend && ! c.isNull() )
00265 {
00266 if ( ! c.isLetterOrNumber() && c != '-' && c != '_' )
00267 {
00268 m_command = KateCmd::self()->queryCommand( text().stripWhiteSpace() );
00269 if ( m_command )
00270 {
00271
00272
00273
00274 m_cmdend = cursorpos;
00275
00276 }
00277 else
00278 m_cmdend = 0;
00279 }
00280 }
00281 else
00282 {
00283 kdDebug(13025)<<"keypress in commandline: \\W -- text is "<<text()<<endl;
00284 m_command = KateCmd::self()->queryCommand( text().stripWhiteSpace() );
00285 if ( m_command )
00286 {
00287
00288 QString t = text();
00289 m_cmdend = 0;
00290 bool b = false;
00291 for ( ; m_cmdend < t.length(); m_cmdend++ )
00292 {
00293 if ( t[m_cmdend].isLetter() )
00294 b = true;
00295 if ( b && ( ! t[m_cmdend].isLetterOrNumber() && t[m_cmdend] != '-' && t[m_cmdend] != '_' ) )
00296 break;
00297 }
00298
00299 if ( c == ':' && cursorpos == m_cmdend )
00300 {
00301
00302
00303 }
00304 }
00305 else
00306 {
00307
00308 if ( m_oldCompletionObject )
00309 {
00310 KCompletion *c = completionObject();
00311 setCompletionObject( m_oldCompletionObject );
00312 m_oldCompletionObject = 0;
00313 delete c;
00314 c = 0;
00315 }
00316
00317 m_cmdend = 0;
00318 }
00319 }
00320
00321
00322 if ( m_command )
00323 {
00324
00325 Kate::CommandExtension *ce = dynamic_cast<Kate::CommandExtension*>(m_command);
00326 if ( ce )
00327 {
00328 KCompletion *cmpl = ce->completionObject( text().left( m_cmdend ).stripWhiteSpace(), m_view );
00329 if ( cmpl )
00330 {
00331
00332
00333
00334
00335 if ( ! m_oldCompletionObject )
00336 m_oldCompletionObject = completionObject();
00337
00338 setCompletionObject( cmpl );
00339 }
00340 }
00341 }
00342 }
00343 else if ( m_command )
00344 {
00345 Kate::CommandExtension *ce = dynamic_cast<Kate::CommandExtension*>( m_command );
00346 if ( ce && ce->wantsToProcessText( text().left( m_cmdend ).stripWhiteSpace() )
00347 && ! ( ev->text().isNull() || ev->text().isEmpty() ) )
00348 ce->processText( m_view, text() );
00349 }
00350 }
00351
00352 void KateCmdLine::fromHistory( bool up )
00353 {
00354 if ( ! KateCmd::self()->historyLength() )
00355 return;
00356
00357 QString s;
00358
00359 if ( up )
00360 {
00361 if ( m_histpos > 0 )
00362 {
00363 m_histpos--;
00364 s = KateCmd::self()->fromHistory( m_histpos );
00365 }
00366 }
00367 else
00368 {
00369 if ( m_histpos < ( KateCmd::self()->historyLength() - 1 ) )
00370 {
00371 m_histpos++;
00372 s = KateCmd::self()->fromHistory( m_histpos );
00373 }
00374 else
00375 {
00376 m_histpos = KateCmd::self()->historyLength();
00377 setText( m_oldText );
00378 }
00379 }
00380 if ( ! s.isEmpty() )
00381 {
00382
00383 setText( s );
00384 static QRegExp reCmd = QRegExp(".*[\\w\\-]+(?:[^a-zA-Z0-9_-]|:\\w+)(.*)");
00385 if ( reCmd.search( text() ) == 0 )
00386 setSelection( text().length() - reCmd.cap(1).length(), reCmd.cap(1).length() );
00387 }
00388 }
00389
00390
00391
00392 using namespace KTextEditor;
00393
00394 static const char* const plus_xpm[] = {
00395 "11 11 3 1",
00396 " c None",
00397 ". c #000000",
00398 "+ c #FFFFFF",
00399 "...........",
00400 ".+++++++++.",
00401 ".+++++++++.",
00402 ".++++.++++.",
00403 ".++++.++++.",
00404 ".++.....++.",
00405 ".++++.++++.",
00406 ".++++.++++.",
00407 ".+++++++++.",
00408 ".+++++++++.",
00409 "..........."};
00410
00411 static const char* const minus_xpm[] = {
00412 "11 11 3 1",
00413 " c None",
00414 ". c #000000",
00415 "+ c #FFFFFF",
00416 "...........",
00417 ".+++++++++.",
00418 ".+++++++++.",
00419 ".+++++++++.",
00420 ".+++++++++.",
00421 ".++.....++.",
00422 ".+++++++++.",
00423 ".+++++++++.",
00424 ".+++++++++.",
00425 ".+++++++++.",
00426 "..........."};
00427
00428
00429 static const char* const bookmark_xpm[]={
00430 "12 12 4 1",
00431 "b c #808080",
00432 "a c #000080",
00433 "# c #0000ff",
00434 ". c None",
00435 "........###.",
00436 ".......#...a",
00437 "......#.##.a",
00438 ".....#.#..aa",
00439 "....#.#...a.",
00440 "...#.#.a.a..",
00441 "..#.#.a.a...",
00442 ".#.#.a.a....",
00443 "#.#.a.a.....",
00444 "#.#a.a...bbb",
00445 "#...a..bbb..",
00446 ".aaa.bbb...."};
00447
00448 const int iconPaneWidth = 16;
00449 const int halfIPW = 8;
00450
00451 static QPixmap minus_px ((const char**)minus_xpm);
00452 static QPixmap plus_px ((const char**)plus_xpm);
00453
00454 KateIconBorder::KateIconBorder ( KateViewInternal* internalView, QWidget *parent )
00455 : QWidget(parent, "", Qt::WStaticContents | Qt::WRepaintNoErase | Qt::WResizeNoErase )
00456 , m_view( internalView->m_view )
00457 , m_doc( internalView->m_doc )
00458 , m_viewInternal( internalView )
00459 , m_iconBorderOn( false )
00460 , m_lineNumbersOn( false )
00461 , m_foldingMarkersOn( false )
00462 , m_dynWrapIndicatorsOn( false )
00463 , m_dynWrapIndicators( 0 )
00464 , m_cachedLNWidth( 0 )
00465 , m_maxCharWidth( 0 )
00466 {
00467 setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ) );
00468
00469 setBackgroundMode( NoBackground );
00470
00471 m_doc->setDescription( MarkInterface::markType01, i18n("Bookmark") );
00472 m_doc->setPixmap( MarkInterface::markType01, QPixmap((const char**)bookmark_xpm) );
00473
00474 updateFont();
00475 }
00476
00477 void KateIconBorder::setIconBorderOn( bool enable )
00478 {
00479 if( enable == m_iconBorderOn )
00480 return;
00481
00482 m_iconBorderOn = enable;
00483
00484 updateGeometry();
00485
00486 QTimer::singleShot( 0, this, SLOT(update()) );
00487 }
00488
00489 void KateIconBorder::setLineNumbersOn( bool enable )
00490 {
00491 if( enable == m_lineNumbersOn )
00492 return;
00493
00494 m_lineNumbersOn = enable;
00495 m_dynWrapIndicatorsOn = (m_dynWrapIndicators == 1) ? enable : m_dynWrapIndicators;
00496
00497 updateGeometry();
00498
00499 QTimer::singleShot( 0, this, SLOT(update()) );
00500 }
00501
00502 void KateIconBorder::setDynWrapIndicators( int state )
00503 {
00504 if (state == m_dynWrapIndicators )
00505 return;
00506
00507 m_dynWrapIndicators = state;
00508 m_dynWrapIndicatorsOn = (state == 1) ? m_lineNumbersOn : state;
00509
00510 updateGeometry ();
00511
00512 QTimer::singleShot( 0, this, SLOT(update()) );
00513 }
00514
00515 void KateIconBorder::setFoldingMarkersOn( bool enable )
00516 {
00517 if( enable == m_foldingMarkersOn )
00518 return;
00519
00520 m_foldingMarkersOn = enable;
00521
00522 updateGeometry();
00523
00524 QTimer::singleShot( 0, this, SLOT(update()) );
00525 }
00526
00527 QSize KateIconBorder::sizeHint() const
00528 {
00529 int w = 0;
00530
00531 if (m_iconBorderOn)
00532 w += iconPaneWidth + 1;
00533
00534 if (m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn)) {
00535 w += lineNumberWidth();
00536 }
00537
00538 if (m_foldingMarkersOn)
00539 w += iconPaneWidth;
00540
00541 w += 4;
00542
00543 return QSize( w, 0 );
00544 }
00545
00546
00547
00548 void KateIconBorder::updateFont()
00549 {
00550 const QFontMetrics *fm = m_view->renderer()->config()->fontMetrics();
00551 m_maxCharWidth = 0;
00552
00553
00554 for (int i = 48; i < 58; i++) {
00555 int charWidth = fm->width( QChar(i) );
00556 m_maxCharWidth = QMAX(m_maxCharWidth, charWidth);
00557 }
00558 }
00559
00560 int KateIconBorder::lineNumberWidth() const
00561 {
00562 int width = m_lineNumbersOn ? ((int)log10((double)(m_view->doc()->numLines())) + 1) * m_maxCharWidth + 4 : 0;
00563
00564 if (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) {
00565 width = QMAX(style().scrollBarExtent().width() + 4, width);
00566
00567 if (m_cachedLNWidth != width || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor()) {
00568 int w = style().scrollBarExtent().width();
00569 int h = m_view->renderer()->config()->fontMetrics()->height();
00570
00571 QSize newSize(w, h);
00572 if ((m_arrow.size() != newSize || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor()) && !newSize.isEmpty()) {
00573 m_arrow.resize(newSize);
00574
00575 QPainter p(&m_arrow);
00576 p.fillRect( 0, 0, w, h, m_view->renderer()->config()->iconBarColor() );
00577
00578 h = m_view->renderer()->config()->fontMetrics()->ascent();
00579
00580 p.setPen(m_view->renderer()->attribute(0)->textColor());
00581 p.drawLine(w/2, h/2, w/2, 0);
00582 #if 1
00583 p.lineTo(w/4, h/4);
00584 p.lineTo(0, 0);
00585 p.lineTo(0, h/2);
00586 p.lineTo(w/2, h-1);
00587 p.lineTo(w*3/4, h-1);
00588 p.lineTo(w-1, h*3/4);
00589 p.lineTo(w*3/4, h/2);
00590 p.lineTo(0, h/2);
00591 #else
00592 p.lineTo(w*3/4, h/4);
00593 p.lineTo(w-1,0);
00594 p.lineTo(w-1, h/2);
00595 p.lineTo(w/2, h-1);
00596 p.lineTo(w/4,h-1);
00597 p.lineTo(0, h*3/4);
00598 p.lineTo(w/4, h/2);
00599 p.lineTo(w-1, h/2);
00600 #endif
00601 }
00602 }
00603 }
00604
00605 return width;
00606 }
00607
00608 void KateIconBorder::paintEvent(QPaintEvent* e)
00609 {
00610 paintBorder(e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
00611 }
00612
00613 void KateIconBorder::paintBorder (int , int y, int , int height)
00614 {
00615 uint h = m_view->renderer()->config()->fontStruct()->fontHeight;
00616 uint startz = (y / h);
00617 uint endz = startz + 1 + (height / h);
00618 uint lineRangesSize = m_viewInternal->lineRanges.size();
00619
00620
00621 int m_px = (h - 11) / 2;
00622 if (m_px < 0)
00623 m_px = 0;
00624
00625 int lnWidth( 0 );
00626 if ( m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) )
00627 {
00628 lnWidth = lineNumberWidth();
00629 if ( lnWidth != m_cachedLNWidth || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor() )
00630 {
00631
00632
00633
00634
00635 m_cachedLNWidth = lnWidth;
00636 m_oldBackgroundColor = m_view->renderer()->config()->iconBarColor();
00637 updateGeometry();
00638 update ();
00639 return;
00640 }
00641 }
00642
00643 int w( this->width() );
00644
00645 QPainter p ( this );
00646 p.setFont ( *m_view->renderer()->config()->font() );
00647
00648
00649 p.setPen ( m_view->renderer()->config()->lineNumberColor() );
00650
00651 KateLineInfo oldInfo;
00652 if (startz < lineRangesSize)
00653 {
00654 if ((m_viewInternal->lineRanges[startz].line-1) < 0)
00655 oldInfo.topLevel = true;
00656 else
00657 m_doc->lineInfo(&oldInfo,m_viewInternal->lineRanges[startz].line-1);
00658 }
00659
00660 for (uint z=startz; z <= endz; z++)
00661 {
00662 int y = h * z;
00663 int realLine = -1;
00664
00665 if (z < lineRangesSize)
00666 realLine = m_viewInternal->lineRanges[z].line;
00667
00668 int lnX ( 0 );
00669
00670 p.fillRect( 0, y, w-4, h, m_view->renderer()->config()->iconBarColor() );
00671 p.fillRect( w-4, y, 4, h, m_view->renderer()->config()->backgroundColor() );
00672
00673
00674 if( m_iconBorderOn )
00675 {
00676 p.drawLine(lnX+iconPaneWidth, y, lnX+iconPaneWidth, y+h);
00677
00678 if( (realLine > -1) && (m_viewInternal->lineRanges[z].startCol == 0) )
00679 {
00680 uint mrk ( m_doc->mark( realLine ) );
00681
00682 if ( mrk )
00683 {
00684 for( uint bit = 0; bit < 32; bit++ )
00685 {
00686 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes)(1<<bit);
00687 if( mrk & markType )
00688 {
00689 QPixmap *px_mark (m_doc->markPixmap( markType ));
00690
00691 if (px_mark)
00692 {
00693
00694 int x_px = (iconPaneWidth - px_mark->width()) / 2;
00695 if (x_px < 0)
00696 x_px = 0;
00697
00698 int y_px = (h - px_mark->height()) / 2;
00699 if (y_px < 0)
00700 y_px = 0;
00701
00702 p.drawPixmap( lnX+x_px, y+y_px, *px_mark);
00703 }
00704 }
00705 }
00706 }
00707 }
00708
00709 lnX += iconPaneWidth + 1;
00710 }
00711
00712
00713 if( m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) )
00714 {
00715 lnX +=2;
00716
00717 if (realLine > -1)
00718 if (m_viewInternal->lineRanges[z].startCol == 0) {
00719 if (m_lineNumbersOn)
00720 p.drawText( lnX + 1, y, lnWidth-4, h, Qt::AlignRight|Qt::AlignVCenter, QString("%1").arg( realLine + 1 ) );
00721 } else if (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) {
00722 p.drawPixmap(lnX + lnWidth - m_arrow.width() - 4, y, m_arrow);
00723 }
00724
00725 lnX += lnWidth;
00726 }
00727
00728
00729 if( m_foldingMarkersOn )
00730 {
00731 if( realLine > -1 )
00732 {
00733 KateLineInfo info;
00734 m_doc->lineInfo(&info,realLine);
00735
00736 if (!info.topLevel)
00737 {
00738 if (info.startsVisibleBlock && (m_viewInternal->lineRanges[z].startCol == 0))
00739 {
00740 if (oldInfo.topLevel)
00741 p.drawLine(lnX+halfIPW,y+m_px,lnX+halfIPW,y+h-1);
00742 else
00743 p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
00744
00745 p.drawPixmap(lnX+3,y+m_px,minus_px);
00746 }
00747 else if (info.startsInVisibleBlock)
00748 {
00749 if (m_viewInternal->lineRanges[z].startCol == 0)
00750 {
00751 if (oldInfo.topLevel)
00752 p.drawLine(lnX+halfIPW,y+m_px,lnX+halfIPW,y+h-1);
00753 else
00754 p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
00755
00756 p.drawPixmap(lnX+3,y+m_px,plus_px);
00757 }
00758 else
00759 {
00760 p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
00761 }
00762
00763 if (!m_viewInternal->lineRanges[z].wrap)
00764 p.drawLine(lnX+halfIPW,y+h-1,lnX+iconPaneWidth-2,y+h-1);
00765 }
00766 else
00767 {
00768 p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
00769
00770 if (info.endsBlock && !m_viewInternal->lineRanges[z].wrap)
00771 p.drawLine(lnX+halfIPW,y+h-1,lnX+iconPaneWidth-2,y+h-1);
00772 }
00773 }
00774
00775 oldInfo = info;
00776 }
00777
00778 lnX += iconPaneWidth;
00779 }
00780 }
00781 }
00782
00783 KateIconBorder::BorderArea KateIconBorder::positionToArea( const QPoint& p ) const
00784 {
00785 int x = 0;
00786 if( m_iconBorderOn ) {
00787 x += iconPaneWidth;
00788 if( p.x() <= x )
00789 return IconBorder;
00790 }
00791 if( m_lineNumbersOn || m_dynWrapIndicators ) {
00792 x += lineNumberWidth();
00793 if( p.x() <= x )
00794 return LineNumbers;
00795 }
00796 if( m_foldingMarkersOn ) {
00797 x += iconPaneWidth;
00798 if( p.x() <= x )
00799 return FoldingMarkers;
00800 }
00801 return None;
00802 }
00803
00804 void KateIconBorder::mousePressEvent( QMouseEvent* e )
00805 {
00806 m_lastClickedLine = m_viewInternal->yToKateLineRange(e->y()).line;
00807
00808 if ( positionToArea( e->pos() ) != IconBorder )
00809 {
00810 QMouseEvent forward( QEvent::MouseButtonPress,
00811 QPoint( 0, e->y() ), e->button(), e->state() );
00812 m_viewInternal->mousePressEvent( &forward );
00813 }
00814 e->accept();
00815 }
00816
00817 void KateIconBorder::mouseMoveEvent( QMouseEvent* e )
00818 {
00819 if ( positionToArea( e->pos() ) != IconBorder )
00820 {
00821 QMouseEvent forward( QEvent::MouseMove,
00822 QPoint( 0, e->y() ), e->button(), e->state() );
00823 m_viewInternal->mouseMoveEvent( &forward );
00824 }
00825 }
00826
00827 void KateIconBorder::mouseReleaseEvent( QMouseEvent* e )
00828 {
00829 uint cursorOnLine = m_viewInternal->yToKateLineRange(e->y()).line;
00830
00831 if (cursorOnLine == m_lastClickedLine &&
00832 cursorOnLine <= m_doc->lastLine() )
00833 {
00834 BorderArea area = positionToArea( e->pos() );
00835 if( area == IconBorder) {
00836 if (e->button() == LeftButton) {
00837 if( m_doc->editableMarks() & KateViewConfig::global()->defaultMarkType() ) {
00838 if( m_doc->mark( cursorOnLine ) & KateViewConfig::global()->defaultMarkType() )
00839 m_doc->removeMark( cursorOnLine, KateViewConfig::global()->defaultMarkType() );
00840 else
00841 m_doc->addMark( cursorOnLine, KateViewConfig::global()->defaultMarkType() );
00842 } else {
00843 showMarkMenu( cursorOnLine, QCursor::pos() );
00844 }
00845 }
00846 else
00847 if (e->button() == RightButton) {
00848 showMarkMenu( cursorOnLine, QCursor::pos() );
00849 }
00850 }
00851
00852 if ( area == FoldingMarkers) {
00853 KateLineInfo info;
00854 m_doc->lineInfo(&info,cursorOnLine);
00855 if ((info.startsVisibleBlock) || (info.startsInVisibleBlock)) {
00856 emit toggleRegionVisibility(cursorOnLine);
00857 }
00858 }
00859 }
00860
00861 QMouseEvent forward( QEvent::MouseButtonRelease,
00862 QPoint( 0, e->y() ), e->button(), e->state() );
00863 m_viewInternal->mouseReleaseEvent( &forward );
00864 }
00865
00866 void KateIconBorder::mouseDoubleClickEvent( QMouseEvent* e )
00867 {
00868 QMouseEvent forward( QEvent::MouseButtonDblClick,
00869 QPoint( 0, e->y() ), e->button(), e->state() );
00870 m_viewInternal->mouseDoubleClickEvent( &forward );
00871 }
00872
00873 void KateIconBorder::showMarkMenu( uint line, const QPoint& pos )
00874 {
00875 QPopupMenu markMenu;
00876 QPopupMenu selectDefaultMark;
00877
00878 typedef QValueVector<int> MarkTypeVector;
00879 MarkTypeVector vec( 33 );
00880 int i=1;
00881
00882 for( uint bit = 0; bit < 32; bit++ ) {
00883 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes)(1<<bit);
00884 if( !(m_doc->editableMarks() & markType) )
00885 continue;
00886
00887 if( !m_doc->markDescription( markType ).isEmpty() ) {
00888 markMenu.insertItem( m_doc->markDescription( markType ), i );
00889 selectDefaultMark.insertItem( m_doc->markDescription( markType ), i+100);
00890 } else {
00891 markMenu.insertItem( i18n("Mark Type %1").arg( bit + 1 ), i );
00892 selectDefaultMark.insertItem( i18n("Mark Type %1").arg( bit + 1 ), i+100);
00893 }
00894
00895 if( m_doc->mark( line ) & markType )
00896 markMenu.setItemChecked( i, true );
00897
00898 if( markType & KateViewConfig::global()->defaultMarkType() )
00899 selectDefaultMark.setItemChecked( i+100, true );
00900
00901 vec[i++] = markType;
00902 }
00903
00904 if( markMenu.count() == 0 )
00905 return;
00906
00907 if( markMenu.count() > 1 )
00908 markMenu.insertItem( i18n("Set Default Mark Type" ), &selectDefaultMark);
00909
00910 int result = markMenu.exec( pos );
00911 if( result <= 0 )
00912 return;
00913
00914 if ( result > 100)
00915 {
00916 KateViewConfig::global()->setDefaultMarkType (vec[result-100]);
00917
00918 KConfig *config = kapp->config();
00919 config->setGroup("Kate View Defaults");
00920 KateViewConfig::global()->writeConfig( config );
00921 }
00922 else
00923 {
00924 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes) vec[result];
00925 if( m_doc->mark( line ) & markType ) {
00926 m_doc->removeMark( line, markType );
00927 } else {
00928 m_doc->addMark( line, markType );
00929 }
00930 }
00931 }
00932
00933
00934 KateViewEncodingAction::KateViewEncodingAction(KateDocument *_doc, KateView *_view, const QString& text, QObject* parent, const char* name)
00935 : KActionMenu (text, parent, name), doc(_doc), view (_view)
00936 {
00937 connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
00938 }
00939
00940 void KateViewEncodingAction::slotAboutToShow()
00941 {
00942 QStringList modes (KGlobal::charsets()->descriptiveEncodingNames());
00943
00944 popupMenu()->clear ();
00945 for (uint z=0; z<modes.size(); ++z)
00946 {
00947 popupMenu()->insertItem ( modes[z], this, SLOT(setMode(int)), 0, z);
00948
00949 bool found = false;
00950 QTextCodec *codecForEnc = KGlobal::charsets()->codecForName(KGlobal::charsets()->encodingForName(modes[z]), found);
00951
00952 if (found && codecForEnc)
00953 {
00954 if (codecForEnc->name() == doc->config()->codec()->name())
00955 popupMenu()->setItemChecked (z, true);
00956 }
00957 }
00958 }
00959
00960 void KateViewEncodingAction::setMode (int mode)
00961 {
00962 QStringList modes (KGlobal::charsets()->descriptiveEncodingNames());
00963 doc->setEncoding( KGlobal::charsets()->encodingForName( modes[mode] ) );
00964 view->reloadFile();
00965 }
00966
00967