diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index e5c5a6a4a85a166fe8528a8284be6438ca03bc99..e4e534d6a385b97a59384df31fc755025ba64075 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -439,6 +439,32 @@ def findFirstZero(p, max):
         p = p + 1
     return -1
 
+
+def extractCharArray(p, maxsize):
+    t = gdb.lookup_type("unsigned char").pointer()
+    p = p.cast(t)
+    i = findFirstZero(p, maxsize)
+    limit = select(i < 0, maxsize, i)
+    s = ""
+    for i in xrange(limit):
+        s += "%c" % int(p.dereference())
+        p += 1
+    if i == maxsize:
+        s += "..."
+    return s
+
+def extractByteArray(value):
+    d_ptr = value['d'].dereference()
+    data = d_ptr['data']
+    size = d_ptr['size']
+    alloc = d_ptr['alloc']
+    check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
+    checkRef(d_ptr["ref"])
+    if size > 0:
+        checkAccess(data, 4)
+        checkAccess(data + size) == 0
+    return extractCharArray(data, 100)
+
 def encodeCharArray(p, maxsize, size = -1):
     t = gdb.lookup_type("unsigned char").pointer()
     p = p.cast(t)
@@ -803,6 +829,8 @@ SalCommand()
 #
 #######################################################################
 
+StopDisplay, DisplayImage1, DisplayString, DisplayImage, DisplayProcess = range(5)
+
 class Dumper:
     def __init__(self):
         self.output = ""
@@ -907,6 +935,14 @@ class Dumper:
             str = encodeString(value)
             self.put('valueencoded="%d",value="%s",' % (7, str))
 
+    def putDisplay(self, format, value = None, cmd = None):
+        self.put('editformat="%s",' % format)
+        if cmd is None:
+            if not value is None:
+                self.put('editvalue="%s",' % value)
+        else:
+            self.put('editvalue="%s|%s",' % (cmd, value))
+
     def putByteArrayValue(self, value):
         str = encodeByteArray(value)
         self.put('valueencoded="%d",value="%s",' % (6, str))
diff --git a/share/qtcreator/gdbmacros/gdbmacros.py b/share/qtcreator/gdbmacros/gdbmacros.py
index 7255fed290ec09b57b913aee8c58e46602732520..b7769c3c9302d26c19cf4a43ad7c07a137d7655d 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.py
+++ b/share/qtcreator/gdbmacros/gdbmacros.py
@@ -406,7 +406,7 @@ def qdump__QImage(d, item):
         d.endChildren()
     format = d.itemFormat(item)
     if format == 0:
-        d.putField("editformat", 0)  # Magic marker for "delete widget"
+        d.putDisplay(StopDisplay)
     elif format == 1:
         if False:
             # Take four bytes at a time, this is critical for performance.
@@ -428,11 +428,8 @@ def qdump__QImage(d, item):
             p = bits.cast(gdb.lookup_type("unsigned char").pointer())
             gdb.execute("dump binary memory %s %s %s" %
                 (filename, cleanAddress(p), cleanAddress(p + nbytes)))
-            d.putField("editformat", 3)  # Magic marker for external "QImage" data.
-            d.beginItem("editvalue")
-            d.put(" %d %d %d %s" % (d_ptr["width"], d_ptr["height"],
-                d_ptr["format"], filename))
-            d.endItem()
+            d.putDisplay(DisplayImage, " %d %d %d %s"
+                % (d_ptr["width"], d_ptr["height"], d_ptr["format"], filename))
 
 
 def qdump__QLinkedList(d, item):
@@ -1979,3 +1976,26 @@ def qdump__TLitC(d, item):
     d.putNumChild(0)
     d.putValue(encodeSymbianString(base, size), "7")
 
+
+#######################################################################
+#
+# Display Test
+#
+#######################################################################
+
+if False:
+    def qdump__Function(d, item):
+        min = item.value["min"]
+        max = item.value["max"]
+        var = extractByteArray(item.value["var"])
+        f = extractByteArray(item.value["f"])
+        d.putValue("%s, %s=%f..%f" % (f, var, min, max))
+        d.putNumChild(0)
+        d.putField("typeformats", "Normal,Displayed");
+        format = d.itemFormat(item)
+        if format == 0:
+            d.putDisplay(StopDisplay)
+        elif format == 1:
+            input = "plot [%s=%f:%f] %s" % (var, min, max, f)
+            d.putDisplay(DisplayProcess, input, "gnuplot")
+
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index b8c0f1e64fc38bd7cf8e4c1b8371efd670396d2f..d046c9fcedfb57aca4e4b255ab8ff1ad4fa6770a 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -42,6 +42,7 @@
 #include <QtCore/QDebug>
 #include <QtCore/QEvent>
 #include <QtCore/QFile>
+#include <QtCore/QProcess>
 #include <QtCore/QTextStream>
 #include <QtCore/QTimer>
 #include <QtCore/QtAlgorithms>
@@ -1209,12 +1210,12 @@ void WatchHandler::cleanup()
     m_watchers->m_fetchTriggered.clear();
     m_tooltips->m_fetchTriggered.clear();
 #if 1
