cppeditorplugin.cpp 15.3 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
con's avatar
con committed
2
**
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
con's avatar
con committed
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
con's avatar
con committed
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** 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.
15
**
16
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** 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
con's avatar
con committed
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
hjk's avatar
hjk committed
29

30
#include "cppeditorplugin.h"
31

32
#include "cppclasswizard.h"
con's avatar
con committed
33 34 35
#include "cppeditor.h"
#include "cppeditorconstants.h"
#include "cppfilewizard.h"
36
#include "cpphoverhandler.h"
37
#include "cppoutline.h"
38
#include "cpptypehierarchy.h"
39
#include "cppsnippetprovider.h"
Leandro Melo's avatar
Leandro Melo committed
40
#include "cppquickfixassistant.h"
Nikolai Kosjar's avatar
Nikolai Kosjar committed
41
#include "cppquickfixes.h"
con's avatar
con committed
42

43
#include <coreplugin/actionmanager/actioncontainer.h>
44 45 46 47
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/fileiconprovider.h>
#include <coreplugin/icore.h>
48
#include <coreplugin/navigationwidget.h>
49 50
#include <coreplugin/progressmanager/progressmanager.h>
#include <cpptools/cpptoolsconstants.h>
51
#include <texteditor/texteditoractionhandler.h>
con's avatar
con committed
52
#include <texteditor/texteditorsettings.h>
53

54
#include <utils/hostosinfo.h>
con's avatar
con committed
55

56 57
#include <QCoreApplication>
#include <QStringList>
con's avatar
con committed
58

59
using namespace CppEditor;
con's avatar
con committed
60 61
using namespace CppEditor::Internal;

Leandro Melo's avatar
Leandro Melo committed
62 63
void registerQuickFixes(ExtensionSystem::IPlugin *plugIn);

64 65
enum { QUICKFIX_INTERVAL = 20 };

66
//////////////////////////// CppEditorFactory /////////////////////////////
con's avatar
con committed
67

68
CppEditorFactory::CppEditorFactory(CppEditorPlugin *owner) :
con's avatar
con committed
69 70
    m_owner(owner)
{
71 72 73 74 75 76
    setId(CppEditor::Constants::CPPEDITOR_ID);
    setDisplayName(qApp->translate("OpenWith::Editors", CppEditor::Constants::CPPEDITOR_DISPLAY_NAME));
    addMimeType(CppEditor::Constants::C_SOURCE_MIMETYPE);
    addMimeType(CppEditor::Constants::C_HEADER_MIMETYPE);
    addMimeType(CppEditor::Constants::CPP_SOURCE_MIMETYPE);
    addMimeType(CppEditor::Constants::CPP_HEADER_MIMETYPE);
77

78 79 80 81 82 83 84 85 86 87
    if (!Utils::HostOsInfo::isMacHost() && !Utils::HostOsInfo::isWindowsHost()) {
        Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance();
        Core::MimeDatabase *mimeDatabase = Core::ICore::mimeDatabase();
        iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_cpp.png")),
                                                     mimeDatabase->findByType(QLatin1String(CppEditor::Constants::CPP_SOURCE_MIMETYPE)));
        iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_c.png")),
                                                     mimeDatabase->findByType(QLatin1String(CppEditor::Constants::C_SOURCE_MIMETYPE)));
        iconProvider->registerIconOverlayForMimeType(QIcon(QLatin1String(":/cppeditor/images/qt_h.png")),
                                                     mimeDatabase->findByType(QLatin1String(CppEditor::Constants::CPP_HEADER_MIMETYPE)));
    }
con's avatar
con committed
88 89
}

90
Core::IEditor *CppEditorFactory::createEditor(QWidget *parent)
con's avatar
con committed
91
{
92
    CPPEditorWidget *editor = new CPPEditorWidget(parent);
con's avatar
con committed
93 94
    editor->setRevisionsVisible(true);
    m_owner->initializeEditor(editor);
95
    return editor->editor();
con's avatar
con committed
96 97
}

98
///////////////////////////////// CppEditorPlugin //////////////////////////////////
con's avatar
con committed
99

