• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Kate

kateviewhelpers.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2007 Mirko Stocker <me@misto.ch>
00003    Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
00004    Copyright (C) 2001 Anders Lund <anders@alweb.dk>
00005    Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License version 2 as published by the Free Software Foundation.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "kateviewhelpers.h"
00023 
00024 #include "katecmd.h"
00025 #include <ktexteditor/attribute.h>
00026 #include <ktexteditor/annotationinterface.h>
00027 #include <ktexteditor/rangefeedback.h>
00028 #include <ktexteditor/containerinterface.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 #include "kateglobal.h"
00039 
00040 #include <kapplication.h>
00041 #include <kcharsets.h>
00042 #include <kcolorscheme.h>
00043 #include <kcolorutils.h>
00044 #include <kdebug.h>
00045 #include <kglobalsettings.h>
00046 #include <klocale.h>
00047 #include <knotification.h>
00048 #include <kglobal.h>
00049 #include <kmenu.h>
00050 #include <kiconloader.h>
00051 #include <kconfiggroup.h>
00052 
00053 #include <QtAlgorithms>
00054 #include <QVariant>
00055 #include <QtCore/QTextCodec>
00056 #include <QtGui/QCursor>
00057 #include <QtGui/QMenu>
00058 #include <QtGui/QPainter>
00059 #include <QtGui/QStyle>
00060 #include <QtCore/QTimer>
00061 #include <QtCore/QRegExp>
00062 #include <QtCore/QTextCodec>
00063 #include <QtGui/QKeyEvent>
00064 #include <QtGui/QPainterPath>
00065 #include <QtGui/QStyleOption>
00066 #include <QtGui/QPalette>
00067 #include <QtGui/QPen>
00068 #include <QtGui/QBoxLayout>
00069 #include <QtGui/QToolButton>
00070 #include <QtGui/QToolTip>
00071 #include <QtGui/QAction>
00072 
00073 #include <math.h>
00074 
00075 #include <kdebug.h>
00076 
00077 #include <QtGui/QWhatsThis>
00078 
00079 //BEGIN KateScrollBar
00080 KateScrollBar::KateScrollBar (Qt::Orientation orientation, KateViewInternal* parent)
00081   : QScrollBar (orientation, parent->m_view)
00082   , m_middleMouseDown (false)
00083   , m_view(parent->m_view)
00084   , m_doc(parent->m_doc)
00085   , m_viewInternal(parent)
00086   , m_topMargin(0)
00087   , m_bottomMargin(0)
00088   , m_savVisibleLines(0)
00089   , m_showMarks(false)
00090 {
00091   connect(this, SIGNAL(valueChanged(int)), this, SLOT(sliderMaybeMoved(int)));
00092   connect(m_doc, SIGNAL(marksChanged(KTextEditor::Document*)), this, SLOT(marksChanged()));
00093 
00094   styleChange(*style());
00095 }
00096 
00097 void KateScrollBar::mousePressEvent(QMouseEvent* e)
00098 {
00099   if (e->button() == Qt::MidButton)
00100     m_middleMouseDown = true;
00101 
00102   QScrollBar::mousePressEvent(e);
00103 
00104   redrawMarks();
00105 }
00106 
00107 void KateScrollBar::mouseReleaseEvent(QMouseEvent* e)
00108 {
00109   QScrollBar::mouseReleaseEvent(e);
00110 
00111   m_middleMouseDown = false;
00112 
00113   redrawMarks();
00114 }
00115 
00116 void KateScrollBar::mouseMoveEvent(QMouseEvent* e)
00117 {
00118   QScrollBar::mouseMoveEvent(e);
00119 
00120   if (e->buttons() | Qt::LeftButton)
00121     redrawMarks();
00122 }
00123 
00124 void KateScrollBar::paintEvent(QPaintEvent *e)
00125 {
00126   QScrollBar::paintEvent(e);
00127 
00128   QPainter painter(this);
00129 
00130   QStyleOptionSlider opt;
00131   opt.init(this);
00132   opt.subControls = QStyle::SC_None;
00133   opt.activeSubControls = QStyle::SC_None;
00134   opt.orientation = orientation();
00135   opt.minimum = minimum();
00136   opt.maximum = maximum();
00137   opt.sliderPosition = sliderPosition();
00138   opt.sliderValue = value();
00139   opt.singleStep = singleStep();
00140   opt.pageStep = pageStep();
00141 
00142   QRect rect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSlider, this);
00143 
00144   QHashIterator<int, QColor> it = m_lines;
00145   while (it.hasNext())
00146   {
00147     it.next();
00148     if (it.key() < rect.top() || it.key() > rect.bottom())
00149     {
00150       painter.setPen(it.value());
00151       painter.drawLine(0, it.key(), width(), it.key());
00152     }
00153   }
00154 }
00155 
00156 void KateScrollBar::resizeEvent(QResizeEvent *e)
00157 {
00158   QScrollBar::resizeEvent(e);
00159   recomputeMarksPositions();
00160 }
00161 
00162 void KateScrollBar::styleChange(QStyle &s)
00163 {
00164   QScrollBar::styleChange(s);
00165 
00166   // Calculate height of buttons
00167   QStyleOptionSlider opt;
00168   opt.init(this);
00169   opt.subControls = QStyle::SC_None;
00170   opt.activeSubControls = QStyle::SC_None;
00171   opt.orientation = this->orientation();
00172   opt.minimum = minimum();
00173   opt.maximum = maximum();
00174   opt.sliderPosition = sliderPosition();
00175   opt.sliderValue = value();
00176   opt.singleStep = singleStep();
00177   opt.pageStep = pageStep();
00178 
00179   m_topMargin = style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSubLine, this).height() + 2;
00180   m_bottomMargin = m_topMargin + style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarAddLine, this).height() + 1;
00181 
00182   recomputeMarksPositions();
00183 }
00184 
00185 void KateScrollBar::sliderChange ( SliderChange change )
00186 {
00187   // call parents implementation
00188   QScrollBar::sliderChange (change);
00189 
00190   if (change == QAbstractSlider::SliderValueChange)
00191   {
00192     redrawMarks();
00193   }
00194   else if (change == QAbstractSlider::SliderRangeChange)
00195   {
00196     recomputeMarksPositions();
00197   }
00198 }
00199 
00200 void KateScrollBar::wheelEvent(QWheelEvent *e)
00201 {
00202   QCoreApplication::sendEvent(m_viewInternal, e);
00203 }
00204 
00205 void KateScrollBar::marksChanged()
00206 {
00207   recomputeMarksPositions();
00208 }
00209 
00210 void KateScrollBar::redrawMarks()
00211 {
00212   if (!m_showMarks)
00213     return;
00214 
00215   update();
00216 }
00217 
00218 void KateScrollBar::recomputeMarksPositions()
00219 {
00220   m_lines.clear();
00221   m_savVisibleLines = m_doc->visibleLines();
00222 
00223   int realHeight = frameGeometry().height() - m_topMargin - m_bottomMargin;
00224 
00225   const QHash<int, KTextEditor::Mark*> &marks = m_doc->marks();
00226   KateCodeFoldingTree *tree = m_doc->foldingTree();
00227 
00228   for (QHash<int, KTextEditor::Mark*>::const_iterator i = marks.constBegin(); i != marks.constEnd(); ++i)
00229   {
00230     KTextEditor::Mark *mark = i.value();
00231 
00232     uint line = mark->line;
00233 
00234     if (tree)
00235     {
00236       KateCodeFoldingNode *node = tree->findNodeForLine(line);
00237 
00238       while (node)
00239       {
00240         if (!node->isVisible())
00241           line = tree->getStartLine(node);
00242         node = node->getParentNode();
00243       }
00244     }
00245 
00246     line = m_doc->getVirtualLine(line);
00247 
00248     double d = (double)line / (m_savVisibleLines - 1);
00249     m_lines.insert(m_topMargin + (int)(d * realHeight),
00250                    QColor(KateRendererConfig::global()->lineMarkerColor((KTextEditor::MarkInterface::MarkTypes)mark->type)));
00251   }
00252 
00253   // with Qt4 we don't have the luxury of painting outside a paint event
00254   // and a paint event wipes the widget... so just update
00255   update();
00256 }
00257 
00258 void KateScrollBar::sliderMaybeMoved(int value)
00259 {
00260   if (m_middleMouseDown) {
00261     // we only need to emit this signal once, as for the following slider
00262     // movements the signal sliderMoved() is already emitted.
00263     // Thus, set m_middleMouseDown to false right away.
00264     m_middleMouseDown = false;
00265     emit sliderMMBMoved(value);
00266   }
00267 }
00268 //END
00269 
00270 
00271 //BEGIN KateCmdLineEditFlagCompletion
00276 class KateCmdLineEditFlagCompletion : public KCompletion
00277 {
00278   public:
00279     KateCmdLineEditFlagCompletion() {;}
00280 
00281     QString makeCompletion( const QString & /*s*/ )
00282     {
00283       return QString();
00284     }
00285 
00286 };
00287 //END KateCmdLineEditFlagCompletion
00288 
00289 //BEGIN KateCmdLineEdit
00290 KateCmdLine::KateCmdLine (KateView *view, QWidget *parent)
00291     : KateViewBarWidget (true, view, parent)
00292 {
00293     QVBoxLayout *topLayout = new QVBoxLayout ();
00294     centralWidget()->setLayout(topLayout);
00295     topLayout->setMargin(0);
00296     m_lineEdit = new KateCmdLineEdit (this, view);
00297     connect(m_lineEdit, SIGNAL(hideRequested()), SIGNAL(hideMe()));
00298     topLayout->addWidget (m_lineEdit);
00299 
00300     setFocusProxy (m_lineEdit);
00301 }
00302 
00303 KateCmdLine::~KateCmdLine()
00304 {
00305 }
00306 
00307 // inserts the given string in the command line edit and selects it so the user can type over it if
00308 // she wants to
00309 void KateCmdLine::setText(const QString &text)
00310 {
00311   m_lineEdit->setText(text);
00312   m_lineEdit->selectAll();
00313 }
00314 
00315 KateCmdLineEdit::KateCmdLineEdit (KateCmdLine *bar, KateView *view)
00316   : KLineEdit ()
00317   , m_view (view)
00318   , m_bar (bar)
00319   , m_msgMode (false)
00320   , m_histpos( 0 )
00321   , m_cmdend( 0 )
00322   , m_command( 0L )
00323   , m_oldCompletionObject( 0L )
00324 {
00325   connect (this, SIGNAL(returnPressed(const QString &)),
00326            this, SLOT(slotReturnPressed(const QString &)));
00327 
00328   completionObject()->insertItems (KateCmd::self()->commandList());
00329   setAutoDeleteCompletionObject( false );
00330   m_cmdRange.setPattern("^([0-9.$]+)?,([0-9.$]+)?");
00331   m_gotoLine.setPattern("[+-]?\\d+");
00332 
00333   m_hideTimer = new QTimer(this);
00334   m_hideTimer->setSingleShot(true);
00335   connect(m_hideTimer, SIGNAL(timeout()), this, SLOT(hideLineEdit()));
00336 
00337   // make sure the timer is stopped when the user switches views. if not, focus will be given to the
00338   // wrong view when KateViewBar::hideCurrentBarWidget() is called after 4 seconds. (the timer is
00339   // used for showing things like "Success" for four seconds after the user has used the kate
00340   // command line)
00341   connect(m_view, SIGNAL(focusOut (KTextEditor::View*)), m_hideTimer, SLOT(stop()));
00342 }
00343 
00344 void KateCmdLineEdit::hideEvent(QHideEvent *e)
00345 {
00346   Q_UNUSED(e);
00347   m_view->showViModeBar();
00348 }
00349 
00350 
00351 QString KateCmdLineEdit::helptext( const QPoint & ) const
00352     {
00353       QString beg = "<qt background=\"white\"><div><table width=\"100%\"><tr><td bgcolor=\"brown\"><font color=\"white\"><b>Help: <big>";
00354       QString mid = "</big></b></font></td></tr><tr><td>";
00355       QString end = "</td></tr></table></div><qt>";
00356 
00357       QString t = text();
00358       QRegExp re( "\\s*help\\s+(.*)" );
00359       if ( re.indexIn( t ) > -1 )
00360       {
00361         QString s;
00362         // get help for command
00363         QString name = re.cap( 1 );
00364         if ( name == "list" )
00365         {
00366           return beg + i18n("Available Commands") + mid
00367               + KateCmd::self()->commandList().join(" ")
00368               + i18n("<p>For help on individual commands, do <code>'help &lt;command&gt;'</code></p>")
00369               + end;
00370         }
00371         else if ( ! name.isEmpty() )
00372         {
00373           KTextEditor::Command *cmd = KateCmd::self()->queryCommand( name );
00374           if ( cmd )
00375           {
00376             if ( cmd->help( m_view, name, s ) )
00377               return beg + name + mid + s + end;
00378             else
00379               return beg + name + mid + i18n("No help for '%1'",  name ) + end;
00380           }
00381           else
00382             return beg + mid + i18n("No such command <b>%1</b>", name) + end;
00383         }
00384       }
00385 
00386       return beg + mid + i18n(
00387           "<p>This is the Katepart <b>command line</b>.<br />"
00388           "Syntax: <code><b>command [ arguments ]</b></code><br />"
00389           "For a list of available commands, enter <code><b>help list</b></code><br />"
00390           "For help for individual commands, enter <code><b>help &lt;command&gt;</b></code></p>")
00391           + end;
00392     }
00393 
00394 
00395 
00396 bool KateCmdLineEdit::event(QEvent *e) {
00397     if (e->type()==QEvent::WhatsThis)
00398         setWhatsThis(helptext(QPoint()));
00399     return KLineEdit::event(e);
00400 }
00401 
00402 void KateCmdLineEdit::slotReturnPressed ( const QString& text )
00403 {
00404   if (text.isEmpty()) return;
00405   // silently ignore leading space characters and colon characers (for vi-heads)
00406   uint n = 0;
00407   const uint textlen=text.length();
00408   while( (n<textlen) && ( text[n].isSpace() || text[n] == ':' ) )
00409     n++;
00410 
00411   if (n>=textlen) return;
00412 
00413   QString cmd = text.mid( n );
00414 
00415   // expand '%' to '1,$' ("all lines") if at the start of the line
00416   if ( cmd.at( 0 ) == '%' ) {
00417     cmd.replace( 0, 1, "1,$" );
00418   }
00419 
00420   KTextEditor::Range range(-1, 0, -1, 0);
00421 
00422   // check if a range was given
00423   if (m_cmdRange.indexIn(cmd) != -1 && m_cmdRange.matchedLength() > 0) {
00424 
00425     cmd.remove( m_cmdRange );
00426 
00427     QString s = m_cmdRange.capturedTexts().at(1);
00428     QString e = m_cmdRange.capturedTexts().at(2);
00429 
00430     if ( s.isEmpty() )
00431       s = ".";
00432     if ( e.isEmpty() )
00433       e = s;
00434 
00435     // replace '$' with the number of the last line and '.' with the current line
00436     if ( s == "$" ) {
00437       s = QString::number( m_view->doc()->lines() );
00438     } else if ( s == "." ) {
00439       s = QString::number( m_view->cursorPosition().line()+1 );
00440     }
00441 
00442     if ( e == "$" ) {
00443       e = QString::number( m_view->doc()->lines() );
00444     } else if ( e == "." ) {
00445       e = QString::number( m_view->cursorPosition().line()+1 );
00446     }
00447 
00448     range.setRange(KTextEditor::Range(s.toInt()-1, 0, e.toInt()-1, 0));
00449   }
00450 
00451   // special case: if the command is just a number with an optional +/- prefix, rewrite to "goto"
00452   if (m_gotoLine.exactMatch(cmd)) {
00453     cmd.prepend("goto ");
00454   }
00455 
00456   // Built in help: if the command starts with "help", [try to] show some help
00457   if ( cmd.startsWith( "help" ) )
00458   {
00459     QWhatsThis::showText(mapToGlobal(QPoint(0,0)), helptext( QPoint() ) );
00460     clear();
00461     KateCmd::self()->appendHistory( cmd );
00462     m_histpos = KateCmd::self()->historyLength();
00463     m_oldText.clear();
00464     return;
00465   }
00466 
00467   if (cmd.length () > 0)
00468   {
00469     KTextEditor::Command *p = KateCmd::self()->queryCommand (cmd);
00470     KTextEditor::RangeCommand *ce = dynamic_cast<KTextEditor::RangeCommand*>(p);
00471 
00472     m_oldText = m_cmdRange.capturedTexts().at(0) + cmd;
00473     m_msgMode = true;
00474 
00475     // we got a range and a valid command, but the command does not inherit the RangeCommand
00476     // extension. bail out.
00477     if ( ( !ce && range.isValid() && p ) || ( range.isValid() && ce && !ce->supportsRange(cmd) ) ) {
00478       setText (i18n ("Error: No range allowed for command \"%1\".",  cmd));
00479     } else {
00480 
00481       if (p)
00482       {
00483         QString msg;
00484 
00485         if ((ce && ce->exec(m_view, cmd, msg, range)) || p->exec (m_view, cmd, msg))
00486         {
00487 
00488           // append command along with range (will be empty if none given) to history
00489           KateCmd::self()->appendHistory( m_cmdRange.capturedTexts().at(0) + cmd );
00490           m_histpos = KateCmd::self()->historyLength();
00491           m_oldText.clear();
00492 
00493           if (msg.length() > 0)
00494             setText (i18n ("Success: ") + msg);
00495           else
00496             setText (i18n ("Success"));
00497         }
00498         else
00499         {
00500           if (msg.length() > 0)
00501             setText (i18n ("Error: ") + msg);
00502           else
00503             setText (i18n ("Command \"%1\" failed.",  cmd));
00504           KNotification::beep();
00505         }
00506       }
00507       else
00508       {
00509         setText (i18n ("No such command: \"%1\"",  cmd));
00510         KNotification::beep();
00511       }
00512     }
00513   }
00514 
00515   // clean up
00516   if ( m_oldCompletionObject )
00517   {
00518     KCompletion *c = completionObject();
00519     setCompletionObject( m_oldCompletionObject );
00520     m_oldCompletionObject = 0;
00521     delete c;
00522     c = 0;
00523   }
00524   m_command = 0;
00525   m_cmdend = 0;
00526 
00527   m_view->setFocus ();
00528   m_hideTimer->start(4000);
00529 }
00530 
00531 void KateCmdLineEdit::hideLineEdit () // unless i have focus ;)
00532 {
00533   if ( ! hasFocus() ) {
00534       emit hideRequested();
00535   }
00536 }
00537 
00538 void KateCmdLineEdit::focusInEvent ( QFocusEvent *ev )
00539 {
00540   if (m_msgMode)
00541   {
00542     m_msgMode = false;
00543     setText (m_oldText);
00544     selectAll();
00545   }
00546 
00547   KLineEdit::focusInEvent (ev);
00548 }
00549 
00550 void KateCmdLineEdit::keyPressEvent( QKeyEvent *ev )
00551 {
00552   if (ev->key() == Qt::Key_Escape)
00553   {
00554     m_view->setFocus ();
00555     hideLineEdit();
00556   }
00557   else if ( ev->key() == Qt::Key_Up )
00558     fromHistory( true );
00559   else if ( ev->key() == Qt::Key_Down )
00560     fromHistory( false );
00561 
00562   uint cursorpos = cursorPosition();
00563   KLineEdit::keyPressEvent (ev);
00564 
00565   // during typing, let us see if we have a valid command
00566   if ( ! m_cmdend || cursorpos <= m_cmdend  )
00567   {
00568     QChar c;
00569     if ( ! ev->text().isEmpty() )
00570       c = ev->text()[0];
00571 
00572     if ( ! m_cmdend && ! c.isNull() ) // we have no command, so lets see if we got one
00573     {
00574       if ( ! c.isLetterOrNumber() && c != '-' && c != '_' )
00575       {
00576         m_command = KateCmd::self()->queryCommand( text().trimmed() );
00577         if ( m_command )
00578         {
00579           //kDebug(13025)<<"keypress in commandline: We have a command! "<<m_command<<". text is '"<<text()<<"'";
00580           // if the typed character is ":",
00581           // we try if the command has flag completions
00582           m_cmdend = cursorpos;
00583           //kDebug(13025)<<"keypress in commandline: Set m_cmdend to "<<m_cmdend;
00584         }
00585         else
00586           m_cmdend = 0;
00587       }
00588     }
00589     else // since cursor is inside the command name, we reconsider it
00590     {
00591       kDebug(13025)<<"keypress in commandline: \\W -- text is "<<text();
00592       m_command = KateCmd::self()->queryCommand( text().trimmed() );
00593       if ( m_command )
00594       {
00595         //kDebug(13025)<<"keypress in commandline: We have a command! "<<m_command;
00596         QString t = text();
00597         m_cmdend = 0;
00598         bool b = false;
00599         for ( ; (int)m_cmdend < t.length(); m_cmdend++ )
00600         {
00601           if ( t[m_cmdend].isLetter() )
00602             b = true;
00603           if ( b && ( ! t[m_cmdend].isLetterOrNumber() && t[m_cmdend] != '-' && t[m_cmdend] != '_' ) )
00604             break;
00605         }
00606 
00607         if ( c == ':' && cursorpos == m_cmdend )
00608         {
00609           // check if this command wants to complete flags
00610           //kDebug(13025)<<"keypress in commandline: Checking if flag completion is desired!";
00611         }
00612       }
00613       else
00614       {
00615         // clean up if needed
00616         if ( m_oldCompletionObject )
00617         {
00618           KCompletion *c = completionObject();
00619           setCompletionObject( m_oldCompletionObject );
00620           m_oldCompletionObject = 0;
00621           delete c;
00622           c = 0;
00623         }
00624 
00625         m_cmdend = 0;
00626       }
00627     }
00628 
00629     // if we got a command, check if it wants to do something.
00630     if ( m_command )
00631     {
00632       //kDebug(13025)<<"Checking for CommandExtension..";
00633       KTextEditor::CommandExtension *ce = dynamic_cast<KTextEditor::CommandExtension*>(m_command);
00634       if ( ce )
00635       {
00636         KCompletion *cmpl = ce->completionObject( m_view, text().left( m_cmdend ).trimmed() );
00637         if ( cmpl )
00638         {
00639         // save the old completion object and use what the command provides
00640         // instead. We also need to prepend the current command name + flag string
00641         // when completion is done
00642           //kDebug(13025)<<"keypress in commandline: Setting completion object!";
00643           if ( ! m_oldCompletionObject )
00644             m_oldCompletionObject = completionObject();
00645 
00646           setCompletionObject( cmpl );
00647         }
00648       }
00649     }
00650   }
00651   else if ( m_command )// check if we should call the commands processText()
00652   {
00653     KTextEditor::CommandExtension *ce = dynamic_cast<KTextEditor::CommandExtension*>( m_command );
00654     if ( ce && ce->wantsToProcessText( text().left( m_cmdend ).trimmed() )
00655          && ! ( ev->text().isNull() || ev->text().isEmpty() ) )
00656       ce->processText( m_view, text() );
00657   }
00658 }
00659 
00660 void KateCmdLineEdit::fromHistory( bool up )
00661 {
00662   if ( ! KateCmd::self()->historyLength() )
00663     return;
00664 
00665   QString s;
00666 
00667   if ( up )
00668   {
00669     if ( m_histpos > 0 )
00670     {
00671       m_histpos--;
00672       s = KateCmd::self()->fromHistory( m_histpos );
00673     }
00674   }
00675   else
00676   {
00677     if ( m_histpos < ( KateCmd::self()->historyLength() - 1 ) )
00678     {
00679       m_histpos++;
00680       s = KateCmd::self()->fromHistory( m_histpos );
00681     }
00682     else
00683     {
00684       m_histpos = KateCmd::self()->historyLength();
00685       setText( m_oldText );
00686     }
00687   }
00688   if ( ! s.isEmpty() )
00689   {
00690     // Select the argument part of the command, so that it is easy to overwrite
00691     setText( s );
00692     static QRegExp reCmd = QRegExp(".*[\\w\\-]+(?:[^a-zA-Z0-9_-]|:\\w+)(.*)");
00693     if ( reCmd.indexIn( text() ) == 0 )
00694       setSelection( text().length() - reCmd.cap(1).length(), reCmd.cap(1).length() );
00695   }
00696 }
00697 //END KateCmdLineEdit
00698 
00699 //BEGIN KateIconBorder
00700 using namespace KTextEditor;
00701 
00702 const int halfIPW = 8;
00703 
00704 KateIconBorder::KateIconBorder ( KateViewInternal* internalView, QWidget *parent )
00705   : QWidget(parent)
00706   , m_view( internalView->m_view )
00707   , m_doc( internalView->m_doc )
00708   , m_viewInternal( internalView )
00709   , m_iconBorderOn( false )
00710   , m_lineNumbersOn( false )
00711   , m_foldingMarkersOn( false )
00712   , m_dynWrapIndicatorsOn( false )
00713   , m_annotationBorderOn( false )
00714   , m_dynWrapIndicators( 0 )
00715   , m_cachedLNWidth( 0 )
00716   , m_maxCharWidth( 0 )
00717   , iconPaneWidth (16)
00718   , m_annotationBorderWidth (6)
00719   , m_foldingRange(0)
00720   , m_lastBlockLine(-1)
00721 {
00722   initializeFoldingColors();
00723 
00724   setAttribute( Qt::WA_StaticContents );
00725   setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum );
00726   setMouseTracking(true);
00727   m_doc->setMarkDescription( MarkInterface::markType01, i18n("Bookmark") );
00728   m_doc->setMarkPixmap( MarkInterface::markType01, KIcon("bookmarks").pixmap(16, 16) );
00729 
00730   updateFont();
00731 }
00732 
00733 void KateIconBorder::initializeFoldingColors()
00734 {
00735   // Get the schema
00736   KateRendererConfig *config = m_view->renderer()->config();
00737   // FIXME next 3 lines temporary until this moves to config
00738   const KColorScheme scheme( QPalette::Normal );
00739   const QColor middle( KColorUtils::tint( config->iconBarColor(), scheme.foreground( KColorScheme::NeutralText ).color(), 0.7 ) );
00740   const QColor final( KColorUtils::tint( config->iconBarColor(), scheme.foreground( KColorScheme::PositiveText ).color(), 0.7 ) );
00741 
00742   const QColor start( config->iconBarColor() );
00743   static const int MIDFOLDINGCOLORS = MAXFOLDINGCOLORS / 2;
00744   static const qreal n = 2.0 / MAXFOLDINGCOLORS;
00745 
00746   int i, j;
00747   for( i = 0; i < MIDFOLDINGCOLORS; i++ ) {
00748     const qreal a = 0.9 * pow(qreal(i) * n, 1.0);
00749     m_foldingColors[i] = KColorUtils::tint( start, middle, a );
00750   }
00751   for( j = 0; i < MAXFOLDINGCOLORS; i++, j++ ) {
00752     const qreal a = 0.9 * pow(qreal(j) * n, 1.0);
00753     m_foldingColors[i] = KColorUtils::tint( middle, final, a );
00754   }
00755 }
00756 
00757 
00758 KateIconBorder::~KateIconBorder() {delete m_foldingRange;}
00759 
00760 void KateIconBorder::setIconBorderOn( bool enable )
00761 {
00762   if( enable == m_iconBorderOn )
00763     return;
00764 
00765   m_iconBorderOn = enable;
00766 
00767   updateGeometry();
00768 
00769   QTimer::singleShot( 0, this, SLOT(update()) );
00770 }
00771 
00772 void KateIconBorder::setAnnotationBorderOn( bool enable )
00773 {
00774   if( enable == m_annotationBorderOn )
00775     return;
00776 
00777   m_annotationBorderOn = enable;
00778 
00779   emit m_view->annotationBorderVisibilityChanged(m_view, enable);
00780 
00781   updateGeometry();
00782 }
00783 
00784 void KateIconBorder::removeAnnotationHovering()
00785 {
00786   // remove hovering if it's still there
00787   if (m_annotationBorderOn && !m_hoveredAnnotationText.isEmpty())
00788   {
00789     m_hoveredAnnotationText.clear();
00790     hideAnnotationTooltip();
00791     QTimer::singleShot( 0, this, SLOT(update()) );
00792   }
00793 }
00794 
00795 void KateIconBorder::setLineNumbersOn( bool enable )
00796 {
00797   if( enable == m_lineNumbersOn )
00798     return;
00799 
00800   m_lineNumbersOn = enable;
00801   m_dynWrapIndicatorsOn = (m_dynWrapIndicators == 1) ? enable : m_dynWrapIndicators;
00802 
00803   updateGeometry();
00804 
00805   QTimer::singleShot( 0, this, SLOT(update()) );
00806 }
00807 
00808 void KateIconBorder::setDynWrapIndicators( int state )
00809 {
00810   if (state == m_dynWrapIndicators )
00811     return;
00812 
00813   m_dynWrapIndicators = state;
00814   m_dynWrapIndicatorsOn = (state == 1) ? m_lineNumbersOn : state;
00815 
00816   updateGeometry ();
00817 
00818   QTimer::singleShot( 0, this, SLOT(update()) );
00819 }
00820 
00821 void KateIconBorder::setFoldingMarkersOn( bool enable )
00822 {
00823   if( enable == m_foldingMarkersOn )
00824     return;
00825 
00826   m_foldingMarkersOn = enable;
00827 
00828   updateGeometry();
00829 
00830   QTimer::singleShot( 0, this, SLOT(update()) );
00831 }
00832 
00833 QSize KateIconBorder::sizeHint() const
00834 {
00835   int w = 0;
00836 
00837   if (m_iconBorderOn)
00838     w += iconPaneWidth + 1;
00839 
00840   if (m_annotationBorderOn)
00841   {
00842     w += m_annotationBorderWidth + 1;
00843   }
00844 
00845   if (m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn)) {
00846     w += lineNumberWidth() + 1;
00847   }
00848 
00849   if (m_foldingMarkersOn)
00850     w += iconPaneWidth + 1;
00851 
00852   w += 4;
00853 
00854   return QSize( w, 0 );
00855 }
00856 
00857 // This function (re)calculates the maximum width of any of the digit characters (0 -> 9)
00858 // for graceful handling of variable-width fonts as the linenumber font.
00859 void KateIconBorder::updateFont()
00860 {
00861   QFontMetrics fm = m_view->renderer()->config()->fontMetrics();
00862   m_maxCharWidth = 0;
00863   // Loop to determine the widest numeric character in the current font.
00864   // 48 is ascii '0'
00865   for (int i = 48; i < 58; i++) {
00866     int charWidth = fm.width( QChar(i) );
00867     m_maxCharWidth = qMax(m_maxCharWidth, charWidth);
00868   }
00869 
00870   // the icon pane scales with the font...
00871   iconPaneWidth = fm.height();
00872 
00873   updateGeometry();
00874 
00875   QTimer::singleShot( 0, this, SLOT(update()) );
00876 }
00877 
00878 int KateIconBorder::lineNumberWidth() const
00879 {
00880   int width = m_lineNumbersOn ? ((int)log10((double)(m_view->doc()->lines())) + 1) * m_maxCharWidth + 4 : 0;
00881 
00882   if (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) {
00883     // HACK: 16 == style().scrollBarExtent().width()
00884     width = qMax(16 + 4, width);
00885 
00886     if (m_cachedLNWidth != width || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor()) {
00887       int w = 16;// HACK: 16 == style().scrollBarExtent().width() style().scrollBarExtent().width();
00888       int h = m_view->renderer()->config()->fontMetrics().height();
00889 
00890       QSize newSize(w, h);
00891       if ((m_arrow.size() != newSize || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor()) && !newSize.isEmpty()) {
00892         m_arrow = QPixmap(newSize);
00893 
00894         QPainter p(&m_arrow);
00895         p.fillRect( 0, 0, w, h, m_view->renderer()->config()->iconBarColor() );
00896 
00897         h = m_view->renderer()->config()->fontMetrics().ascent();
00898 
00899         p.setPen(m_view->renderer()->config()->lineNumberColor());
00900 
00901         QPainterPath path;
00902         path.moveTo(w/2, h/2);
00903         path.lineTo(w/2, 0);
00904         path.lineTo(w/4, h/4);
00905         path.lineTo(0, 0);
00906         path.lineTo(0, h/2);
00907         path.lineTo(w/2, h-1);
00908         path.lineTo(w*3/4, h-1);
00909         path.lineTo(w-1, h*3/4);
00910         path.lineTo(w*3/4, h/2);
00911         path.lineTo(0, h/2);
00912         p.drawPath(path);
00913       }
00914     }
00915   }
00916 
00917   return width;
00918 }
00919 
00920 QBrush KateIconBorder::foldingColor(KateLineInfo *info,int realLine, bool solid) {
00921   int depth;
00922   if (info != 0) {
00923     depth = info->depth;
00924   } else {
00925     KateLineInfo tmp;
00926     m_doc->lineInfo(&tmp, realLine);
00927     depth = tmp.depth;
00928   }
00929 
00930   QColor result;
00931   if (depth < MAXFOLDINGCOLORS)
00932     result = m_foldingColors[depth];
00933   else
00934     result = m_foldingColors[MAXFOLDINGCOLORS-1];
00935   if (!solid)
00936     result.setAlphaF(0.4);
00937 
00938   return QBrush( result );
00939 
00940 }
00941 
00942 void KateIconBorder::paintEvent(QPaintEvent* e)
00943 {
00944   paintBorder(e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height());
00945 }
00946 
00947 static void paintTriangle (QPainter &painter, const QColor &baseColor, int xOffset, int yOffset, int width, int height, bool open)
00948 {
00949   painter.setRenderHint(QPainter::Antialiasing);
00950 
00951   qreal size = qMin (width, height);
00952 
00953   QColor c;
00954   if ( KColorUtils::luma( baseColor ) > 0.25 )
00955     c = KColorUtils::darken( baseColor );
00956   else
00957     c = KColorUtils::shade( baseColor, 0.2 );
00958 
00959   QPen pen;
00960   pen.setJoinStyle (Qt::RoundJoin);
00961   pen.setColor (c);
00962   pen.setWidthF (1.5);
00963   painter.setPen ( pen );
00964 
00965   painter.setBrush ( c );
00966 
00967   // let some border, if possible
00968   size *= 0.6;
00969 
00970   qreal halfSize = size / 2;
00971   qreal halfSizeP = halfSize * 0.6;
00972   QPointF middle (xOffset + (qreal)width / 2, yOffset + (qreal)height / 2);
00973 
00974   if (open)
00975   {
00976     QPointF points[3] = { middle+QPointF(-halfSize, -halfSizeP), middle+QPointF(halfSize, -halfSizeP), middle+QPointF(0, halfSizeP) };
00977     painter.drawConvexPolygon(points, 3);
00978   }
00979   else
00980   {
00981     QPointF points[3] = { middle+QPointF(-halfSizeP, -halfSize), middle+QPointF(-halfSizeP, halfSize), middle+QPointF(halfSizeP, 0) };
00982     painter.drawConvexPolygon(points, 3);
00983   }
00984 
00985   painter.setRenderHint(QPainter::Antialiasing, false);
00986 }
00987 
00988 void KateIconBorder::paintBorder (int /*x*/, int y, int /*width*/, int height)
00989 {
00990   QMutexLocker lock(m_view->m_doc->smartMutex());
00991   uint h = m_view->renderer()->config()->fontMetrics().height();
00992   uint startz = (y / h);
00993   uint endz = startz + 1 + (height / h);
00994   uint lineRangesSize = m_viewInternal->cache()->viewCacheLineCount();
00995 
00996   // center the folding boxes
00997   int m_px = (h - 11) / 2;
00998   if (m_px < 0)
00999     m_px = 0;
01000 
01001   int lnWidth( 0 );
01002   if ( m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) ) // avoid calculating unless needed ;-)
01003   {
01004     lnWidth = lineNumberWidth();
01005     if ( lnWidth != m_cachedLNWidth || m_oldBackgroundColor != m_view->renderer()->config()->iconBarColor() )
01006     {
01007       // we went from n0 ->n9 lines or vice verca
01008       // this causes an extra updateGeometry() first time the line numbers
01009       // are displayed, but sizeHint() is supposed to be const so we can't set
01010       // the cached value there.
01011       m_cachedLNWidth = lnWidth;
01012       m_oldBackgroundColor = m_view->renderer()->config()->iconBarColor();
01013       updateGeometry();
01014       update ();
01015       return;
01016     }
01017   }
01018 
01019   int w( this->width() );                     // sane value/calc only once
01020 
01021   QPainter p ( this );
01022   p.setRenderHints (QPainter::TextAntialiasing);
01023   p.setFont ( m_view->renderer()->config()->font() ); // for line numbers
01024 
01025   KateLineInfo oldInfo;
01026   if (startz < lineRangesSize)
01027   {
01028     if ((m_viewInternal->cache()->viewLine(startz).line()-1) < 0)
01029       oldInfo.topLevel = true;
01030     else
01031       m_doc->lineInfo(&oldInfo,m_viewInternal->cache()->viewLine(startz).line()-1);
01032   }
01033 
01034   KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01035       m_view->annotationModel() : m_doc->annotationModel();
01036 
01037   for (uint z=startz; z <= endz; z++)
01038   {
01039     int y = h * z;
01040     int realLine = -1;
01041 
01042     if (z < lineRangesSize)
01043       realLine = m_viewInternal->cache()->viewLine(z).line();
01044 
01045     int lnX = 0;
01046 
01047     p.fillRect( 0, y, w-4, h, m_view->renderer()->config()->iconBarColor() );
01048     p.fillRect( w-4, y, 4, h, m_view->renderer()->config()->backgroundColor() );
01049 
01050     // icon pane
01051     if( m_iconBorderOn )
01052     {
01053       p.setPen ( m_view->renderer()->config()->lineNumberColor() );
01054       p.setBrush ( m_view->renderer()->config()->lineNumberColor() );
01055       p.drawLine(lnX+iconPaneWidth+1, y, lnX+iconPaneWidth+1, y+h);
01056 
01057       if( (realLine > -1) && (m_viewInternal->cache()->viewLine(z).startCol() == 0) )
01058       {
01059         uint mrk ( m_doc->mark( realLine ) ); // call only once
01060 
01061         if ( mrk )
01062         {
01063           for( uint bit = 0; bit < 32; bit++ )
01064           {
01065             MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes)(1<<bit);
01066             if( mrk & markType )
01067             {
01068               QPixmap px_mark (m_doc->markPixmap( markType ));
01069 
01070               if (!px_mark.isNull() && h > 0 && iconPaneWidth > 0)
01071               {
01072                 if (iconPaneWidth < px_mark.width() || h < (uint)px_mark.height())
01073                   px_mark = px_mark.scaled (iconPaneWidth, h, Qt::KeepAspectRatio);
01074 
01075                 // center the mark pixmap
01076                 int x_px = (iconPaneWidth - px_mark.width()) / 2;
01077                 if (x_px < 0)
01078                   x_px = 0;
01079 
01080                 int y_px = (h - px_mark.height()) / 2;
01081                 if (y_px < 0)
01082                   y_px = 0;
01083 
01084                 p.drawPixmap( lnX+x_px, y+y_px, px_mark);
01085               }
01086             }
01087           }
01088         }
01089       }
01090 
01091       lnX += iconPaneWidth + 2;
01092     }
01093 
01094     // annotation information
01095     if( m_annotationBorderOn )
01096     {
01097       // Draw a border line between annotations and the line numbers
01098       p.setPen ( m_view->renderer()->config()->lineNumberColor() );
01099       p.setBrush ( m_view->renderer()->config()->lineNumberColor() );
01100 
01101       int borderWidth = m_annotationBorderWidth;
01102       p.drawLine(lnX+borderWidth+1, y, lnX+borderWidth+1, y+h);
01103 
01104       if( (realLine > -1) && model )
01105       {
01106         // Fetch data from the model
01107         QVariant text = model->data( realLine, Qt::DisplayRole );
01108         QVariant foreground = model->data( realLine, Qt::ForegroundRole );
01109         QVariant background = model->data( realLine, Qt::BackgroundRole );
01110         // Fill the background
01111         if( background.isValid() )
01112         {
01113           p.fillRect( lnX, y, borderWidth + 1, h, background.value<QBrush>() );
01114         }
01115         // Set the pen for drawing the foreground
01116         if( foreground.isValid() )
01117         {
01118           p.setBrush( foreground.value<QBrush>() );
01119         }
01120 
01121         // Draw a border around all adjacent entries that have the same text as the currently hovered one
01122         if( m_hoveredAnnotationText == text.toString() )
01123         {
01124           p.drawLine( lnX, y, lnX, y+h );
01125           p.drawLine( lnX+borderWidth, y, lnX+borderWidth, y+h );
01126 
01127           QVariant beforeText = model->data( realLine-1, Qt::DisplayRole );
01128           QVariant afterText = model->data( realLine+1, Qt::DisplayRole );
01129           if( ((beforeText.isValid() && beforeText.canConvert<QString>()
01130               && text.isValid() && text.canConvert<QString>()
01131               && beforeText.toString() != text.toString()) || realLine == 0)
01132               && m_viewInternal->cache()->viewLine(z).viewLine() == 0)
01133           {
01134             p.drawLine( lnX+1, y, lnX+borderWidth, y );
01135           }
01136 
01137           if( ((afterText.isValid() && afterText.canConvert<QString>()
01138               && text.isValid() && text.canConvert<QString>()
01139               && afterText.toString() != text.toString())
01140                 || realLine == m_view->doc()->lines() - 1)
01141               && m_viewInternal->cache()->viewLine(z).viewLine() == m_viewInternal->cache()->viewLineCount(realLine)-1)
01142           {
01143             p.drawLine( lnX+1, y+h-1, lnX+borderWidth, y+h-1 );
01144           }
01145         }
01146         if( foreground.isValid() )
01147         {
01148           QPen pen = p.pen();
01149           pen.setWidth( 1 );
01150           p.setPen( pen );
01151         }
01152 
01153         // Now draw the normal text
01154         if( text.isValid() && text.canConvert<QString>() && (m_viewInternal->cache()->viewLine(z).startCol() == 0)  )
01155         {
01156           p.drawText( lnX+3, y, borderWidth-3, h, Qt::AlignLeft|Qt::AlignVCenter, text.toString() );
01157         }
01158       }
01159 
01160       // adjust current X position and reset the pen and brush
01161       lnX += borderWidth + 2;
01162     }
01163 
01164     // line number
01165     if( m_lineNumbersOn || (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) )
01166     {
01167       p.setPen ( m_view->renderer()->config()->lineNumberColor() );
01168       p.setBrush ( m_view->renderer()->config()->lineNumberColor() );
01169 
01170       if (realLine > -1) {
01171         if (m_viewInternal->cache()->viewLine(z).startCol() == 0) {
01172           if (m_lineNumbersOn)
01173             p.drawText( lnX, y, lnWidth-4, h, Qt::AlignRight|Qt::AlignVCenter, QString("%1").arg( realLine + 1 ) );
01174         } else if (m_view->dynWordWrap() && m_dynWrapIndicatorsOn) {
01175           p.drawPixmap(lnX + lnWidth - m_arrow.width() - 2, y, m_arrow);
01176         }
01177       }
01178 
01179       lnX += lnWidth + 2;
01180     }
01181 
01182     // folding markers
01183     if( m_foldingMarkersOn )
01184     {
01185       if( realLine > -1 )
01186       {
01187         KateLineInfo info;
01188         m_doc->lineInfo(&info,realLine);
01189 
01190         QBrush brush (foldingColor(&info,realLine,true));
01191         p.fillRect(lnX, y, iconPaneWidth, h, brush);
01192 
01193         if (!info.topLevel)
01194         {
01195           if (info.startsVisibleBlock && (m_viewInternal->cache()->viewLine(z).startCol() == 0))
01196           {
01197             paintTriangle (p, brush.color(), lnX, y, iconPaneWidth, h, true);
01198           }
01199           else if (info.startsInVisibleBlock && m_viewInternal->cache()->viewLine(z).startCol() == 0)
01200           {
01201             paintTriangle (p, brush.color(), lnX, y, iconPaneWidth, h, false);
01202           }
01203           else
01204           {
01205            // p.drawLine(lnX+halfIPW,y,lnX+halfIPW,y+h-1);
01206 
01207            // if (info.endsBlock && !m_viewInternal->cache()->viewLine(z).wrap())
01208             //  p.drawLine(lnX+halfIPW,y+h-1,lnX+iconPaneWidth-2,y+h-1);
01209           }
01210         }
01211 
01212         oldInfo = info;
01213       }
01214 
01215       lnX += iconPaneWidth + 2;
01216     }
01217   }
01218 }
01219 
01220 KateIconBorder::BorderArea KateIconBorder::positionToArea( const QPoint& p ) const
01221 {
01222   int x = 0;
01223   if( m_iconBorderOn ) {
01224     x += iconPaneWidth;
01225     if( p.x() <= x )
01226       return IconBorder;
01227   }
01228   if( this->m_annotationBorderOn ) {
01229     x += m_annotationBorderWidth;
01230     if( p.x() <= x )
01231       return AnnotationBorder;
01232   }
01233   if( m_lineNumbersOn || m_dynWrapIndicators ) {
01234     x += lineNumberWidth();
01235     if( p.x() <= x )
01236       return LineNumbers;
01237   }
01238   if( m_foldingMarkersOn ) {
01239     x += iconPaneWidth;
01240     if( p.x() <= x )
01241       return FoldingMarkers;
01242   }
01243   return None;
01244 }
01245 
01246 void KateIconBorder::mousePressEvent( QMouseEvent* e )
01247 {
01248   const KateTextLayout& t = m_viewInternal->yToKateTextLayout(e->y());
01249   if (t.isValid()) {
01250     m_lastClickedLine = t.line();
01251     if ( positionToArea( e->pos() ) != IconBorder && positionToArea( e->pos() ) != AnnotationBorder )
01252     {
01253       QMouseEvent forward( QEvent::MouseButtonPress,
01254         QPoint( 0, e->y() ), e->button(), e->buttons(),e->modifiers() );
01255       m_viewInternal->mousePressEvent( &forward );
01256     }
01257     return e->accept();
01258   }
01259 
01260   QWidget::mousePressEvent(e);
01261 }
01262 
01263 void KateIconBorder::showBlock(int line)
01264 {
01265   if (line == m_lastBlockLine) return;
01266   m_lastBlockLine = line;
01267 
01268   // get the new range, that should be highlighted
01269   KTextEditor::Range newRange = KTextEditor::Range::invalid();
01270   KateCodeFoldingTree *tree = m_doc->foldingTree();
01271   if (tree) {
01272     KateCodeFoldingNode *node = tree->findNodeForLine(line);
01273     KTextEditor::Cursor beg;
01274     KTextEditor::Cursor end;
01275     if (node != tree->rootNode () && node->getBegin(tree, &beg) && node->getEnd(tree, &end)) {
01276       newRange = KTextEditor::Range(beg, end);
01277     }
01278     KateLineInfo info;
01279     tree->getLineInfo(&info,line);
01280     if ((info.startsVisibleBlock)){
01281       node=tree->findNodeStartingAt(line);
01282       if (node) {
01283         if (node != tree->rootNode () && node->getBegin(tree, &beg) && node->getEnd(tree, &end)) {
01284           newRange = KTextEditor::Range(beg, end);
01285         }
01286       }
01287     }
01288 
01289   }
01290 
01291   if (newRange.isValid() && m_foldingRange && *m_foldingRange == newRange) {
01292     // new range equals the old one, nothing to do.
01293     return;
01294   } else { // the ranges differ, delete the old, if it exists
01295     delete m_foldingRange;
01296     m_foldingRange = 0;
01297   }
01298 
01299   if (newRange.isValid()) {
01300     kDebug(13025) << "new folding hl-range:" << newRange;
01301     m_foldingRange = m_doc->newSmartRange(newRange);
01302     static_cast<KateSmartRange*>(m_foldingRange)->setInternal();
01303     KTextEditor::Attribute::Ptr attr(new KTextEditor::Attribute());
01304     attr->setBackground(foldingColor(0, line, false));
01305     m_foldingRange->setAttribute(attr);
01306     m_doc->addHighlightToView(m_view, m_foldingRange, false);
01307   }
01308 }
01309 
01310 void KateIconBorder::hideBlock() {
01311   m_lastBlockLine=-1;
01312   delete m_foldingRange;
01313   m_foldingRange = 0;
01314 }
01315 
01316 void KateIconBorder::leaveEvent(QEvent *event)
01317 {
01318   hideBlock();
01319   removeAnnotationHovering();
01320 
01321   QWidget::leaveEvent(event);
01322 }
01323 
01324 void KateIconBorder::mouseMoveEvent( QMouseEvent* e )
01325 {
01326   const KateTextLayout& t = m_viewInternal->yToKateTextLayout(e->y());
01327   if (t.isValid()) {
01328     if ( positionToArea( e->pos() ) == FoldingMarkers) showBlock(t.line());
01329     else hideBlock();
01330     if ( positionToArea( e->pos() ) == AnnotationBorder )
01331     {
01332       KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01333         m_view->annotationModel() : m_doc->annotationModel();
01334       if (model)
01335       {
01336         m_hoveredAnnotationText = model->data( t.line(), Qt::DisplayRole ).toString();
01337         showAnnotationTooltip( t.line(), e->globalPos() );
01338         QTimer::singleShot( 0, this, SLOT(update()) );
01339       }
01340     }
01341     else
01342     {
01343       m_hoveredAnnotationText.clear();
01344       hideAnnotationTooltip();
01345       QTimer::singleShot( 0, this, SLOT(update()) );
01346     }
01347     if ( positionToArea( e->pos() ) != IconBorder )
01348     {
01349       QMouseEvent forward( QEvent::MouseMove,
01350         QPoint( 0, e->y() ), e->button(), e->buttons(),e->modifiers() );
01351       m_viewInternal->mouseMoveEvent( &forward );
01352     }
01353   }
01354   else
01355   {
01356     // remove hovering if it's still there
01357     removeAnnotationHovering();
01358   }
01359 
01360   QWidget::mouseMoveEvent(e);
01361 }
01362 
01363 void KateIconBorder::mouseReleaseEvent( QMouseEvent* e )
01364 {
01365   int cursorOnLine = m_viewInternal->yToKateTextLayout(e->y()).line();
01366 
01367   if (cursorOnLine == m_lastClickedLine &&
01368       cursorOnLine <= m_doc->lastLine() )
01369   {
01370     BorderArea area = positionToArea( e->pos() );
01371     if( area == IconBorder) {
01372       if (e->button() == Qt::LeftButton) {
01373         if( m_doc->editableMarks() & KateViewConfig::global()->defaultMarkType() ) {
01374           if( m_doc->mark( cursorOnLine ) & KateViewConfig::global()->defaultMarkType() )
01375             m_doc->removeMark( cursorOnLine, KateViewConfig::global()->defaultMarkType() );
01376           else
01377             m_doc->addMark( cursorOnLine, KateViewConfig::global()->defaultMarkType() );
01378           } else {
01379             showMarkMenu( cursorOnLine, QCursor::pos() );
01380           }
01381         }
01382         else
01383         if (e->button() == Qt::RightButton) {
01384           showMarkMenu( cursorOnLine, QCursor::pos() );
01385         }
01386     }
01387 
01388     if ( area == FoldingMarkers) {
01389       KateLineInfo info;
01390       m_doc->lineInfo(&info,cursorOnLine);
01391       if ((info.startsVisibleBlock) || (info.startsInVisibleBlock)) {
01392         emit toggleRegionVisibility(cursorOnLine);
01393       }
01394     }
01395 
01396     if ( area == AnnotationBorder ) {
01397       if( e->button() == Qt::LeftButton && KGlobalSettings::singleClick() ) {
01398         emit m_view->annotationActivated( m_view, cursorOnLine );
01399       } else if ( e->button() == Qt::RightButton ) {
01400         showAnnotationMenu( cursorOnLine, e->globalPos() );
01401       }
01402     }
01403   }
01404 
01405   QMouseEvent forward( QEvent::MouseButtonRelease,
01406     QPoint( 0, e->y() ), e->button(), e->buttons(),e->modifiers() );
01407   m_viewInternal->mouseReleaseEvent( &forward );
01408 }
01409 
01410 void KateIconBorder::mouseDoubleClickEvent( QMouseEvent* e )
01411 {
01412   int cursorOnLine = m_viewInternal->yToKateTextLayout(e->y()).line();
01413 
01414   if (cursorOnLine == m_lastClickedLine &&
01415       cursorOnLine <= m_doc->lastLine() )
01416   {
01417     BorderArea area = positionToArea( e->pos() );
01418     if( area == AnnotationBorder && !KGlobalSettings::singleClick() ) {
01419       emit m_view->annotationActivated( m_view, cursorOnLine );
01420     }
01421   }
01422   QMouseEvent forward( QEvent::MouseButtonDblClick,
01423     QPoint( 0, e->y() ), e->button(), e->buttons(),e->modifiers() );
01424   m_viewInternal->mouseDoubleClickEvent( &forward );
01425 }
01426 
01427 void KateIconBorder::showMarkMenu( uint line, const QPoint& pos )
01428 {
01429   KMenu markMenu;
01430   KMenu selectDefaultMark;
01431 
01432   QVector<int> vec( 33 );
01433   int i=1;
01434 
01435   for( uint bit = 0; bit < 32; bit++ ) {
01436     MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes)(1<<bit);
01437     if( !(m_doc->editableMarks() & markType) )
01438       continue;
01439 
01440     QAction *mA;
01441     QAction *dMA;
01442     if( !m_doc->markDescription( markType ).isEmpty() ) {
01443       mA=markMenu.addAction( m_doc->markDescription( markType ));
01444       dMA=selectDefaultMark.addAction( m_doc->markDescription( markType ));
01445     } else {
01446       mA=markMenu.addAction( i18n("Mark Type %1",  bit + 1 ));
01447       dMA=selectDefaultMark.addAction( i18n("Mark Type %1",  bit + 1 ));
01448     }
01449     mA->setData(i);
01450     mA->setCheckable(true);
01451     dMA->setData(i+100);
01452     dMA->setCheckable(true);
01453     if( m_doc->mark( line ) & markType )
01454       mA->setChecked(true );
01455 
01456     if( markType & KateViewConfig::global()->defaultMarkType() )
01457       dMA->setChecked(true );
01458 
01459     vec[i++] = markType;
01460   }
01461 
01462   if( markMenu.actions().count() == 0 )
01463     return;
01464 
01465   if( markMenu.actions().count() > 1 )
01466     markMenu.addAction( i18n("Set Default Mark Type" ))->setMenu(&selectDefaultMark);
01467 
01468   QAction *rA = markMenu.exec( pos );
01469   if( !rA )
01470     return;
01471   int result=rA->data().toInt();
01472   if ( result > 100)
01473   {
01474      KateViewConfig::global()->setDefaultMarkType (vec[result-100]);
01475      // flush config, otherwise it isn't nessecarily done
01476      KConfigGroup cg(KGlobal::config(), "Kate View Defaults");
01477      KateViewConfig::global()->writeConfig(cg);
01478   }
01479   else
01480   {
01481     MarkInterface::MarkTypes markType = (MarkInterface::MarkTypes) vec[result];
01482     if( m_doc->mark( line ) & markType ) {
01483       m_doc->removeMark( line, markType );
01484     } else {
01485         m_doc->addMark( line, markType );
01486     }
01487   }
01488 }
01489 
01490 void KateIconBorder::showAnnotationTooltip( int line, const QPoint& pos )
01491 {
01492   KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01493     m_view->annotationModel() : m_doc->annotationModel();
01494 
01495   if( model )
01496   {
01497     QVariant data = model->data( line, Qt::ToolTipRole );
01498     QString tip = data.toString();
01499     if (!tip.isEmpty())
01500       QToolTip::showText( pos, data.toString(), this );
01501   }
01502 }
01503 
01504 
01505 int KateIconBorder::annotationLineWidth( int line )
01506 {
01507   KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01508     m_view->annotationModel() : m_doc->annotationModel();
01509 
01510   if( model )
01511   {
01512     QVariant data = model->data( line, Qt::DisplayRole );
01513     return data.toString().length() * m_maxCharWidth + 8;
01514   }
01515   return 8;
01516 }
01517 
01518 void KateIconBorder::updateAnnotationLine( int line )
01519 {
01520   if( annotationLineWidth(line) > m_annotationBorderWidth )
01521   {
01522     m_annotationBorderWidth = annotationLineWidth(line);
01523     updateGeometry();
01524 
01525     QTimer::singleShot( 0, this, SLOT(update()) );
01526   }
01527 }
01528 
01529 void KateIconBorder::showAnnotationMenu( int line, const QPoint& pos)
01530 {
01531   KMenu menu;
01532   QAction a("Disable Annotation Bar", &menu);
01533   menu.addAction(&a);
01534   emit m_view->annotationContextMenuAboutToShow( m_view, &menu, line  );
01535   if (menu.exec(pos) == &a)
01536     m_view->setAnnotationBorderVisible(false);
01537 }
01538 
01539 void KateIconBorder::hideAnnotationTooltip()
01540 {
01541   QToolTip::hideText();
01542 }
01543 
01544 void KateIconBorder::updateAnnotationBorderWidth( )
01545 {
01546   m_annotationBorderWidth = 6;
01547   KTextEditor::AnnotationModel *model = m_view->annotationModel() ?
01548     m_view->annotationModel() : m_doc->annotationModel();
01549 
01550   if( model ) {
01551     for( int i = 0; i < m_view->doc()->lines(); i++ ) {
01552       int curwidth = annotationLineWidth( i );
01553       if( curwidth > m_annotationBorderWidth )
01554         m_annotationBorderWidth = curwidth;
01555     }
01556   }
01557 
01558   updateGeometry();
01559 
01560   QTimer::singleShot( 0, this, SLOT(update()) );
01561 }
01562 
01563 
01564 
01565 void KateIconBorder::annotationModelChanged( KTextEditor::AnnotationModel * oldmodel, KTextEditor::AnnotationModel * newmodel )
01566 {
01567   if( oldmodel )
01568   {
01569     oldmodel->disconnect( this );
01570   }
01571   if( newmodel )
01572   {
01573     connect( newmodel, SIGNAL(reset()), this, SLOT(updateAnnotationBorderWidth()) );
01574     connect( newmodel, SIGNAL(lineChanged( int )), this, SLOT(updateAnnotationLine( int )) );
01575   }
01576   updateAnnotationBorderWidth();
01577 }
01578 
01579 //END KateIconBorder
01580 
01581 //BEGIN KateViewEncodingAction
01582 // Acording to http://www.iana.org/assignments/ianacharset-mib
01583 // the default/unknown mib value is 2.
01584 #define MIB_DEFAULT 2
01585 
01586 class KateViewEncodingAction::Private
01587 {
01588   public:
01589     Private(KateViewEncodingAction *parent)
01590     : q(parent),
01591     defaultAction(0),
01592     currentSubAction(0)
01593     {
01594     }
01595     
01596     void init(bool);
01597     
01598     void _k_subActionTriggered(QAction*);
01599     
01600     KateViewEncodingAction *q;
01601     QAction *defaultAction;
01602     QAction *currentSubAction;
01603 };
01604 
01605 bool lessThanAction(KSelectAction *a, KSelectAction *b)
01606 {
01607   return a->text() < b->text();
01608 }
01609 
01610 void KateViewEncodingAction::Private::init(bool showAutoOptions)
01611 {
01612   QList<KSelectAction *> actions;
01613   
01614   q->setToolBarMode(MenuMode);
01615   defaultAction = q->addAction(i18nc("Encodings menu", "Disabled"));
01616   defaultAction->setData(QVariant((uint)KEncodingProber::None));
01617   
01618   QAction *tmp = q->addAction(i18nc("Encodings menu", "Autodetect"));
01619   tmp->setData(QVariant((uint)KEncodingProber::Universal));
01620   
01621   q->menu()->addSeparator();
01622 
01623   int i;
01624   foreach(const QStringList &encodingsForScript, KGlobal::charsets()->encodingsByScript())
01625   {
01626     KSelectAction* tmp = new KSelectAction(encodingsForScript.at(0),q);
01627     if (showAutoOptions)
01628     {
01629       KEncodingProber::ProberType scri=KEncodingProber::proberTypeForName(encodingsForScript.at(0));
01630       tmp->addAction(i18nc("Encodings menu","Autodetect"))->setData(QVariant((uint)scri));
01631       tmp->menu()->addSeparator();
01632     }
01633     for (i=1; i<encodingsForScript.size(); ++i)
01634     {
01635       tmp->addAction(encodingsForScript.at(i));
01636     }
01637     q->connect(tmp,SIGNAL(triggered(QAction*)),q,SLOT(_k_subActionTriggered(QAction*)));
01638     tmp->setCheckable(true);
01639     actions << tmp;
01640   }
01641   qSort(actions.begin(), actions.end(), lessThanAction);
01642   foreach (KSelectAction *action, actions)
01643     q->addAction(action);
01644 }
01645 
01646 void KateViewEncodingAction::Private::_k_subActionTriggered(QAction *action)
01647 {
01648   if (currentSubAction==action)
01649     return;
01650   currentSubAction=action;
01651   bool ok = false;
01652   int mib = q->mibForName(action->text(), &ok);
01653   if (ok)
01654   {
01655     emit q->triggered(action->text());
01656     emit q->triggered(q->codecForMib(mib));
01657   }
01658   else
01659   {
01660     if (!action->data().isNull())
01661       emit q->triggered((KEncodingProber::ProberType) action->data().toUInt());
01662   }
01663 }
01664 
01665 KateViewEncodingAction::KateViewEncodingAction(KateDocument *_doc, KateView *_view, const QString& text, QObject *parent)
01666 : KSelectAction(text, parent), doc(_doc), view (_view), d(new Private(this))
01667 {
01668   d->init(true);
01669   connect(this,SIGNAL(triggered(KEncodingProber::ProberType)),this,SLOT(setProberTypeForEncodingAutoDetection(KEncodingProber::ProberType)));
01670   connect(this,SIGNAL(triggered(const QString&)),this,SLOT(setEncoding(const QString&)));
01671   connect(menu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
01672 }
01673 
01674 KateViewEncodingAction::~KateViewEncodingAction()
01675 {
01676     delete d;
01677 }
01678 
01679 void KateViewEncodingAction::actionTriggered(QAction *action)
01680 {
01681   if (action == d->defaultAction)
01682     emit triggered(KEncodingProber::None);
01683   else
01684     emit triggered(KEncodingProber::Universal);
01685 }
01686 
01687 void KateViewEncodingAction::slotAboutToShow()
01688 {
01689   // setCurrentProberType(doc->proberTypeForEncodingAutoDetection());
01690 }
01691 
01692 void KateViewEncodingAction::setEncoding (const QString &e)
01693 {
01694   doc->setEncoding(e);
01695 
01696   view->reloadFile();
01697 
01698 }
01699 void KateViewEncodingAction::setProberTypeForEncodingAutoDetection (KEncodingProber::ProberType proberType)
01700 {
01701   doc->setProberTypeForEncodingAutoDetection(proberType);
01702   view->reloadFile();
01703 }
01704 
01705 KEncodingProber::ProberType KateViewEncodingAction::currentProberType() const
01706 {
01707   return d->currentSubAction->data().isNull()?
01708   KEncodingProber::None:
01709   (KEncodingProber::ProberType)d->currentSubAction->data().toUInt();
01710 }
01711 
01712 bool KateViewEncodingAction::setCurrentProberType(KEncodingProber::ProberType scri)
01713 {
01714     int i;
01715     
01716     if (scri == KEncodingProber::None) 
01717     {
01718       d->currentSubAction=actions().at(0);
01719       d->currentSubAction->trigger();
01720       return true;
01721     }
01722     
01723     if (scri == KEncodingProber::Universal) 
01724     {
01725       d->currentSubAction=actions().at(1);
01726       d->currentSubAction->trigger();
01727       return true;
01728     }
01729     
01730     for (i=2;i<actions().size();++i)
01731     {
01732       if (actions().at(i)->menu())
01733       {
01734         if (!actions().at(i)->menu()->actions().isEmpty()
01735           &&!actions().at(i)->menu()->actions().at(0)->data().isNull()
01736           &&actions().at(i)->menu()->actions().at(0)->data().toUInt()==(uint)scri
01737           )
01738         {
01739           d->currentSubAction=actions().at(i)->menu()->actions().at(0);
01740           d->currentSubAction->trigger();
01741           return true;
01742         }
01743       }
01744     }
01745     return false;
01746 }
01747 
01748 int KateViewEncodingAction::mibForName(const QString &codecName, bool *ok) const
01749 {
01750   // FIXME logic is good but code is ugly
01751   
01752   bool success = false;
01753   int mib = MIB_DEFAULT;
01754   KCharsets *charsets = KGlobal::charsets();
01755   
01756   if (codecName == d->defaultAction->text())
01757     success = true;
01758   else
01759   {
01760     QTextCodec *codec = charsets->codecForName(codecName, success);
01761     if (!success)
01762     {
01763       // Maybe we got a description name instead
01764       codec = charsets->codecForName(charsets->encodingForName(codecName), success);
01765     }
01766     
01767     if (codec)
01768       mib = codec->mibEnum();
01769   }
01770   
01771   if (ok)
01772     *ok = success;
01773   
01774   if (success)
01775     return mib;
01776   
01777   kWarning() << "Invalid codec name: "  << codecName;
01778   return MIB_DEFAULT;
01779 }
01780 
01781 QTextCodec *KateViewEncodingAction::codecForMib(int mib) const
01782 {
01783   if (mib == MIB_DEFAULT)
01784   {
01785     // FIXME offer to change the default codec
01786     return QTextCodec::codecForLocale();
01787   }
01788   else
01789     return QTextCodec::codecForMib(mib);
01790 }
01791 
01792 QTextCodec *KateViewEncodingAction::currentCodec() const
01793 {
01794   return codecForMib(currentCodecMib());
01795 }
01796 
01797 bool KateViewEncodingAction::setCurrentCodec( QTextCodec *codec )
01798 {
01799   if (!codec)
01800     return false;
01801   
01802   int i,j;
01803   for (i=2;i<actions().size();++i)
01804   {
01805     if (actions().at(i)->menu())
01806     {
01807       for (j=1;j<actions().at(i)->menu()->actions().size();++j)
01808       {
01809         if (!j && !actions().at(i)->menu()->actions().at(j)->data().isNull())
01810           continue;
01811         if (codec==KGlobal::charsets()->codecForName(actions().at(i)->menu()->actions().at(j)->text()))
01812         {
01813           d->currentSubAction=actions().at(i)->menu()->actions().at(j);
01814           d->currentSubAction->trigger();
01815           return true;
01816         }
01817       }
01818     }
01819   }
01820   return false;
01821   
01822 }
01823 
01824 QString KateViewEncodingAction::currentCodecName() const
01825 {
01826   return d->currentSubAction->text();
01827 }
01828 
01829 bool KateViewEncodingAction::setCurrentCodec( const QString &codecName )
01830 {
01831   return setCurrentCodec(KGlobal::charsets()->codecForName(codecName));
01832 }
01833 
01834 int KateViewEncodingAction::currentCodecMib() const
01835 {
01836   return mibForName(currentCodecName());
01837 }
01838 
01839 bool KateViewEncodingAction::setCurrentCodec( int mib )
01840 {
01841   if (mib == MIB_DEFAULT)
01842     return setCurrentAction(d->defaultAction);
01843   else
01844     return setCurrentCodec(codecForMib(mib));
01845 }
01846 //END KateViewEncodingAction
01847 
01848 //BEGIN KateViewBar related classes
01849 
01850 KateViewBarWidget::KateViewBarWidget (bool addCloseButton, KateView* view, QWidget *parent)
01851  : QWidget (parent), m_view(view)
01852 {
01853   QHBoxLayout *layout = new QHBoxLayout;
01854 
01855   // NOTE: Here be cosmetics.
01856   layout->setMargin(2);
01857 
01858   // hide button
01859   if (addCloseButton) {
01860     QToolButton *hideButton = new QToolButton(this);
01861     hideButton->setAutoRaise(true);
01862     hideButton->setIcon(KIcon("dialog-close"));
01863     connect(hideButton, SIGNAL(clicked()), SIGNAL(hideMe()));
01864     layout->addWidget(hideButton);
01865     layout->setAlignment( hideButton, Qt::AlignLeft|Qt::AlignTop );
01866   }
01867 
01868   // widget to be used as parent for the real content
01869   m_centralWidget = new QWidget (this);
01870   layout->addWidget(m_centralWidget);
01871 
01872   setLayout(layout);
01873   setFocusProxy(m_centralWidget);
01874 }
01875 
01876 KateStackedWidget::KateStackedWidget(QWidget* parent)
01877   : QStackedWidget(parent)
01878 {}
01879 
01880 QSize KateStackedWidget::sizeHint() const
01881 {
01882   if (currentWidget())
01883     return currentWidget()->sizeHint();
01884   return QStackedWidget::sizeHint();
01885 }
01886 
01887 QSize KateStackedWidget::minimumSize() const
01888 {
01889   if (currentWidget())
01890     return currentWidget()->minimumSize();
01891   return QStackedWidget::minimumSize();
01892 }
01893 
01894 
01895 
01896 KateViewBar::KateViewBar (bool external,KTextEditor::ViewBarContainer::Position pos,QWidget *parent, KateView *view)
01897  : QWidget (parent), m_external(external), m_pos(pos),m_view (view), m_permanentBarWidget(0)
01898 
01899 {
01900   m_layout = new QVBoxLayout(this);
01901   m_stack = new KateStackedWidget(this);
01902   m_layout->addWidget(m_stack);
01903 
01904   m_stack->hide();
01905   hide ();
01906 }
01907 
01908 void KateViewBar::addBarWidget (KateViewBarWidget *newBarWidget)
01909 {
01910   if (hasWidget(newBarWidget)) {
01911     kDebug(13025) << "this bar widget is already added";
01912     return;
01913   }
01914   // add new widget, invisible...
01915   newBarWidget->hide();
01916   m_stack->addWidget (newBarWidget);
01917   connect(newBarWidget, SIGNAL(hideMe()), SLOT(hideCurrentBarWidget()));
01918 
01919   kDebug(13025)<<"add barwidget " << newBarWidget;
01920 }
01921 
01922 void KateViewBar::addPermanentBarWidget (KateViewBarWidget *barWidget)
01923 {
01924   // remove old widget from layout (if any)
01925   if (m_permanentBarWidget) {
01926     m_permanentBarWidget->hide();
01927     m_layout->removeWidget(m_permanentBarWidget);
01928   }
01929 
01930   m_layout->addWidget(barWidget, 0, Qt::AlignBottom);
01931   m_permanentBarWidget = barWidget;
01932   m_permanentBarWidget->show();
01933 
01934   setViewBarVisible(true);
01935 }
01936 
01937 void KateViewBar::removePermanentBarWidget (KateViewBarWidget *barWidget)
01938 {
01939   if (m_permanentBarWidget != barWidget) {
01940     kDebug(13025) << "no such permanent widget exists in bar";
01941     return;
01942   }
01943 
01944   if (!m_permanentBarWidget)
01945     return;
01946 
01947   m_permanentBarWidget->hide();
01948   m_layout->removeWidget(m_permanentBarWidget);
01949   m_permanentBarWidget = 0;
01950 
01951   if (!m_stack->isVisible()) {
01952     setViewBarVisible(false);
01953   }
01954 }
01955 
01956 bool KateViewBar::hasPermanentWidget (KateViewBarWidget *barWidget ) const
01957 {
01958     return (m_permanentBarWidget == barWidget);
01959 }
01960 
01961 void KateViewBar::showBarWidget (KateViewBarWidget *barWidget)
01962 {
01963   // raise correct widget
01964   m_stack->setCurrentWidget (barWidget);
01965   barWidget->show();
01966   m_stack->show();
01967 
01968   // if we have any permanent widget, bar is always visible,
01969   // no need to show it
01970   if (!m_permanentBarWidget) {
01971     setViewBarVisible(true);
01972   }
01973 }
01974 
01975 bool KateViewBar::hasWidget(KateViewBarWidget* wid) const
01976 {
01977     int count = m_stack->count();
01978     for (int i=0; i<count; ++i) {
01979         if (m_stack->widget(i) == wid) {
01980             return true;
01981         }
01982     }
01983     return false;
01984 }
01985 
01986 void KateViewBar::hideCurrentBarWidget ()
01987 {
01988   KateViewBarWidget *current=qobject_cast<KateViewBarWidget*>(m_stack->currentWidget());
01989   if (current) {
01990     current->closed();
01991   }
01992   m_stack->hide();
01993 
01994   // if we have any permanent widget, bar is always visible,
01995   // no need to hide it
01996   if (!m_permanentBarWidget) {
01997     setViewBarVisible(false);
01998   }
01999 
02000   m_view->setFocus();
02001   kDebug(13025)<<"hide barwidget";
02002 }
02003 
02004 void KateViewBar::setViewBarVisible (bool visible)
02005 {
02006   if (m_external) {
02007     KTextEditor::ViewBarContainer *viewBarContainer=qobject_cast<KTextEditor::ViewBarContainer*>( KateGlobal::self()->container() );
02008     if (viewBarContainer) {
02009       if (visible) {
02010         viewBarContainer->showViewBarForView(m_view,m_pos);
02011       } else {
02012         viewBarContainer->hideViewBarForView(m_view,m_pos);
02013       }
02014     }
02015   } else {
02016     setVisible (visible);
02017   }
02018 }
02019 
02020 void KateViewBar::keyPressEvent(QKeyEvent* event)
02021 {
02022   if (event->key() == Qt::Key_Escape) {
02023     hideCurrentBarWidget();
02024     return;
02025   }
02026   QWidget::keyPressEvent(event);
02027 
02028 }
02029 
02030 void KateViewBar::hideEvent(QHideEvent* event)
02031 {
02032   Q_UNUSED(event);
02033 //   if (!event->spontaneous())
02034 //     m_view->setFocus();
02035 }
02036 
02037 //END KateViewBar related classes
02038 
02039 #include "kateviewhelpers.moc"
02040 
02041 // kate: space-indent on; indent-width 2; replace-tabs on;
02042 

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal