1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2010-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if defined (HAVE_CONFIG_H) 27 # include "config.h" 28 #endif 29 30 #if defined (HAVE_FLTK) 31 32 #if defined (WIN32) 33 # define WIN32_LEAN_AND_MEAN 34 #endif 35 36 #include <string> 37 38 #include <FL/Fl.H> 39 #include <FL/Fl_File_Chooser.H> 40 41 // FLTK headers may include X11/X.h which defines Complex, and that 42 // conflicts with Octave's Complex typedef. We don't need the X11 43 // Complex definition in this file, so remove it before including Octave 44 // headers which may require Octave's Complex typedef. 45 #undef Complex 46 47 #endif 48 49 #include "dMatrix.h" 50 #include "file-ops.h" 51 52 #include "Cell.h" 53 #include "defun-dld.h" 54 #include "errwarn.h" 55 #include "ov.h" 56 57 DEFUN_DLD (__fltk_uigetfile__, args, , 58 doc: /* -*- texinfo -*- 59 @deftypefn {} {} __fltk_uigetfile__ (@dots{}) 60 Undocumented internal function. 61 @end deftypefn */) 62 { 63 #if defined (HAVE_FLTK) 64 65 // Expected argument list: 66 // 67 // args(0) ... FileFilter in fltk format 68 // args(1) ... Title 69 // args(2) ... Default Filename 70 // args(3) ... PositionValue [x,y] 71 // args(4) ... SelectValue "on"/"off"/"dir"/"create" 72 73 octave_value_list retval (3, octave_value (0)); 74 75 std::string file_filter = args(0).string_value (); 76 std::string title = args(1).string_value (); 77 std::string default_name = args(2).string_value (); 78 Matrix pos = args(3).matrix_value (); 79 80 int multi_type = Fl_File_Chooser::SINGLE; 81 std::string flabel = "Filename:"; 82 83 std::string multi = args(4).string_value (); 84 if (multi == "on") 85 multi_type = Fl_File_Chooser::MULTI; 86 else if (multi == "dir") 87 { 88 multi_type = Fl_File_Chooser::DIRECTORY; 89 flabel = "Directory:"; 90 } 91 else if (multi == "create") 92 multi_type = Fl_File_Chooser::CREATE; 93 94 Fl_File_Chooser::filename_label = flabel.c_str (); 95 96 Fl_File_Chooser fc (default_name.c_str (), file_filter.c_str (), 97 multi_type, title.c_str ()); 98 99 fc.preview (0); 100 101 if (multi_type == Fl_File_Chooser::CREATE) 102 fc.ok_label ("Save"); 103 104 fc.show (); 105 106 while (fc.shown ()) 107 Fl::wait (); 108 109 if (fc.value ()) 110 { 111 int file_count = fc.count (); 112 std::string fname; 113 114 // FLTK uses forward slash even for Windows 115 std::string sep = "/"; 116 std::size_t idx; 117 118 if (file_count == 1 && multi_type != Fl_File_Chooser::DIRECTORY) 119 { 120 fname = fc.value (); 121 idx = fname.find_last_of (sep); 122 retval(0) = fname.substr (idx + 1); 123 } 124 else 125 { 126 Cell file_cell = Cell (file_count, 1); 127 for (octave_idx_type n = 1; n <= file_count; n++) 128 { 129 fname = fc.value (n); 130 idx = fname.find_last_of (sep); 131 file_cell(n - 1) = fname.substr (idx + 1); 132 } 133 retval(0) = file_cell; 134 } 135 136 if (multi_type == Fl_File_Chooser::DIRECTORY) 137 retval(0) = octave::sys::file_ops::native_separator_path (std::string (fc.value ())); 138 else 139 { 140 retval(1) = octave::sys::file_ops::native_separator_path (std::string (fc.directory ()) + sep); 141 retval(2) = fc.filter_value () + 1; 142 } 143 } 144 145 fc.hide (); 146 Fl::flush (); 147 148 return retval; 149 150 #else 151 152 octave_unused_parameter (args); 153 154 err_disabled_feature ("__fltk_uigetfile__", "OpenGL and FLTK"); 155 156 #endif 157 } 158 159 /* 160 ## No test needed for internal helper function. 161 %!assert (1) 162 */ 163