100
CppEditorPlugin *CppEditorPlugin::m_instance = 0;
con's avatar
con committed
101

102
CppEditorPlugin::CppEditorPlugin() :
con's avatar
con committed
103
    m_actionHandler(0),
104
    m_sortedOutline(false),
105 106
    m_renameSymbolUnderCursorAction(0),
    m_findUsagesAction(0),
107
    m_updateCodeModelAction(0),
Leandro Melo's avatar
Leandro Melo committed
108 109
    m_openTypeHierarchyAction(0),
    m_quickFixProvider(0)
con's avatar
con committed
110 111 112 113
{
    m_instance = this;
}

114
CppEditorPlugin::~CppEditorPlugin()
con's avatar
con committed
115 116 117 118 119
{
    delete m_actionHandler;
    m_instance = 0;
}

120
CppEditorPlugin *CppEditorPlugin::instance()
con's avatar
con committed
121 122 123 124
{
    return m_instance;
}

125
void CppEditorPlugin::initializeEditor(CPPEditorWidget *editor)
con's avatar
con committed
126 127 128
{
    m_actionHandler->setupActions(editor);

Orgad Shaneh's avatar
Orgad Shaneh committed
129
    editor->setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID);
130
    TextEditor::TextEditorSettings::instance()->initializeEditor(editor);
con's avatar
con committed
131

132
    // method combo box sorting
133 134
    connect(this, SIGNAL(outlineSortingChanged(bool)),
            editor, SLOT(setSortedOutline(bool)));
135 136
}

137
void CppEditorPlugin::setSortedOutline(bool sorted)
138
{
139 140
    m_sortedOutline = sorted;
    emit outlineSortingChanged(sorted);
141 142
}

143
bool CppEditorPlugin::sortedOutline() const
144
{
145
    return m_sortedOutline;
con's avatar
con committed
146 147
}

148
CppQuickFixAssistProvider *CppEditorPlugin::quickFixProvider() const
Leandro Melo's avatar
Leandro Melo committed
149 150 151
{
    return m_quickFixProvider;
}
152

