Diffstat (limited to 'noncore/apps/tinykate/libkate/view/kateview.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/tinykate/libkate/view/kateview.cpp | 2923 |
1 files changed, 2923 insertions, 0 deletions
diff --git a/noncore/apps/tinykate/libkate/view/kateview.cpp b/noncore/apps/tinykate/libkate/view/kateview.cpp new file mode 100644 index 0000000..8f3a25e --- a/dev/null +++ b/noncore/apps/tinykate/libkate/view/kateview.cpp @@ -0,0 +1,2923 @@ +/*************************************************************************** + kateview.cpp - description + ------------------- + begin : Mon Jan 15 2001 + copyright : (C) 2001 by Christoph "Crossfire" Cullmann + (C) 2002 by Joseph Wenninger + email : crossfire@babylon2k.de + jowenn@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +/* + Copyright (C) 1998, 1999 Jochen Wilhelmy + digisnap@cs.tu-berlin.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + + + +#include "kateview.h" + +#include "../document/katedocument.h" +#include "../document/katecmd.h" +#include "../document/katehighlight.h" +#include "kateviewdialog.h" +#include "../document/katedialogs.h" + +#include <qfocusdata.h> +#include <kdebug.h> +#include <kapplication.h> +#include <qscrollbar.h> +#include <qiodevice.h> +#include <qpopupmenu.h> +#include <kpopupmenu.h> +#include <qkeycode.h> +#include <qintdict.h> +#include <kconfig.h> +#include <qfont.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qfileinfo.h> +#include <qfile.h> +#include <qevent.h> +#include <qdir.h> +#include <qvbox.h> +#include <qprintdialog.h> +#include <qpaintdevicemetrics.h> +#include <qiodevice.h> +#include <qbuffer.h> +#include <qfocusdata.h> +#include <klocale.h> +#include <kglobal.h> +#include <kdebug.h> +#include <kmessagebox.h> +#include <qregexp.h> +#include <kdialogbase.h> +#include <klineeditdlg.h> +#include <qapplication.h> +#include <kfiledialog.h> +#include <kiconloader.h> +#include "../document/katetextline.h" +#include "kateviewdialog.h" +#include "kateundohistory.h" +#include <qlayout.h> + +KateViewInternal::KateViewInternal(KateView *view, KateDocument *doc) : QWidget(view) +{ + waitForPreHighlight=-1; + myView = view; + myDoc = doc; + + iconBorderWidth = 16; + iconBorderHeight = 800; + + QWidget::setCursor(ibeamCursor); + setBackgroundMode(NoBackground); + + setFocusPolicy(StrongFocus); + + xScroll = new QScrollBar(QScrollBar::Horizontal,myView); + yScroll = new QScrollBar(QScrollBar::Vertical,myView); + connect(xScroll,SIGNAL(valueChanged(int)),SLOT(changeXPos(int))); + connect(yScroll,SIGNAL(valueChanged(int)),SLOT(changeYPos(int))); + connect(yScroll,SIGNAL(valueChanged(int)),myView,SIGNAL(scrollValueChanged(int))); + connect( doc, SIGNAL (preHighlightChanged(long)),this,SLOT(slotPreHighlightUpdate(long))); + + xPos = 0; + yPos = 0; + + scrollTimer = 0; + + cursor.x = 0; + cursor.y = 0; + cursorOn = false; + cursorTimer = 0; + cXPos = 0; + cOldXPos = 0; + + startLine = 0; + endLine = -1; + + exposeCursor = false; + updateState = 0; + numLines = 0; + lineRanges = 0L; + newXPos = -1; + newYPos = -1; + + drawBuffer = new QPixmap (); + drawBuffer->setOptimization (QPixmap::BestOptim); + + bm.sXPos = 0; + bm.eXPos = -1; + +} + + +KateViewInternal::~KateViewInternal() +{ + delete [] lineRanges; + delete drawBuffer; +} + + +void KateViewInternal::slotPreHighlightUpdate(long line) +{ + //kdDebug()<<QString("slotPreHighlightUpdate - Wait for: %1, line: %2").arg(waitForPreHighlight).arg(line)<<endl; + if (waitForPreHighlight!=-1) + { + if (line>=waitForPreHighlight) + { + waitForPreHighlight=-1; + repaint(); + } + } +} + +void KateViewInternal::doCursorCommand(VConfig &c, int cmdNum) { + + switch (cmdNum) { + case KateView::cmLeft: + cursorLeft(c); + break; + case KateView::cmRight: + cursorRight(c); + break; + case KateView::cmWordLeft: + wordLeft(c); + break; + case KateView::cmWordRight: + wordRight(c); + break; + case KateView::cmHome: + home(c); + break; + case KateView::cmEnd: + end(c); + break; + case KateView::cmUp: + cursorUp(c); + break; + case KateView::cmDown: + cursorDown(c); + break; + case KateView::cmScrollUp: + scrollUp(c); + break; + case KateView::cmScrollDown: + scrollDown(c); + break; + case KateView::cmTopOfView: + topOfView(c); + break; + case KateView::cmBottomOfView: + bottomOfView(c); + break; + case KateView::cmPageUp: + pageUp(c); + break; + case KateView::cmPageDown: + pageDown(c); + break; + case KateView::cmTop: + top_home(c); + break; + case KateView::cmBottom: + bottom_end(c); + break; + } +} + +void KateViewInternal::doEditCommand(VConfig &c, int cmdNum) { + + switch (cmdNum) { + case KateView::cmCopy: + myDoc->copy(c.flags); + return; + case KateView::cmSelectAll: + myDoc->selectAll(); + return; + case KateView::cmDeselectAll: + myDoc->deselectAll(); + return; + case KateView::cmInvertSelection: + myDoc->invertSelection(); + return; + } + if (myView->isReadOnly()) return; + switch (cmdNum) { + case KateView::cmReturn: + if (c.flags & KateView::cfDelOnInput) myDoc->delMarkedText(c); + myDoc->newLine(c); + //emit returnPressed(); + //e->ignore(); + return; + case KateView::cmDelete: + if ((c.flags & KateView::cfDelOnInput) && myDoc->hasMarkedText()) + myDoc->delMarkedText(c); + else myDoc->del(c); + return; + case KateView::cmBackspace: + if ((c.flags & KateView::cfDelOnInput) && myDoc->hasMarkedText()) + myDoc->delMarkedText(c); + else myDoc->backspace(c); + return; + case KateView::cmKillLine: + myDoc->killLine(c); + return; + case KateView::cmCut: + myDoc->cut(c); + return; + case KateView::cmPaste: + if (c.flags & KateView::cfDelOnInput) myDoc->delMarkedText(c); + myDoc->paste(c); + return; + case KateView::cmUndo: + myDoc->undo(c); + return; + case KateView::cmRedo: + myDoc->redo(c); + return; + case KateView::cmIndent: + myDoc->indent(c); + return; + case KateView::cmUnindent: + myDoc->unIndent(c); + return; + case KateView::cmCleanIndent: + myDoc->cleanIndent(c); + return; + case KateView::cmComment: + myDoc->comment(c); + return; + case KateView::cmUncomment: + myDoc->unComment(c); + return; + } +} + +void KateViewInternal::cursorLeft(VConfig &c) { + + cursor.x--; + if (c.flags & KateView::cfWrapCursor && cursor.x < 0 && cursor.y > 0) { + cursor.y--; + cursor.x = myDoc->textLength(cursor.y); + } + cOldXPos = cXPos = myDoc->textWidth(cursor); + changeState(c); +} + +void KateViewInternal::cursorRight(VConfig &c) { + + if (c.flags & KateView::cfWrapCursor) { + if (cursor.x >= myDoc->textLength(cursor.y)) { + if (cursor.y == myDoc->lastLine()) return; + cursor.y++; + cursor.x = -1; + } + } + cursor.x++; + cOldXPos = cXPos = myDoc->textWidth(cursor); + changeState(c); +} + +void KateViewInternal::wordLeft(VConfig &c) { + Highlight *highlight; + + highlight = myDoc->highlight(); + TextLine::Ptr textLine = myDoc->getTextLine(cursor.y); + + if (cursor.x > 0) { + do { + cursor.x--; + } while (cursor.x > 0 && !highlight->isInWord(textLine->getChar(cursor.x))); + while (cursor.x > 0 && highlight->isInWord(textLine->getChar(cursor.x -1))) + cursor.x--; + } else { + if (cursor.y > 0) { + cursor.y--; + textLine = myDoc->getTextLine(cursor.y); + cursor.x = textLine->length(); + } + } + + cOldXPos = cXPos = myDoc->textWidth(cursor); + changeState(c); +} + +void KateViewInternal::wordRight(VConfig &c) { + Highlight *highlight; + int len; + + highlight = myDoc->highlight(); + TextLine::Ptr textLine = myDoc->getTextLine(cursor.y); + len = textLine->length(); + + if (cursor.x < len) { + do { + cursor.x++; + } while (cursor.x < len && highlight->isInWord(textLine->getChar(cursor.x))); + while (cursor.x < len && !highlight->isInWord(textLine->getChar(cursor.x))) + cursor.x++; + } else { + if (cursor.y < myDoc->lastLine()) { + cursor.y++; + textLine = myDoc->getTextLine(cursor.y); + cursor.x = 0; + } + } + + cOldXPos = cXPos = myDoc->textWidth(cursor); + changeState(c); +} + +void KateViewInternal::home(VConfig &c) { + int lc; + + lc = (c.flags & KateView::cfSmartHome) ? myDoc->getTextLine(cursor.y)->firstChar() : 0; + if (lc <= 0 || cursor.x == lc) { + cursor.x = 0; + cOldXPos = cXPos = 0; + } else { + cursor.x = lc; + cOldXPos = cXPos = myDoc->textWidth(cursor); + } + + changeState(c); +} + +void KateViewInternal::end(VConfig &c) { + cursor.x = myDoc->textLength(cursor.y); + cOldXPos = cXPos = myDoc->textWidth(cursor); + changeState(c); +} + + +void KateViewInternal::cursorUp(VConfig &c) { + + cursor.y--; + cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos); + changeState(c); +} + + +void KateViewInternal::cursorDown(VConfig &c) { + int x; + + if (cursor.y == myDoc->lastLine()) { + x = myDoc->textLength(cursor.y); + if (cursor.x >= x) return; + cursor.x = x; + cXPos = myDoc->textWidth(cursor); + } else { + cursor.y++; + cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor, cursor, cOldXPos); + } + changeState(c); +} + +void KateViewInternal::scrollUp(VConfig &c) { + + if (! yPos) return; + + newYPos = yPos - myDoc->fontHeight; + if (cursor.y == (yPos + height())/myDoc->fontHeight -1) { + cursor.y--; + cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos); + + changeState(c); + } +} + +void KateViewInternal::scrollDown(VConfig &c) { + + if (endLine >= myDoc->lastLine()) return; + + newYPos = yPos + myDoc->fontHeight; + if (cursor.y == (yPos + myDoc->fontHeight -1)/myDoc->fontHeight) { + cursor.y++; + cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos); + changeState(c); + } +} + +void KateViewInternal::topOfView(VConfig &c) { + + cursor.y = (yPos + myDoc->fontHeight -1)/myDoc->fontHeight; + cursor.x = 0; + cOldXPos = cXPos = 0; + changeState(c); +} + +void KateViewInternal::bottomOfView(VConfig &c) { + + cursor.y = (yPos + height())/myDoc->fontHeight -1; + if (cursor.y < 0) cursor.y = 0; + if (cursor.y > myDoc->lastLine()) cursor.y = myDoc->lastLine(); + cursor.x = 0; + cOldXPos = cXPos = 0; + changeState(c); +} + +void KateViewInternal::pageUp(VConfig &c) { + int lines = (endLine - startLine - 1); + + if (lines <= 0) lines = 1; + + if (!(c.flags & KateView::cfPageUDMovesCursor) && yPos > 0) { + newYPos = yPos - lines * myDoc->fontHeight; + if (newYPos < 0) newYPos = 0; + } + cursor.y -= lines; + cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor, cursor, cOldXPos); + changeState(c); +// cursorPageUp(c); +} + +void KateViewInternal::pageDown(VConfig &c) { + + int lines = (endLine - startLine - 1); + + if (!(c.flags & KateView::cfPageUDMovesCursor) && endLine < myDoc->lastLine()) { + if (lines < myDoc->lastLine() - endLine) + newYPos = yPos + lines * myDoc->fontHeight; + else + newYPos = yPos + (myDoc->lastLine() - endLine) * myDoc->fontHeight; + } + cursor.y += lines; + cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos); + changeState(c); +// cursorPageDown(c); +} + +// go to the top, same X position +void KateViewInternal::top(VConfig &c) { + +// cursor.x = 0; + cursor.y = 0; + cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos); +// cOldXPos = cXPos = 0; + changeState(c); +} + +// go to the bottom, same X position +void KateViewInternal::bottom(VConfig &c) { + +// cursor.x = 0; + cursor.y = myDoc->lastLine(); + cXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor,cursor,cOldXPos); +// cOldXPos = cXPos = 0; + changeState(c); +} + +// go to the top left corner +void KateViewInternal::top_home(VConfig &c) +{ + cursor.y = 0; + cursor.x = 0; + cOldXPos = cXPos = 0; + changeState(c); +} + +// go to the bottom right corner +void KateViewInternal::bottom_end(VConfig &c) { + + cursor.y = myDoc->lastLine(); + cursor.x = myDoc->textLength(cursor.y); + cOldXPos = cXPos = myDoc->textWidth(cursor); + changeState(c); +} + + +void KateViewInternal::changeXPos(int p) { + int dx; + + dx = xPos - p; + xPos = p; + if (QABS(dx) < width()) scroll(dx, 0); else update(); +} + +void KateViewInternal::changeYPos(int p) { + int dy; + + dy = yPos - p; + yPos = p; + clearDirtyCache(height()); + + if (QABS(dy) < height()) + { + scroll(0, dy); + leftBorder->scroll(0, dy); + } + else + update(); +} + + +void KateViewInternal::getVConfig(VConfig &c) { + + c.view = myView; + c.cursor = cursor; + c.cXPos = cXPos; + c.flags = myView->configFlags; +} + +void KateViewInternal::changeState(VConfig &c) { + /* + * we need to be sure to kill the selection on an attempted cursor + * movement even if the cursor doesn't physically move, + * but we need to be careful not to do some other things in this case, + * like we don't want to expose the cursor + */ + +// if (cursor.x == c.cursor.x && cursor.y == c.cursor.y) return; + bool nullMove = (cursor.x == c.cursor.x && cursor.y == c.cursor.y); + +// if (cursor.y != c.cursor.y || c.flags & KateView::cfMark) myDoc->recordReset(); + + if (! nullMove) { + + exposeCursor = true; + + // mark old position of cursor as dirty + if (cursorOn) { + tagLines(c.cursor.y, c.cursor.y, c.cXPos -2, c.cXPos +3); + cursorOn = false; + } + + // mark old bracket mark position as dirty + if (bm.sXPos < bm.eXPos) { + tagLines(bm.cursor.y, bm.cursor.y, bm.sXPos, bm.eXPos); + } + // make new bracket mark + myDoc->newBracketMark(cursor, bm); + + // remove trailing spaces when leaving a line + if (c.flags & KateView::cfRemoveSpaces && cursor.y != c.cursor.y) { + TextLine::Ptr textLine = myDoc->getTextLine(c.cursor.y); + int newLen = textLine->lastChar(); + if (newLen != textLine->length()) { + textLine->truncate(newLen); + // if some spaces are removed, tag the line as dirty + myDoc->tagLines(c.cursor.y, c.cursor.y); + } + } + } + + if (c.flags & KateView::cfMark) { + if (! nullMove) + myDoc->selectTo(c, cursor, cXPos); + } else { + if (!(c.flags & KateView::cfPersistent)) + myDoc->deselectAll(); + } +} + +void KateViewInternal::insLine(int line) { + + if (line <= cursor.y) { + cursor.y++; + } + if (line < startLine) { + startLine++; + endLine++; + yPos += myDoc->fontHeight; + } else if (line <= endLine) { + tagAll(); + } +} + +void KateViewInternal::delLine(int line) { + + if (line <= cursor.y && cursor.y > 0) { + cursor.y--; + } + if (line < startLine) { + startLine--; + endLine--; + yPos -= myDoc->fontHeight; + } else if (line <= endLine) { + tagAll(); + } +} + +void KateViewInternal::updateCursor() { + cOldXPos = cXPos = myDoc->textWidth(cursor); +} + + +void KateViewInternal::updateCursor(PointStruc &newCursor) { + updateCursor(newCursor, myView->config()); +} + +void KateViewInternal::updateCursor(PointStruc &newCursor, int flags) { + + if (!(flags & KateView::cfPersistent)) myDoc->deselectAll(); + + exposeCursor = true; + if (cursorOn) { + tagLines(cursor.y, cursor.y, cXPos -2, cXPos +3); + cursorOn = false; + } + + if (bm.sXPos < bm.eXPos) { + tagLines(bm.cursor.y, bm.cursor.y, bm.sXPos, bm.eXPos); + } + myDoc->newBracketMark(newCursor, bm); + + cursor = newCursor; + cOldXPos = cXPos = myDoc->textWidth(cursor); +} + +// init the line dirty cache +void KateViewInternal::clearDirtyCache(int height) { + int lines, z; + + // calc start and end line of visible part + startLine = yPos/myDoc->fontHeight; + endLine = (yPos + height -1)/myDoc->fontHeight; + + updateState = 0; + + lines = endLine - startLine +1; + if (lines > numLines) { // resize the dirty cache + numLines = lines*2; + delete [] lineRanges; + lineRanges = new LineRange[numLines]; + } + + for (z = 0; z < lines; z++) { // clear all lines + lineRanges[z].start = 0xffffff; + lineRanges[z].end = -2; + } + newXPos = newYPos = -1; +} + +void KateViewInternal::tagLines(int start, int end, int x1, int x2) { + LineRange *r; + int z; + + start -= startLine; + if (start < 0) start = 0; + end -= startLine; + if (end > endLine - startLine) end = endLine - startLine; + + if (x1 <= 0) x1 = -2; + if (x1 < xPos-2) x1 = xPos-2; + if (x2 > width() + xPos-2) x2 = width() + xPos-2; + if (x1 >= x2) return; + + r = &lineRanges[start]; + for (z = start; z <= end; z++) { + if (x1 < r->start) r->start = x1; + if (x2 > r->end) r->end = x2; + r++; + updateState |= 1; + } +} + +void KateViewInternal::tagAll() { + updateState = 3; +} + +void KateViewInternal::setPos(int x, int y) { + newXPos = x; + newYPos = y; +} + +void KateViewInternal::center() { + newXPos = 0; + newYPos = cursor.y*myDoc->fontHeight - height()/2; + if (newYPos < 0) newYPos = 0; +} + +void KateViewInternal::updateView(int flags) { + int fontHeight; + int oldXPos, oldYPos; + int w, h; + int z; + bool b; + int xMax, yMax; + int cYPos; + int cXPosMin, cXPosMax, cYPosMin, cYPosMax; + int dx, dy; + int pageScroll; + int scrollbarWidth = style().scrollBarExtent().width(); + +//debug("upView %d %d %d %d %d", exposeCursor, updateState, flags, newXPos, newYPos); + if (exposeCursor || flags & KateView::ufDocGeometry) { + emit myView->newCurPos(); + } else { + if (updateState == 0 && newXPos < 0 && newYPos < 0) return; + } + + if (cursorTimer) { + killTimer(cursorTimer); + cursorTimer = startTimer(KApplication::cursorFlashTime() / 2); + cursorOn = true; + } + + oldXPos = xPos; + oldYPos = yPos; +/* if (flags & ufPos) { + xPos = newXPos; + yPos = newYPos; + exposeCursor = true; + }*/ + if (newXPos >= 0) xPos = newXPos; + if (newYPos >= 0) yPos = newYPos; + + fontHeight = myDoc->fontHeight; + cYPos = cursor.y*fontHeight; + + z = 0; + do { + w = myView->width() - 4; + h = myView->height() - 4; + + xMax = myDoc->textWidth() - w; + b = (xPos > 0 || xMax > 0); + if (b) h -= scrollbarWidth; + yMax = myDoc->textHeight() - h; + if (yPos > 0 || yMax > 0) { + w -= scrollbarWidth; + xMax += scrollbarWidth; + if (!b && xMax > 0) { + h -= scrollbarWidth; + yMax += scrollbarWidth; + } + } + + if (!exposeCursor) break; +// if (flags & KateView::ufNoScroll) break; +/* + if (flags & KateView::ufCenter) { + cXPosMin = xPos + w/3; + cXPosMax = xPos + (w*2)/3; + cYPosMin = yPos + h/3; + cYPosMax = yPos + ((h - fontHeight)*2)/3; + } else {*/ + cXPosMin = xPos + 4; + cXPosMax = xPos + w - 8; + cYPosMin = yPos; + cYPosMax = yPos + (h - fontHeight); +// } + + if (cXPos < cXPosMin) { + xPos -= cXPosMin - cXPos; + } + if (xPos < 0) xPos = 0; + if (cXPos > cXPosMax) { + xPos += cXPos - cXPosMax; + } + if (cYPos < cYPosMin) { + yPos -= cYPosMin - cYPos; + } + if (yPos < 0) yPos = 0; + if (cYPos > cYPosMax) { + yPos += cYPos - cYPosMax; + } + + z++; + } while (z < 2); + + if (xMax < xPos) xMax = xPos; + if (yMax < yPos) yMax = yPos; + + if (xMax > 0) { + pageScroll = w - (w % fontHeight) - fontHeight; + if (pageScroll <= 0) + pageScroll = fontHeight; + + xScroll->blockSignals(true); + xScroll->setGeometry(2,h + 2,w,scrollbarWidth); + xScroll->setRange(0,xMax); + xScroll->setValue(xPos); + xScroll->setSteps(fontHeight,pageScroll); + xScroll->blockSignals(false); + xScroll->show(); + } else xScroll->hide(); + + if (yMax > 0) { + pageScroll = h - (h % fontHeight) - fontHeight; + if (pageScroll <= 0) + pageScroll = fontHeight; + + yScroll->blockSignals(true); + yScroll->setGeometry(w + 2,2,scrollbarWidth,h); + yScroll->setRange(0,yMax); + yScroll->setValue(yPos); + yScroll->setSteps(fontHeight,pageScroll); + yScroll->blockSignals(false); + yScroll->show(); + } else yScroll->hide(); + + if (w != width() || h != height()) { + clearDirtyCache(h); + resize(w,h); + } else { + dx = oldXPos - xPos; + dy = oldYPos - yPos; + + b = updateState == 3; + if (flags & KateView::ufUpdateOnScroll) { + b |= dx || dy; + } else { + b |= QABS(dx)*3 > w*2 || QABS(dy)*3 > h*2; + } + + if (b) { + clearDirtyCache(h); + update(); + } else { + if (dy) + leftBorder->scroll(0, dy); + if (updateState > 0) paintTextLines(oldXPos, oldYPos); + clearDirtyCache(h); + + if (dx || dy) { + scroll(dx,dy); +// kapp->syncX(); +// scroll2(dx - dx/2,dy - dy/2); +// } else { + } + if (cursorOn) paintCursor(); + if (bm.eXPos > bm.sXPos) paintBracketMark(); + } + } + exposeCursor = false; +// updateState = 0; +} + + +void KateViewInternal::paintTextLines(int xPos, int yPos) { +// int xStart, xEnd; + int line;//, z; + int h; + LineRange *r; + + if (!drawBuffer) return; + if (drawBuffer->isNull()) return; + + QPainter paint; + paint.begin(drawBuffer); + + h = myDoc->fontHeight; + r = lineRanges; + for (line = startLine; line <= endLine; line++) { + if (r->start < r->end) { +//debug("painttextline %d %d %d", line, r->start, r->end); + myDoc->paintTextLine(paint, line, r->start, r->end, myView->configFlags & KateView::cfShowTabs); + bitBlt(this, r->start - (xPos-2), line*h - yPos, drawBuffer, 0, 0, + r->end - r->start, h); + leftBorder->paintLine(line); + } + r++; + } + + paint.end(); +} + +void KateViewInternal::paintCursor() { + int h, y, x; + static int cx = 0, cy = 0, ch = 0; + + h = myDoc->fontHeight; + y = h*cursor.y - yPos; + x = cXPos - (xPos-2); + + if(myDoc->myFont != font()) setFont(myDoc->myFont); + if(cx != x || cy != y || ch != h){ + cx = x; + cy = y; + ch = h; + setMicroFocusHint(cx, cy, 0, ch - 2); + } + + QPainter paint; + if (cursorOn) { + paint.begin(this); + paint.setClipping(false); + paint.setPen(myDoc->cursorCol(cursor.x,cursor.y)); + + h += y - 1; + paint.drawLine(x, y, x, h); + + paint.end(); + } else { if (drawBuffer && !drawBuffer->isNull()) { + paint.begin(drawBuffer); + myDoc->paintTextLine(paint, cursor.y, cXPos - 2, cXPos + 3, myView->configFlags & KateView::cfShowTabs); + bitBlt(this,x - 2,y, drawBuffer, 0, 0, 5, h); + paint.end(); } + } + +} + +void KateViewInternal::paintBracketMark() { + int y; + + y = myDoc->fontHeight*(bm.cursor.y +1) - yPos -1; + + QPainter paint; + paint.begin(this); + paint.setPen(myDoc->cursorCol(bm.cursor.x, bm.cursor.y)); + + paint.drawLine(bm.sXPos - (xPos-2), y, bm.eXPos - (xPos-2) -1, y); + paint.end(); +} + +void KateViewInternal::placeCursor(int x, int y, int flags) { + VConfig c; + + getVConfig(c); + c.flags |= flags; + cursor.y = (yPos + y)/myDoc->fontHeight; + cXPos = cOldXPos = myDoc->textWidth(c.flags & KateView::cfWrapCursor, cursor,xPos-2 + x); + changeState(c); +} + +// given physical coordinates, report whether the text there is selected +bool KateViewInternal::isTargetSelected(int x, int y) { + + y = (yPos + y) / myDoc->fontHeight; + + TextLine::Ptr line = myDoc->getTextLine(y); + if (!line) + return false; + + x = myDoc->textPos(line, x); + + return line->isSelected(x); +} + +void KateViewInternal::focusInEvent(QFocusEvent *) { +// debug("got focus %d",cursorTimer); + + if (!cursorTimer) { + cursorTimer = startTimer(KApplication::cursorFlashTime() / 2); + cursorOn = true; + paintCursor(); + } +} + +void KateViewInternal::focusOutEvent(QFocusEvent *) { +// debug("lost focus %d", cursorTimer); + + if (cursorTimer) { + killTimer(cursorTimer); + cursorTimer = 0; + } + + if (cursorOn) { + cursorOn = false; + paintCursor(); + } +} + +void KateViewInternal::keyPressEvent(QKeyEvent *e) { + VConfig c; +// int ascii; + +/* if (e->state() & AltButton) { + e->ignore(); + return; + }*/ +// debug("ascii %i, key %i, state %i",e->ascii(), e->key(), e->state()); + + getVConfig(c); +// ascii = e->ascii(); + + if (!myView->isReadOnly()) { + if (c.flags & KateView::cfTabIndents && myDoc->hasMarkedText()) { + if (e->key() == Qt::Key_Tab) { + myDoc->indent(c); + myDoc->updateViews(); + return; + } + if (e->key() == Qt::Key_Backtab) { + myDoc->unIndent(c); + myDoc->updateViews(); + return; + } + } + if ( !(e->state() & ControlButton ) && myDoc->insertChars(c, e->text())) { + myDoc->updateViews(); + e->accept(); + return; + } + } + e->ignore(); +} + +void KateViewInternal::mousePressEvent(QMouseEvent *e) { + + if (e->button() == LeftButton) { + + int flags; + + flags = 0; + if (e->state() & ShiftButton) { + flags |= KateView::cfMark; + if (e->state() & ControlButton) flags |= KateView::cfMark | KateView::cfKeepSelection; + } + placeCursor(e->x(), e->y(), flags); + scrollX = 0; + scrollY = 0; + if (!scrollTimer) scrollTimer = startTimer(50); + myDoc->updateViews(); + } + if (e->button() == MidButton) { + placeCursor(e->x(), e->y()); + if (! myView->isReadOnly()) + myView->paste(); + } + if (myView->rmbMenu && e->button() == RightButton) { + myView->rmbMenu->popup(mapToGlobal(e->pos())); + } + myView->mousePressEvent(e); // this doesn't do anything, does it? + // it does :-), we need this for KDevelop, so please don't uncomment it again -Sandy +} + +void KateViewInternal::mouseDoubleClickEvent(QMouseEvent *e) { + + if (e->button() == LeftButton) { + VConfig c; + getVConfig(c); + myDoc->selectWord(c.cursor, c.flags); + myDoc->updateViews(); + } +} + +void KateViewInternal::mouseReleaseEvent(QMouseEvent *e) { + + if (e->button() == LeftButton) { + if (myView->config() & KateView::cfMouseAutoCopy) myView->copy(); + killTimer(scrollTimer); + scrollTimer = 0; + } +} + +void KateViewInternal::mouseMoveEvent(QMouseEvent *e) { + + if (e->state() & LeftButton) { + int flags; + int d; + int x = e->x(), + y = e->y(); + + mouseX = e->x(); + mouseY = e->y(); + scrollX = 0; + scrollY = 0; + d = myDoc->fontHeight; + if (mouseX < 0) { + mouseX = 0; + scrollX = -d; + } + if (mouseX > width()) { + mouseX = width(); + scrollX = d; + } + if (mouseY < 0) { + mouseY = 0; + scrollY = -d; + } + if (mouseY > height()) { + mouseY = height(); + scrollY = d; + } +//debug("modifiers %d", ((KGuiCmdApp *) kapp)->getModifiers()); + flags = KateView::cfMark; + if (e->state() & ControlButton) flags |= KateView::cfKeepSelection; + placeCursor(mouseX, mouseY, flags); + myDoc->updateViews(/*ufNoScroll*/); + } +} + + + +void KateViewInternal::wheelEvent( QWheelEvent *e ) +{ + if( yScroll->isVisible() == true ) + { + QApplication::sendEvent( yScroll, e ); + } +} + + + +void KateViewInternal::paintEvent(QPaintEvent *e) { + int xStart, xEnd; + int h; + int line, y, yEnd; + + QRect updateR = e->rect(); + + if (!drawBuffer) return; + if (drawBuffer->isNull()) return; + + QPainter paint; + paint.begin(drawBuffer); + + xStart = xPos-2 + updateR.x(); + xEnd = xStart + updateR.width(); + + h = myDoc->fontHeight; + line = (yPos + updateR.y()) / h; + y = line*h - yPos; + yEnd = updateR.y() + updateR.height(); + waitForPreHighlight=myDoc->needPreHighlight(waitForPreHighlight=line+((long)(yEnd-y)/h)+5); + + while (y < yEnd) + { + TextLine *textLine; + int ctxNum = 0; + myDoc->paintTextLine(paint, line, xStart, xEnd, myView->configFlags & KateView::cfShowTabs); + bitBlt(this, updateR.x(), y, drawBuffer, 0, 0, updateR.width(), h); + leftBorder->paintLine(line); + line++; + y += h; + } + paint.end(); + + if (cursorOn) paintCursor(); + if (bm.eXPos > bm.sXPos) paintBracketMark(); +} + +void KateViewInternal::resizeEvent(QResizeEvent *) +{ + drawBuffer->resize (width(), myDoc->fontHeight); + leftBorder->resize(iconBorderWidth, height()); +} + +void KateViewInternal::timerEvent(QTimerEvent *e) { + if (e->timerId() == cursorTimer) { + cursorOn = !cursorOn; + paintCursor(); + } + if (e->timerId() == scrollTimer && (scrollX | scrollY)) { + xScroll->setValue(xPos + scrollX); + yScroll->setValue(yPos + scrollY); + + placeCursor(mouseX, mouseY, KateView::cfMark); + myDoc->updateViews(/*ufNoScroll*/); + } +} + +uint KateView::uniqueID = 0; + +KateView::KateView(KateDocument *doc, QWidget *parent, const char * name) : Kate::View (doc, parent, name) +{ + + myViewID = uniqueID; + uniqueID++; + + active = false; + myIconBorder = false; + + myDoc = doc; + myViewInternal = new KateViewInternal (this,doc); + myViewInternal->move(2, 2); + myViewInternal->leftBorder = new KateIconBorder(this, myViewInternal); + myViewInternal->leftBorder->setGeometry(2, 2, myViewInternal->iconBorderWidth, myViewInternal->iconBorderHeight); + myViewInternal->leftBorder->hide(); + + doc->addView( this ); + + + // some defaults + configFlags = KateView::cfAutoIndent | KateView::cfBackspaceIndents + | KateView::cfTabIndents | KateView::cfKeepIndentProfile + | KateView::cfRemoveSpaces + | KateView::cfDelOnInput | KateView::cfMouseAutoCopy | KateView::cfWrapCursor + | KateView::cfGroupUndo | KateView::cfShowTabs | KateView::cfSmartHome; + + searchFlags = 0; + replacePrompt = 0L; + rmbMenu = 0L; + + + setFocusProxy( myViewInternal ); + myViewInternal->setFocus(); + resize(parent->width() -4, parent->height() -4); + + + myViewInternal->installEventFilter( this ); + + //setupActions(); + + connect( this, SIGNAL( newStatus() ), this, SLOT( slotUpdate() ) ); + connect( this, SIGNAL( newUndo() ), this, SLOT( slotNewUndo() ) ); + connect( doc, SIGNAL( fileNameChanged() ), this, SLOT( slotFileStatusChanged() ) ); + connect( doc, SIGNAL( highlightChanged() ), this, SLOT( slotHighlightChanged() ) ); + + readConfig(); +// setHighlight->setCurrentItem(getHl()); + slotUpdate(); +} + +KateView::~KateView() +{ + + if (myDoc && !myDoc->m_bSingleViewMode) + myDoc->removeView( this ); + + delete myViewInternal; + +} + +#if 0 +void KateView::setupActions() +{ +#if 0 + KStdAction::close( this, SLOT(flush()), actionCollection(), "file_close" ); + + KStdAction::save(this, SLOT(save()), actionCollection()); + + // setup edit menu + editUndo = KStdAction::undo(this, SLOT(undo()), actionCollection()); + editRedo = KStdAction::redo(this, SLOT(redo()), actionCollection()); + editUndoHist = new KAction(i18n("Undo/Redo &History..."), 0, this, SLOT(undoHistory()), + actionCollection(), "edit_undoHistory"); + KStdAction::cut(this, SLOT(cut()), actionCollection()); + KStdAction::copy(this, SLOT(copy()), actionCollection()); + KStdAction::paste(this, SLOT(paste()), actionCollection()); + + if ( myDoc->hasBrowserExtension() ) + { + KStdAction::saveAs(this, SLOT(saveAs()), myDoc->actionCollection()); + KStdAction::find(this, SLOT(find()), myDoc->actionCollection(), "find"); + KStdAction::findNext(this, SLOT(findAgain()), myDoc->actionCollection(), "find_again"); + KStdAction::findPrev(this, SLOT(findPrev()), myDoc->actionCollection(), "find_prev"); + KStdAction::gotoLine(this, SLOT(gotoLine()), myDoc->actionCollection(), "goto_line" ); + new KAction(i18n("&Configure Editor..."), 0, this, SLOT(configDialog()),myDoc->actionCollection(), "set_confdlg"); + setHighlight = new KSelectAction(i18n("&Highlight Mode"), 0, myDoc->actionCollection(), "set_highlight"); + KStdAction::selectAll(this, SLOT(selectAll()), myDoc->actionCollection(), "select_all"); + new KAction(i18n("&Deselect All"), 0, this, SLOT(deselectAll()), + myDoc->actionCollection(), "unselect_all"); + new KAction(i18n("Invert &Selection"), 0, this, SLOT(invertSelection()), + myDoc->actionCollection(), "invert_select"); + + new KAction(i18n("Increase Font Sizes"), "viewmag+", 0, this, SLOT(slotIncFontSizes()), + myDoc->actionCollection(), "incFontSizes"); + new KAction(i18n("Decrease Font Sizes"), "viewmag-", 0, this, SLOT(slotDecFontSizes()), + myDoc->actionCollection(), "decFontSizes"); + } + else + { + KStdAction::saveAs(this, SLOT(saveAs()), actionCollection()); + KStdAction::find(this, SLOT(find()), actionCollection()); + KStdAction::findNext(this, SLOT(findAgain()), actionCollection()); + KStdAction::findPrev(this, SLOT(findPrev()), actionCollection(), "edit_find_prev"); + KStdAction::gotoLine(this, SLOT(gotoLine()), actionCollection()); + new KAction(i18n("&Configure Editor..."), 0, this, SLOT(configDialog()),actionCollection(), "set_confdlg"); + setHighlight = new KSelectAction(i18n("&Highlight Mode"), 0, actionCollection(), "set_highlight"); + KStdAction::selectAll(this, SLOT(selectAll()), actionCollection()); + new KAction(i18n("&Deselect All"), 0, this, SLOT(deselectAll()), + actionCollection(), "edit_deselectAll"); + new KAction(i18n("Invert &Selection"), 0, this, SLOT(invertSelection()), + actionCollection(), "edit_invertSelection"); + + new KAction(i18n("Increase Font Sizes"), "viewmag+", 0, this, SLOT(slotIncFontSizes()), + actionCollection(), "incFontSizes"); + new KAction(i18n("Decrease Font Sizes"), "viewmag-", 0, this, SLOT(slotDecFontSizes()), + actionCollection(), "decFontSizes"); + } + + new KAction(i18n("Apply Word Wrap"), 0, myDoc, SLOT(applyWordWrap()), actionCollection(), "edit_apply_wordwrap"); + + KStdAction::replace(this, SLOT(replace()), actionCollection()); + + new KAction(i18n("Editing Co&mmand"), Qt::CTRL+Qt::Key_M, this, SLOT(slotEditCommand()), + actionCollection(), "edit_cmd"); + + // setup bookmark menu + bookmarkToggle = new KAction(i18n("Toggle &Bookmark"), Qt::CTRL+Qt::Key_B, this, SLOT(toggleBookmark()), actionCollection(), "edit_bookmarkToggle"); + bookmarkClear = new KAction(i18n("Clear Bookmarks"), 0, this, SLOT(clearBookmarks()), actionCollection(), "edit_bookmarksClear"); + + // connect settings menu aboutToshow + bookmarkMenu = new KActionMenu(i18n("&Bookmarks"), actionCollection(), "bookmarks"); + connect(bookmarkMenu->popupMenu(), SIGNAL(aboutToShow()), this, SLOT(bookmarkMenuAboutToShow())); + + new KToggleAction(i18n("Show &IconBorder"), Key_F6, this, SLOT(toggleIconBorder()), actionCollection(), "view_border"); + + // setup Tools menu + KStdAction::spelling(this, SLOT(spellcheck()), actionCollection()); + new KAction(i18n("&Indent"), "indent", Qt::CTRL+Qt::Key_I, this, SLOT(indent()), + actionCollection(), "tools_indent"); + new KAction(i18n("&Unindent"), "unindent", Qt::CTRL+Qt::Key_U, this, SLOT(unIndent()), + actionCollection(), "tools_unindent"); + new KAction(i18n("&Clean Indentation"), 0, this, SLOT(cleanIndent()), + actionCollection(), "tools_cleanIndent"); + new KAction(i18n("C&omment"), CTRL+Qt::Key_NumberSign, this, SLOT(comment()), + actionCollection(), "tools_comment"); + new KAction(i18n("Unco&mment"), CTRL+SHIFT+Qt::Key_NumberSign, this, SLOT(uncomment()), + actionCollection(), "tools_uncomment"); + + setVerticalSelection = new KToggleAction(i18n("&Vertical Selection"), Key_F4, this, SLOT(toggleVertical()), + actionCollection(), "set_verticalSelect"); + + connect(setHighlight, SIGNAL(activated(int)), this, SLOT(setHl(int))); + QStringList list; + for (int z = 0; z < HlManager::self()->highlights(); z++) + list.append(HlManager::self()->hlName(z)); + setHighlight->setItems(list); + + setEndOfLine = new KSelectAction(i18n("&End Of Line"), 0, actionCollection(), "set_eol"); + connect(setEndOfLine, SIGNAL(activated(int)), this, SLOT(setEol(int))); + list.clear(); + list.append("&Unix"); + list.append("&Windows/Dos"); + list.append("&Macintosh"); + setEndOfLine->setItems(list); +#endif +} +#endif + +void KateView::slotUpdate() +{ + int cfg = config(); + +#warning fixme setVerticalSelection->setChecked(cfg & KateView::cfVerticalSelect); + + slotNewUndo(); +} +void KateView::slotFileStatusChanged() +{ + int eol = getEol(); + eol = eol>=1 ? eol : 0; + +#warning fixme setEndOfLine->setCurrentItem(eol); +} +void KateView::slotNewUndo() +{ +#if 0 + int state = undoState(); + + editUndoHist->setEnabled(state & 1 || state & 2); + + QString t = i18n("Und&o"); // it would be nicer to fetch the original string + if (state & 1) { + editUndo->setEnabled(true); + t += ' '; + t += i18n(undoTypeName(nextUndoType())); + } else { + editUndo->setEnabled(false); + } + editUndo->setText(t); + + t = i18n("Re&do"); // it would be nicer to fetch the original string + if (state & 2) { + editRedo->setEnabled(true); + t += ' '; + t += i18n(undoTypeName(nextRedoType())); + } else { + editRedo->setEnabled(false); + } + editRedo->setText(t); +#endif +} + +void KateView::slotHighlightChanged() +{ +// setHighlight->setCurrentItem(getHl()); +} + + +void KateView::keyPressEvent( QKeyEvent *ev ) +{ + switch ( ev->key() ) + { + case Key_Left: + if ( ev->state() & ShiftButton ) + { + if ( ev->state() & ControlButton ) + shiftWordLeft(); + else + shiftCursorLeft(); + } + else if ( ev->state() & ControlButton ) + wordLeft(); + else + cursorLeft(); + break; + case Key_Right: + if ( ev->state() & ShiftButton ) + { + if ( ev->state() & ControlButton ) + shiftWordRight(); + else + shiftCursorRight(); + } + else if ( ev->state() & ControlButton ) + wordRight(); + else + cursorRight(); + break; + case Key_Home: + if ( ev->state() & ShiftButton ) + { + if ( ev->state() & ControlButton ) + shiftTop(); + else + shiftHome(); + } + else if ( ev->state() & ControlButton ) + top(); + else + home(); + break; + case Key_End: + if ( ev->state() & ShiftButton ) + { + if ( ev->state() & ControlButton ) + shiftBottom(); + else + shiftEnd(); + } + else if ( ev->state() & ControlButton ) + bottom(); + else + end(); + break; + case Key_Up: + if ( ev->state() & ShiftButton ) + shiftUp(); + else if ( ev->state() & ControlButton ) + scrollUp(); + else + up(); + break; + case Key_Down: + if ( ev->state() & ShiftButton ) + shiftDown(); + else if ( ev->state() & ControlButton ) + scrollDown(); + else + down(); + break; + case Key_PageUp: + if ( ev->state() & ShiftButton ) + shiftPageUp(); + else if ( ev->state() & ControlButton ) + topOfView(); + else + pageUp(); + break; + case Key_PageDown: + if ( ev->state() & ShiftButton ) + shiftPageDown(); + else if ( ev->state() & ControlButton ) + bottomOfView(); + else + pageDown(); + break; + case Key_Return: + case Key_Enter: + keyReturn(); + break; + case Key_Delete: + if ( ev->state() & ControlButton ) + { + VConfig c; + shiftWordRight(); + myViewInternal->getVConfig(c); + myDoc->delMarkedText(c); + myViewInternal->update(); + } + else keyDelete(); + break; + case Key_Backspace: + if ( ev->state() & ControlButton ) + { + VConfig c; + shiftWordLeft(); + myViewInternal->getVConfig(c); + myDoc->delMarkedText(c); + myViewInternal->update(); + } + else backspace(); + break; + case Key_Insert: + toggleInsert(); + break; + case Key_K: + if ( ev->state() & ControlButton ) + { + killLine(); + break; + } + default: + KTextEditor::View::keyPressEvent( ev ); + return; + break; + } + ev->accept(); +} + + +void KateView::setCursorPosition( int line, int col, bool /*mark*/ ) +{ + setCursorPositionInternal( line, col ); +} + +void KateView::getCursorPosition( int *line, int *col ) +{ + if ( line ) + *line = currentLine(); + + if ( col ) + *col = currentColumn(); +} + + +int KateView::currentLine() { + return myViewInternal->cursor.y; +} + +int KateView::currentColumn() { + return myDoc->currentColumn(myViewInternal->cursor); +} + +int KateView::currentCharNum() { + return myViewInternal->cursor.x; +} + +void KateView::setCursorPositionInternal(int line, int col) { + PointStruc cursor; + + cursor.x = col; + cursor.y = line; + myViewInternal->updateCursor(cursor); + myViewInternal->center(); +// myViewInternal->updateView(ufPos, 0, line*myDoc->fontHeight - height()/2); +// myDoc->updateViews(myViewInternal); //uptade all other views except this one + myDoc->updateViews(); +} + +int KateView::config() { + int flags; + + flags = configFlags; + if (myDoc->singleSelection()) flags |= KateView::cfSingleSelection; + return flags; +} + +void KateView::setConfig(int flags) { + bool updateView; + + // cfSingleSelection is a doc-property + myDoc->setSingleSelection(flags & KateView::cfSingleSelection); + flags &= ~KateView::cfSingleSelection; + + if (flags != configFlags) { + // update the view if visibility of tabs has changed + updateView = (flags ^ configFlags) & KateView::cfShowTabs; + configFlags = flags; + emit newStatus(); + if (updateView) myViewInternal->update(); + } +} + +int KateView::tabWidth() { + return myDoc->tabChars; +} + +void KateView::setTabWidth(int w) { + myDoc->setTabWidth(w); + myDoc->updateViews(); +} + +void KateView::setEncoding (QString e) { + myDoc->setEncoding (e); + myDoc->updateViews(); +} + +int KateView::undoSteps() { + return myDoc->undoSteps; +} + +void KateView::setUndoSteps(int s) { + myDoc->setUndoSteps(s); +} + +bool KateView::isReadOnly() { + return myDoc->readOnly; +} + +bool KateView::isModified() { + return myDoc->modified; +} + +void KateView::setReadOnly(bool m) { + myDoc->setReadOnly(m); +} + +void KateView::setModified(bool m) { + myDoc->setModified(m); +} + +bool KateView::isLastView() { + return myDoc->isLastView(1); +} + +KateDocument *KateView::doc() { + return myDoc; +} + +int KateView::undoState() { + if (isReadOnly()) + return 0; + else + return myDoc->undoState; +} + +int KateView::nextUndoType() { + return myDoc->nextUndoType(); +} + +int KateView::nextRedoType() { + return myDoc->nextRedoType(); +} + +void KateView::undoTypeList(QValueList<int> &lst) +{ + myDoc->undoTypeList(lst); +} + +void KateView::redoTypeList(QValueList<int> &lst) +{ + myDoc->redoTypeList(lst); +} + +const char * KateView::undoTypeName(int type) { + return KateActionGroup::typeName(type); +} + +QColor* KateView::getColors() +{ + return myDoc->colors; +} + +void KateView::applyColors() +{ + myDoc->tagAll(); + myDoc->updateViews(); +} + +bool KateView::isOverwriteMode() const +{ + return ( configFlags & KateView::cfOvr ); +} + +void KateView::setOverwriteMode( bool b ) +{ + if ( isOverwriteMode() && !b ) + setConfig( configFlags ^ KateView::cfOvr ); + else + setConfig( configFlags | KateView::cfOvr ); +} + +void KateView::toggleInsert() { + setConfig(configFlags ^ KateView::cfOvr); +} + +void KateView::toggleVertical() +{ + setConfig(configFlags ^ KateView::cfVerticalSelect); +} + + +int KateView::numLines() { + return myDoc->numLines(); +} + +QString KateView::text() { + return myDoc->text(); +} + +QString KateView::currentTextLine() { + TextLine::Ptr textLine = myDoc->getTextLine(myViewInternal->cursor.y); + return QString(textLine->getText(), textLine->length()); +} + +QString KateView::textLine(int num) { + TextLine::Ptr textLine = myDoc->getTextLine(num); + return QString(textLine->getText(), textLine->length()); +} + +QString KateView::currentWord() { + return myDoc->getWord(myViewInternal->cursor); +} + +QString KateView::word(int x, int y) { + PointStruc cursor; + cursor.y = (myViewInternal->yPos + y)/myDoc->fontHeight; + if (cursor.y < 0 || cursor.y > myDoc->lastLine()) return QString(); + cursor.x = myDoc->textPos(myDoc->getTextLine(cursor.y), myViewInternal->xPos-2 + x); + return myDoc->getWord(cursor); +} + +void KateView::setText(const QString &s) { + myDoc->setText(s); + myDoc->updateViews(); +} + +void KateView::insertText(const QString &s, bool /*mark*/) { + VConfig c; + myViewInternal->getVConfig(c); + myDoc->insert(c, s); + myDoc->updateViews(); +} + +bool KateView::hasMarkedText() { + return myDoc->hasMarkedText(); +} + +QString KateView::markedText() { + return myDoc->markedText(configFlags); +} + +bool KateView::canDiscard() { + int query; + + if (isModified()) { + query = KMessageBox::warningYesNoCancel(this, + i18n("The current Document has been modified.\nWould you like to save it?")); + switch (query) { + case KMessageBox::Yes: //yes + if (save() == CANCEL) return false; + if (isModified()) { + query = KMessageBox::warningContinueCancel(this, + i18n("Could not save the document.\nDiscard it and continue?"), + QString::null, i18n("&Discard")); + if (query == KMessageBox::Cancel) return false; + } + break; + case KMessageBox::Cancel: //cancel + return false; + } + } + return true; +} + +void KateView::flush() +{ + if (canDiscard()) myDoc->flush(); +} + +KateView::fileResult KateView::save() { + int query = KMessageBox::Yes; + if (isModified()) { + return saveAs(); + } + return OK; +} + +KateView::fileResult KateView::saveAs() { + return OK; +} + +void KateView::doCursorCommand(int cmdNum) { + VConfig c; + myViewInternal->getVConfig(c); + if (cmdNum & selectFlag) c.flags |= KateView::cfMark; + if (cmdNum & multiSelectFlag) c.flags |= KateView::cfMark | KateView::cfKeepSelection; + cmdNum &= ~(selectFlag | multiSelectFlag); + myViewInternal->doCursorCommand(c, cmdNum); + myDoc->updateViews(); +} + +void KateView::doEditCommand(int cmdNum) { + VConfig c; + myViewInternal->getVConfig(c); + myViewInternal->doEditCommand(c, cmdNum); + myDoc->updateViews(); +} + +void KateView::undoMultiple(int count) { + if (isReadOnly()) + return; + + VConfig c; + myViewInternal->getVConfig(c); + myDoc->undo(c, count); + myDoc->updateViews(); +} + +void KateView::redoMultiple(int count) { + if (isReadOnly()) + return; + + VConfig c; + myViewInternal->getVConfig(c); + myDoc->redo(c, count); + myDoc->updateViews(); +} + +void KateView::undoHistory() +{ + UndoHistory *undoH; + + undoH = new UndoHistory(this, this, "UndoHistory", true); + + undoH->setCaption(i18n("Undo/Redo History")); + + connect(this,SIGNAL(newUndo()),undoH,SLOT(newUndo())); + connect(undoH,SIGNAL(undo(int)),this,SLOT(undoMultiple(int))); + connect(undoH,SIGNAL(redo(int)),this,SLOT(redoMultiple(int))); + + undoH->exec(); + + delete undoH; +} + +static void kwview_addToStrList(QStringList &list, const QString &str) { + if (list.count() > 0) { + if (list.first() == str) return; + QStringList::Iterator it; + it = list.find(str); + if (*it != 0L) list.remove(it); + if (list.count() >= 16) list.remove(list.fromLast()); + } + list.prepend(str); +} + +void KateView::find() { + SearchDialog *searchDialog; + + if (!myDoc->hasMarkedText()) searchFlags &= ~KateView::sfSelected; + + searchDialog = new SearchDialog(this, myDoc->searchForList, myDoc->replaceWithList, + searchFlags & ~KateView::sfReplace); + + // If the user has marked some text we use that otherwise + // use the word under the cursor. + QString str; + if (myDoc->hasMarkedText()) + str = markedText(); + + if (str.isEmpty()) + str = currentWord(); + + if (!str.isEmpty()) + { + str.replace(QRegExp("^\n"), ""); + int pos=str.find("\n"); + if (pos>-1) + str=str.left(pos); + searchDialog->setSearchText( str ); + } + + myViewInternal->focusOutEvent(0L);// QT bug ? + if (searchDialog->exec() == QDialog::Accepted) { + kwview_addToStrList(myDoc->searchForList, searchDialog->getSearchFor()); + searchFlags = searchDialog->getFlags() | (searchFlags & KateView::sfPrompt); + initSearch(s, searchFlags); + findAgain(s); + } + delete searchDialog; +} + +void KateView::replace() { + SearchDialog *searchDialog; + + if (isReadOnly()) return; + + if (!myDoc->hasMarkedText()) searchFlags &= ~KateView::sfSelected; + searchDialog = new SearchDialog(this, myDoc->searchForList, myDoc->replaceWithList, + searchFlags | KateView::sfReplace); + + // If the user has marked some text we use that otherwise + // use the word under the cursor. + QString str; + if (myDoc->hasMarkedText()) + str = markedText(); + + if (str.isEmpty()) + str = currentWord(); + + if (!str.isEmpty()) + { + str.replace(QRegExp("^\n"), ""); + int pos=str.find("\n"); + if (pos>-1) + str=str.left(pos); + searchDialog->setSearchText( str ); + } + + myViewInternal->focusOutEvent(0L);// QT bug ? + if (searchDialog->exec() == QDialog::Accepted) { +// myDoc->recordReset(); + kwview_addToStrList(myDoc->searchForList, searchDialog->getSearchFor()); + kwview_addToStrList(myDoc->replaceWithList, searchDialog->getReplaceWith()); + searchFlags = searchDialog->getFlags(); + initSearch(s, searchFlags); + replaceAgain(); + } + delete searchDialog; +} + +void KateView::gotoLine() { + GotoLineDialog *dlg; + PointStruc cursor; + + dlg = new GotoLineDialog(this, myViewInternal->cursor.y + 1, myDoc->numLines()); +// dlg = new GotoLineDialog(myViewInternal->cursor.y + 1, this); + + if (dlg->exec() == QDialog::Accepted) { +// myDoc->recordReset(); + cursor.x = 0; + cursor.y = dlg->getLine() - 1; + myDoc->needPreHighlight(cursor.y); + myViewInternal->updateCursor(cursor); + myViewInternal->center(); + myViewInternal->updateView(KateView::ufUpdateOnScroll); + myDoc->updateViews(this); //uptade all other views except this one + } + delete dlg; +} + + +void KateView::initSearch(SConfig &s, int flags) { + + s.flags = flags; + s.setPattern(myDoc->searchForList.first()); + + if (!(s.flags & KateView::sfFromBeginning)) { + // If we are continuing a backward search, make sure we do not get stuck + // at an existing match. + s.cursor = myViewInternal->cursor; + TextLine::Ptr textLine = myDoc->getTextLine(s.cursor.y); + QString const txt(textLine->getText(),textLine->length()); + const QString searchFor= myDoc->searchForList.first(); + int pos = s.cursor.x-searchFor.length()-1; + if ( pos < 0 ) pos = 0; + pos= txt.find(searchFor, pos, s.flags & KateView::sfCaseSensitive); + if ( s.flags & KateView::sfBackward ) + { + if ( pos <= s.cursor.x ) s.cursor.x= pos-1; + } + else + if ( pos == s.cursor.x ) s.cursor.x++; + } else { + if (!(s.flags & KateView::sfBackward)) { + s.cursor.x = 0; + s.cursor.y = 0; + } else { + s.cursor.x = -1; + s.cursor.y = myDoc->lastLine(); + } + s.flags |= KateView::sfFinished; + } + if (!(s.flags & KateView::sfBackward)) { + if (!(s.cursor.x || s.cursor.y)) + s.flags |= KateView::sfFinished; + } + s.startCursor = s.cursor; +} + +void KateView::continueSearch(SConfig &s) { + + if (!(s.flags & KateView::sfBackward)) { + s.cursor.x = 0; + s.cursor.y = 0; + } else { + s.cursor.x = -1; + s.cursor.y = myDoc->lastLine(); + } + s.flags |= KateView::sfFinished; + s.flags &= ~KateView::sfAgain; +} + +void KateView::findAgain(SConfig &s) { + int query; + PointStruc cursor; + QString str; + + QString searchFor = myDoc->searchForList.first(); + + if( searchFor.isEmpty() ) { + find(); + return; + } + + do { + query = KMessageBox::Cancel; + if (myDoc->doSearch(s,searchFor)) { + cursor = s.cursor; + if (!(s.flags & KateView::sfBackward)) + s.cursor.x += s.matchedLength; + myViewInternal->updateCursor(s.cursor); //does deselectAll() + exposeFound(cursor,s.matchedLength,(s.flags & KateView::sfAgain) ? 0 : KateView::ufUpdateOnScroll,false); + } else { + if (!(s.flags & KateView::sfFinished)) { + // ask for continue + if (!(s.flags & KateView::sfBackward)) { + // forward search + str = i18n("End of document reached.\n" + "Continue from the beginning?"); + query = KMessageBox::warningContinueCancel(this, + str, i18n("Find"), i18n("Continue")); + } else { + // backward search + str = i18n("Beginning of document reached.\n" + "Continue from the end?"); + query = KMessageBox::warningContinueCancel(this, + str, i18n("Find"), i18n("Continue")); + } + continueSearch(s); + } else { + // wrapped + KMessageBox::sorry(this, + i18n("Search string '%1' not found!").arg(searchFor), + i18n("Find")); + } + } + } while (query == KMessageBox::Continue); +} + +void KateView::replaceAgain() { + if (isReadOnly()) + return; + + replaces = 0; + if (s.flags & KateView::sfPrompt) { + doReplaceAction(-1); + } else { + doReplaceAction(KateView::srAll); + } +} + +void KateView::doReplaceAction(int result, bool found) { + int rlen; + PointStruc cursor; + bool started; + + QString searchFor = myDoc->searchForList.first(); + QString replaceWith = myDoc->replaceWithList.first(); + rlen = replaceWith.length(); + + switch (result) { + case KateView::srYes: //yes + myDoc->recordStart(this, s.cursor, configFlags, + KateActionGroup::ugReplace, true); + myDoc->recordReplace(s.cursor, s.matchedLength, replaceWith); + replaces++; + if (s.cursor.y == s.startCursor.y && s.cursor.x < s.startCursor.x) + s.startCursor.x += rlen - s.matchedLength; + if (!(s.flags & KateView::sfBackward)) s.cursor.x += rlen; + myDoc->recordEnd(this, s.cursor, configFlags | KateView::cfPersistent); + break; + case KateView::srNo: //no + if (!(s.flags & KateView::sfBackward)) s.cursor.x += s.matchedLength; + break; + case KateView::srAll: //replace all + deleteReplacePrompt(); + do { + started = false; + while (found || myDoc->doSearch(s,searchFor)) { + if (!started) { + found = false; + myDoc->recordStart(this, s.cursor, configFlags, + KateActionGroup::ugReplace); + started = true; + } + myDoc->recordReplace(s.cursor, s.matchedLength, replaceWith); + replaces++; + if (s.cursor.y == s.startCursor.y && s.cursor.x < s.startCursor.x) + s.startCursor.x += rlen - s.matchedLength; + if (!(s.flags & KateView::sfBackward)) s.cursor.x += rlen; + } + if (started) myDoc->recordEnd(this, s.cursor, + configFlags | KateView::cfPersistent); + } while (!askReplaceEnd()); + return; + case KateView::srCancel: //cancel + deleteReplacePrompt(); + return; + default: + replacePrompt = 0L; + } + + do { + if (myDoc->doSearch(s,searchFor)) { + //text found: highlight it, show replace prompt if needed and exit + cursor = s.cursor; + if (!(s.flags & KateView::sfBackward)) cursor.x += s.matchedLength; + myViewInternal->updateCursor(cursor); //does deselectAll() + exposeFound(s.cursor,s.matchedLength,(s.flags & KateView::sfAgain) ? 0 : KateView::ufUpdateOnScroll,true); + if (replacePrompt == 0L) { + replacePrompt = new ReplacePrompt(this); + myDoc->setPseudoModal(replacePrompt);//disable(); + connect(replacePrompt,SIGNAL(clicked()),this,SLOT(replaceSlot())); + replacePrompt->show(); //this is not modal + } + return; //exit if text found + } + //nothing found: repeat until user cancels "repeat from beginning" dialog + } while (!askReplaceEnd()); + deleteReplacePrompt(); +} + +void KateView::exposeFound(PointStruc &cursor, int slen, int flags, bool replace) { + int x1, x2, y1, y2, xPos, yPos; + + VConfig c; + myViewInternal->getVConfig(c); + myDoc->selectLength(cursor,slen,c.flags); + + TextLine::Ptr textLine = myDoc->getTextLine(cursor.y); + x1 = myDoc->textWidth(textLine,cursor.x) -10; + x2 = myDoc->textWidth(textLine,cursor.x + slen) +20; + y1 = myDoc->fontHeight*cursor.y -10; + y2 = y1 + myDoc->fontHeight +30; + + xPos = myViewInternal->xPos; + yPos = myViewInternal->yPos; + + if (x1 < 0) x1 = 0; + if (replace) y2 += 90; + + if (x1 < xPos || x2 > xPos + myViewInternal->width()) { + xPos = x2 - myViewInternal->width(); + } + if (y1 < yPos || y2 > yPos + myViewInternal->height()) { + xPos = x2 - myViewInternal->width(); + yPos = myDoc->fontHeight*cursor.y - height()/3; + } + myViewInternal->setPos(xPos, yPos); + myViewInternal->updateView(flags);// | ufPos,xPos,yPos); + myDoc->updateViews(this); +} + +void KateView::deleteReplacePrompt() { + myDoc->setPseudoModal(0L); +} + +bool KateView::askReplaceEnd() { + QString str; + int query; + + myDoc->updateViews(); + if (s.flags & KateView::sfFinished) { + // replace finished + str = i18n("%1 replacement(s) made").arg(replaces); + KMessageBox::information(this, str, i18n("Replace")); + return true; + } + + // ask for continue + if (!(s.flags & KateView::sfBackward)) { + // forward search + str = i18n("%1 replacement(s) made.\n" + "End of document reached.\n" + "Continue from the beginning?").arg(replaces); + query = KMessageBox::questionYesNo(this, str, i18n("Replace"), + i18n("Continue"), i18n("Stop")); + } else { + // backward search + str = i18n("%1 replacement(s) made.\n" + "Beginning of document reached.\n" + "Continue from the end?").arg(replaces); + query = KMessageBox::questionYesNo(this, str, i18n("Replace"), + i18n("Continue"), i18n("Stop")); + } + replaces = 0; + continueSearch(s); + return (query == KMessageBox::No); +} + +void KateView::replaceSlot() { + doReplaceAction(replacePrompt->result(),true); +} + +void KateView::installPopup(QPopupMenu *rmb_Menu) +{ + rmbMenu = rmb_Menu; +} + +void KateView::readConfig() +{ + KConfig *config = KGlobal::config(); + config->setGroup("Kate View"); + + searchFlags = config->readNumEntry("SearchFlags", KateView::sfPrompt); + configFlags = config->readNumEntry("ConfigFlags", configFlags) & ~KateView::cfMark; + + config->sync(); +} + +void KateView::writeConfig() +{ + KConfig *config = KGlobal::config(); + config->setGroup("Kate View"); + + config->writeEntry("SearchFlags",searchFlags); + config->writeEntry("ConfigFlags",configFlags); + + config->sync(); +} + +void KateView::readSessionConfig(KConfig *config) +{ + PointStruc cursor; + + myViewInternal->xPos = config->readNumEntry("XPos"); + myViewInternal->yPos = config->readNumEntry("YPos"); + cursor.x = config->readNumEntry("CursorX"); + cursor.y = config->readNumEntry("CursorY"); + myViewInternal->updateCursor(cursor); + myIconBorder = config->readBoolEntry("IconBorder on"); + setIconBorder(myIconBorder); +} + +void KateView::writeSessionConfig(KConfig *config) +{ + config->writeEntry("XPos",myViewInternal->xPos); + config->writeEntry("YPos",myViewInternal->yPos); + config->writeEntry("CursorX",myViewInternal->cursor.x); + config->writeEntry("CursorY",myViewInternal->cursor.y); + config->writeEntry("IconBorder on", myIconBorder); +} + +void KateView::configDialog() +{ + +#warning fixme + +#if 1 + KDialogBase *kd = new KDialogBase(KDialogBase::IconList, + i18n("Configure Editor"), + KDialogBase::Ok | KDialogBase::Cancel | + KDialogBase::Help , + KDialogBase::Ok, this, "tabdialog"); + + // color options + QFrame *page=kd->addPage(i18n("Colors")); + (new QVBoxLayout(page))->setAutoAdd(true); + ColorConfig *colorConfig = new ColorConfig(page); + QColor* colors = getColors(); + colorConfig->setColors(colors); + + page = kd->addPage(i18n("Fonts")); + (new QVBoxLayout(page))->setAutoAdd(true); + + FontConfig *fontConfig = new FontConfig(page); + fontConfig->setFont (myDoc->getFont()); + + // indent options + page=kd->addPage(i18n("Indent")); + (new QVBoxLayout(page))->setAutoAdd(true); + + IndentConfigTab *indentConfig = new IndentConfigTab(page, this); + + // select options + page=kd->addPage(i18n("Select")); + (new QVBoxLayout(page))->setAutoAdd(true); + + SelectConfigTab *selectConfig = new SelectConfigTab(page, this); + + // edit options + page=kd->addPage(i18n("Edit")); + (new QVBoxLayout(page))->setAutoAdd(true); + + EditConfigTab *editConfig = new EditConfigTab(page, this); + + + + HighlightDialogPage *hlPage; + HlManager *hlManager; + HlDataList hlDataList; + ItemStyleList defaultStyleList; + + hlManager = HlManager::self(); + + defaultStyleList.setAutoDelete(true); + hlManager->getDefaults(defaultStyleList); + + hlDataList.setAutoDelete(true); + //this gets the data from the KConfig object + hlManager->getHlDataList(hlDataList); + + page=kd->addPage(i18n("Highlighting")); + (new QVBoxLayout(page))->setAutoAdd(true); + + hlPage = new HighlightDialogPage(hlManager, &defaultStyleList, &hlDataList, 0, page); + + if (kd->exec()) { + // color options + colorConfig->getColors(colors); + myDoc->setFont (fontConfig->getFont()); + + applyColors(); + // indent options + indentConfig->getData(this); + // select options + selectConfig->getData(this); + // edit options + editConfig->getData(this); + // spell checker + hlManager->setHlDataList(hlDataList); + hlManager->setDefaults(defaultStyleList); + hlPage->saveData(); + } + + delete kd; + +#endif +} + +int KateView::getHl() { + return myDoc->highlightNum(); +} + +void KateView::setDontChangeHlOnSave() +{ + myDoc->setDontChangeHlOnSave(); +} + +void KateView::setHl(int n) { + myDoc->setHighlight(n); + myDoc->setDontChangeHlOnSave(); + myDoc->updateViews(); +} + +int KateView::getEol() { + return myDoc->eolMode; +} + +void KateView::setEol(int eol) { + if (isReadOnly()) + return; + + myDoc->eolMode = eol; + myDoc->setModified(true); +} + + + +void KateView::paintEvent(QPaintEvent *e) { + int x, y; + + QRect updateR = e->rect(); // update rectangle +// debug("Update rect = ( %i, %i, %i, %i )", +// updateR.x(),updateR.y(), updateR.width(), updateR.height() ); + + int ux1 = updateR.x(); + int uy1 = updateR.y(); + int ux2 = ux1 + updateR.width(); + int uy2 = uy1 + updateR.height(); + + QPainter paint; + paint.begin(this); + + QColorGroup g = colorGroup(); + x = width(); + y = height(); + + paint.setPen(g.dark()); + if (uy1 <= 0) paint.drawLine(0,0,x-2,0); + if (ux1 <= 0) paint.drawLine(0,1,0,y-2); + + paint.setPen(black); + if (uy1 <= 1) paint.drawLine(1,1,x-3,1); + if (ux1 <= 1) paint.drawLine(1,2,1,y-3); + + paint.setPen(g.midlight()); + if (uy2 >= y-1) paint.drawLine(1,y-2,x-3,y-2); + if (ux2 >= x-1) paint.drawLine(x-2,1,x-2,y-2); + + paint.setPen(g.light()); + if (uy2 >= y) paint.drawLine(0,y-1,x-2,y-1); + if (ux2 >= x) paint.drawLine(x-1,0,x-1,y-1); + + x -= 2 + 16; + y -= 2 + 16; + if (ux2 > x && uy2 > y) { + paint.fillRect(x,y,16,16,g.background()); + } + paint.end(); +} + +void KateView::resizeEvent(QResizeEvent *) { + +// debug("Resize %d, %d",e->size().width(),e->size().height()); + +//myViewInternal->resize(width() -20, height() -20); + myViewInternal->tagAll(); + myViewInternal->updateView(0/*ufNoScroll*/); +} + + +// Applies a new pattern to the search context. +void SConfig::setPattern(QString &newPattern) { + bool regExp = (flags & KateView::sfRegularExpression); + + m_pattern = newPattern; + if (regExp) { + m_regExp.setCaseSensitive(flags & KateView::sfCaseSensitive); + m_regExp.setPattern(m_pattern); + } +} + +// Applies the search context to the given string, and returns whether a match was found. If one is, +// the length of the string matched is also returned. +int SConfig::search(QString &text, int index) { + bool regExp = (flags & KateView::sfRegularExpression); + bool caseSensitive = (flags & KateView::sfCaseSensitive); + + if (flags & KateView::sfBackward) { + if (regExp) { + index = text.findRev(m_regExp, index); + } + else { + index = text.findRev(m_pattern, index, caseSensitive); + } + } + else { + if (regExp) { + index = text.find(m_regExp, index); + } + else { + index = text.find(m_pattern, index, caseSensitive); + } + } + + // Work out the matched length. + if (index != -1) + { + if (regExp) { + m_regExp.match(text, index, &matchedLength, false); + } + else { + matchedLength = m_pattern.length(); + } + } + return index; +} + +void KateView::setActive (bool b) +{ + active = b; +} + +bool KateView::isActive () +{ + return active; +} + +void KateView::setFocus () +{ + QWidget::setFocus (); + + emit gotFocus (this); +} + +bool KateView::eventFilter (QObject *object, QEvent *event) +{ + + if ( (event->type() == QEvent::FocusIn) ) + emit gotFocus (this); + + if ( (event->type() == QEvent::KeyPress) ) + { + QKeyEvent * ke=(QKeyEvent *)event; + + if ((ke->key()==Qt::Key_Tab) || (ke->key()==Qt::Key_BackTab)) + { + myViewInternal->keyPressEvent(ke); + return true; + } + } + return QWidget::eventFilter (object, event); +} + +void KateView::findAgain (bool back) +{ + bool b= (searchFlags & sfBackward) > 0; + initSearch(s, (searchFlags & ((b==back)?~sfBackward:~0) & ~sfFromBeginning) // clear flag for forward searching + | sfPrompt | sfAgain | ((b!=back)?sfBackward:0) ); + if (s.flags & sfReplace) + replaceAgain(); + else + KateView::findAgain(s); +} + +void KateView::slotEditCommand () +{ +#warning fixme +/* + bool ok; + QString cmd = KLineEditDlg::getText("Editing Command", "", &ok, this); + + if (ok) + myDoc->cmd()->execCmd (cmd, this);*/ +} + +void KateView::setIconBorder (bool enable) +{ + myIconBorder = enable; + + if (myIconBorder) + { + myViewInternal->move(myViewInternal->iconBorderWidth+2, 2); + myViewInternal->leftBorder->show(); + } + else + { + myViewInternal->leftBorder->hide(); + myViewInternal->move(2, 2); + } +} + +void KateView::toggleIconBorder () +{ + setIconBorder (!myIconBorder); +} + +void KateView::gotoMark (Kate::Mark *mark) +{ + PointStruc cursor; + + cursor.x = 0; + cursor.y = mark->line; + myDoc->needPreHighlight(cursor.y); + myViewInternal->updateCursor(cursor); + myViewInternal->center(); + myViewInternal->updateView(KateView::ufUpdateOnScroll); + myDoc->updateViews(this); +} + +void KateView::toggleBookmark () +{ + TextLine::Ptr line = myDoc->getTextLine (currentLine()); + + if (line->mark()&KateDocument::Bookmark) + line->delMark(KateDocument::Bookmark); + else + line->addMark(KateDocument::Bookmark); + + myDoc->tagLines (currentLine(), currentLine()); + myDoc->updateViews(); +} + +void KateView::clearBookmarks() +{ + QList<Kate::Mark> list = myDoc->marks(); + for (int i=0; (uint) i < list.count(); i++) + { + if (list.at(i)->type&KateDocument::Bookmark) + { + myDoc->getTextLine(list.at(i)->line)->delMark(KateDocument::Bookmark); + myDoc->tagLines(list.at(i)->line, list.at(i)->line); + } + } + + myDoc->updateViews(); +} + +void KateView::bookmarkMenuAboutToShow() +{ +#warning fixme +#if 0 + bookmarkMenu->popupMenu()->clear (); + bookmarkToggle->plug (bookmarkMenu->popupMenu()); + bookmarkClear->plug (bookmarkMenu->popupMenu()); + bookmarkMenu->popupMenu()->insertSeparator (); + + list = myDoc->marks(); + for (int i=0; (uint) i < list.count(); i++) + { + if (list.at(i)->type&KateDocument::Bookmark) + { + QString bText = textLine(list.at(i)->line); + bText.truncate(32); + bText.append ("..."); + bookmarkMenu->popupMenu()->insertItem ( QString("%1 - \"%2\"").arg(list.at(i)->line).arg(bText), this, SLOT (gotoBookmark(int)), 0, i ); + } + } +#endif +} + +void KateView::gotoBookmark (int n) +{ + gotoMark (list.at(n)); +} + +int KateView::getHlCount () +{ + return HlManager::self()->highlights(); +} + +QString KateView::getHlName (int z) +{ + return HlManager::self()->hlName(z); +} + +QString KateView::getHlSection (int z) +{ + return HlManager::self()->hlSection (z); +} + +void KateView::slotIncFontSizes () +{ + QFont font = myDoc->getFont(); + font.setPointSize (font.pointSize()+2); + myDoc->setFont (font); +} + +void KateView::slotDecFontSizes () +{ + QFont font = myDoc->getFont(); + font.setPointSize (font.pointSize()-2); + myDoc->setFont (font); +} + +const char*bookmark_xpm[]={ +"12 16 4 1", +"b c #808080", +"a c #000080", +"# c #0000ff", +". c None", +"............", +"............", +"........###.", +".......#...a", +"......#.##.a", +".....#.#..aa", +"....#.#...a.", +"...#.#.a.a..", +"..#.#.a.a...", +".#.#.a.a....", +"#.#.a.a.....", +"#.#a.a...bbb", +"#...a..bbb..", +".aaa.bbb....", +"............", +"............"}; + +const char* breakpoint_xpm[]={ +"11 16 6 1", +"c c #c6c6c6", +". c None", +"# c #000000", +"d c #840000", +"a c #ffffff", +"b c #ff0000", +"...........", +"...........", +"...#####...", +"..#aaaaa#..", +".#abbbbbb#.", +"#abbbbbbbb#", +"#abcacacbd#", +"#abbbbbbbb#", +"#abcacacbd#", +"#abbbbbbbb#", +".#bbbbbbb#.", +"..#bdbdb#..", +"...#####...", +"...........", +"...........", +"..........."}; + +const char*breakpoint_bl_xpm[]={ +"11 16 7 1", +"a c #c0c0ff", +"# c #000000", +"c c #0000c0", +"e c #0000ff", +"b c #dcdcdc", +"d c #ffffff", +". c None", +"...........", +"...........", +"...#####...", +"..#ababa#..", +".#bcccccc#.", +"#acccccccc#", +"#bcadadace#", +"#acccccccc#", +"#bcadadace#", +"#acccccccc#", +".#ccccccc#.", +"..#cecec#..", +"...#####...", +"...........", +"...........", +"..........."}; + +const char*breakpoint_gr_xpm[]={ +"11 16 6 1", +"c c #c6c6c6", +"d c #2c2c2c", +"# c #000000", +". c None", +"a c #ffffff", +"b c #555555", +"...........", +"...........", +"...#####...", +"..#aaaaa#..", +".#abbbbbb#.", +"#abbbbbbbb#", +"#abcacacbd#", +"#abbbbbbbb#", +"#abcacacbd#", +"#abbbbbbbb#", +".#bbbbbbb#.", +"..#bdbdb#..", +"...#####...", +"...........", +"...........", +"..........."}; + +const char*ddd_xpm[]={ +"11 16 4 1", +"a c #00ff00", +"b c #000000", +". c None", +"# c #00c000", +"...........", +"...........", +"...........", +"#a.........", +"#aaa.......", +"#aaaaa.....", +"#aaaaaaa...", +"#aaaaaaaaa.", +"#aaaaaaa#b.", +"#aaaaa#b...", +"#aaa#b.....", +"#a#b.......", +"#b.........", +"...........", +"...........", +"..........."}; + + + +KateIconBorder::KateIconBorder(KateView *view, KateViewInternal *internalView) + : QWidget(view), myView(view), myInternalView(internalView) +{ + lmbSetsBreakpoints = true; +} + +KateIconBorder::~KateIconBorder() +{ +} + +void KateIconBorder::paintLine(int i) +{ + if (!myView->myIconBorder) return; + + QPainter p(this); + + int fontHeight = myView->doc()->fontHeight; + int y = i*fontHeight - myInternalView->yPos; + p.fillRect(0, y, myInternalView->iconBorderWidth-2, fontHeight, colorGroup().background()); + p.setPen(white); + p.drawLine(myInternalView->iconBorderWidth-2, y, myInternalView->iconBorderWidth-2, y + fontHeight); + p.setPen(QColor(colorGroup().background()).dark()); + p.drawLine(myInternalView->iconBorderWidth-1, y, myInternalView->iconBorderWidth-1, y + fontHeight); + + TextLine *line = myView->doc()->getTextLine(i); + if (!line) + return; + + if (line->mark()&KateDocument::Bookmark) + p.drawPixmap(2, y, QPixmap(bookmark_xpm)); /* + if (line && (line->breakpointId() != -1)) { + if (!line->breakpointEnabled()) + p.drawPixmap(2, y, QPixmap(breakpoint_gr_xpm)); + else if (line->breakpointPending()) + p.drawPixmap(2, y, QPixmap(breakpoint_bl_xpm)); + else + p.drawPixmap(2, y, QPixmap(breakpoint_xpm)); + } + if (line->isExecutionPoint()) + p.drawPixmap(2, y, QPixmap(ddd_xpm)); */ +} + + +void KateIconBorder::paintEvent(QPaintEvent* e) +{ + if (!myView->myIconBorder) return; + + int lineStart = 0; + int lineEnd = 0; + + QRect updateR = e->rect(); + + KateDocument *doc = myView->doc(); + int h = doc->fontHeight; + int yPos = myInternalView->yPos; + if (h) { + lineStart = (yPos + updateR.y()) / h; + lineEnd = QMAX((yPos + updateR.y() + updateR.height()) / h, (int)doc->numLines()); + } + + for(int i = lineStart; i <= lineEnd; ++i) + paintLine(i); +} + + +void KateIconBorder::mousePressEvent(QMouseEvent* e) +{ + myInternalView->placeCursor( 0, e->y(), 0 ); + + KateDocument *doc = myView->doc(); + int cursorOnLine = (e->y() + myInternalView->yPos) / doc->fontHeight; + TextLine *line = doc->getTextLine(cursorOnLine); + + switch (e->button()) { + case LeftButton: + if (!line) + break; + else + { + if (line->mark()&KateDocument::Bookmark) + line->delMark (KateDocument::Bookmark); + else + line->addMark (KateDocument::Bookmark); + + doc->tagLines(cursorOnLine, cursorOnLine); + doc->updateViews(); + } + break; + /* case RightButton: + { + if (!line) + break; + KPopupMenu popup; + popup.setCheckable(true); + popup.insertTitle(i18n("Breakpoints/Bookmarks")); + int idToggleBookmark = popup.insertItem(i18n("Toggle bookmark")); + popup.insertSeparator(); + int idToggleBreakpoint = popup.insertItem(i18n("Toggle breakpoint")); + int idEditBreakpoint = popup.insertItem(i18n("Edit breakpoint")); + int idEnableBreakpoint = popup.insertItem(i18n("Disable breakpoint")); + popup.insertSeparator(); + popup.insertSeparator(); + int idLmbSetsBreakpoints = popup.insertItem(i18n("LMB sets breakpoints")); + int idLmbSetsBookmarks = popup.insertItem(i18n("LMB sets bookmarks")); + + popup.setItemChecked(idLmbSetsBreakpoints, lmbSetsBreakpoints); + popup.setItemChecked(idLmbSetsBookmarks, !lmbSetsBreakpoints); + + if (line->breakpointId() == -1) { + popup.setItemEnabled(idEditBreakpoint, false); + popup.setItemEnabled(idEnableBreakpoint, false); + popup.changeItem(idEnableBreakpoint, i18n("Enable breakpoint")); + } + int res = popup.exec(mapToGlobal(e->pos())); + if (res == idToggleBookmark) { + line->toggleBookmark(); + doc->tagLines(cursorOnLine, cursorOnLine); + doc->updateViews(); + } else if (res == idToggleBreakpoint) + emit myView->toggledBreakpoint(cursorOnLine); + else if (res == idEditBreakpoint) + emit myView->editedBreakpoint(cursorOnLine); + else if (res == idEnableBreakpoint) + emit myView->toggledBreakpointEnabled(cursorOnLine+1); + else if (res == idLmbSetsBreakpoints || res == idLmbSetsBookmarks) + lmbSetsBreakpoints = !lmbSetsBreakpoints; + break; + } + case MidButton: + line->toggleBookmark(); + doc->tagLines(cursorOnLine, cursorOnLine); + doc->updateViews(); + break; */ + default: + break; + } +} + + + |