changeset 29835:a946d742fb97

allow community news window to be opened from command line * libgui/src/community-news.h, libgui/src/community-news.cc: New files with community news widget extracted from main-window.cc. * libgui/src/module.mk: Update. * main-window.h, main-window.cc (main_window::m_community_news_window): Delete member variable and all uses. (main_window::load_and_display_community_news, main_window::display_community_news): Delete. (main_window::show_community_news_signal): New signal. (main_window::main_window): To display community news, emit show_community_news_signal instead of calling load_and_display_community_news. (main_window::construct_news_menu): Use lambda expression in menu action to emit show_community_news_signal. * event-manager.h, event-manager.cc (interpreter_events::show_community_news, event_manager::show_community_news): New functions. (F__event_manager_show_community_news__): New function. * qt-interpreter-events.h, qt-interpreter-events.cc (qt_interpreter_events::show_community_news): New function. qt_interpreter_events::show_community_news_signal): New signal. * octave-qobject.h, octave-qobject.cc (base_qobject::m_community_news): New data member. (base_qobject::community_news_widget, base_qobject::show_community_news): New functions. (base_qobject::base_qobject): Connect qt_interpreter_events show_community_news_signal to base_object show_community_news slot. If creating main_window, also connect main_window show_community_news_signal to base_object show_community_news slot. (base_qobject::start_gui): Connect main_window show_community_news_signal to base_object show_community_news slot. (base_qobject::~base_qobject): Also close m_community_news window and delete object.
author John W. Eaton <jwe@octave.org>
date Fri, 25 Jun 2021 17:27:17 -0400
parents 87925a935c7d
children 56465c0739fa
files libgui/src/community-news.cc libgui/src/community-news.h libgui/src/main-window.cc libgui/src/main-window.h libgui/src/module.mk libgui/src/octave-qobject.cc libgui/src/octave-qobject.h libgui/src/qt-interpreter-events.cc libgui/src/qt-interpreter-events.h libinterp/corefcn/event-manager.cc libinterp/corefcn/event-manager.h
diffstat 11 files changed, 296 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/src/community-news.cc	Fri Jun 25 17:27:17 2021 -0400
@@ -0,0 +1,143 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2011-2021 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <QDesktopWidget>
+#include <QLayout>
+#include <QTextBrowser>
+#include <QThread>
+
+#include "community-news.h"
+#include "gui-preferences-nr.h"
+#include "news-reader.h"
+#include "octave-qobject.h"
+
+namespace octave
+{
+  community_news::community_news (base_qobject& oct_qobj, int serial)
+    : QWidget (nullptr), m_browser (nullptr)
+  {
+    construct (oct_qobj, "https://octave.org", "community-news.html", serial);
+  }
+
+  community_news::community_news (base_qobject& oct_qobj, QWidget *parent,
+                                  const QString& base_url, const QString& page,
+                                  int serial)
+    : QWidget (parent), m_browser (nullptr)
+  {
+    construct (oct_qobj, base_url, page, serial);
+  }
+
+  void community_news::construct (base_qobject& oct_qobj,
+                                  const QString& base_url, const QString& page,
+                                  int serial)
+  {
+    m_browser = new QTextBrowser (this);
+
+    m_browser->setObjectName ("OctaveNews");
+    m_browser->setOpenExternalLinks (true);
+
+    QVBoxLayout *vlayout = new QVBoxLayout;
+
+    vlayout->addWidget (m_browser);
+
+    setLayout (vlayout);
+    setWindowTitle (tr ("Octave Community News"));
+
+    int win_x, win_y;
+    get_screen_geometry (win_x, win_y);
+
+    resize (win_x/2, win_y/2);
+    move ((win_x - width ())/2, (win_y - height ())/2);
+
+    resource_manager& rmgr = oct_qobj.get_resource_manager ();
+    gui_settings *settings = rmgr.get_settings ();
+
+    // FIXME: should be configurable...  See also the icon for the
+    // release notes window.
+    QString icon = ":/actions/icons/logo.png";
+    setWindowIcon (QIcon (icon));
+
+    // FIXME: This is a news reader preference, so shouldn't it be used
+    // in the news_reader object?
+
+    bool connect_to_web
+      = (settings
+         ? settings->value (nr_allow_connection).toBool ()
+         : true);
+
+    QThread *worker_thread = new QThread;
+
+    news_reader *reader = new news_reader (oct_qobj, base_url, page,
+                                           serial, connect_to_web);
+
+    reader->moveToThread (worker_thread);
+
+    connect (reader, &news_reader::display_news_signal,
+             this, &community_news::set_news);
+
+    connect (worker_thread, &QThread::started,
+             reader, &news_reader::process);
+
+    connect (reader, &news_reader::finished, worker_thread, &QThread::quit);
+
+    connect (reader, &news_reader::finished, reader, &news_reader::deleteLater);
+
+    connect (worker_thread, &QThread::finished,
+             worker_thread, &QThread::deleteLater);
+
+    worker_thread->start ();
+  }
+
+  void community_news::set_news (const QString& news)
+  {
+    m_browser->setHtml (news);
+  }
+
+  void community_news::display (void)
+  {
+    if (! isVisible ())
+      show ();
+    else if (isMinimized ())
+      showNormal ();
+
+    raise ();
+    activateWindow ();
+  }
+
+  // FIXME: This function is duplicated in main_window.cc.  Maybe it
+  // should be a utility function?
+
+  void community_news::get_screen_geometry (int& width, int& height)
+  {
+    QRect screen_geometry = QApplication::desktop ()->availableGeometry (this);
+
+    width = screen_geometry.width ();
+    height = screen_geometry.height ();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/src/community-news.h	Fri Jun 25 17:27:17 2021 -0400
@@ -0,0 +1,70 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2011-2021 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if ! defined (octave_community_news_h)
+#define octave_community_news_h 1
+
+#include <QString>
+#include <QWidget>
+
+class QTextBrowser;
+
+namespace octave
+{
+  class base_qobject;
+
+  class community_news : public QWidget
+  {
+    Q_OBJECT
+
+  public:
+
+    community_news (base_qobject& oct_qobj, int serial);
+
+    community_news (base_qobject& oct_qobj, QWidget *parent = nullptr,
+                    const QString& base_url = "https://octave.org",
+                    const QString& page = "community-news.html",
+                    int serial = -1);
+
+    ~community_news (void) = default;
+
+  public slots:
+
+    void set_news (const QString& news);
+
+    void display (void);
+
+  private:
+
+    void construct (base_qobject& oct_qobj, const QString& base_url,
+                    const QString& page, int serial);
+
+    void get_screen_geometry (int& width, int& height);
+
+    QTextBrowser *m_browser;
+  };
+}
+
+#endif
--- a/libgui/src/main-window.cc	Sat Jun 26 07:05:12 2021 -0400
+++ b/libgui/src/main-window.cc	Fri Jun 25 17:27:17 2021 -0400
@@ -101,7 +101,7 @@
       m_external_editor (new external_editor_interface (this, m_octave_qobj)),
       m_active_editor (m_external_editor), m_settings_dlg (nullptr),
       m_find_files_dlg (nullptr), m_set_path_dlg (nullptr),
-      m_release_notes_window (nullptr), m_community_news_window (nullptr),
+      m_release_notes_window (nullptr),
       m_clipboard (QApplication::clipboard ()),
       m_prevent_readline_conflicts (true),
       m_prevent_readline_conflicts_menu (false),
@@ -192,7 +192,7 @@
 
     if (connect_to_web
         && (! last_checked.isValid () || one_day_ago > last_checked))
-      load_and_display_community_news (serial);
+      emit show_community_news_signal (serial);
 
     construct_octave_qt_link ();
 
@@ -217,7 +217,6 @@
     // the functions where they are constructed.
 
     delete m_release_notes_window;
-    delete m_community_news_window;
   }
 
   void main_window::adopt_dock_widgets (void)
@@ -913,96 +912,6 @@
     m_release_notes_window->activateWindow ();
   }
 
