diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index db5413c3446c8370c5d99db1a79d0c380508c424..8d5bf3ff6836993981b4320e0345ff07044500b7 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -684,6 +684,64 @@ void BaseTextEditor::selectBlockDown()
     _q_matchParentheses();
 }
 
+void BaseTextEditor::moveLineUp()
+{
+    moveLineUpDown(true);
+}
+
+void BaseTextEditor::moveLineDown()
+{
+    moveLineUpDown(false);
+}
+
+void BaseTextEditor::moveLineUpDown(bool up)
+{
+    QTextCursor cursor = textCursor();
+    QTextCursor move = cursor;
+    move.beginEditBlock();
+
+    bool hasSelection = cursor.hasSelection();
+
+    if (cursor.hasSelection()) {
+        move.setPosition(cursor.selectionStart());
+        move.movePosition(QTextCursor::StartOfBlock);
+        move.setPosition(cursor.selectionEnd(), QTextCursor::KeepAnchor);
+        move.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+    } else {
+        move.movePosition(QTextCursor::StartOfBlock);
+        move.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+    }
+    QString text = move.selectedText();
+    move.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
+    move.removeSelectedText();
+    
+    if (up) {
+        move.movePosition(QTextCursor::PreviousBlock);
+        move.insertBlock();
+        move.movePosition(QTextCursor::Left);
+    } else {
+        move.movePosition(QTextCursor::EndOfBlock);
+        if (move.atBlockStart()) { // empty block
+            move.movePosition(QTextCursor::NextBlock);
+            move.insertBlock();
+            move.movePosition(QTextCursor::Left);
+        } else {
+            move.insertBlock();
+        }
+    }
+    
+    int start = move.position();
+    move.clearSelection();
+    move.insertText(text);
+    int end = move.position();
+    move.endEditBlock();
+    if (hasSelection) {
+        move.setPosition(start);
+        move.setPosition(end, QTextCursor::KeepAnchor);
+    }
+
+    setTextCursor(move);
+}
 
 void BaseTextEditor::cleanWhitespace()
 {
@@ -740,9 +798,13 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
         QTextCursor cursor = textCursor();
         if (d->m_inBlockSelectionMode)
             cursor.clearSelection();
-        cursor.insertBlock();
         if (d->m_document->tabSettings().m_autoIndent) {
+            cursor.beginEditBlock();
+            cursor.insertBlock();
             indent(document(), cursor, QChar::Null);
+            cursor.endEditBlock();
+        } else {
+            cursor.insertBlock();
         }
         e->accept();
         setTextCursor(cursor);
diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h
index 1219439fc986264c6e55230cac59b0b00c507a4e..7c2206722bf6f6baa1deeab1423dfc60829067f2 100644
--- a/src/plugins/texteditor/basetexteditor.h
+++ b/src/plugins/texteditor/basetexteditor.h
@@ -329,6 +329,9 @@ public slots:
     void selectBlockUp();
     void selectBlockDown();
 
+    void moveLineUp();
+    void moveLineDown();
+
     void cleanWhitespace();
 
 signals:
@@ -447,6 +450,7 @@ private:
     void indentOrUnindent(bool doIndent);
     void handleHomeKey(bool anchor);
     void handleBackspaceKey();
+    void moveLineUpDown(bool up);
 
     void toggleBlockVisible(const QTextBlock &block);
     QRect collapseBox(const QTextBlock &block);
diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp
index 12fc7d1fac5a3d2b55f6c76d412e008238a86d75..39a12ee93fd98159b1e5efb2a797626bbd2d3e75 100644
--- a/src/plugins/texteditor/texteditoractionhandler.cpp
+++ b/src/plugins/texteditor/texteditoractionhandler.cpp
@@ -71,6 +71,7 @@ TextEditorActionHandler::TextEditorActionHandler(Core::ICore *core,
                  = m_gotoBlockStartAction = m_gotoBlockStartWithSelectionAction
                  = m_gotoBlockEndAction = m_gotoBlockEndWithSelectionAction
                  = m_selectBlockUpAction = m_selectBlockDownAction
+                 = m_moveLineUpAction = m_moveLineDownAction
                  = 0;
 
     m_contextId << m_core->uniqueIDManager()->uniqueIdentifier(context);
@@ -223,6 +224,16 @@ void TextEditorActionHandler::createActions()
     command = am->registerAction(m_selectBlockDownAction, Constants::SELECT_BLOCK_DOWN, m_contextId);
     command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+U")));
     connect(m_selectBlockDownAction, SIGNAL(triggered()), this, SLOT(selectBlockDown()));
+
+    m_moveLineUpAction= new QAction(tr("Move Line Up"), this);
+    command = am->registerAction(m_moveLineUpAction, Constants::MOVE_LINE_UP, m_contextId);
+    command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+Up")));
+    connect(m_moveLineUpAction, SIGNAL(triggered()), this, SLOT(moveLineUp()));
+
+    m_moveLineDownAction= new QAction(tr("Move Line Down"), this);
+    command = am->registerAction(m_moveLineDownAction, Constants::MOVE_LINE_DOWN, m_contextId);
+    command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+Down")));
+    connect(m_moveLineDownAction, SIGNAL(triggered()), this, SLOT(moveLineDown()));
 }
 
 bool TextEditorActionHandler::supportsAction(const QString & /*id */) const
@@ -287,6 +298,8 @@ void TextEditorActionHandler::updateActions(UpdateMode um)
     m_gotoBlockEndWithSelectionAction->setEnabled(um != NoEditor);
     m_selectBlockUpAction->setEnabled(um != NoEditor);
     m_selectBlockDownAction->setEnabled(um != NoEditor);
+    m_moveLineUpAction->setEnabled(um != NoEditor);
+    m_moveLineDownAction->setEnabled(um != NoEditor);
 
     m_visualizeWhitespaceAction->setEnabled(um != NoEditor);
     if (m_currentEditor)
@@ -390,6 +403,8 @@ FUNCTION(gotoBlockStartWithSelection)
 FUNCTION(gotoBlockEndWithSelection)
 FUNCTION(selectBlockUp)
 FUNCTION(selectBlockDown)
+FUNCTION(moveLineUp)
+FUNCTION(moveLineDown)
 
 void TextEditorActionHandler::updateCurrentEditor(Core::IContext *object)
 {
diff --git a/src/plugins/texteditor/texteditoractionhandler.h b/src/plugins/texteditor/texteditoractionhandler.h
index 520ae26ddf6618e0a09d18cc80f8751592901fbc..98e8c9198a9dd10ac27d8f6e558f01c14311af3c 100644
--- a/src/plugins/texteditor/texteditoractionhandler.h
+++ b/src/plugins/texteditor/texteditoractionhandler.h
@@ -116,6 +116,8 @@ private slots:
     void gotoBlockEndWithSelection();
     void selectBlockUp();
     void selectBlockDown();
+    void moveLineUp();
+    void moveLineDown();
     void updateCurrentEditor(Core::IContext *object);
 
 private:
@@ -145,6 +147,8 @@ private:
     QAction *m_gotoBlockEndWithSelectionAction;
     QAction *m_selectBlockUpAction;
     QAction *m_selectBlockDownAction;
+    QAction *m_moveLineUpAction;
+    QAction *m_moveLineDownAction;
 
     uint m_optionalActions;
     QPointer<BaseTextEditor> m_currentEditor;
diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h
index 192a07c257e86ec089721fc19f27edbfc3b857b7..d9147a9a9e92cd37f1e5ae452e3100be99e6a154 100644
--- a/src/plugins/texteditor/texteditorconstants.h
+++ b/src/plugins/texteditor/texteditorconstants.h
@@ -55,6 +55,8 @@ const char * const GOTO_BLOCK_END        = "TextEditor.GotoBlockEnd";
 const char * const GOTO_BLOCK_END_WITH_SELECTION = "TextEditor.GotoBlockEndWithSelection";
 const char * const SELECT_BLOCK_UP       = "TextEditor.SelectBlockUp";
 const char * const SELECT_BLOCK_DOWN     = "TextEditor.SelectBlockDown";
+const char * const MOVE_LINE_UP       = "TextEditor.MoveLineUp";
+const char * const MOVE_LINE_DOWN     = "TextEditor.MoveLineDown";
 const char * const DELETE_LINE           = "TextEditor.DeleteLine";
 const char * const DELETE_WORD           = "TextEditor.DeleteWord";
 const char * const SELECT_ENCODING       = "TextEditor.SelectEncoding";