From d1fd61cbf35189e3a4823e8afa1c85d9c005f19b Mon Sep 17 00:00:00 2001
From: Daniel Teske <daniel.teske@digia.com>
Date: Wed, 15 Jan 2014 16:58:52 +0100
Subject: [PATCH] Android: Add minimal Java editing support

Indentation for blocks '{'. '}' and completion for keywords.

TODO: "New File" is missing,
TODO: probably needs some tweaks to the indentation.
Task-number: QTCREATORBUG-11220

Change-Id: I758b3815e47d1427d39c0248eb16e39ffb7a29fb
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
---
 src/plugins/android/Java.mimetypes.xml        |   8 ++
 src/plugins/android/android.pro               |  14 +-
 src/plugins/android/android.qbs               |  10 ++
 src/plugins/android/android.qrc               |   1 +
 src/plugins/android/androidconstants.h        |   3 +
 src/plugins/android/androidplugin.cpp         |   7 +
 src/plugins/android/javaautocompleter.cpp     |  44 ++++++
 src/plugins/android/javaautocompleter.h       |  51 +++++++
 .../android/javacompletionassistprovider.cpp  | 120 ++++++++++++++++
 .../android/javacompletionassistprovider.h    |  60 ++++++++
 src/plugins/android/javaeditor.cpp            | 134 ++++++++++++++++++
 src/plugins/android/javaeditor.h              |  88 ++++++++++++
 src/plugins/android/javaeditorfactory.cpp     |  54 +++++++
 src/plugins/android/javaeditorfactory.h       |  48 +++++++
 src/plugins/android/javaindenter.cpp          |  91 ++++++++++++
 src/plugins/android/javaindenter.h            |  53 +++++++
 16 files changed, 784 insertions(+), 2 deletions(-)
 create mode 100644 src/plugins/android/Java.mimetypes.xml
 create mode 100644 src/plugins/android/javaautocompleter.cpp
 create mode 100644 src/plugins/android/javaautocompleter.h
 create mode 100644 src/plugins/android/javacompletionassistprovider.cpp
 create mode 100644 src/plugins/android/javacompletionassistprovider.h
 create mode 100644 src/plugins/android/javaeditor.cpp
 create mode 100644 src/plugins/android/javaeditor.h
 create mode 100644 src/plugins/android/javaeditorfactory.cpp
 create mode 100644 src/plugins/android/javaeditorfactory.h
 create mode 100644 src/plugins/android/javaindenter.cpp
 create mode 100644 src/plugins/android/javaindenter.h

diff --git a/src/plugins/android/Java.mimetypes.xml b/src/plugins/android/Java.mimetypes.xml
new file mode 100644
index 00000000000..e3c6f49d2a1
--- /dev/null
+++ b/src/plugins/android/Java.mimetypes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+    <mime-type type="text/x-java">
+        <sub-class-of type="text/x-csrc"/>
+        <comment>Java Source file</comment>
+        <glob pattern="*.java"/>
+    </mime-type>
+</mime-info>
diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro
index 5833827e345..455e312bf01 100644
--- a/src/plugins/android/android.pro
+++ b/src/plugins/android/android.pro
@@ -49,7 +49,12 @@ HEADERS += \
     createandroidmanifestwizard.h \
     androidpotentialkit.h \
     androidextralibrarylistmodel.h \
-    androidsignaloperation.h
+    androidsignaloperation.h \
+    javaeditor.h \
+    javaeditorfactory.h \
+    javaindenter.h \
+    javaautocompleter.h \
+    javacompletionassistprovider.h
 
 SOURCES += \
     androidconfigurations.cpp \
@@ -93,7 +98,12 @@ SOURCES += \
     createandroidmanifestwizard.cpp \
     androidpotentialkit.cpp \
     androidextralibrarylistmodel.cpp \
-    androidsignaloperation.cpp
+    androidsignaloperation.cpp \
+    javaeditor.cpp \
+    javaeditorfactory.cpp \
+    javaindenter.cpp \
+    javaautocompleter.cpp \
+    javacompletionassistprovider.cpp
 
 FORMS += \
     androidsettingswidget.ui \
diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs
index 9e9c1f867fb..593f0c5b6f0 100644
--- a/src/plugins/android/android.qbs
+++ b/src/plugins/android/android.qbs
@@ -112,6 +112,16 @@ QtcPlugin {
         "certificatesmodel.h",
         "createandroidmanifestwizard.cpp",
         "createandroidmanifestwizard.h",
+        "javaautocompleter.cpp",
+        "javaautocompleter.h",
+        "javacompletionassistprovider.cpp",
+        "javacompletionassistprovider.h",
+        "javaeditor.cpp",
+        "javaeditor.h",
+        "javaeditorfactory.cpp",
+        "javaeditorfactory.h",
+        "javaindenter.cpp",
+        "javaindenter.h",
         "javaparser.cpp",
         "javaparser.h",
     ]