153
bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage)
con's avatar
con committed
154
{
hjk's avatar
hjk committed
155
    if (!Core::ICore::mimeDatabase()->addMimeTypes(QLatin1String(":/cppeditor/CppEditor.mimetypes.xml"), errorMessage))
con's avatar
con committed
156 157
        return false;

158
    addAutoReleasedObject(new CppEditorFactory(this));
159
    addAutoReleasedObject(new CppHoverHandler);
160
    addAutoReleasedObject(new CppOutlineWidgetFactory);
161
    addAutoReleasedObject(new CppTypeHierarchyFactory);
162
    addAutoReleasedObject(new CppSnippetProvider);
163

Leandro Melo's avatar
Leandro Melo committed
164 165
    m_quickFixProvider = new CppQuickFixAssistProvider;
    addAutoReleasedObject(m_quickFixProvider);
Nikolai Kosjar's avatar
Nikolai Kosjar committed
166
    CppEditor::Internal::registerQuickFixes(this);
Roberto Raggi's avatar
Roberto Raggi committed
167

hjk's avatar
hjk committed
168
    QObject *core = Core::ICore::instance();
con's avatar
con committed
169 170
    CppFileWizard::BaseFileWizardParameters wizardParameters(Core::IWizard::FileWizard);

171
    wizardParameters.setCategory(QLatin1String(Constants::WIZARD_CATEGORY));
172 173
    wizardParameters.setDisplayCategory(QCoreApplication::translate(Constants::WIZARD_CATEGORY,
                                                                    Constants::WIZARD_TR_CATEGORY));
174
    wizardParameters.setDisplayName(tr("C++ Class"));
Friedemann Kleint's avatar
Friedemann Kleint committed
175 176
    wizardParameters.setId(QLatin1String("A.Class"));
    wizardParameters.setKind(Core::IWizard::ClassWizard);
177
    wizardParameters.setDescription(tr("Creates a C++ header and a source file for a new class that you can add to a C++ project."));
Friedemann Kleint's avatar
Friedemann Kleint committed
178
    addAutoReleasedObject(new CppClassWizard(wizardParameters, core));
con's avatar
con committed
179

Friedemann Kleint's avatar
Friedemann Kleint committed
180
    wizardParameters.setKind(Core::IWizard::FileWizard);
181
    wizardParameters.setDescription(tr("Creates a C++ source file that you can add to a C++ project."));
182
    wizardParameters.setDisplayName(tr("C++ Source File"));
Friedemann Kleint's avatar
Friedemann Kleint committed
183
    wizardParameters.setId(QLatin1String("B.Source"));
184
    addAutoReleasedObject(new CppFileWizard(wizardParameters, Source, core));
con's avatar
con committed
185

186
    wizardParameters.setDescription(tr("Creates a C++ header file that you can add to a C++ project."));
187
    wizardParameters.setDisplayName(tr("C++ Header File"));
Friedemann Kleint's avatar
Friedemann Kleint committed
188 189
    wizardParameters.setId(QLatin1String("C.Header"));
    addAutoReleasedObject(new CppFileWizard(wizardParameters, Header, core));
con's avatar
con committed
190

191
    Core::Context context(CppEditor::Constants::C_CPPEDITOR);
con's avatar
con committed
192

Eike Ziller's avatar
Eike Ziller committed
193
    Core::ActionContainer *contextMenu= Core::ActionManager::createMenu(CppEditor::Constants::M_CONTEXT);
con's avatar
con committed
194

con's avatar
con committed
195
    Core::Command *cmd;
Eike Ziller's avatar
Eike Ziller committed
196
    Core::ActionContainer *cppToolsMenu = Core::ActionManager::actionContainer(Core::Id(CppTools::Constants::M_TOOLS_CPP));
con's avatar
con committed
197

Eike Ziller's avatar
Eike Ziller committed
198
    cmd = Core::ActionManager::command(Core::Id(CppTools::Constants::SWITCH_HEADER_SOURCE));
199 200
    contextMenu->addAction(cmd);

Eike Ziller's avatar
Eike Ziller committed
201
    cmd = Core::ActionManager::command(TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR);
mae's avatar
mae committed
202
    contextMenu->addAction(cmd);
203
    cppToolsMenu->addAction(cmd);
con's avatar
con committed
204

205
    QAction *switchDeclarationDefinition = new QAction(tr("Switch Between Method Declaration/Definition"), this);
Eike Ziller's avatar
Eike Ziller committed
206
    cmd = Core::ActionManager::registerAction(switchDeclarationDefinition,
207
        Constants::SWITCH_DECLARATION_DEFINITION, context, true);
208
    cmd->setDefaultKeySequence(QKeySequence(tr("Shift+F2")));
con's avatar
con committed
209 210
    connect(switchDeclarationDefinition, SIGNAL(triggered()),
            this, SLOT(switchDeclarationDefinition()));
mae's avatar
mae committed
211
    contextMenu->addAction(cmd);
212
    cppToolsMenu->addAction(cmd);
con's avatar
con committed
213

214 215 216 217
    cmd = Core::ActionManager::command(TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR_IN_NEXT_SPLIT);
    cppToolsMenu->addAction(cmd);

    QAction *openDeclarationDefinitionInNextSplit =
218
            new QAction(tr("Open Method Declaration/Definition in Next Split"), this);
219 220
    cmd = Core::ActionManager::registerAction(openDeclarationDefinitionInNextSplit,
        Constants::OPEN_DECLARATION_DEFINITION_IN_NEXT_SPLIT, context, true);
221 222 223
    cmd->setDefaultKeySequence(QKeySequence(Utils::HostOsInfo::isMacHost()
                                            ? tr("Meta+E, Shift+F2")
                                            : tr("Ctrl+E, Shift+F2")));
224 225 226 227
    connect(openDeclarationDefinitionInNextSplit, SIGNAL(triggered()),
            this, SLOT(openDeclarationDefinitionInNextSplit()));
    cppToolsMenu->addAction(cmd);

228
    m_findUsagesAction = new QAction(tr("Find Usages"), this);
Eike Ziller's avatar
Eike Ziller committed
229
    cmd = Core::ActionManager::registerAction(m_findUsagesAction, Constants::FIND_USAGES, context);
230
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+U")));
231
    connect(m_findUsagesAction, SIGNAL(triggered()), this, SLOT(findUsages()));
232
    contextMenu->addAction(cmd);
233
    cppToolsMenu->addAction(cmd);
234

235
    m_openTypeHierarchyAction = new QAction(tr("Open Type Hierarchy"), this);
Eike Ziller's avatar
Eike Ziller committed
236
    cmd = Core::ActionManager::registerAction(m_openTypeHierarchyAction, Constants::OPEN_TYPE_HIERARCHY, context);
Eike Ziller's avatar
Eike Ziller committed
237
    cmd->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Shift+T") : tr("Ctrl+Shift+T")));
238 239 240 241
    connect(m_openTypeHierarchyAction, SIGNAL(triggered()), this, SLOT(openTypeHierarchy()));
    contextMenu->addAction(cmd);
    cppToolsMenu->addAction(cmd);

242
    // Refactoring sub-menu
243
    Core::Context globalContext(Core::Constants::C_GLOBAL);
244
    Core::Command *sep = contextMenu->addSeparator(globalContext);
245
    sep->action()->setObjectName(QLatin1String(Constants::M_REFACTORING_MENU_INSERTION_POINT));
246
    contextMenu->addSeparator(globalContext);
247 248 249

    m_renameSymbolUnderCursorAction = new QAction(tr("Rename Symbol Under Cursor"),
                                                  this);
Eike Ziller's avatar
Eike Ziller committed
250
    cmd = Core::ActionManager::registerAction(m_renameSymbolUnderCursorAction,
251 252
                             Constants::RENAME_SYMBOL_UNDER_CURSOR,
                             context);
253
    cmd->setDefaultKeySequence(QKeySequence(tr("CTRL+SHIFT+R")));
254 255 256 257 258
    connect(m_renameSymbolUnderCursorAction, SIGNAL(triggered()),
            this, SLOT(renameSymbolUnderCursor()));
    cppToolsMenu->addAction(cmd);

    // Update context in global context
259
    cppToolsMenu->addSeparator(globalContext);
260
    m_updateCodeModelAction = new QAction(tr("Update Code Model"), this);
Eike Ziller's avatar
Eike Ziller committed
261
    cmd = Core::ActionManager::registerAction(m_updateCodeModelAction, Core::Id(Constants::UPDATE_CODEMODEL), globalContext);
262
    CppTools::CppModelManagerInterface *cppModelManager = CppTools::CppModelManagerInterface::instance();
263 264
    connect(m_updateCodeModelAction, SIGNAL(triggered()), cppModelManager, SLOT(updateModifiedSourceFiles()));
    cppToolsMenu->addAction(cmd);
265

266
    m_actionHandler = new TextEditor::TextEditorActionHandler(CppEditor::Constants::C_CPPEDITOR,
con's avatar
con committed
267 268
        TextEditor::TextEditorActionHandler::Format
        | TextEditor::TextEditorActionHandler::UnCommentSelection
269 270
        | TextEditor::TextEditorActionHandler::UnCollapseAll
        | TextEditor::TextEditorActionHandler::FollowSymbolUnderCursor);
con's avatar
con committed
271

272
    m_actionHandler->initializeActions();
273

274
    contextMenu->addSeparator(context);
275

Eike Ziller's avatar
Eike Ziller committed
276
    cmd = Core::ActionManager::command(TextEditor::Constants::AUTO_INDENT_SELECTION);
mae's avatar
mae committed
277
    contextMenu->addAction(cmd);
278

Eike Ziller's avatar
Eike Ziller committed
279
    cmd = Core::ActionManager::command(TextEditor::Constants::UN_COMMENT_SELECTION);
mae's avatar
mae committed
280
    contextMenu->addAction(cmd);
281

hjk's avatar
hjk committed
282
    connect(Core::ICore::progressManager(), SIGNAL(taskStarted(QString)),
283
            this, SLOT(onTaskStarted(QString)));
hjk's avatar
hjk committed
284
    connect(Core::ICore::progressManager(), SIGNAL(allTasksFinished(QString)),
285
            this, SLOT(onAllTasksFinished(QString)));
286

hjk's avatar
hjk committed
287
    connect(Core::ICore::editorManager(), SIGNAL(currentEditorChanged(Core::IEditor*)), SLOT(currentEditorChanged(Core::IEditor*)));
288

289
    readSettings();
con's avatar
con committed
290 291 292
    return true;
}

