예제 #1
0
void SwapFile::fileLoaded(const QString&)
{
  // look for swap file
  if (!updateFileName())
    return;

  if (!m_swapfile.exists())
  {
    kDebug (13020) << "No swap file";
    return;
  }

  if (!QFileInfo(m_swapfile).isReadable())
  {
    kWarning( 13020 ) << "Can't open swap file (missing permissions)";
    return;
  }

  // sanity check
  QFile peekFile(fileName());
  if (peekFile.open(QIODevice::ReadOnly)) {
    QDataStream stream(&peekFile);
    if (!isValidSwapFile(stream, true)) {
      removeSwapFile();
      return;
    }
    peekFile.close();
  } else {
    kWarning( 13020 ) << "Can't open swap file:" << fileName();
    return;
  }

  // show swap file message
  m_document->setReadWrite(false);
  showSwapFileMessage();
}
예제 #2
0
bool SwapFile::recover(QDataStream& stream, bool checkDigest)
{
  if (!isValidSwapFile(stream, checkDigest)) {
    return false;
  }

  // disconnect current signals
  setTrackingEnabled(false);

  // needed to set undo/redo cursors in a sane way
  bool firstEditInGroup = false;
  KTextEditor::Cursor undoCursor = KTextEditor::Cursor::invalid();
  KTextEditor::Cursor redoCursor = KTextEditor::Cursor::invalid();

  // replay swapfile
  bool editRunning = false;
  bool brokenSwapFile = false;
  while (!stream.atEnd()) {
    if (brokenSwapFile)
      break;

    qint8 type;
    stream >> type;
    switch (type) {
      case EA_StartEditing: {
        m_document->editStart();
        editRunning = true;
        firstEditInGroup = true;
        undoCursor = KTextEditor::Cursor::invalid();
        redoCursor = KTextEditor::Cursor::invalid();
        break;
      }
      case EA_FinishEditing: {
        m_document->editEnd();
        
        // empty editStart() / editEnd() groups exist: only set cursor if required
        if (!firstEditInGroup) {
          // set undo/redo cursor of last KateUndoGroup of the undo manager
          m_document->undoManager()->setUndoRedoCursorsOfLastGroup(undoCursor, redoCursor);
          m_document->undoManager()->undoSafePoint();
        }
        firstEditInGroup = false;
        editRunning = false;
        break;
      }
      case EA_WrapLine: {
        if (!editRunning) {
          brokenSwapFile = true;
          break;
        }

        int line = 0, column = 0;
        stream >> line >> column;
        
        // emulate buffer unwrapLine with document
        m_document->editWrapLine(line, column, true);

        // track undo/redo cursor
        if (firstEditInGroup) {
          firstEditInGroup = false;
          undoCursor = KTextEditor::Cursor(line, column);
        }
        redoCursor = KTextEditor::Cursor(line + 1, 0);

        break;
      }
      case EA_UnwrapLine: {
        if (!editRunning) {
          brokenSwapFile = true;
          break;
        }

        int line = 0;
        stream >> line;
        
        // assert valid line
        Q_ASSERT (line > 0);

        const int undoColumn = m_document->lineLength(line - 1);

        // emulate buffer unwrapLine with document
        m_document->editUnWrapLine(line - 1, true, 0);

        // track undo/redo cursor
        if (firstEditInGroup) {
          firstEditInGroup = false;
          undoCursor = KTextEditor::Cursor(line, 0);
        }
        redoCursor = KTextEditor::Cursor(line - 1, undoColumn);

        break;
      }
      case EA_InsertText: {
        if (!editRunning) {
          brokenSwapFile = true;
          break;
        }

        int line, column;
        QByteArray text;
        stream >> line >> column >> text;
        m_document->insertText(KTextEditor::Cursor(line, column), QString::fromUtf8 (text.data (), text.size()));

        // track undo/redo cursor
        if (firstEditInGroup) {
          firstEditInGroup = false;
          undoCursor = KTextEditor::Cursor(line, column);
        }
        redoCursor = KTextEditor::Cursor(line, column + text.size());

        break;
      }
      case EA_RemoveText: {
        if (!editRunning) {
          brokenSwapFile = true;
          break;
        }

        int line, startColumn, endColumn;
        stream >> line >> startColumn >> endColumn;
        m_document->removeText (KTextEditor::Range(KTextEditor::Cursor(line, startColumn), KTextEditor::Cursor(line, endColumn)));

        // track undo/redo cursor
        if (firstEditInGroup) {
          firstEditInGroup = false;
          undoCursor = KTextEditor::Cursor(line, endColumn);
        }
        redoCursor = KTextEditor::Cursor(line, startColumn);

        break;
      }
      default: {
        kWarning( 13020 ) << "Unknown type:" << type;
      }
    }
  }

  // balanced editStart and editEnd?
  if (editRunning) {
    brokenSwapFile = true;
    m_document->editEnd();
  }

  // warn the user if the swap file is not complete
  if (brokenSwapFile) {
    kWarning ( 13020 ) << "Some data might be lost";
  } else {
    // set sane final cursor, if possible
    KTextEditor::View * view = m_document->activeView();
    redoCursor = m_document->undoManager()->lastRedoCursor();
    if (view && redoCursor.isValid()) {
      view->setCursorPosition(redoCursor);
    }
  }

  // reconnect the signals
  setTrackingEnabled(true);

  return true;
}
예제 #3
0
bool SwapFile::recover(QDataStream& stream, bool checkDigest)
{
  if (!isValidSwapFile(stream, checkDigest)) {
    return false;
  }

  // disconnect current signals
  setTrackingEnabled(false);

  // replay swapfile
  bool editStarted = false;
  bool brokenSwapFile = false;
  while (!stream.atEnd()) {
    if (brokenSwapFile)
      break;

    qint8 type;
    stream >> type;
    switch (type) {
      case EA_StartEditing: {
        m_document->editStart();
        editStarted = true;
        break;
      }
      case EA_FinishEditing: {
        m_document->editEnd();
        editStarted = false;
        break;
      }
      case EA_WrapLine: {
        if (!editStarted) {
          brokenSwapFile = true;
          break;
        }

        int line = 0, column = 0;
        stream >> line >> column;
        
        // emulate buffer unwrapLine with document
        m_document->editWrapLine(line, column, true);
        break;
      }
      case EA_UnwrapLine: {
        if (!editStarted) {
          brokenSwapFile = true;
          break;
        }

        int line = 0;
        stream >> line;
        
        // assert valid line
        Q_ASSERT (line > 0);
        
        // emulate buffer unwrapLine with document
        m_document->editUnWrapLine(line - 1, true, 0);
        break;
      }
      case EA_InsertText: {
        if (!editStarted) {
          brokenSwapFile = true;
          break;
        }

        int line, column;
        QByteArray text;
        stream >> line >> column >> text;
        m_document->insertText(KTextEditor::Cursor(line, column), QString::fromUtf8 (text.data (), text.size()));
        break;
      }
      case EA_RemoveText: {
        if (!editStarted) {
          brokenSwapFile = true;
          break;
        }

        int line, startColumn, endColumn;
        stream >> line >> startColumn >> endColumn;
        m_document->removeText (KTextEditor::Range(KTextEditor::Cursor(line, startColumn), KTextEditor::Cursor(line, endColumn)));
        break;
      }
      default: {
        kWarning( 13020 ) << "Unknown type:" << type;
      }
    }
  }

  // balance editStart and editEnd
  if (editStarted) {
    brokenSwapFile = true;
    m_document->editEnd();
  }

  // warn the user if the swap file is not complete
  if (brokenSwapFile) {
    kWarning ( 13020 ) << "Some data might be lost";
  }
  
  // reconnect the signals
  setTrackingEnabled(true);
  
  return true;
}