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

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
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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