cppeditorplugin.cpp 14.6 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"
42
#include "cpphighlighterfactory.h"
con's avatar
con committed
43

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

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

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

60
using namespace Core;
61
using namespace CppEditor;
con's avatar
con committed
62 63
using namespace CppEditor::Internal;

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

66 67
enum { QUICKFIX_INTERVAL = 20 };

68
//////////////////////////// CppEditorFactory /////////////////////////////
con's avatar
con committed
69

70
CppEditorFactory::CppEditorFactory(CppEditorPlugin *owner) :
con's avatar
con committed
71 72
    m_owner(owner)
{
73 74 75 76 77 78
    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);
79

80
    if (!Utils::HostOsInfo::isMacHost() && !Utils::HostOsInfo::isWindowsHost()) {
81 82 83
        FileIconProvider::registerIconOverlayForMimeType(":/cppeditor/images/qt_cpp.png", CppEditor::Constants::CPP_SOURCE_MIMETYPE);
        FileIconProvider::registerIconOverlayForMimeType(":/cppeditor/images/qt_c.png", CppEditor::Constants::C_SOURCE_MIMETYPE);
        FileIconProvider::registerIconOverlayForMimeType(":/cppeditor/images/qt_h.png", CppEditor::Constants::CPP_HEADER_MIMETYPE);
84
    }
con's avatar
con committed
85 86
}

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

95
///////////////////////////////// CppEditorPlugin //////////////////////////////////
con's avatar
con committed
96

97
CppEditorPlugin *CppEditorPlugin::m_instance = 0;
con's avatar
con committed
98

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

111
CppEditorPlugin::~CppEditorPlugin()
con's avatar
con committed
112 113 114 115 116
{
    delete m_actionHandler;
    m_instance = 0;
}

117
CppEditorPlugin *CppEditorPlugin::instance()
con's avatar
con committed
118 119 120 121
{
    return m_instance;
}

122
void CppEditorPlugin::initializeEditor(CPPEditorWidget *editor)
con's avatar
con committed
123 124 125
{
    m_actionHandler->setupActions(editor);

Orgad Shaneh's avatar
Orgad Shaneh committed
126
    editor->setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID);
127
    TextEditor::TextEditorSettings::initializeEditor(editor);
con's avatar
con committed
128

129
    // method combo box sorting
Kai Koehne's avatar
Kai Koehne committed
130 131
    connect(this, SIGNAL(outlineSortingChanged(bool)),
            editor, SLOT(setSortedOutline(bool)));
132 133
}

134
void CppEditorPlugin::setSortedOutline(bool sorted)
135
{
Kai Koehne's avatar
Kai Koehne committed
136 137
    m_sortedOutline = sorted;
    emit outlineSortingChanged(sorted);
138 139
}

140
bool CppEditorPlugin::sortedOutline() const
141
{
Kai Koehne's avatar
Kai Koehne committed
142
    return m_sortedOutline;
con's avatar
con committed
143 144
}

145
CppQuickFixAssistProvider *CppEditorPlugin::quickFixProvider() const
Leandro Melo's avatar
Leandro Melo committed
146 147 148
{
    return m_quickFixProvider;
}
149

