00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kateviewhelpers.h"
00023 #include "kateviewhelpers.moc"
00024
00025 #include "katecmd.h"
00026 #include <ktexteditor/attribute.h>
00027 #include <ktexteditor/annotationinterface.h>
00028 #include <ktexteditor/rangefeedback.h>
00029 #include "katecodefolding.h"
00030 #include "kateconfig.h"
00031 #include "katedocument.h"
00032 #include "katerenderer.h"
00033 #include "kateview.h"
00034 #include "kateviewinternal.h"
00035 #include "katelayoutcache.h"
00036 #include "katetextlayout.h"
00037 #include "katesmartrange.h"
00038
00039 #include <kapplication.h>
00040 #include <kglobalsettings.h>
00041 #include <klocale.h>
00042 #include <knotification.h>
00043 #include <kglobal.h>
00044 #include <kmenu.h>
00045 #include <kiconloader.h>
00046 #include <kconfiggroup.h>
00047
00048 #include <QtGui/QCursor>
00049 #include <QtGui/QPainter>
00050 #include <QtGui/QStyle>
00051 #include <QtCore/QTimer>
00052 #include <QtCore/QRegExp>
00053 #include <QtCore/QTextCodec>
00054 #include <QtGui/QKeyEvent>
00055 #include <QtGui/QPainterPath>
00056 #include <QtGui/QStyleOption>
00057 #include <QtGui/QPalette>
00058 #include <QtGui/QPen>
00059 #include <QtGui/QBoxLayout>
00060 #include <QtGui/QToolButton>
00061 #include <QtGui/QToolTip>
00062 #include <QtGui/QAction>
00063
00064 #include <math.h>
00065
00066 #include <kdebug.h>
00067
00068 #include <QtGui/QWhatsThis>
00069
00070
00071 KateScrollBar::KateScrollBar (Qt::Orientation orientation, KateViewInternal* parent)
00072 : QScrollBar (orientation, parent->m_view)
00073 , m_middleMouseDown (false)
00074 , m_view(parent->m_view)
00075 , m_doc(parent->m_doc)
00076 , m_viewInternal(parent)
00077 , m_topMargin(0)
00078 , m_bottomMargin(0)
00079 , m_savVisibleLines(0)
00080 , m_showMarks(false)
00081 {
00082 connect(this, SIGNAL(valueChanged(int)), this, SLOT(sliderMaybeMoved(int)));
00083 connect(m_doc, SIGNAL(marksChanged(KTextEditor::Document*)), this, SLOT(marksChanged()));
00084
00085 styleChange(*style());
00086 }
00087
00088 void KateScrollBar::mousePressEvent(QMouseEvent* e)
00089 {
00090 if (e->button() == Qt::MidButton)
00091 m_middleMouseDown = true;
00092
00093 QScrollBar::mousePressEvent(e);
00094
00095 redrawMarks();
00096 }
00097
00098 void KateScrollBar::mouseReleaseEvent(QMouseEvent* e)
00099 {
00100 QScrollBar::mouseReleaseEvent(e);
00101
00102 m_middleMouseDown = false;
00103
00104 redrawMarks();
00105 }
00106
00107 void KateScrollBar::mouseMoveEvent(QMouseEvent* e)
00108 {
00109 QScrollBar::mouseMoveEvent(e);
00110
00111 if (e->buttons() | Qt::LeftButton)
00112 redrawMarks();
00113 }
00114
00115 void KateScrollBar::paintEvent(QPaintEvent *e)
00116 {
00117 QScrollBar::paintEvent(e);
00118
00119 QPainter painter(this);
00120
00121 QStyleOptionSlider opt;
00122 opt.init(this);
00123 opt.subControls = QStyle::SC_None;
00124 opt.activeSubControls = QStyle::SC_None;
00125 opt.orientation = orientation();
00126 opt.minimum = minimum();
00127 opt.maximum = maximum();
00128 opt.sliderPosition = sliderPosition();
00129 opt.sliderValue = value();
00130 opt.singleStep = singleStep();
00131 opt.pageStep = pageStep();
00132
00133 QRect rect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSlider, this);
00134
00135 QHashIterator<int, QColor> it = m_lines;
00136 while (it.hasNext())
00137 {
00138 it.next();
00139 if (it.key() < rect.top() || it.key() > rect.bottom())
00140 {
00141 painter.setPen(it.value());
00142 painter.drawLine(0, it.key(), width(), it.key());
00143 }
00144 }
00145 }
00146
00147 void KateScrollBar::resizeEvent(QResizeEvent *e)
00148 {
00149 QScrollBar::resizeEvent(e);
00150 recomputeMarksPositions();
00151 }
00152
00153 void KateScrollBar::styleChange(QStyle &s)
00154 {
00155 QScrollBar::styleChange(s);
00156
00157
00158 QStyleOptionSlider opt;
00159 opt.init(this);
00160 opt.subControls = QStyle::SC_None;
00161 opt.activeSubControls = QStyle::SC_None;
00162 opt.orientation = this->orientation();
00163 opt.minimum = minimum();
00164 opt.maximum = maximum();
00165 opt.sliderPosition = sliderPosition();
00166 opt.sliderValue = value();
00167 opt.singleStep = singleStep();
00168 opt.pageStep = pageStep();
00169
00170 m_topMargin = style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSubLine, this).height() + 2;
00171 m_bottomMargin = m_topMargin + style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarAddLine, this).height() + 1;
00172
00173 recomputeMarksPositions();
00174 }
00175
00176 void KateScrollBar::sliderChange ( SliderChange change )
00177 {
00178
00179 QScrollBar::sliderChange (change);
00180
00181 if (change == QAbstractSlider::SliderValueChange)
00182 {
00183 redrawMarks();
00184 }
00185 else if (change == QAbstractSlider::SliderRangeChange)
00186 {
00187 recomputeMarksPositions();
00188 }
00189 }
00190
00191 void KateScrollBar::marksChanged()
00192 {
00193 recomputeMarksPositions();
00194 }
00195
00196 void KateScrollBar::redrawMarks()
00197 {
00198 if (!m_showMarks)
00199 return;
00200
00201 update();
00202 }
00203
00204 void KateScrollBar::recomputeMarksPositions()
00205 {
00206 m_lines.clear();
00207 m_savVisibleLines = m_doc->visibleLines();
00208
00209 int realHeight = frameGeometry().height() - m_topMargin - m_bottomMargin;
00210
00211 const QHash<int, KTextEditor::Mark*> &marks = m_doc->marks();
00212 KateCodeFoldingTree *tree = m_doc->foldingTree();
00213
00214 for (QHash<int, KTextEditor::Mark*>::const_iterator i = marks.constBegin(); i != marks.constEnd(); ++i)
00215 {
00216 KTextEditor::Mark *mark = i.value();
00217
00218 uint line = mark->line;
00219
00220 if (tree)
00221 {
00222 KateCodeFoldingNode *node = tree->findNodeForLine(line);
00223
00224 while (node)
00225 {
00226 if (!node->isVisible())
00227 line = tree->getStartLine(node);
00228 node = node->getParentNode();
00229 }
00230 }
00231
00232 line = m_doc->getVirtualLine(line);
00233
00234 double d = (double)line / (m_savVisibleLines - 1);
00235 m_lines.insert(m_topMargin + (int)(d * realHeight),
00236 QColor(KateRendererConfig::global()->lineMarkerColor((KTextEditor::MarkInterface::MarkTypes)mark->type)));
00237 }
00238
00239
00240
00241 update();
00242 }
00243
00244 void KateScrollBar::sliderMaybeMoved(int value)
00245 {
00246 if (m_middleMouseDown) {
00247
00248
00249
00250 m_middleMouseDown = false;
00251 emit sliderMMBMoved(value);
00252 }
00253 }
00254
00255
00256
00257
00262 class KateCmdLineEditFlagCompletion : public KCompletion
00263 {
00264 public:
00265 KateCmdLineEditFlagCompletion() {;}
00266
00267 QString makeCompletion( const QString & )
00268 {
00269 return QString();
00270 }
00271
00272 };
00273
00274
00275
00276 KateCmdLine::KateCmdLine (KateView *view, KateViewBar *viewBar)
00277 : KateViewBarWidget (viewBar)
00278 {
00279 QVBoxLayout *topLayout = new QVBoxLayout ();
00280 centralWidget()->setLayout(topLayout);
00281 topLayout->setMargin(0);
00282 m_lineEdit = new KateCmdLineEdit (this, view);
00283 topLayout->addWidget (m_lineEdit);
00284
00285 setFocusProxy (m_lineEdit);
00286 }
00287
00288 KateCmdLine::~KateCmdLine()
00289 {
00290 }
00291
00292 KateCmdLineEdit::KateCmdLineEdit (KateCmdLine *bar, KateView *view)
00293 : KLineEdit ()
00294 , m_view (view)
00295 , m_bar (bar)
00296 , m_msgMode (false)
00297 , m_histpos( 0 )
00298 , m_cmdend( 0 )
00299 , m_command( 0L )
00300 , m_oldCompletionObject( 0L )
00301 {
00302 connect (this, SIGNAL(returnPressed(const QString &)),
00303 this, SLOT(slotReturnPressed(const QString &)));
00304
00305 completionObject()->insertItems (KateCmd::self()->commandList());
00306 setAutoDeleteCompletionObject( false );
00307 }
00308
00309
00310 QString KateCmdLineEdit::helptext( const QPoint & ) const
00311 {
00312 QString beg = "<qt background=\"white\"><div><table width=\"100%\"><tr><td bgcolor=\"brown\"><font color=\"white\"><b>Help: <big>";
00313 QString mid = "</big></b></font></td></tr><tr><td>";
00314 QString end = "</td></tr></table></div><qt>";
00315
00316 QString t = text();
00317 QRegExp re( "\\s*help\\s+(.*)" );
00318 if ( re.indexIn( t ) > -1 )
00319 {
00320 QString s;
00321
00322 QString name = re.cap( 1 );
00323 if ( name == "list" )
00324 {
00325 return beg + i18n("Available Commands") + mid
00326 + KateCmd::self()->commandList().join(" ")
00327 + i18n("<p>For help on individual commands, do <code>'help <command>'</code></p>")
00328 + end;
00329 }
00330 else if ( ! name.isEmpty() )
00331 {
00332 KTextEditor::Command *cmd = KateCmd::self()->queryCommand( name );
00333 if ( cmd )
00334 {
00335 if ( cmd->help( (KTextEditor::View*)parentWidget(), name, s ) )
00336 return beg + name + mid + s + end;
00337 else
00338 return beg + name + mid + i18n("No help for '%1'", name ) + end;
00339 }
00340 else
00341 return beg + mid + i18n("No such command <b>%1</b>", name) + end;
00342 }
00343 }
00344
00345 return beg + mid + i18n(
00346 "<p>This is the Katepart <b>command line</b>.<br />"
00347 "Syntax: <code><b>command [ arguments ]</b></code><br />"
00348 "For a list of available commands, enter <code><b>help list</b></code><br />"
00349 "For help for individual commands, enter <code><b>help <command></b></code></p>")
00350 + end;
00351 }
00352
00353
00354
00355 bool KateCmdLineEdit::event(QEvent *e) {
00356 if (e->type()==QEvent::WhatsThis)
00357 setWhatsThis(helptext(QPoint()));
00358 return KLineEdit::event(e);
00359 }
00360
00361 void KateCmdLineEdit::slotReturnPressed ( const QString& text )
00362 {
00363 if (text.isEmpty()) return;
00364
00365 uint n = 0;
00366 const uint textlen=text.length();
00367 while( (n<textlen) &&text[n].isSpace() )
00368 n++;
00369
00370 if (n>=textlen) return;
00371
00372 QString cmd = text.mid( n );
00373
00374
00375 if ( cmd.startsWith( "help" ) )
00376 {
00377 QWhatsThis::showText(mapToGlobal(QPoint(0,0)), helptext( QPoint() ) );
00378 clear();
00379 KateCmd::self()->appendHistory( cmd );
00380 m_histpos = KateCmd::self()->historyLength();
00381 m_oldText = QString ();
00382 return;
00383 }
00384
00385 if (cmd.length () > 0)
00386 {
00387 KTextEditor::Command *p = KateCmd::self()->queryCommand (cmd);
00388
00389 m_oldText = cmd;
00390 m_msgMode = true;
00391
00392 if (p)
00393 {
00394 QString msg;
00395
00396 if (p->exec (m_view, cmd, msg))
00397 {
00398 KateCmd::self()->appendHistory( cmd );
00399 m_histpos = KateCmd::self()->historyLength();
00400 m_oldText = QString ();
00401
00402 if (msg.length() > 0)
00403 setText (i18n ("Success: ") + msg);
00404 else
00405 setText (i18n ("Success"));
00406 }
00407 else
00408 {
00409 if (msg.length() > 0)
00410 setText (i18n ("Error: ") + msg);
00411 else
00412 setText (i18n ("Command \"%1\" failed.", cmd));
00413 KNotification::beep();
00414 }
00415 }
00416 else
00417 {
00418 setText (i18n ("No such command: \"%1\"", cmd));
00419 KNotification::beep();
00420 }
00421 }
00422
00423
00424 if ( m_oldCompletionObject )
00425 {
00426 KCompletion *c = completionObject();
00427 setCompletionObject( m_oldCompletionObject );
00428 m_oldCompletionObject = 0;
00429 delete c;
00430 c = 0;
00431 }
00432 m_command = 0;
00433 m_cmdend = 0;
00434
00435 m_view->setFocus ();
00436 QTimer::singleShot( 4000, this, SLOT(hideBar()) );
00437 }
00438
00439 void KateCmdLineEdit::hideBar ()
00440 {
00441 if ( ! hasFocus() ) {
00442 m_bar->hideBar ();
00443 }
00444 }
00445
00446 void KateCmdLineEdit::focusInEvent ( QFocusEvent *ev )
00447 {
00448 if (m_msgMode)
00449 {
00450 m_msgMode = false;
00451 setText (m_oldText);
00452 selectAll();
00453 }
00454
00455 KLineEdit::focusInEvent (ev);
00456 }
00457
00458 void KateCmdLineEdit::keyPressEvent( QKeyEvent *ev )
00459 {
00460 if (ev->key() == Qt::Key_Escape)
00461 {
00462 m_view->setFocus ();
00463 hideBar();
00464 }
00465 else if ( ev->key() == Qt::Key_Up )
00466 fromHistory( true );
00467 else if ( ev->key() == Qt::Key_Down )
00468 fromHistory( false );
00469
00470 uint cursorpos = cursorPosition();
00471 KLineEdit::keyPressEvent (ev);
00472
00473
00474 if ( ! m_cmdend || cursorpos <= m_cmdend )
00475 {
00476 QChar c;
00477 if ( ! ev->text().isEmpty() )
00478 c = ev->text()[0];
00479
00480 if ( ! m_cmdend && ! c.isNull() )
00481 {
00482 if ( ! c.isLetterOrNumber() && c != '-' && c != '_' )
00483 {
00484 m_command = KateCmd::self()->queryCommand( text().trimmed() );
00485 if ( m_command )
00486 {
00487
00488
00489
00490 m_cmdend = cursorpos;
00491
00492 }
00493 else
00494 m_cmdend = 0;
00495 }
00496 }
00497 else
00498 {
00499 kDebug(13025)<<"keypress in commandline: \\W -- text is "<<text();
00500 m_command = KateCmd::self()->queryCommand( text().trimmed() );
00501 if ( m_command )
00502 {
00503
00504 QString t = text();
00505 m_cmdend = 0;
00506 bool b = false;
00507 for ( ; (int)m_cmdend < t.length(); m_cmdend++ )
00508 {
00509 if ( t[m_cmdend].isLetter() )
00510 b = true;
00511 if ( b && ( ! t[m_cmdend].isLetterOrNumber() && t[m_cmdend] != '-' && t[m_cmdend] != '_' ) )
00512 break;
00513 }
00514
00515 if ( c == ':' && cursorpos == m_cmdend )
00516 {
00517
00518
00519 }
00520 }
00521 else
00522 {
00523
00524 if ( m_oldCompletionObject )
00525 {
00526 KCompletion *c = completionObject();
00527 setCompletionObject( m_oldCompletionObject );
00528 m_oldCompletionObject = 0;
00529 delete c;
00530 c = 0;
00531 }
00532
00533 m_cmdend = 0;
00534 }
00535 }
00536
00537
00538 if ( m_command )
00539 {
00540
00541 KTextEditor::CommandExtension *ce = dynamic_cast<KTextEditor::CommandExtension*>(m_command);
00542 if ( ce )
00543 {
00544 KCompletion *cmpl = ce->completionObject( m_view, text().left( m_cmdend ).trimmed() );
00545 if ( cmpl )
00546 {
00547
00548
00549
00550
00551 if ( ! m_oldCompletionObject )
00552 m_oldCompletionObject = completionObject();
00553
00554 setCompletionObject( cmpl );
00555 }
00556 }
00557 }
00558 }
00559 else if ( m_command )
00560 {
00561 KTextEditor::CommandExtension *ce = dynamic_cast<KTextEditor::CommandExtension*>( m_command );
00562 if ( ce && ce->wantsToProcessText( text().left( m_cmdend ).trimmed() )
00563 && ! ( ev->text().isNull() || ev->text().isEmpty() ) )
00564 ce->processText( m_view, text() );
00565 }
00566 }
00567
00568 void KateCmdLineEdit::fromHistory( bool up )
00569 {
00570 if ( ! KateCmd::self()->historyLength() )
00571 return;
00572
00573 QString s;
00574
00575 if ( up )
00576 {
00577 if ( m_histpos > 0 )
00578 {
00579 m_histpos--;
00580 s = KateCmd::self()->fromHistory( m_histpos );
00581 }
00582 }
00583 else
00584 {
00585 if ( m_histpos < ( KateCmd::self()->historyLength() - 1 ) )
00586 {
00587 m_histpos++;
00588 s = KateCmd::self()->fromHistory( m_histpos );
00589 }
00590 else
00591 {
00592 m_histpos = KateCmd::self()->historyLength();
00593 setText( m_oldText );
00594 }
00595 }
00596 if ( ! s.isEmpty() )
00597 {
00598
00599 setText( s );
00600 static QRegExp reCmd = QRegExp(".*[\\w\\-]+(?:[^a-zA-Z0-9_-]|:\\w+)(.*)");
00601 if ( reCmd.indexIn( text() ) == 0 )
00602 setSelection( text().length() - reCmd.cap(1).length(), reCmd.cap(1).length() );
00603 }
00604 }
00605
00606
00607
00608 using namespace KTextEditor;
00609
00610 const int halfIPW = 8;
00611
00612 KateIconBorder::KateIconBorder ( KateViewInternal* internalView, QWidget *parent )
00613 : QWidget(parent)
00614 , m_view( internalView->m_view )
00615 , m_doc( internalView->m_doc )
00616 , m_viewInternal( internalView )
00617 , m_iconBorderOn( false )
00618 , m_lineNumbersOn( false )
00619 , m_foldingMarkersOn( false )
00620 , m_dynWrapIndicatorsOn( false )
00621 , m_annotationBorderOn( false )
00622 , m_dynWrapIndicators( 0 )
00623 , m_cachedLNWidth( 0 )
00624 , m_maxCharWidth( 0 )
00625 , iconPaneWidth (16)
00626 , m_annotationBorderWidth (6)
00627 , m_foldingRange(0)
00628 , m_lastBlockLine(-1)
00629 {
00630
00631 for (int i=0;i<MAXFOLDINGCOLORS;i++) {
00632 int r,g,b;
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 if (i==0) {
00649 r=0xff;
00650 g=0xff;
00651 b=0xff;
00652 } else
00653 if (i<3) {
00654 r=0xff;
00655 g=0xff;
00656 b=0xff-0x40-0x40*i;
00657 } else if (i<7) {
00658 r=0xff-0x40*(i-3); g=0xff;b=0;
00659 } else if (i<15) {
00660
00661
00662 r=0;g=0xff-0x10*(i-7);b=0;
00663 } else {
00664
00665 r=0;g=0;b=0;
00666 }
00667 m_foldingColors[i]=QBrush(QColor(r,g,b,0x88),Qt::SolidPattern );
00668 m_foldingColorsSolid[i]=QBrush(QColor(r,g,b),Qt::SolidPattern);
00669 }
00670
00671 setAttribute( Qt::WA_StaticContents );
00672 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum );
00673 setMouseTracking(true);
00674 m_doc->setMarkDescription( MarkInterface::markType01, i18n("Bookmark") );
00675 m_doc->setMarkPixmap( MarkInterface::markType01, KIcon("bookmarks").pixmap(16, 16) );
00676
00677 updateFont();
00678 }
00679
00680 KateIconBorder::~KateIconBorder() {delete m_foldingRange;}
00681
00682 void KateIconBorder::setIconBorderOn( bool enable )
00683 {
00684 if( enable == m_iconBorderOn )
00685 return;
00686
00687 m_iconBorderOn = enable;
00688
00689 updateGeometry();
00690
00691 QTimer::singleShot( 0, this, SLOT(update()) );
00692 }
00693
00694 void KateIconBorder::setAnnotationBorderOn( bool enable )
00695 {
00696 if( enable == m_annotationBorderOn )
00697 return;
00698
00699 m_annotationBorderOn = enable;
00700
00701 emit m_view->annotationBorderVisibilityChanged(m_view, enable);
00702
00703 updateGeometry();
00704 }
00705
00706 void KateIconBorder::removeAnnotationHovering()
00707 {
00708
00709 if (m_annotationBorderOn && !m_hoveredAnnotationText.isEmpty())
00710 {
00711 m_hoveredAnnotationText = QString();
00712 hideAnnotationTooltip();
00713 QTimer::singleShot( 0, this, SLOT(update()) );
00714 }
00715 }
00716
00717 void KateIconBorder::setLineNumbersOn( bool enable )
00718 {
00719 if( enable == m_lineNumbersOn )
00720 return;
00721
00722 m_lineNumbersOn = enable;
00723 m_dynWrapIndicatorsOn = (m_dynWrapIndicators == 1) ? enable : m_dynWrapIndicators;
00724
00725 updateGeometry();
00726
00727 QTimer::singleShot( 0, this, SLOT(update()) );
00728 }
00729
00730 void KateIconBorder::setDynWrapIndicators( int state )
00731 {
00732 if (state == m_dynWrapIndicators )
00733 return;
00734
00735 m_dynWrapIndicators = state;
00736 m_dynWrapIndicatorsOn = (state == 1) ? m_lineNumbersOn : state;
00737
00738 updateGeometry ();
00739
00740 QTimer::singleShot( 0, this, SLOT(update()) );
00741 }
00742
00743 void KateIconBorder::setFoldingMarkersOn( bool enable )
00744 {
00745 if( enable == m_foldingMarkersOn )
00746 return;
00747
00748 m_foldingMarkersOn = enable;
00749
00750 updateGeometry();
00751
00752 QTimer::singleShot( 0, this, SLOT(update()) );
00753 }
00754
00755 QSize KateIconBorder::sizeHint() const
00756 {
00757 int w = 0;
00758
00759 if (m_iconBorderOn)
00760 w += iconPaneWidth + 1;
00761
00762 if (m_annotationBorderOn)
00763 {
00764 w += m_annotationBorderWidth + 1;
00765 }
00766
00767 if (m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn)) {
00768 w += lineNumberWidth() + 1;
00769 }
00770
00771 if (m_foldingMarkersOn)
00772 w += iconPaneWidth + 1;
00773
00774 w += 4;
00775
00776 return QSize( w, 0 );
00777 }
00778
00779
00780
00781 void KateIconBorder::updateFont()
00782 {
00783 QFontMetrics fm = m_view->renderer()->config()->fontMetrics();
00784 m_maxCharWidth = 0;
00785
00786
00787 for (int i = 48; i < 58; i++) {
00788 int charWidth = fm.width( QChar(i) );
00789 m_maxCharWidth = qMax(m_maxCharWidth, charWidth);
00790 }
00791
00792
00793 iconPaneWidth = fm.height();
00794
00795 updateGeometry();
00796
00797 QTimer::singleShot( 0, this, SLOT(update()) );
00798 }
00799
00800 int KateIconBorder::lineNumberWidth() const
00801 {
00802 int width = m_lineNumbersOn ? ((int)log10((double)(m_view->doc()->lines())) + 1) * m_maxCharWidth + 4 : 0;
00803
00804 if (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) {
00805
00806 width = qMax(16 + 4, width);
00807
00808 if (m_cachedLNWidth != width || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor()) {
00809 int w = 16;
00810 int h = m_view->renderer()->config()->fontMetrics().height();
00811
00812 QSize newSize(w, h);
00813 if ((m_arrow.size() != newSize || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor()) && !newSize.isEmpty()) {
00814 m_arrow = QPixmap(newSize);
00815
00816 QPainter p(&m_arrow);
00817 p.fillRect( 0, 0, w, h, m_view->renderer()->config()->iconBarColor() );
00818
00819 h = m_view->renderer()->config()->fontMetrics().ascent();
00820
00821 p.setPen(m_view->renderer()->config()->lineNumberColor());
00822
00823 QPainterPath path;
00824 path.moveTo(w/2, h/2);
00825 path.lineTo(w/2, 0);
00826 path.lineTo(w/4, h/4);
00827 path.lineTo(0, 0);
00828 path.lineTo(0, h/2);
00829 path.lineTo(w/2, h-1);
00830 path.lineTo(w*3/4, h-1);
00831 path.lineTo(w-1, h*3/4);
00832 path.lineTo(w*3/4, h/2);
00833 path.lineTo(0, h/2);
00834 p.drawPath(path);
00835 }
00836 }
00837 }
00838
00839 return width;
00840 }
00841
00842 const QBrush& KateIconBorder::foldingColor(KateLineInfo *info,int realLine, bool solid) {
00843 int depth;
00844 if (info!=0) {
00845 depth=info->depth;
00846 } else {
00847 KateLineInfo tmp;
00848 m_doc->lineInfo(&tmp,realLine);
00849 depth=tmp.depth;
00850 }
00851
00852 if (solid) {
00853 if (depth<MAXFOLDINGCOLORS)
00854 return m_foldingColorsSolid[depth];
00855 else
00856 return m_foldingColorsSolid[MAXFOLDINGCOLORS-1];
00857 } else {
00858 if (depth<MAXFOLDINGCOLORS)
00859 return m_foldingColors[depth];
00860 else
00861 return m_foldingColors[MAXFOLDINGCOLORS-1];
00862 }
00863
00864 }
00865
00866 void KateIconBorder::paintEvent(QPaintEvent* e)
00867 {
00868 paintBorder(e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
00869 }
00870
00871 static void paintTriangle (QPainter &painter, const QColor &baseColor, int xOffset, int yOffset, int width, int height, bool open)
00872 {
00873 painter.setRenderHint(QPainter::Antialiasing);
00874
00875 qreal size = qMin (width, height);
00876
00877 QColor c = baseColor.dark ();
00878
00879
00880 if (c == baseColor)
00881 c = baseColor.light ();
00882
00883 QPen pen;
00884 pen.setJoinStyle (Qt::RoundJoin);
00885 pen.setColor (c);
00886 pen.setWidthF (1.5);
00887 painter.setPen ( pen );
00888
00889 painter.setBrush ( c );
00890
00891
00892 size *= 0.6;
00893
00894 qreal halfSize = size / 2;
00895 qreal halfSizeP = halfSize * 0.6;
00896 QPointF middle (xOffset + (qreal)width / 2, yOffset + (qreal)height / 2);
00897
00898 if (open)
00899 {
00900 QPointF points[3] = { middle+QPointF(-halfSize, -halfSizeP), middle+QPointF(halfSize, -halfSizeP), middle+QPointF(0, halfSizeP) };
00901 painter.drawConvexPolygon(points, 3);
00902 }
00903 else
00904 {
00905 QPointF points[3] = { middle+QPointF(-halfSizeP, -halfSize), middle+QPointF(-halfSizeP, halfSize), middle+QPointF(halfSizeP, 0) };
00906 painter.drawConvexPolygon(points, 3);
00907 }
00908
00909 painter.setRenderHint(QPainter::Antialiasing, false);
00910 }
00911
00912 void KateIconBorder::paintBorder (int , int y, int , int height)
00913 {
00914 uint h = m_view->renderer()->config()->fontMetrics().height();
00915 uint startz = (y / h);
00916 uint endz = startz + 1 + (height / h);
00917 uint lineRangesSize = m_viewInternal->cache()->viewCacheLineCount();
00918
00919
00920 int m_px = (h - 11) / 2;
00921 if (m_px < 0)
00922 m_px = 0;
00923
00924 int lnWidth( 0 );
00925 if ( m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) )
00926 {
00927 lnWidth = lineNumberWidth();
00928 if ( lnWidth != m_cachedLNWidth || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor() )
00929 {
00930
00931
00932
00933
00934 m_cachedLNWidth = lnWidth;
00935 m_oldBackgroundColor = m_view->renderer()->config()->iconBarColor();
00936 updateGeometry();
00937 update ();
00938 return;
00939 }
00940 }
00941
00942 int w( this->width() );
00943
00944 QPainter p ( this );
00945 p.setRenderHints (QPainter::TextAntialiasing);
00946 p.setFont ( m_view->renderer()->config()->font() );
00947
00948
00949 p.setPen ( m_view->renderer()->config()->lineNumberColor() );
00950 p.setBrush ( m_view->renderer()->config()->lineNumberColor() );
00951
00952 KateLineInfo oldInfo;
00953 if (startz < lineRangesSize)
00954 {
00955 if ((m_viewInternal->cache()->viewLine(startz).line()-1) < 0)
00956 oldInfo.topLevel = true;
00957 else
00958 m_doc->lineInfo(&oldInfo,m_viewInternal->cache()->viewLine(startz).line()-1);
00959 }
00960
00961 KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
00962 m_view->annotationModel() : m_doc->annotationModel();
00963
00964 for (uint z=startz; z <= endz; z++)
00965 {
00966 int y = h * z;
00967 int realLine = -1;
00968
00969 if (z < lineRangesSize)
00970 realLine = m_viewInternal->cache()->viewLine(z).line();
00971
00972 int lnX = 0;
00973
00974 p.fillRect( 0, y, w-4, h, m_view->renderer()->config()->iconBarColor() );
00975 p.fillRect( w-4, y, 4, h, m_view->renderer()->config()->backgroundColor() );
00976
00977
00978 if( m_iconBorderOn )
00979 {
00980 p.setPen ( m_view->renderer()->config()->lineNumberColor() );
00981 p.setBrush ( m_view->renderer()->config()->lineNumberColor() );
00982 p.drawLine(lnX+iconPaneWidth+1, y, lnX+iconPaneWidth+1, y+h);
00983
00984 if( (realLine > -1) && (m_viewInternal->cache()->viewLine(z).startCol() == 0) )
00985 {
00986 uint mrk ( m_doc->mark( realLine ) );
00987
00988 if ( mrk )
00989 {
00990 for( uint bit = 0; bit < 32; bit++ )
00991 {
00992 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes)(1<<bit);
00993 if( mrk & markType )
00994 {
00995 QPixmap px_mark (m_doc->markPixmap( markType ));
00996
00997 if (!px_mark.isNull())
00998 {
00999
01000 int x_px = (iconPaneWidth - px_mark.width()) / 2;
01001 if (x_px < 0)
01002 x_px = 0;
01003
01004 int y_px = (h - px_mark.height()) / 2;
01005 if (y_px < 0)
01006 y_px = 0;
01007
01008 p.drawPixmap( lnX+x_px, y+y_px, px_mark);
01009 }
01010 }
01011 }
01012 }
01013 }
01014
01015 lnX += iconPaneWidth + 2;
01016 }
01017
01018
01019 if( m_annotationBorderOn )
01020 {
01021
01022 p.setPen ( m_view->renderer()->config()->lineNumberColor() );
01023 p.setBrush ( m_view->renderer()->config()->lineNumberColor() );
01024
01025 int borderWidth = m_annotationBorderWidth;
01026 p.drawLine(lnX+borderWidth+1, y, lnX+borderWidth+1, y+h);
01027
01028 if( (realLine > -1) && model )
01029 {
01030
01031 QVariant text = model->data( realLine, Qt::DisplayRole );
01032 QVariant foreground = model->data( realLine, Qt::ForegroundRole );
01033 QVariant background = model->data( realLine, Qt::BackgroundRole );
01034
01035 if( background.isValid() )
01036 {
01037 p.fillRect( lnX, y, borderWidth + 1, h, background.value<QBrush>() );
01038 }
01039
01040 if( foreground.isValid() )
01041 {
01042 p.setBrush( foreground.value<QBrush>() );
01043 }
01044
01045
01046 if( m_hoveredAnnotationText == text.toString() )
01047 {
01048 p.drawLine( lnX, y, lnX, y+h );
01049 p.drawLine( lnX+borderWidth, y, lnX+borderWidth, y+h );
01050
01051 QVariant beforeText = model->data( realLine-1, Qt::DisplayRole );
01052 QVariant afterText = model->data( realLine+1, Qt::DisplayRole );
01053 if( (beforeText.isValid() && beforeText.canConvert<QString>()
01054 && text.isValid() && text.canConvert<QString>()
01055 && beforeText.toString() != text.toString() || realLine == 0)
01056 && m_viewInternal->cache()->viewLine(z).viewLine() == 0)
01057 {
01058 p.drawLine( lnX+1, y, lnX+borderWidth, y );
01059 }
01060
01061 if( ((afterText.isValid() && afterText.canConvert<QString>()
01062 && text.isValid() && text.canConvert<QString>()
01063 && afterText.toString() != text.toString())
01064 || realLine == m_view->doc()->lines() - 1)
01065 && m_viewInternal->cache()->viewLine(z).viewLine() == m_viewInternal->cache()->viewLineCount(realLine)-1)
01066 {
01067 p.drawLine( lnX+1, y+h-1, lnX+borderWidth, y+h-1 );
01068 }
01069 }
01070 if( foreground.isValid() )
01071 {
01072 QPen pen = p.pen();
01073 pen.setWidth( 1 );
01074 p.setPen( pen );
01075 }
01076
01077
01078 if( text.isValid() && text.canConvert<QString>() && (m_viewInternal->cache()->viewLine(z).startCol() == 0) )
01079 {
01080 p.drawText( lnX+3, y, borderWidth-3, h, Qt::AlignLeft|Qt::AlignVCenter, text.toString() );
01081 }
01082 }
01083
01084
01085 lnX += borderWidth + 2;
01086
01087 p.setPen ( m_view->renderer()->config()->lineNumberColor() );
01088 p.setBrush ( m_view->renderer()->config()->lineNumberColor() );
01089 }
01090
01091
01092 if( m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) )
01093 {
01094 if (realLine > -1)
01095 if (m_viewInternal->cache()->viewLine(z).startCol() == 0) {
01096 if (m_lineNumbersOn)
01097 p.drawText( lnX, y, lnWidth-4, h, Qt::AlignRight|Qt::AlignVCenter, QString("%1").arg( realLine + 1 ) );
01098 } else if (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) {
01099 p.drawPixmap(lnX + lnWidth - m_arrow.width() - 2, y, m_arrow);
01100 }
01101
01102 lnX += lnWidth + 2;
01103 }
01104
01105
01106 if( m_foldingMarkersOn )
01107 {
01108 if( realLine > -1 )
01109 {
01110 KateLineInfo info;
01111 m_doc->lineInfo(&info,realLine);
01112
01113 QBrush brush (foldingColor(&info,realLine,true));
01114 p.fillRect(lnX, y, iconPaneWidth, h, brush);
01115
01116 if (!info.topLevel)
01117 {
01118 if (info.startsVisibleBlock && (m_viewInternal->cache()->viewLine(z).startCol() == 0))
01119 {
01120 paintTriangle (p, brush.color(), lnX, y, iconPaneWidth, h, true);
01121 }
01122 else if (info.startsInVisibleBlock && m_viewInternal->cache()->viewLine(z).startCol() == 0)
01123 {
01124 paintTriangle (p, brush.color(), lnX, y, iconPaneWidth, h, false);
01125 }
01126 else
01127 {
01128
01129
01130
01131
01132 }
01133 }
01134
01135 oldInfo = info;
01136 }
01137
01138 lnX += iconPaneWidth + 2;
01139 }
01140 }
01141 }
01142
01143 KateIconBorder::BorderArea KateIconBorder::positionToArea( const QPoint& p ) const
01144 {
01145 int x = 0;
01146 if( m_iconBorderOn ) {
01147 x += iconPaneWidth;
01148 if( p.x() <= x )
01149 return IconBorder;
01150 }
01151 if( this->m_annotationBorderOn ) {
01152 x += m_annotationBorderWidth;
01153 if( p.x() <= x )
01154 return AnnotationBorder;
01155 }
01156 if( m_lineNumbersOn || m_dynWrapIndicators ) {
01157 x += lineNumberWidth();
01158 if( p.x() <= x )
01159 return LineNumbers;
01160 }
01161 if( m_foldingMarkersOn ) {
01162 x += iconPaneWidth;
01163 if( p.x() <= x )
01164 return FoldingMarkers;
01165 }
01166 return None;
01167 }
01168
01169 void KateIconBorder::mousePressEvent( QMouseEvent* e )
01170 {
01171 const KateTextLayout& t = m_viewInternal->yToKateTextLayout(e->y());
01172 if (t.isValid()) {
01173 m_lastClickedLine = t.line();
01174 if ( positionToArea( e->pos() ) != IconBorder && positionToArea( e->pos() ) != AnnotationBorder )
01175 {
01176 QMouseEvent forward( QEvent::MouseButtonPress,
01177 QPoint( 0, e->y() ), e->button(), e->buttons(),e->modifiers() );
01178 m_viewInternal->mousePressEvent( &forward );
01179 }
01180 return e->accept();
01181 }
01182
01183 QWidget::mousePressEvent(e);
01184 }
01185
01186 void KateIconBorder::showBlock(int line)
01187 {
01188 if (line == m_lastBlockLine) return;
01189 m_lastBlockLine = line;
01190
01191
01192 KTextEditor::Range newRange = KTextEditor::Range::invalid();
01193 KateCodeFoldingTree *tree = m_doc->foldingTree();
01194 if (tree) {
01195 KateCodeFoldingNode *node = tree->findNodeForLine(line);
01196 KTextEditor::Cursor beg;
01197 KTextEditor::Cursor end;
01198 if (node != tree->rootNode () && node->getBegin(tree, &beg) && node->getEnd(tree, &end)) {
01199 newRange = KTextEditor::Range(beg, end);
01200 }
01201 }
01202
01203 if (newRange.isValid() && m_foldingRange && *m_foldingRange == newRange) {
01204
01205 return;
01206 } else {
01207 delete m_foldingRange;
01208 m_foldingRange = 0;
01209 }
01210
01211 if (newRange.isValid()) {
01212 kDebug(13025) << "new folding hl-range:" << newRange;
01213 m_foldingRange = m_doc->newSmartRange(newRange);
01214 static_cast<KateSmartRange*>(m_foldingRange)->setInternal();
01215 KTextEditor::Attribute::Ptr attr(new KTextEditor::Attribute());
01216 attr->setBackground(foldingColor(0, line, false));
01217 m_foldingRange->setAttribute(attr);
01218 m_doc->addHighlightToView(m_view, m_foldingRange, false);
01219 }
01220 }
01221
01222 void KateIconBorder::hideBlock() {
01223 m_lastBlockLine=-1;
01224 delete m_foldingRange;
01225 m_foldingRange = 0;
01226 }
01227
01228 void KateIconBorder::leaveEvent(QEvent *event)
01229 {
01230 hideBlock();
01231 removeAnnotationHovering();
01232
01233 QWidget::leaveEvent(event);
01234 }
01235
01236 void KateIconBorder::mouseMoveEvent( QMouseEvent* e )
01237 {
01238 const KateTextLayout& t = m_viewInternal->yToKateTextLayout(e->y());
01239 if (t.isValid()) {
01240 if ( positionToArea( e->pos() ) == FoldingMarkers) showBlock(t.line());
01241 else hideBlock();
01242 if ( positionToArea( e->pos() ) == AnnotationBorder )
01243 {
01244 KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01245 m_view->annotationModel() : m_doc->annotationModel();
01246 if (model)
01247 {
01248 m_hoveredAnnotationText = model->data( t.line(), Qt::DisplayRole ).toString();
01249 showAnnotationTooltip( t.line(), e->globalPos() );
01250 QTimer::singleShot( 0, this, SLOT(update()) );
01251 }
01252 }
01253 else
01254 {
01255 m_hoveredAnnotationText = QString();
01256 hideAnnotationTooltip();
01257 QTimer::singleShot( 0, this, SLOT(update()) );
01258 }
01259 if ( positionToArea( e->pos() ) != IconBorder )
01260 {
01261 QMouseEvent forward( QEvent::MouseMove,
01262 QPoint( 0, e->y() ), e->button(), e->buttons(),e->modifiers() );
01263 m_viewInternal->mouseMoveEvent( &forward );
01264 }
01265 }
01266 else
01267 {
01268
01269 removeAnnotationHovering();
01270 }
01271
01272 QWidget::mouseMoveEvent(e);
01273 }
01274
01275 void KateIconBorder::mouseReleaseEvent( QMouseEvent* e )
01276 {
01277 int cursorOnLine = m_viewInternal->yToKateTextLayout(e->y()).line();
01278
01279 if (cursorOnLine == m_lastClickedLine &&
01280 cursorOnLine <= m_doc->lastLine() )
01281 {
01282 BorderArea area = positionToArea( e->pos() );
01283 if( area == IconBorder) {
01284 if (e->button() == Qt::LeftButton) {
01285 if( m_doc->editableMarks() & KateViewConfig::global()->defaultMarkType() ) {
01286 if( m_doc->mark( cursorOnLine ) & KateViewConfig::global()->defaultMarkType() )
01287 m_doc->removeMark( cursorOnLine, KateViewConfig::global()->defaultMarkType() );
01288 else
01289 m_doc->addMark( cursorOnLine, KateViewConfig::global()->defaultMarkType() );
01290 } else {
01291 showMarkMenu( cursorOnLine, QCursor::pos() );
01292 }
01293 }
01294 else
01295 if (e->button() == Qt::RightButton) {
01296 showMarkMenu( cursorOnLine, QCursor::pos() );
01297 }
01298 }
01299
01300 if ( area == FoldingMarkers) {
01301 KateLineInfo info;
01302 m_doc->lineInfo(&info,cursorOnLine);
01303 if ((info.startsVisibleBlock) || (info.startsInVisibleBlock)) {
01304 emit toggleRegionVisibility(cursorOnLine);
01305 }
01306 }
01307
01308 if ( area == AnnotationBorder ) {
01309 if( e->button() == Qt::LeftButton && KGlobalSettings::singleClick() ) {
01310 emit m_view->annotationActivated( m_view, cursorOnLine );
01311 } else if ( e->button() == Qt::RightButton ) {
01312 showAnnotationMenu( cursorOnLine, e->globalPos() );
01313 }
01314 }
01315 }
01316
01317 QMouseEvent forward( QEvent::MouseButtonRelease,
01318 QPoint( 0, e->y() ), e->button(), e->buttons(),e->modifiers() );
01319 m_viewInternal->mouseReleaseEvent( &forward );
01320 }
01321
01322 void KateIconBorder::mouseDoubleClickEvent( QMouseEvent* e )
01323 {
01324 int cursorOnLine = m_viewInternal->yToKateTextLayout(e->y()).line();
01325
01326 if (cursorOnLine == m_lastClickedLine &&
01327 cursorOnLine <= m_doc->lastLine() )
01328 {
01329 BorderArea area = positionToArea( e->pos() );
01330 if( area == AnnotationBorder && !KGlobalSettings::singleClick() ) {
01331 emit m_view->annotationActivated( m_view, cursorOnLine );
01332 }
01333 }
01334 QMouseEvent forward( QEvent::MouseButtonDblClick,
01335 QPoint( 0, e->y() ), e->button(), e->buttons(),e->modifiers() );
01336 m_viewInternal->mouseDoubleClickEvent( &forward );
01337 }
01338
01339 void KateIconBorder::showMarkMenu( uint line, const QPoint& pos )
01340 {
01341 KMenu markMenu;
01342 KMenu selectDefaultMark;
01343
01344 QVector<int> vec( 33 );
01345 int i=1;
01346
01347 for( uint bit = 0; bit < 32; bit++ ) {
01348 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes)(1<<bit);
01349 if( !(m_doc->editableMarks() & markType) )
01350 continue;
01351
01352 QAction *mA;
01353 QAction *dMA;
01354 if( !m_doc->markDescription( markType ).isEmpty() ) {
01355 mA=markMenu.addAction( m_doc->markDescription( markType ));
01356 dMA=selectDefaultMark.addAction( m_doc->markDescription( markType ));
01357 } else {
01358 mA=markMenu.addAction( i18n("Mark Type %1", bit + 1 ));
01359 dMA=selectDefaultMark.addAction( i18n("Mark Type %1", bit + 1 ));
01360 }
01361 mA->setData(i);
01362 mA->setCheckable(true);
01363 dMA->setData(i+100);
01364 dMA->setCheckable(true);
01365 if( m_doc->mark( line ) & markType )
01366 mA->setChecked(true );
01367
01368 if( markType & KateViewConfig::global()->defaultMarkType() )
01369 dMA->setChecked(true );
01370
01371 vec[i++] = markType;
01372 }
01373
01374 if( markMenu.actions().count() == 0 )
01375 return;
01376
01377 if( markMenu.actions().count() > 1 )
01378 markMenu.addAction( i18n("Set Default Mark Type" ))->setMenu(&selectDefaultMark);
01379
01380 QAction *rA = markMenu.exec( pos );
01381 if( !rA )
01382 return;
01383 int result=rA->data().toInt();
01384 if ( result > 100)
01385 {
01386 KateViewConfig::global()->setDefaultMarkType (vec[result-100]);
01387
01388 KConfigGroup cg(KGlobal::config(), "Kate View Defaults");
01389 KateViewConfig::global()->writeConfig(cg);
01390 }
01391 else
01392 {
01393 MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes) vec[result];
01394 if( m_doc->mark( line ) & markType ) {
01395 m_doc->removeMark( line, markType );
01396 } else {
01397 m_doc->addMark( line, markType );
01398 }
01399 }
01400 }
01401
01402 void KateIconBorder::showAnnotationTooltip( int line, const QPoint& pos )
01403 {
01404 KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01405 m_view->annotationModel() : m_doc->annotationModel();
01406
01407 if( model )
01408 {
01409 QVariant data = model->data( line, Qt::ToolTipRole );
01410 QString tip = data.toString();
01411 if (!tip.isEmpty())
01412 QToolTip::showText( pos, data.toString(), this );
01413 }
01414 }
01415
01416
01417 int KateIconBorder::annotationLineWidth( int line )
01418 {
01419 KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01420 m_view->annotationModel() : m_doc->annotationModel();
01421
01422 if( model )
01423 {
01424 QVariant data = model->data( line, Qt::DisplayRole );
01425 return data.toString().length() * m_maxCharWidth + 8;
01426 }
01427 return 8;
01428 }
01429
01430 void KateIconBorder::updateAnnotationLine( int line )
01431 {
01432 if( annotationLineWidth(line) > m_annotationBorderWidth )
01433 {
01434 m_annotationBorderWidth = annotationLineWidth(line);
01435 updateGeometry();
01436
01437 QTimer::singleShot( 0, this, SLOT(update()) );
01438 }
01439 }
01440
01441 void KateIconBorder::showAnnotationMenu( int line, const QPoint& pos)
01442 {
01443 KMenu menu;
01444 QAction a("Disable Annotation Bar", &menu);
01445 menu.addAction(&a);
01446 emit m_view->annotationContextMenuAboutToShow( m_view, &menu, line );
01447 if (menu.exec(pos) == &a)
01448 m_view->setAnnotationBorderVisible(false);
01449 }
01450
01451 void KateIconBorder::hideAnnotationTooltip()
01452 {
01453 QToolTip::hideText();
01454 }
01455
01456 void KateIconBorder::updateAnnotationBorderWidth( )
01457 {
01458 m_annotationBorderWidth = 6;
01459 KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01460 m_view->annotationModel() : m_doc->annotationModel();
01461
01462 if( model ) {
01463 for( int i = 0; i < m_view->doc()->lines(); i++ ) {
01464 int curwidth = annotationLineWidth( i );
01465 if( curwidth > m_annotationBorderWidth )
01466 m_annotationBorderWidth = curwidth;
01467 }
01468 }
01469
01470 updateGeometry();
01471
01472 QTimer::singleShot( 0, this, SLOT(update()) );
01473 }
01474
01475
01476
01477 void KateIconBorder::annotationModelChanged( KTextEditor::AnnotationModel * oldmodel, KTextEditor::AnnotationModel * newmodel )
01478 {
01479 if( oldmodel )
01480 {
01481 oldmodel->disconnect( this );
01482 }
01483 if( newmodel )
01484 {
01485 connect( newmodel, SIGNAL(reset()), this, SLOT(updateAnnotationBorderWidth()) );
01486 connect( newmodel, SIGNAL(lineChanged( int )), this, SLOT(updateAnnotationLine( int )) );
01487 }
01488 updateAnnotationBorderWidth();
01489 }
01490
01491
01492
01493
01494 KateViewEncodingAction::KateViewEncodingAction(KateDocument *_doc, KateView *_view, const QString& text, QObject *parent)
01495 : KCodecAction(text, parent,true), doc(_doc), view (_view)
01496 {
01497 connect(this,SIGNAL(triggered(KEncodingDetector::AutoDetectScript)),this,SLOT(setScriptForEncodingAutoDetection(KEncodingDetector::AutoDetectScript)));
01498 connect(this,SIGNAL(triggered(const QString&)),this,SLOT(setEncoding(const QString&)));
01499 connect(menu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
01500 }
01501
01502 void KateViewEncodingAction::slotAboutToShow()
01503 {
01504 if (doc->scriptForEncodingAutoDetection()==KEncodingDetector::None)
01505 {
01506 if (!setCurrentCodec(doc->encoding()))
01507 kWarning() << "KateViewEncodingAction: cannot set current "<<doc->encoding();
01508 }
01509 else
01510 setCurrentAutoDetectScript(doc->scriptForEncodingAutoDetection());
01511 }
01512
01513 void KateViewEncodingAction::setEncoding (const QString &e)
01514 {
01515 doc->setEncoding(e);
01516
01517
01518 view->reloadFile();
01519
01520 }
01521 void KateViewEncodingAction::setScriptForEncodingAutoDetection (KEncodingDetector::AutoDetectScript script)
01522 {
01523 if (script==KEncodingDetector::SemiautomaticDetection)
01524 {
01525 doc->setEncoding("");
01526 #ifdef DECODE_DEBUG
01527 kWarning() << "KEncodingDetector::SemiautomaticDetection " <<doc->encoding();
01528 #endif
01529 }
01530 else
01531 doc->setScriptForEncodingAutoDetection(script);
01532 view->reloadFile();
01533 }
01534
01535
01536
01537
01538 KateViewBarWidget::KateViewBarWidget (KateViewBar *viewBar)
01539 : QWidget (viewBar), m_viewBar (viewBar)
01540 {
01541 m_viewBar->addBarWidget (this);
01542
01543 QHBoxLayout *layout = new QHBoxLayout;
01544
01545
01546 layout->setMargin(2);
01547
01548
01549 QToolButton *hideButton = new QToolButton(this);
01550 hideButton->setAutoRaise(true);
01551 hideButton->setIcon(KIcon("dialog-close"));
01552 connect(hideButton, SIGNAL(clicked()), this, SLOT(hideBar()));
01553 layout->addWidget(hideButton);
01554 layout->setAlignment( hideButton, Qt::AlignLeft|Qt::AlignTop );
01555
01556
01557 m_centralWidget = new QWidget ();
01558 layout->addWidget(m_centralWidget);
01559
01560 setLayout(layout);
01561 setFocusProxy(m_centralWidget);
01562 }
01563
01564 void KateViewBarWidget::showBar ()
01565 {
01566 m_viewBar->showBarWidget (this);
01567 }
01568
01569 void KateViewBarWidget::hideBar ()
01570 {
01571
01572 if (!hideIsTriggered ())
01573 return;
01574
01575 m_viewBar->hideBarWidget ();
01576 }
01577
01578
01579
01580 KateStackedLayout::KateStackedLayout(QWidget* parent)
01581 : QStackedLayout(parent)
01582 {}
01583
01584 QSize KateStackedLayout::sizeHint() const
01585 {
01586 if (currentWidget())
01587 return currentWidget()->sizeHint();
01588 return QStackedLayout::sizeHint();
01589 }
01590
01591 QSize KateStackedLayout::minimumSize() const
01592 {
01593 if (currentWidget())
01594 return currentWidget()->minimumSize();
01595 return QStackedLayout::minimumSize();
01596 }
01597
01598
01599
01600 KateViewBar::KateViewBar (KateView *view)
01601 : QWidget (view), m_view (view)
01602 {
01603 m_stack = new KateStackedLayout(this);
01604 hide ();
01605 }
01606
01607 void KateViewBar::addBarWidget (KateViewBarWidget *newBarWidget)
01608 {
01609
01610 m_stack->addWidget (newBarWidget);
01611
01612 kDebug(13025)<<"add barwidget " << newBarWidget;
01613 }
01614
01615 void KateViewBar::showBarWidget (KateViewBarWidget *barWidget)
01616 {
01617
01618 m_stack->setCurrentWidget (barWidget);
01619 kDebug(13025)<<"show barwidget " << barWidget;
01620 show ();
01621 }
01622
01623 void KateViewBar::hideBarWidget ()
01624 {
01625 hide();
01626 kDebug(13025)<<"hide barwidget";
01627 }
01628
01629 void KateViewBar::keyPressEvent(QKeyEvent* event)
01630 {
01631 if (event->key() == Qt::Key_Escape) {
01632 hideBarWidget();
01633 return;
01634 }
01635 QWidget::keyPressEvent(event);
01636
01637 }
01638
01639 void KateViewBar::hideEvent(QHideEvent* event)
01640 {
01641 if (!event->spontaneous())
01642 m_view->setFocus();
01643 }
01644
01645
01646
01647
01648
01649
01650