forked from qt-creator/qt-creator
QmlJS: Implement renaming of usages.
Task-number: QTCREATORBUG-3669 Change-Id: I2c600cae5ac445ca80eafe6557ba276c14a77a73 Reviewed-on: http://codereview.qt.nokia.com/1413 Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com>
This commit is contained in:
@@ -1333,6 +1333,11 @@ void QmlJSTextEditorWidget::findUsages()
|
|||||||
m_findReferences->findUsages(file()->fileName(), textCursor().position());
|
m_findReferences->findUsages(file()->fileName(), textCursor().position());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlJSTextEditorWidget::renameUsages()
|
||||||
|
{
|
||||||
|
m_findReferences->renameUsages(file()->fileName(), textCursor().position());
|
||||||
|
}
|
||||||
|
|
||||||
void QmlJSTextEditorWidget::showContextPane()
|
void QmlJSTextEditorWidget::showContextPane()
|
||||||
{
|
{
|
||||||
if (m_contextPane && m_semanticInfo.isValid()) {
|
if (m_contextPane && m_semanticInfo.isValid()) {
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ public slots:
|
|||||||
void forceSemanticRehighlight();
|
void forceSemanticRehighlight();
|
||||||
void followSymbolUnderCursor();
|
void followSymbolUnderCursor();
|
||||||
void findUsages();
|
void findUsages();
|
||||||
|
void renameUsages();
|
||||||
void showContextPane();
|
void showContextPane();
|
||||||
virtual void setFontSettings(const TextEditor::FontSettings &);
|
virtual void setFontSettings(const TextEditor::FontSettings &);
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const char * const TASK_SEARCH = "QmlJSEditor.TaskSearch";
|
|||||||
|
|
||||||
const char * const FOLLOW_SYMBOL_UNDER_CURSOR = "QmlJSEditor.FollowSymbolUnderCursor";
|
const char * const FOLLOW_SYMBOL_UNDER_CURSOR = "QmlJSEditor.FollowSymbolUnderCursor";
|
||||||
const char * const FIND_USAGES = "QmlJSEditor.FindUsages";
|
const char * const FIND_USAGES = "QmlJSEditor.FindUsages";
|
||||||
|
const char * const RENAME_USAGES = "QmlJSEditor.RenameUsages";
|
||||||
const char * const SHOW_QT_QUICK_HELPER = "QmlJSEditor.ShowQtQuickHelper";
|
const char * const SHOW_QT_QUICK_HELPER = "QmlJSEditor.ShowQtQuickHelper";
|
||||||
|
|
||||||
const char * const QML_MIMETYPE = "application/x-qml";
|
const char * const QML_MIMETYPE = "application/x-qml";
|
||||||
|
|||||||
@@ -180,6 +180,13 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e
|
|||||||
contextMenu->addAction(cmd);
|
contextMenu->addAction(cmd);
|
||||||
qmlToolsMenu->addAction(cmd);
|
qmlToolsMenu->addAction(cmd);
|
||||||
|
|
||||||
|
QAction *renameUsagesAction = new QAction(tr("Rename Usages"), this);
|
||||||
|
cmd = am->registerAction(renameUsagesAction, Constants::RENAME_USAGES, context);
|
||||||
|
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+R")));
|
||||||
|
connect(renameUsagesAction, SIGNAL(triggered()), this, SLOT(renameUsages()));
|
||||||
|
contextMenu->addAction(cmd);
|
||||||
|
qmlToolsMenu->addAction(cmd);
|
||||||
|
|
||||||
QAction *showQuickToolbar = new QAction(tr("Show Qt Quick Toolbar"), this);
|
QAction *showQuickToolbar = new QAction(tr("Show Qt Quick Toolbar"), this);
|
||||||
cmd = am->registerAction(showQuickToolbar, Constants::SHOW_QT_QUICK_HELPER, context);
|
cmd = am->registerAction(showQuickToolbar, Constants::SHOW_QT_QUICK_HELPER, context);
|
||||||
#ifdef Q_WS_MACX
|
#ifdef Q_WS_MACX
|
||||||
@@ -281,6 +288,13 @@ void QmlJSEditorPlugin::findUsages()
|
|||||||
editor->findUsages();
|
editor->findUsages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlJSEditorPlugin::renameUsages()
|
||||||
|
{
|
||||||
|
Core::EditorManager *em = Core::EditorManager::instance();
|
||||||
|
if (QmlJSTextEditorWidget *editor = qobject_cast<QmlJSTextEditorWidget*>(em->currentEditor()->widget()))
|
||||||
|
editor->renameUsages();
|
||||||
|
}
|
||||||
|
|
||||||
void QmlJSEditorPlugin::showContextPane()
|
void QmlJSEditorPlugin::showContextPane()
|
||||||
{
|
{
|
||||||
Core::EditorManager *em = Core::EditorManager::instance();
|
Core::EditorManager *em = Core::EditorManager::instance();
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ public:
|
|||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void followSymbolUnderCursor();
|
void followSymbolUnderCursor();
|
||||||
void findUsages();
|
void findUsages();
|
||||||
|
void renameUsages();
|
||||||
void showContextPane();
|
void showContextPane();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
|||||||
@@ -795,7 +795,8 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
|
|||||||
const ModelManagerInterface::WorkingCopy workingCopy,
|
const ModelManagerInterface::WorkingCopy workingCopy,
|
||||||
Snapshot snapshot,
|
Snapshot snapshot,
|
||||||
const QString fileName,
|
const QString fileName,
|
||||||
quint32 offset)
|
quint32 offset,
|
||||||
|
QString replacement)
|
||||||
{
|
{
|
||||||
// update snapshot from workingCopy to make sure it's up to date
|
// update snapshot from workingCopy to make sure it's up to date
|
||||||
// ### remove?
|
// ### remove?
|
||||||
@@ -832,6 +833,8 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
|
|||||||
const QString &name = findTarget.name();
|
const QString &name = findTarget.name();
|
||||||
if (name.isEmpty())
|
if (name.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
if (!replacement.isNull() && replacement.isEmpty())
|
||||||
|
replacement = name;
|
||||||
|
|
||||||
QStringList files;
|
QStringList files;
|
||||||
foreach (const Document::Ptr &doc, snapshot) {
|
foreach (const Document::Ptr &doc, snapshot) {
|
||||||
@@ -841,12 +844,14 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
|
|||||||
|
|
||||||
future.setProgressRange(0, files.size());
|
future.setProgressRange(0, files.size());
|
||||||
|
|
||||||
|
// report a dummy usage to indicate the search is starting
|
||||||
|
FindReferences::Usage searchStarting(replacement, QString(), 0, 0, 0);
|
||||||
|
|
||||||
if (findTarget.typeKind() == findTarget.TypeKind){
|
if (findTarget.typeKind() == findTarget.TypeKind){
|
||||||
const ObjectValue *typeValue = value_cast<const ObjectValue*>(findTarget.targetValue());
|
const ObjectValue *typeValue = value_cast<const ObjectValue*>(findTarget.targetValue());
|
||||||
if (!typeValue)
|
if (!typeValue)
|
||||||
return;
|
return;
|
||||||
// report a dummy usage to indicate the search is starting
|
future.reportResult(searchStarting);
|
||||||
future.reportResult(FindReferences::Usage());
|
|
||||||
|
|
||||||
SearchFileForType process(context, name, typeValue);
|
SearchFileForType process(context, name, typeValue);
|
||||||
UpdateUI reduce(&future);
|
UpdateUI reduce(&future);
|
||||||
@@ -859,8 +864,7 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
|
|||||||
scope->lookupMember(name, &context, &scope);
|
scope->lookupMember(name, &context, &scope);
|
||||||
if (!scope)
|
if (!scope)
|
||||||
return;
|
return;
|
||||||
// report a dummy usage to indicate the search is starting
|
future.reportResult(searchStarting);
|
||||||
future.reportResult(FindReferences::Usage());
|
|
||||||
|
|
||||||
ProcessFile process(context, name, scope);
|
ProcessFile process(context, name, scope);
|
||||||
UpdateUI reduce(&future);
|
UpdateUI reduce(&future);
|
||||||
@@ -871,18 +875,30 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FindReferences::findUsages(const QString &fileName, quint32 offset)
|
void FindReferences::findUsages(const QString &fileName, quint32 offset)
|
||||||
{
|
|
||||||
findAll_helper(fileName, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FindReferences::findAll_helper(const QString &fileName, quint32 offset)
|
|
||||||
{
|
{
|
||||||
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
||||||
|
|
||||||
|
|
||||||
QFuture<Usage> result = QtConcurrent::run(
|
QFuture<Usage> result = QtConcurrent::run(
|
||||||
&find_helper, modelManager->workingCopy(),
|
&find_helper, modelManager->workingCopy(),
|
||||||
modelManager->snapshot(), fileName, offset);
|
modelManager->snapshot(), fileName, offset,
|
||||||
|
QString());
|
||||||
|
m_watcher.setFuture(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindReferences::renameUsages(const QString &fileName, quint32 offset,
|
||||||
|
const QString &replacement)
|
||||||
|
{
|
||||||
|
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
||||||
|
|
||||||
|
// an empty non-null string asks the future to use the current name as base
|
||||||
|
QString newName = replacement;
|
||||||
|
if (newName.isNull())
|
||||||
|
newName = QLatin1String("");
|
||||||
|
|
||||||
|
QFuture<Usage> result = QtConcurrent::run(
|
||||||
|
&find_helper, modelManager->workingCopy(),
|
||||||
|
modelManager->snapshot(), fileName, offset,
|
||||||
|
newName);
|
||||||
m_watcher.setFuture(result);
|
m_watcher.setFuture(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,7 +906,18 @@ void FindReferences::displayResults(int first, int last)
|
|||||||
{
|
{
|
||||||
// the first usage is always a dummy to indicate we now start searching
|
// the first usage is always a dummy to indicate we now start searching
|
||||||
if (first == 0) {
|
if (first == 0) {
|
||||||
Find::SearchResult *search = _resultWindow->startNewSearch(Find::SearchResultWindow::SearchOnly);
|
Usage dummy = m_watcher.future().resultAt(0);
|
||||||
|
QString replacement = dummy.path;
|
||||||
|
|
||||||
|
Find::SearchResult *search;
|
||||||
|
if (replacement.isEmpty()) {
|
||||||
|
search = _resultWindow->startNewSearch(Find::SearchResultWindow::SearchOnly);
|
||||||
|
} else {
|
||||||
|
search = _resultWindow->startNewSearch(Find::SearchResultWindow::SearchAndReplace);
|
||||||
|
_resultWindow->setTextToReplace(replacement);
|
||||||
|
connect(search, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)),
|
||||||
|
SLOT(onReplaceButtonClicked(QString,QList<Find::SearchResultItem>)));
|
||||||
|
}
|
||||||
connect(search, SIGNAL(activated(Find::SearchResultItem)),
|
connect(search, SIGNAL(activated(Find::SearchResultItem)),
|
||||||
this, SLOT(openEditor(Find::SearchResultItem)));
|
this, SLOT(openEditor(Find::SearchResultItem)));
|
||||||
_resultWindow->popup(true);
|
_resultWindow->popup(true);
|
||||||
@@ -930,3 +957,26 @@ void FindReferences::openEditor(const Find::SearchResultItem &item)
|
|||||||
Core::EditorManager::instance()->openEditor(item.text, QString(), Core::EditorManager::ModeSwitch);
|
Core::EditorManager::instance()->openEditor(item.text, QString(), Core::EditorManager::ModeSwitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindReferences::onReplaceButtonClicked(const QString &text, const QList<Find::SearchResultItem> &items)
|
||||||
|
{
|
||||||
|
const QStringList fileNames = TextEditor::BaseFileFind::replaceAll(text, items);
|
||||||
|
|
||||||
|
// files that are opened in an editor are changed, but not saved
|
||||||
|
QStringList changedOnDisk;
|
||||||
|
QStringList changedUnsavedEditors;
|
||||||
|
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||||
|
foreach (const QString &fileName, fileNames) {
|
||||||
|
if (editorManager->editorsForFileName(fileName).isEmpty())
|
||||||
|
changedOnDisk += fileName;
|
||||||
|
else
|
||||||
|
changedUnsavedEditors += fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changedOnDisk.isEmpty())
|
||||||
|
QmlJS::ModelManagerInterface::instance()->updateSourceFiles(changedOnDisk, true);
|
||||||
|
if (!changedUnsavedEditors.isEmpty())
|
||||||
|
QmlJS::ModelManagerInterface::instance()->updateSourceFiles(changedUnsavedEditors, false);
|
||||||
|
|
||||||
|
_resultWindow->hide();
|
||||||
|
}
|
||||||
|
|||||||
@@ -81,14 +81,14 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void findUsages(const QString &fileName, quint32 offset);
|
void findUsages(const QString &fileName, quint32 offset);
|
||||||
|
void renameUsages(const QString &fileName, quint32 offset,
|
||||||
|
const QString &replacement = QString());
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void displayResults(int first, int last);
|
void displayResults(int first, int last);
|
||||||
void searchFinished();
|
void searchFinished();
|
||||||
void openEditor(const Find::SearchResultItem &item);
|
void openEditor(const Find::SearchResultItem &item);
|
||||||
|
void onReplaceButtonClicked(const QString &text, const QList<Find::SearchResultItem> &items);
|
||||||
private:
|
|
||||||
void findAll_helper(const QString &fileName, quint32 offset);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Find::SearchResultWindow *_resultWindow;
|
Find::SearchResultWindow *_resultWindow;
|
||||||
|
|||||||
Reference in New Issue
Block a user