150
bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage)
con's avatar
con committed
151
{
hjk's avatar
hjk committed
152
    if (!Core::MimeDatabase::addMimeTypes(QLatin1String(":/cppeditor/CppEditor.mimetypes.xml"), errorMessage))
con's avatar
con committed
153 154
        return false;

155
    addAutoReleasedObject(new CppEditorFactory(this));
156
    addAutoReleasedObject(new CppHoverHandler);
157
    addAutoReleasedObject(new CppOutlineWidgetFactory);
158
    addAutoReleasedObject(new CppTypeHierarchyFactory);
159
    addAutoReleasedObject(new CppSnippetProvider);
160
    addAutoReleasedObject(new CppHighlighterFactory);
161

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

hjk's avatar
hjk committed
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
    QString trCat = QCoreApplication::translate(Constants::WIZARD_CATEGORY, Constants::WIZARD_TR_CATEGORY);

    IWizard *wizard = new CppClassWizard;
    wizard->setWizardKind(IWizard::ClassWizard);
    wizard->setCategory(QLatin1String(Constants::WIZARD_CATEGORY));
    wizard->setDisplayCategory(trCat);
    wizard->setDisplayName(tr("C++ Class"));
    wizard->setId(QLatin1String("A.Class"));
    wizard->setDescription(tr("Creates a C++ header and a source file for a new class that you can add to a C++ project."));
    addAutoReleasedObject(wizard);

    wizard = new CppFileWizard(Source);
    wizard->setWizardKind(IWizard::FileWizard);
    wizard->setCategory(QLatin1String(Constants::WIZARD_CATEGORY));
    wizard->setDisplayCategory(trCat);
    wizard->setDisplayName(tr("C++ Class"));
    wizard->setDescription(tr("Creates a C++ source file that you can add to a C++ project."));
    wizard->setDisplayName(tr("C++ Source File"));
    wizard->setId(QLatin1String("B.Source"));
    addAutoReleasedObject(wizard);

    wizard = new CppFileWizard(Header);
    wizard->setWizardKind(IWizard::FileWizard);
    wizard->setCategory(QLatin1String(Constants::WIZARD_CATEGORY));
    wizard->setDisplayCategory(trCat);
    wizard->setDescription(tr("Creates a C++ header file that you can add to a C++ project."));
    wizard->setDisplayName(tr("C++ Header File"));
    wizard->setId(QLatin1String("C.Header"));
    addAutoReleasedObject(wizard);
con's avatar
con committed
195

196
    Context context(CppEditor::Constants::C_CPPEDITOR);
con's avatar
con committed
197

198
    ActionContainer *contextMenu = ActionManager::createMenu(CppEditor::Constants::M_CONTEXT);
con's avatar
con committed
199

200 201
    Command *cmd;
    ActionContainer *cppToolsMenu = ActionManager::actionContainer(CppTools::Constants::M_TOOLS_CPP);
con's avatar
con committed
202

203
    cmd = ActionManager::command(CppTools::Constants::SWITCH_HEADER_SOURCE);
204 205
    contextMenu->addAction(cmd);

206
    cmd = ActionManager::command(TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR);
mae's avatar
mae committed
207
    contextMenu->addAction(cmd);
208
    cppToolsMenu->addAction(cmd);
con's avatar
con committed
209

hjk's avatar
hjk committed
210
    QAction *switchDeclarationDefinition = new QAction(tr("Switch Between Method Declaration/Definition"), this);
211
    cmd = ActionManager::registerAction(switchDeclarationDefinition,
212
        Constants::SWITCH_DECLARATION_DEFINITION, context, true);
213
    cmd->setDefaultKeySequence(QKeySequence(tr("Shift+F2")));
con's avatar
con committed
214 215
    connect(switchDeclarationDefinition, SIGNAL(triggered()),
            this, SLOT(switchDeclarationDefinition()));
mae's avatar
mae committed
216
    contextMenu->addAction(cmd);
217
    cppToolsMenu->addAction(cmd);
con's avatar
con committed
218

219
    cmd = ActionManager::command(TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR_IN_NEXT_SPLIT);
220 221 222
    cppToolsMenu->addAction(cmd);

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

233
    m_findUsagesAction = new QAction(tr("Find Usages"), this);
234
    cmd = ActionManager::registerAction(m_findUsagesAction, Constants::FIND_USAGES, context);
235
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+U")));
236
    connect(m_findUsagesAction, SIGNAL(triggered()), this, SLOT(findUsages()));
237
    contextMenu->addAction(cmd);
238
    cppToolsMenu->addAction(cmd);
239

240
    m_openTypeHierarchyAction = new QAction(tr("Open Type Hierarchy"), this);
241 242
    cmd = ActionManager::registerAction(m_openTypeHierarchyAction, Constants::OPEN_TYPE_HIERARCHY, context);
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+Shift+T") : tr("Ctrl+Shift+T")));
243 244 245 246
    connect(m_openTypeHierarchyAction, SIGNAL(triggered()), this, SLOT(openTypeHierarchy()));
    contextMenu->addAction(cmd);
    cppToolsMenu->addAction(cmd);

247
    // Refactoring sub-menu
248 249
    Context globalContext(Core::Constants::C_GLOBAL);
    Command *sep = contextMenu->addSeparator(globalContext);
250
    sep->action()->setObjectName(QLatin1String(Constants::M_REFACTORING_MENU_INSERTION_POINT));
251
    contextMenu->addSeparator(globalContext);
252 253 254

    m_renameSymbolUnderCursorAction = new QAction(tr("Rename Symbol Under Cursor"),
                                                  this);
255
    cmd = ActionManager::registerAction(m_renameSymbolUnderCursorAction,
256 257
                             Constants::RENAME_SYMBOL_UNDER_CURSOR,
                             context);
258
    cmd->setDefaultKeySequence(QKeySequence(tr("CTRL+SHIFT+R")));
259 260 261 262 263
    connect(m_renameSymbolUnderCursorAction, SIGNAL(triggered()),
            this, SLOT(renameSymbolUnderCursor()));
    cppToolsMenu->addAction(cmd);

    // Update context in global context
264
    cppToolsMenu->addSeparator(globalContext);
265
    m_updateCodeModelAction = new QAction(tr("Update Code Model"), this);
266
    cmd = ActionManager::registerAction(m_updateCodeModelAction, Constants::UPDATE_CODEMODEL, globalContext);
267
    CppTools::CppModelManagerInterface *cppModelManager = CppTools::CppModelManagerInterface::instance();
268 269
    connect(m_updateCodeModelAction, SIGNAL(triggered()), cppModelManager, SLOT(updateModifiedSourceFiles()));
    cppToolsMenu->addAction(cmd);
270

271
    m_actionHandler = new TextEditor::TextEditorActionHandler(CppEditor::Constants::C_CPPEDITOR,
con's avatar
con committed
272 273
        TextEditor::TextEditorActionHandler::Format
        | TextEditor::TextEditorActionHandler::UnCommentSelection
274 275
        | TextEditor::TextEditorActionHandler::UnCollapseAll
        | TextEditor::TextEditorActionHandler::FollowSymbolUnderCursor);
con's avatar
con committed
276

277
    m_actionHandler->initializeActions();
278

279
    contextMenu->addSeparator(context);
280

281
    cmd = ActionManager::command(TextEditor::Constants::AUTO_INDENT_SELECTION);
mae's avatar
mae committed
282
    contextMenu->addAction(cmd);
283

284
    cmd = ActionManager::command(TextEditor::Constants::UN_COMMENT_SELECTION);
mae's avatar
mae committed
285
    contextMenu->addAction(cmd);
286

287 288 289 290
    connect(ProgressManager::instance(), SIGNAL(taskStarted(Core::Id)),
            this, SLOT(onTaskStarted(Core::Id)));
    connect(ProgressManager::instance(), SIGNAL(allTasksFinished(Core::Id)),
            this, SLOT(onAllTasksFinished(Core::Id)));
291

292 293
    connect(EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
            SLOT(currentEditorChanged(Core::IEditor*)));
294

295
    readSettings();
con's avatar
con committed
296 297 298
    return true;
}