-  void main_window::load_and_display_community_news (int serial)
-  {
-    resource_manager& rmgr = m_octave_qobj.get_resource_manager ();
-    gui_settings *settings = rmgr.get_settings ();
-
-    bool connect_to_web
-      = (settings
-         ? settings->value (nr_allow_connection).toBool ()
-         : true);
-
-    QString base_url = "https://octave.org";
-    QString page = "community-news.html";
-
-    QThread *worker_thread = new QThread;
-
-    news_reader *reader = new news_reader (m_octave_qobj, base_url, page,
-                                           serial, connect_to_web);
-
-    reader->moveToThread (worker_thread);
-
-    connect (reader, &news_reader::display_news_signal,
-             this, &main_window::display_community_news);
-
-    connect (worker_thread, &QThread::started,
-             reader, &news_reader::process);
-
-    connect (reader, &news_reader::finished, worker_thread, &QThread::quit);
-
-    connect (reader, &news_reader::finished, reader, &news_reader::deleteLater);
-
-    connect (worker_thread, &QThread::finished,
-             worker_thread, &QThread::deleteLater);
-
-    worker_thread->start ();
-  }
-
-  void main_window::display_community_news (const QString& news)
-  {
-    if (! m_community_news_window)
-      {
-        // We want the window manager to give the community news window
-        // a title bar, so don't its parent to main_window.  Do remember
-        // to delete in the main_window destructor.
-
-        m_community_news_window = new QWidget ();
-
-        QTextBrowser *browser = new QTextBrowser (m_community_news_window);
-
-        browser->setHtml (news);
-        browser->setObjectName ("OctaveNews");
-        browser->setOpenExternalLinks (true);
-
-        QVBoxLayout *vlayout = new QVBoxLayout;
-
-        vlayout->addWidget (browser);
-
-        m_community_news_window->setLayout (vlayout);
-        m_community_news_window->setWindowTitle (tr ("Octave Community News"));
-
-        int win_x, win_y;
-        get_screen_geometry (&win_x, &win_y);
-
-        m_community_news_window->resize (win_x/2, win_y/2);
-        m_community_news_window->move ((win_x - m_community_news_window->width ())/2,
-                                       (win_y - m_community_news_window->height ())/2);
-      }
-    else
-      {
-        // Window already exists, just update the browser contents
-        QTextBrowser *browser
-
-          = m_community_news_window->findChild<QTextBrowser *>("OctaveNews"
-                                                               , Qt::FindDirectChildrenOnly
-                                                              );
-        if (browser)
-          browser->setHtml (news);
-      }
-
-    if (! m_community_news_window->isVisible ())
-      m_community_news_window->show ();
-    else if (m_community_news_window->isMinimized ())
-      m_community_news_window->showNormal ();
-
-    // same icon as release notes
-    m_community_news_window->setWindowIcon (QIcon (m_release_notes_icon));
-
-    m_community_news_window->raise ();
-    m_community_news_window->activateWindow ();
-  }
-
   void main_window::open_bug_tracker_page (void)
   {
     QDesktopServices::openUrl (QUrl ("https://octave.org/bugs.html"));
@@ -2680,8 +2589,14 @@
     m_release_notes_action = add_action (news_menu, QIcon (),
                                          tr ("Release Notes"), SLOT (display_release_notes ()));
 
-    m_current_news_action = add_action (news_menu, QIcon (),
-                                        tr ("Community News"), SLOT (load_and_display_community_news ()));
+    // Currently a special case so we can use a lambda expression.
+    m_current_news_action
+      = news_menu->addAction (QIcon (), tr ("Community News"),
+                              [=] () {
+                                emit show_community_news_signal (-1);
+                              });
+    addAction (m_current_news_action);
+    m_current_news_action->setShortcutContext (Qt::ApplicationShortcut);
   }
 
   void main_window::construct_tool_bar (void)
