Repository: spyder-ide/spyder

Issue:
Add a "Copy to clipboard" button to the "About Spyder" window
## New Feature Description

I propose that we add a `Copy to clipboard` button in the `About Spyder` dialog window, like we have already in the `Dependencies` dialog window.

I suggest that we copy the information with already the right format so that those can be copied directly in the `Version` section of our issue template.

* Spyder version: 
* Python version: 
* Qt version: 
* PyQt version: 
* Operating System name/version: 
 
![image](https://user-images.githubusercontent.com/10170372/45179757-65e70200-b1e7-11e8-9971-af5b4b6cc481.png)



Discussion:
I think this would be much better than what have now.

To simplify things further could we have the about copy button pull in the dependencies as well. then there is only one instruction: click button in about, then paste here.
I agree with this change too.

Resolving patch:
diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py
--- a/spyder/app/mainwindow.py
+++ b/spyder/app/mainwindow.py
@@ -1150,7 +1150,7 @@ def add_ipm_action(text, path):
         about_action = create_action(self,
                                 _("About %s...") % "Spyder",
                                 icon=ima.icon('MessageBoxInformation'),
-                                triggered=self.about)
+                                triggered=self.show_about)
         self.help_menu_actions += [MENU_SEPARATOR, about_action]
 
         # Status bar widgets
@@ -2672,123 +2672,11 @@ def add_to_toolbar(self, toolbar, widget):
             add_actions(toolbar, actions)
 
     @Slot()
-    def about(self):
-        """Create About Spyder dialog with general information."""
-        versions = get_versions()
-        # Show Git revision for development version
-        revlink = ''
-        if versions['revision']:
-            rev = versions['revision']
-            revlink = " (<a href='https://github.com/spyder-ide/spyder/"\
-                      "commit/%s'>Commit: %s</a>)" % (rev, rev)
-
-        # Get current font properties
-        font = self.font()
-        font_family = font.family()
-        font_size = font.pointSize()
-        if sys.platform == 'darwin':
-            font_size -= 2
-
-        msgBox = QMessageBox(self)
-        msgBox.setText(
-            """
-            <div style='font-family: "{font_family}";
-                        font-size: {font_size}pt;
-                        font-weight: normal;
-                        '>
-            <p>
-            <b>Spyder {spyder_ver}</b> {revision}
-            <br>
-            The Scientific Python Development Environment |
-            <a href="{website_url}">Spyder-IDE.org</a>
-            <br>
-            Copyright &copy; 2009-2019 Spyder Project Contributors and
-            <a href="{github_url}/blob/master/AUTHORS.txt">others</a>.
-            <br>
-            Distributed under the terms of the
-            <a href="{github_url}/blob/master/LICENSE.txt">MIT License</a>.
-            </p>
-            <p>
-            Created by Pierre Raybaut; current maintainer is Carlos Cordoba.
-            Developed by the
-            <a href="{github_url}/graphs/contributors">international
-            Spyder community</a>. Many thanks to all the Spyder beta testers
-            and dedicated users.
-            </p>
-            <p>For help with Spyder errors and crashes, please read our
-            <a href="{trouble_url}">Troubleshooting Guide</a>, and for bug
-            reports and feature requests, visit our
-            <a href="{github_url}">Github site</a>. For project discussion,
-            see our <a href="{forum_url}">Google Group</a>.
-            </p>
-            <p>
-            This project is part of a larger effort to promote and
-            facilitate the use of Python for scientific and engineering
-            software development.
-            The popular Python distributions
-            <a href="https://www.anaconda.com/download/">Anaconda</a> and
-            <a href="https://winpython.github.io/">WinPython</a>
-            also contribute to this plan.
-            </p>
-            <p>
-            Python {python_ver} {bitness}-bit | Qt {qt_ver} |
-            {qt_api} {qt_api_ver} | {os_name} {os_ver}
-            </p>
-            <p><small>Certain source files under other compatible permissive
-            licenses and/or originally by other authors.
-            Spyder 3 theme icons derived from
-            <a href="https://fontawesome.com/">Font Awesome</a> 4.7
-            (&copy; 2016 David Gandy; SIL OFL 1.1) and
-            <a href="http://materialdesignicons.com/">Material Design</a>
-            (&copy; 2014 Austin Andrews; SIL OFL 1.1).
-            Most Spyder 2 theme icons sourced from the
-            <a href="https://www.everaldo.com">Crystal Project iconset</a>
-            (&copy; 2006-2007 Everaldo Coelho; LGPL 2.1+).
-            Other icons from
-            <a href="http://p.yusukekamiyamane.com/">Yusuke Kamiyamane</a>
-            (&copy; 2013 Yusuke Kamiyamane; CC-BY 3.0),
-            the <a href="http://www.famfamfam.com/lab/icons/silk/">FamFamFam
-            Silk icon set</a> 1.3 (&copy; 2006 Mark James; CC-BY 2.5), and
-            the <a href="https://www.kde.org/">KDE Oxygen icons</a>
-            (&copy; 2007 KDE Artists; LGPL 3.0+).</small>
-            </p>
-            <p>
-            See the <a href="{github_url}/blob/master/NOTICE.txt">NOTICE</a>
-            file for full legal information.
-            </p>
-            </div>
-            """.format(
-                spyder_ver=versions['spyder'],
-                revision=revlink,
-                website_url=__website_url__,
-                github_url=__project_url__,
-                trouble_url=__trouble_url__,
-                forum_url=__forum_url__,
-                python_ver=versions['python'],
-                bitness=versions['bitness'],
-                qt_ver=versions['qt'],
-                qt_api=versions['qt_api'],
-                qt_api_ver=versions['qt_api_ver'],
-                os_name=versions['system'],
-                os_ver=versions['release'],
-                font_family=font_family,
-                font_size=font_size,
-            )
-        )
-        msgBox.setWindowTitle(_("About %s") % "Spyder")
-        msgBox.setStandardButtons(QMessageBox.Ok)
-
-        from spyder.config.gui import is_dark_interface
-        if is_dark_interface():
-            icon_filename = "spyder.svg"
-        else:
-            icon_filename = "spyder_dark.svg"
-        app_icon = QIcon(get_image_path(icon_filename))
-        msgBox.setIconPixmap(app_icon.pixmap(QSize(64, 64)))
-
-        msgBox.setTextInteractionFlags(
-            Qt.LinksAccessibleByMouse | Qt.TextSelectableByMouse)
-        msgBox.exec_()
+    def show_about(self):
+        """Show About Spyder dialog box"""
+        from spyder.widgets.about import AboutDialog
+        abt = AboutDialog(self)
+        abt.exec_()
 
     @Slot()
     def show_dependencies(self):
