FINAL CUT
ffiledialog.h
1 /***********************************************************************
2 * ffiledialog.h - Widget FFileDialog (a file chooser dialog) *
3 * *
4 * This file is part of the FINAL CUT widget toolkit *
5 * *
6 * Copyright 2014-2026 Markus Gans *
7 * *
8 * FINAL CUT is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as *
10 * published by the Free Software Foundation; either version 3 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * FINAL CUT is distributed in the hope that it will be useful, but *
14 * WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this program. If not, see *
20 * <http://www.gnu.org/licenses/>. *
21 ***********************************************************************/
22 
23 /* Inheritance diagram
24  * ═══════════════════
25  *
26  * ▕▔▔▔▔▔▔▔▔▔▏ ▕▔▔▔▔▔▔▔▔▔▏
27  * ▕ FVTerm ▏ ▕ FObject ▏
28  * ▕▁▁▁▁▁▁▁▁▁▏ ▕▁▁▁▁▁▁▁▁▁▏
29  * ▲ ▲
30  * │ │
31  * └─────┬─────┘
32  * │
33  * ▕▔▔▔▔▔▔▔▔▔▏
34  * ▕ FWidget ▏
35  * ▕▁▁▁▁▁▁▁▁▁▏
36  * ▲
37  * │
38  * ▕▔▔▔▔▔▔▔▔▔▏
39  * ▕ FWindow ▏
40  * ▕▁▁▁▁▁▁▁▁▁▏
41  * ▲
42  * │
43  * ▕▔▔▔▔▔▔▔▔▔▏
44  * ▕ FDialog ▏
45  * ▕▁▁▁▁▁▁▁▁▁▏
46  * ▲
47  * │
48  * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▏
49  * ▕ FFileDialog ▏
50  * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▏
51  */
52 
53 #ifndef FFILEDIALOG_H
54 #define FFILEDIALOG_H
55 
56 #if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
57  #error "Only <final/final.h> can be included directly."
58 #endif
59 
60 #include <sys/param.h>
61 #include <sys/types.h>
62 
63 #include <dirent.h>
64 #include <fnmatch.h>
65 #include <libgen.h>
66 #include <unistd.h>
67 
68 #include <string>
69 #include <vector>
70 
71 #include "final/dialog/fdialog.h"
72 #include "final/dialog/fmessagebox.h"
73 #include "final/output/tty/fterm.h"
74 #include "final/widget/fbutton.h"
75 #include "final/widget/fcheckbox.h"
76 #include "final/widget/flineedit.h"
77 #include "final/widget/flistbox.h"
78 #include "final/widget/fstatusbar.h"
79 
80 namespace finalcut
81 {
82 
83 //----------------------------------------------------------------------
84 // class FFileDialog
85 //----------------------------------------------------------------------
86 
87 class FFileDialog : public FDialog
88 {
89  public:
90  // Enumeration
91  enum class DialogType : uInt8
92  {
93  Open = 0,
94  Save = 1
95  };
96 
97  // Constructors
98  explicit FFileDialog (FWidget* = nullptr);
99 
100  FFileDialog ( const FString&
101  , FString&&
102  , DialogType = DialogType::Open
103  , FWidget* = nullptr );
104 
105  // Destructor
106  ~FFileDialog() noexcept override;
107 
108  // Accessors
109  auto getClassName() const -> FString override;
110  auto getPath() const -> FString;
111  auto getFilter() const -> FString;
112  auto getSelectedFile() const -> FString;
113  auto getShowHiddenFiles() const noexcept -> bool;
114 
115  // Mutators
116  void setPath (const FString&);
117  void setFilter (const FString&);
118  void setShowHiddenFiles (bool = true);
119  void unsetShowHiddenFiles();
120 
121  // Event handler
122  void onKeyPress (FKeyEvent*) override;
123 
124  // Methods
125  static auto fileOpenChooser ( FWidget*
126  , const FString& = FString()
127  , const FString& = FString() ) -> FString;
128  static auto fileSaveChooser ( FWidget*
129  , const FString& = FString()
130  , const FString& = FString() ) -> FString;
131 
132  protected:
133  // Method
134  void adjustSize() override;
135 
136  private:
137  // Enumeration
138  enum class CloseDir : uInt8 { success, error };
139 
140  struct FDirEntry
141  {
142  // Constructor
143  FDirEntry()
144  : fifo{false}
145  , character_device{false}
146  , directory{false}
147  , block_device{false}
148  , regular_file{false}
149  , symbolic_link{false}
150  , socket{false}
151  { }
152 
153  // Data members
154  std::string name{};
155  // Type of file
156  uChar fifo : 1;
157  uChar character_device : 1;
158  uChar directory : 1;
159  uChar block_device : 1;
160  uChar regular_file : 1;
161  uChar symbolic_link : 1;
162  uChar socket : 1;
163  uChar : 1; // padding bits
164  };
165 
166  using DirEntries = std::vector<FDirEntry>;
167 
168  // Methods
169  void init();
170  void widgetSettings (const FPoint&);
171  void initCallbacks();
172  auto patternMatch ( const std::string&
173  , const std::string& ) const -> bool;
174  void clear();
175  auto numOfDirs() -> sInt64;
176  void sortDir();
177  auto readDir() -> int;
178  void getEntry (const std::string&, std::string&& name, const struct dirent*);
179  void followSymLink (const std::string&, FDirEntry&) const;
180  auto openDirectory() -> DIR*;
181  auto closeDirectory (DIR*) -> CloseDir;
182  void readDirEntries (DIR*);
183  auto getSelectedFileName() const -> std::string;
184  auto isCurrentDirectory (const std::string&) const -> bool;
185  auto isParentDirectory (const std::string&) const -> bool;
186  auto isHiddenEntry (const std::string&) const -> bool;
187  auto isRootDirectory (const std::string&) const -> bool;
188  void dirEntriesToList();
189  void selectDirectoryEntry (const std::string&);
190  auto changeDir (const FString&) -> int;
191  void printPath (const FString&);
192  void setTitelbarText();
193  static auto getHomeDir() -> FString;
194  auto isFilterInput() const -> bool;
195  auto isDirectoryInput() const -> bool;
196  void activateNewFilter();
197  void activateDefaultFilter();
198  void findItem (const FString&);
199  void changeIntoSubDir();
200 
201  // Callback methods
202  void cb_processActivate();
203  void cb_processRowChanged();
204  void cb_processClicked();
205  void cb_processCancel();
206  void cb_processOpen();
207  void cb_processShowHidden();
208 
209  // Data members
210  DirEntries dir_entries{};
211  FString directory{};
212  FString filter_pattern{};
213  FLineEdit file_name{this};
214  FListBox file_browser{this};
215  FCheckBox hidden_check{this};
216  FButton cancel_btn{this};
217  FButton open_btn{this};
218  DialogType dlg_type{DialogType::Open};
219  bool show_hidden{false};
220 
221  // Friend functions
222  friend auto sortByName ( const FFileDialog::FDirEntry&
223  , const FFileDialog::FDirEntry& ) -> bool;
224  friend auto sortDirFirst (const FFileDialog::FDirEntry&) -> bool;
225  friend auto isRegularFile (const std::string&) noexcept -> bool;
226 
227  friend auto fileChooser ( FWidget*
228  , const FString&
229  , const FString&
230  , FFileDialog::DialogType) -> FString;
231 };
232 
233 // FMessageBox inline functions
234 //----------------------------------------------------------------------
235 inline auto FFileDialog::getClassName() const -> FString
236 { return "FFileDialog"; }
237 
238 //----------------------------------------------------------------------
239 inline auto FFileDialog::getPath() const -> FString
240 { return directory; }
241 
242 //----------------------------------------------------------------------
243 inline auto FFileDialog::getFilter() const -> FString
244 { return filter_pattern; }
245 
246 //----------------------------------------------------------------------
247 inline void FFileDialog::unsetShowHiddenFiles()
248 { setShowHiddenFiles(false); }
249 
250 //----------------------------------------------------------------------
251 inline auto FFileDialog::getShowHiddenFiles() const noexcept -> bool
252 { return show_hidden; }
253 
254 } // namespace finalcut
255 
256 #endif // FFILEDIALOG_H
Definition: ffiledialog.h:87
Definition: fbutton.h:60
Definition: flistbox.h:173
Definition: class_template.cpp:25
Definition: fpoint.h:50
Definition: fcheckbox.h:64
Definition: fstring.h:82
Definition: fdialog.h:69
Definition: fwidget.h:129
Definition: flineedit.h:67
Definition: fevent.h:124