OSDN Git Service

VCS: Add a 'Apply patch chunk' pairing 'Revert chunk' to VCS editor.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Fri, 12 Aug 2011 11:42:21 +0000 (13:42 +0200)
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>
Fri, 12 Aug 2011 11:45:25 +0000 (13:45 +0200)
Fix "Open With" editor-by-mimetype search to return all (diff) editors.

Change-Id: I8d9d3cee9e5fcee5555d6e301818ed22ad4390ac
Reviewed-on: http://codereview.qt.nokia.com/2912
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
src/plugins/coreplugin/editormanager/editormanager.cpp
src/plugins/vcsbase/vcsbaseeditor.cpp
src/plugins/vcsbase/vcsbaseeditor.h

index e05ed77..c7f293f 100644 (file)
@@ -1039,7 +1039,6 @@ static void mimeTypeFactoryRecursion(const MimeDatabase *db,
             list->push_back(*fit);
             if (firstMatchOnly)
                 return;
-            break;
         }
     }
     // Any parent mime type classes? -> recurse
index dfbe558..b61aa9a 100644 (file)
@@ -122,6 +122,26 @@ QByteArray DiffChunk::asPatch() const
     return rc;
 }
 
+namespace Internal {
+
+// Data to be passed to apply/revert diff chunk actions.
+class DiffChunkAction
+{
+public:
+    DiffChunkAction(const DiffChunk &dc = DiffChunk(), bool revertIn = false) :
+        chunk(dc), revert(revertIn) {}
+
+    DiffChunk chunk;
+    bool revert;
+};
+
+} // namespace Internal
+} // VCSBase
+
+Q_DECLARE_METATYPE(VCSBase::Internal::DiffChunkAction)
+
+namespace VCSBase {
+
 /*!
     \class VCSBase::VCSBaseEditor
 
@@ -554,11 +574,23 @@ void VCSBaseEditorWidget::contextMenuEvent(QContextMenuEvent *e)
         connect(menu->addAction(tr("Send to CodePaster...")), SIGNAL(triggered()),
                 this, SLOT(slotPaste()));
         menu->addSeparator();
-        QAction *revertAction = menu->addAction(tr("Revert Chunk..."));
+        // Apply/revert diff chunk.
         const DiffChunk chunk = diffChunk(cursorForPosition(e->pos()));
-        revertAction->setEnabled(canRevertDiffChunk(chunk));
-        revertAction->setData(qVariantFromValue(chunk));
-        connect(revertAction, SIGNAL(triggered()), this, SLOT(slotRevertDiffChunk()));
+        const bool canApply = canApplyDiffChunk(chunk);
+        // Apply a chunk from a diff loaded into the editor. This typically will
+        // not have the 'source' property set and thus will only work if the working
+        // directory matches that of the patch (see findDiffFile()). In addition,
+        // the user has "Open With" and choose the right diff editor so that
+        // fileNameFromDiffSpecification() works.
+        QAction *applyAction = menu->addAction(tr("Apply Chunk..."));
+        applyAction->setEnabled(canApply);
+        applyAction->setData(qVariantFromValue(Internal::DiffChunkAction(chunk, false)));
+        connect(applyAction, SIGNAL(triggered()), this, SLOT(slotApplyDiffChunk()));
+        // Revert a chunk from a VCS diff, which might be linked to reloading the diff.
+        QAction *revertAction = menu->addAction(tr("Revert Chunk..."));
+        revertAction->setEnabled(isRevertDiffChunkEnabled() && canApply);
+        revertAction->setData(qVariantFromValue(Internal::DiffChunkAction(chunk, true)));
+        connect(revertAction, SIGNAL(triggered()), this, SLOT(slotApplyDiffChunk()));
     }
         break;
     default:
@@ -1073,34 +1105,40 @@ void VCSBaseEditorWidget::setRevertDiffChunkEnabled(bool e)
     d->m_revertChunkEnabled = e;
 }
 
-bool VCSBaseEditorWidget::canRevertDiffChunk(const DiffChunk &dc) const
+bool VCSBaseEditorWidget::canApplyDiffChunk(const DiffChunk &dc) const
 {
-    if (!isRevertDiffChunkEnabled() || !dc.isValid())
+    if (!dc.isValid())
         return false;
     const QFileInfo fi(dc.fileName);
     // Default implementation using patch.exe relies on absolute paths.
     return fi.isFile() && fi.isAbsolute() && fi.isWritable();
 }
 
-// Default implementation of revert: Revert a chunk by piping it into patch
-// with '-R', assuming we got absolute paths from the VCS plugins.
-bool VCSBaseEditorWidget::revertDiffChunk(const DiffChunk &dc) const
+// Default implementation of revert: Apply a chunk by piping it into patch,
+// (passing '-R' for revert), assuming we got absolute paths from the VCS plugins.
+bool VCSBaseEditorWidget::applyDiffChunk(const DiffChunk &dc, bool revert) const
 {
-    return VCSBasePlugin::runPatch(dc.asPatch(), QString(), 0, true);
+    return VCSBasePlugin::runPatch(dc.asPatch(), QString(), 0, revert);
 }
 
-void VCSBaseEditorWidget::slotRevertDiffChunk()
+void VCSBaseEditorWidget::slotApplyDiffChunk()
 {
     const QAction *a = qobject_cast<QAction *>(sender());
     QTC_ASSERT(a, return ; )
-    const DiffChunk chunk = qvariant_cast<DiffChunk>(a->data());
-    if (QMessageBox::No == QMessageBox::question(this, tr("Revert Chunk"),
-                                                  tr("Would you like to revert the chunk?"),
-                                                  QMessageBox::Yes|QMessageBox::No))
+    const Internal::DiffChunkAction chunkAction = qvariant_cast<Internal::DiffChunkAction>(a->data());
+    const QString title = chunkAction.revert ? tr("Revert Chunk") : tr("Apply Chunk");
+    const QString question = chunkAction.revert ?
+        tr("Would you like to revert the chunk?") : tr("Would you like to apply the chunk?");
+    if (QMessageBox::No == QMessageBox::question(this, title, question, QMessageBox::Yes|QMessageBox::No))
         return;
 
-    if (revertDiffChunk(chunk))
-        emit diffChunkReverted(chunk);
+    if (applyDiffChunk(chunkAction.chunk, chunkAction.revert)) {
+        if (chunkAction.revert) {
+            emit diffChunkReverted(chunkAction.chunk);
+        } else {
+            emit diffChunkApplied(chunkAction.chunk);
+        }
+    }
 }
 
 // Tagging of editors for re-use.
index 4074503..92184f6 100644 (file)
@@ -199,6 +199,7 @@ signals:
     // for LogOutput/AnnotateOutput content types.
     void describeRequested(const QString &source, const QString &change);
     void annotateRevisionRequested(const QString &source, const QString &change, int lineNumber);
+    void diffChunkApplied(const VCSBase::DiffChunk &dc);
     void diffChunkReverted(const VCSBase::DiffChunk &dc);
 
 public slots:
@@ -226,7 +227,7 @@ private slots:
     void slotDiffCursorPositionChanged();
     void slotAnnotateRevision();
     void slotCopyRevision();
-    void slotRevertDiffChunk();
+    void slotApplyDiffChunk();
     void slotPaste();
 
 protected:
@@ -235,9 +236,9 @@ protected:
      * source and version control. */
     QString findDiffFile(const QString &f, Core::IVersionControl *control = 0) const;
 
-    virtual bool canRevertDiffChunk(const DiffChunk &dc) const;
+    virtual bool canApplyDiffChunk(const DiffChunk &dc) const;
     // Revert a patch chunk. Default implementation uses patch.exe
-    virtual bool revertDiffChunk(const DiffChunk &dc) const;
+    virtual bool applyDiffChunk(const DiffChunk &dc, bool revert = false) const;
 
 private:
     // Implement to return a set of change identifiers in