diff --git a/spyder/widgets/about.py b/spyder/widgets/about.py
new file mode 100644
--- /dev/null
+++ b/spyder/widgets/about.py
@@ -0,0 +1,205 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright © Spyder Project Contributors
+# Licensed under the terms of the MIT License
+# (see spyder/__init__.py for details)
+
+"""Module serving the "About Spyder" function"""
+
+# Standard library imports
+import sys
+
+# Third party imports
+from qtpy.QtCore import Qt
+from qtpy.QtGui import QPixmap
+from qtpy.QtWidgets import (QApplication, QDialog, QDialogButtonBox,
+                            QHBoxLayout, QVBoxLayout, QLabel, QPushButton, )
+
+# Local imports
+from spyder import (__project_url__, __forum_url__,
+                    __trouble_url__, __website_url__, get_versions)
+from spyder.config.base import _
+from spyder.config.base import get_image_path
+from spyder.config.gui import is_dark_interface
+from spyder.utils import icon_manager as ima
+
+
+class AboutDialog(QDialog):
+
+    def __init__(self, parent):
+        """Create About Spyder dialog with general information."""
+
+        QDialog.__init__(self, parent)
+        versions = get_versions()
+        # Show Git revision for development version
+        revlink = ''
+        if versions['revision']:
+            rev = versions['revision']
+            revlink = " (<a href='https://github.com/spyder-ide/spyder/" \
+                      "commit/%s'>Commit: %s</a>)" % (rev, rev)
+
+        # Get current font properties
+        font = self.font()
+        font_family = font.family()
+        font_size = font.pointSize()
+        if sys.platform == 'darwin':
+            font_size -= 2
+
+        self.label = QLabel(_(
+            """
+            <div style='font-family: "{font_family}";
+                        font-size: {font_size}pt;
+                        font-weight: normal;
+                        '>
+            <p>
+            <b>Spyder {spyder_ver}</b> {revision}
+            <br>
+            The Scientific Python Development Environment |
+            <a href="{website_url}">Spyder-IDE.org</a>
+            <br>
+            Copyright &copy; 2009-2020 Spyder Project Contributors and
+            <a href="{github_url}/blob/master/AUTHORS.txt">others</a>.
+            <br>
+            Distributed under the terms of the
+            <a href="{github_url}/blob/master/LICENSE.txt">MIT License</a>.
+            </p>
+            <p>
+            Created by Pierre Raybaut; current maintainer is Carlos Cordoba.
+            Developed by the
+            <a href="{github_url}/graphs/contributors">international
+            Spyder community</a>. Many thanks to all the Spyder beta testers
+            and dedicated users.
+            </p>
+            <p>For help with Spyder errors and crashes, please read our
+            <a href="{trouble_url}">Troubleshooting Guide</a>, and for bug
+            reports and feature requests, visit our
+            <a href="{github_url}">Github site</a>. For project discussion,
+            see our <a href="{forum_url}">Google Group</a>.
+            </p>
+            <p>
+            This project is part of a larger effort to promote and
+            facilitate the use of Python for scientific and engineering
+            software development.
+            The popular Python distributions
+            <a href="https://www.anaconda.com/download/">Anaconda</a> and
+            <a href="https://winpython.github.io/">WinPython</a>
+            also contribute to this plan.
+            </p>
+            <p>
+            Python {python_ver} {bitness}-bit | Qt {qt_ver} |
+            {qt_api} {qt_api_ver} | {os_name} {os_ver}
+            </p>
+            <p><small>Certain source files under other compatible permissive
+            licenses and/or originally by other authors.
+            Spyder 3 theme icons derived from
+            <a href="https://fontawesome.com/">Font Awesome</a> 4.7
+            (&copy; 2016 David Gandy; SIL OFL 1.1) and
+            <a href="http://materialdesignicons.com/">Material Design</a>
+            (&copy; 2014 Austin Andrews; SIL OFL 1.1).
+            Most Spyder 2 theme icons sourced from the
+            <a href="https://www.everaldo.com">Crystal Project iconset</a>
+            (&copy; 2006-2007 Everaldo Coelho; LGPL 2.1+).
+            Other icons from
+            <a href="http://p.yusukekamiyamane.com/">Yusuke Kamiyamane</a>
+            (&copy; 2013 Yusuke Kamiyamane; CC-BY 3.0),
+            the <a href="http://www.famfamfam.com/lab/icons/silk/">FamFamFam
+            Silk icon set</a> 1.3 (&copy; 2006 Mark James; CC-BY 2.5), and
+            the <a href="https://www.kde.org/">KDE Oxygen icons</a>
+            (&copy; 2007 KDE Artists; LGPL 3.0+).</small>
+            </p>
+            <p>
+            See the <a href="{github_url}/blob/master/NOTICE.txt">NOTICE</a>
+            file for full legal information.
+            </p>
+            </div>
+            """.format(
+                spyder_ver=versions['spyder'],
+                revision=revlink,
+                website_url=__website_url__,
+                github_url=__project_url__,
+                trouble_url=__trouble_url__,
+                forum_url=__forum_url__,
+                python_ver=versions['python'],
+                bitness=versions['bitness'],
+                qt_ver=versions['qt'],
+                qt_api=versions['qt_api'],
+                qt_api_ver=versions['qt_api_ver'],
+                os_name=versions['system'],
+                os_ver=versions['release'],
+                font_family=font_family,
+                font_size=font_size,
+            )
+        ))
+        self.label.setWordWrap(True)
+        self.label.setAlignment(Qt.AlignTop)
+        self.label.setOpenExternalLinks(True)
+
+        if is_dark_interface():
+            icon_filename = "spyder.svg"
+        else:
+            icon_filename = "spyder_dark.svg"
+
+        pixmap = QPixmap(get_image_path(icon_filename))
+        self.label_pic = QLabel(self)
+        self.label_pic.setPixmap(pixmap.scaled(64, 64))
+        self.label_pic.setAlignment(Qt.AlignTop)
+
+        btn = QPushButton(_("Copy to clipboard"), )
+        bbox = QDialogButtonBox(QDialogButtonBox.Ok)
+
+        # Widget setup
+        self.setWindowIcon(ima.icon('tooloptions'))
+        self.setModal(True)
+
+        # Layout
+        tophlayout = QHBoxLayout()
+        tophlayout.addWidget(self.label_pic)
+        tophlayout.addWidget(self.label)
+
+        btmhlayout = QHBoxLayout()
+        btmhlayout.addWidget(btn)
+        btmhlayout.addStretch()
+        btmhlayout.addWidget(bbox)
+
+        vlayout = QVBoxLayout()
+        vlayout.addLayout(tophlayout)
+        vlayout.addLayout(btmhlayout)
+
+        self.setLayout(vlayout)
+        self.setFixedSize(410, 560)
+
+        # Signals
+        btn.clicked.connect(self.copy_to_clipboard)
+        bbox.accepted.connect(self.accept)
+
+    def copy_to_clipboard(self):
+        versions = get_versions()
+        QApplication.clipboard().setText(
+            "* Spyder version: {spyder_ver} {revision}\n"
+            "* Python version: {python_ver} {bitness}-bit\n"
+            "* Qt version: {qt_ver}\n"
+            "* {qt_api} version: {qt_api_ver}\n"
+            "* Operating System: {os_name} {os_ver}".format(
+                spyder_ver=versions['spyder'],
+                revision=versions['revision'],
+                python_ver=versions['python'],
+                bitness=versions['bitness'],
+                qt_ver=versions['qt'],
+                qt_api=versions['qt_api'],
+                qt_api_ver=versions['qt_api_ver'],
+                os_name=versions['system'],
+                os_ver=versions['release']))
+
+
+def test():
+    """Run about widget test"""
+
+    from spyder.utils.qthelpers import qapplication
+    qapplication()
+    abt = AboutDialog(None)
+    abt.show()
+    sys.exit(abt.exec_())
+
+
+if __name__ == '__main__':
+    test()


Test patch:
diff --git a/.github/scripts/modules_test.sh b/.github/scripts/modules_test.sh
--- a/.github/scripts/modules_test.sh
+++ b/.github/scripts/modules_test.sh
@@ -46,6 +46,9 @@ for f in spyder/*/*.py; do
     if [[ $f == spyder/widgets/switcher.py ]]; then
         continue
     fi
+    if [[ $f == spyder/widgets/about.py ]]; then
+    continue
+    fi
     python "$f"
     if [ $? -ne 0 ]; then
         exit 1