1 #include "config.h"
2 #include "i18n.h"
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <signal.h>
7 #include <sys/types.h>
8 #include <sys/wait.h>
9 #include <unistd.h>
10 
11 #include <fx.h>
12 #include <fxkeys.h>
13 #include <FXPNGIcon.h>
14 
15 #include "xfedefs.h"
16 #include "icons.h"
17 #include "xfeutils.h"
18 #include "startupnotification.h"
19 #include "File.h"
20 #include "FileList.h"
21 #include "FileDict.h"
22 #include "Preferences.h"
23 #include "FilePanel.h"
24 #include "InputDialog.h"
25 #include "HistInputDialog.h"
26 #include "DirPanel.h"
27 #include "MessageBox.h"
28 #include "TextWindow.h"
29 #include "CommandWindow.h"
30 #include "Bookmarks.h"
31 #include "FileDialog.h"
32 #include "help.h"
33 #include "DirHistBox.h"
34 #include "SearchWindow.h"
35 #include "XFileExplorer.h"
36 
37 // Size of the location bar
38 #define LOCATION_BAR_LENGTH    60
39 #define LOCATION_BAR_HEIGHT    6
40 
41 
42 // Global variables
43 FXString clipboard = "";
44 char     OpenHistory[OPEN_HIST_SIZE][MAX_COMMAND_SIZE];
45 int      OpenNum;
46 char     FilterHistory[FILTER_HIST_SIZE][MAX_PATTERN_SIZE];
47 int      FilterNum;
48 
49 FXbool allowPopupScroll = false;
50 FXuint single_click;
51 FXbool file_tooltips;
52 FXbool relative_resize;
53 
54 // External global variables
55 extern char**   args;
56 extern int      panel_mode;
57 extern FXString homedir;
58 extern FXString xdgdatahome;
59 extern FXString xdgconfighome;
60 
61 // Global options
62 #if defined(linux)
63 extern FXStringDict* fsdevices;
64 extern FXStringDict* updevices;
65 #endif
66 
67 
68 // Helper function to draw a toolbar separator
toolbarSeparator(FXToolBar * tb)69 static void toolbarSeparator(FXToolBar* tb)
70 {
71 #define SEP_SPACE    1
72     new FXFrame(tb, LAYOUT_CENTER_Y|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, SEP_SPACE);
73     new FXVerticalSeparator(tb, LAYOUT_SIDE_TOP|LAYOUT_CENTER_Y|SEPARATOR_GROOVE|LAYOUT_FILL_Y);
74     new FXFrame(tb, LAYOUT_CENTER_Y|LAYOUT_LEFT|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0, 0, SEP_SPACE);
75 }
76 
77 
78 // Map
79 FXDEFMAP(XFileExplorer) XFileExplorerMap[] =
80 {
81     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_TOGGLE_STATUS, XFileExplorer::onCmdToggleStatus),
82     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_RUN, XFileExplorer::onCmdRun),
83     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_SU, XFileExplorer::onCmdSu),
84     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_COPY, XFileExplorer::onCmdFileCopyClp),
85     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_CUT, XFileExplorer::onCmdFileCutClp),
86     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_ADDCOPY, XFileExplorer::onCmdFileAddCopyClp),
87     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_ADDCUT, XFileExplorer::onCmdFileAddCutClp),
88     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_PASTE, XFileExplorer::onCmdFilePasteClp),
89     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_RENAME, XFileExplorer::onCmdFileRename),
90     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_COPYTO, XFileExplorer::onCmdFileCopyto),
91     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_MOVETO, XFileExplorer::onCmdFileMoveto),
92     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_SYMLINK, XFileExplorer::onCmdFileSymlink),
93     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_PROPERTIES, XFileExplorer::onCmdFileProperties),
94     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_DELETE, XFileExplorer::onCmdFileDelete),
95     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_TRASH, XFileExplorer::onCmdFileTrash),
96     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_RESTORE, XFileExplorer::onCmdFileRestore),
97     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_QUIT, XFileExplorer::onQuit),
98     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_HELP, XFileExplorer::onCmdHelp),
99     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_ABOUT, XFileExplorer::onCmdAbout),
100     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_ASSOC, XFileExplorer::onCmdFileAssoc),
101     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_REFRESH, XFileExplorer::onCmdRefresh),
102     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_EMPTY_TRASH, XFileExplorer::onCmdEmptyTrash),
103     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_TRASH_SIZE, XFileExplorer::onCmdTrashSize),
104     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_XTERM, XFileExplorer::onCmdXTerm),
105     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_CLEAR_LOCATION, XFileExplorer::onCmdClearLocation),
106     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_GOTO_LOCATION, XFileExplorer::onCmdGotoLocation),
107     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_PREFS, XFileExplorer::onCmdPrefs),
108     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_HORZ_PANELS, XFileExplorer::onCmdHorzVertPanels),
109     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_VERT_PANELS, XFileExplorer::onCmdHorzVertPanels),
110     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_SHOW_ONE_PANEL, XFileExplorer::onCmdShowPanels),
111     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_SHOW_TWO_PANELS, XFileExplorer::onCmdShowPanels),
112     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_SHOW_TREE_PANEL, XFileExplorer::onCmdShowPanels),
113     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_SHOW_TREE_TWO_PANELS, XFileExplorer::onCmdShowPanels),
114     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_SYNCHRONIZE_PANELS, XFileExplorer::onCmdSynchronizePanels),
115     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_SWITCH_PANELS, XFileExplorer::onCmdSwitchPanels),
116     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_RESTART, XFileExplorer::onCmdRestart),
117     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_NEW_WIN, XFileExplorer::onCmdNewWindow),
118     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_BOOKMARK, XFileExplorer::onCmdBookmark),
119     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_DIR_UP, XFileExplorer::onCmdDirUp),
120     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_ADD_BOOKMARK, XFileExplorer::onCmdBookmark),
121     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_DIR_BACK, XFileExplorer::onCmdDirBack),
122     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_DIR_FORWARD, XFileExplorer::onCmdDirForward),
123     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_DIR_BACK_HIST, XFileExplorer::onCmdDirBackHist),
124     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_DIR_FORWARD_HIST, XFileExplorer::onCmdDirForwardHist),
125     FXMAPFUNC(SEL_KEYPRESS, 0, XFileExplorer::onKeyPress),
126     FXMAPFUNC(SEL_KEYRELEASE, 0, XFileExplorer::onKeyRelease),
127     FXMAPFUNC(SEL_SIGNAL, XFileExplorer::ID_HARVEST, XFileExplorer::onSigHarvest),
128     FXMAPFUNC(SEL_SIGNAL, XFileExplorer::ID_QUIT, XFileExplorer::onQuit),
129     FXMAPFUNC(SEL_CLOSE, 0, XFileExplorer::onQuit),
130     FXMAPFUNC(SEL_COMMAND, XFileExplorer::ID_FILE_SEARCH, XFileExplorer::onCmdFileSearch),
131     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_DIR_FORWARD_HIST, XFileExplorer::onUpdDirForwardHist),
132     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_DIR_BACK_HIST, XFileExplorer::onUpdDirBackHist),
133     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_DIR_BACK, XFileExplorer::onUpdDirBack),
134     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_DIR_FORWARD, XFileExplorer::onUpdDirForward),
135     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_TOGGLE_STATUS, XFileExplorer::onUpdToggleStatus),
136     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_HORZ_PANELS, XFileExplorer::onUpdHorzVertPanels),
137     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_VERT_PANELS, XFileExplorer::onUpdHorzVertPanels),
138     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_SHOW_ONE_PANEL, XFileExplorer::onUpdShowPanels),
139     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_SHOW_TWO_PANELS, XFileExplorer::onUpdShowPanels),
140     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_SHOW_TREE_PANEL, XFileExplorer::onUpdShowPanels),
141     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_SHOW_TREE_TWO_PANELS, XFileExplorer::onUpdShowPanels),
142     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_GOTO_LOCATION, XFileExplorer::onUpdFileLocation),
143     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_EMPTY_TRASH, XFileExplorer::onUpdEmptyTrash),
144     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_EMPTY_TRASH, XFileExplorer::onUpdTrashSize),
145     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_DELETE, XFileExplorer::onUpdFileDelete),
146     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_TRASH, XFileExplorer::onUpdFileTrash),
147     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_RESTORE, XFileExplorer::onUpdFileRestore),
148     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_RENAME, XFileExplorer::onUpdFileRename),
149     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_PROPERTIES, XFileExplorer::onUpdFileMan),
150     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_COPYTO, XFileExplorer::onUpdFileMan),
151     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_MOVETO, XFileExplorer::onUpdFileMan),
152     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_SYMLINK, XFileExplorer::onUpdFileMan),
153     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_COPY, XFileExplorer::onUpdFileMan),
154     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_CUT, XFileExplorer::onUpdFileMan),
155     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_PASTE, XFileExplorer::onUpdFilePaste),
156     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_SYNCHRONIZE_PANELS, XFileExplorer::onUpdSynchronizePanels),
157     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_SWITCH_PANELS, XFileExplorer::onUpdSwitchPanels),
158     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_SU, XFileExplorer::onUpdSu),
159     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_QUIT, XFileExplorer::onUpdQuit),
160     FXMAPFUNC(SEL_UPDATE, XFileExplorer::ID_FILE_SEARCH, XFileExplorer::onUpdFileSearch),
161 };
162 
163 
164 // Object implementation
FXIMPLEMENT(XFileExplorer,FXMainWindow,XFileExplorerMap,ARRAYNUMBER (XFileExplorerMap))165 FXIMPLEMENT(XFileExplorer, FXMainWindow, XFileExplorerMap, ARRAYNUMBER(XFileExplorerMap))
166 
167 
168 
169 // Make some windows
170 XFileExplorer::XFileExplorer(FXApp* app, vector_FXString URIs, const FXbool iconic, const FXbool maximized, const char* title, FXIcon* bigicon, FXIcon* miniicon) :
171     FXMainWindow(app, title, bigicon, miniicon, DECOR_ALL)
172 {
173     bookmarks = new Bookmarks("bookmarks", this, ID_BOOKMARK);
174 
175     // Menu bar
176     menubar = new FXMenuBar(this, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|FRAME_RAISED);
177 
178     // Site where to dock (for toolbars)
179     FXDockSite* topdock = new FXDockSite(this, LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
180 
181     // General toolbar
182     FXToolBarShell* dragshell1 = new FXToolBarShell(this, FRAME_RAISED);
183     generaltoolbar = new FXToolBar(topdock, dragshell1, LAYOUT_DOCK_NEXT|LAYOUT_SIDE_TOP|FRAME_RAISED|LAYOUT_FILL_Y);
184     new FXToolBarGrip(generaltoolbar, generaltoolbar, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
185 
186     // Tools toolbar
187     FXToolBarShell* dragshell2 = new FXToolBarShell(this, FRAME_RAISED);
188     toolstoolbar = new FXToolBar(topdock, dragshell2, LAYOUT_DOCK_SAME|LAYOUT_SIDE_TOP|FRAME_RAISED|LAYOUT_FILL_Y);
189     new FXToolBarGrip(toolstoolbar, toolstoolbar, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
190 
191     // Panel toolbar
192     FXToolBarShell* dragshell3 = new FXToolBarShell(this, FRAME_RAISED);
193     paneltoolbar = new FXToolBar(topdock, dragshell3, LAYOUT_DOCK_SAME|LAYOUT_SIDE_TOP|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
194     new FXToolBarGrip(paneltoolbar, paneltoolbar, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
195 
196     // Location bar
197     FXToolBarShell* dragshell4 = new FXToolBarShell(this, FRAME_RAISED);
198     locationbar = new FXToolBar(topdock, dragshell4, LAYOUT_DOCK_NEXT|LAYOUT_SIDE_TOP|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y);
199     new FXToolBarGrip(locationbar, locationbar, FXToolBar::ID_TOOLBARGRIP, TOOLBARGRIP_DOUBLE);
200 
201     // Main splitter
202     FXHorizontalFrame* hframe = new FXHorizontalFrame(this, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
203     FXSplitter*        mainsplit = new FXSplitter(hframe, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_TRACKING|FRAME_NONE);
204 
205     // File list background, foreground, highlight, progress bar and attention colors
206     listbackcolor = getApp()->reg().readColorEntry("SETTINGS", "listbackcolor", FXRGB(255, 255, 255));
207     listforecolor = getApp()->reg().readColorEntry("SETTINGS", "listforecolor", FXRGB(0, 0, 0));
208     highlightcolor = getApp()->reg().readColorEntry("SETTINGS", "highlightcolor", FXRGB(238, 238, 238));
209     pbarcolor = getApp()->reg().readColorEntry("SETTINGS", "pbarcolor", FXRGB(0, 0, 255));
210     attentioncolor = getApp()->reg().readColorEntry("SETTINGS", "attentioncolor", FXRGB(255, 0, 0));
211     scrollbarcolor = getApp()->reg().readColorEntry("SETTINGS", "scrollbarcolor", FXRGB(237, 233, 227));
212 
213     // Smooth scrolling
214     smoothscroll = getApp()->reg().readUnsignedEntry("SETTINGS", "smooth_scroll", true);
215 
216     // Directory panel on the left (with minimum size)
217     dirpanel = new DirPanel(this, mainsplit, listbackcolor, listforecolor, smoothscroll, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_NONE, 0, 0, 0, 0);
218 
219     // Splitter containing the two panels
220     panelsplit = new FXSplitter(mainsplit, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_TRACKING|FRAME_NONE);
221 
222     // Stack file panels horizontally or vertically	(directory panel is always vertical)
223     vertpanels = getApp()->reg().readUnsignedEntry("OPTIONS", "vert_panels", true);
224     if (vertpanels)
225     {
226         panelsplit->setSplitterStyle(panelsplit->getSplitterStyle()&~SPLITTER_VERTICAL);
227     }
228     else
229     {
230         panelsplit->setSplitterStyle(panelsplit->getSplitterStyle()|SPLITTER_VERTICAL);
231     }
232 
233     // File panels on the right : remembers size of each field
234     lpanel = new FilePanel(this, "LEFT PANEL", panelsplit, dirpanel,
235                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "name_size", 200),
236                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "size_size", 60),
237                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "type_size", 100),
238                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "ext_size", 100),
239                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "modd_size", 150),
240                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "user_size", 50),
241                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "grou_size", 50),
242                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "attr_size", 100),
243                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "deldate_size", 150),
244                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "origpath_size", 200),
245                            getApp()->reg().readUnsignedEntry("LEFT PANEL", "showthumbnails", 0),
246                            listbackcolor, listforecolor, attentioncolor, smoothscroll,
247                            LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_NONE, 0, 0, 0, 0);
248 
249     rpanel = new FilePanel(this, "RIGHT PANEL", panelsplit, dirpanel,
250                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "name_size", 200),
251                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "size_size", 60),
252                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "type_size", 100),
253                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "ext_size", 100),
254                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "modd_size", 150),
255                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "user_size", 50),
256                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "grou_size", 50),
257                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "attr_size", 100),
258                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "deldate_size", 150),
259                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "origpath_size", 200),
260                            getApp()->reg().readUnsignedEntry("RIGHT PANEL", "showthumbnails", 0),
261                            listbackcolor, listforecolor, attentioncolor, smoothscroll,
262                            LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_NONE, 0, 0, 0, 0);
263 
264     lpanel->Next(rpanel);
265     rpanel->Next(lpanel);
266     lpanel->setActive();
267 
268     FXString sort_func;
269 
270     // Dir panel options
271     sort_func = getApp()->reg().readStringEntry("DIR PANEL", "sort_func", "ascendingCase");
272     if (sort_func == "ascendingCase")
273     {
274         dirpanel->setSortFunc(DirList::ascendingCase);
275     }
276     else if (sort_func == "descendingCase")
277     {
278         dirpanel->setSortFunc(DirList::descendingCase);
279     }
280     else if (sort_func == "ascending")
281     {
282         dirpanel->setSortFunc(DirList::ascending);
283     }
284     else if (sort_func == "descending")
285     {
286         dirpanel->setSortFunc(DirList::descending);
287     }
288 
289     // Left panel options
290     sort_func = getApp()->reg().readStringEntry("LEFT PANEL", "sort_func", "ascendingCase");
291     if (sort_func == "ascendingCase")
292     {
293         lpanel->setSortFunc(FileList::ascendingCase);
294     }
295     else if (sort_func == "ascendingCaseMix")
296     {
297         lpanel->setSortFunc(FileList::ascendingCaseMix);
298     }
299     else if (sort_func == "descendingCase")
300     {
301         lpanel->setSortFunc(FileList::descendingCase);
302     }
303     else if (sort_func == "descendingCaseMix")
304     {
305         lpanel->setSortFunc(FileList::descendingCaseMix);
306     }
307     else if (sort_func == "ascending")
308     {
309         lpanel->setSortFunc(FileList::ascending);
310     }
311     else if (sort_func == "ascendingMix")
312     {
313         lpanel->setSortFunc(FileList::ascendingMix);
314     }
315     else if (sort_func == "descending")
316     {
317         lpanel->setSortFunc(FileList::descending);
318     }
319     else if (sort_func == "descendingMix")
320     {
321         lpanel->setSortFunc(FileList::descendingMix);
322     }
323     else if (sort_func == "ascendingSize")
324     {
325         lpanel->setSortFunc(FileList::ascendingSize);
326     }
327     else if (sort_func == "ascendingSizeMix")
328     {
329         lpanel->setSortFunc(FileList::ascendingSizeMix);
330     }
331     else if (sort_func == "descendingSize")
332     {
333         lpanel->setSortFunc(FileList::descendingSize);
334     }
335     else if (sort_func == "descendingSizeMix")
336     {
337         lpanel->setSortFunc(FileList::descendingSizeMix);
338     }
339     else if (sort_func == "ascendingType")
340     {
341         lpanel->setSortFunc(FileList::ascendingType);
342     }
343     else if (sort_func == "ascendingTypeMix")
344     {
345         lpanel->setSortFunc(FileList::ascendingTypeMix);
346     }
347     else if (sort_func == "descendingType")
348     {
349         lpanel->setSortFunc(FileList::descendingType);
350     }
351     else if (sort_func == "descendingTypeMix")
352     {
353         lpanel->setSortFunc(FileList::descendingTypeMix);
354     }
355     else if (sort_func == "ascendingExt")
356     {
357         lpanel->setSortFunc(FileList::ascendingExt);
358     }
359     else if (sort_func == "ascendingExtMix")
360     {
361         lpanel->setSortFunc(FileList::ascendingExtMix);
362     }
363     else if (sort_func == "descendingExt")
364     {
365         lpanel->setSortFunc(FileList::descendingExt);
366     }
367     else if (sort_func == "descendingExtMix")
368     {
369         lpanel->setSortFunc(FileList::descendingExtMix);
370     }
371     else if (sort_func == "ascendingTime")
372     {
373         lpanel->setSortFunc(FileList::ascendingTime);
374     }
375     else if (sort_func == "ascendingTimeMix")
376     {
377         lpanel->setSortFunc(FileList::ascendingTimeMix);
378     }
379     else if (sort_func == "descendingTime")
380     {
381         lpanel->setSortFunc(FileList::descendingTime);
382     }
383     else if (sort_func == "descendingTimeMix")
384     {
385         lpanel->setSortFunc(FileList::descendingTimeMix);
386     }
387     else if (sort_func == "ascendingUser")
388     {
389         lpanel->setSortFunc(FileList::ascendingUser);
390     }
391     else if (sort_func == "ascendingUserMix")
392     {
393         lpanel->setSortFunc(FileList::ascendingUserMix);
394     }
395     else if (sort_func == "descendingUser")
396     {
397         lpanel->setSortFunc(FileList::descendingUser);
398     }
399     else if (sort_func == "descendingUserMix")
400     {
401         lpanel->setSortFunc(FileList::descendingUserMix);
402     }
403     else if (sort_func == "ascendingGroup")
404     {
405         lpanel->setSortFunc(FileList::ascendingGroup);
406     }
407     else if (sort_func == "ascendingGroupMix")
408     {
409         lpanel->setSortFunc(FileList::ascendingGroupMix);
410     }
411     else if (sort_func == "descendingGroup")
412     {
413         lpanel->setSortFunc(FileList::descendingGroup);
414     }
415     else if (sort_func == "descendingGroupMix")
416     {
417         lpanel->setSortFunc(FileList::descendingGroupMix);
418     }
419     else if (sort_func == "ascendingPerm")
420     {
421         lpanel->setSortFunc(FileList::ascendingPerm);
422     }
423     else if (sort_func == "ascendingPermMix")
424     {
425         lpanel->setSortFunc(FileList::ascendingPermMix);
426     }
427     else if (sort_func == "descendingPerm")
428     {
429         lpanel->setSortFunc(FileList::descendingPerm);
430     }
431     else if (sort_func == "descendingPermMix")
432     {
433         lpanel->setSortFunc(FileList::descendingPermMix);
434     }
435     FXuint ignore_case = getApp()->reg().readUnsignedEntry("LEFT PANEL", "ignore_case", 1);
436     lpanel->setIgnoreCase(ignore_case);
437     FXuint dirs_first = getApp()->reg().readUnsignedEntry("LEFT PANEL", "dirs_first", 1);
438     lpanel->setDirsFirst(dirs_first);
439 
440     // Right panel options
441     sort_func = getApp()->reg().readStringEntry("RIGHT PANEL", "sort_func", "ascendingCase");
442     if (sort_func == "ascendingCase")
443     {
444         rpanel->setSortFunc(FileList::ascendingCase);
445     }
446     else if (sort_func == "ascendingCaseMix")
447     {
448         rpanel->setSortFunc(FileList::ascendingCaseMix);
449     }
450     else if (sort_func == "descendingCase")
451     {
452         rpanel->setSortFunc(FileList::descendingCase);
453     }
454     else if (sort_func == "descendingCaseMix")
455     {
456         rpanel->setSortFunc(FileList::descendingCaseMix);
457     }
458     else if (sort_func == "ascending")
459     {
460         rpanel->setSortFunc(FileList::ascending);
461     }
462     else if (sort_func == "ascendingMix")
463     {
464         rpanel->setSortFunc(FileList::ascendingMix);
465     }
466     else if (sort_func == "descending")
467     {
468         rpanel->setSortFunc(FileList::descending);
469     }
470     else if (sort_func == "descendingMix")
471     {
472         rpanel->setSortFunc(FileList::descendingMix);
473     }
474     else if (sort_func == "ascendingSize")
475     {
476         rpanel->setSortFunc(FileList::ascendingSize);
477     }
478     else if (sort_func == "ascendingSizeMix")
479     {
480         rpanel->setSortFunc(FileList::ascendingSizeMix);
481     }
482     else if (sort_func == "descendingSize")
483     {
484         rpanel->setSortFunc(FileList::descendingSize);
485     }
486     else if (sort_func == "descendingSizeMix")
487     {
488         rpanel->setSortFunc(FileList::descendingSizeMix);
489     }
490     else if (sort_func == "ascendingType")
491     {
492         rpanel->setSortFunc(FileList::ascendingType);
493     }
494     else if (sort_func == "ascendingTypeMix")
495     {
496         rpanel->setSortFunc(FileList::ascendingTypeMix);
497     }
498     else if (sort_func == "descendingType")
499     {
500         rpanel->setSortFunc(FileList::descendingType);
501     }
502     else if (sort_func == "descendingTypeMix")
503     {
504         rpanel->setSortFunc(FileList::descendingTypeMix);
505     }
506     else if (sort_func == "ascendingExt")
507     {
508         rpanel->setSortFunc(FileList::ascendingExt);
509     }
510     else if (sort_func == "ascendingExtMix")
511     {
512         rpanel->setSortFunc(FileList::ascendingExtMix);
513     }
514     else if (sort_func == "descendingExt")
515     {
516         rpanel->setSortFunc(FileList::descendingExt);
517     }
518     else if (sort_func == "descendingExtMix")
519     {
520         rpanel->setSortFunc(FileList::descendingExtMix);
521     }
522     else if (sort_func == "ascendingTime")
523     {
524         rpanel->setSortFunc(FileList::ascendingTime);
525     }
526     else if (sort_func == "ascendingTimeMix")
527     {
528         rpanel->setSortFunc(FileList::ascendingTimeMix);
529     }
530     else if (sort_func == "descendingTime")
531     {
532         rpanel->setSortFunc(FileList::descendingTime);
533     }
534     else if (sort_func == "descendingTimeMix")
535     {
536         rpanel->setSortFunc(FileList::descendingTimeMix);
537     }
538     else if (sort_func == "ascendingUser")
539     {
540         rpanel->setSortFunc(FileList::ascendingUser);
541     }
542     else if (sort_func == "ascendingUserMix")
543     {
544         rpanel->setSortFunc(FileList::ascendingUserMix);
545     }
546     else if (sort_func == "descendingUser")
547     {
548         rpanel->setSortFunc(FileList::descendingUser);
549     }
550     else if (sort_func == "descendingUserMix")
551     {
552         rpanel->setSortFunc(FileList::descendingUserMix);
553     }
554     else if (sort_func == "ascendingGroup")
555     {
556         rpanel->setSortFunc(FileList::ascendingGroup);
557     }
558     else if (sort_func == "ascendingGroupMix")
559     {
560         rpanel->setSortFunc(FileList::ascendingGroupMix);
561     }
562     else if (sort_func == "descendingGroup")
563     {
564         rpanel->setSortFunc(FileList::descendingGroup);
565     }
566     else if (sort_func == "descendingGroupMix")
567     {
568         rpanel->setSortFunc(FileList::descendingGroupMix);
569     }
570     else if (sort_func == "ascendingPerm")
571     {
572         rpanel->setSortFunc(FileList::ascendingPerm);
573     }
574     else if (sort_func == "ascendingPermMix")
575     {
576         rpanel->setSortFunc(FileList::ascendingPermMix);
577     }
578     else if (sort_func == "descendingPerm")
579     {
580         rpanel->setSortFunc(FileList::descendingPerm);
581     }
582     else if (sort_func == "descendingPermMix")
583     {
584         rpanel->setSortFunc(FileList::descendingPermMix);
585     }
586     ignore_case = getApp()->reg().readUnsignedEntry("RIGHT PANEL", "ignore_case", 1);
587     rpanel->setIgnoreCase(ignore_case);
588     dirs_first = getApp()->reg().readUnsignedEntry("RIGHT PANEL", "dirs_first", 1);
589     rpanel->setDirsFirst(dirs_first);
590 
591     FXButton* btn = NULL;
592     FXHotKey  hotkey;
593     FXString  key;
594 
595     // General toolbar
596     key = getApp()->reg().readStringEntry("KEYBINDINGS", "go_back", "Ctrl-Backspace");
597     btn = new FXButton(generaltoolbar, TAB+_("Go to previous folder")+PARS(key), dirbackicon, this, XFileExplorer::ID_DIR_BACK, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
598     hotkey = _parseAccel(key);
599     btn->addHotKey(hotkey);
600 
601     btnbackhist = new FXArrowButton(generaltoolbar, this, XFileExplorer::ID_DIR_BACK_HIST, LAYOUT_FILL_Y|FRAME_RAISED|FRAME_THICK|ARROW_DOWN|ARROW_TOOLBAR);
602 
603     key = getApp()->reg().readStringEntry("KEYBINDINGS", "go_forward", "Shift-Backspace");
604     btn = new FXButton(generaltoolbar, TAB+_("Go to next folder")+PARS(key), dirforwardicon, this, XFileExplorer::ID_DIR_FORWARD, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
605     hotkey = _parseAccel(key);
606     btn->addHotKey(hotkey);
607 
608     btnforwardhist = new FXArrowButton(generaltoolbar, this, XFileExplorer::ID_DIR_FORWARD_HIST, LAYOUT_FILL_Y|FRAME_RAISED|FRAME_THICK|ARROW_DOWN|ARROW_TOOLBAR);
609 
610     key = getApp()->reg().readStringEntry("KEYBINDINGS", "go_up", "Backspace");
611     btn = new FXButton(generaltoolbar, TAB+_("Go to parent folder")+PARS(key), dirupicon, this, XFileExplorer::ID_DIR_UP, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
612     hotkey = _parseAccel(key);
613     btn->addHotKey(hotkey);
614 
615     toolbarSeparator(generaltoolbar);
616 
617     key = getApp()->reg().readStringEntry("KEYBINDINGS", "go_home", "Ctrl-H");
618     new FXButton(generaltoolbar, TAB+_("Go to home folder")+PARS(key), homeicon, lpanel, FilePanel::ID_GO_HOME, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
619 
620     key = getApp()->reg().readStringEntry("KEYBINDINGS", "refresh", "Ctrl-R");
621     new FXButton(generaltoolbar, TAB+_("Refresh panels")+PARS(key), reloadicon, this, XFileExplorer::ID_REFRESH, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
622 
623     toolbarSeparator(generaltoolbar);
624 
625     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_file", "Ctrl-N");
626     new FXButton(generaltoolbar, TAB+_("Create new file")+PARS(key), newfileicon, lpanel, FilePanel::ID_NEW_FILE, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
627 
628     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_folder", "F7");
629     new FXButton(generaltoolbar, TAB+_("Create new folder")+PARS(key), newfoldericon, lpanel, FilePanel::ID_NEW_DIR, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
630 
631     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_symlink", "Ctrl-J");
632     new FXButton(generaltoolbar, TAB+_("Create new symlink")+PARS(key), newlinkicon, lpanel, FilePanel::ID_NEW_SYMLINK, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
633 
634     toolbarSeparator(generaltoolbar);
635 
636     key = getApp()->reg().readStringEntry("KEYBINDINGS", "copy", "Ctrl-C");
637     new FXButton(generaltoolbar, TAB+_("Copy selected files to clipboard")+PARS(key), copy_clpicon, this, XFileExplorer::ID_FILE_COPY, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
638 
639     // Shift + copy key binding can be used to add files to the copy clipboard
640     // but this feature is disabled if the key binding already uses the Shift key
641     if (key.lower().find("shift") < 0)
642     {
643         key = "Shift-" + key;
644         hotkey = _parseAccel(key);
645         getAccelTable()->addAccel(hotkey, this, FXSEL(SEL_COMMAND, XFileExplorer::ID_FILE_ADDCOPY));
646     }
647 
648     // Shift + cut key binding can be used to add files to the cut clipboard
649     // but this feature is disabled if the key binding already uses the Shift key
650     key = getApp()->reg().readStringEntry("KEYBINDINGS", "cut", "Ctrl-X");
651     new FXButton(generaltoolbar, TAB+_("Cut selected files to clipboard")+PARS(key), cut_clpicon, this, XFileExplorer::ID_FILE_CUT, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
652 
653     if (key.lower().find("shift") < 0)
654     {
655         key = "Shift-" + key;
656         hotkey = _parseAccel(key);
657         getAccelTable()->addAccel(hotkey, this, FXSEL(SEL_COMMAND, XFileExplorer::ID_FILE_ADDCUT));
658     }
659 
660     key = getApp()->reg().readStringEntry("KEYBINDINGS", "paste", "Ctrl-V");
661     new FXButton(generaltoolbar, TAB+_("Paste from clipboard")+PARS(key), paste_clpicon, this, XFileExplorer::ID_FILE_PASTE, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
662 
663     key = getApp()->reg().readStringEntry("KEYBINDINGS", "properties", "F9");
664     new FXButton(generaltoolbar, TAB+_("Show properties of selected files")+PARS(key), attribicon, this, XFileExplorer::ID_FILE_PROPERTIES, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
665 
666     toolbarSeparator(generaltoolbar);
667 
668     key = getApp()->reg().readStringEntry("KEYBINDINGS", "move_to_trash", "Del");
669     new FXButton(generaltoolbar, TAB+_("Move selected files to trash can")+PARS(key), filedeleteicon, this, XFileExplorer::ID_FILE_TRASH, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
670 
671     key = getApp()->reg().readStringEntry("KEYBINDINGS", "restore_from_trash", "Alt-Del");
672     new FXButton(generaltoolbar, TAB+_("Restore selected files from trash can")+PARS(key), filerestoreicon, this, XFileExplorer::ID_FILE_RESTORE, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
673 
674     key = getApp()->reg().readStringEntry("KEYBINDINGS", "delete", "Shift-Del");
675     new FXButton(generaltoolbar, TAB+_("Delete selected files")+PARS(key), filedelete_permicon, this, XFileExplorer::ID_FILE_DELETE, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
676 
677     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_window", "F3");
678     new FXButton(toolstoolbar, TAB+_("Launch Xfe")+PARS(key), minixfeicon, this, XFileExplorer::ID_NEW_WIN, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
679 
680     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_root_window", "Shift-F3");
681     new FXButton(toolstoolbar, TAB+_("Launch Xfe as root")+PARS(key), minixferooticon, this, XFileExplorer::ID_SU, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
682 
683     key = getApp()->reg().readStringEntry("KEYBINDINGS", "execute_command", "Ctrl-E");
684     new FXButton(toolstoolbar, TAB+_("Execute command")+PARS(key), runicon, this, XFileExplorer::ID_RUN, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
685 
686     key = getApp()->reg().readStringEntry("KEYBINDINGS", "terminal", "Ctrl-T");
687     new FXButton(toolstoolbar, TAB+_("Launch terminal")+PARS(key), shellicon, this, XFileExplorer::ID_XTERM, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
688 
689     key = getApp()->reg().readStringEntry("KEYBINDINGS", "search", "Ctrl-F");
690     new FXButton(toolstoolbar, _("Search")+TAB+_("Search files and folders...")+PARS(key), searchicon, this, XFileExplorer::ID_FILE_SEARCH, BUTTON_TOOLBAR|ICON_BEFORE_TEXT|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
691 
692 #if defined(linux)
693     toolbarSeparator(toolstoolbar);
694 
695     // Mount and unmount buttons
696     key = getApp()->reg().readStringEntry("KEYBINDINGS", "mount", "Ctrl-M");
697     btn = new FXButton(toolstoolbar, TAB+_("Mount (Linux only)")+PARS(key), maphosticon, lpanel, FilePanel::ID_MOUNT, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
698     hotkey = _parseAccel(key);
699     btn->addHotKey(hotkey);
700 
701     key = getApp()->reg().readStringEntry("KEYBINDINGS", "unmount", "Ctrl-U");
702     btn = new FXButton(toolstoolbar, TAB+_("Unmount (Linux only)")+PARS(key), unmaphosticon, lpanel, FilePanel::ID_UMOUNT, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT);
703     hotkey = _parseAccel(key);
704     btn->addHotKey(hotkey);
705 #endif
706 
707     // Panel toolbar
708 
709     // Show one panel
710     key = getApp()->reg().readStringEntry("KEYBINDINGS", "one_panel", "Ctrl-F1");
711     btn = new FXButton(paneltoolbar, TAB+_("Show one panel")+PARS(key), onepanelicon, this, XFileExplorer::ID_SHOW_ONE_PANEL, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
712     hotkey = _parseAccel(key);
713     btn->addHotKey(hotkey);
714 
715     // Show tree and panel
716     key = getApp()->reg().readStringEntry("KEYBINDINGS", "tree_panel", "Ctrl-F2");
717     btn = new FXButton(paneltoolbar, TAB+_("Show tree and panel")+PARS(key), treeonepanelicon, this, XFileExplorer::ID_SHOW_TREE_PANEL, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
718     hotkey = _parseAccel(key);
719     btn->addHotKey(hotkey);
720 
721     // Show two panels
722     key = getApp()->reg().readStringEntry("KEYBINDINGS", "two_panels", "Ctrl-F3");
723     btn = new FXButton(paneltoolbar, TAB+_("Show two panels")+PARS(key), twopanelsicon, this, XFileExplorer::ID_SHOW_TWO_PANELS, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
724     hotkey = _parseAccel(key);
725     btn->addHotKey(hotkey);
726 
727     // Show tree and two panels
728     key = getApp()->reg().readStringEntry("KEYBINDINGS", "tree_two_panels", "Ctrl-F4");
729     btn = new FXButton(paneltoolbar, TAB+_("Show tree and two panels")+PARS(key), treetwopanelsicon, this, XFileExplorer::ID_SHOW_TREE_TWO_PANELS, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
730     hotkey = _parseAccel(key);
731     btn->addHotKey(hotkey);
732 
733     toolbarSeparator(paneltoolbar);
734 
735     // Vertical panels
736     key = getApp()->reg().readStringEntry("KEYBINDINGS", "vert_panels", "Ctrl-Shift-F1");
737     btn = new FXButton(paneltoolbar, TAB+_("Vertical panels")+PARS(key), vertpanelsicon, this, XFileExplorer::ID_VERT_PANELS, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
738     hotkey = _parseAccel(key);
739     btn->addHotKey(hotkey);
740 
741     // Horizontal panels
742     key = getApp()->reg().readStringEntry("KEYBINDINGS", "horz_panels", "Ctrl-Shift-F2");
743     btn = new FXButton(paneltoolbar, TAB+_("Horizontal panels")+PARS(key), horzpanelsicon, this, XFileExplorer::ID_HORZ_PANELS, BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT);
744     hotkey = _parseAccel(key);
745     btn->addHotKey(hotkey);
746 
747     toolbarSeparator(paneltoolbar);
748 
749     // Switch display modes
750     key = getApp()->reg().readStringEntry("KEYBINDINGS", "big_icons", "F10");
751     btn = new FXButton(paneltoolbar, TAB+_("Big icon list")+PARS(key), bigiconsicon, lpanel, FilePanel::ID_SHOW_BIG_ICONS, BUTTON_TOOLBAR|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT|FRAME_RAISED);
752     hotkey = _parseAccel(key);
753     btn->addHotKey(hotkey);
754 
755     key = getApp()->reg().readStringEntry("KEYBINDINGS", "small_icons", "F11");
756     btn = new FXButton(paneltoolbar, TAB+_("Small icon list")+PARS(key), smalliconsicon, lpanel, FilePanel::ID_SHOW_MINI_ICONS, BUTTON_TOOLBAR|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT|FRAME_RAISED);
757     hotkey = _parseAccel(key);
758     btn->addHotKey(hotkey);
759 
760     key = getApp()->reg().readStringEntry("KEYBINDINGS", "detailed_file_list", "F12");
761     btn = new FXButton(paneltoolbar, TAB+_("Detailed file list")+PARS(key), detailsicon, lpanel, FilePanel::ID_SHOW_DETAILS, BUTTON_TOOLBAR|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT|FRAME_RAISED);
762     hotkey = _parseAccel(key);
763     btn->addHotKey(hotkey);
764 
765     // Location bar
766     new FXLabel(locationbar, _("Location:"));
767     key = getApp()->reg().readStringEntry("KEYBINDINGS", "clear_location", "Ctrl-L");
768     btn = new FXButton(locationbar, TAB+_("Clear location")+PARS(key), locationicon, this, ID_CLEAR_LOCATION, BUTTON_TOOLBAR|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT|FRAME_RAISED);
769     hotkey = _parseAccel(key);
770     btn->addHotKey(hotkey);
771     address = new ComboBox(locationbar, LOCATION_BAR_LENGTH, this, ID_GOTO_LOCATION, COMBOBOX_INSERT_LAST|JUSTIFY_LEFT|LAYOUT_CENTER_Y);
772     address->setNumVisible(5);
773     new FXButton(locationbar, TAB+_("Go to location"), entericon, this, ID_GOTO_LOCATION, BUTTON_TOOLBAR|LAYOUT_CENTER_Y|LAYOUT_LEFT|ICON_BEFORE_TEXT|FRAME_RAISED);
774 
775     // Menus
776 
777     // File menu
778     filemenu = new FXMenuPane(this);
779     FXMenuCommand* mc = NULL;
780 
781     mc = new FXMenuCommand(filemenu, _("New &file..."), newfileicon, lpanel, FilePanel::ID_NEW_FILE);
782     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_file", "Ctrl-N");
783     mc->setAccelText(key);
784     hotkey = _parseAccel(key);
785     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
786 
787     mc = new FXMenuCommand(filemenu, _("New fo&lder..."), newfoldericon, lpanel, FilePanel::ID_NEW_DIR);
788     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_folder", "F7");
789     mc->setAccelText(key);
790     hotkey = _parseAccel(key);
791     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
792 
793     mc = new FXMenuCommand(filemenu, _("New s&ymlink..."), newlinkicon, lpanel, FilePanel::ID_NEW_SYMLINK);
794     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_symlink", "Ctrl-J");
795     mc->setAccelText(key);
796     hotkey = _parseAccel(key);
797     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
798 
799     mc = new FXMenuCommand(filemenu, _("Go &home"), homeicon, lpanel, FilePanel::ID_GO_HOME);
800     key = getApp()->reg().readStringEntry("KEYBINDINGS", "go_home", "Ctrl-H");
801     mc->setAccelText(key);
802     hotkey = _parseAccel(key);
803     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
804 
805     mc = new FXMenuCommand(filemenu, _("&Refresh"), reloadicon, this, XFileExplorer::ID_REFRESH);
806     key = getApp()->reg().readStringEntry("KEYBINDINGS", "refresh", "Ctrl-R");
807     mc->setAccelText(key);
808     hotkey = _parseAccel(key);
809     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
810 
811     new FXMenuSeparator(filemenu);
812 
813     mc = new FXMenuCommand(filemenu, _("&Open"), fileopenicon, lpanel, FilePanel::ID_OPEN);
814     key = getApp()->reg().readStringEntry("KEYBINDINGS", "open", "Ctrl-O");
815     mc->setAccelText(key);
816     hotkey = _parseAccel(key);
817     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
818 
819     mc = new FXMenuCommand(filemenu, _("Re&name..."), renameiticon, this, XFileExplorer::ID_FILE_RENAME);
820     key = getApp()->reg().readStringEntry("KEYBINDINGS", "rename", "F2");
821     mc->setAccelText(key);
822     hotkey = _parseAccel(key);
823     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
824 
825     mc = new FXMenuCommand(filemenu, _("&Copy to..."), copy_clpicon, this, XFileExplorer::ID_FILE_COPYTO);
826     key = getApp()->reg().readStringEntry("KEYBINDINGS", "copy_to", "F5");
827     mc->setAccelText(key);
828     hotkey = _parseAccel(key);
829     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
830 
831     mc = new FXMenuCommand(filemenu, _("&Move to..."), moveiticon, this, XFileExplorer::ID_FILE_MOVETO);
832     key = getApp()->reg().readStringEntry("KEYBINDINGS", "move_to", "F6");
833     mc->setAccelText(key);
834     hotkey = _parseAccel(key);
835     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
836 
837     mc = new FXMenuCommand(filemenu, _("&Symlink to..."), minilinkicon, this, XFileExplorer::ID_FILE_SYMLINK);
838     key = getApp()->reg().readStringEntry("KEYBINDINGS", "symlink_to", "Ctrl-S");
839     mc->setAccelText(key);
840     hotkey = _parseAccel(key);
841     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
842 
843     mc = new FXMenuCommand(filemenu, _("Mo&ve to trash"), filedeleteicon, this, XFileExplorer::ID_FILE_TRASH);
844     key = getApp()->reg().readStringEntry("KEYBINDINGS", "move_to_trash", "Del");
845     mc->setAccelText(key);
846     hotkey = _parseAccel(key);
847     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
848 
849     mc = new FXMenuCommand(filemenu, _("R&estore from trash"), filerestoreicon, this, XFileExplorer::ID_FILE_RESTORE);
850     key = getApp()->reg().readStringEntry("KEYBINDINGS", "restore_from_trash", "Alt-Del");
851     mc->setAccelText(key);
852     hotkey = _parseAccel(key);
853     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
854 
855     mc = new FXMenuCommand(filemenu, _("&Delete"), filedelete_permicon, this, XFileExplorer::ID_FILE_DELETE);
856     key = getApp()->reg().readStringEntry("KEYBINDINGS", "delete", "Shift-Del");
857     mc->setAccelText(key);
858     hotkey = _parseAccel(key);
859     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
860 
861     mc = new FXMenuCommand(filemenu, _("&Properties"), attribicon, this, XFileExplorer::ID_FILE_PROPERTIES);
862     key = getApp()->reg().readStringEntry("KEYBINDINGS", "properties", "F9");
863     mc->setAccelText(key);
864     hotkey = _parseAccel(key);
865     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
866 
867     new FXMenuSeparator(filemenu);
868 
869     mc = new FXMenuCommand(filemenu, _("&Quit"), quiticon, this, XFileExplorer::ID_QUIT);
870     key = getApp()->reg().readStringEntry("KEYBINDINGS", "quit", "Ctrl-Q");
871     mc->setAccelText(key);
872     hotkey = _parseAccel(key);
873     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
874 
875     filemenutitle = new FXMenuTitle(menubar, _("&File"), NULL, filemenu);
876 
877     // Edit menu
878     editmenu = new FXMenuPane(this);
879 
880     mc = new FXMenuCommand(editmenu, _("&Copy"), copy_clpicon, this, XFileExplorer::ID_FILE_COPY);
881     key = getApp()->reg().readStringEntry("KEYBINDINGS", "copy", "Ctrl-C");
882     mc->setAccelText(key);
883     hotkey = _parseAccel(key);
884     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
885 
886     mc = new FXMenuCommand(editmenu, _("C&ut"), cut_clpicon, this, XFileExplorer::ID_FILE_CUT);
887     key = getApp()->reg().readStringEntry("KEYBINDINGS", "cut", "Ctrl-X");
888     mc->setAccelText(key);
889     hotkey = _parseAccel(key);
890     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
891 
892     mc = new FXMenuCommand(editmenu, _("&Paste"), paste_clpicon, this, XFileExplorer::ID_FILE_PASTE);
893     key = getApp()->reg().readStringEntry("KEYBINDINGS", "paste", "Ctrl-V");
894     mc->setAccelText(key);
895     hotkey = _parseAccel(key);
896     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
897 
898     new FXMenuSeparator(editmenu);
899 
900     mc = new FXMenuCommand(editmenu, _("&Select all"), selallicon, lpanel, FilePanel::ID_SELECT_ALL);
901     key = getApp()->reg().readStringEntry("KEYBINDINGS", "select_all", "Ctrl-A");
902     mc->setAccelText(key);
903     hotkey = _parseAccel(key);
904     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
905 
906     mc = new FXMenuCommand(editmenu, _("&Deselect all"), deselicon, lpanel, FilePanel::ID_DESELECT_ALL);
907     key = getApp()->reg().readStringEntry("KEYBINDINGS", "deselect_all", "Ctrl-Z");
908     mc->setAccelText(key);
909     hotkey = _parseAccel(key);
910     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
911 
912     mc = new FXMenuCommand(editmenu, _("&Invert selection"), invselicon, lpanel, FilePanel::ID_SELECT_INVERSE);
913     key = getApp()->reg().readStringEntry("KEYBINDINGS", "invert_selection", "Ctrl-I");
914     mc->setAccelText(key);
915     hotkey = _parseAccel(key);
916     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
917 
918     new FXMenuSeparator(editmenu);
919     new FXMenuCommand(editmenu, _("P&references"), prefsicon, this, XFileExplorer::ID_PREFS);
920 
921     editmenutitle = new FXMenuTitle(menubar, _("&Edit"), NULL, editmenu);
922 
923     // View menu
924     viewmenu = new FXMenuPane(this);
925     new FXMenuCheck(viewmenu, _("&General toolbar"), generaltoolbar, FXWindow::ID_TOGGLESHOWN);
926     new FXMenuCheck(viewmenu, _("&Tools toolbar"), toolstoolbar, FXWindow::ID_TOGGLESHOWN);
927     new FXMenuCheck(viewmenu, _("&Panel toolbar"), paneltoolbar, FXWindow::ID_TOGGLESHOWN);
928     new FXMenuCheck(viewmenu, _("&Location bar"), locationbar, FXWindow::ID_TOGGLESHOWN);
929     new FXMenuCheck(viewmenu, _("&Status bar"), this, XFileExplorer::ID_TOGGLE_STATUS);
930 
931     new FXMenuSeparator(viewmenu);
932 
933     mc = new FXMenuRadio(viewmenu, _("&One panel"), this, XFileExplorer::ID_SHOW_ONE_PANEL);
934     key = getApp()->reg().readStringEntry("KEYBINDINGS", "one_panel", "Ctrl-F1");
935     mc->setAccelText(key);
936 
937     mc = new FXMenuRadio(viewmenu, _("T&ree and panel"), this, XFileExplorer::ID_SHOW_TREE_PANEL);
938     key = getApp()->reg().readStringEntry("KEYBINDINGS", "tree_panel", "Ctrl-F2");
939     mc->setAccelText(key);
940 
941     mc = new FXMenuRadio(viewmenu, _("Two &panels"), this, XFileExplorer::ID_SHOW_TWO_PANELS);
942     key = getApp()->reg().readStringEntry("KEYBINDINGS", "two_panels", "Ctrl-F3");
943     mc->setAccelText(key);
944 
945     mc = new FXMenuRadio(viewmenu, _("Tr&ee and two panels"), this, XFileExplorer::ID_SHOW_TREE_TWO_PANELS);
946     key = getApp()->reg().readStringEntry("KEYBINDINGS", "tree_two_panels", "Ctrl-F4");
947     mc->setAccelText(key);
948 
949     new FXMenuSeparator(viewmenu);
950 
951     mc = new FXMenuRadio(viewmenu, _("&Vertical panels"), this, XFileExplorer::ID_VERT_PANELS);
952     key = getApp()->reg().readStringEntry("KEYBINDINGS", "vert_panels", "Ctrl-Shift-F1");
953     mc->setAccelText(key);
954 
955     mc = new FXMenuRadio(viewmenu, _("&Horizontal panels"), this, XFileExplorer::ID_HORZ_PANELS);
956     key = getApp()->reg().readStringEntry("KEYBINDINGS", "horz_panels", "Ctrl-Shift-F2");
957     mc->setAccelText(key);
958 
959     viewmenutitle = new FXMenuTitle(menubar, _("&View"), NULL, viewmenu);
960 
961     // Bookmarks menu
962     bookmarksmenu = new FXMenuPane(this);
963     mc = new FXMenuCommand(bookmarksmenu, _("&Add bookmark"), setbookicon, this, ID_ADD_BOOKMARK);
964     key = getApp()->reg().readStringEntry("KEYBINDINGS", "add_bookmark", "Ctrl-B");
965     mc->setAccelText(key);
966     hotkey = _parseAccel(key);
967     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
968 
969     new FXMenuSeparator(bookmarksmenu);
970     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_1);
971     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_2);
972     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_3);
973     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_4);
974     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_5);
975     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_6);
976     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_7);
977     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_8);
978     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_9);
979     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_10);
980     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_11);
981     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_12);
982     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_13);
983     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_14);
984     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_15);
985     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_16);
986     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_17);
987     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_18);
988     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_19);
989     new FXMenuCommand(bookmarksmenu, FXString::null, NULL, bookmarks, Bookmarks::ID_BOOKMARK_20);
990     new FXMenuSeparator(bookmarksmenu);
991     new FXMenuCommand(bookmarksmenu, _("&Clear bookmarks"), clrbookicon, bookmarks, Bookmarks::ID_CLEAR);
992 
993     bookmarksmenutitle = new FXMenuTitle(menubar, _("&Bookmarks"), NULL, bookmarksmenu);
994 
995     // Left Panel Menu
996     lpanelmenu = new FXMenuPane(this);
997     new FXMenuCommand(lpanelmenu, _("&Filter..."), filtericon, lpanel, FilePanel::ID_FILTER);
998     new FXMenuCheck(lpanelmenu, _("&Hidden files"), lpanel->getList(), FileList::ID_TOGGLE_HIDDEN);
999     new FXMenuCheck(lpanelmenu, _("&Thumbnails"), lpanel->getList(), FileList::ID_TOGGLE_THUMBNAILS);
1000     new FXMenuSeparator(lpanelmenu);
1001     new FXMenuRadio(lpanelmenu, _("&Big icons"), lpanel->getList(), IconList::ID_SHOW_BIG_ICONS);
1002     new FXMenuRadio(lpanelmenu, _("&Small icons"), lpanel->getList(), IconList::ID_SHOW_MINI_ICONS);
1003     new FXMenuRadio(lpanelmenu, _("F&ull file list"), lpanel->getList(), IconList::ID_SHOW_DETAILS);
1004     new FXMenuSeparator(lpanelmenu);
1005     new FXMenuRadio(lpanelmenu, _("&Rows"), lpanel->getList(), FileList::ID_ARRANGE_BY_ROWS);
1006     new FXMenuRadio(lpanelmenu, _("&Columns"), lpanel->getList(), FileList::ID_ARRANGE_BY_COLUMNS);
1007     new FXMenuCheck(lpanelmenu, _("Autosize"), lpanel->getList(), FileList::ID_AUTOSIZE);
1008     new FXMenuSeparator(lpanelmenu);
1009     new FXMenuRadio(lpanelmenu, _("&Name"), lpanel->getList(), FileList::ID_SORT_BY_NAME);
1010     new FXMenuRadio(lpanelmenu, _("Si&ze"), lpanel->getList(), FileList::ID_SORT_BY_SIZE);
1011     new FXMenuRadio(lpanelmenu, _("T&ype"), lpanel->getList(), FileList::ID_SORT_BY_TYPE);
1012     new FXMenuRadio(lpanelmenu, _("E&xtension"), lpanel->getList(), FileList::ID_SORT_BY_EXT);
1013     new FXMenuRadio(lpanelmenu, _("D&ate"), lpanel->getList(), FileList::ID_SORT_BY_TIME);
1014     new FXMenuRadio(lpanelmenu, _("Us&er"), lpanel->getList(), FileList::ID_SORT_BY_USER);
1015     new FXMenuRadio(lpanelmenu, _("Gr&oup"), lpanel->getList(), FileList::ID_SORT_BY_GROUP);
1016     new FXMenuRadio(lpanelmenu, _("&Permissions"), lpanel->getList(), FileList::ID_SORT_BY_PERM);
1017     new FXMenuRadio(lpanelmenu, _("Deletion date"), lpanel->getList(), FileList::ID_SORT_BY_DELTIME);
1018     new FXMenuRadio(lpanelmenu, _("Original path"), lpanel->getList(), FileList::ID_SORT_BY_ORIGPATH);
1019     new FXMenuSeparator(lpanelmenu);
1020     new FXMenuCheck(lpanelmenu, _("I&gnore case"), lpanel->getList(), FileList::ID_SORT_CASE);
1021     new FXMenuCheck(lpanelmenu, _("Fol&ders first"), lpanel->getList(), FileList::ID_DIRS_FIRST);
1022     new FXMenuCheck(lpanelmenu, _("Re&verse order"), lpanel->getList(), FileList::ID_SORT_REVERSE);
1023     lpanelmenutitle = new FXMenuTitle(menubar, _("&Left panel"), NULL, lpanelmenu);
1024 
1025     // Right Panel Menu
1026     rpanelmenu = new FXMenuPane(this);
1027     new FXMenuCommand(rpanelmenu, _("&Filter"), filtericon, rpanel, FilePanel::ID_FILTER);
1028     new FXMenuCheck(rpanelmenu, _("&Hidden files"), rpanel->getList(), FileList::ID_TOGGLE_HIDDEN);
1029     new FXMenuCheck(rpanelmenu, _("&Thumbnails"), rpanel->getList(), FileList::ID_TOGGLE_THUMBNAILS);
1030     new FXMenuSeparator(rpanelmenu);
1031     new FXMenuRadio(rpanelmenu, _("&Big icons"), rpanel->getList(), IconList::ID_SHOW_BIG_ICONS);
1032     new FXMenuRadio(rpanelmenu, _("&Small icons"), rpanel->getList(), IconList::ID_SHOW_MINI_ICONS);
1033     new FXMenuRadio(rpanelmenu, _("F&ull file list"), rpanel->getList(), IconList::ID_SHOW_DETAILS);
1034     new FXMenuSeparator(rpanelmenu);
1035     new FXMenuRadio(rpanelmenu, _("&Rows"), rpanel->getList(), FileList::ID_ARRANGE_BY_ROWS);
1036     new FXMenuRadio(rpanelmenu, _("&Columns"), rpanel->getList(), FileList::ID_ARRANGE_BY_COLUMNS);
1037     new FXMenuCheck(rpanelmenu, _("Autosize"), rpanel->getList(), FileList::ID_AUTOSIZE);
1038     new FXMenuSeparator(rpanelmenu);
1039     new FXMenuRadio(rpanelmenu, _("&Name"), rpanel->getList(), FileList::ID_SORT_BY_NAME);
1040     new FXMenuRadio(rpanelmenu, _("Si&ze"), rpanel->getList(), FileList::ID_SORT_BY_SIZE);
1041     new FXMenuRadio(rpanelmenu, _("T&ype"), rpanel->getList(), FileList::ID_SORT_BY_TYPE);
1042     new FXMenuRadio(rpanelmenu, _("E&xtension"), rpanel->getList(), FileList::ID_SORT_BY_EXT);
1043     new FXMenuRadio(rpanelmenu, _("D&ate"), rpanel->getList(), FileList::ID_SORT_BY_TIME);
1044     new FXMenuRadio(rpanelmenu, _("Us&er"), rpanel->getList(), FileList::ID_SORT_BY_USER);
1045     new FXMenuRadio(rpanelmenu, _("Gr&oup"), rpanel->getList(), FileList::ID_SORT_BY_GROUP);
1046     new FXMenuRadio(rpanelmenu, _("&Permissions"), rpanel->getList(), FileList::ID_SORT_BY_PERM);
1047     new FXMenuRadio(rpanelmenu, _("Deletion date"), rpanel->getList(), FileList::ID_SORT_BY_DELTIME);
1048     new FXMenuRadio(rpanelmenu, _("Original path"), rpanel->getList(), FileList::ID_SORT_BY_ORIGPATH);
1049     new FXMenuSeparator(rpanelmenu);
1050     new FXMenuCheck(rpanelmenu, _("I&gnore case"), rpanel->getList(), FileList::ID_SORT_CASE);
1051     new FXMenuCheck(rpanelmenu, _("&Folders first"), rpanel->getList(), FileList::ID_DIRS_FIRST);
1052     new FXMenuCheck(rpanelmenu, _("Re&verse order"), rpanel->getList(), FileList::ID_SORT_REVERSE);
1053     rpanelmenutitle = new FXMenuTitle(menubar, _("&Right panel"), NULL, rpanelmenu);
1054 
1055     // Tools menu
1056     toolsmenu = new FXMenuPane(this);
1057 
1058     mc = new FXMenuCommand(toolsmenu, _("New &window"), minixfeicon, this, XFileExplorer::ID_NEW_WIN);
1059     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_window", "F3");
1060     mc->setAccelText(key);
1061     hotkey = _parseAccel(key);
1062     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1063 
1064     mc = new FXMenuCommand(toolsmenu, _("New &root window"), minixferooticon, this, XFileExplorer::ID_SU);
1065     key = getApp()->reg().readStringEntry("KEYBINDINGS", "new_root_window", "Shift-F3");
1066     mc->setAccelText(key);
1067     hotkey = _parseAccel(key);
1068     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1069 
1070     new FXMenuSeparator(toolsmenu);
1071 
1072     mc = new FXMenuCommand(toolsmenu, _("E&xecute command..."), runicon, this, ID_RUN);
1073     key = getApp()->reg().readStringEntry("KEYBINDINGS", "execute_command", "Ctrl-E");
1074     mc->setAccelText(key);
1075     hotkey = _parseAccel(key);
1076     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1077 
1078     mc = new FXMenuCommand(toolsmenu, _("&Terminal"), minishellicon, this, XFileExplorer::ID_XTERM);
1079     key = getApp()->reg().readStringEntry("KEYBINDINGS", "terminal", "Ctrl-T");
1080     mc->setAccelText(key);
1081     hotkey = _parseAccel(key);
1082     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1083 
1084     mc = new FXMenuCommand(toolsmenu, _("&Synchronize panels"), syncpanelsicon, this, XFileExplorer::ID_SYNCHRONIZE_PANELS);
1085     key = getApp()->reg().readStringEntry("KEYBINDINGS", "synchronize_panels", "Ctrl-Y");
1086     mc->setAccelText(key);
1087     hotkey = _parseAccel(key);
1088     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1089 
1090     mc = new FXMenuCommand(toolsmenu, _("Sw&itch panels"), switchpanelsicon, this, XFileExplorer::ID_SWITCH_PANELS);
1091     key = getApp()->reg().readStringEntry("KEYBINDINGS", "switch_panels", "Ctrl-K");
1092     mc->setAccelText(key);
1093     hotkey = _parseAccel(key);
1094     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1095 
1096     mc = new FXMenuCommand(toolsmenu, _("Go to script folder"), gotodiricon, lpanel, FilePanel::ID_GO_SCRIPTDIR);
1097 
1098     mc = new FXMenuCommand(toolsmenu, _("&Search files..."), searchicon, this, XFileExplorer::ID_FILE_SEARCH);
1099     key = getApp()->reg().readStringEntry("KEYBINDINGS", "search", "Ctrl-F");
1100     mc->setAccelText(key);
1101     hotkey = _parseAccel(key);
1102     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1103 
1104 #if defined(linux)
1105     new FXMenuSeparator(toolsmenu);
1106 
1107     mc = new FXMenuCommand(toolsmenu, _("&Mount"), maphosticon, lpanel, FilePanel::ID_MOUNT);
1108     key = getApp()->reg().readStringEntry("KEYBINDINGS", "mount", "Ctrl-M");
1109     mc->setAccelText(key);
1110 
1111     mc = new FXMenuCommand(toolsmenu, _("&Unmount"), unmaphosticon, lpanel, FilePanel::ID_UMOUNT);
1112     key = getApp()->reg().readStringEntry("KEYBINDINGS", "unmount", "Ctrl-U");
1113     mc->setAccelText(key);
1114 #endif
1115     toolsmenutitle = new FXMenuTitle(menubar, _("&Tools"), NULL, toolsmenu);
1116 
1117     // Trash menu
1118     trashmenu = new FXMenuPane(this);
1119 
1120     mc = new FXMenuCommand(trashmenu, _("&Go to trash"), totrashicon, lpanel, FilePanel::ID_GO_TRASH);
1121     key = getApp()->reg().readStringEntry("KEYBINDINGS", "go_to_trash", "Ctrl-F8");
1122     mc->setAccelText(key);
1123     hotkey = _parseAccel(key);
1124     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1125 
1126     mc = new FXMenuCommand(trashmenu, _("&Trash size"), filedeleteicon, this, XFileExplorer::ID_TRASH_SIZE);
1127 
1128     mc = new FXMenuCommand(trashmenu, _("&Empty trash can"), trash_fullicon, this, XFileExplorer::ID_EMPTY_TRASH);
1129     key = getApp()->reg().readStringEntry("KEYBINDINGS", "empty_trash_can", "Ctrl-Del");
1130     mc->setAccelText(key);
1131     hotkey = _parseAccel(key);
1132     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1133 
1134 
1135     trashmenutitle = new FXMenuTitle(menubar, _("T&rash"), NULL, trashmenu);
1136 
1137     // Help menu
1138     helpmenu = new FXMenuPane(this);
1139 
1140     mc = new FXMenuCommand(helpmenu, _("&Help"), helpicon, this, ID_HELP);
1141     key = getApp()->reg().readStringEntry("KEYBINDINGS", "help", "F1");
1142     mc->setAccelText(key);
1143     hotkey = _parseAccel(key);
1144     getAccelTable()->addAccel(hotkey, mc, FXSEL(SEL_COMMAND, FXMenuCommand::ID_ACCEL));
1145 
1146     new FXMenuCommand(helpmenu, _("&About X File Explorer"), NULL, this, ID_ABOUT);
1147     helpmenutitle = new FXMenuTitle(menubar, _("&Help"), NULL, helpmenu);
1148 
1149     // Other accelerators
1150 
1151     key = getApp()->reg().readStringEntry("KEYBINDINGS", "edit", "F4");
1152     hotkey = _parseAccel(key);
1153     getAccelTable()->addAccel(hotkey, lpanel, FXSEL(SEL_COMMAND, FilePanel::ID_EDIT));
1154 
1155     key = getApp()->reg().readStringEntry("KEYBINDINGS", "view", "Shift-F4");
1156     hotkey = _parseAccel(key);
1157     getAccelTable()->addAccel(hotkey, lpanel, FXSEL(SEL_COMMAND, FilePanel::ID_VIEW));
1158 
1159     key = getApp()->reg().readStringEntry("KEYBINDINGS", "compare", "F8");
1160     hotkey = _parseAccel(key);
1161     getAccelTable()->addAccel(hotkey, lpanel, FXSEL(SEL_COMMAND, FilePanel::ID_COMPARE));
1162 
1163     key = getApp()->reg().readStringEntry("KEYBINDINGS", "hidden_dirs", "Ctrl-F5");
1164     hotkey = _parseAccel(key);
1165     getAccelTable()->addAccel(hotkey, dirpanel, FXSEL(SEL_COMMAND, DirPanel::ID_TOGGLE_HIDDEN));
1166 
1167     key = getApp()->reg().readStringEntry("KEYBINDINGS", "filter", "Ctrl-D");
1168     hotkey = _parseAccel(key);
1169     getAccelTable()->addAccel(hotkey, lpanel, FXSEL(SEL_COMMAND, FilePanel::ID_FILTER_CURRENT));
1170 
1171     key = getApp()->reg().readStringEntry("KEYBINDINGS", "hidden_files", "Ctrl-F6");
1172     hotkey = _parseAccel(key);
1173     getAccelTable()->addAccel(hotkey, lpanel, FXSEL(SEL_COMMAND, FilePanel::ID_TOGGLE_HIDDEN));
1174 
1175     key = getApp()->reg().readStringEntry("KEYBINDINGS", "thumbnails", "Ctrl-F7");
1176     hotkey = _parseAccel(key);
1177     getAccelTable()->addAccel(hotkey, lpanel, FXSEL(SEL_COMMAND, FilePanel::ID_TOGGLE_THUMBNAILS));
1178 
1179     key = getApp()->reg().readStringEntry("KEYBINDINGS", "close", "Ctrl-W");
1180     hotkey = _parseAccel(key);
1181     getAccelTable()->addAccel(hotkey, this, FXSEL(SEL_COMMAND, XFileExplorer::ID_QUIT));
1182 
1183     // Escape key
1184     getAccelTable()->addAccel(KEY_Escape, lpanel, FXSEL(SEL_COMMAND, FilePanel::ID_DESELECT_ALL));
1185 
1186     // Make a tool tip
1187     new FXToolTip(app, 0);
1188 
1189     // File operations dialog
1190     rundialog = NULL;
1191     prefsdialog = NULL;
1192     helpwindow = NULL;
1193     searchwindow = NULL;
1194 
1195     // Initial focus is on (left) file panel
1196     panelfocus = FILEPANEL_FOCUS;
1197 
1198     // Trahscan locations
1199     trashfileslocation = xdgdatahome + PATHSEPSTRING TRASHFILESPATH;
1200     trashinfolocation = xdgdatahome + PATHSEPSTRING TRASHINFOPATH;
1201 
1202     // Start location (we return to the start location after each chdir)
1203     startlocation = FXSystem::getCurrentDirectory();
1204 
1205     // Other initializations
1206     starticonic = iconic;
1207     startmaximized = maximized;
1208     startdir1 = "";
1209     startdir2 = "";
1210     startURIs = URIs;
1211     nbstartfiles = 0;
1212     stop = false;
1213 
1214     // Class variables initializations
1215     panel_view = 0;
1216     RunHistSize = 0;
1217     liststyle = 0;
1218     twopanels_lpanel_pct = 0.0;
1219     treepanel_tree_pct = 0.0;
1220     treetwopanels_tree_pct = 0.0;
1221     treetwopanels_lpanel_pct = 0.0;
1222     search_xpos = 0;
1223     search_ypos = 0;
1224     search_width = 0;
1225     search_height = 0;
1226     winshow = true;
1227 
1228     // Read URIs to open on startup
1229     // Find if startdir1 and startdir2 are specified
1230     // Get the number of files to open, if any
1231     for (FXuint n = 0; n < startURIs.size(); n++)
1232     {
1233         if (::isDirectory(startURIs[n]))
1234         {
1235             if (startdir1 == "")
1236             {
1237                 startdir1 = startURIs[n];
1238                 continue;
1239             }
1240             if (startdir2 == "")
1241             {
1242                 startdir2 = startURIs[n];
1243                 continue;
1244             }
1245         }
1246         if (::isFile(startURIs[n]))
1247         {
1248             nbstartfiles++;
1249         }
1250     }
1251 
1252     prevdir = FXString::null;
1253     prev_width = getWidth();
1254 }
1255 
1256 
1257 // Save configuration when quitting
saveConfig()1258 void XFileExplorer::saveConfig()
1259 {
1260     // Get autosave flag
1261     FXbool auto_save_layout = getApp()->reg().readUnsignedEntry("OPTIONS", "auto_save_layout", true);
1262 
1263     if (auto_save_layout == true)
1264     {
1265         FXString sort_func;
1266 
1267         // Dir panel options
1268         if (dirpanel->getSortFunc() == DirList::ascendingCase)
1269         {
1270             sort_func = "ascendingCase";
1271         }
1272         else if (dirpanel->getSortFunc() == DirList::descendingCase)
1273         {
1274             sort_func = "descendingCase";
1275         }
1276         else if (dirpanel->getSortFunc() == DirList::ascending)
1277         {
1278             sort_func = "ascending";
1279         }
1280         else if (dirpanel->getSortFunc() == DirList::descending)
1281         {
1282             sort_func = "descending";
1283         }
1284         else
1285         {
1286             sort_func = "ascendingCase";
1287         }
1288         getApp()->reg().writeStringEntry("DIR PANEL", "sort_func", sort_func.text());
1289         getApp()->reg().writeUnsignedEntry("DIR PANEL", "hidden_dir", dirpanel->shownHiddenFiles());
1290 
1291         // Search panel options
1292         if (searchwindow)
1293         {
1294             // Search dialog properties
1295             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "search_xpos", (FXuint)searchwindow->getX());
1296             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "search_ypos", (FXuint)searchwindow->getY());
1297             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "search_width", (FXuint)searchwindow->getWidth());
1298             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "search_height", (FXuint)searchwindow->getHeight());
1299             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "name_size", (FXuint)searchwindow->getHeaderSize(0));
1300             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "dir_size", (FXuint)searchwindow->getHeaderSize(1));
1301             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "size_size", (FXuint)searchwindow->getHeaderSize(2));
1302             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "type_size", (FXuint)searchwindow->getHeaderSize(3));
1303             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "ext_size", (FXuint)searchwindow->getHeaderSize(4));
1304             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "modd_size", (FXuint)searchwindow->getHeaderSize(5));
1305             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "user_size", (FXuint)searchwindow->getHeaderSize(6));
1306             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "grou_size", (FXuint)searchwindow->getHeaderSize(7));
1307             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "attr_size", (FXuint)searchwindow->getHeaderSize(8));
1308             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "showthumbnails", (FXuint)searchwindow->shownThumbnails());
1309             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "find_ignorecase", (FXuint)searchwindow->getFindIgnoreCase());
1310             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "find_hidden", (FXuint)searchwindow->getFindHidden());
1311             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "grep_ignorecase", (FXuint)searchwindow->getGrepIgnoreCase());
1312             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "moreoptions", (FXuint)searchwindow->shownMoreOptions());
1313             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "liststyle", (FXuint)searchwindow->getListStyle());
1314             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "dirs_first", (FXuint)searchwindow->getDirsFirst());
1315             getApp()->reg().writeUnsignedEntry("SEARCH PANEL", "ignore_case", (FXuint)searchwindow->getIgnoreCase());
1316 
1317             // Get and write sort function for search window
1318             if (searchwindow->getSortFunc() == FileList::ascendingCase)
1319             {
1320                 sort_func = "ascendingCase";
1321             }
1322             else if (searchwindow->getSortFunc() == FileList::ascendingCaseMix)
1323             {
1324                 sort_func = "ascendingCaseMix";
1325             }
1326             else if (searchwindow->getSortFunc() == FileList::descendingCase)
1327             {
1328                 sort_func = "descendingCase";
1329             }
1330             else if (searchwindow->getSortFunc() == FileList::descendingCaseMix)
1331             {
1332                 sort_func = "descendingCaseMix";
1333             }
1334             else if (searchwindow->getSortFunc() == FileList::ascending)
1335             {
1336                 sort_func = "ascending";
1337             }
1338             else if (searchwindow->getSortFunc() == FileList::ascendingMix)
1339             {
1340                 sort_func = "ascendingMix";
1341             }
1342             else if (searchwindow->getSortFunc() == FileList::descending)
1343             {
1344                 sort_func = "descending";
1345             }
1346             else if (searchwindow->getSortFunc() == FileList::descendingMix)
1347             {
1348                 sort_func = "descendingMix";
1349             }
1350             else if (searchwindow->getSortFunc() == FileList::ascendingDirCase)
1351             {
1352                 sort_func = "ascendingDirCase";
1353             }
1354             else if (searchwindow->getSortFunc() == FileList::ascendingDirCaseMix)
1355             {
1356                 sort_func = "ascendingDirCaseMix";
1357             }
1358             else if (searchwindow->getSortFunc() == FileList::descendingDirCase)
1359             {
1360                 sort_func = "descendingDirCase";
1361             }
1362             else if (searchwindow->getSortFunc() == FileList::descendingDirCaseMix)
1363             {
1364                 sort_func = "descendingDirCaseMix";
1365             }
1366             else if (searchwindow->getSortFunc() == FileList::ascendingDir)
1367             {
1368                 sort_func = "ascendingDir";
1369             }
1370             else if (searchwindow->getSortFunc() == FileList::ascendingDirMix)
1371             {
1372                 sort_func = "ascendingDirMix";
1373             }
1374             else if (searchwindow->getSortFunc() == FileList::descendingDir)
1375             {
1376                 sort_func = "descendingDir";
1377             }
1378             else if (searchwindow->getSortFunc() == FileList::descendingDirMix)
1379             {
1380                 sort_func = "descendingDirMix";
1381             }
1382             else if (searchwindow->getSortFunc() == FileList::ascendingSize)
1383             {
1384                 sort_func = "ascendingSize";
1385             }
1386             else if (searchwindow->getSortFunc() == FileList::ascendingSizeMix)
1387             {
1388                 sort_func = "ascendingSizeMix";
1389             }
1390             else if (searchwindow->getSortFunc() == FileList::descendingSize)
1391             {
1392                 sort_func = "descendingSize";
1393             }
1394             else if (searchwindow->getSortFunc() == FileList::descendingSizeMix)
1395             {
1396                 sort_func = "descendingSizeMix";
1397             }
1398             else if (searchwindow->getSortFunc() == FileList::ascendingType)
1399             {
1400                 sort_func = "ascendingType";
1401             }
1402             else if (searchwindow->getSortFunc() == FileList::ascendingTypeMix)
1403             {
1404                 sort_func = "ascendingTypeMix";
1405             }
1406             else if (searchwindow->getSortFunc() == FileList::descendingType)
1407             {
1408                 sort_func = "descendingType";
1409             }
1410             else if (searchwindow->getSortFunc() == FileList::descendingTypeMix)
1411             {
1412                 sort_func = "descendingTypeMix";
1413             }
1414             else if (searchwindow->getSortFunc() == FileList::ascendingExt)
1415             {
1416                 sort_func = "ascendingExt";
1417             }
1418             else if (searchwindow->getSortFunc() == FileList::ascendingExtMix)
1419             {
1420                 sort_func = "ascendingExtMix";
1421             }
1422             else if (searchwindow->getSortFunc() == FileList::descendingExt)
1423             {
1424                 sort_func = "descendingExt";
1425             }
1426             else if (searchwindow->getSortFunc() == FileList::descendingExtMix)
1427             {
1428                 sort_func = "descendingExtMix";
1429             }
1430             else if (searchwindow->getSortFunc() == FileList::ascendingTime)
1431             {
1432                 sort_func = "ascendingTime";
1433             }
1434             else if (searchwindow->getSortFunc() == FileList::ascendingTimeMix)
1435             {
1436                 sort_func = "ascendingTimeMix";
1437             }
1438             else if (searchwindow->getSortFunc() == FileList::descendingTime)
1439             {
1440                 sort_func = "descendingTime";
1441             }
1442             else if (searchwindow->getSortFunc() == FileList::descendingTimeMix)
1443             {
1444                 sort_func = "descendingTimeMix";
1445             }
1446             else if (searchwindow->getSortFunc() == FileList::ascendingUser)
1447             {
1448                 sort_func = "ascendingUser";
1449             }
1450             else if (searchwindow->getSortFunc() == FileList::ascendingUserMix)
1451             {
1452                 sort_func = "ascendingUserMix";
1453             }
1454             else if (searchwindow->getSortFunc() == FileList::descendingUser)
1455             {
1456                 sort_func = "descendingUser";
1457             }
1458             else if (searchwindow->getSortFunc() == FileList::descendingUserMix)
1459             {
1460                 sort_func = "descendingUserMix";
1461             }
1462             else if (searchwindow->getSortFunc() == FileList::ascendingGroup)
1463             {
1464                 sort_func = "ascendingGroup";
1465             }
1466             else if (searchwindow->getSortFunc() == FileList::ascendingGroupMix)
1467             {
1468                 sort_func = "ascendingGroupMix";
1469             }
1470             else if (searchwindow->getSortFunc() == FileList::descendingGroup)
1471             {
1472                 sort_func = "descendingGroup";
1473             }
1474             else if (searchwindow->getSortFunc() == FileList::descendingGroupMix)
1475             {
1476                 sort_func = "descendingGroupMix";
1477             }
1478             else if (searchwindow->getSortFunc() == FileList::ascendingPerm)
1479             {
1480                 sort_func = "ascendingPerm";
1481             }
1482             else if (searchwindow->getSortFunc() == FileList::ascendingPermMix)
1483             {
1484                 sort_func = "ascendingPermMix";
1485             }
1486             else if (searchwindow->getSortFunc() == FileList::descendingPerm)
1487             {
1488                 sort_func = "descendingPerm";
1489             }
1490             else if (searchwindow->getSortFunc() == FileList::descendingPermMix)
1491             {
1492                 sort_func = "descendingPermMix";
1493             }
1494             else
1495             {
1496                 sort_func = "ascendingCase";
1497             }
1498             getApp()->reg().writeStringEntry("SEARCH PANEL", "sort_func", sort_func.text());
1499         }
1500 
1501         // Left panel options
1502         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "name_size", lpanel->getHeaderSize(0));
1503         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "size_size", lpanel->getHeaderSize(1));
1504         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "type_size", lpanel->getHeaderSize(2));
1505         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "ext_size", lpanel->getHeaderSize(3));
1506         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "modd_size", lpanel->getHeaderSize(4));
1507         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "user_size", lpanel->getHeaderSize(5));
1508         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "grou_size", lpanel->getHeaderSize(6));
1509         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "attr_size", lpanel->getHeaderSize(7));
1510         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "deldate_size", lpanel->getHeaderSize(8));
1511         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "origpath_size", lpanel->getHeaderSize(9));
1512         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "liststyle", lpanel->getListStyle());
1513         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "hiddenfiles", lpanel->shownHiddenFiles());
1514         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "showthumbnails", lpanel->shownThumbnails());
1515 
1516         // Get and write sort function for left panel
1517         if (lpanel->getSortFunc() == FileList::ascendingCase)
1518         {
1519             sort_func = "ascendingCase";
1520         }
1521         else if (lpanel->getSortFunc() == FileList::ascendingCaseMix)
1522         {
1523             sort_func = "ascendingCaseMix";
1524         }
1525         else if (lpanel->getSortFunc() == FileList::descendingCase)
1526         {
1527             sort_func = "descendingCase";
1528         }
1529         else if (lpanel->getSortFunc() == FileList::descendingCaseMix)
1530         {
1531             sort_func = "descendingCaseMix";
1532         }
1533         else if (lpanel->getSortFunc() == FileList::ascending)
1534         {
1535             sort_func = "ascending";
1536         }
1537         else if (lpanel->getSortFunc() == FileList::ascendingMix)
1538         {
1539             sort_func = "ascendingMix";
1540         }
1541         else if (lpanel->getSortFunc() == FileList::descending)
1542         {
1543             sort_func = "descending";
1544         }
1545         else if (lpanel->getSortFunc() == FileList::descendingMix)
1546         {
1547             sort_func = "descendingMix";
1548         }
1549         else if (lpanel->getSortFunc() == FileList::ascendingSize)
1550         {
1551             sort_func = "ascendingSize";
1552         }
1553         else if (lpanel->getSortFunc() == FileList::ascendingSizeMix)
1554         {
1555             sort_func = "ascendingSizeMix";
1556         }
1557         else if (lpanel->getSortFunc() == FileList::descendingSize)
1558         {
1559             sort_func = "descendingSize";
1560         }
1561         else if (lpanel->getSortFunc() == FileList::descendingSizeMix)
1562         {
1563             sort_func = "descendingSizeMix";
1564         }
1565         else if (lpanel->getSortFunc() == FileList::ascendingType)
1566         {
1567             sort_func = "ascendingType";
1568         }
1569         else if (lpanel->getSortFunc() == FileList::ascendingTypeMix)
1570         {
1571             sort_func = "ascendingTypeMix";
1572         }
1573         else if (lpanel->getSortFunc() == FileList::descendingType)
1574         {
1575             sort_func = "descendingType";
1576         }
1577         else if (lpanel->getSortFunc() == FileList::descendingTypeMix)
1578         {
1579             sort_func = "descendingTypeMix";
1580         }
1581         else if (lpanel->getSortFunc() == FileList::ascendingExt)
1582         {
1583             sort_func = "ascendingExt";
1584         }
1585         else if (lpanel->getSortFunc() == FileList::ascendingExtMix)
1586         {
1587             sort_func = "ascendingExtMix";
1588         }
1589         else if (lpanel->getSortFunc() == FileList::descendingExt)
1590         {
1591             sort_func = "descendingExt";
1592         }
1593         else if (lpanel->getSortFunc() == FileList::descendingExtMix)
1594         {
1595             sort_func = "descendingExtMix";
1596         }
1597         else if (lpanel->getSortFunc() == FileList::ascendingTime)
1598         {
1599             sort_func = "ascendingTime";
1600         }
1601         else if (lpanel->getSortFunc() == FileList::ascendingTimeMix)
1602         {
1603             sort_func = "ascendingTimeMix";
1604         }
1605         else if (lpanel->getSortFunc() == FileList::descendingTime)
1606         {
1607             sort_func = "descendingTime";
1608         }
1609         else if (lpanel->getSortFunc() == FileList::descendingTimeMix)
1610         {
1611             sort_func = "descendingTimeMix";
1612         }
1613         else if (lpanel->getSortFunc() == FileList::ascendingUser)
1614         {
1615             sort_func = "ascendingUser";
1616         }
1617         else if (lpanel->getSortFunc() == FileList::ascendingUserMix)
1618         {
1619             sort_func = "ascendingUserMix";
1620         }
1621         else if (lpanel->getSortFunc() == FileList::descendingUser)
1622         {
1623             sort_func = "descendingUser";
1624         }
1625         else if (lpanel->getSortFunc() == FileList::descendingUserMix)
1626         {
1627             sort_func = "descendingUserMix";
1628         }
1629         else if (lpanel->getSortFunc() == FileList::ascendingGroup)
1630         {
1631             sort_func = "ascendingGroup";
1632         }
1633         else if (lpanel->getSortFunc() == FileList::ascendingGroupMix)
1634         {
1635             sort_func = "ascendingGroupMix";
1636         }
1637         else if (lpanel->getSortFunc() == FileList::descendingGroup)
1638         {
1639             sort_func = "descendingGroup";
1640         }
1641         else if (lpanel->getSortFunc() == FileList::descendingGroupMix)
1642         {
1643             sort_func = "descendingGroupMix";
1644         }
1645         else if (lpanel->getSortFunc() == FileList::ascendingPerm)
1646         {
1647             sort_func = "ascendingPerm";
1648         }
1649         else if (lpanel->getSortFunc() == FileList::ascendingPermMix)
1650         {
1651             sort_func = "ascendingPermMix";
1652         }
1653         else if (lpanel->getSortFunc() == FileList::descendingPerm)
1654         {
1655             sort_func = "descendingPerm";
1656         }
1657         else if (lpanel->getSortFunc() == FileList::descendingPermMix)
1658         {
1659             sort_func = "descendingPermMix";
1660         }
1661         else
1662         {
1663             sort_func = "ascendingCase";
1664         }
1665         getApp()->reg().writeStringEntry("LEFT PANEL", "sort_func", sort_func.text());
1666         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "ignore_case", lpanel->getIgnoreCase());
1667         getApp()->reg().writeUnsignedEntry("LEFT PANEL", "dirs_first", lpanel->getDirsFirst());
1668 
1669         // Right panel options
1670         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "name_size", rpanel->getHeaderSize(0));
1671         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "size_size", rpanel->getHeaderSize(1));
1672         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "type_size", rpanel->getHeaderSize(2));
1673         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "ext_size", rpanel->getHeaderSize(3));
1674         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "modd_size", rpanel->getHeaderSize(4));
1675         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "user_size", rpanel->getHeaderSize(5));
1676         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "grou_size", rpanel->getHeaderSize(6));
1677         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "attr_size", rpanel->getHeaderSize(7));
1678         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "deldate_size", rpanel->getHeaderSize(8));
1679         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "origpath_size", rpanel->getHeaderSize(9));
1680         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "liststyle", rpanel->getListStyle());
1681         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "hiddenfiles", rpanel->shownHiddenFiles());
1682         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "showthumbnails", rpanel->shownThumbnails());
1683 
1684         // Get and write sort function for right panel
1685         if (rpanel->getSortFunc() == FileList::ascendingCase)
1686         {
1687             sort_func = "ascendingCase";
1688         }
1689         else if (rpanel->getSortFunc() == FileList::ascendingCaseMix)
1690         {
1691             sort_func = "ascendingCaseMix";
1692         }
1693         else if (rpanel->getSortFunc() == FileList::descendingCase)
1694         {
1695             sort_func = "descendingCase";
1696         }
1697         else if (rpanel->getSortFunc() == FileList::descendingCaseMix)
1698         {
1699             sort_func = "descendingCaseMix";
1700         }
1701         else if (rpanel->getSortFunc() == FileList::ascending)
1702         {
1703             sort_func = "ascending";
1704         }
1705         else if (rpanel->getSortFunc() == FileList::ascendingMix)
1706         {
1707             sort_func = "ascendingMix";
1708         }
1709         else if (rpanel->getSortFunc() == FileList::descending)
1710         {
1711             sort_func = "descending";
1712         }
1713         else if (rpanel->getSortFunc() == FileList::descendingMix)
1714         {
1715             sort_func = "descendingMix";
1716         }
1717         else if (rpanel->getSortFunc() == FileList::ascendingSize)
1718         {
1719             sort_func = "ascendingSize";
1720         }
1721         else if (rpanel->getSortFunc() == FileList::ascendingSizeMix)
1722         {
1723             sort_func = "ascendingSizeMix";
1724         }
1725         else if (rpanel->getSortFunc() == FileList::descendingSize)
1726         {
1727             sort_func = "descendingSize";
1728         }
1729         else if (rpanel->getSortFunc() == FileList::descendingSizeMix)
1730         {
1731             sort_func = "descendingSizeMix";
1732         }
1733         else if (rpanel->getSortFunc() == FileList::ascendingType)
1734         {
1735             sort_func = "ascendingType";
1736         }
1737         else if (rpanel->getSortFunc() == FileList::ascendingTypeMix)
1738         {
1739             sort_func = "ascendingTypeMix";
1740         }
1741         else if (rpanel->getSortFunc() == FileList::descendingType)
1742         {
1743             sort_func = "descendingType";
1744         }
1745         else if (rpanel->getSortFunc() == FileList::descendingTypeMix)
1746         {
1747             sort_func = "descendingTypeMix";
1748         }
1749         else if (rpanel->getSortFunc() == FileList::ascendingExt)
1750         {
1751             sort_func = "ascendingExt";
1752         }
1753         else if (rpanel->getSortFunc() == FileList::ascendingExtMix)
1754         {
1755             sort_func = "ascendingExtMix";
1756         }
1757         else if (rpanel->getSortFunc() == FileList::descendingExt)
1758         {
1759             sort_func = "descendingExt";
1760         }
1761         else if (rpanel->getSortFunc() == FileList::descendingExtMix)
1762         {
1763             sort_func = "descendingExtMix";
1764         }
1765         else if (rpanel->getSortFunc() == FileList::ascendingTime)
1766         {
1767             sort_func = "ascendingTime";
1768         }
1769         else if (rpanel->getSortFunc() == FileList::ascendingTimeMix)
1770         {
1771             sort_func = "ascendingTimeMix";
1772         }
1773         else if (rpanel->getSortFunc() == FileList::descendingTime)
1774         {
1775             sort_func = "descendingTime";
1776         }
1777         else if (rpanel->getSortFunc() == FileList::descendingTimeMix)
1778         {
1779             sort_func = "descendingTimeMix";
1780         }
1781         else if (rpanel->getSortFunc() == FileList::ascendingUser)
1782         {
1783             sort_func = "ascendingUser";
1784         }
1785         else if (rpanel->getSortFunc() == FileList::ascendingUserMix)
1786         {
1787             sort_func = "ascendingUserMix";
1788         }
1789         else if (rpanel->getSortFunc() == FileList::descendingUser)
1790         {
1791             sort_func = "descendingUser";
1792         }
1793         else if (rpanel->getSortFunc() == FileList::descendingUserMix)
1794         {
1795             sort_func = "descendingUserMix";
1796         }
1797         else if (rpanel->getSortFunc() == FileList::ascendingGroup)
1798         {
1799             sort_func = "ascendingGroup";
1800         }
1801         else if (rpanel->getSortFunc() == FileList::ascendingGroupMix)
1802         {
1803             sort_func = "ascendingGroupMix";
1804         }
1805         else if (rpanel->getSortFunc() == FileList::descendingGroup)
1806         {
1807             sort_func = "descendingGroup";
1808         }
1809         else if (rpanel->getSortFunc() == FileList::descendingGroupMix)
1810         {
1811             sort_func = "descendingGroupMix";
1812         }
1813         else if (rpanel->getSortFunc() == FileList::ascendingPerm)
1814         {
1815             sort_func = "ascendingPerm";
1816         }
1817         else if (rpanel->getSortFunc() == FileList::ascendingPermMix)
1818         {
1819             sort_func = "ascendingPermMix";
1820         }
1821         else if (rpanel->getSortFunc() == FileList::descendingPerm)
1822         {
1823             sort_func = "descendingPerm";
1824         }
1825         else if (rpanel->getSortFunc() == FileList::descendingPermMix)
1826         {
1827             sort_func = "descendingPermMix";
1828         }
1829         else
1830         {
1831             sort_func = "ascendingCase";
1832         }
1833         getApp()->reg().writeStringEntry("RIGHT PANEL", "sort_func", sort_func.text());
1834         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "ignore_case", rpanel->getIgnoreCase());
1835         getApp()->reg().writeUnsignedEntry("RIGHT PANEL", "dirs_first", rpanel->getDirsFirst());
1836 
1837         // Global options
1838         getApp()->reg().writeUnsignedEntry("OPTIONS", "width", (FXuint)getWidth());
1839         getApp()->reg().writeUnsignedEntry("OPTIONS", "height", (FXuint)getHeight());
1840 
1841         // Get value of window position flag and position the window
1842         FXbool save_win_pos = getApp()->reg().readUnsignedEntry("SETTINGS", "save_win_pos", false);
1843         if (save_win_pos)
1844         {
1845             // Account for the Window Manager border size
1846             XWindowAttributes xwattr;
1847             if (XGetWindowAttributes((Display*)getApp()->getDisplay(), this->id(), &xwattr))
1848             {
1849                 getApp()->reg().writeIntEntry("OPTIONS", "xpos", getX()-xwattr.x);
1850                 getApp()->reg().writeIntEntry("OPTIONS", "ypos", getY()-xwattr.y);
1851             }
1852             else
1853             {
1854                 getApp()->reg().writeIntEntry("OPTIONS", "xpos", getX());
1855                 getApp()->reg().writeIntEntry("OPTIONS", "ypos", getY());
1856             }
1857         }
1858         getApp()->reg().writeUnsignedEntry("OPTIONS", "generaltoolbar", (FXuint)generaltoolbar->shown());
1859         getApp()->reg().writeUnsignedEntry("OPTIONS", "toolstoolbar", (FXuint)toolstoolbar->shown());
1860         getApp()->reg().writeUnsignedEntry("OPTIONS", "paneltoolbar", (FXuint)paneltoolbar->shown());
1861         getApp()->reg().writeUnsignedEntry("OPTIONS", "locationbar", (FXuint)locationbar->shown());
1862         getApp()->reg().writeUnsignedEntry("OPTIONS", "status", (FXuint)lpanel->statusbarShown());
1863         getApp()->reg().writeUnsignedEntry("SETTINGS", "file_tooltips", (FXuint)file_tooltips);
1864         getApp()->reg().writeUnsignedEntry("SETTINGS", "relative_resize", (FXuint)relative_resize);
1865         getApp()->reg().writeRealEntry("OPTIONS", "treepanel_tree_pct", (int)(treepanel_tree_pct*1000)/1000.0);
1866         getApp()->reg().writeRealEntry("OPTIONS", "twopanels_lpanel_pct", (int)(twopanels_lpanel_pct*1000)/1000.0);
1867         getApp()->reg().writeRealEntry("OPTIONS", "treetwopanels_tree_pct", (int)(treetwopanels_tree_pct*1000)/1000.0);
1868         getApp()->reg().writeRealEntry("OPTIONS", "treetwopanels_lpanel_pct", (int)(treetwopanels_lpanel_pct*1000)/1000.0);
1869 
1870         // Panel stacking
1871         getApp()->reg().writeUnsignedEntry("OPTIONS", "vert_panels", vertpanels);
1872 
1873         // Save panel view only if not given from command line
1874         if (panel_mode == -1)
1875         {
1876             getApp()->reg().writeUnsignedEntry("OPTIONS", "panel_view", (FXuint)panel_view);
1877         }
1878 
1879         getApp()->reg().writeUnsignedEntry("SETTINGS", "single_click", single_click);
1880 
1881         FXString history = "";
1882         for (int i = 0; i < RunHistSize; i++)
1883         {
1884             history += RunHistory[i];
1885             history += ":";
1886         }
1887         if (RunHistSize)
1888         {
1889             getApp()->reg().writeStringEntry("HISTORY", "run", history.text());
1890         }
1891 
1892         history = "";
1893         for (int i = 0; i < OpenNum; i++)
1894         {
1895             history += OpenHistory[i];
1896             history += ":";
1897         }
1898         if (OpenNum)
1899         {
1900             getApp()->reg().writeStringEntry("HISTORY", "open", history.text());
1901         }
1902 
1903         history = "";
1904         for (int i = 0; i < FilterNum; i++)
1905         {
1906             history += FilterHistory[i];
1907             history += ":";
1908         }
1909         if (FilterNum)
1910         {
1911             getApp()->reg().writeStringEntry("HISTORY", "filter", history.text());
1912         }
1913     }
1914 
1915     // Last visited directories
1916     getApp()->reg().writeStringEntry("LEFT PANEL", "lastdir", lpanel->getDirectory().text());
1917     getApp()->reg().writeStringEntry("RIGHT PANEL", "lastdir", rpanel->getDirectory().text());
1918 
1919     getApp()->reg().write();
1920 }
1921 
1922 
1923 // Make application
create()1924 void XFileExplorer::create()
1925 {
1926     // Switch to two panels mode if startdir2 was specified
1927     // and no particular panel mode was selected
1928     if ((startdir2 != "") && (panel_mode == -1))
1929     {
1930         panel_mode = 2;
1931     }
1932 
1933     // Eventually select panel mode from the command line option
1934     // or revert to last saved panel view
1935     switch (panel_mode)
1936     {
1937     case 0:
1938         panel_view = TREE_PANEL;
1939         break;
1940 
1941     case 1:
1942         panel_view = ONE_PANEL;
1943         break;
1944 
1945     case 2:
1946         panel_view = TWO_PANELS;
1947         break;
1948 
1949     case 3:
1950         panel_view = TREE_TWO_PANELS;
1951         break;
1952 
1953     default:
1954         panel_view = getApp()->reg().readUnsignedEntry("OPTIONS", "panel_view", TREE_PANEL);
1955     }
1956 
1957     int width = getApp()->reg().readUnsignedEntry("OPTIONS", "width", DEFAULT_WINDOW_WIDTH);
1958     int height = getApp()->reg().readUnsignedEntry("OPTIONS", "height", DEFAULT_WINDOW_HEIGHT);
1959     int save_win_pos = getApp()->reg().readUnsignedEntry("SETTINGS", "save_win_pos", false);
1960     if (save_win_pos)
1961     {
1962         int xpos = getApp()->reg().readIntEntry("OPTIONS", "xpos", DEFAULT_WINDOW_XPOS);
1963         int ypos = getApp()->reg().readIntEntry("OPTIONS", "ypos", DEFAULT_WINDOW_YPOS);
1964         position(xpos, ypos, width, height);
1965     }
1966     else
1967     {
1968         position(getX(), getY(), width, height);
1969     }
1970 
1971     // Search dialog geometry
1972     search_xpos = getApp()->reg().readUnsignedEntry("SEARCH PANEL", "search_xpos", 200);
1973     search_ypos = getApp()->reg().readUnsignedEntry("SEARCH PANEL", "search_ypos", 200);
1974     search_width = getApp()->reg().readUnsignedEntry("SEARCH PANEL", "search_width", 650);
1975     search_height = getApp()->reg().readUnsignedEntry("SEARCH PANEL", "search_height", 480);
1976 
1977     FXMainWindow::create();
1978 
1979     twopanels_lpanel_pct = getApp()->reg().readRealEntry("OPTIONS", "twopanels_lpanel_pct", 0.50);
1980     treepanel_tree_pct = getApp()->reg().readRealEntry("OPTIONS", "treepanel_tree_pct", 0.20);
1981     treetwopanels_tree_pct = getApp()->reg().readRealEntry("OPTIONS", "treetwopanels_tree_pct", 0.20);
1982     treetwopanels_lpanel_pct = getApp()->reg().readRealEntry("OPTIONS", "treetwopanels_lpanel_pct", 0.40);
1983 
1984     int window_width = getWidth();
1985     int window_height = getHeight();
1986 
1987     switch (panel_view)
1988     {
1989     case ONE_PANEL:
1990         rpanel->hide();
1991         dirpanel->hide();
1992         // Handle drag corner
1993         rpanel->showCorner(false);
1994         lpanel->showCorner(true);
1995         // Handle active icon
1996         lpanel->showActiveIcon(false);
1997         lpanel->setWidth((int)round(1.0*window_width));
1998         break;
1999 
2000     case TWO_PANELS:
2001         dirpanel->hide();
2002         if (vertpanels)
2003         {
2004             lpanel->setWidth((int)round(twopanels_lpanel_pct*window_width));
2005         }
2006         else
2007         {
2008             lpanel->setHeight((int)round(twopanels_lpanel_pct*window_height));
2009         }
2010         // Handle drag corner
2011         rpanel->showCorner(true);
2012         lpanel->showCorner(false);
2013         // Handle active icon
2014         lpanel->showActiveIcon(true);
2015         break;
2016 
2017     case TREE_PANEL:
2018         rpanel->hide();
2019         dirpanel->setWidth((int)round(treepanel_tree_pct*window_width));
2020         lpanel->setWidth((int)round((1.0-treepanel_tree_pct)*window_width));
2021         // Handle drag corner
2022         rpanel->showCorner(false);
2023         lpanel->showCorner(true);
2024         // Handle active icon
2025         lpanel->showActiveIcon(true);
2026         break;
2027 
2028     case TREE_TWO_PANELS:
2029         dirpanel->setWidth((int)round(treetwopanels_tree_pct*window_width));
2030         if (vertpanels)
2031         {
2032             lpanel->setWidth((int)round(treetwopanels_lpanel_pct*window_width));
2033         }
2034         else
2035         {
2036             lpanel->setHeight((int)round(treetwopanels_lpanel_pct*window_height));
2037         }
2038         // Handle drag corner
2039         rpanel->showCorner(true);
2040         lpanel->showCorner(false);
2041         // Handle active icon
2042         lpanel->showActiveIcon(true);
2043         break;
2044     }
2045 
2046     if (!getApp()->reg().readUnsignedEntry("OPTIONS", "generaltoolbar", true))
2047     {
2048         generaltoolbar->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_TOGGLESHOWN), NULL);
2049     }
2050     if (!getApp()->reg().readUnsignedEntry("OPTIONS", "toolstoolbar", true))
2051     {
2052         toolstoolbar->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_TOGGLESHOWN), NULL);
2053     }
2054     if (!getApp()->reg().readUnsignedEntry("OPTIONS", "paneltoolbar", true))
2055     {
2056         paneltoolbar->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_TOGGLESHOWN), NULL);
2057     }
2058     if (!getApp()->reg().readUnsignedEntry("OPTIONS", "locationbar", true))
2059     {
2060         locationbar->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_TOGGLESHOWN), NULL);
2061     }
2062     if (!getApp()->reg().readUnsignedEntry("OPTIONS", "status", true))
2063     {
2064         handle(this, FXSEL(SEL_COMMAND, XFileExplorer::ID_TOGGLE_STATUS), NULL);
2065     }
2066     file_tooltips = getApp()->reg().readUnsignedEntry("SETTINGS", "file_tooltips", 1);
2067     relative_resize = getApp()->reg().readUnsignedEntry("SETTINGS", "relative_resize", 1);
2068 
2069     // Wheel scrolling
2070     int wheellines = getApp()->reg().readUnsignedEntry("SETTINGS", "wheellines", 5);
2071     getApp()->setWheelLines(wheellines);
2072 
2073     // Scrollbar size
2074     int barsize = getApp()->reg().readUnsignedEntry("SETTINGS", "scrollbarsize", 15);
2075     getApp()->setScrollBarSize(barsize);
2076 
2077     // If there are only files to open, tell Xfe not to show its window
2078     winshow = true;
2079     if ((startdir1 == "") && (startdir2 == "") && (nbstartfiles > 0))
2080     {
2081         winshow = false;
2082     }
2083 
2084     // Read start directory mode
2085     int startdirmode = getApp()->reg().readUnsignedEntry("OPTIONS", "startdir_mode", START_HOMEDIR);
2086 
2087     // Open left and right panels in starting directories (if specified) or in home / current or last directory
2088     if (startdir1 == "")
2089     {
2090         switch (startdirmode)
2091         {
2092         case START_HOMEDIR:
2093             startdir1 = FXSystem::getHomeDirectory();
2094             break;
2095 
2096         case START_CURRENTDIR:
2097             startdir1 = FXSystem::getCurrentDirectory();
2098             break;
2099 
2100         case START_LASTDIR:
2101             startdir1 = getApp()->reg().readStringEntry("LEFT PANEL", "lastdir", ROOTDIR);
2102             break;
2103         }
2104     }
2105     if (startdir2 == "")
2106     {
2107         switch (startdirmode)
2108         {
2109         case START_HOMEDIR:
2110             startdir2 = FXSystem::getHomeDirectory();
2111             break;
2112 
2113         case START_CURRENTDIR:
2114             startdir2 = FXSystem::getCurrentDirectory();
2115             break;
2116 
2117         case START_LASTDIR:
2118             startdir2 = getApp()->reg().readStringEntry("RIGHT PANEL", "lastdir", ROOTDIR);
2119             break;
2120         }
2121     }
2122 
2123     lpanel->setDirectory(startdir1, true);
2124     lpanel->setPathLink(startdir1);
2125     lpanel->setPathText(startdir1);
2126     rpanel->setDirectory(startdir2, true);
2127     rpanel->setPathLink(startdir2);
2128     rpanel->setPathText(startdir2);
2129     dirpanel->setDirectory(startdir1, true);
2130 
2131     // Open file on startup, if any
2132     if (nbstartfiles > 0)
2133     {
2134         openFiles(startURIs);
2135     }
2136 
2137     // Show window
2138     if (winshow)
2139     {
2140         show();
2141     }
2142 
2143     // Set file panels list style
2144     liststyle = getApp()->reg().readUnsignedEntry("LEFT PANEL", "liststyle", _ICONLIST_DETAILED );
2145     lpanel->setListStyle(liststyle);
2146     liststyle = getApp()->reg().readUnsignedEntry("RIGHT PANEL", "liststyle", _ICONLIST_DETAILED );
2147     rpanel->setListStyle(liststyle);
2148 
2149     // Show or hide hidden files listed in panels
2150     FXbool hiddenfiles = getApp()->reg().readUnsignedEntry("LEFT PANEL", "hiddenfiles", 0);
2151     lpanel->showHiddenFiles(hiddenfiles);
2152     hiddenfiles = getApp()->reg().readUnsignedEntry("RIGHT PANEL", "hiddenfiles", 0);
2153     rpanel->showHiddenFiles(hiddenfiles);
2154 
2155     // Show or hide hidden directories listed in dirpanel
2156     FXbool hidden_dir = getApp()->reg().readUnsignedEntry("DIR PANEL", "hidden_dir", 0);
2157     dirpanel->showHiddenFiles(hidden_dir);
2158 
2159     // History
2160     FXString history = getApp()->reg().readStringEntry("HISTORY", "run", "");
2161     int      i;
2162     FXString histent;
2163     RunHistSize = 0;
2164     if (history != "")
2165     {
2166         for (i = 0; ; i++)
2167         {
2168             histent = history.section(':', i);
2169             if (streq(histent.text(), ""))
2170             {
2171                 break;
2172             }
2173             strlcpy(RunHistory[i], histent.text(), histent.length()+1);
2174         }
2175         RunHistSize = i;
2176     }
2177 
2178     history = getApp()->reg().readStringEntry("HISTORY", "open", "");
2179     histent = "";
2180     OpenNum = 0;
2181     if (history != "")
2182     {
2183         for (i = 0; ; i++)
2184         {
2185             histent = history.section(':', i);
2186             if (streq(histent.text(), ""))
2187             {
2188                 break;
2189             }
2190             strlcpy(OpenHistory[i], histent.text(), histent.length()+1);
2191         }
2192         OpenNum = i;
2193     }
2194 
2195     history = getApp()->reg().readStringEntry("HISTORY", "filter", "");
2196     histent = "";
2197     FilterNum = 0;
2198     if (history != "")
2199     {
2200         for (i = 0; ; i++)
2201         {
2202             histent = history.section(':', i);
2203             if (streq(histent.text(), ""))
2204             {
2205                 break;
2206             }
2207             strlcpy(FilterHistory[i], histent.text(), histent.length()+1);
2208         }
2209         FilterNum = i;
2210     }
2211 
2212     getApp()->forceRefresh();
2213 
2214     // Running as root?
2215     FXbool root_warn = getApp()->reg().readUnsignedEntry("OPTIONS", "root_warn", true);
2216     if ((getuid() == 0) && root_warn)
2217     {
2218         MessageBox::information(this, BOX_OK, _("Warning"), _("Running Xfe as root!"));
2219     }
2220 
2221     // Initial focus is always on the left panel
2222     lpanel->setFocusOnList();
2223 
2224 #if defined(linux)
2225     // Warning message if a mount point is down
2226     FXbool mount_warn = getApp()->reg().readUnsignedEntry("OPTIONS", "mount_warn", true);
2227     if (mount_warn)
2228     {
2229         int d;
2230         for (d = updevices->first(); d < updevices->size(); d = updevices->next(d))
2231         {
2232             if (streq(updevices->data(d), "down"))
2233             {
2234                 MessageBox::warning(this, BOX_OK, _("Warning"), _("Mount point %s is not responding..."), updevices->key(d));
2235             }
2236         }
2237     }
2238 #endif
2239 
2240     // If no Xfe local configuration exists (i.e. at first call or after a purge of the configuration files),
2241     // copy the global xferc file to the local configuration directory, and read / write the registry
2242     int      mask;
2243     FXString configlocation = xdgconfighome + PATHSEPSTRING XFECONFIGPATH;
2244     FXString configpath = configlocation + PATHSEPSTRING XFECONFIGNAME;
2245     if (!existFile(configpath))
2246     {
2247         // If old configuration path (i.e. ~/.xfe) exists then warn the user about the new configuration scheme
2248         FXString oldconfigpath = homedir + PATHSEPSTRING ".xfe";
2249         if (existFile(oldconfigpath))
2250         {
2251             // Display warning message
2252             FXString message;
2253             message.format(_("Starting from Xfe 1.32, the location of the configuration files has changed to '%s'.\nNote you can manually edit the new configuration files to import your old customizations..."), configlocation.text());
2254             MessageBox::warning(this, BOX_OK, _("Warning"), "%s", message.text());
2255         }
2256 
2257         // Create ~/.config/xfe directory if it doesn't exist
2258         if (!existFile(configlocation))
2259         {
2260             // Create the ~/.config/xfe directory according to the umask
2261             mask = umask(0);
2262             umask(mask);
2263             errno = 0;
2264             int ret = mkpath(configlocation.text(), 511 & ~mask);
2265             int errcode = errno;
2266             if (ret == -1)
2267             {
2268                 if (errcode)
2269                 {
2270                     MessageBox::error(this, BOX_OK, _("Error"), _("Can't create Xfe config folder %s: %s"), configlocation.text(), strerror(errcode));
2271                 }
2272                 else
2273                 {
2274                     MessageBox::error(this, BOX_OK, _("Error"), _("Can't create Xfe config folder %s"), configlocation.text());
2275                 }
2276             }
2277         }
2278 
2279         // Copy the global xfrec file (three possible locations) to the local configuration file
2280         if (existFile("/usr/share/xfe/xferc"))
2281         {
2282             FXFile::copy("/usr/share/xfe/xferc", configpath, false);
2283         }
2284         else if (existFile("/usr/local/share/xfe/xferc"))
2285         {
2286             FXFile::copy("/usr/local/share/xfe/xferc", configpath, false);
2287         }
2288         else if (existFile("/opt/local/share/xfe/xferc"))
2289         {
2290             FXFile::copy("/opt/local/share/xfe/xferc", configpath, false);
2291         }
2292 
2293         // If nothing is found, display a file dialog to let the user choose the right place
2294         else
2295         {
2296             FileDialog browse(this, _("No global xferc file found! Please select a configuration file..."));
2297 
2298             const char* patterns[] =
2299             {
2300                 _("XFE configuration file"), "*xferc*", NULL
2301             };
2302             browse.setFilename(ROOTDIR);
2303             browse.setPatternList(patterns);
2304 
2305             if (browse.execute())
2306             {
2307                 FXString path = browse.getFilename();
2308                 FXFile::copy(path, configpath, false);
2309             }
2310             else
2311             {
2312                 MessageBox::error(this, BOX_OK, _("Error"), _("Xfe cannot run without a global xferc configuration file"));
2313                 exit(EXIT_FAILURE);
2314             }
2315         }
2316 
2317         // Read and write the registry
2318         getApp()->reg().read();
2319         getApp()->reg().write();
2320     }
2321 
2322     // Create trash can files directory if it doesn't exist
2323     if (!existFile(trashfileslocation))
2324     {
2325         // Create the trash can files directory according to the umask
2326         mask = umask(0);
2327         umask(mask);
2328         errno = 0;
2329         int ret = mkpath(trashfileslocation.text(), 511 & ~mask);
2330         int errcode = errno;
2331         if (ret == -1)
2332         {
2333             if (errcode)
2334             {
2335                 MessageBox::error(this, BOX_OK, _("Error"), _("Can't create trash can 'files' folder %s: %s"), trashfileslocation.text(), strerror(errcode));
2336             }
2337             else
2338             {
2339                 MessageBox::error(this, BOX_OK, _("Error"), _("Can't create trash can 'files' folder %s"), trashfileslocation.text());
2340             }
2341         }
2342     }
2343 
2344     // Create trash can info directory if it doesn't exist
2345     if (!existFile(trashinfolocation))
2346     {
2347         // Create the trash can info directory according to the umask
2348         mask = umask(0);
2349         umask(mask);
2350         errno = 0;
2351         int ret = mkpath(trashinfolocation.text(), 511 & ~mask);
2352         int errcode = errno;
2353         if (ret == -1)
2354         {
2355             if (errcode)
2356             {
2357                 MessageBox::error(this, BOX_OK, _("Error"), _("Can't create trash can 'info' folder %s: %s"), trashinfolocation.text(), strerror(errcode));
2358             }
2359             else
2360             {
2361                 MessageBox::error(this, BOX_OK, _("Error"), _("Can't create trash can 'info' folder %s"), trashinfolocation.text());
2362             }
2363         }
2364     }
2365 
2366     // If necessary, replace the old default view command "xfv" with the new one
2367     if (getApp()->reg().readUnsignedEntry("OPTIONS", "xfv_replaced", false) == false)
2368     {
2369         FXStringDict* strdict = getApp()->reg().find("FILETYPES");
2370         FileDict*     assoc = new FileDict(getApp());
2371 
2372         FXString key, value, newvalue;
2373         FXString strtmp, open, view, edit, command;
2374         for (int i = strdict->first(); i < strdict->size(); i = strdict->next(i))
2375         {
2376             // Read key and value of each filetype
2377             key = strdict->key(i);
2378             value = strdict->data(i);
2379 
2380             // Replace the old txtviewer string with the new one
2381             if (value.contains("xfv"))
2382             {
2383                 // Obtain the open, view, edit and command strings
2384                 strtmp = value.before(';', 1);
2385                 command = value.after(';', 1);
2386                 open = strtmp.section(',', 0);
2387                 view = strtmp.section(',', 1);
2388                 edit = strtmp.section(',', 2);
2389 
2390                 // Replace the view command with the new value
2391                 value = open + "," + DEFAULT_TXTVIEWER + "," + edit + ";" + command;
2392                 assoc->replace(key.text(), value.text());
2393             }
2394         }
2395 
2396         // Wrire registry
2397         getApp()->reg().write();
2398         getApp()->reg().writeUnsignedEntry("OPTIONS", "xfv_replaced", true);
2399     }
2400 
2401     // Eventually start iconic or maximized
2402     if (starticonic)
2403     {
2404         minimize();
2405     }
2406     if (startmaximized)
2407     {
2408         maximize();
2409     }
2410 
2411 #ifdef STARTUP_NOTIFICATION
2412     startup_completed();
2413 #endif
2414 
2415     // Tell Xfe to stop, if we didn't show its window
2416     if (!winshow)
2417     {
2418         stop = true;
2419     }
2420 }
2421 
2422 
2423 // Destructor
~XFileExplorer()2424 XFileExplorer::~XFileExplorer()
2425 {
2426     delete menubar;
2427     delete locationbar;
2428     delete address;
2429     delete filemenu;
2430     delete toolsmenu;
2431     delete trashmenu;
2432     delete editmenu;
2433     delete bookmarksmenu;
2434     delete viewmenu;
2435     delete lpanelmenu;
2436     delete rpanelmenu;
2437     delete helpmenu;
2438     delete filemenutitle;
2439     delete trashmenutitle;
2440     delete editmenutitle;
2441     delete bookmarksmenutitle;
2442     delete viewmenutitle;
2443     delete lpanelmenutitle;
2444     delete rpanelmenutitle;
2445     delete helpmenutitle;
2446     delete generaltoolbar;
2447     delete paneltoolbar;
2448     delete toolstoolbar;
2449     delete dirpanel;
2450     delete lpanel;
2451     delete rpanel;
2452     delete bookmarks;
2453     delete btnbackhist;
2454     delete btnforwardhist;
2455     delete rundialog;
2456     delete prefsdialog;
2457     delete helpwindow;
2458     delete searchwindow;
2459 }
2460 
2461 
2462 // If Tab pressed, cycle through the panels
onKeyPress(FXObject * sender,FXSelector sel,void * ptr)2463 long XFileExplorer::onKeyPress(FXObject* sender, FXSelector sel, void* ptr)
2464 {
2465     FXEvent* event = (FXEvent*)ptr;
2466     int      current;
2467 
2468     // Tab was pressed : cycle through the panels from left to right
2469     if (event->code == KEY_Tab)
2470     {
2471         if (dirpanel->shown())
2472         {
2473             if (dirpanel->isActive())
2474             {
2475                 lpanel->setFocusOnList();
2476                 current = lpanel->getCurrentItem();
2477                 if (current < 0)
2478                 {
2479                     current = 0;
2480                 }
2481                 lpanel->setCurrentItem(current);
2482                 lpanel->selectItem(current);
2483             }
2484             else if ((rpanel->shown()) && (lpanel->isActive()))
2485             {
2486                 rpanel->setFocusOnList();
2487                 current = rpanel->getCurrentItem();
2488                 if (current < 0)
2489                 {
2490                     current = 0;
2491                 }
2492                 rpanel->setCurrentItem(current);
2493                 rpanel->selectItem(current);
2494             }
2495             else
2496             {
2497                 dirpanel->setFocusOnList();
2498                 current = lpanel->getCurrentItem();
2499                 if (current < 0)
2500                 {
2501                     current = 0;
2502                 }
2503                 lpanel->deselectItem(current);
2504             }
2505         }
2506         else if (rpanel->shown())
2507         {
2508             if (lpanel->getCurrent() == rpanel)
2509             {
2510                 lpanel->setActive();
2511                 current = lpanel->getCurrentItem();
2512                 if (current < 0)
2513                 {
2514                     current = 0;
2515                 }
2516                 lpanel->setCurrentItem(current);
2517                 lpanel->selectItem(current);
2518             }
2519             else
2520             {
2521                 rpanel->setActive();
2522                 current = rpanel->getCurrentItem();
2523                 if (current < 0)
2524                 {
2525                     current = 0;
2526                 }
2527                 rpanel->setCurrentItem(current);
2528                 rpanel->selectItem(current);
2529             }
2530         }
2531         return(1);
2532     }
2533 
2534     // Shift-Tab was pressed : cycle through the panels from right to left
2535     else if (((event->state&SHIFTMASK) && (event->code == KEY_Tab)) ||
2536              ((event->state&SHIFTMASK) && (event->code == KEY_ISO_Left_Tab)))
2537     {
2538         if (rpanel->shown())
2539         {
2540             if (rpanel->isActive())
2541             {
2542                 lpanel->setFocusOnList();
2543                 current = lpanel->getCurrentItem();
2544                 if (current < 0)
2545                 {
2546                     current = 0;
2547                 }
2548                 lpanel->setCurrentItem(current);
2549                 lpanel->selectItem(current);
2550             }
2551             else if (dirpanel->shown() && dirpanel->isActive())
2552             {
2553                 rpanel->setFocusOnList();
2554                 current = rpanel->getCurrentItem();
2555                 if (current < 0)
2556                 {
2557                     current = 0;
2558                 }
2559                 rpanel->setCurrentItem(current);
2560                 rpanel->selectItem(current);
2561             }
2562             else if (lpanel->isActive())
2563             {
2564                 if (dirpanel->shown())
2565                 {
2566                     dirpanel->setFocusOnList();
2567                     current = lpanel->getCurrentItem();
2568                     if (current < 0)
2569                     {
2570                         current = 0;
2571                     }
2572                     lpanel->deselectItem(current);
2573                 }
2574                 else
2575                 {
2576                     rpanel->setFocusOnList();
2577                     current = rpanel->getCurrentItem();
2578                     if (current < 0)
2579                     {
2580                         current = 0;
2581                     }
2582                     rpanel->setCurrentItem(current);
2583                     rpanel->selectItem(current);
2584                 }
2585             }
2586         }
2587         else
2588         {
2589             if (dirpanel->isActive() && dirpanel->shown())
2590             {
2591                 lpanel->setFocusOnList();
2592                 current = lpanel->getCurrentItem();
2593                 if (current < 0)
2594                 {
2595                     current = 0;
2596                 }
2597                 lpanel->setCurrentItem(current);
2598                 lpanel->selectItem(current);
2599             }
2600             else if (dirpanel->shown())
2601             {
2602                 dirpanel->setFocusOnList();
2603                 current = lpanel->getCurrentItem();
2604                 if (current < 0)
2605                 {
2606                     current = 0;
2607                 }
2608                 lpanel->deselectItem(current);
2609             }
2610         }
2611 
2612         return(1);
2613     }
2614 
2615     // Shift-F10 or Menu was pressed : open popup menu
2616    	else if ((event->state&SHIFTMASK && event->code == KEY_F10) || event->code == KEY_Menu)
2617     {
2618         lpanel->getCurrent()->handle(sender, FXSEL(SEL_COMMAND, FilePanel::ID_POPUP_MENU), ptr);
2619         return(1);
2620     }
2621 
2622     // Any other key was pressed : handle the pressed key in the usual way
2623     else
2624     {
2625         if (FXTopWindow::onKeyPress(sender, sel, ptr))
2626         {
2627             return(1);
2628         }
2629     }
2630 
2631     return(0);
2632 }
2633 
2634 
onKeyRelease(FXObject * sender,FXSelector sel,void * ptr)2635 long XFileExplorer::onKeyRelease(FXObject* sender, FXSelector sel, void* ptr)
2636 {
2637     if (FXTopWindow::onKeyRelease(sender, sel, ptr))
2638     {
2639         return(1);
2640     }
2641 
2642     return(0);
2643 }
2644 
2645 
2646 // Harvest the zombies
onSigHarvest(FXObject *,FXSelector,void *)2647 long XFileExplorer::onSigHarvest(FXObject*, FXSelector, void*)
2648 {
2649     while (waitpid(-1, NULL, WNOHANG) > 0)
2650     {
2651     }
2652     return(1);
2653 }
2654 
2655 
2656 // Handle quitting
onQuit(FXObject *,FXSelector,void *)2657 long XFileExplorer::onQuit(FXObject*, FXSelector, void*)
2658 {
2659     saveConfig();
2660 
2661     getApp()->exit(EXIT_SUCCESS);
2662     return(1);
2663 }
2664 
2665 
2666 // Directory up
onCmdDirUp(FXObject * sender,FXSelector,void *)2667 long XFileExplorer::onCmdDirUp(FXObject* sender, FXSelector, void*)
2668 {
2669     lpanel->getCurrent()->handle(sender, FXSEL(SEL_COMMAND, FilePanel::ID_DIRECTORY_UP), NULL);
2670 
2671     // Set focus on dirpanel or filepanel
2672     if (panelfocus == DIRPANEL_FOCUS)
2673     {
2674         dirpanel->setFocusOnList();
2675     }
2676     else
2677     {
2678         lpanel->getCurrent()->setFocusOnList();
2679     }
2680 
2681     return(1);
2682 }
2683 
2684 
2685 // Directory back
onCmdDirBack(FXObject *,FXSelector,void *)2686 long XFileExplorer::onCmdDirBack(FXObject*, FXSelector, void*)
2687 {
2688     StringItem* item;
2689     FXString    pathname;
2690     FilePanel*  filepanel = lpanel->getCurrent();
2691 
2692     // Get the previous directory
2693     item = filepanel->backhistGetFirst();
2694     if (item)
2695     {
2696         pathname = filepanel->backhistGetString(item);
2697     }
2698 
2699     // Update the history
2700     filepanel->backhistRemoveFirstItem();
2701     filepanel->forwardhistInsertFirstItem(filepanel->getDirectory());
2702 
2703     // Go to the previous directory
2704     filepanel->setDirectory(pathname, false);
2705     filepanel->updatePath();
2706     dirpanel->setDirectory(pathname, false);
2707 
2708     // Set focus on dirpanel or filepanel
2709     if (panelfocus == DIRPANEL_FOCUS)
2710     {
2711         dirpanel->setFocusOnList();
2712     }
2713     else
2714     {
2715         filepanel->setFocusOnList();
2716     }
2717 
2718     return(1);
2719 }
2720 
2721 
2722 // Update directory back
onUpdDirBack(FXObject * sender,FXSelector,void * ptr)2723 long XFileExplorer::onUpdDirBack(FXObject* sender, FXSelector, void* ptr)
2724 {
2725     FXString   pathname;
2726     FilePanel* filepanel = lpanel->getCurrent();
2727 
2728     // Gray out the button if no item in history
2729     if (filepanel->backhistGetNumItems() == 0)
2730     {
2731         sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), ptr);
2732     }
2733     else
2734     {
2735         sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
2736     }
2737 
2738     return(1);
2739 }
2740 
2741 
2742 // Directory forward
onCmdDirForward(FXObject *,FXSelector,void *)2743 long XFileExplorer::onCmdDirForward(FXObject*, FXSelector, void*)
2744 {
2745     StringItem* item;
2746     FXString    pathname;
2747     FilePanel*  filepanel = lpanel->getCurrent();
2748 
2749     // Get the next directory
2750     item = filepanel->forwardhistGetFirst();
2751     if (item)
2752     {
2753         pathname = filepanel->forwardhistGetString(item);
2754     }
2755 
2756     // Update the history
2757     filepanel->forwardhistRemoveFirstItem();
2758     filepanel->backhistInsertFirstItem(lpanel->getCurrent()->getDirectory());
2759 
2760     // Go to the next directory
2761     filepanel->setDirectory(pathname, false);
2762     filepanel->updatePath();
2763     dirpanel->setDirectory(pathname, true);
2764 
2765     // Set focus on dirpanel or filepanel
2766     if (panelfocus == DIRPANEL_FOCUS)
2767     {
2768         dirpanel->setFocusOnList();
2769     }
2770     else
2771     {
2772         filepanel->setFocusOnList();
2773     }
2774 
2775     return(1);
2776 }
2777 
2778 
2779 // Update directory forward
onUpdDirForward(FXObject * sender,FXSelector sel,void * ptr)2780 long XFileExplorer::onUpdDirForward(FXObject* sender, FXSelector sel, void* ptr)
2781 {
2782     FXString   pathname;
2783     FilePanel* filepanel = lpanel->getCurrent();
2784 
2785     // Gray out the button if no item in history
2786     if (filepanel->forwardhistGetNumItems() == 0)
2787     {
2788         sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), ptr);
2789     }
2790     else
2791     {
2792         sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
2793     }
2794 
2795     return(1);
2796 }
2797 
2798 
2799 // Directory back history
onCmdDirBackHist(FXObject * sender,FXSelector sel,void * ptr)2800 long XFileExplorer::onCmdDirBackHist(FXObject* sender, FXSelector sel, void* ptr)
2801 {
2802     StringItem* item;
2803     FXString    pathname;
2804     FilePanel*  filepanel = lpanel->getCurrent();
2805 
2806     // Get all string items and display them in a list box
2807     int num = filepanel->backhistGetNumItems();
2808 
2809     if (num > 0)
2810     {
2811         FXString* dirs = new FXString[num];
2812         FXString  strlist = "";
2813 
2814         // Get string items
2815         item = filepanel->backhistGetFirst();
2816         int nb = 0;
2817         for (int i = 0; i <= num-1; i++)
2818         {
2819             if (item)
2820             {
2821                 FXString str = filepanel->backhistGetString(item);
2822                 FXbool   flag = true;
2823                 for (int j = 0; j <= nb-1; j++)
2824                 {
2825                     if (str == dirs[j])
2826                     {
2827                         flag = false;
2828                         break;
2829                     }
2830                 }
2831                 if (flag)
2832                 {
2833                     dirs[nb] = str;
2834                     strlist = strlist+str+"\n";
2835                     nb++;
2836                 }
2837                 item = filepanel->backhistGetNext(item);
2838             }
2839         }
2840 
2841         // Display list box
2842         int pos = DirHistBox::box(btnbackhist, DECOR_NONE, strlist, getX()+40, getY()+60);
2843 
2844         // If an item was selected
2845         if (pos != -1)
2846         {
2847             // Update back history
2848             if (pos == num-1)
2849             {
2850                 filepanel->backhistRemoveAllItems();
2851             }
2852             else
2853             {
2854                 item = filepanel->backhistGetItemAtPos(pos+1);
2855                 filepanel->backhistRemoveAllItemsBefore(item);
2856             }
2857 
2858             // Update forward history
2859             filepanel->forwardhistInsertFirstItem(filepanel->getDirectory());
2860             if (pos > 0)
2861             {
2862                 for (int i = 0; i <= pos-1; i++)
2863                 {
2864                     filepanel->forwardhistInsertFirstItem(dirs[i]);
2865                 }
2866             }
2867 
2868             // Go to to the selected directory
2869             pathname = dirs[pos];
2870             filepanel->setDirectory(pathname, false);
2871             filepanel->updatePath();
2872             dirpanel->setDirectory(pathname, true);
2873         }
2874         delete[]dirs;
2875     }
2876 
2877     return(1);
2878 }
2879 
2880 
2881 // Update directory back
onUpdDirBackHist(FXObject * sender,FXSelector sel,void * ptr)2882 long XFileExplorer::onUpdDirBackHist(FXObject* sender, FXSelector sel, void* ptr)
2883 {
2884     FXString   pathname;
2885     FilePanel* filepanel = lpanel->getCurrent();
2886 
2887     // Gray out the button if no item in history
2888     if (filepanel->backhistGetNumItems() == 0)
2889     {
2890         sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), ptr);
2891     }
2892     else
2893     {
2894         sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
2895     }
2896 
2897     return(1);
2898 }
2899 
2900 
2901 // Directory forward history
onCmdDirForwardHist(FXObject * sender,FXSelector sel,void * ptr)2902 long XFileExplorer::onCmdDirForwardHist(FXObject* sender, FXSelector sel, void* ptr)
2903 {
2904     StringItem* item;
2905     FXString    pathname;
2906     FilePanel*  filepanel = lpanel->getCurrent();
2907 
2908     // Get all string items and display them in a list box
2909     int num = filepanel->forwardhistGetNumItems();
2910 
2911     if (num > 0)
2912     {
2913         FXString* dirs = new FXString[num];
2914         FXString  strlist = "";
2915 
2916         // Get string items
2917         item = filepanel->forwardhistGetFirst();
2918         int nb = 0;
2919         for (int i = 0; i <= num-1; i++)
2920         {
2921             if (item)
2922             {
2923                 FXString str = filepanel->forwardhistGetString(item);
2924                 FXbool   flag = true;
2925                 for (int j = 0; j <= nb-1; j++)
2926                 {
2927                     if (str == dirs[j])
2928                     {
2929                         flag = false;
2930                         break;
2931                     }
2932                 }
2933                 if (flag)
2934                 {
2935                     dirs[nb] = str;
2936                     strlist = strlist+str+"\n";
2937                     nb++;
2938                 }
2939                 item = filepanel->forwardhistGetNext(item);
2940             }
2941         }
2942 
2943         // Display list box
2944         int pos = DirHistBox::box(btnforwardhist, DECOR_NONE, strlist, getX()+85, getY()+60);
2945 
2946         // If an item was selected
2947         if (pos != -1)
2948         {
2949             // Update forward history
2950             if (pos == num-1)
2951             {
2952                 filepanel->forwardhistRemoveAllItems();
2953             }
2954             else
2955             {
2956                 item = filepanel->forwardhistGetItemAtPos(pos+1);
2957                 filepanel->forwardhistRemoveAllItemsBefore(item);
2958             }
2959 
2960             // Update back history
2961             filepanel->backhistInsertFirstItem(filepanel->getDirectory());
2962             if (pos > 0)
2963             {
2964                 for (int i = 0; i <= pos-1; i++)
2965                 {
2966                     filepanel->backhistInsertFirstItem(dirs[i]);
2967                 }
2968             }
2969 
2970             // Go to to the selected directory
2971             pathname = dirs[pos];
2972             filepanel->setDirectory(pathname, false);
2973             filepanel->updatePath();
2974             dirpanel->setDirectory(pathname, true);
2975         }
2976         delete[]dirs;
2977     }
2978 
2979     return(1);
2980 }
2981 
2982 
2983 // Update directory forward
onUpdDirForwardHist(FXObject * sender,FXSelector sel,void * ptr)2984 long XFileExplorer::onUpdDirForwardHist(FXObject* sender, FXSelector sel, void* ptr)
2985 {
2986     FXString   pathname;
2987     FilePanel* filepanel = lpanel->getCurrent();
2988 
2989     // Gray out the button if no item in history
2990     if (filepanel->forwardhistGetNumItems() == 0)
2991     {
2992         sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), ptr);
2993     }
2994     else
2995     {
2996         sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
2997     }
2998 
2999     return(1);
3000 }
3001 
3002 
3003 // Handle bookmarks
onCmdBookmark(FXObject *,FXSelector s,void * p)3004 long XFileExplorer::onCmdBookmark(FXObject*, FXSelector s, void* p)
3005 {
3006     if (FXSELID(s) == ID_ADD_BOOKMARK)
3007     {
3008         bookmarks->appendBookmark(lpanel->getCurrent()->getDirectory());
3009         saveConfig();
3010     }
3011 
3012     // Handle location address fields
3013     else if (FXSELID(s) == ID_BOOKMARK)
3014     {
3015         lpanel->getCurrent()->setDirectory((char*)p);
3016         lpanel->getCurrent()->updatePath();
3017         dirpanel->setDirectory((char*)p, true);
3018         FXString item;
3019         int      i = 0;
3020         int      count = address->getNumItems();
3021         if (!count)
3022         {
3023             count++;
3024             address->insertItem(0, address->getText());
3025         }
3026         while (i < count)
3027         {
3028             item = address->getItem(i++);
3029             if (streq((char*)p, (const char*)&item[0]))
3030             {
3031                 i--;
3032                 break;
3033             }
3034         }
3035         if (i == count)
3036         {
3037             address->insertItem(0, (char*)p);
3038         }
3039 
3040         // Set focus to the active panel
3041         lpanel->getCurrent()->setFocusOnList();
3042     }
3043     return(1);
3044 }
3045 
3046 
3047 // Goto location entered into the text field;
onCmdGotoLocation(FXObject *,FXSelector,void *)3048 long XFileExplorer::onCmdGotoLocation(FXObject*, FXSelector, void*)
3049 {
3050     // Location where we want to go
3051     FXString location = address->getText();
3052 
3053     // In case location is given in URI form, convert it
3054     location = ::fileFromURI(location);
3055 
3056     // Get complete path
3057     FXString path = FXPath::absolute(lpanel->getCurrent()->getDirectory(), location);
3058     FXString dir = path;
3059 
3060     // Go up to the lowest directory which still exists
3061     while (!FXPath::isTopDirectory(dir) && !::isDirectory(dir))
3062     {
3063         dir = FXPath::upLevel(dir);
3064     }
3065 
3066     // Move to this existing directory
3067     lpanel->getCurrent()->setDirectory(dir);
3068     lpanel->getCurrent()->updatePath();
3069     dirpanel->setDirectory(dir, true);
3070     address->setText(dir);
3071 
3072     return(1);
3073 }
3074 
3075 
3076 // Clear location bar
onCmdClearLocation(FXObject *,FXSelector,void *)3077 long XFileExplorer::onCmdClearLocation(FXObject*, FXSelector, void*)
3078 {
3079     address->setText(FXString::null);
3080     address->CursorEnd();
3081     return(1);
3082 }
3083 
3084 
3085 // Restart the application when required
onCmdRestart(FXObject *,FXSelector,void *)3086 long XFileExplorer::onCmdRestart(FXObject*, FXSelector, void*)
3087 {
3088     saveConfig();
3089 
3090     if (fork() == 0) // Child
3091     {
3092         execvp("xfe", args);
3093     }
3094     else // Parent
3095     {
3096         exit(EXIT_SUCCESS);
3097     }
3098     return(1);
3099 }
3100 
3101 
3102 // Start a new Xfe session
onCmdNewWindow(FXObject *,FXSelector,void *)3103 long XFileExplorer::onCmdNewWindow(FXObject*, FXSelector, void*)
3104 {
3105     FXString cmd = "xfe " + homedir + " &";
3106 
3107     int ret = system(cmd.text());
3108 
3109     if (ret < 0)
3110     {
3111         MessageBox::error(this, BOX_OK, _("Error"), _("Can't execute command %s"), cmd.text());
3112         return(0);
3113     }
3114 
3115     return(1);
3116 }
3117 
3118 
3119 // Run Terminal
onCmdXTerm(FXObject *,FXSelector,void *)3120 long XFileExplorer::onCmdXTerm(FXObject*, FXSelector, void*)
3121 {
3122     int ret;
3123 
3124     getApp()->beginWaitCursor();
3125     FXString xterm = getApp()->reg().readStringEntry("PROGS", "xterm", "xterm -sb");
3126 
3127     ret = chdir(lpanel->getCurrent()->getDirectory().text());
3128     if (ret < 0)
3129     {
3130         int errcode = errno;
3131         if (errcode)
3132         {
3133             MessageBox::error(this, BOX_OK, _("Error"), _("Can't enter folder %s: %s"), lpanel->getCurrent()->getDirectory().text(), strerror(errcode));
3134         }
3135         else
3136         {
3137             MessageBox::error(this, BOX_OK, _("Error"), _("Can't enter folder %s"), lpanel->getCurrent()->getDirectory().text());
3138         }
3139 
3140         return(0);
3141     }
3142 
3143     FXString cmd = xterm;
3144     cmd += " &";
3145 
3146     ret = system(cmd.text());
3147     if (ret < 0)
3148     {
3149         MessageBox::error(this, BOX_OK, _("Error"), _("Can't execute command %s"), cmd.text());
3150         return(0);
3151     }
3152 
3153     lpanel->getCurrent()->setFocusOnList();
3154     ret = chdir(startlocation.text());
3155     if (ret < 0)
3156     {
3157         int errcode = errno;
3158         if (errcode)
3159         {
3160             MessageBox::error(this, BOX_OK, _("Error"), _("Can't enter folder %s: %s"), startlocation.text(), strerror(errcode));
3161         }
3162         else
3163         {
3164             MessageBox::error(this, BOX_OK, _("Error"), _("Can't enter folder %s"), startlocation.text());
3165         }
3166 
3167         return(0);
3168     }
3169 
3170     getApp()->endWaitCursor();
3171     return(1);
3172 }
3173 
3174 
3175 // Help menu
onCmdHelp(FXObject *,FXSelector,void *)3176 long XFileExplorer::onCmdHelp(FXObject*, FXSelector, void*)
3177 {
3178     // Display help window
3179     if (helpwindow == NULL)
3180     {
3181         helpwindow = new TextWindow(getApp(), _("Help"), 40, 120);
3182     }
3183     helpwindow->setIcon(helpicon);
3184 
3185     // Set text font
3186     FXString fontspec;
3187     fontspec = getApp()->reg().readStringEntry("SETTINGS", "textfont", DEFAULT_TEXT_FONT);
3188     if (!fontspec.empty())
3189     {
3190         FXFont* font = new FXFont(getApp(), fontspec);
3191         font->create();
3192         helpwindow->setFont(font);
3193     }
3194 
3195     // NB: The HELP_TEXT macro is defined in help.h
3196     FXString str = (FXString)"                         "+COPYRIGHT+HELP_TEXT;
3197     helpwindow->setText(str.text());
3198     // Non modal window
3199     helpwindow->create();
3200     helpwindow->show(PLACEMENT_OWNER);
3201     lpanel->getCurrent()->setFocusOnList();
3202     return(1);
3203 }
3204 
3205 
3206 // About menu
onCmdAbout(FXObject *,FXSelector,void *)3207 long XFileExplorer::onCmdAbout(FXObject*, FXSelector, void*)
3208 {
3209     FXString msg;
3210 
3211     msg.format(_("X File Explorer Version %s"), VERSION);
3212     FXString copyright = (FXString)"\n\n" + COPYRIGHT + "\n\n" + _("Based on X WinCommander by Maxim Baranov\n");
3213     FXString translators =
3214         _ ("\nTranslators\n\
3215 -------------\n\
3216 Argentinian Spanish: Bruno Gilberto Luciani\n\
3217 Brazilian Portuguese: Eduardo R.B.S., Jose Carlos Medeiros,\n\
3218 Phantom X, Tomas Acauan Schertel\n\
3219 Bosnian: Samir Ribi, Bajrami Emran, Balagija Jasmina,\n\
3220 Bilalovi, Omar Cogo Emir\n\
3221 Catalan: muzzol\n\
3222 Chinese: Xin Li\n\
3223 Chinese (Taïwan): Wei-Lun Chao\n\
3224 Colombian Spanish: Vladimir Támara (Pasos de Jesús)\n\
3225 Czech: David Vachulka\n\
3226 Danish: Jonas Bardino, Vidar Jon Bauge\n\
3227 Dutch: Hans Strijards\n\
3228 Finnish: Kimmo Siira\n\
3229 French: Claude Leo Mercier, Roland Baudin\n\
3230 German: Bastian Kleineidam, Joachim Wiedorn, Tim Benke, Jens Körner\n\
3231 Greek: Nikos Papadopoulos\n\
3232 Hungarian: Attila Szervac, Sandor Sipos\n\
3233 Italian: Claudio Fontana, Giorgio Moscardi\n\
3234 Japanese: Karl Skewes\n\
3235 Norwegian: Vidar Jon Bauge\n\
3236 Polish: Jacek Dziura, Franciszek Janowski\n\
3237 Portuguese: Miguel Santinho\n\
3238 Russian: Dimitri Sertolov, Vad Vad\n\
3239 Spanish: Felix Medrano Sanz, Lucas 'Basurero' Vieites,\n\
3240 Martin Carr\n\
3241 Swedish: Anders F. Bjorklund\n\
3242 Turkish: erkaN\n\
3243 ");
3244 
3245     msg = msg + copyright + translators;
3246     MessageBox about(this,_("About X File Explorer"),msg.text(),xfeicon,BOX_OK|DECOR_TITLE|DECOR_BORDER,
3247                      JUSTIFY_CENTER_X|ICON_BEFORE_TEXT|LAYOUT_CENTER_Y|LAYOUT_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
3248     about.execute(PLACEMENT_OWNER);
3249     lpanel->getCurrent()->setFocusOnList();
3250     return 1;
3251 }
3252 
3253 
3254 // Handle file association (called by Properties.cpp and FilePanel.cpp)
onCmdFileAssoc(FXObject *,FXSelector s,void * p)3255 long XFileExplorer::onCmdFileAssoc(FXObject*,FXSelector s,void* p)
3256 {
3257     char** str=(char**)p;
3258     char* ext=str[0];
3259     char* cmd=str[1];
3260 
3261     // ext=extension, cmd=associated command
3262     // replace : to allow immediate association in Xfe
3263     FileDict* associations=lpanel->getAssociations();
3264     associations->replace(ext,cmd);
3265     associations=rpanel->getAssociations();
3266     associations->replace(ext,cmd);
3267 
3268     saveConfig();
3269 
3270     return 1;
3271 }
3272 
3273 
3274 // FilePanel and DirPanel refresh
onCmdRefresh(FXObject *,FXSelector,void *)3275 long XFileExplorer::onCmdRefresh(FXObject*,FXSelector,void*)
3276 {
3277     getApp()->beginWaitCursor();
3278 
3279 #if defined(linux)
3280     dirpanel->forceDevicesRefresh();
3281 #endif
3282 
3283 	lpanel->onCmdRefresh(0,0,0);
3284 	rpanel->onCmdRefresh(0,0,0);
3285 	dirpanel->forceRefresh();
3286     getApp()->endWaitCursor();
3287 
3288     return 1;
3289 }
3290 
3291 
3292 // Update file location
onUpdFileLocation(FXObject * sender,FXSelector,void *)3293 long XFileExplorer::onUpdFileLocation(FXObject* sender,FXSelector,void*)
3294 {
3295     FXString currentdir=lpanel->getCurrent()->getDirectory();
3296     if (currentdir != prevdir)
3297     {
3298         address->setText(::cleanPath(currentdir));
3299         prevdir=currentdir;
3300     }
3301 
3302     return 1;
3303 }
3304 
3305 
3306 // Switch between vertical and horizontal panels
onCmdHorzVertPanels(FXObject * sender,FXSelector sel,void * ptr)3307 long XFileExplorer::onCmdHorzVertPanels(FXObject* sender,FXSelector sel,void* ptr)
3308 {
3309     switch(FXSELID(sel))
3310     {
3311     case ID_VERT_PANELS:
3312         panelsplit->setSplitterStyle(panelsplit->getSplitterStyle()&~SPLITTER_VERTICAL);
3313         vertpanels=true;
3314         break;
3315 
3316     case ID_HORZ_PANELS:
3317         panelsplit->setSplitterStyle(panelsplit->getSplitterStyle()|SPLITTER_VERTICAL);
3318         vertpanels=false;
3319         break;
3320     }
3321 
3322     return 1;
3323 }
3324 
3325 
3326 // Switch between the four possible panel views
onCmdShowPanels(FXObject * sender,FXSelector sel,void * ptr)3327 long XFileExplorer::onCmdShowPanels(FXObject* sender,FXSelector sel,void* ptr)
3328 {
3329     // Get window width and height
3330     int window_width=getWidth();
3331     int window_height=getHeight();
3332 
3333     switch(FXSELID(sel))
3334     {
3335     case ID_SHOW_ONE_PANEL:
3336         panel_view=ONE_PANEL;
3337         if (dirpanel->shown())
3338             dirpanel->handle(sender,FXSEL(SEL_COMMAND,DirPanel::ID_TOGGLE_TREE),ptr);
3339         if (rpanel->shown())
3340             rpanel->handle(sender,FXSEL(SEL_COMMAND,FXWindow::ID_TOGGLESHOWN),ptr);
3341         // Handle drag corner
3342         rpanel->showCorner(false);
3343         lpanel->showCorner(true);
3344         // Handle active icon
3345         lpanel->showActiveIcon(false);
3346 
3347         break;
3348 
3349     case ID_SHOW_TWO_PANELS:
3350         panel_view=TWO_PANELS;
3351         if (vertpanels)
3352             lpanel->setWidth((int)round(twopanels_lpanel_pct*window_width));
3353         else
3354             lpanel->setHeight((int)round(twopanels_lpanel_pct*window_height));
3355         if (dirpanel->shown())
3356             dirpanel->handle(sender,FXSEL(SEL_COMMAND,DirPanel::ID_TOGGLE_TREE),ptr);
3357         if (!rpanel->shown())
3358             rpanel->handle(sender,FXSEL(SEL_COMMAND,FXWindow::ID_TOGGLESHOWN),ptr);
3359         // Handle drag corner
3360         rpanel->showCorner(true);
3361         lpanel->showCorner(false);
3362         // Handle active icon
3363         lpanel->showActiveIcon(true);
3364         break;
3365 
3366     case ID_SHOW_TREE_PANEL:
3367         panel_view=TREE_PANEL;
3368         dirpanel->setWidth((int)round(treepanel_tree_pct*window_width) );
3369         if (!dirpanel->shown())
3370             dirpanel->handle(sender,FXSEL(SEL_COMMAND,DirPanel::ID_TOGGLE_TREE),ptr);
3371         if (rpanel->shown())
3372             rpanel->handle(sender,FXSEL(SEL_COMMAND,FXWindow::ID_TOGGLESHOWN),ptr);
3373         // Handle drag corner
3374         rpanel->showCorner(false);
3375         lpanel->showCorner(true);
3376         // Handle active icon
3377         lpanel->showActiveIcon(true);
3378         break;
3379 
3380     case ID_SHOW_TREE_TWO_PANELS:
3381         panel_view=TREE_TWO_PANELS;
3382         dirpanel->setWidth((int)round(treetwopanels_tree_pct*window_width) );
3383         if (vertpanels)
3384             lpanel->setWidth((int)round(treetwopanels_lpanel_pct*window_width));
3385         else
3386             lpanel->setHeight((int)round(treetwopanels_lpanel_pct*window_height));
3387         if (!dirpanel->shown())
3388             dirpanel->handle(sender,FXSEL(SEL_COMMAND,DirPanel::ID_TOGGLE_TREE),ptr);
3389         if (!rpanel->shown())
3390             rpanel->handle(sender,FXSEL(SEL_COMMAND,FXWindow::ID_TOGGLESHOWN),ptr);
3391         // Handle drag corner
3392         lpanel->showCorner(false);
3393         rpanel->showCorner(true);
3394         // Handle active icon
3395         lpanel->showActiveIcon(true);
3396         break;
3397     }
3398 
3399     // Set focus on current panel
3400     lpanel->getCurrent()->setFocusOnList();
3401 
3402     return 1;
3403 }
3404 
3405 
3406 // Update the horizontal / vertical panel radio menus
onUpdHorzVertPanels(FXObject * sender,FXSelector sel,void * ptr)3407 long XFileExplorer::onUpdHorzVertPanels(FXObject* sender,FXSelector sel,void* ptr)
3408 {
3409     if (rpanel->shown())
3410     {
3411         sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),ptr);
3412 
3413         if (vertpanels)
3414         {
3415             lpanel->hidePanelSeparator();
3416             rpanel->hidePanelSeparator();
3417 
3418             if ( FXSELID(sel) == ID_HORZ_PANELS )
3419                 sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),ptr);
3420             else
3421                 sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),ptr);
3422         }
3423         else
3424         {
3425             lpanel->showPanelSeparator();
3426             rpanel->hidePanelSeparator();
3427 
3428             if ( FXSELID(sel) == ID_VERT_PANELS )
3429                 sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_UNCHECK),ptr);
3430             else
3431                 sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_CHECK),ptr);
3432         }
3433     }
3434     else
3435     {
3436         lpanel->hidePanelSeparator();
3437         rpanel->hidePanelSeparator();
3438 
3439         sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),ptr);
3440     }
3441 
3442     return 1;
3443 }
3444 
3445 
3446 // Update the panels
onUpdShowPanels(FXObject * sender,FXSelector sel,void * ptr)3447 long XFileExplorer::onUpdShowPanels(FXObject* sender,FXSelector sel,void* ptr)
3448 {
3449     // Keep the panel sizes relative to the window width or height (if option enabled)
3450 
3451     register int width;
3452     register int height;
3453 
3454     // Get the current window width and height
3455     width=getWidth();
3456     height=getHeight();
3457 
3458     // If width has changed and relative resizing option is enabled
3459     if (relative_resize && prev_width!=width)
3460     {
3461         // One panel mode not relevant
3462 
3463         // Two panels mode
3464         if (!dirpanel->shown() && rpanel->shown())
3465         {
3466             // Set left panel width / height to the new value
3467             if (vertpanels)
3468                 lpanel->setWidth((int)round(twopanels_lpanel_pct*width));
3469             else
3470                 lpanel->setHeight((int)round(twopanels_lpanel_pct*height));
3471         }
3472 
3473         // Tree panel mode
3474         else if (dirpanel->shown() && !rpanel->shown())
3475         {
3476             // Set dirpanel width to the new value
3477             dirpanel->setWidth((int)round(treepanel_tree_pct * width) );
3478         }
3479 
3480         // Tree and two panels mode
3481         else if (dirpanel->shown() && rpanel->shown())
3482         {
3483             // Set dirpanel width to the new value
3484             dirpanel->setWidth((int)round(treetwopanels_tree_pct * width) );
3485 
3486             // Set left panel width / height to the new value
3487             if (vertpanels)
3488                 lpanel->setWidth((int)round(treetwopanels_lpanel_pct*width));
3489             else
3490                 lpanel->setHeight((int)round(treetwopanels_lpanel_pct*height));
3491         }
3492     }
3493 
3494     // Update previous window width
3495     prev_width=width;
3496 
3497     // Update the panel menus and the panel display
3498     FXuint msg=FXWindow::ID_UNCHECK;
3499     switch(FXSELID(sel))
3500     {
3501     case ID_SHOW_ONE_PANEL:
3502         if (!dirpanel->shown() && !rpanel->shown())
3503         {
3504             msg = FXWindow::ID_CHECK;
3505             if (rpanelmenutitle->shown())
3506             {
3507                 rpanelmenutitle->hide();
3508                 rpanelmenutitle->disable();
3509                 lpanelmenutitle->setText(_("&Panel"));
3510                 lpanel->show();
3511                 //lpanel->repaint();
3512                 lpanel->setActive();
3513             }
3514         }
3515         break;
3516 
3517     case ID_SHOW_TWO_PANELS:
3518         if (!dirpanel->shown() && rpanel->shown())
3519         {
3520             // Update the left panel relative size (only if the window size is sufficient)
3521             if (vertpanels)
3522             {
3523                 if (getWidth()>10)
3524                     twopanels_lpanel_pct=(double)(lpanel->getWidth())/(double)(getWidth());
3525             }
3526             else
3527             {
3528                 if (getHeight()>10)
3529                     twopanels_lpanel_pct=(double)(lpanel->getHeight())/(double)(getHeight());
3530             }
3531 
3532             msg=FXWindow::ID_CHECK;
3533             if (!rpanelmenutitle->shown())
3534             {
3535                 rpanelmenutitle->enable();
3536                 rpanelmenutitle->show();
3537                 rpanelmenutitle->setText(_("&Right panel"));
3538                 lpanelmenutitle->setText(_("&Left panel"));
3539                 //lpanel->repaint();
3540                 lpanel->setActive();
3541             }
3542         }
3543         break;
3544 
3545     case ID_SHOW_TREE_PANEL:
3546         if (dirpanel->shown() && !rpanel->shown())
3547         {
3548             // Update the tree panel relative size (only if the window size is sufficient)
3549             if (getWidth()>10)
3550                 treepanel_tree_pct=(double)(dirpanel->getWidth())/(double)(getWidth());
3551 
3552             msg=FXWindow::ID_CHECK;
3553             if (rpanelmenutitle->shown())
3554             {
3555                 rpanelmenutitle->hide();
3556                 rpanelmenutitle->disable();
3557                 lpanelmenutitle->setText(_("&Panel"));
3558                 //lpanel->repaint();
3559                 lpanel->setActive();
3560             }
3561         }
3562         break;
3563 
3564     case ID_SHOW_TREE_TWO_PANELS:
3565         if (dirpanel->shown() && rpanel->shown())
3566         {
3567             // Update the tree panel relative size (only if the window size is sufficient)
3568             if (getWidth()>10)
3569                 treetwopanels_tree_pct=(double)(dirpanel->getWidth())/(double)(getWidth());
3570 
3571             // Update the left panel relative size (only if the window size is sufficient)
3572             if (vertpanels)
3573             {
3574                 if (getWidth()>10)
3575                     treetwopanels_lpanel_pct=(double)(lpanel->getWidth())/(double)(getWidth());
3576             }
3577             else
3578             {
3579                 if (getHeight()>10)
3580                     treetwopanels_lpanel_pct=(double)(lpanel->getHeight())/(double)(getHeight());
3581             }
3582 
3583             msg = FXWindow::ID_CHECK;
3584             if (!rpanelmenutitle->shown())
3585             {
3586                 rpanelmenutitle->enable();
3587                 rpanelmenutitle->show();
3588                 rpanelmenutitle->setText(_("&Right panel"));
3589                 lpanelmenutitle->setText(_("&Left panel"));
3590                 //lpanel->repaint();
3591                 lpanel->setActive();
3592             }
3593         }
3594         break;
3595     }
3596     sender->handle(this,FXSEL(SEL_COMMAND,msg),ptr);
3597 
3598     return 1;
3599 }
3600 
3601 
3602 // Synchronize the panels to the same directory
onCmdSynchronizePanels(FXObject * sender,FXSelector sel,void *)3603 long XFileExplorer::onCmdSynchronizePanels(FXObject* sender,FXSelector sel,void*)
3604 {
3605     FXString dir;
3606 
3607     // Left panel is active
3608     if (lpanel->getCurrent() == lpanel)
3609     {
3610         dir=lpanel->getDirectory();
3611         rpanel->setDirectory(dir);
3612         rpanel->updatePath();
3613     }
3614 
3615     // Right panel is active
3616     else
3617     {
3618         dir=rpanel->getDirectory();
3619         lpanel->setDirectory(dir);
3620         lpanel->updatePath();
3621 
3622     }
3623     return 1;
3624 }
3625 
3626 
3627 // Update the synchronize panels menu item
onUpdSynchronizePanels(FXObject * o,FXSelector,void *)3628 long XFileExplorer::onUpdSynchronizePanels(FXObject* o,FXSelector,void*)
3629 {
3630     if (rpanel->shown())
3631         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
3632     else
3633         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
3634 
3635     return 1;
3636 }
3637 
3638 
3639 // Switch the panels
onCmdSwitchPanels(FXObject * sender,FXSelector sel,void *)3640 long XFileExplorer::onCmdSwitchPanels(FXObject* sender,FXSelector sel,void*)
3641 {
3642     FXString leftdir, rightdir;
3643 
3644     leftdir=lpanel->getDirectory();
3645     rightdir=rpanel->getDirectory();
3646     lpanel->setDirectory(rightdir);
3647     lpanel->updatePath();
3648     rpanel->setDirectory(leftdir);
3649     rpanel->updatePath();
3650 
3651     return 1;
3652 }
3653 
3654 
3655 // Update the switch panels menu item
onUpdSwitchPanels(FXObject * o,FXSelector,void *)3656 long XFileExplorer::onUpdSwitchPanels(FXObject* o,FXSelector,void*)
3657 {
3658     if (rpanel->shown())
3659         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
3660     else
3661         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
3662 
3663     return 1;
3664 }
3665 
3666 
3667 // Preferences
onCmdPrefs(FXObject *,FXSelector s,void * p)3668 long XFileExplorer::onCmdPrefs(FXObject*,FXSelector s,void* p)
3669 {
3670     if (prefsdialog==NULL)
3671         prefsdialog=new PreferencesBox(this,listbackcolor,listforecolor,highlightcolor,pbarcolor,attentioncolor,scrollbarcolor);
3672     prefsdialog->execute(PLACEMENT_OWNER);
3673     lpanel->getCurrent()->setFocusOnList();
3674     return 1;
3675 }
3676 
3677 
3678 // Toggle status bar
onCmdToggleStatus(FXObject *,FXSelector s,void * p)3679 long XFileExplorer::onCmdToggleStatus(FXObject*,FXSelector s,void* p)
3680 {
3681     dirpanel->toggleStatusbar();
3682     lpanel->toggleStatusbar();
3683     rpanel->toggleStatusbar();
3684     return 1;
3685 }
3686 
3687 
onUpdToggleStatus(FXObject * o,FXSelector s,void * p)3688 long XFileExplorer::onUpdToggleStatus(FXObject* o,FXSelector s,void* p)
3689 {
3690     FXMenuCheck* cmd =(FXMenuCheck*)o;
3691     if (lpanel->statusbarShown())
3692         cmd->setCheck(true);
3693     else
3694         cmd->setCheck(false);
3695     return 1;
3696 }
3697 
3698 
3699 // Run shell command or X program
onCmdRun(FXObject *,FXSelector,void *)3700 long XFileExplorer::onCmdRun(FXObject*,FXSelector,void*)
3701 {
3702     int ret;
3703 
3704     ret=chdir(lpanel->getCurrent()->getDirectory().text());
3705     if (ret < 0)
3706     {
3707         int errcode=errno;
3708         if (errcode)
3709             MessageBox::error(this,BOX_OK,_("Error"),_("Can't enter folder %s: %s"),lpanel->getCurrent()->getDirectory().text(),strerror(errcode));
3710         else
3711             MessageBox::error(this,BOX_OK,_("Error"),_("Can't enter folder %s"),lpanel->getCurrent()->getDirectory().text());
3712 
3713         return 0;
3714     }
3715 
3716     FXString command=" ";
3717     if (rundialog==NULL)
3718         rundialog=new HistInputDialog(this,"",_("Execute the command:"),_("Execute command"),"", bigexecicon,HIST_INPUT_EXECUTABLE_FILE,true,_("Console mode"));
3719     rundialog->create();
3720     rundialog->setText(command);
3721     rundialog->CursorEnd();
3722     rundialog->selectAll();
3723     rundialog->clearItems();
3724     for (int i=0; i<RunHistSize; i++)
3725         rundialog->appendItem(RunHistory[i]);
3726     rundialog->sortItems();
3727 
3728     rundialog->setDirectory(ROOTDIR);
3729     if (rundialog->execute())
3730     {
3731         command=rundialog->getText();
3732         if (command != " ")
3733         {
3734             // Execute command in command window
3735             if (rundialog->getOption())
3736             {
3737                 // Make and show command window
3738                 CommandWindow* cmdwin=new CommandWindow(getApp(),_("Command log"),command,30,80);
3739                 cmdwin->create();
3740                 cmdwin->setIcon(runicon);
3741 
3742                 // The CommandWindow object will delete itself when closed!
3743             }
3744 
3745             // Execute silently in background
3746             else
3747             {
3748                 command+=" &";
3749                 ret=system(command.text());
3750                 if (ret < 0)
3751                 {
3752                     MessageBox::error(this,BOX_OK,_("Error"),_("Can't execute command %s"),command.text());
3753                     return 0;
3754                 }
3755             }
3756         }
3757         // Update history list
3758         RunHistSize=rundialog->getHistorySize();
3759         command=rundialog->getText();
3760 
3761         // Check if cmd is a new string, i.e. is not already in history
3762         FXbool newstr=true;
3763         for (int i=0; i<RunHistSize-1; i++)
3764         {
3765             if (streq(RunHistory[i],command.text()))
3766             {
3767                 newstr=false;
3768                 break;
3769             }
3770         }
3771 
3772         // No new string or history limit reached
3773         if (!newstr || RunHistSize>RUN_HIST_SIZE)
3774             RunHistSize--;
3775 
3776         // Restore original history order
3777         rundialog->clearItems();
3778         for (int i = 0; i < RunHistSize; i++)
3779         {
3780             rundialog->appendItem(RunHistory[i]);
3781 		}
3782 
3783         // New string
3784         if (newstr)
3785         {
3786             // FIFO
3787             strlcpy(RunHistory[0],command.text(),command.length()+1);
3788             for (int i=1; i<RunHistSize; i++)
3789                 strlcpy(RunHistory[i],rundialog->getHistoryItem(i-1).text(),rundialog->getHistoryItem(i-1).length()+1);
3790         }
3791     }
3792     ret=chdir(startlocation.text());
3793     if (ret < 0)
3794     {
3795         int errcode=errno;
3796         if (errcode)
3797             MessageBox::error(this,BOX_OK,_("Error"),_("Can't enter folder %s: %s"),startlocation.text(),strerror(errcode));
3798         else
3799             MessageBox::error(this,BOX_OK,_("Error"),_("Can't enter folder %s"),startlocation.text());
3800 
3801         return 0;
3802     }
3803 
3804     lpanel->getCurrent()->setFocusOnList();
3805     return 1;
3806 }
3807 
3808 
3809 // Run an Xfe as root
onCmdSu(FXObject *,FXSelector,void *)3810 long XFileExplorer::onCmdSu(FXObject*,FXSelector,void*)
3811 {
3812     int ret;
3813 
3814     // Wait cursor
3815     getApp()->beginWaitCursor();
3816 
3817     // Obtain preferred root mode
3818     FXbool use_sudo=getApp()->reg().readUnsignedEntry("OPTIONS","use_sudo",false);
3819 
3820     // Select sudo or su to launch xfe as root
3821     ret=chdir(lpanel->getCurrent()->getDirectory().text());
3822     if (ret < 0)
3823     {
3824         int errcode=errno;
3825         if (errcode)
3826             MessageBox::error(this,BOX_OK,_("Error"),_("Can't enter folder %s: %s"),lpanel->getCurrent()->getDirectory().text(),strerror(errcode));
3827         else
3828             MessageBox::error(this,BOX_OK,_("Error"),_("Can't enter folder %s"),lpanel->getCurrent()->getDirectory().text());
3829 
3830         return 0;
3831     }
3832 
3833     FXString title, cmd, command;
3834     if (use_sudo)
3835     {
3836         title = _("Enter the user password:");
3837 	    FXString sudo_cmd = getApp()->reg().readStringEntry("OPTIONS", "sudo_cmd", DEFAULT_SUDO_CMD);
3838         cmd = " -g 60x4 -e " + sudo_cmd;
3839     }
3840     else
3841     {
3842         title = _("Enter the root password:");
3843     	FXString su_cmd = getApp()->reg().readStringEntry("OPTIONS", "su_cmd", DEFAULT_SU_CMD);
3844         cmd = " -g 60x4 -e " + su_cmd;
3845     }
3846 
3847     // Get text font
3848     FXString fontspec = getApp()->reg().readStringEntry("SETTINGS", "textfont", DEFAULT_TEXT_FONT);
3849     if (fontspec.empty())
3850     {
3851 		command = "st -t " + ::quote(title) + cmd;
3852 	}
3853 	else
3854 	{
3855 		FXchar fontsize[32];
3856         FXFont* font = new FXFont(getApp(), fontspec);
3857         font->create();
3858 		snprintf(fontsize, sizeof(fontsize), "%d",(int)(font->getSize()/10)); // Size is in deci-points, thus divide by 10
3859 		command = "st -t " + ::quote(title) + " -f '" + (font->getFamily()).text() + ":pixelsize=" + fontsize + "'" + cmd;
3860     }
3861 
3862     // Execute su or sudo command in an internal st terminal
3863     int status = runst(command);
3864 
3865     // If error
3866     ret=chdir(startlocation.text());
3867     if (ret < 0)
3868     {
3869         int errcode=errno;
3870         if (errcode)
3871             MessageBox::error(this,BOX_OK,_("Error"),_("Can't enter folder %s: %s"),startlocation.text(),strerror(errcode));
3872         else
3873             MessageBox::error(this,BOX_OK,_("Error"),_("Can't enter folder %s"),startlocation.text());
3874 
3875         return 0;
3876     }
3877 
3878     if (status<0)
3879     {
3880         MessageBox::error(getApp(),BOX_OK,_("Error"),_("An error has occurred!"));
3881         getApp()->endWaitCursor();
3882         return 0;
3883     }
3884 
3885     // Wait cursor
3886     getApp()->endWaitCursor();
3887     return 1;
3888 }
3889 
3890 
3891 // File search dialog
onCmdFileSearch(FXObject * o,FXSelector sel,void *)3892 long XFileExplorer::onCmdFileSearch(FXObject* o,FXSelector sel,void*)
3893 {
3894     // Display search box
3895     if (searchwindow==NULL)
3896         searchwindow=new SearchWindow(getApp(),_("Search files and folders"),
3897                                       DECOR_ALL,search_xpos,search_ypos,search_width,search_height,0,0,0,0,0,0);
3898 
3899     // Non modal window
3900     searchwindow->create();
3901     searchwindow->show(PLACEMENT_DEFAULT);
3902 
3903     // Set search path in search window
3904     searchwindow->setSearchPath(lpanel->getCurrent()->getDirectory());
3905 
3906     return 1;
3907 }
3908 
3909 
3910 // Update file search button
onUpdFileSearch(FXObject * o,FXSelector,void *)3911 long XFileExplorer::onUpdFileSearch(FXObject* o,FXSelector,void*)
3912 {
3913 
3914     if (searchwindow != NULL && searchwindow->shown())
3915         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
3916     else
3917         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
3918 
3919     return 1;
3920 }
3921 
3922 
3923 // Empty trash can
onCmdEmptyTrash(FXObject *,FXSelector sel,void * ptr)3924 long XFileExplorer::onCmdEmptyTrash(FXObject*,FXSelector sel,void* ptr)
3925 {
3926     // Wait cursor
3927     getApp()->beginWaitCursor();
3928 
3929     // Compute trash directory size
3930     char buf[MAXPATHLEN+1];
3931     char size[64];
3932     FXString hsize;
3933     FXulong dirsize;
3934     FXuint nbfiles=0, nbsubfolders=0;
3935     FXulong totalsize=0;
3936 
3937     FXString dirpath=trashfileslocation;
3938     strlcpy(buf,dirpath.text(),dirpath.length()+1);
3939     dirsize=pathsize(buf,&nbfiles,&nbsubfolders,&totalsize);
3940 
3941 #if __WORDSIZE == 64
3942     snprintf(size,sizeof(size)-1,"%lu",dirsize);
3943 #else
3944     snprintf(size,sizeof(size)-1,"%llu",dirsize);
3945 #endif
3946     hsize=::hSize(size);
3947 #if __WORDSIZE == 64
3948     snprintf(size,sizeof(size)-1,_("%s (%lu bytes)"),hsize.text(),dirsize);
3949 #else
3950     snprintf(size,sizeof(size)-1,_("%s (%llu bytes)"),hsize.text(),dirsize);
3951 #endif
3952     snprintf(size,sizeof(size)-1,_("%u files, %u subfolders"),nbfiles-nbsubfolders,nbsubfolders-1);
3953 
3954     // Wait cursor
3955     getApp()->endWaitCursor();
3956 
3957     // Confirmation message
3958     FXString message=_("Do you really want to empty the trash can?") + FXString(" (") + hsize + _(" in ") + FXString(size) + FXString(")")
3959                      + _("\n\nAll items will be definitively lost!");
3960 
3961     MessageBox box(this,_("Empty trash can"),message,trash_full_bigicon,BOX_OK_CANCEL|DECOR_TITLE|DECOR_BORDER);
3962     if (box.execute(PLACEMENT_CURSOR) != BOX_CLICKED_OK)
3963         return 0;
3964 
3965     // Wait cursor
3966     getApp()->beginWaitCursor();
3967 
3968     // Delete trash can files folder
3969     File* f;
3970     f=new File(this,_("File delete"),DELETE);
3971     f->create();
3972     f->remove(trashfileslocation);
3973     delete f;
3974 
3975     // Delete trash can info folder
3976     f=new File(this,_("File delete"),DELETE);
3977     f->create();
3978     f->remove(trashinfolocation);
3979     delete f;
3980 
3981     // Re-create the trash can files directory
3982     if (!existFile(trashfileslocation))
3983     {
3984         errno=0;
3985         int ret=mkpath(trashfileslocation.text(),0755);
3986         int errcode=errno;
3987         if (ret==-1)
3988         {
3989             if (errcode)
3990                 MessageBox::error(this,BOX_OK,_("Error"),_("Can't create trash can 'files' folder %s: %s"),trashfileslocation.text(),strerror(errcode));
3991             else
3992                 MessageBox::error(this,BOX_OK,_("Error"),_("Can't create trash can 'files' folder %s"),trashfileslocation.text());
3993         }
3994     }
3995 
3996     // Re-create the trash can info directory
3997     if (!existFile(trashinfolocation))
3998     {
3999         errno=0;
4000         int ret=mkpath(trashinfolocation.text(),0755);
4001         int errcode=errno;
4002         if (ret==-1)
4003         {
4004             if (errcode)
4005                 MessageBox::error(this,BOX_OK,_("Error"),_("Can't create trash can 'info' folder %s: %s"),trashinfolocation.text(),strerror(errcode));
4006             else
4007                 MessageBox::error(this,BOX_OK,_("Error"),_("Can't create trash can 'info' folder %s"),trashinfolocation.text());
4008         }
4009     }
4010 
4011     // Wait cursor
4012     getApp()->endWaitCursor();
4013 
4014     onCmdRefresh(0,0,0);
4015 
4016     return 1;
4017 }
4018 
4019 
4020 // Display trash size
onCmdTrashSize(FXObject *,FXSelector sel,void *)4021 long XFileExplorer::onCmdTrashSize(FXObject*,FXSelector sel,void*)
4022 {
4023     struct stat linfo;
4024     FXString trashsize, trashmtime, trashnbfiles, trashnbfolders;
4025     if (lstatrep(trashfileslocation.text(),&linfo)==0)
4026     {
4027         // Read time format
4028         FXString timeformat=getApp()->reg().readStringEntry("SETTINGS","time_format",DEFAULT_TIME_FORMAT);
4029 
4030         // Trash files size
4031         trashmtime=FXSystem::time(timeformat.text(),linfo.st_mtime);
4032         char buf[MAXPATHLEN];
4033         FXulong dirsize=0;
4034         FXuint nbfiles=0, nbsubfolders=0;
4035         FXulong totalsize=0;
4036         strlcpy(buf,trashfileslocation.text(),trashfileslocation.length()+1);
4037         dirsize=pathsize(buf,&nbfiles,&nbsubfolders,&totalsize);
4038 #if __WORDSIZE == 64
4039         snprintf(buf,sizeof(buf),"%lu",dirsize);
4040 #else
4041         snprintf(buf,sizeof(buf),"%llu",dirsize);
4042 #endif
4043         trashsize=::hSize(buf);
4044         trashnbfiles=FXStringVal(nbfiles-nbsubfolders);
4045         trashnbfolders=FXStringVal(nbsubfolders-1);
4046 
4047         // Dialog box
4048         FXString msg;
4049         msg.format(_("Trash size: %s (%s files, %s subfolders)\n\nModified date: %s"),
4050                    trashsize.text(),trashnbfiles.text(),trashnbfolders.text(),trashmtime.text());
4051         MessageBox dialog(this,_("Trash size"),msg.text(),delete_bigicon,BOX_OK|DECOR_TITLE|DECOR_BORDER,
4052                           JUSTIFY_LEFT|ICON_BEFORE_TEXT|LAYOUT_CENTER_Y|LAYOUT_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
4053         dialog.execute(PLACEMENT_CURSOR);
4054     }
4055     else
4056     {
4057         // Error
4058         MessageBox::error(this,BOX_OK,_("Error"),_("Trash can 'files' folder %s is not readable!"),trashfileslocation.text());
4059         return 0;
4060     }
4061 
4062     return 1;
4063 }
4064 
4065 
4066 // File copy to clipboard
onCmdFileCopyClp(FXObject * o,FXSelector sel,void *)4067 long XFileExplorer::onCmdFileCopyClp(FXObject* o, FXSelector sel, void*)
4068 {
4069     if (dirpanel->isActive())
4070         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_COPY_CLIPBOARD),NULL);
4071 
4072     else
4073         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_COPY_CLIPBOARD),NULL);
4074 
4075     return 1;
4076 }
4077 
4078 
4079 // File cut to clipboard
onCmdFileCutClp(FXObject * o,FXSelector sel,void *)4080 long XFileExplorer::onCmdFileCutClp(FXObject* o, FXSelector sel, void*)
4081 {
4082     if (dirpanel->isActive())
4083         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_CUT_CLIPBOARD),NULL);
4084 
4085     else
4086         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_CUT_CLIPBOARD),NULL);
4087 
4088     return 1;
4089 }
4090 
4091 
4092 // File add copy to clipboard
onCmdFileAddCopyClp(FXObject * o,FXSelector sel,void *)4093 long XFileExplorer::onCmdFileAddCopyClp(FXObject* o, FXSelector sel, void*)
4094 {
4095     if (dirpanel->isActive())
4096         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_ADDCOPY_CLIPBOARD),NULL);
4097 
4098     else
4099         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_ADDCOPY_CLIPBOARD),NULL);
4100 
4101     return 1;
4102 }
4103 
4104 
4105 // File add cut to clipboard
onCmdFileAddCutClp(FXObject * o,FXSelector sel,void *)4106 long XFileExplorer::onCmdFileAddCutClp(FXObject* o, FXSelector sel, void*)
4107 {
4108     if (dirpanel->isActive())
4109         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_ADDCUT_CLIPBOARD),NULL);
4110 
4111     else
4112         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_ADDCUT_CLIPBOARD),NULL);
4113 
4114     return 1;
4115 }
4116 
4117 
4118 // File paste from clipboard
onCmdFilePasteClp(FXObject * o,FXSelector sel,void *)4119 long XFileExplorer::onCmdFilePasteClp(FXObject* o, FXSelector sel, void*)
4120 {
4121     if (dirpanel->isActive())
4122         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_PASTE_CLIPBOARD),NULL);
4123 
4124     else
4125         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_PASTE_CLIPBOARD),NULL);
4126     return 1;
4127 }
4128 
4129 
4130 // File rename
onCmdFileRename(FXObject * o,FXSelector sel,void *)4131 long XFileExplorer::onCmdFileRename(FXObject* o, FXSelector sel, void*)
4132 {
4133     lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_FILE_RENAME),NULL);
4134     return 1;
4135 }
4136 
4137 
4138 // File move
onCmdFileMoveto(FXObject * o,FXSelector sel,void * ptr)4139 long XFileExplorer::onCmdFileMoveto(FXObject* o, FXSelector sel, void* ptr)
4140 {
4141     if (dirpanel->isActive())
4142         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_DIR_MOVETO),ptr);
4143 
4144     else
4145         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_FILE_MOVETO),NULL);
4146     return 1;
4147 }
4148 
4149 
4150 // File copy to
onCmdFileCopyto(FXObject * o,FXSelector sel,void * ptr)4151 long XFileExplorer::onCmdFileCopyto(FXObject* o, FXSelector sel, void* ptr)
4152 {
4153     if (dirpanel->isActive())
4154         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_DIR_COPYTO),ptr);
4155 
4156     else
4157         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_FILE_COPYTO),NULL);
4158 
4159     return 1;
4160 }
4161 
4162 
4163 // File symlink
onCmdFileSymlink(FXObject * o,FXSelector sel,void * ptr)4164 long XFileExplorer::onCmdFileSymlink(FXObject* o, FXSelector sel, void* ptr)
4165 {
4166     if (dirpanel->isActive())
4167         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_DIR_SYMLINK),ptr);
4168 
4169     else
4170         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_FILE_SYMLINK),NULL);
4171 
4172     return 1;
4173 }
4174 
4175 
4176 // File trash
onCmdFileTrash(FXObject * o,FXSelector sel,void * ptr)4177 long XFileExplorer::onCmdFileTrash(FXObject* o, FXSelector sel, void* ptr)
4178 {
4179     if (dirpanel->isActive())
4180         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_DIR_TRASH),ptr);
4181 
4182     else
4183         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_FILE_TRASH),ptr);
4184 
4185     return 1;
4186 }
4187 
4188 
4189 // File restore
onCmdFileRestore(FXObject * o,FXSelector sel,void * ptr)4190 long XFileExplorer::onCmdFileRestore(FXObject* o,FXSelector sel,void* ptr)
4191 {
4192     if (dirpanel->isActive())
4193         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_DIR_RESTORE),ptr);
4194 
4195     else
4196         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_FILE_RESTORE),ptr);
4197 
4198     return 1;
4199 }
4200 
4201 
4202 // File delete
onCmdFileDelete(FXObject * o,FXSelector sel,void * ptr)4203 long XFileExplorer::onCmdFileDelete(FXObject* o,FXSelector sel,void* ptr)
4204 {
4205     if (dirpanel->isActive())
4206         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_DIR_DELETE),ptr);
4207 
4208     else
4209         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_FILE_DELETE),ptr);
4210 
4211     return 1;
4212 }
4213 
4214 
4215 // File properties
onCmdFileProperties(FXObject * o,FXSelector sel,void *)4216 long XFileExplorer::onCmdFileProperties(FXObject* o,FXSelector sel,void*)
4217 {
4218     if (dirpanel->isActive())
4219         dirpanel->handle(o,FXSEL(SEL_COMMAND,DirPanel::ID_PROPERTIES),NULL);
4220 
4221     else
4222         lpanel->getCurrent()->handle(o,FXSEL(SEL_COMMAND,FilePanel::ID_PROPERTIES),NULL);
4223 
4224     return 1;
4225 }
4226 
4227 
4228 // Update the empty trash can and trash menus
onUpdEmptyTrash(FXObject * o,FXSelector,void * ptr)4229 long XFileExplorer::onUpdEmptyTrash(FXObject* o,FXSelector,void* ptr)
4230 {
4231 
4232     FXbool use_trash_can=getApp()->reg().readUnsignedEntry("OPTIONS","use_trash_can",true);
4233     if (use_trash_can)
4234     {
4235         // Update the empty trash can menu
4236         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
4237 
4238         // Update the trash menu title
4239         helpmenutitle->setText("");
4240         trashmenutitle->setText(_("T&rash"));
4241         trashmenutitle->enable();
4242         trashmenutitle->show();
4243         helpmenutitle->setText(_("&Help"));
4244     }
4245     else
4246     {
4247         // Update the empty trash can menu
4248         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
4249 
4250         // Update the trash menu title
4251         trashmenutitle->hide();
4252         trashmenutitle->disable();
4253         helpmenutitle->setText("");
4254         helpmenutitle->setText(_("&Help"));
4255     }
4256 
4257     return 1;
4258 }
4259 
4260 
4261 // Update the trash size menu
onUpdTrashSize(FXObject * o,FXSelector,void *)4262 long XFileExplorer::onUpdTrashSize(FXObject* o,FXSelector,void*)
4263 {
4264     FXbool use_trash_can=getApp()->reg().readUnsignedEntry("OPTIONS","use_trash_can",true);
4265     if (use_trash_can)
4266         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
4267     else
4268         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
4269 
4270     return 1;
4271 }
4272 
4273 
4274 // Update the file delete menu item
onUpdFileDelete(FXObject * o,FXSelector,void * ptr)4275 long XFileExplorer::onUpdFileDelete(FXObject* o,FXSelector,void* ptr)
4276 {
4277     if (dirpanel->isActive())
4278         dirpanel->handle(o,FXSEL(SEL_UPDATE,DirPanel::ID_DIR_DELETE),ptr);
4279 
4280     else
4281         lpanel->getCurrent()->handle(o,FXSEL(SEL_UPDATE,FilePanel::ID_FILE_DELETE),ptr);
4282 
4283     return 1;
4284 }
4285 
4286 
4287 // Update the move to trash menu item
onUpdFileTrash(FXObject * o,FXSelector,void * ptr)4288 long XFileExplorer::onUpdFileTrash(FXObject* o,FXSelector,void* ptr)
4289 {
4290     if (dirpanel->isActive())
4291         dirpanel->handle(o,FXSEL(SEL_UPDATE,DirPanel::ID_DIR_TRASH),ptr);
4292 
4293     else
4294         lpanel->getCurrent()->handle(o,FXSEL(SEL_UPDATE,FilePanel::ID_FILE_TRASH),ptr);
4295 
4296     return 1;
4297 }
4298 
4299 
4300 // Update the restore from trash menu item
onUpdFileRestore(FXObject * o,FXSelector,void * ptr)4301 long XFileExplorer::onUpdFileRestore(FXObject* o,FXSelector,void* ptr)
4302 {
4303     if (dirpanel->isActive())
4304         dirpanel->handle(o,FXSEL(SEL_UPDATE,DirPanel::ID_DIR_RESTORE),ptr);
4305 
4306     else
4307         lpanel->getCurrent()->handle(o,FXSEL(SEL_UPDATE,FilePanel::ID_FILE_RESTORE),ptr);
4308 
4309     return 1;
4310 }
4311 
4312 
4313 // Update the file operation menu items
onUpdFileMan(FXObject * o,FXSelector,void *)4314 long XFileExplorer::onUpdFileMan(FXObject* o,FXSelector,void*)
4315 {
4316     // Update the panelfocus variable
4317     if (lpanel->getCurrent()->isActive())
4318         panelfocus=FILEPANEL_FOCUS;
4319     if (dirpanel->isActive())
4320         panelfocus=DIRPANEL_FOCUS;
4321 
4322     // Update the file operation menu items
4323     if (dirpanel->isActive())
4324     {
4325         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
4326     }
4327     else
4328     {
4329         int num=lpanel->getCurrent()->getNumSelectedItems();
4330         if (num==0)
4331             o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
4332         else if (num==1 && lpanel->getCurrent()->isItemSelected(0))
4333             o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
4334         else
4335             o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
4336     }
4337 
4338     return 1;
4339 }
4340 
4341 
4342 // Update the file rename menu items
onUpdFileRename(FXObject * o,FXSelector,void *)4343 long XFileExplorer::onUpdFileRename(FXObject* o,FXSelector,void*)
4344 {
4345     int num=lpanel->getCurrent()->getNumSelectedItems();
4346     if (num==1)
4347     {
4348         if (lpanel->getCurrent()->isItemSelected(0))
4349             o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
4350         else
4351             o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
4352     }
4353     else
4354         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
4355     return 1;
4356 }
4357 
4358 
4359 // Update the paste menu and button
onUpdFilePaste(FXObject * o,FXSelector sel,void *)4360 long XFileExplorer::onUpdFilePaste(FXObject* o,FXSelector sel,void*)
4361 {
4362     lpanel->getCurrent()->handle(o,FXSEL(SEL_UPDATE,FilePanel::ID_PASTE_CLIPBOARD),NULL);
4363     return 1;
4364 }
4365 
4366 
4367 // Update the root menu items
onUpdSu(FXObject * o,FXSelector,void *)4368 long XFileExplorer::onUpdSu(FXObject* o,FXSelector,void*)
4369 {
4370     FXbool root_mode=getApp()->reg().readUnsignedEntry("OPTIONS","root_mode",true);
4371 
4372     if (!root_mode || getuid()==0)
4373         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
4374     else
4375         o->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
4376 
4377     return 1;
4378 }
4379 
4380 
4381 
4382 // Open files URIS
openFiles(vector_FXString startURIs)4383 void XFileExplorer::openFiles(vector_FXString startURIs)
4384 {
4385     FXString pathname, samecmd, cmd, cmdname, itemslist=" ";
4386     FileAssoc* association;
4387     FXbool same=true;
4388     FXbool first=true;
4389 
4390     // Default programs
4391     FXString txtviewer=getApp()->reg().readStringEntry("PROGS","txtviewer",DEFAULT_TXTVIEWER);
4392     FXString txteditor=getApp()->reg().readStringEntry("PROGS","txteditor",DEFAULT_TXTEDITOR);
4393     FXString imgviewer=getApp()->reg().readStringEntry("PROGS","imgviewer",DEFAULT_IMGVIEWER);
4394     FXString imgeditor=getApp()->reg().readStringEntry("PROGS","imgeditor",DEFAULT_IMGEDITOR);
4395     FXString pdfviewer=getApp()->reg().readStringEntry("PROGS","pdfviewer",DEFAULT_PDFVIEWER);
4396     FXString audioplayer=getApp()->reg().readStringEntry("PROGS","audioplayer",DEFAULT_AUDIOPLAYER);
4397     FXString videoplayer=getApp()->reg().readStringEntry("PROGS","videoplayer",DEFAULT_VIDEOPLAYER);
4398     FXString archiver=getApp()->reg().readStringEntry("PROGS","archiver",DEFAULT_ARCHIVER);
4399 
4400     // Update associations dictionary
4401     FileDict* assocdict=new FileDict(getApp());
4402 
4403     // Check if all files have the same association
4404     for (FXuint u=0; u<startURIs.size(); u++)
4405     {
4406         if (::isFile(startURIs[u]))
4407         {
4408             // Increment number of selected items
4409             pathname=startURIs[u];
4410             association=assocdict->findFileBinding(pathname.text());
4411 
4412             if (association)
4413             {
4414                 cmd = association->command.section(',',0);
4415 
4416                 // Use a default program if possible
4417                 switch (progs[cmd])
4418                 {
4419                 case TXTVIEWER:
4420                     cmd=txtviewer;
4421                     break;
4422 
4423                 case TXTEDITOR:
4424                     cmd=txteditor;
4425                     break;
4426 
4427                 case IMGVIEWER:
4428                     cmd=imgviewer;
4429                     break;
4430 
4431                 case IMGEDITOR:
4432                     cmd=imgeditor;
4433                     break;
4434 
4435                 case PDFVIEWER:
4436                     cmd=pdfviewer;
4437                     break;
4438 
4439                 case AUDIOPLAYER:
4440                     cmd=audioplayer;
4441                     break;
4442 
4443                 case VIDEOPLAYER:
4444                     cmd=videoplayer;
4445                     break;
4446 
4447                 case ARCHIVER:
4448                     cmd=archiver;
4449                     break;
4450 
4451                 case NONE: // No program found
4452                     ;
4453                     break;
4454                 }
4455 
4456                 if (cmd != "")
4457                 {
4458                     // First item
4459                     if (first)
4460                     {
4461                         samecmd = cmd;
4462                         first=false;
4463                     }
4464 
4465                     if (samecmd != cmd)
4466                     {
4467                         same=false;
4468                         break;
4469                     }
4470 
4471                     // List of items
4472                     itemslist += ::quote(pathname) + " ";
4473                 }
4474                 else
4475                 {
4476                     same=false;
4477                     break;
4478                 }
4479             }
4480             else
4481             {
4482                 same=false;
4483                 break;
4484             }
4485         }
4486     }
4487 
4488 #ifdef STARTUP_NOTIFICATION
4489     // Startup notification option and exceptions (if any)
4490     FXbool usesn=getApp()->reg().readUnsignedEntry("OPTIONS","use_startup_notification",true);
4491     FXString snexcepts=getApp()->reg().readStringEntry("OPTIONS","startup_notification_exceptions","");
4492 #endif
4493 
4494     // Same command for all files: open them
4495     if (same)
4496     {
4497         cmdname=samecmd;
4498 
4499         // If command exists, run it
4500         if (::existCommand(cmdname))
4501         {
4502             cmd=samecmd+itemslist;
4503 #ifdef STARTUP_NOTIFICATION
4504             runcmd(cmd,cmdname,lpanel->getDirectory(),startlocation,usesn,snexcepts);
4505 #else
4506             runcmd(cmd,lpanel->getDirectory(),startlocation);
4507 #endif
4508         }
4509 
4510         // Command does not exist
4511         else
4512             MessageBox::error(this,BOX_OK,_("Error"),_("Command not found: %s"),cmd.text());
4513     }
4514 
4515     // Files have different commands: handle them separately
4516     else
4517     {
4518         for (FXuint u=0; u<startURIs.size(); u++)
4519         {
4520             if (::isFile(startURIs[u]))
4521             {
4522                 pathname=startURIs[u];
4523                 association=assocdict->findFileBinding(pathname.text());
4524                 if (association)
4525                 {
4526                     // Use it to open the file
4527                     cmd = association->command.section(',',0);
4528 
4529                     // Use a default program if possible
4530                     switch (progs[cmd])
4531                     {
4532                     case TXTVIEWER:
4533                         cmd=txtviewer;
4534                         break;
4535 
4536                     case TXTEDITOR:
4537                         cmd=txteditor;
4538                         break;
4539 
4540                     case IMGVIEWER:
4541                         cmd=imgviewer;
4542                         break;
4543 
4544                     case IMGEDITOR:
4545                         cmd=imgeditor;
4546                         break;
4547 
4548                     case PDFVIEWER:
4549                         cmd=pdfviewer;
4550                         break;
4551 
4552                     case AUDIOPLAYER:
4553                         cmd=audioplayer;
4554                         break;
4555 
4556                     case VIDEOPLAYER:
4557                         cmd=videoplayer;
4558                         break;
4559 
4560                     case ARCHIVER:
4561                         cmd=archiver;
4562                         break;
4563 
4564                     case NONE: // No program found
4565                         ;
4566                         break;
4567                     }
4568 
4569                     if (cmd != "")
4570                     {
4571                         cmdname=cmd;
4572 
4573                         // If command exists, run it
4574                         if (::existCommand(cmdname))
4575                         {
4576                             cmd=cmdname+" "+::quote(pathname);
4577 #ifdef STARTUP_NOTIFICATION
4578                             runcmd(cmd,cmdname,lpanel->getDirectory(),startlocation,usesn,snexcepts);
4579 #else
4580                             runcmd(cmd,lpanel->getDirectory(),startlocation);
4581 #endif
4582                         }
4583 
4584                         // Command does not exist
4585                         else
4586                             MessageBox::error(this,BOX_OK,_("Error"),_("Command not found: %s"),cmdname.text());
4587                     }
4588 
4589                     // Command string is void
4590                     else
4591                         MessageBox::error(this,BOX_OK,_("Error"),_("Invalid file association: %s"),FXPath::extension(pathname).text());
4592                 }
4593 
4594                 // Other cases
4595                 else
4596                     MessageBox::error(this,BOX_OK,_("Error"),_("File association not found: %s"),FXPath::extension(pathname).text());
4597             }
4598         }
4599     }
4600 }
4601 
4602 
4603 // Quit immediately and properly, if asked
onUpdQuit(FXObject * o,FXSelector,void *)4604 long XFileExplorer::onUpdQuit(FXObject* o,FXSelector,void*)
4605 {
4606     if (stop)
4607         onQuit(0,0,0);
4608 
4609     return 1;
4610 }
4611 
4612