fakevimplugin.cpp 10.3 KB
Newer Older
hjk's avatar
hjk committed
1 2 3 4
/***************************************************************************
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
hjk's avatar
hjk committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/

#include "fakevimplugin.h"

36 37
#include "fakevimconstants.h"
#include "fakevimhandler.h"
hjk's avatar
hjk committed
38

39
#include <coreplugin/actionmanager/actionmanager.h>
hjk's avatar
hjk committed
40 41
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
42
#include <coreplugin/filemanager.h>
hjk's avatar
hjk committed
43
#include <coreplugin/icore.h>
44
#include <coreplugin/ifile.h>
hjk's avatar
hjk committed
45 46 47 48 49 50 51 52 53 54 55
#include <coreplugin/messagemanager.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/session.h>

#include <texteditor/basetexteditor.h>
#include <texteditor/basetextmark.h>
#include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h>
56
#include <texteditor/interactionsettings.h>
57 58
#include <texteditor/tabsettings.h>
#include <texteditor/texteditorsettings.h>
hjk's avatar
hjk committed
59 60 61 62

#include <utils/qtcassert.h>

#include <QtCore/QDebug>
63
#include <QtCore/QtPlugin>
hjk's avatar
hjk committed
64 65 66 67
#include <QtCore/QObject>
#include <QtCore/QPoint>
#include <QtCore/QSettings>

68
#include <QtGui/QMessageBox>
hjk's avatar
hjk committed
69 70 71
#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextBlock>
#include <QtGui/QTextCursor>
72
#include <QtGui/QTextEdit>
hjk's avatar
hjk committed
73 74 75 76 77 78 79 80 81 82 83 84


using namespace FakeVim::Internal;
using namespace TextEditor;
using namespace Core;
using namespace ProjectExplorer;


namespace FakeVim {
namespace Constants {

const char * const INSTALL_HANDLER        = "FakeVim.InstallHandler";
85
const char * const MINI_BUFFER            = "FakeVim.MiniBuffer";
hjk's avatar
hjk committed
86 87 88 89 90 91 92 93
const char * const INSTALL_KEY            = "Alt+V,Alt+V";

} // namespace Constants
} // namespace FakeVim


///////////////////////////////////////////////////////////////////////
//
94
// FakeVimPluginPrivate
hjk's avatar
hjk committed
95 96 97
//
///////////////////////////////////////////////////////////////////////

98 99 100 101
namespace FakeVim {
namespace Internal {

class FakeVimPluginPrivate : public QObject
hjk's avatar
hjk committed
102
{
103 104 105 106 107 108 109
    Q_OBJECT

public:
    FakeVimPluginPrivate(FakeVimPlugin *);
    ~FakeVimPluginPrivate();
    friend class FakeVimPlugin;

110
    bool initialize();
111 112 113 114 115
    void shutdown();

private slots:
    void editorOpened(Core::IEditor *);
    void editorAboutToClose(Core::IEditor *);
116 117 118 119 120 121 122 123 124

    void installHandler();
    void installHandler(Core::IEditor *editor);
    void removeHandler();

    void showCommandBuffer(const QString &contents);
    void showExtraInformation(const QString &msg);
    void changeSelection(const QList<QTextEdit::ExtraSelection> &selections);
    void writeFile(bool *handled, const QString &fileName, const QString &contents);
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

private:
    FakeVimPlugin *q;
    QAction *m_installHandlerAction; 
    Core::ICore *m_core;
};

} // namespace Internal
} // namespace FakeVim

FakeVimPluginPrivate::FakeVimPluginPrivate(FakeVimPlugin *plugin)
{       
    q = plugin;
    m_installHandlerAction = 0;
    m_core = 0;
hjk's avatar
hjk committed
140 141
}

142 143 144
FakeVimPluginPrivate::~FakeVimPluginPrivate()
{
}
hjk's avatar
hjk committed
145

146
void FakeVimPluginPrivate::shutdown()
hjk's avatar
hjk committed
147 148 149
{
}

150
bool FakeVimPluginPrivate::initialize()
hjk's avatar
hjk committed
151
{
152
    m_core = Core::ICore::instance();
153
    QTC_ASSERT(m_core, return false);
hjk's avatar
hjk committed
154

155
    Core::ActionManager *actionManager = m_core->actionManager();
hjk's avatar
hjk committed
156 157 158 159 160 161 162 163
    QTC_ASSERT(actionManager, return false);

    QList<int> globalcontext;
    globalcontext << Core::Constants::C_GLOBAL_ID;

    m_installHandlerAction = new QAction(this);
    m_installHandlerAction->setText(tr("Set vi-Style Keyboard Action Handler"));
    
con's avatar
con committed
164
    Core::Command *cmd = 0;
hjk's avatar
hjk committed
165 166 167 168
    cmd = actionManager->registerAction(m_installHandlerAction,
        Constants::INSTALL_HANDLER, globalcontext);
    cmd->setDefaultKeySequence(QKeySequence(Constants::INSTALL_KEY));

169
    ActionContainer *advancedMenu =
hjk's avatar
hjk committed
170
        actionManager->actionContainer(Core::Constants::M_EDIT_ADVANCED);
171
    advancedMenu->addAction(cmd, Core::Constants::G_EDIT_EDITOR);
hjk's avatar
hjk committed
172 173 174

    connect(m_installHandlerAction, SIGNAL(triggered()),
        this, SLOT(installHandler()));
175 176 177 178 179 180 181 182

    // EditorManager
    QObject *editorManager = m_core->editorManager();
    connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
        this, SLOT(editorAboutToClose(Core::IEditor*)));
    connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
        this, SLOT(editorOpened(Core::IEditor*)));

hjk's avatar
hjk committed
183 184 185
    return true;
}

186
void FakeVimPluginPrivate::installHandler(Core::IEditor *editor)
187
{
188 189 190 191 192 193 194
    QWidget *widget = editor->widget();
    
    FakeVimHandler *handler = new FakeVimHandler(widget, this);

    connect(handler, SIGNAL(extraInformationChanged(QString)),
        this, SLOT(showExtraInformation(QString)));
    connect(handler, SIGNAL(commandBufferChanged(QString)),
hjk's avatar
hjk committed
195
        this, SLOT(showCommandBuffer(QString)));
196 197 198 199 200 201 202 203 204
    connect(handler, SIGNAL(quitRequested()),
        this, SLOT(removeHandler()), Qt::QueuedConnection);
    connect(handler, SIGNAL(writeFileRequested(bool*,QString,QString)),
        this, SLOT(writeFile(bool*,QString,QString)));
    connect(handler, SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)),
        this, SLOT(changeSelection(QList<QTextEdit::ExtraSelection>)));

    handler->setupWidget();
    handler->setExtraData(editor);
205

206
    if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(widget)) {
207 208
        using namespace TextEditor;
        using namespace FakeVim::Constants;
209
        handler->setCurrentFileName(editor->file()->fileName());
210
        TabSettings settings = bt->tabSettings();
211
        handler->setConfigValue(ConfigTabStop,
212
            QString::number(settings.m_tabSize));
213
        handler->setConfigValue(ConfigShiftWidth,
214
            QString::number(settings.m_indentSize));
215
        handler->setConfigValue(ConfigExpandTab,
216
            settings.m_spacesForTabs ? ConfigOn : ConfigOff);
217
        handler->setConfigValue(ConfigSmartTab,
218
            settings.m_smartBackspace ? ConfigOn : ConfigOff); 
219
        handler->setConfigValue(ConfigAutoIndent,
220
            settings.m_autoIndent ? ConfigOn : ConfigOff); 
221
    }
hjk's avatar
hjk committed
222 223
}

224 225
void FakeVimPluginPrivate::writeFile(bool *handled,
    const QString &fileName, const QString &contents)
226
{
227 228
    Q_UNUSED(contents);

229 230 231 232 233 234
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (!handler)
        return;

    Core::IEditor *editor = qobject_cast<Core::IEditor *>(handler->extraData());
    if (editor && editor->file()->fileName() == fileName) {
hjk's avatar
hjk committed
235
        // Handle that as a special case for nicer interaction with core
236 237 238 239 240 241
        Core::IFile *file = editor->file();
        m_core->fileManager()->blockFileChange(file);
        file->save(fileName);
        m_core->fileManager()->unblockFileChange(file);
        *handled = true;
    } 
242 243
}

244
void FakeVimPluginPrivate::removeHandler()
hjk's avatar
hjk committed
245
{
246 247 248 249
    if (FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender())) {
        handler->restoreWidget();
        handler->deleteLater();
    }
hjk's avatar
hjk committed
250 251
    Core::EditorManager::instance()->hideEditorInfoBar(
        QLatin1String(Constants::MINI_BUFFER));
hjk's avatar
hjk committed
252 253
}

254
void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
255
{
256
    Q_UNUSED(editor);
257
    //qDebug() << "OPENING: " << editor << editor->widget();
258
    //installHandler(editor);
259 260 261 262 263 264 265 266 267 268

#if 1
    QSettings *s = ICore::instance()->settings();
    bool automatic = s->value("textInteractionSettings/UseVim").toBool();
    //qDebug() << "USE VIM: " << automatic;
    if (automatic)
       installHandler(editor);
#endif

#if 0
269 270 271 272 273 274 275
    QWidget *widget = editor->widget();
    if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(widget)) {
        InteractionSettings settings = bt->interactionSettings();
        qDebug() << "USE VIM: " << settings.m_useVim;
        if (settings.m_useVim)
            installHandler(editor);
    }
276
#endif
277 278
}

279
void FakeVimPluginPrivate::editorAboutToClose(Core::IEditor *editor)
280
{
281 282
    Q_UNUSED(editor);
    //qDebug() << "CLOSING: " << editor;
283 284
}

285
void FakeVimPluginPrivate::showCommandBuffer(const QString &contents)
hjk's avatar
hjk committed
286
{
287 288 289 290 291 292 293
    //qDebug() << "SHOW COMMAND BUFFER" << contents;
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (handler) {
        Core::EditorManager::instance()->showEditorInfoBar( 
            QLatin1String(Constants::MINI_BUFFER), contents,
            tr("Quit FakeVim"), handler, SLOT(quit()));
    }
hjk's avatar
hjk committed
294 295
}

296
void FakeVimPluginPrivate::showExtraInformation(const QString &text)
297
{
298 299 300
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (handler)
        QMessageBox::information(handler->widget(), tr("FakeVim Information"), text);
301 302
}

303 304
void FakeVimPluginPrivate::changeSelection
    (const QList<QTextEdit::ExtraSelection> &selection)
305
{
306 307 308
    if (FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender()))
        if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(handler->widget()))
            bt->setExtraSelections(BaseTextEditor::FakeVimSelection, selection);
309 310
}

311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326

///////////////////////////////////////////////////////////////////////
//
// FakeVimPlugin
//
///////////////////////////////////////////////////////////////////////

FakeVimPlugin::FakeVimPlugin()
    : d(new FakeVimPluginPrivate(this))
{}

FakeVimPlugin::~FakeVimPlugin()
{
    delete d;
}

327
bool FakeVimPlugin::initialize(const QStringList &arguments, QString *errorMessage)
328
{
329 330 331
    Q_UNUSED(arguments);
    Q_UNUSED(errorMessage);
    return d->initialize();
332 333 334 335 336 337 338 339 340 341 342 343
}

void FakeVimPlugin::shutdown()
{
    d->shutdown();
}

void FakeVimPlugin::extensionsInitialized()
{
}

#include "fakevimplugin.moc"
hjk's avatar
hjk committed
344 345

Q_EXPORT_PLUGIN(FakeVimPlugin)