--- a/libgui/src/main-window.h	Sat Jun 26 07:05:12 2021 -0400
+++ b/libgui/src/main-window.h	Fri Jun 25 17:27:17 2021 -0400
@@ -107,6 +107,8 @@
     void open_file_signal (const QString& file, const QString& enc, int line);
     void step_into_file_signal (void);
 
+    void show_community_news_signal (int serial);
+
     void update_gui_lexer_signal (bool);
 
     void insert_debugger_pointer_signal (const QString& file, int line);
@@ -145,8 +147,6 @@
     void file_remove_proxy (const QString& o, const QString& n);
     void open_online_documentation_page (void);
     void display_release_notes (void);
-    void load_and_display_community_news (int serial = -1);
-    void display_community_news (const QString& news);
     void open_bug_tracker_page (void);
     void open_octave_packages_page (void);
     void open_contribute_page (void);
@@ -423,8 +423,6 @@
 
     QWidget *m_release_notes_window;
 
-    QWidget *m_community_news_window;
-
     QClipboard *m_clipboard;
 
     //! Some class global flags.
--- a/libgui/src/module.mk	Sat Jun 26 07:05:12 2021 -0400
+++ b/libgui/src/module.mk	Fri Jun 25 17:27:17 2021 -0400
@@ -135,6 +135,7 @@
 OCTAVE_GUI_SRC_MOC = \
   %reldir%/moc-external-editor-interface.cc \
   %reldir%/moc-command-widget.cc \