293
void CppEditorPlugin::readSettings()
294
{
hjk's avatar
hjk committed
295
    m_sortedOutline = Core::ICore::settings()->value(QLatin1String("CppTools/SortedMethodOverview"), false).toBool();
296 297
}

298
void CppEditorPlugin::writeSettings()
299
{
hjk's avatar
hjk committed
300
    Core::ICore::settings()->setValue(QLatin1String("CppTools/SortedMethodOverview"), m_sortedOutline);
301 302
}

303
void CppEditorPlugin::extensionsInitialized()
con's avatar
con committed
304 305 306
{
}

307
ExtensionSystem::IPlugin::ShutdownFlag CppEditorPlugin::aboutToShutdown()
308 309
{
    writeSettings();
310
    return SynchronousShutdown;
311 312
}

313
void CppEditorPlugin::switchDeclarationDefinition()
con's avatar
con committed
314
{
315
    CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(Core::EditorManager::currentEditor()->widget());
316
    if (editor)
317 318 319
        editor->switchDeclarationDefinition(/*inNextSplit*/ false);
}

320
void CppEditorPlugin::openDeclarationDefinitionInNextSplit()
321 322 323 324
{
    CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(Core::EditorManager::currentEditor()->widget());
    if (editor)
        editor->switchDeclarationDefinition(/*inNextSplit*/ true);
con's avatar
con committed
325 326
}

