1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "perforceeditor.h"
36 #include "annotationhighlighter.h"
37 #include "perforceconstants.h"
38 #include "perforceplugin.h"
40 #include <coreplugin/editormanager/editormanager.h>
41 #include <utils/qtcassert.h>
42 #include <vcsbase/diffhighlighter.h>
44 #include <QtCore/QDebug>
45 #include <QtCore/QFileInfo>
46 #include <QtCore/QProcess>
47 #include <QtCore/QRegExp>
48 #include <QtCore/QSet>
49 #include <QtCore/QTextStream>
51 #include <QtGui/QAction>
52 #include <QtGui/QKeyEvent>
53 #include <QtGui/QLayout>
54 #include <QtGui/QMenu>
55 #include <QtGui/QTextCursor>
56 #include <QtGui/QTextEdit>
57 #include <QtGui/QTextBlock>
62 // ------------ PerforceEditor
63 PerforceEditor::PerforceEditor(const VCSBase::VCSBaseEditorParameters *type,
65 VCSBase::VCSBaseEditorWidget(type, parent),
66 m_changeNumberPattern(QLatin1String("^\\d+$")),
67 m_plugin(PerforcePlugin::perforcePluginInstance())
69 QTC_ASSERT(m_changeNumberPattern.isValid(), /**/);
70 setAnnotateRevisionTextFormat(tr("Annotate change list \"%1\""));
71 if (Perforce::Constants::debug)
72 qDebug() << "PerforceEditor::PerforceEditor" << type->type << type->id;
75 QSet<QString> PerforceEditor::annotationChanges() const
77 QSet<QString> changes;
78 const QString txt = toPlainText();
81 // Hunt for first change number in annotation: "<change>:"
82 QRegExp r(QLatin1String("^(\\d+):"));
83 QTC_ASSERT(r.isValid(), return changes);
84 if (r.indexIn(txt) != -1) {
85 changes.insert(r.cap(1));
86 r.setPattern(QLatin1String("\n(\\d+):"));
87 QTC_ASSERT(r.isValid(), return changes);
89 while ((pos = r.indexIn(txt, pos)) != -1) {
90 pos += r.matchedLength();
91 changes.insert(r.cap(1));
94 if (Perforce::Constants::debug)
95 qDebug() << "PerforceEditor::annotationChanges() returns #" << changes.size();
99 QString PerforceEditor::changeUnderCursor(const QTextCursor &c) const
101 QTextCursor cursor = c;
102 // Any number is regarded as change number.
103 cursor.select(QTextCursor::WordUnderCursor);
104 if (!cursor.hasSelection())
106 const QString change = cursor.selectedText();
107 return m_changeNumberPattern.exactMatch(change) ? change : QString();
110 VCSBase::DiffHighlighter *PerforceEditor::createDiffHighlighter() const
112 const QRegExp filePattern(QLatin1String("^====.*"));
113 return new VCSBase::DiffHighlighter(filePattern);
116 VCSBase::BaseAnnotationHighlighter *PerforceEditor::createAnnotationHighlighter(const QSet<QString> &changes) const
118 return new PerforceAnnotationHighlighter(changes);
121 QString PerforceEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
123 QString errorMessage;
124 const QString diffIndicator = QLatin1String("==== ");
125 const QString diffEndIndicator = QLatin1String(" ====");
126 // Go back chunks. Note that for 'describe', an extra, empty line
128 for (QTextBlock block = inBlock; block.isValid(); block = block.previous()) {
129 QString diffFileName = block.text();
130 if (diffFileName.startsWith(diffIndicator) && diffFileName.endsWith(diffEndIndicator)) {
132 // 1) "==== //depot/.../mainwindow.cpp#2 - /depot/.../mainwindow.cpp ===="
133 // (as created by p4 diff) or
134 // 2) "==== //depot/.../mainwindow.cpp#15 (text) ===="
135 // (as created by p4 describe).
136 diffFileName.remove(0, diffIndicator.size());
137 diffFileName.truncate(diffFileName.size() - diffEndIndicator.size());
138 const int separatorPos = diffFileName.indexOf(QLatin1String(" - "));
139 if (separatorPos == -1) {
140 // ==== depot path (text) ==== (p4 describe)
141 const int blankPos = diffFileName.indexOf(QLatin1Char(' '));
144 diffFileName.truncate(blankPos);
146 // ==== depot path - local path ==== (p4 diff)
147 diffFileName.truncate(separatorPos);
149 // Split off revision "#4"
150 const int revisionPos = diffFileName.lastIndexOf(QLatin1Char('#'));
151 if (revisionPos != -1 && revisionPos < diffFileName.length() - 1)
152 diffFileName.truncate(revisionPos);
153 // Ask plugin to map back
154 const QString fileName = m_plugin->fileNameFromPerforceName(diffFileName.trimmed(), false, &errorMessage);
155 if (fileName.isEmpty())
156 qWarning("%s", qPrintable(errorMessage));
163 QStringList PerforceEditor::annotationPreviousVersions(const QString &v) const
166 const int changeList = v.toInt(&ok);
167 if (!ok || changeList < 2)
168 return QStringList();
169 return QStringList(QString::number(changeList - 1));
172 } // namespace Internal
173 } // namespace Perforce