Ylva And Malin
noc_file_dialog.h
Go to the documentation of this file.
1 
2 /* noc_file_dialog library
3  *
4  * Copyright (c) 2015 Guillaume Chereau <guillaume@noctua-software.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 /* A portable library to create open and save dialogs on linux, osx and
26  * windows.
27  *
28  * The library define a single function : noc_file_dialog_open.
29  * With three different implementations.
30  *
31  * Usage:
32  *
33  * The library does not automatically select the implementation, you need to
34  * define one of those macros before including this file:
35  *
36  * NOC_FILE_DIALOG_GTK
37  * NOC_FILE_DIALOG_WIN32
38  * NOC_FILE_DIALOG_OSX
39  */
40 
41 enum {
42  NOC_FILE_DIALOG_OPEN = 1 << 0, // Create an open file dialog.
43  NOC_FILE_DIALOG_SAVE = 1 << 1, // Create a save file dialog.
44  NOC_FILE_DIALOG_DIR = 1 << 2, // Open a directory.
46 };
47 
48 // There is a single function defined.
49 
50 /* flags : union of the NOC_FILE_DIALOG_XXX masks.
51  * filters : a list of strings separated by '\0' of the form:
52  * "name1 reg1 name2 reg2 ..."
53  * The last value is followed by two '\0'. For example,
54  * to filter png and jpeg files, you can use:
55  * "png\0*.png\0jpeg\0*.jpeg\0"
56  * You can also separate patterns with ';':
57  * "jpeg\0*.jpg;*.jpeg\0"
58  * Set to NULL for no filter.
59  * default_path : the default file to use or NULL.
60  * default_name : the default file name to use or NULL.
61  *
62  * The function return a C string. There is no need to free it, as it is
63  * managed by the library. The string is valid until the next call to
64  * no_dialog_open. If the user canceled, the return value is NULL.
65  */
66 const char *noc_file_dialog_open(int flags,
67  const char *filters,
68  const char *default_path,
69  const char *default_name);
70 
71 #ifdef NOC_FILE_DIALOG_IMPLEMENTATION
72 
73 #include <stdlib.h>
74 #include <string.h>
75 
76 static char *g_noc_file_dialog_ret = NULL;
77 
78 #ifdef NOC_FILE_DIALOG_GTK
79 
80 #include <gtk/gtk.h>
81 
82 const char* noc_file_dialog_open(int flags,
83  const char *filters,
84  const char *default_path,
85  const char *default_name)
86 {
87  GtkWidget *dialog;
88  GtkFileFilter *filter;
89  GtkFileChooser *chooser;
90  GtkFileChooserAction action;
91  gint res;
92  char buf[128], *patterns;
93 
94  action = flags & NOC_FILE_DIALOG_SAVE ? GTK_FILE_CHOOSER_ACTION_SAVE :
95  GTK_FILE_CHOOSER_ACTION_OPEN;
96  if (flags & NOC_FILE_DIALOG_DIR)
97  action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
98 
99  gtk_init_check(NULL, NULL);
100  dialog = gtk_file_chooser_dialog_new(
101  flags & NOC_FILE_DIALOG_SAVE ? "Save File" : "Open File",
102  NULL,
103  action,
104  "_Cancel", GTK_RESPONSE_CANCEL,
105  flags & NOC_FILE_DIALOG_SAVE ? "_Save" : "_Open", GTK_RESPONSE_ACCEPT,
106  NULL );
107  chooser = GTK_FILE_CHOOSER(dialog);
109  gtk_file_chooser_set_do_overwrite_confirmation(chooser, TRUE);
110 
111  if (default_path)
112  gtk_file_chooser_set_filename(chooser, default_path);
113  if (default_name)
114  gtk_file_chooser_set_current_name(chooser, default_name);
115 
116  while (filters && *filters) {
117  filter = gtk_file_filter_new();
118  gtk_file_filter_set_name(filter, filters);
119  filters += strlen(filters) + 1;
120 
121  // Split the filter pattern with ';'.
122  strcpy(buf, filters);
123  buf[strlen(buf)] = '\0';
124  for (patterns = buf; *patterns; patterns++)
125  if (*patterns == ';') *patterns = '\0';
126  patterns = buf;
127  while (*patterns) {
128  gtk_file_filter_add_pattern(filter, patterns);
129  patterns += strlen(patterns) + 1;
130  }
131 
132  gtk_file_chooser_add_filter(chooser, filter);
133  filters += strlen(filters) + 1;
134  }
135 
136  res = gtk_dialog_run(GTK_DIALOG(dialog));
137 
138  free(g_noc_file_dialog_ret);
139  g_noc_file_dialog_ret = NULL;
140 
141  if (res == GTK_RESPONSE_ACCEPT)
142  g_noc_file_dialog_ret = gtk_file_chooser_get_filename(chooser);
143  gtk_widget_destroy(dialog);
144  while (gtk_events_pending()) gtk_main_iteration();
145  return g_noc_file_dialog_ret;
146 }
147 
148 // #include <nautilus.h>
149 
150 // const char* noc_file_dialog_open(int flags,
151 // const char *filters,
152 // const char *default_path,
153 // const char *default_name)
154 // {
155 // return nullptr;
156 // }
157 
158 #endif
159 
160 #ifdef NOC_FILE_DIALOG_WIN32
161 
162 #include <windows.h>
163 #include <commdlg.h>
164 
165 const char *noc_file_dialog_open(int flags,
166  const char *filters,
167  const char *default_path,
168  const char *default_name)
169 {
170  OPENFILENAME ofn; // common dialog box structure
171  char szFile[260]; // buffer for file name
172  int ret;
173 
174  ZeroMemory(&ofn, sizeof(ofn));
175  ofn.lStructSize = sizeof(ofn);
176  ofn.lpstrFile = szFile;
177  ofn.lpstrFile[0] = '\0';
178  ofn.nMaxFile = sizeof(szFile);
179  ofn.lpstrFilter = filters;
180  ofn.nFilterIndex = 1;
181  ofn.lpstrFileTitle = NULL;
182  ofn.nMaxFileTitle = 0;
183  ofn.lpstrInitialDir = NULL;
184  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
185 
186  if (flags & NOC_FILE_DIALOG_OPEN)
187  ret = GetOpenFileName(&ofn);
188  else
189  ret = GetSaveFileName(&ofn);
190 
191  free(g_noc_file_dialog_ret);
192  g_noc_file_dialog_ret = ret ? strdup(szFile) : NULL;
193  return g_noc_file_dialog_ret;
194 }
195 
196 #endif
197 
198 #ifdef NOC_FILE_DIALOG_OSX
199 
200 #include <AppKit/AppKit.h>
201 
202 const char *noc_file_dialog_open(int flags,
203  const char *filters,
204  const char *default_path,
205  const char *default_name)
206 {
207  NSURL *url;
208  const char *utf8_path;
209  NSSavePanel *panel;
210  NSOpenPanel *open_panel;
211  NSMutableArray *types_array;
212  NSURL *default_url;
213  char buf[128], *patterns;
214  // XXX: I don't know about memory management with cococa, need to check
215  // if I leak memory here.
216  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
217 
218  if (flags & NOC_FILE_DIALOG_OPEN) {
219  panel = open_panel = [NSOpenPanel openPanel];
220  } else {
221  panel = [NSSavePanel savePanel];
222  }
223 
224  if (flags & NOC_FILE_DIALOG_DIR) {
225  [open_panel setCanChooseDirectories:YES];
226  [open_panel setCanChooseFiles:NO];
227  }
228 
229  if (default_path) {
230  default_url = [NSURL fileURLWithPath:
231  [NSString stringWithUTF8String:default_path]];
232  [panel setDirectoryURL:default_url];
233  [panel setNameFieldStringValue:default_url.lastPathComponent];
234  }
235 
236  if (filters) {
237  types_array = [NSMutableArray array];
238  while (*filters) {
239  filters += strlen(filters) + 1; // skip the name
240  // Split the filter pattern with ';'.
241  strcpy(buf, filters);
242  buf[strlen(buf) + 1] = '\0';
243  for (patterns = buf; *patterns; patterns++)
244  if (*patterns == ';') *patterns = '\0';
245  patterns = buf;
246  while (*patterns) {
247  assert(strncmp(patterns, "*.", 2) == 0);
248  patterns += 2; // Skip the "*."
249  [types_array addObject:[NSString stringWithUTF8String: patterns]];
250  patterns += strlen(patterns) + 1;
251  }
252  filters += strlen(filters) + 1;
253  }
254  [panel setAllowedFileTypes:types_array];
255  }
256 
257  free(g_noc_file_dialog_ret);
258  g_noc_file_dialog_ret = NULL;
259  if ( [panel runModal] == NSModalResponseOK ) {
260  url = [panel URL];
261  utf8_path = [[url path] UTF8String];
262  g_noc_file_dialog_ret = strdup(utf8_path);
263  }
264 
265  [pool release];
266  return g_noc_file_dialog_ret;
267 }
268 #endif
269 
270 
271 #endif
Definition: noc_file_dialog.h:45
Definition: noc_file_dialog.h:44
Definition: noc_file_dialog.h:42
Definition: noc_file_dialog.h:43
const char * noc_file_dialog_open(int flags, const char *filters, const char *default_path, const char *default_name)
GLint GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: wglext.h:328