299
void CppEditorPlugin::readSettings()
300
{
301
    m_sortedOutline = ICore::settings()->value(QLatin1String("CppTools/SortedMethodOverview"), false).toBool();
302 303
}

304
void CppEditorPlugin::writeSettings()
305
{
306
    ICore::settings()->setValue(QLatin1String("CppTools/SortedMethodOverview"), m_sortedOutline);
307 308
}

309
void CppEditorPlugin::extensionsInitialized()
con's avatar
con committed
310 311 312
{
}

313
ExtensionSystem::IPlugin::ShutdownFlag CppEditorPlugin::aboutToShutdown()
314 315
{
    writeSettings();
316
    return SynchronousShutdown;
317 318
}

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

326
void CppEditorPlugin::openDeclarationDefinitionInNextSplit()
327
{
328
    CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
329 330
    if (editor)
        editor->switchDeclarationDefinition(/*inNextSplit*/ true);
con's avatar
con committed
331 332
}

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

340
void CppEditorPlugin::findUsages()
341
{
342
    CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
343 344 345 346
    if (editor)
        editor->findUsages();
}

347
void CppEditorPlugin::onTaskStarted(Core::Id type)
348
{
349
    if (type == CppTools::Constants::TASK_INDEX) {
350 351
        m_renameSymbolUnderCursorAction->setEnabled(false);
        m_findUsagesAction->setEnabled(false);
352
        m_updateCodeModelAction->setEnabled(false);
353
        m_openTypeHierarchyAction->setEnabled(false);
354
    }
355 356
}

357
void CppEditorPlugin::onAllTasksFinished(Core::Id type)
358
{
359
    if (type == CppTools::Constants::TASK_INDEX) {
360 361
        m_renameSymbolUnderCursorAction->setEnabled(true);
        m_findUsagesAction->setEnabled(true);
362
        m_updateCodeModelAction->setEnabled(true);
363
        m_openTypeHierarchyAction->setEnabled(true);
364
    }
365 366
}

367
void CppEditorPlugin::currentEditorChanged(IEditor *editor)
368
{
369
    if (!editor)
370 371
        return;

372
    if (CPPEditorWidget *textEditor = qobject_cast<CPPEditorWidget *>(editor->widget()))
373
        textEditor->semanticRehighlight(/*force = */ true);
374 375
}

376
void CppEditorPlugin::openTypeHierarchy()
377
{
378
    CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
379
    if (editor) {
380 381
        NavigationWidget *navigation = NavigationWidget::instance();
        navigation->activateSubWidget(Constants::TYPE_HIERARCHY_ID);
382 383 384 385
        emit typeHierarchyRequested();
    }
}

386
Q_EXPORT_PLUGIN(CppEditorPlugin)