| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2014-01-07 13:27:11 +01:00
										 |  |  | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Contact: http://www.qt-project.org/legal
 | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** 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.
 | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** 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 | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "refactoringchanges.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-20 14:03:07 +01:00
										 |  |  | #include "basetexteditor.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-15 11:53:22 +02:00
										 |  |  | #include <coreplugin/icore.h>
 | 
					
						
							|  |  |  | #include <coreplugin/dialogs/readonlyfilesdialog.h>
 | 
					
						
							| 
									
										
										
										
											2011-09-20 13:10:17 +02:00
										 |  |  | #include <utils/qtcassert.h>
 | 
					
						
							| 
									
										
										
										
											2012-10-15 11:53:22 +02:00
										 |  |  | #include <utils/fileutils.h>
 | 
					
						
							| 
									
										
										
										
											2011-03-30 15:15:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-15 10:42:41 +01:00
										 |  |  | #include <QFile>
 | 
					
						
							| 
									
										
										
										
											2012-10-15 11:53:22 +02:00
										 |  |  | #include <QFileInfo>
 | 
					
						
							| 
									
										
										
										
											2012-02-15 10:42:41 +01:00
										 |  |  | #include <QTextBlock>
 | 
					
						
							|  |  |  | #include <QTextCursor>
 | 
					
						
							|  |  |  | #include <QTextDocument>
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							| 
									
										
										
										
											2012-10-15 11:53:22 +02:00
										 |  |  | #include <QApplication>
 | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace TextEditor; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-08 16:40:46 +02:00
										 |  |  | RefactoringChanges::RefactoringChanges() | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     : m_data(new RefactoringChangesData) | 
					
						
							|  |  |  | {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RefactoringChanges::RefactoringChanges(RefactoringChangesData *data) | 
					
						
							|  |  |  |     : m_data(data) | 
					
						
							| 
									
										
										
										
											2010-07-08 16:40:46 +02:00
										 |  |  | {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | RefactoringChanges::~RefactoringChanges() | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | {} | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-16 14:35:58 +01:00
										 |  |  | QList<QPair<QTextCursor, QTextCursor > > RefactoringChanges::rangesToSelections(QTextDocument *document, | 
					
						
							|  |  |  |                                                                                 const QList<Range> &ranges) | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-01-16 14:35:58 +01:00
										 |  |  |     QList<QPair<QTextCursor, QTextCursor> > selections; | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     foreach (const Range &range, ranges) { | 
					
						
							| 
									
										
										
										
											2012-01-16 14:35:58 +01:00
										 |  |  |         QTextCursor start(document); | 
					
						
							|  |  |  |         start.setPosition(range.start); | 
					
						
							|  |  |  |         start.setKeepPositionOnInsert(true); | 
					
						
							|  |  |  |         QTextCursor end(document); | 
					
						
							|  |  |  |         end.setPosition(qMin(range.end, document->characterCount() - 1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         selections.append(qMakePair(start, end)); | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return selections; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | bool RefactoringChanges::createFile(const QString &fileName, const QString &contents, bool reindent, bool openEditor) const | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (QFile::exists(fileName)) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-18 16:31:16 +01:00
										 |  |  |     // Create a text document for the new file:
 | 
					
						
							|  |  |  |     QTextDocument *document = new QTextDocument; | 
					
						
							|  |  |  |     QTextCursor cursor(document); | 
					
						
							|  |  |  |     cursor.beginEditBlock(); | 
					
						
							|  |  |  |     cursor.insertText(contents); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Reindent the contents:
 | 
					
						
							|  |  |  |     if (reindent) { | 
					
						
							|  |  |  |         cursor.select(QTextCursor::Document); | 
					
						
							|  |  |  |         m_data->indentSelection(cursor, fileName, 0); | 
					
						
							| 
									
										
										
										
											2010-08-12 13:46:18 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-01-18 16:31:16 +01:00
										 |  |  |     cursor.endEditBlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Write the file to disk:
 | 
					
						
							|  |  |  |     Utils::TextFileFormat format; | 
					
						
							| 
									
										
										
										
											2013-08-29 15:46:04 +02:00
										 |  |  |     format.codec = Core::EditorManager::defaultTextCodec(); | 
					
						
							| 
									
										
										
										
											2012-01-18 16:31:16 +01:00
										 |  |  |     QString error; | 
					
						
							|  |  |  |     bool saveOk = format.writeFile(fileName, document->toPlainText(), &error); | 
					
						
							|  |  |  |     delete document; | 
					
						
							|  |  |  |     if (!saveOk) | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2010-08-12 13:46:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     m_data->fileChanged(fileName); | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-18 16:31:16 +01:00
										 |  |  |     if (openEditor) | 
					
						
							|  |  |  |         this->openEditor(fileName, /*bool activate =*/ false, -1, -1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2010-06-14 14:52:43 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-08 16:40:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | bool RefactoringChanges::removeFile(const QString &fileName) const | 
					
						
							| 
									
										
										
										
											2010-07-08 16:40:46 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |     if (!QFile::exists(fileName)) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 14:26:30 +02:00
										 |  |  |     // ### implement!
 | 
					
						
							|  |  |  |     qWarning() << "RefactoringChanges::removeFile is not implemented"; | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | BaseTextEditorWidget *RefactoringChanges::openEditor(const QString &fileName, bool activate, int line, int column) | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     Core::EditorManager::OpenEditorFlags flags = Core::EditorManager::IgnoreNavigationHistory; | 
					
						
							|  |  |  |     if (!activate) | 
					
						
							| 
									
										
										
										
											2013-05-31 12:52:53 +02:00
										 |  |  |         flags |= Core::EditorManager::DoNotChangeCurrentEditor; | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     if (line != -1) { | 
					
						
							|  |  |  |         // openEditorAt uses a 1-based line and a 0-based column!
 | 
					
						
							|  |  |  |         column -= 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-05-30 17:26:51 +02:00
										 |  |  |     Core::IEditor *editor = Core::EditorManager::openEditorAt( | 
					
						
							| 
									
										
										
										
											2011-11-10 11:36:51 +01:00
										 |  |  |                 fileName, line, column, Core::Id(), flags); | 
					
						
							| 
									
										
										
										
											2012-01-18 16:31:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (editor) | 
					
						
							|  |  |  |         return qobject_cast<BaseTextEditorWidget *>(editor->widget()); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | RefactoringFilePtr RefactoringChanges::file(BaseTextEditorWidget *editor) | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     return RefactoringFilePtr(new RefactoringFile(editor)); | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | RefactoringFilePtr RefactoringChanges::file(const QString &fileName) const | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     return RefactoringFilePtr(new RefactoringFile(fileName, m_data)); | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-10 09:50:04 +02:00
										 |  |  | RefactoringFile::RefactoringFile(QTextDocument *document, const QString &fileName) | 
					
						
							|  |  |  |     : m_fileName(fileName) | 
					
						
							|  |  |  |     , m_document(document) | 
					
						
							|  |  |  |     , m_editor(0) | 
					
						
							|  |  |  |     , m_openEditor(false) | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     , m_activateEditor(false) | 
					
						
							|  |  |  |     , m_editorCursorPosition(-1) | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |     , m_appliedOnce(false) | 
					
						
							| 
									
										
										
										
											2011-08-10 09:50:04 +02:00
										 |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RefactoringFile::RefactoringFile(BaseTextEditorWidget *editor) | 
					
						
							| 
									
										
										
										
											2013-12-12 15:07:54 +01:00
										 |  |  |     : m_fileName(editor->baseTextDocument()->filePath()) | 
					
						
							| 
									
										
										
										
											2011-08-10 09:50:04 +02:00
										 |  |  |     , m_document(0) | 
					
						
							|  |  |  |     , m_editor(editor) | 
					
						
							|  |  |  |     , m_openEditor(false) | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     , m_activateEditor(false) | 
					
						
							|  |  |  |     , m_editorCursorPosition(-1) | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |     , m_appliedOnce(false) | 
					
						
							| 
									
										
										
										
											2011-08-10 09:50:04 +02:00
										 |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | RefactoringFile::RefactoringFile(const QString &fileName, const QSharedPointer<RefactoringChangesData> &data) | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |     : m_fileName(fileName) | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     , m_data(data) | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |     , m_document(0) | 
					
						
							|  |  |  |     , m_editor(0) | 
					
						
							| 
									
										
										
										
											2010-08-12 13:46:18 +02:00
										 |  |  |     , m_openEditor(false) | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     , m_activateEditor(false) | 
					
						
							|  |  |  |     , m_editorCursorPosition(-1) | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |     , m_appliedOnce(false) | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-18 09:40:50 +02:00
										 |  |  |     QList<Core::IEditor *> editors = Core::EditorManager::documentModel()->editorsForFilePath(fileName); | 
					
						
							|  |  |  |     if (!editors.isEmpty()) | 
					
						
							|  |  |  |         m_editor = qobject_cast<TextEditor::BaseTextEditorWidget *>(editors.first()->widget()); | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RefactoringFile::~RefactoringFile() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete m_document; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RefactoringFile::isValid() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     if (m_fileName.isEmpty()) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     return document(); | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const QTextDocument *RefactoringFile::document() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return mutableDocument(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QTextDocument *RefactoringFile::mutableDocument() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-12 13:46:18 +02:00
										 |  |  |     if (m_editor) | 
					
						
							|  |  |  |         return m_editor->document(); | 
					
						
							| 
									
										
										
										
											2013-07-17 00:01:45 +03:00
										 |  |  |     if (!m_document) { | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |         QString fileContents; | 
					
						
							| 
									
										
										
										
											2011-09-20 13:10:17 +02:00
										 |  |  |         if (!m_fileName.isEmpty()) { | 
					
						
							|  |  |  |             QString error; | 
					
						
							| 
									
										
										
										
											2013-08-29 15:46:04 +02:00
										 |  |  |             QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec(); | 
					
						
							| 
									
										
										
										
											2011-09-20 13:10:17 +02:00
										 |  |  |             Utils::TextFileFormat::ReadResult result = Utils::TextFileFormat::readFile( | 
					
						
							|  |  |  |                         m_fileName, defaultCodec, | 
					
						
							|  |  |  |                         &fileContents, &m_textFileFormat, | 
					
						
							|  |  |  |                         &error); | 
					
						
							|  |  |  |             if (result != Utils::TextFileFormat::ReadSuccess) { | 
					
						
							|  |  |  |                 qWarning() << "Could not read " << m_fileName << ". Error: " << error; | 
					
						
							|  |  |  |                 m_textFileFormat.codec = 0; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-09-20 13:10:17 +02:00
										 |  |  |         // always make a QTextDocument to avoid excessive null checks
 | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |         m_document = new QTextDocument(fileContents); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return m_document; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const QTextCursor RefactoringFile::cursor() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_editor) | 
					
						
							|  |  |  |         return m_editor->textCursor(); | 
					
						
							| 
									
										
										
										
											2013-07-17 00:01:45 +03:00
										 |  |  |     if (!m_fileName.isEmpty()) { | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         if (QTextDocument *doc = mutableDocument()) | 
					
						
							|  |  |  |             return QTextCursor(doc); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return QTextCursor(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 14:18:36 +02:00
										 |  |  | QString RefactoringFile::fileName() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_fileName; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-18 09:40:50 +02:00
										 |  |  | BaseTextEditorWidget *RefactoringFile::editor() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_editor; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | int RefactoringFile::position(unsigned line, unsigned column) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-14 15:40:11 +01:00
										 |  |  |     QTC_ASSERT(line != 0, return -1); | 
					
						
							|  |  |  |     QTC_ASSERT(column != 0, return -1); | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  |     if (const QTextDocument *doc = document()) | 
					
						
							|  |  |  |         return doc->findBlockByNumber(line - 1).position() + column - 1; | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | void RefactoringFile::lineAndColumn(int offset, unsigned *line, unsigned *column) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-14 15:40:11 +01:00
										 |  |  |     QTC_ASSERT(line, return); | 
					
						
							|  |  |  |     QTC_ASSERT(column, return); | 
					
						
							|  |  |  |     QTC_ASSERT(offset >= 0, return); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     QTextCursor c(cursor()); | 
					
						
							|  |  |  |     c.setPosition(offset); | 
					
						
							|  |  |  |     *line = c.blockNumber() + 1; | 
					
						
							|  |  |  |     *column = c.positionInBlock() + 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | QChar RefactoringFile::charAt(int pos) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (const QTextDocument *doc = document()) | 
					
						
							|  |  |  |         return doc->characterAt(pos); | 
					
						
							|  |  |  |     return QChar(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 11:48:29 +02:00
										 |  |  | QString RefactoringFile::textOf(int start, int end) const | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QTextCursor c = cursor(); | 
					
						
							|  |  |  |     c.setPosition(start); | 
					
						
							|  |  |  |     c.setPosition(end, QTextCursor::KeepAnchor); | 
					
						
							|  |  |  |     return c.selectedText(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 11:48:29 +02:00
										 |  |  | QString RefactoringFile::textOf(const Range &range) const | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-13 11:48:29 +02:00
										 |  |  |     return textOf(range.start, range.end); | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | void RefactoringFile::setChangeSet(const Utils::ChangeSet &changeSet) | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (m_fileName.isEmpty()) | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 13:46:18 +02:00
										 |  |  |     m_changes = changeSet; | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | void RefactoringFile::appendIndentRange(const Range &range) | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (m_fileName.isEmpty()) | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 13:46:18 +02:00
										 |  |  |     m_indentRanges.append(range); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  | void RefactoringFile::appendReindentRange(const Range &range) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_fileName.isEmpty()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_reindentRanges.append(range); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | void RefactoringFile::setOpenEditor(bool activate, int pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_openEditor = true; | 
					
						
							|  |  |  |     m_activateEditor = activate; | 
					
						
							|  |  |  |     m_editorCursorPosition = pos; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-08-12 11:34:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | void RefactoringFile::apply() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-10-15 11:53:22 +02:00
										 |  |  |     // test file permissions
 | 
					
						
							|  |  |  |     if (!QFileInfo(fileName()).isWritable()) { | 
					
						
							|  |  |  |         const QString &path = fileName(); | 
					
						
							|  |  |  |         Core::Internal::ReadOnlyFilesDialog roDialog(path, Core::ICore::mainWindow()); | 
					
						
							|  |  |  |         const QString &failDetailText = QApplication::translate("RefactoringFile::apply", | 
					
						
							|  |  |  |                                                                 "Refactoring cannot be applied."); | 
					
						
							|  |  |  |         roDialog.setShowFailWarning(true, failDetailText); | 
					
						
							|  |  |  |         if (roDialog.exec() == Core::Internal::ReadOnlyFilesDialog::RO_Cancel) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     // open / activate / goto position
 | 
					
						
							|  |  |  |     if (m_openEditor && !m_fileName.isEmpty()) { | 
					
						
							| 
									
										
										
										
											2012-05-20 21:15:30 +02:00
										 |  |  |         unsigned line = unsigned(-1), column = unsigned(-1); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         if (m_editorCursorPosition != -1) | 
					
						
							|  |  |  |             lineAndColumn(m_editorCursorPosition, &line, &column); | 
					
						
							|  |  |  |         m_editor = RefactoringChanges::openEditor(m_fileName, m_activateEditor, line, column); | 
					
						
							|  |  |  |         m_openEditor = false; | 
					
						
							|  |  |  |         m_activateEditor = false; | 
					
						
							|  |  |  |         m_editorCursorPosition = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // apply changes, if any
 | 
					
						
							|  |  |  |     if (m_data && !(m_indentRanges.isEmpty() && m_changes.isEmpty())) { | 
					
						
							|  |  |  |         QTextDocument *doc = mutableDocument(); | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |         if (doc) { | 
					
						
							| 
									
										
										
										
											2011-10-20 15:41:44 +02:00
										 |  |  |             QTextCursor c = cursor(); | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |             if (m_appliedOnce) | 
					
						
							|  |  |  |                 c.joinPreviousEditBlock(); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 c.beginEditBlock(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // build indent selections now, applying the changeset will change locations
 | 
					
						
							| 
									
										
										
										
											2012-01-16 14:35:58 +01:00
										 |  |  |             const QList<QPair<QTextCursor, QTextCursor> > &indentSelections = | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |                     RefactoringChanges::rangesToSelections(doc, m_indentRanges); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             m_indentRanges.clear(); | 
					
						
							| 
									
										
										
										
											2012-01-16 14:35:58 +01:00
										 |  |  |             const QList<QPair<QTextCursor, QTextCursor> > &reindentSelections = | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |                     RefactoringChanges::rangesToSelections(doc, m_reindentRanges); | 
					
						
							|  |  |  |             m_reindentRanges.clear(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // apply changes and reindent
 | 
					
						
							|  |  |  |             m_changes.apply(&c); | 
					
						
							|  |  |  |             m_changes.clear(); | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-16 14:35:58 +01:00
										 |  |  |             indentOrReindent(&RefactoringChangesData::indentSelection, indentSelections); | 
					
						
							|  |  |  |             indentOrReindent(&RefactoringChangesData::reindentSelection, reindentSelections); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             c.endEditBlock(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |             // if this document doesn't have an editor, write the result to a file
 | 
					
						
							|  |  |  |             if (!m_editor && m_textFileFormat.codec) { | 
					
						
							|  |  |  |                 QTC_ASSERT(!m_fileName.isEmpty(), return); | 
					
						
							|  |  |  |                 QString error; | 
					
						
							|  |  |  |                 if (!m_textFileFormat.writeFile(m_fileName, doc->toPlainText(), &error)) | 
					
						
							|  |  |  |                     qWarning() << "Could not apply changes to" << m_fileName << ". Error: " << error; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  |             fileChanged(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_appliedOnce = true; | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-16 14:35:58 +01:00
										 |  |  | void RefactoringFile::indentOrReindent(void (RefactoringChangesData::*mf)(const QTextCursor &, | 
					
						
							|  |  |  |                                                                           const QString &, | 
					
						
							|  |  |  |                                                                           const BaseTextEditorWidget *) const, | 
					
						
							|  |  |  |                                        const QList<QPair<QTextCursor, QTextCursor> > &ranges) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-03-11 17:23:55 +01:00
										 |  |  |     typedef QPair<QTextCursor, QTextCursor> CursorPair; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (const CursorPair &p, ranges) { | 
					
						
							| 
									
										
										
										
											2012-01-16 14:35:58 +01:00
										 |  |  |         QTextCursor selection(p.first.document()); | 
					
						
							|  |  |  |         selection.setPosition(p.first.position()); | 
					
						
							|  |  |  |         selection.setPosition(p.second.position(), QTextCursor::KeepAnchor); | 
					
						
							|  |  |  |         ((*m_data).*(mf))(selection, m_fileName, m_editor); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | void RefactoringFile::fileChanged() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_fileName.isEmpty()) | 
					
						
							|  |  |  |         m_data->fileChanged(m_fileName); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-22 13:41:19 +02:00
										 |  |  | RefactoringChangesData::~RefactoringChangesData() | 
					
						
							|  |  |  | {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | void RefactoringChangesData::indentSelection(const QTextCursor &, const QString &, const BaseTextEditorWidget *) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qWarning() << Q_FUNC_INFO << "not implemented"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-12 13:23:48 +01:00
										 |  |  | void RefactoringChangesData::reindentSelection(const QTextCursor &, const QString &, const BaseTextEditorWidget *) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qWarning() << Q_FUNC_INFO << "not implemented"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  | void RefactoringChangesData::fileChanged(const QString &) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-08 16:40:46 +02:00
										 |  |  | } |