-    for (EditWindows::ConstIterator it = m_editWindows.begin();
-            it != m_editWindows.end(); ++it) {
+    for (EditHandlers::ConstIterator it = m_editHandlers.begin();
+            it != m_editHandlers.end(); ++it) {
         if (!it.value().isNull())
             delete it.value();
     }
-    m_editWindows.clear();
+    m_editHandlers.clear();
 #endif
 }
 
@@ -1348,21 +1349,21 @@ static void swapEndian(char *d, int nchar)
 
 void WatchHandler::showEditValue(const WatchData &data)
 {
-    QWidget *w = m_editWindows.value(data.iname);
+    QObject *w = m_editHandlers.value(data.iname);
     if (data.editformat == 0x0) {
-        m_editWindows.remove(data.iname);
+        m_editHandlers.remove(data.iname);
         delete w;
-    } else if (data.editformat == 0x1 || data.editformat == 0x3) {
+    } else if (data.editformat == 1 || data.editformat == 3) {
         // QImage
         if (!w) {
             w = new QLabel;
-            m_editWindows[data.iname] = w;
+            m_editHandlers[data.iname] = w;
         }
         if (QLabel *l = qobject_cast<QLabel *>(w)) {
             int width, height, format;
             QByteArray ba;
             uchar *bits;
-            if (data.editformat == 0x1) {
+            if (data.editformat == 1) {
                 ba = QByteArray::fromHex(data.editvalue);
                 const int *header = (int *)(ba.data());
                 swapEndian(ba.data(), ba.size());
@@ -1370,7 +1371,7 @@ void WatchHandler::showEditValue(const WatchData &data)
                 width = header[0];
                 height = header[1];
                 format = header[2];
-            } else { // data.editformat == 0x3
+            } else { // data.editformat == 3
                 QTextStream ts(data.editvalue);
                 QString fileName;
                 ts >> width >> height >> format >> fileName;
@@ -1384,11 +1385,11 @@ void WatchHandler::showEditValue(const WatchData &data)
             l->resize(width, height);
             l->show();
         }
-    } else if (data.editformat == 0x2) {
+    } else if (data.editformat == 2) {
         // QString
         if (!w) {
             w = new QTextEdit;
-            m_editWindows[data.iname] = w;
+            m_editHandlers[data.iname] = w;
         }
         QByteArray ba = QByteArray::fromHex(data.editvalue);
         QString str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2);
@@ -1398,6 +1399,19 @@ void WatchHandler::showEditValue(const WatchData &data)
             t->resize(400, 200);
             t->show();
         }
+    } else if (data.editformat == 4) {
+        // Generic Process.
+        int pos = data.editvalue.indexOf('|');
+        QByteArray cmd = data.editvalue.left(pos);
+        QByteArray input = data.editvalue.mid(pos + 1);
+        QProcess *p = qobject_cast<QProcess *>(w);
+        if (!p) {
+            p = new QProcess;
+            p->start(cmd);
+            p->waitForStarted();
+            m_editHandlers[data.iname] = p;
+        }
+        p->write(input + "\n");
     } else {
         QTC_ASSERT(false, qDebug() << "Display format: " << data.editformat);
     }
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index e2f4ddf0f930c73e14d1aa9d5c429f3c7efdd5fb..d6b26ef6bdf83cb9c0ad010609936d8c9343e2a1 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -282,14 +282,17 @@ private:
     bool m_expandPointers;
     bool m_inChange;
 
-    typedef QMap<QString, QPointer<QWidget> > EditWindows;
-    EditWindows m_editWindows;
+    // QWidgets and QProcesses taking care of special displays.
+    typedef QMap<QString, QPointer<QObject> > EditHandlers;
+    EditHandlers m_editHandlers;
 
     QHash<QByteArray, int> m_watcherNames;
     QByteArray watcherName(const QByteArray &exp);
     QHash<QString, int> m_typeFormats;
     QHash<QString, int> m_individualFormats;
-    QSet<QByteArray> m_expandedINames;  // Those expanded in the treeview.
+
+    // Items expanded in the Locals & Watchers view.
+    QSet<QByteArray> m_expandedINames; 
 
     WatchModel *m_locals;
     WatchModel *m_watchers;
diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp
index 18540d2cfb37eb9385ac7a3c8f15bceebfb7e5e4..36b3940701efc55f617b85d241e42236c995120a 100644
--- a/tests/manual/gdbdebugger/simple/app.cpp
+++ b/tests/manual/gdbdebugger/simple/app.cpp
@@ -361,6 +361,28 @@ void testQImage()
     pain.end();
 }
 
+struct Function
+{
+    Function(QByteArray var, QByteArray f, double min, double max)
+      : var(var), f(f), min(min), max(max) {}
+    QByteArray var;
+    QByteArray f;
+    double min;
+    double max;
+};
+
+void testFunction()
+{
+    Function func("x", "sin(x)", 0, 1);
+    func.max = 10;
+    func.f = "cos(x)";
+    func.max = 4;
+    func.max = 5;
+    func.max = 6;
+    func.max = 7;
+    func.max = 8;
+}
+
 void testIO()
 {
     qDebug() << "qDebug() 1";
@@ -1467,6 +1489,7 @@ int main(int argc, char *argv[])
     list2 << 0;
 
     testQStandardItemModel();
+    testFunction();
     testQImage();
     testNoArgumentName(1, 2, 3);
     testIO();