author | paule <paule> | 2007-01-13 07:24:51 (UTC) |
---|---|---|
committer | paule <paule> | 2007-01-13 07:24:51 (UTC) |
commit | 4892c61a3e76c031d7b882854dcb0dfbd575f045 (patch) (side-by-side diff) | |
tree | 5c5de924caf9683ad844fd1ef6d27aff433a560b | |
parent | 80d1934bbbfaea40ee08cf6be738c6517de9477c (diff) | |
download | opie-4892c61a3e76c031d7b882854dcb0dfbd575f045.zip opie-4892c61a3e76c031d7b882854dcb0dfbd575f045.tar.gz opie-4892c61a3e76c031d7b882854dcb0dfbd575f045.tar.bz2 |
Clear document modified flag on save
-rw-r--r-- | noncore/apps/tinykate/libkate/document/katedocument.cpp | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/noncore/apps/tinykate/libkate/document/katedocument.cpp b/noncore/apps/tinykate/libkate/document/katedocument.cpp index a70f3aa..b82a86a 100644 --- a/noncore/apps/tinykate/libkate/document/katedocument.cpp +++ b/noncore/apps/tinykate/libkate/document/katedocument.cpp @@ -1,1136 +1,1141 @@ /*************************************************************************** katedocument.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 "katedocument.h" #include "kmessagebox.h" #include "kglobal.h" //#include "kcharsets.h" #include "kdebug.h" //#include "kinstance.h" #include "kglobalsettings.h" //#include "kaction.h" //#include "kstdaction.h" #include "../view/kateview.h" #include "katebuffer.h" #include "katetextline.h" #include "katecmd.h" /* OPIE */ #include <opie2/odebug.h> #include <qpe/config.h> /* QT */ #include <qfileinfo.h> #include <qdatetime.h> #include <qstring.h> #include <qtimer.h> #include <qobject.h> #include <qapplication.h> #include <qclipboard.h> #include <qfont.h> #include <qpainter.h> #include <qfile.h> #include <qtextstream.h> #include <qtextcodec.h> /* STD */ #include <sys/time.h> #include <unistd.h> #include <stdio.h> KateAction::KateAction(Action a, PointStruc &cursor, int len, const QString &text) : action(a), cursor(cursor), len(len), text(text) { } KateActionGroup::KateActionGroup(PointStruc &aStart, int type) : start(aStart), action(0L), undoType(type) { } KateActionGroup::~KateActionGroup() { KateAction *current, *next; current = action; while (current) { next = current->next; delete current; current = next; } } void KateActionGroup::insertAction(KateAction *a) { a->next = action; action = a; } const char * KateActionGroup::typeName(int type) { // return a short text description of the given undo group type suitable for a menu // not the lack of i18n's, the caller is expected to handle translation switch (type) { case ugPaste : return "Paste Text"; case ugDelBlock : return "Selection Overwrite"; case ugIndent : return "Indent"; case ugUnindent : return "Unindent"; case ugComment : return "Comment"; case ugUncomment : return "Uncomment"; case ugReplace : return "Text Replace"; case ugSpell : return "Spell Check"; case ugInsChar : return "Typing"; case ugDelChar : return "Delete Text"; case ugInsLine : return "New Line"; case ugDelLine : return "Delete Line"; } return ""; } const int KateDocument::maxAttribs = 32; QStringList KateDocument::searchForList = QStringList(); QStringList KateDocument::replaceWithList = QStringList(); uint KateDocument::uniqueID = 0; QPtrDict<KateDocument::KateDocPrivate>* KateDocument::d_ptr = 0; KateDocument::KateDocument(bool bSingleViewMode, bool bBrowserView, QWidget *parentWidget, const char *widgetName, QObject *, const char *) : Kate::Document (), myFont(KGlobalSettings::generalFont()), myFontBold(KGlobalSettings::generalFont()), myFontItalic(KGlobalSettings::generalFont()), myFontBI(KGlobalSettings::generalFont()), myFontMetrics (myFont), myFontMetricsBold (myFontBold), myFontMetricsItalic (myFontItalic), myFontMetricsBI (myFontBI), hlManager(HlManager::self ()) { d(this)->hlSetByUser = false; PreHighlightedTill=0; RequestPreHighlightTill=0; m_bSingleViewMode=bSingleViewMode; m_bBrowserView = bBrowserView; m_url = QString::null; // NOTE: QFont::CharSet doesn't provide all the charsets KDE supports // (esp. it doesn't distinguish between UTF-8 and iso10646-1) myEncoding = QString::fromLatin1(QTextCodec::codecForLocale()->name()); maxLength = -1; setFont (KGlobalSettings::generalFont()); myDocID = uniqueID; uniqueID++; myDocName = QString (""); fileInfo = new QFileInfo (); myCmd = new KateCmd (this); connect(this,SIGNAL(modifiedChanged()),this,SLOT(slotModChanged())); buffer = new KWBuffer; connect(buffer, SIGNAL(linesChanged(int)), this, SLOT(slotBufferChanged())); // connect(buffer, SIGNAL(textChanged()), this, SIGNAL(textChanged())); connect(buffer, SIGNAL(needHighlight(long,long)),this,SLOT(slotBufferHighlight(long,long))); colors[0] = KGlobalSettings::baseColor(); colors[1] = KGlobalSettings::highlightColor(); m_attribs = new Attribute[maxAttribs]; m_highlight = 0L; tabChars = 8; m_singleSelection = false; newDocGeometry = false; readOnly = false; newDoc = false; modified = false; undoList.setAutoDelete(true); undoState = 0; undoSteps = 50; pseudoModal = 0L; clear(); setHighlight(0); //calls updateFontData() // if the user changes the highlight with the dialog, notify the doc connect(hlManager,SIGNAL(changed()),SLOT(hlChanged())); newDocGeometry = false; readConfig(); setReadOnly(false); } void KateDocument::setDontChangeHlOnSave() { d(this)->hlSetByUser = true; } void KateDocument::setFont (QFont font) { kdDebug()<<"Kate:: setFont"<<endl; int oldwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0 myFont = font; myFontBold = QFont (font); myFontBold.setBold (true); myFontItalic = QFont (font); myFontItalic.setItalic (true); myFontBI = QFont (font); myFontBI.setBold (true); myFontBI.setItalic (true); myFontMetrics = CachedFontMetrics (myFont); myFontMetricsBold = CachedFontMetrics (myFontBold); myFontMetricsItalic = CachedFontMetrics (myFontItalic); myFontMetricsBI = CachedFontMetrics (myFontBI); int newwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0 maxLength=maxLength*(float)newwidth/(float)oldwidth; //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0 updateFontData(); updateViews(); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0 } long KateDocument::needPreHighlight(long till) { int max=numLines()-1; if (till>max) { till=max; } if (PreHighlightedTill>=till) return -1; long tmp=RequestPreHighlightTill; if (RequestPreHighlightTill<till) { RequestPreHighlightTill=till; if (tmp<=PreHighlightedTill) QTimer::singleShot(10,this,SLOT(doPreHighlight())); } return RequestPreHighlightTill; } void KateDocument::doPreHighlight() { int from = PreHighlightedTill; int till = PreHighlightedTill+200; int max = numLines()-1; if (till > max) { till = max; } PreHighlightedTill = till; updateLines(from,till); emit preHighlightChanged(PreHighlightedTill); if (PreHighlightedTill<RequestPreHighlightTill) QTimer::singleShot(10,this,SLOT(doPreHighlight())); } KateDocument::~KateDocument() { m_highlight->release(); writeConfig(); if ( !m_bSingleViewMode ) { m_views.setAutoDelete( true ); m_views.clear(); m_views.setAutoDelete( false ); } delete_d(this); } void KateDocument::openURL(const QString &filename) { m_file=filename; fileInfo->setFile (m_file); setMTime(); if (!fileInfo->exists() || !fileInfo->isReadable()) { odebug << "File doesn't exit or couldn't be read" << oendl; return ; } buffer->clear(); #warning fixme // buffer->insertFile(0, m_file, KGlobal::charsets()->codecForName(myEncoding)); odebug << "Telling buffer to open file" << oendl; buffer->insertFile(0, m_file, QTextCodec::codecForLocale()); setMTime(); if (myWordWrap) wrapText (myWordWrapAt); int hl = hlManager->wildcardFind( m_file ); setHighlight(hl); updateLines(); updateViews(); emit fileNameChanged(); return ; } bool KateDocument::saveFile() { QFile f( m_file ); if ( !f.open( IO_WriteOnly ) ) return false; // Error QTextStream stream(&f); stream.setEncoding(QTextStream::RawUnicode); // disable Unicode headers #warning fixme // stream.setCodec(KGlobal::charsets()->codecForName(myEncoding)); stream.setCodec(QTextCodec::codecForLocale()); // this line sets the mapper to the correct codec int maxLine = numLines(); int line = 0; while(true) { stream << getTextLine(line)->getString(); line++; if (line >= maxLine) break; if (eolMode == KateDocument::eolUnix) stream << "\n"; else if (eolMode == KateDocument::eolDos) stream << "\r\n"; else if (eolMode == KateDocument::eolMacintosh) stream << '\r'; }; f.close(); fileInfo->setFile (m_file); setMTime(); if (!(d(this)->hlSetByUser)) { int hl = hlManager->wildcardFind( m_file ); setHighlight(hl); } emit fileNameChanged (); - return (f.status() == IO_Ok); + if(f.status() == IO_Ok) { + setModified(false); + return true; + } + else + return false; } KTextEditor::View *KateDocument::createView( QWidget *parent, const char *name ) { return new KateView( this, parent, name); } QString KateDocument::textLine( int line ) const { TextLine::Ptr l = getTextLine( line ); if ( !l ) return QString(); return l->getString(); } void KateDocument::replaceLine(const QString& s,int line) { remove_Line(line,false); insert_Line(s,line,true); } void KateDocument::insertLine( const QString &str, int l ) { insert_Line(str,l,true); } void KateDocument::insert_Line(const QString& s,int line, bool update) { kdDebug(13020)<<"KateDocument::insertLine "<<s<<QString(" %1").arg(line)<<endl; TextLine::Ptr TL=new TextLine(); TL->append(s.unicode(),s.length()); buffer->insertLine(line,TL); if (update) { newDocGeometry=true; updateLines(line); updateViews(); } } void KateDocument::insertAt( const QString &s, int line, int col, bool ) { VConfig c; c.view = 0; // ### FIXME c.cursor.x = col; c.cursor.y = line; c.cXPos = 0; // ### FIXME c.flags = 0; // ### FIXME insert( c, s ); } void KateDocument::removeLine( int line ) { remove_Line(line,true); } void KateDocument::remove_Line(int line,bool update) { kdDebug(13020)<<"KateDocument::removeLine "<<QString("%1").arg(line)<<endl; buffer->removeLine(line); // newDocGeometry=true; // if line==0) if (update) { updateLines(line); updateViews(); } } int KateDocument::length() const { return text().length(); } void KateDocument::setSelection( int , int , int , int ) { } bool KateDocument::hasSelection() const { return (selectEnd >= selectStart); } QString KateDocument::selection() const { uint flags = 0; TextLine::Ptr textLine; int len, z, start, end, i; len = 1; if (!(flags & KateView::cfVerticalSelect)) { for (z = selectStart; z <= selectEnd; z++) { textLine = getTextLine(z); len += textLine->numSelected(); if (textLine->isSelected()) len++; } QString s; len = 0; for (z = selectStart; z <= selectEnd; z++) { textLine = getTextLine(z); end = 0; do { start = textLine->findUnselected(end); end = textLine->findSelected(start); for (i = start; i < end; i++) { s[len] = textLine->getChar(i); len++; } } while (start < end); if (textLine->isSelected()) { s[len] = '\n'; len++; } } // s[len] = '\0'; return s; } else { for (z = selectStart; z <= selectEnd; z++) { textLine = getTextLine(z); len += textLine->numSelected() + 1; } QString s; len = 0; for (z = selectStart; z <= selectEnd; z++) { textLine = getTextLine(z); end = 0; do { start = textLine->findUnselected(end); end = textLine->findSelected(start); for (i = start; i < end; i++) { s[len] = textLine->getChar(i); len++; } } while (start < end); s[len] = '\n'; len++; } // s[len] = '\0'; // the final \0 is not counted in length() return s; } } int KateDocument::numLines() const { return buffer->count(); } TextLine::Ptr KateDocument::getTextLine(int line) const { // This is a hack to get this stuff working. return buffer->line(line); } int KateDocument::textLength(int line) { TextLine::Ptr textLine = getTextLine(line); if (!textLine) return 0; return textLine->length(); } void KateDocument::setTabWidth(int chars) { if (tabChars == chars) return; if (chars < 1) chars = 1; if (chars > 16) chars = 16; tabChars = chars; updateFontData(); maxLength = -1; for (int i=0; i < buffer->count(); i++) { TextLine::Ptr textLine = buffer->line(i); int len = textWidth(textLine,textLine->length()); if (len > maxLength) { maxLength = len; longestLine = textLine; } } } void KateDocument::setReadOnly(bool m) { KTextEditor::View *view; if (m != readOnly) { readOnly = m; // if (readOnly) recordReset(); for (view = m_views.first(); view != 0L; view = m_views.next() ) { emit static_cast<KateView *>( view )->newStatus(); } } } bool KateDocument::isReadOnly() const { return readOnly; } void KateDocument::setNewDoc( bool m ) { // KTextEditor::View *view; if ( m != newDoc ) { newDoc = m; //// if (readOnly) recordReset(); // for (view = m_views.first(); view != 0L; view = m_views.next() ) { // emit static_cast<KateView *>( view )->newStatus(); // } } } bool KateDocument::isNewDoc() const { return newDoc; } void KateDocument::setModified(bool m) { KTextEditor::View *view; if (m != modified) { modified = m; for (view = m_views.first(); view != 0L; view = m_views.next() ) { emit static_cast<KateView *>( view )->newStatus(); } emit modifiedChanged (); } } bool KateDocument::isModified() const { return modified; } void KateDocument::readConfig() { KateConfig *config = KGlobal::config(); config->setGroup("Kate Document"); myWordWrap = config->readBoolEntry("Word Wrap On", false); myWordWrapAt = config->readNumEntry("Word Wrap At", 80); if (myWordWrap) wrapText (myWordWrapAt); setTabWidth(config->readNumEntry("TabWidth", 8)); setUndoSteps(config->readNumEntry("UndoSteps", 50)); m_singleSelection = config->readBoolEntry("SingleSelection", false); myEncoding = config->readEntry("Encoding", QString::fromLatin1(QTextCodec::codecForLocale()->name())); setFont (config->readFontEntry("Font", myFont)); colors[0] = config->readColorEntry("Color Background", colors[0]); colors[1] = config->readColorEntry("Color Selected", colors[1]); // config->sync(); } void KateDocument::writeConfig() { KateConfig *config = KGlobal::config(); config->setGroup("Kate Document"); config->writeEntry("Word Wrap On", myWordWrap); config->writeEntry("Word Wrap At", myWordWrapAt); config->writeEntry("TabWidth", tabChars); config->writeEntry("UndoSteps", undoSteps); config->writeEntry("SingleSelection", m_singleSelection); config->writeEntry("Encoding", myEncoding); config->writeEntry("Font", myFont); config->writeEntry("Color Background", colors[0]); config->writeEntry("Color Selected", colors[1]); // config->sync(); } void KateDocument::readSessionConfig(KateConfig *config) { m_url = config->readEntry("URL"); // ### doesn't this break the encoding? (Simon) setHighlight(hlManager->nameFind(config->readEntry("Highlight"))); // anders: restore bookmarks if possible QValueList<int> l = config->readIntListEntry("Bookmarks"); if ( l.count() ) { for (uint i=0; i < l.count(); i++) { if ( numLines() < l[i] ) break; getTextLine( l[i] )->addMark( Bookmark ); } } } void KateDocument::writeSessionConfig(KateConfig *config) { #if 0 config->writeEntry("URL", m_url); // ### encoding?? (Simon) config->writeEntry("Highlight", m_highlight->name()); // anders: save bookmarks QList<Kate::Mark> l = marks(); QValueList<int> ml; for (uint i=0; i < l.count(); i++) { if ( l.at(i)->type == 1) // only save bookmarks ml << l.at(i)->line; } if ( ml.count() ) config->writeEntry("Bookmarks", ml); #endif } void KateDocument::setHighlight(int n) { Highlight *h; // hlNumber = n; h = hlManager->getHl(n); if (h == m_highlight) { updateLines(); } else { if (m_highlight != 0L) m_highlight->release(); h->use(); m_highlight = h; makeAttribs(); } PreHighlightedTill=0; RequestPreHighlightTill=0; emit(highlightChanged()); } void KateDocument::makeAttribs() { odebug << "KateDocument::makeAttribs()" << oendl; m_numAttribs = hlManager->makeAttribs(m_highlight, m_attribs, maxAttribs); updateFontData(); updateLines(); } void KateDocument::updateFontData() { int maxAscent, maxDescent; int tabWidth; KateView *view; maxAscent = myFontMetrics.ascent(); maxDescent = myFontMetrics.descent(); tabWidth = myFontMetrics.width(' '); fontHeight = maxAscent + maxDescent + 1; fontAscent = maxAscent; m_tabWidth = tabChars*tabWidth; for (view = views.first(); view != 0L; view = views.next() ) { view->myViewInternal->drawBuffer->resize(view->width(),fontHeight); view->tagAll(); view->updateCursor(); } } void KateDocument::hlChanged() { //slot makeAttribs(); updateViews(); } void KateDocument::addView(KTextEditor::View *view) { views.append( static_cast<KateView *>( view ) ); KTextEditor::Document::addView( view ); connect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) ); } void KateDocument::removeView(KTextEditor::View *view) { // if (undoView == view) recordReset(); disconnect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) ); views.removeRef( static_cast<KateView *>( view ) ); KTextEditor::Document::removeView( view ); } void KateDocument::slotViewDestroyed() { views.removeRef( static_cast<const KateView *>( sender() ) ); } bool KateDocument::ownedView(KateView *view) { // do we own the given view? return (views.containsRef(view) > 0); } bool KateDocument::isLastView(int numViews) { return ((int) views.count() == numViews); } int KateDocument::textWidth(const TextLine::Ptr &textLine, int cursorX) { int x; int z; QChar ch; Attribute *a; x = 0; for (z = 0; z < cursorX; z++) { ch = textLine->getChar(z); a = &m_attribs[textLine->getAttr(z)]; if (ch == '\t') x += m_tabWidth - (x % m_tabWidth); else if (a->bold && a->italic) x += myFontMetricsBI.width(ch); else if (a->bold) x += myFontMetricsBold.width(ch); else if (a->italic) x += myFontMetricsItalic.width(ch); else x += myFontMetrics.width(ch); } return x; } int KateDocument::textWidth(PointStruc &cursor) { if (cursor.x < 0) cursor.x = 0; if (cursor.y < 0) cursor.y = 0; if (cursor.y >= numLines()) cursor.y = lastLine(); return textWidth(getTextLine(cursor.y),cursor.x); } int KateDocument::textWidth(bool wrapCursor, PointStruc &cursor, int xPos) { int len; int x, oldX; int z; QChar ch; Attribute *a; if (cursor.y < 0) cursor.y = 0; if (cursor.y > lastLine()) cursor.y = lastLine(); TextLine::Ptr textLine = getTextLine(cursor.y); len = textLine->length(); x = oldX = z = 0; while (x < xPos && (!wrapCursor || z < len)) { oldX = x; ch = textLine->getChar(z); a = &m_attribs[textLine->getAttr(z)]; if (ch == '\t') x += m_tabWidth - (x % m_tabWidth); else if (a->bold && a->italic) x += myFontMetricsBI.width(ch); else if (a->bold) x += myFontMetricsBold.width(ch); else if (a->italic) x += myFontMetricsItalic.width(ch); else x += myFontMetrics.width(ch); z++; } if (xPos - oldX < x - xPos && z > 0) { z--; x = oldX; } cursor.x = z; return x; } int KateDocument::textPos(const TextLine::Ptr &textLine, int xPos) { int x, oldX; int z; QChar ch; Attribute *a; x = oldX = z = 0; while (x < xPos) { // && z < len) { oldX = x; ch = textLine->getChar(z); a = &m_attribs[textLine->getAttr(z)]; if (ch == '\t') x += m_tabWidth - (x % m_tabWidth); else if (a->bold && a->italic) x += myFontMetricsBI.width(ch); else if (a->bold) x += myFontMetricsBold.width(ch); else if (a->italic) x += myFontMetricsItalic.width(ch); else x += myFontMetrics.width(ch); z++; } if (xPos - oldX < x - xPos && z > 0) { z--; // newXPos = oldX; }// else newXPos = x; return z; } int KateDocument::textWidth() { return int(maxLength + 8); } int KateDocument::textHeight() { return numLines()*fontHeight; } void KateDocument::insert(VConfig &c, const QString &s) { int pos; QChar ch; QString buf; if (s.isEmpty()) return; recordStart(c, KateActionGroup::ugPaste); pos = 0; if (!(c.flags & KateView::cfVerticalSelect)) { do { ch = s[pos]; if (ch.isPrint() || ch == '\t') { buf += ch; // append char to buffer } else if (ch == '\n') { recordAction(KateAction::newLine, c.cursor); // wrap contents behind cursor to new line recordInsert(c, buf); // append to old line // c.cursor.x += buf.length(); buf.truncate(0); // clear buffer c.cursor.y++; c.cursor.x = 0; } pos++; } while (pos < (int) s.length()); } else { int xPos; xPos = textWidth(c.cursor); do { ch = s[pos]; if (ch.isPrint() || ch == '\t') { buf += ch; } else if (ch == '\n') { recordInsert(c, buf); c.cursor.x += buf.length(); buf.truncate(0); c.cursor.y++; if (c.cursor.y >= numLines()) recordAction(KateAction::insLine, c.cursor); c.cursor.x = textPos(getTextLine(c.cursor.y), xPos); } pos++; } while (pos < (int) s.length()); } recordInsert(c, buf); c.cursor.x += buf.length(); recordEnd(c); } void KateDocument::insertFile(VConfig &c, QIODevice &dev) { recordStart(c, KateActionGroup::ugPaste); QString buf; QChar ch, last; QTextStream stream( &dev ); while ( !stream.atEnd() ) { stream >> ch; if (ch.isPrint() || ch == '\t') { buf += ch; } else if (ch == '\n' || ch == '\r') { if (last != '\r' || ch != '\n') { recordAction(KateAction::newLine, c.cursor); recordInsert(c, buf); buf.truncate(0); c.cursor.y++; c.cursor.x = 0; } last = ch; } } recordInsert(c, buf); recordEnd(c); } int KateDocument::currentColumn(PointStruc &cursor) { return getTextLine(cursor.y)->cursorX(cursor.x,tabChars); } bool KateDocument::insertChars(VConfig &c, const QString &chars) { int z, pos, l; bool onlySpaces; QChar ch; QString buf; TextLine::Ptr textLine = getTextLine(c.cursor.y); pos = 0; onlySpaces = true; for (z = 0; z < (int) chars.length(); z++) { ch = chars[z]; if (ch == '\t' && c.flags & KateView::cfReplaceTabs) { l = tabChars - (textLine->cursorX(c.cursor.x, tabChars) % tabChars); while (l > 0) { buf.insert(pos, ' '); pos++; l--; } } else if (ch.isPrint() || ch == '\t') { buf.insert(pos, ch); pos++; if (ch != ' ') onlySpaces = false; if (c.flags & KateView::cfAutoBrackets) { if (ch == '(') buf.insert(pos, ')'); if (ch == '[') buf.insert(pos, ']'); if (ch == '{') buf.insert(pos, '}'); } } } //pos = cursor increment //return false if nothing has to be inserted if (buf.isEmpty()) return false; //auto deletion of the marked text occurs not very often and can therefore // be recorded separately if (c.flags &KateView:: cfDelOnInput) delMarkedText(c); recordStart(c, KateActionGroup::ugInsChar); recordReplace(c/*.cursor*/, (c.flags & KateView::cfOvr) ? buf.length() : 0, buf); c.cursor.x += pos; if (myWordWrap && myWordWrapAt > 0) { int line; const QChar *s; // int pos; PointStruc actionCursor; line = c.cursor.y; do { textLine = getTextLine(line); s = textLine->getText(); l = textLine->length(); for (z = myWordWrapAt; z < l; z++) if (!s[z].isSpace()) break; //search for text to wrap if (z >= l) break; // nothing more to wrap pos = myWordWrapAt; for (; z >= 0; z--) { //find wrap position if (s[z].isSpace()) { pos = z + 1; break; } } //pos = wrap position if (line == c.cursor.y && pos <= c.cursor.x) { //wrap cursor c.cursor.y++; c.cursor.x -= pos; } if (line == lastLine() || (getTextLine(line+1)->length() == 0) ) { //at end of doc: create new line actionCursor.x = pos; actionCursor.y = line; recordAction(KateAction::newLine,actionCursor); } else { //wrap actionCursor.y = line + 1; if (!s[l - 1].isSpace()) { //add space in next line if necessary actionCursor.x = 0; recordInsert(actionCursor, " "); } actionCursor.x = textLine->length() - pos; recordAction(KateAction::wordWrap, actionCursor); } line++; } while (true); } recordEnd(c); return true; } QString tabString(int pos, int tabChars) { QString s; while (pos >= tabChars) { s += '\t'; pos -= tabChars; } while (pos > 0) { s += ' '; pos--; } return s; } void KateDocument::newLine(VConfig &c) { //auto deletion of marked text is done by the view to have a more // "low level" KateDocument::newLine method recordStart(c, KateActionGroup::ugInsLine); if (!(c.flags & KateView::cfAutoIndent)) { recordAction(KateAction::newLine,c.cursor); c.cursor.y++; c.cursor.x = 0; } else { TextLine::Ptr textLine = getTextLine(c.cursor.y); int pos = textLine->firstChar(); if (c.cursor.x < pos) c.cursor.x = pos; // place cursor on first char if before int y = c.cursor.y; while ((y > 0) && (pos < 0)) { // search a not empty text line textLine = getTextLine(--y); pos = textLine->firstChar(); } recordAction(KateAction::newLine, c.cursor); c.cursor.y++; c.cursor.x = 0; if (pos > 0) { pos = textLine->cursorX(pos, tabChars); // if (getTextLine(c.cursor.y)->length() > 0) { QString s = tabString(pos, (c.flags & KateView::cfSpaceIndent) ? 0xffffff : tabChars); recordInsert(c.cursor, s); pos = s.length(); // } // recordInsert(c.cursor, QString(textLine->getText(), pos)); c.cursor.x = pos; } } recordEnd(c); } void KateDocument::killLine(VConfig &c) { recordStart(c, KateActionGroup::ugDelLine); c.cursor.x = 0; recordDelete(c.cursor, 0xffffff); if (c.cursor.y < lastLine()) { recordAction(KateAction::killLine, c.cursor); } recordEnd(c); } void KateDocument::backspace(VConfig &c) { if (c.cursor.x <= 0 && c.cursor.y <= 0) return; if (c.cursor.x > 0) { recordStart(c, KateActionGroup::ugDelChar); if (!(c.flags & KateView::cfBackspaceIndents)) { // ordinary backspace c.cursor.x--; recordDelete(c.cursor, 1); } else { // backspace indents: erase to next indent position int l = 1; // del one char TextLine::Ptr textLine = getTextLine(c.cursor.y); int pos = textLine->firstChar(); if (pos < 0 || pos >= c.cursor.x) { // only spaces on left side of cursor // search a line with less spaces int y = c.cursor.y; while (y > 0) { textLine = getTextLine(--y); pos = textLine->firstChar(); if (pos >= 0 && pos < c.cursor.x) { l = c.cursor.x - pos; // del more chars break; } } } // break effectively jumps here c.cursor.x -= l; recordDelete(c.cursor, l); } } else { // c.cursor.x == 0: wrap to previous line recordStart(c, KateActionGroup::ugDelLine); c.cursor.y--; |