• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

Kate

kateviewhelpers.cpp

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

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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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