summaryrefslogtreecommitdiff
path: root/src/plugins/texteditor/refactoringchanges.cpp
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2010-08-12 13:46:18 +0200
committerChristian Kamm <christian.d.kamm@nokia.com>2010-08-12 14:21:35 +0200
commit0355e37e537751d4c9fd527c8a6ddf87e8d9dd43 (patch)
tree59d1c17497c4aa87dae4bf8669dc0e8eca34cb3f /src/plugins/texteditor/refactoringchanges.cpp
parentca5076e5ae84931a5cc7bd157171ace7c0a2ff7c (diff)
downloadqt-creator-0355e37e537751d4c9fd527c8a6ddf87e8d9dd43.tar.gz
QuickFix: Migrate to a nicer API for cross-file quick fixes.
Diffstat (limited to 'src/plugins/texteditor/refactoringchanges.cpp')
-rw-r--r--src/plugins/texteditor/refactoringchanges.cpp231
1 files changed, 89 insertions, 142 deletions
diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp
index d44acc2361..9f0575b8af 100644
--- a/src/plugins/texteditor/refactoringchanges.cpp
+++ b/src/plugins/texteditor/refactoringchanges.cpp
@@ -45,99 +45,6 @@ RefactoringChanges::RefactoringChanges()
RefactoringChanges::~RefactoringChanges()
{}
-QStringList RefactoringChanges::apply()
-{
- QSet<QString> changed;
-
- { // open editors
- QHashIterator<QString, int> it(m_cursorByFile);
- while (it.hasNext()) {
- it.next();
- const QString &fileName = it.key();
- int pos = it.value();
-
- BaseTextEditor *editor = editorForFile(fileName, true);
- if (pos != -1) {
- QTextCursor cursor = editor->textCursor();
- cursor.setPosition(pos);
- editor->setTextCursor(cursor);
- }
-
- if (m_fileNameToShow == fileName) {
- Core::EditorManager *editorManager = Core::EditorManager::instance();
- editorManager->activateEditor(editor->editableInterface());
- }
- }
- }
-
- { // change and indent files
- QHashIterator<QString, Utils::ChangeSet> it(m_changesByFile);
- while (it.hasNext()) {
- it.next();
- const QString &fileName = it.key();
- Utils::ChangeSet changes = it.value();
-
- QTextDocument *document;
- QScopedPointer<QFile> file;
- QTextCursor cursor;
- {
- if (BaseTextEditor *editor = editorForFile(fileName, false)) {
- document = editor->document();
- cursor = editor->textCursor();
- } else {
- file.reset(new QFile(fileName));
- if (!file->open(QIODevice::ReadWrite)) {
- qWarning() << "RefactoringChanges could not open" << fileName << "for read/write, skipping";
- continue;
- }
- document = new QTextDocument(file->readAll());
- cursor = QTextCursor(document);
- }
- }
-
- {
- cursor.beginEditBlock();
-
- // build indent selections now, applying the changeset will change locations
- const QList<QTextCursor> &indentSelections = rangesToSelections(
- document, m_indentRangesByFile.values(fileName));
-
- // apply changes and reindent
- changes.apply(&cursor);
-
- // newly created files must be indented specially - there's no way to select everything in an empty file
- if (m_filesToCreate.contains(fileName) && m_indentRangesByFile.contains(fileName)) {
- QTextCursor completeSelection(cursor);
- completeSelection.select(QTextCursor::Document);
- indentSelection(completeSelection);
- } else {
- foreach (const QTextCursor &selection, indentSelections)
- indentSelection(selection);
- }
-
- cursor.endEditBlock();
- }
-
- // if this document came from a file, write the result to it
- if (file) {
- const QByteArray &newContents = document->toPlainText().toUtf8();
- file->resize(newContents.size());
- file->seek(0);
- file->write(newContents);
- delete document;
- }
-
- changed.insert(fileName);
- }
- }
-
- { // Delete files
- // ###
- }
-
- return changed.toList();
-}
-
BaseTextEditor *RefactoringChanges::editorForFile(const QString &fileName,
bool openIfClosed)
{
@@ -185,19 +92,37 @@ bool RefactoringChanges::createFile(const QString &fileName, const QString &cont
{
if (QFile::exists(fileName))
return false;
- if (m_changesByFile.contains(fileName))
- return false;
- m_filesToCreate.insert(fileName);
+ BaseTextEditor *editor = editorForFile(fileName, openEditor);
+
+ QTextDocument *document;
+ if (editor)
+ document = editor->document();
+ else
+ document = new QTextDocument;
- Utils::ChangeSet changes;
- changes.insert(0, contents);
- m_changesByFile.insert(fileName, changes);
+ {
+ QTextCursor cursor(document);
+ cursor.beginEditBlock();
- if (reindent)
- m_indentRangesByFile.insert(fileName, Range(0, 0));
- if (openEditor)
- m_cursorByFile.insert(fileName, -1);
+ cursor.insertText(contents);
+
+ if (reindent) {
+ cursor.select(QTextCursor::Document);
+ indentSelection(cursor);
+ }
+
+ cursor.endEditBlock();
+ }
+
+ if (!editor) {
+ QFile file(fileName);
+ file.open(QFile::WriteOnly);
+ file.write(document->toPlainText().toUtf8());
+ delete document;
+ }
+
+ fileChanged(fileName);
return true;
}
@@ -219,34 +144,25 @@ RefactoringFile RefactoringChanges::file(const QString &fileName)
return RefactoringFile();
}
-void RefactoringChanges::openEditor(const QString &fileName, int pos)
-{
- m_cursorByFile.insert(fileName, pos);
-}
-
-void RefactoringChanges::setActiveEditor(const QString &fileName, int pos)
+BaseTextEditor *RefactoringChanges::openEditor(const QString &fileName, int pos)
{
- m_cursorByFile.insert(fileName, pos);
- m_fileNameToShow = fileName;
+ BaseTextEditor *editor = editorForFile(fileName, true);
+ if (pos != -1) {
+ QTextCursor cursor = editor->textCursor();
+ cursor.setPosition(pos);
+ editor->setTextCursor(cursor);
+ }
+ return editor;
}
-void RefactoringChanges::changeFile(const QString &fileName, const Utils::ChangeSet &changes, bool openEditor)
+BaseTextEditor *RefactoringChanges::activateEditor(const QString &fileName, int pos)
{
- m_changesByFile.insert(fileName, changes);
-
- if (openEditor)
- m_cursorByFile.insert(fileName, -1);
-}
+ BaseTextEditor *editor = openEditor(fileName, pos);
-void RefactoringChanges::reindent(const QString &fileName, const Range &range, bool openEditor)
-{
- m_indentRangesByFile.insert(fileName, range);
+ Core::EditorManager *editorManager = Core::EditorManager::instance();
+ editorManager->activateEditor(editor->editableInterface());
- // simplify apply by never having files indented that are not also changed
- if (!m_changesByFile.contains(fileName))
- m_changesByFile.insert(fileName, Utils::ChangeSet());
- if (openEditor)
- m_cursorByFile.insert(fileName, -1);
+ return editor;
}
@@ -254,6 +170,7 @@ RefactoringFile::RefactoringFile()
: m_refactoringChanges(0)
, m_document(0)
, m_editor(0)
+ , m_openEditor(false)
{ }
RefactoringFile::RefactoringFile(const QString &fileName, RefactoringChanges *refactoringChanges)
@@ -261,6 +178,7 @@ RefactoringFile::RefactoringFile(const QString &fileName, RefactoringChanges *re
, m_refactoringChanges(refactoringChanges)
, m_document(0)
, m_editor(0)
+ , m_openEditor(false)
{
m_editor = RefactoringChanges::editorForFile(fileName, false);
}
@@ -271,12 +189,48 @@ RefactoringFile::RefactoringFile(const RefactoringFile &other)
, m_document(0)
, m_editor(other.m_editor)
{
- if (other.m_document)
- m_document = new QTextDocument(other.m_document);
+ Q_ASSERT_X(!other.m_document && other.m_changes.isEmpty() && other.m_indentRanges.isEmpty(),
+ "RefactoringFile", "A refactoring file with changes is not copyable");
}
RefactoringFile::~RefactoringFile()
{
+ if (m_openEditor)
+ m_editor = m_refactoringChanges->openEditor(m_fileName, -1);
+
+ // apply changes, if any
+ if (!m_indentRanges.isEmpty() || !m_changes.isEmpty()) {
+ QTextDocument *doc = mutableDocument();
+ {
+ QTextCursor c = cursor();
+ c.beginEditBlock();
+
+ // build indent selections now, applying the changeset will change locations
+ const QList<QTextCursor> &indentSelections =
+ RefactoringChanges::rangesToSelections(
+ doc, m_indentRanges);
+
+ // apply changes and reindent
+ m_changes.apply(&c);
+ foreach (const QTextCursor &selection, indentSelections) {
+ m_refactoringChanges->indentSelection(selection);
+ }
+
+ c.endEditBlock();
+ }
+
+ // if this document doesn't have an editor, write the result to a file
+ if (!m_editor) {
+ const QByteArray &newContents = doc->toPlainText().toUtf8();
+ QFile file(m_fileName);
+ file.open(QFile::WriteOnly);
+ //file->resize(newContents.size()); // ### necessary?
+ file.write(newContents);
+ }
+
+ m_refactoringChanges->fileChanged(m_fileName);
+ }
+
delete m_document;
}
@@ -287,15 +241,14 @@ bool RefactoringFile::isValid() const
const QTextDocument *RefactoringFile::document() const
{
- if (m_editor)
- return m_editor->document();
-
return mutableDocument();
}
QTextDocument *RefactoringFile::mutableDocument() const
{
- if (!m_document && !m_fileName.isEmpty()) {
+ if (m_editor)
+ return m_editor->document();
+ else if (!m_document && !m_fileName.isEmpty()) {
QString fileContents;
{
QFile file(m_fileName);
@@ -350,13 +303,11 @@ bool RefactoringFile::change(const Utils::ChangeSet &changeSet, bool openEditor)
{
if (m_fileName.isEmpty())
return false;
- if (!m_refactoringChanges->m_changesByFile.value(m_fileName).isEmpty())
+ if (!m_changes.isEmpty())
return false;
- m_refactoringChanges->m_changesByFile.insert(m_fileName, changeSet);
-
- if (openEditor)
- m_refactoringChanges->m_cursorByFile.insert(m_fileName, -1);
+ m_changes = changeSet;
+ m_openEditor = openEditor;
return true;
}
@@ -366,14 +317,10 @@ bool RefactoringFile::indent(const Range &range, bool openEditor)
if (m_fileName.isEmpty())
return false;
- m_refactoringChanges->m_indentRangesByFile.insert(m_fileName, range);
-
- // simplify apply by never having files indented that are not also changed
- if (!m_refactoringChanges->m_changesByFile.contains(m_fileName))
- m_refactoringChanges->m_changesByFile.insert(m_fileName, Utils::ChangeSet());
+ m_indentRanges.append(range);
if (openEditor)
- m_refactoringChanges->m_cursorByFile.insert(m_fileName, -1);
+ m_openEditor = true;
return true;
}