diff --git a/src/plugins/android/android.qrc b/src/plugins/android/android.qrc
index 94570ee5f5d..a731753b7e7 100644
--- a/src/plugins/android/android.qrc
+++ b/src/plugins/android/android.qrc
@@ -1,5 +1,6 @@
 <RCC>
     <qresource prefix="/android">
         <file>images/QtAndroid.png</file>
+        <file>Java.mimetypes.xml</file>
     </qresource>
 </RCC>
diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h
index 7cfcdf00699..d685625e157 100644
--- a/src/plugins/android/androidconstants.h
+++ b/src/plugins/android/androidconstants.h
@@ -67,6 +67,9 @@ const char ANDROID_MANIFEST_EDITOR_ID[] = "Android.AndroidManifestEditor.Id";
 const char ANDROID_MANIFEST_EDITOR_CONTEXT[] = "Android.AndroidManifestEditor.Id";
 
 const char ANDROID_BUILDDIRECTORY[] = "android-build";
+const char JAVA_EDITOR_ID[] = "java.editor";
+const char C_JAVA_EDITOR[] = "Java Editor";
+const char JAVA_MIMETYPE[] = "text/x-java";
 } // namespace Constants;
 } // namespace Android
 
diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp
index e772c7fc7ce..77640d02a96 100644
--- a/src/plugins/android/androidplugin.cpp
+++ b/src/plugins/android/androidplugin.cpp
@@ -46,6 +46,8 @@
 #include "androidgdbserverkitinformation.h"
 #include "androidmanifesteditorfactory.h"
 #include "androidpotentialkit.h"
+#include "javaeditorfactory.h"
+#include "javacompletionassistprovider.h"
 #ifdef HAVE_QBS
 #  include "androidqbspropertyprovider.h"
 #endif
@@ -83,6 +85,8 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa
     addAutoReleasedObject(new Internal::AndroidDeployConfigurationFactory);
     addAutoReleasedObject(new Internal::AndroidDeviceFactory);
     addAutoReleasedObject(new Internal::AndroidPotentialKit);
+    addAutoReleasedObject(new Internal::JavaEditorFactory);
+    addAutoReleasedObject(new Internal::JavaCompletionAssistProvider);
     ProjectExplorer::KitManager::registerKitInformation(new Internal::AndroidGdbServerKitInformation);
 
     // AndroidManifest.xml editor
@@ -99,6 +103,9 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa
     }
     addAutoReleasedObject(new Internal::AndroidManifestEditorFactory);
 
+    if (!Core::MimeDatabase::addMimeTypes(QLatin1String(":android/Java.mimetypes.xml"), errorMessage))
+        return false;
+
     connect(ProjectExplorer::KitManager::instance(), SIGNAL(kitsLoaded()),
             this, SLOT(kitsRestored()));
 