+  %reldir%/moc-community-news.cc \
   %reldir%/moc-dialog.cc \
   %reldir%/moc-documentation-dock-widget.cc \
   %reldir%/moc-documentation.cc \
@@ -188,6 +189,7 @@
 
 noinst_HEADERS += \
   %reldir%/command-widget.h \
+  %reldir%/community-news.h \
   %reldir%/dialog.h \
   %reldir%/octave-dock-widget.h \
   %reldir%/documentation-dock-widget.h \
@@ -253,6 +255,7 @@
 
 %canon_reldir%_%canon_reldir%_la_SOURCES = \
   %reldir%/command-widget.cc \
+  %reldir%/community-news.cc \
   %reldir%/dialog.cc \
   %reldir%/documentation-dock-widget.cc \
   %reldir%/documentation.cc \
--- a/libgui/src/octave-qobject.cc	Sat Jun 26 07:05:12 2021 -0400
+++ b/libgui/src/octave-qobject.cc	Fri Jun 25 17:27:17 2021 -0400
@@ -41,6 +41,7 @@
 #include "QTerminal.h"
 
 #include "command-widget.h"
+#include "community-news.h"
 #include "documentation-dock-widget.h"
 #include "files-dock-widget.h"
 #include "history-dock-widget.h"
@@ -277,6 +278,9 @@
     connect (qt_link (), &qt_interpreter_events::edit_variable_signal,
              this, &base_qobject::show_variable_editor_window);
 
+    connect (qt_link (), &qt_interpreter_events::show_community_news_signal,
+             this, &base_qobject::show_community_news);
+
     if (m_app_context.experimental_terminal_widget ())
       {
         m_qapplication->setQuitOnLastWindowClosed (false);
@@ -287,6 +291,9 @@
           {
             m_main_window = new main_window (*this);
 
+            connect (m_main_window, &main_window::show_community_news_signal,
+                     this, &base_qobject::show_community_news);
+
             if (m_interpreter_ready)
               m_main_window->handle_octave_ready ();
             else
@@ -352,6 +359,9 @@
 
         if (m_variable_editor_widget)
           m_variable_editor_widget->close ();
+
+        if (m_community_news)
+          m_community_news->close ();
       }
     else
       {
@@ -365,6 +375,7 @@
     delete m_workspace_widget;
     delete m_editor_widget;
     delete m_variable_editor_widget;
+    delete m_community_news;
 
     delete m_interpreter_qobj;
     delete m_qsci_tr;
@@ -707,6 +718,15 @@
     return m_variable_editor_widget;
   }
 
+  QPointer<community_news> base_qobject::community_news_widget (int serial)
+  {
+    if (! m_community_news)
+      m_community_news
+        = QPointer<community_news> (new community_news (*this, serial));
+
+    return m_community_news;
+  }
+
   bool base_qobject::confirm_shutdown (void)
   {
     // Currently, we forward to main_window::confirm_shutdown instead of
@@ -736,6 +756,9 @@
         connect (m_main_window, &main_window::close_gui_signal,
                  this, &base_qobject::close_gui);
 
+        connect (m_main_window, &main_window::show_community_news_signal,
+                 this, &base_qobject::show_community_news);
+
         if (m_interpreter_ready)
           m_main_window->handle_octave_ready ();
         else
@@ -855,6 +878,14 @@
        });
   }
 
