# HG changeset patch
# User Markus Mützel <markus.muetzel@gmx.de>
# Date 1629630233 -7200
#      Sun Aug 22 13:03:53 2021 +0200
# Node ID eccca1b14ea82bf9bde8af3a4c03f5198b5512dc
# Parent  06f4e4d986a1b73f1f075b56ad3a105e974b9748
WIP: event manager dialogs and uigetfile position (bug #60980).

diff -r 06f4e4d986a1 -r eccca1b14ea8 libgui/src/qt-interpreter-events.h
--- a/libgui/src/qt-interpreter-events.h	Sat Aug 21 21:45:19 2021 -0400
+++ b/libgui/src/qt-interpreter-events.h	Sun Aug 22 13:03:53 2021 +0200
@@ -86,6 +86,8 @@
     void start_gui (bool gui_app = false);
     void close_gui (void);
 
+    bool have_dialogs (void) const { return true; }
+
     std::list<std::string>
     file_dialog (const filter_list& filter, const std::string& title,
                  const std::string& filename, const std::string& pathname,
diff -r 06f4e4d986a1 -r eccca1b14ea8 libinterp/corefcn/event-manager.cc
--- a/libinterp/corefcn/event-manager.cc	Sat Aug 21 21:45:19 2021 -0400
+++ b/libinterp/corefcn/event-manager.cc	Sun Aug 22 13:03:53 2021 +0200
@@ -234,6 +234,17 @@
   return ovl (evmgr.enabled ());
 }
 
+DEFMETHOD (__event_manager_have_dialogs__, interp, , ,
+           doc: /* -*- texinfo -*-
+@deftypefn {} {} __event_manager_have_dialogs__ ()
+Undocumented internal function.
+@end deftypefn */)
+{
+  event_manager& evmgr = interp.get_event_manager ();
+
+  return ovl (evmgr.have_dialogs ());
+}
+
 DEFMETHOD (__event_manager_edit_file__, interp, args, ,
            doc: /* -*- texinfo -*-
 @deftypefn {} {} __event_manager_edit_file__ (@var{file})
@@ -295,11 +306,11 @@
 
 DEFMETHOD (__event_manager_file_dialog__, interp, args, ,
            doc: /* -*- texinfo -*-
-@deftypefn {} {} __event_manager_file_dialog__ (@var{filterlist}, @var{title}, @var{filename}, @var{size} @var{multiselect}, @var{pathname})
+@deftypefn {} {} __event_manager_file_dialog__ (@var{filterlist}, @var{title}, @var{filename}, @var{multiselect}, @var{pathname})
 Undocumented internal function.
 @end deftypefn */)
 {
-  if (args.length () != 6)
+  if (args.length () != 5)
     return ovl ();
 
   octave_value_list retval (3);
@@ -307,9 +318,8 @@
   const Array<std::string> flist = args(0).cellstr_value ();
   std::string title = args(1).string_value ();
   std::string filename = args(2).string_value ();
-  Matrix pos = args(3).matrix_value ();
-  std::string multi_on = args(4).string_value (); // on, off, create
-  std::string pathname = args(5).string_value ();
+  std::string multi_on = args(3).string_value (); // on, off, create
+  std::string pathname = args(4).string_value ();
 
   octave_idx_type nel;
 
diff -r 06f4e4d986a1 -r eccca1b14ea8 libinterp/corefcn/event-manager.h
--- a/libinterp/corefcn/event-manager.h	Sat Aug 21 21:45:19 2021 -0400
+++ b/libinterp/corefcn/event-manager.h	Sun Aug 22 13:03:53 2021 +0200
@@ -100,6 +100,8 @@
 
     // Dialogs.
 
+    virtual bool have_dialogs (void) const { return false; }
+
     typedef std::list<std::pair<std::string, std::string>> filter_list;
 
     virtual std::list<std::string>
@@ -322,6 +324,11 @@
       return link_enabled;
     }
 
+    bool have_dialogs (void) const
+    {
+      return m_qt_event_handlers && m_qt_event_handlers->have_dialogs ();
+    }
+
     // Make the Qt actions available for others.  This is a temporary
     // solution to allow Qt actions like opening the documentation
     // browser when the primary interpreter_events object is not the one
@@ -385,7 +392,7 @@
                  const std::string& filename, const std::string& dirname,
                  const std::string& multimode)
     {
-      return (enabled ()
+      return (enabled () && have_dialogs ()
               ? instance->file_dialog (filter, title, filename, dirname,
                                        multimode)
               : std::list<std::string> ());
@@ -398,7 +405,7 @@
                   const std::list<float>& nc,
                   const std::list<std::string>& defaults)
     {
-      return (enabled ()
+      return (enabled () && have_dialogs ()
               ? instance->input_dialog (prompt, title, nr, nc, defaults)
               : std::list<std::string> ());
     }
@@ -413,7 +420,7 @@
                  const std::string& ok_string,
                  const std::string& cancel_string)
     {
-      return (enabled ()
+      return (enabled () && have_dialogs ()
               ? instance->list_dialog (list, mode, width, height,
                                        initial_value, name, prompt,
                                        ok_string, cancel_string)
@@ -425,7 +432,7 @@
                      const std::string& btn1, const std::string& btn2,
                      const std::string& btn3, const std::string& btndef)
     {
-      return (enabled ()
+      return (enabled () && have_dialogs ()
               ? instance->question_dialog (msg, title, btn1,
                                            btn2, btn3, btndef)
               : "");
diff -r 06f4e4d986a1 -r eccca1b14ea8 libinterp/dldfcn/__fltk_uigetfile__.cc
--- a/libinterp/dldfcn/__fltk_uigetfile__.cc	Sat Aug 21 21:45:19 2021 -0400
+++ b/libinterp/dldfcn/__fltk_uigetfile__.cc	Sun Aug 22 13:03:53 2021 +0200
@@ -29,20 +29,20 @@
 
 #if defined (HAVE_FLTK)
 
-#if defined (WIN32)
-#  define WIN32_LEAN_AND_MEAN
-#endif
+#  if defined (WIN32)
+#    define WIN32_LEAN_AND_MEAN
+#  endif
 
-#include <string>
+#  include <string>
 
-#include <FL/Fl.H>
-#include <FL/Fl_File_Chooser.H>
+#  include <FL/Fl.H>
+#  include <FL/Fl_File_Chooser.H>
 
 // FLTK headers may include X11/X.h which defines Complex, and that
 // conflicts with Octave's Complex typedef.  We don't need the X11
 // Complex definition in this file, so remove it before including Octave
 // headers which may require Octave's Complex typedef.
-#undef Complex
+#  undef Complex
 
 #endif
 
@@ -69,20 +69,18 @@
   //   args(0) ... FileFilter in fltk format
   //   args(1) ... Title
   //   args(2) ... Default Filename
-  //   args(3) ... PositionValue [x,y]
-  //   args(4) ... SelectValue "on"/"off"/"dir"/"create"
+  //   args(3) ... SelectValue "on"/"off"/"dir"/"create"
 
   octave_value_list retval (3, octave_value (0));
 
   std::string file_filter = args(0).string_value ();
   std::string title = args(1).string_value ();
   std::string default_name = args(2).string_value ();
-  Matrix pos = args(3).matrix_value ();
 
   int multi_type = Fl_File_Chooser::SINGLE;
   std::string flabel = "Filename:";
 
-  std::string multi = args(4).string_value ();
+  std::string multi = args(3).string_value ();
   if (multi == "on")
     multi_type = Fl_File_Chooser::MULTI;
   else if (multi == "dir")
diff -r 06f4e4d986a1 -r eccca1b14ea8 scripts/gui/private/__get_funcname__.m
--- a/scripts/gui/private/__get_funcname__.m	Sat Aug 21 21:45:19 2021 -0400
+++ b/scripts/gui/private/__get_funcname__.m	Sun Aug 22 13:03:53 2021 +0200
@@ -33,7 +33,7 @@
 
 function funcname = __get_funcname__ (basename)
 
-  if (! __event_manager_enabled__ ())
+  if (! __event_manager_enabled__ () || ! __event_manager_have_dialogs__ ())
     tk = graphics_toolkit ();
     funcname = [ "__" basename "_" tk "__"];
     if (numel (tk) > 0 && ! strcmp (tk, "fltk")
diff -r 06f4e4d986a1 -r eccca1b14ea8 scripts/gui/private/__uigetfile_fltk__.m
--- a/scripts/gui/private/__uigetfile_fltk__.m	Sat Aug 21 21:45:19 2021 -0400
+++ b/scripts/gui/private/__uigetfile_fltk__.m	Sun Aug 22 13:03:53 2021 +0200
@@ -24,11 +24,11 @@
 ########################################################################
 
 ## -*- texinfo -*-
-## @deftypefn {} {[@var{fname}, @var{fpath}, @var{fltidx}] =} __uigetfile_fltk__ (@var{filters}, @var{title}, @var{defval}, @var{position}, @var{multiselect}, @var{defdir})
+## @deftypefn {} {[@var{fname}, @var{fpath}, @var{fltidx}] =} __uigetfile_fltk__ (@var{filters}, @var{title}, @var{defval}, @var{multiselect}, @var{defdir})
 ## Undocumented internal function.
 ## @end deftypefn
 
-function [retval, retpath, retindex] = __uigetfile_fltk__ (filters, title, defval, position, multiselect, defdir)
+function [retval, retpath, retindex] = __uigetfile_fltk__ (filters, title, defval, multiselect, defdir)
 
   if (exist ("__fltk_uigetfile__") != 3)
     error ("uigetfile: fltk graphics toolkit required");
@@ -39,6 +39,6 @@
     defval = fullfile (defdir, defval);
   endif
   [retval, retpath, retindex] = ...
-    __fltk_uigetfile__ (filters, title, defval, position, multiselect);
+    __fltk_uigetfile__ (filters, title, defval, multiselect);
 
 endfunction
diff -r 06f4e4d986a1 -r eccca1b14ea8 scripts/gui/uigetfile.m
--- a/scripts/gui/uigetfile.m	Sat Aug 21 21:45:19 2021 -0400
+++ b/scripts/gui/uigetfile.m	Sun Aug 22 13:03:53 2021 +0200
@@ -28,7 +28,6 @@
 ## @deftypefnx {} {[@dots{}] =} uigetfile (@var{flt})
 ## @deftypefnx {} {[@dots{}] =} uigetfile (@var{flt}, @var{dialog_name})
 ## @deftypefnx {} {[@dots{}] =} uigetfile (@var{flt}, @var{dialog_name}, @var{default_file})
-## @deftypefnx {} {[@dots{}] =} uigetfile (@dots{}, "Position", [@var{px} @var{py}])
 ## @deftypefnx {} {[@dots{}] =} uigetfile (@dots{}, "MultiSelect", @var{mode})
 ##
 ## Open a GUI dialog for selecting a file and return the filename @var{fname},
@@ -74,11 +73,9 @@
 ## If @var{default_file} is given then it will be selected in the GUI dialog.
 ## If, in addition, a path is given it is also used as current path.
 ##
-## The screen position of the GUI dialog can be set using the
-## @qcode{"Position"} key and a 2-element vector containing the pixel
-## coordinates.  Two or more files can be selected when setting the
-## @qcode{"MultiSelect"} key to @qcode{"on"}.  In that case @var{fname} is a
-## cell array containing the files.
+## Two or more files can be selected when setting the @qcode{"MultiSelect"} key
+## to @qcode{"on"}.  In that case, @var{fname} is a cell array containing the
+## files.
 ##
 ## The outputs @var{fname} and @var{fpath} are strings returning the chosen
 ## name and path, respectively.  However, if the @samp{Cancel} button is
@@ -99,7 +96,6 @@
   outargs = {cell(0, 2),         # File Filter
              "Open File",        # Dialog Title
              "",                 # Default filename
-             [240, 120],         # Dialog Position (pixel x/y)
              "off",              # MultiSelect on/off
              pwd};               # Default directory
 
@@ -113,7 +109,13 @@
     endif
   endif
 
-  optidx = min ([idx1, idx2, nargin+1]);
+  if (! isempty (idx2))
+    ## FIXME: Remove handling the "position" property completely in Octave 9
+    warning (['uigetfile: The "position" argument is deprecated and will ', ...
+              "be ignored. Consider removing it from the function call."]);
+  endif
+
+  optidx = min ([idx1, nargin+1]);
 
   args = varargin(1:optidx-1);
 
@@ -121,7 +123,7 @@
   if (len > 0)
     [outargs{1}, outargs{3}, defdir] = __file_filter__ ("uigetfile", args{1});
     if (! isempty (defdir))
-      outargs{6} = defdir;
+      outargs{5} = defdir;
     endif
   else
     outargs{1} = __file_filter__ ("uigetfile", outargs{1});
@@ -146,7 +148,7 @@
         [fdir, fname, fext] = fileparts (varargin{3});
       endif
       if (! isempty (fdir))
-        outargs{6} = fdir;
+        outargs{5} = fdir;
       endif
       if (! isempty (fname) || ! isempty (fext))
         outargs{3} = [fname fext];
@@ -168,22 +170,19 @@
       prop = varargin{i};
       val = varargin{i + 1};
       if (strcmpi (prop, "position"))
-        if (! isnumeric (val) || length (val) != 2)
-          error ('uigetfile: "Position" must be a 2-element vector');
-        endif
-        outargs{4} = val;
+        ## FIXME: Remove handling this option in Octave 9.
       elseif (strcmpi (prop, "multiselect"))
         if (! ischar (val))
           error ('uigetfile: MultiSelect value must be a string ("on"/"off")');
         endif
-        outargs{5} = tolower (val);
+        outargs{4} = tolower (val);
       else
         error ("uigetfile: unknown argument '%s'", prop);
       endif
     endfor
   endif
 
-  if (__event_manager_enabled__ ())
+  if (__event_manager_have_dialogs__ ())
     [retfile, retpath, retindex] = __event_manager_file_dialog__ (outargs{:});
   else
     funcname = __get_funcname__ (mfilename ());
