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-2024 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
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 { 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 char* const, const struct dirent*);
179  void followSymLink (const char* const, FDirEntry&) const;
180  auto openDirectory() -> DIR*;
181  auto closeDirectory (DIR*) -> CloseDir;
182  void readDirEntries (DIR*);
183  auto isCurrentDirectory (const struct dirent*) const -> bool;
184  auto isParentDirectory (const struct dirent*) const -> bool;
185  auto isHiddenEntry (const struct dirent*) const -> bool;
186  auto isRootDirectory (const char* const) const -> bool;
187  void dirEntriesToList();
188  void selectDirectoryEntry (const std::string&);
189  auto changeDir (const FString&) -> int;
190  void printPath (const FString&);
191  void setTitelbarText();
192  static auto getHomeDir() -> FString;
193  auto isFilterInput() const -> bool;
194  auto isDirectoryInput() const -> bool;
195  void activateNewFilter();
196  void activateDefaultFilter();
197  void findItem (const FString&);
198  void changeIntoSubDir();
199 
200  // Callback methods
201  void cb_processActivate();
202  void cb_processRowChanged();
203  void cb_processClicked();
204  void cb_processCancel();
205  void cb_processOpen();
206  void cb_processShowHidden();
207 
208  // Data members
209  DirEntries dir_entries{};
210  FString directory{};
211  FString filter_pattern{};
212  FLineEdit filename{this};
213  FListBox filebrowser{this};
214  FCheckBox hidden_check{this};
215  FButton cancel_btn{this};
216  FButton open_btn{this};
217  DialogType dlg_type{DialogType::Open};
218  bool show_hidden{false};
219 
220  // Friend functions
221  friend auto sortByName ( const FFileDialog::FDirEntry&
222  , const FFileDialog::FDirEntry& ) -> bool;
223  friend auto sortDirFirst (const FFileDialog::FDirEntry&) -> bool;
224  friend auto fileChooser ( FWidget*
225  , const FString&
226  , const FString&
227  , FFileDialog::DialogType) -> FString;
228 };
229 
230 // FMessageBox inline functions
231 //----------------------------------------------------------------------
232 inline auto FFileDialog::getClassName() const -> FString
233 { return "FFileDialog"; }
234 
235 //----------------------------------------------------------------------
236 inline auto FFileDialog::getPath() const -> FString
237 { return directory; }
238 
239 //----------------------------------------------------------------------
240 inline auto FFileDialog::getFilter() const -> FString
241 { return filter_pattern; }
242 
243 //----------------------------------------------------------------------
244 inline void FFileDialog::unsetShowHiddenFiles()
245 { setShowHiddenFiles(false); }
246 
247 //----------------------------------------------------------------------
248 inline auto FFileDialog::getShowHiddenFiles() const noexcept -> bool
249 { return show_hidden; }
250 
251 } // namespace finalcut
252 
253 #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:79
Definition: fdialog.h:69
Definition: fwidget.h:129
Definition: flineedit.h:67
Definition: fevent.h:124