+  void base_qobject::show_community_news (int serial)
+  {
+    // Ensure widget exists.
+    community_news_widget (serial);
+
+    m_community_news->display ();
+  }
+
   void base_qobject::execute_command (const QString& command)
   {
     emit interpreter_event
--- a/libgui/src/octave-qobject.h	Sat Jun 26 07:05:12 2021 -0400
+++ b/libgui/src/octave-qobject.h	Fri Jun 25 17:27:17 2021 -0400
@@ -40,6 +40,7 @@
 
 namespace octave
 {
+  class community_news;
   class main_window;
   class qt_application;
   class qt_interpreter_events;
@@ -183,6 +184,8 @@
     QPointer<variable_editor>
     variable_editor_widget (main_window *mw = nullptr);
 
+    QPointer<community_news> community_news_widget (int serial = -1);
+
     QThread *main_thread (void) { return m_main_thread; }
 
     // Declared virtual so that a derived class may redefine this
@@ -223,6 +226,8 @@
 
     void handle_variable_editor_update (void);
 
+    void show_community_news (int serial);
+
     void interpreter_ready (void);
 
     void interpreter_event (const fcn_callback& fcn);
@@ -291,6 +296,8 @@
 
     QPointer<variable_editor> m_variable_editor_widget;
 
+    QPointer<community_news> m_community_news;
+
     main_window *m_main_window;
   };
 }
--- a/libgui/src/qt-interpreter-events.cc	Sat Jun 26 07:05:12 2021 -0400
+++ b/libgui/src/qt-interpreter-events.cc	Fri Jun 25 17:27:17 2021 -0400
@@ -286,6 +286,11 @@
     emit show_workspace_signal ();
   }
 
+  void qt_interpreter_events::show_community_news (int serial)
+  {
+    emit show_community_news_signal (serial);
+  }
+
   bool qt_interpreter_events::edit_file (const std::string& file)
   {
     emit edit_file_signal (QString::fromStdString (file));
--- a/libgui/src/qt-interpreter-events.h	Sat Jun 26 07:05:12 2021 -0400
+++ b/libgui/src/qt-interpreter-events.h	Fri Jun 25 17:27:17 2021 -0400
@@ -127,6 +127,8 @@
 
     void show_workspace (void);
 
+    void show_community_news (int serial);
+
     bool edit_file (const std::string& file);
 
     void edit_variable (const std::string& name, const octave_value& val);
@@ -279,6 +281,8 @@
 
     void show_workspace_signal (void);
 
+    void show_community_news_signal (int serial);
+
     // Note: this signal currently not used by the old terminal widget.
     void interpreter_output_signal (const QString& msg);
 
--- a/libinterp/corefcn/event-manager.cc	Sat Jun 26 07:05:12 2021 -0400
+++ b/libinterp/corefcn/event-manager.cc	Fri Jun 25 17:27:17 2021 -0400
@@ -721,6 +721,19 @@
   return ovl ();
 }
 
+DEFMETHOD (__event_manager_show_community_news__, interp, , ,
+           doc: /* -*- texinfo -*-
+@deftypefn {} {} __event_manager_show_community_news__ ()
+Undocumented internal function.
+@end deftypefn */)
+{
+  octave::event_manager& evmgr = interp.get_event_manager ();
+
+  evmgr.show_community_news ();
+
+  return ovl ();
+}
+
 DEFMETHOD (__event_manager_gui_status_update__, interp, args, ,
            doc: /* -*- texinfo -*-
 @deftypefn {} {} __event_manager_gui_status_update__ (@var{feature}, @var{status})
--- a/libinterp/corefcn/event-manager.h	Sat Jun 26 07:05:12 2021 -0400
+++ b/libinterp/corefcn/event-manager.h	Fri Jun 25 17:27:17 2021 -0400
@@ -161,6 +161,8 @@
 
     virtual void show_workspace (void) { }
 
+    virtual void show_community_news (int /*serial*/) { }
+
     virtual bool edit_file (const std::string& /*file*/) { return false; }
 
     virtual void
@@ -485,6 +487,12 @@
         instance->show_workspace ();
     }
 
+    void show_community_news (int serial = -1)
+    {
+      if (enabled ())
+        instance->show_community_news (serial);
+    }
+
     bool edit_file (const std::string& file)
     {
       return enabled () ? instance->edit_file (file) : false;