327
void CppEditorPlugin::renameSymbolUnderCursor()
328
{
329
    CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(Core::EditorManager::currentEditor()->widget());
330 331 332 333
    if (editor)
        editor->renameSymbolUnderCursor();
}

334
void CppEditorPlugin::findUsages()
335
{
336
    CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(Core::EditorManager::currentEditor()->widget());
337 338 339 340
    if (editor)
        editor->findUsages();
}

341
void CppEditorPlugin::onTaskStarted(const QString &type)
342
{
343
    if (type == QLatin1String(CppTools::Constants::TASK_INDEX)) {
344 345
        m_renameSymbolUnderCursorAction->setEnabled(false);
        m_findUsagesAction->setEnabled(false);
346
        m_updateCodeModelAction->setEnabled(false);
347
        m_openTypeHierarchyAction->setEnabled(false);
348
    }
349 350
}

351
void CppEditorPlugin::onAllTasksFinished(const QString &type)
352
{
353
    if (type == QLatin1String(CppTools::Constants::TASK_INDEX)) {
354 355
        m_renameSymbolUnderCursorAction->setEnabled(true);
        m_findUsagesAction->setEnabled(true);
356
        m_updateCodeModelAction->setEnabled(true);
357
        m_openTypeHierarchyAction->setEnabled(true);
358
    }
359 360
}

361
void CppEditorPlugin::currentEditorChanged(Core::IEditor *editor)
362
{
363
    if (!editor)
364 365
        return;

366
    if (CPPEditorWidget *textEditor = qobject_cast<CPPEditorWidget *>(editor->widget()))
367
        textEditor->semanticRehighlight(/*force = */ true);
368 369
}

370
void CppEditorPlugin::openTypeHierarchy()
371
{
372
    CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(Core::EditorManager::currentEditor()->widget());
373 374
    if (editor) {
        Core::NavigationWidget *navigation = Core::NavigationWidget::instance();
375
        navigation->activateSubWidget(Core::Id(Constants::TYPE_HIERARCHY_ID));
376 377 378 379
        emit typeHierarchyRequested();
    }
}

380
Q_EXPORT_PLUGIN(CppEditorPlugin)