diff --git a/src/plugins/android/javaautocompleter.cpp b/src/plugins/android/javaautocompleter.cpp
new file mode 100644
index 00000000000..bc460294949
--- /dev/null
+++ b/src/plugins/android/javaautocompleter.cpp
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "javaautocompleter.h"
+
+using namespace Android;
+using namespace Android::Internal;
+
+JavaAutoCompleter::JavaAutoCompleter()
+{
+}
+
+bool JavaAutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert) const
+{
+    Q_UNUSED(cursor)
+    Q_UNUSED(textToInsert)
+    return true;
+}
diff --git a/src/plugins/android/javaautocompleter.h b/src/plugins/android/javaautocompleter.h
new file mode 100644
index 00000000000..5e1078c0c3d
--- /dev/null
+++ b/src/plugins/android/javaautocompleter.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef JAVAAUTOCOMPLETER_H
+#define JAVAAUTOCOMPLETER_H
+
+#include <texteditor/autocompleter.h>
+
+namespace Android {
+namespace Internal {
+
+class JavaAutoCompleter : public TextEditor::AutoCompleter
+{
+public:
+    // TODO What does the base class do?
+    // I only need the contextAllowsAutoParenthses change
+    JavaAutoCompleter();
+    bool contextAllowsAutoParentheses(const QTextCursor &cursor,
+                                      const QString &textToInsert = QString()) const;
+};
+}
+}
+
+
+#endif // JAVAAUTOCOMPLETER_H
diff --git a/src/plugins/android/javacompletionassistprovider.cpp b/src/plugins/android/javacompletionassistprovider.cpp
new file mode 100644
index 00000000000..142c999e90a
--- /dev/null
+++ b/src/plugins/android/javacompletionassistprovider.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "javacompletionassistprovider.h"
+#include "androidconstants.h"
+
+#include <texteditor/codeassist/keywordscompletionassist.h>
+
+using namespace Android;
+using namespace Android::Internal;
+
+static const char *const keywords[] = {
+    "abstract",
+    "continue",
+    "for",
+    "new",
+    "switch",
+    "assert",
+    "default",
+    "goto",
+    "package",
+    "synchronized",
+    "boolean",
+    "do",
+    "if",
+    "private",
+    "this",
+    "break",
+    "double",
+    "implements",
+    "protected",
+    "throw"
+    "byte",
+    "else",
+    "import",
+    "public",
+    "throws",
+    "case",
+    "enum",
+    "instanceof",
+    "return",
+    "transient",
+    "catch",
+    "extends",
+    "int",
+    "short",
+    "try",
+    "char",
+    "final",
+    "interface",
+    "static",
+    "void",
+    "class",
+    "finally",
+    "long",
+    "strictfp",
+    "volatile",
+    "const",
+    "float",
+    "native",
+    "super",
+    "while",
+    0
+};
+
+JavaCompletionAssistProvider::JavaCompletionAssistProvider()
+{
+}
+
+JavaCompletionAssistProvider::~JavaCompletionAssistProvider()
+{
+
+}
+
+void JavaCompletionAssistProvider::init() const
+{
+    for (uint i = 0; i < sizeof keywords / sizeof keywords[0] - 1; i++)
+        m_keywords.append(QLatin1String(keywords[i]));
+}
+
+bool JavaCompletionAssistProvider::supportsEditor(const Core::Id &editorId) const
+{
+    return editorId == Constants::JAVA_EDITOR_ID;
+}
+
+TextEditor::IAssistProcessor *JavaCompletionAssistProvider::createProcessor() const
+{
+    if (m_keywords.isEmpty())
+        init();
+    TextEditor::Keywords keywords = TextEditor::Keywords(m_keywords,
+                                                         QStringList(),
+                                                         QMap<QString, QStringList>());
+    return new TextEditor::KeywordsCompletionAssistProcessor(keywords);
+}
diff --git a/src/plugins/android/javacompletionassistprovider.h b/src/plugins/android/javacompletionassistprovider.h
new file mode 100644
index 00000000000..92b68f389e0
--- /dev/null
+++ b/src/plugins/android/javacompletionassistprovider.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef JAVACOMPLETIONASSISTPROVIDER_H
+#define JAVACOMPLETIONASSISTPROVIDER_H
+
+#include <texteditor/codeassist/completionassistprovider.h>
+
+#include <QStringList>
+
+namespace Android {
+namespace Internal {
+
+class JavaCompletionAssistProvider : public TextEditor::CompletionAssistProvider
+{
+    Q_OBJECT
+public:
+    JavaCompletionAssistProvider();
+    ~JavaCompletionAssistProvider();
+
+    void init() const;
+
+    bool supportsEditor(const Core::Id &editorId) const;
+    TextEditor::IAssistProcessor *createProcessor() const;
+
+private:
+    mutable QStringList m_keywords;
+};
+
+}
+}
+
+
+#endif // JAVACOMPLETIONASSISTPROVIDER_H
diff --git a/src/plugins/android/javaeditor.cpp b/src/plugins/android/javaeditor.cpp
new file mode 100644
index 00000000000..c4c922873aa
--- /dev/null
+++ b/src/plugins/android/javaeditor.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "javaeditor.h"
+#include "javaindenter.h"
+#include "javaautocompleter.h"
+#include "androidconstants.h"
+#include "javacompletionassistprovider.h"
+
+#include <texteditor/texteditorsettings.h>
+#include <texteditor/texteditorconstants.h>
+#include <texteditor/normalindenter.h>
+#include <texteditor/highlighterutils.h>
+#include <coreplugin/mimedatabase.h>
+#include <extensionsystem/pluginmanager.h>
+
+#include <QFileInfo>
+
+using namespace Android;
+using namespace Android::Internal;
+
+//
+// JavaEditor
+//
+
+JavaEditor::JavaEditor(JavaEditorWidget *editor)
+  : BaseTextEditor(editor)
+{
+    setContext(Core::Context(Constants::C_JAVA_EDITOR,
+              TextEditor::Constants::C_TEXTEDITOR));
+}
+
+Core::IEditor *JavaEditor::duplicate()
+{
+    JavaEditorWidget *ret = new JavaEditorWidget(
+                qobject_cast<JavaEditorWidget*>(editorWidget()));
+    TextEditor::TextEditorSettings::initializeEditor(ret);
+    return ret->editor();
+}
+
+Core::Id JavaEditor::id() const
+{
+    return Core::Id(Constants::JAVA_EDITOR_ID);
+}
+
+TextEditor::CompletionAssistProvider *JavaEditor::completionAssistProvider()
+{
+    return ExtensionSystem::PluginManager::getObject<JavaCompletionAssistProvider>();
+}
+
+//
+// JavaEditorWidget
+//
+
+JavaEditorWidget::JavaEditorWidget(QWidget *parent)
+    : BaseTextEditorWidget(new JavaDocument(), parent)
+{
+    ctor();
+}
+
+JavaEditorWidget::JavaEditorWidget(JavaEditorWidget *other)
+    : BaseTextEditorWidget(other)
+{
+    ctor();
+}
+
+void JavaEditorWidget::ctor()
+{
+    m_commentDefinition.clearCommentStyles();
+    m_commentDefinition.singleLine = QLatin1String("//");
+    m_commentDefinition.multiLineStart = QLatin1String("/*");
+    m_commentDefinition.multiLineEnd = QLatin1String("*/");
+    setAutoCompleter(new JavaAutoCompleter);
+}
+
+void JavaEditorWidget::unCommentSelection()
+{
+    Utils::unCommentSelection(this, m_commentDefinition);
+}
+
+TextEditor::BaseTextEditor *JavaEditorWidget::createEditor()
+{
+    return new JavaEditor(this);
+}
+
+//
+// JavaDocument
+//
+
+JavaDocument::JavaDocument()
+        : TextEditor::BaseTextDocument()
+{
+    setMimeType(QLatin1String(Constants::JAVA_MIMETYPE));
+    setSyntaxHighlighter(TextEditor::createGenericSyntaxHighlighter(Core::MimeDatabase::findByType(QLatin1String(Constants::JAVA_MIMETYPE))));
+    setIndenter(new JavaIndenter);
+}
+
+QString JavaDocument::defaultPath() const
+{
+    QFileInfo fi(filePath());
+    return fi.absolutePath();
+}
+
+QString JavaDocument::suggestedFileName() const
+{
+    QFileInfo fi(filePath());
+    return fi.fileName();
+}
diff --git a/src/plugins/android/javaeditor.h b/src/plugins/android/javaeditor.h
new file mode 100644
index 00000000000..369136858de
--- /dev/null
+++ b/src/plugins/android/javaeditor.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef JAVAEDITOR_H
+#define JAVAEDITOR_H
+
+#include <texteditor/basetextdocument.h>
+#include <texteditor/basetexteditor.h>
+#include <utils/uncommentselection.h>
+
+namespace Android {
+namespace Internal {
+
+class JavaEditorFactory;
+class JavaEditorWidget;
+
+class JavaEditor : public TextEditor::BaseTextEditor
+{
+    Q_OBJECT
+
+public:
+    JavaEditor(JavaEditorWidget *);
+
+    bool duplicateSupported() const { return true; }
+    Core::IEditor *duplicate();
+    Core::Id id() const;
+    TextEditor::CompletionAssistProvider *completionAssistProvider();
+};
+
+class JavaEditorWidget : public TextEditor::BaseTextEditorWidget
+{
+    Q_OBJECT
+
+public:
+    JavaEditorWidget(QWidget *parent = 0);
+    JavaEditorWidget(JavaEditorWidget *other);
+
+    void unCommentSelection();
+
+protected:
+    TextEditor::BaseTextEditor *createEditor();
+
+private:
+    JavaEditorWidget(BaseTextEditorWidget *); // avoid stupidity
+    void ctor();
+    Utils::CommentDefinition m_commentDefinition;
+};
+
+class JavaDocument : public TextEditor::BaseTextDocument
+{
+    Q_OBJECT
+
+public:
+    JavaDocument();
+    QString defaultPath() const;
+    QString suggestedFileName() const;
+};
+
+} // namespace Internal
+} // namespace QmakeProjectManager
+
+#endif // JAVAEDITOR_H
diff --git a/src/plugins/android/javaeditorfactory.cpp b/src/plugins/android/javaeditorfactory.cpp
new file mode 100644
index 00000000000..be9bee9dccb
--- /dev/null
+++ b/src/plugins/android/javaeditorfactory.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "javaeditorfactory.h"
+#include "javaeditor.h"
+#include "androidconstants.h"
+
+#include <texteditor/texteditoractionhandler.h>
+#include <texteditor/texteditorsettings.h>
+
+using namespace Android;
+using namespace Android::Internal;
+
+JavaEditorFactory::JavaEditorFactory()
+{
+    setId(Android::Constants::JAVA_EDITOR_ID);
+    setDisplayName(tr("Java Editor"));
+    addMimeType(Android::Constants::JAVA_MIMETYPE);
+    new TextEditor::TextEditorActionHandler(this, Constants::C_JAVA_EDITOR,
+                  TextEditor::TextEditorActionHandler::UnCommentSelection);
+}
+
+Core::IEditor *JavaEditorFactory::createEditor()
+{
+    JavaEditorWidget *editor = new JavaEditorWidget;
+    TextEditor::TextEditorSettings::initializeEditor(editor);
+    return editor->editor();
+}
diff --git a/src/plugins/android/javaeditorfactory.h b/src/plugins/android/javaeditorfactory.h
new file mode 100644
index 00000000000..69f96a1dae1
--- /dev/null
+++ b/src/plugins/android/javaeditorfactory.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef JAVAEDITORFACTORY_H
+#define JAVAEDITORFACTORY_H
+#include <coreplugin/editormanager/ieditorfactory.h>
+
+namespace Android {
+namespace Internal {
+
+class JavaEditorFactory : public Core::IEditorFactory
+{
+    Q_OBJECT
+
+public:
+    JavaEditorFactory();
+    Core::IEditor *createEditor();
+};
+}
+}
+
+#endif // JAVAEDITORFACTORY_H
diff --git a/src/plugins/android/javaindenter.cpp b/src/plugins/android/javaindenter.cpp
new file mode 100644
index 00000000000..51cfd1c9300
--- /dev/null
+++ b/src/plugins/android/javaindenter.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "javaindenter.h"
+#include <texteditor/tabsettings.h>
+
+#include <QTextDocument>
+
+using namespace Android;
+using namespace Android::Internal;
+
+JavaIndenter::JavaIndenter()
+{
+}
+
+JavaIndenter::~JavaIndenter()
+{}
+
+bool JavaIndenter::isElectricCharacter(const QChar &ch) const
+{
+    if (ch == QLatin1Char('{')
+            || ch == QLatin1Char('}')) {
+        return true;
+    }
+    return false;
+}
+
+void JavaIndenter::indentBlock(QTextDocument *doc,
+                                 const QTextBlock &block,
+                                 const QChar &typedChar,
+                                 const TextEditor::TabSettings &tabSettings)
+{
+    // At beginning: Leave as is.
+    if (block == doc->begin())
+        return;
+
+    const int tabsize = tabSettings.m_indentSize;
+
+    QTextBlock previous = block.previous();
+    QString previousText = previous.text();
+    while (previousText.trimmed().isEmpty()) {
+        previous = previous.previous();
+        if (previous == doc->begin())
+            return;
+        previousText = previous.text();
+    }
+
+    int adjust = 0;
+    if (previousText.contains(QLatin1Char('{')))
+        adjust = tabsize;
+
+    if (block.text().contains(QLatin1Char('}')) || typedChar == QLatin1Char('}'))
+        adjust += -tabsize;
+
+    // Count the indentation of the previous line.
+    int i = 0;
+    while (i < previousText.size()) {
+        if (!previousText.at(i).isSpace()) {
+            tabSettings.indentLine(block, tabSettings.columnAt(previousText, i)
+                                   + adjust);
+            break;
+        }
+        ++i;
+    }
+}
diff --git a/src/plugins/android/javaindenter.h b/src/plugins/android/javaindenter.h
new file mode 100644
index 00000000000..50bf742ece0
--- /dev/null
+++ b/src/plugins/android/javaindenter.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef JAVAINDENTER_H
+#define JAVAINDENTER_H
+
+#include <texteditor/indenter.h>
+
+namespace Android {
+namespace Internal {
+class JavaIndenter : public TextEditor::Indenter
+{
+public:
+    JavaIndenter();
+    virtual ~JavaIndenter();
+
+    bool isElectricCharacter(const QChar &ch) const;
+
+    virtual void indentBlock(QTextDocument *doc,
+                             const QTextBlock &block,
+                             const QChar &typedChar,
+                             const TextEditor::TabSettings &tabSettings);
+};
+}
+}
+
+#endif // JAVAINDENTER_H
-- 
GitLab