First checkin, AXE release 0.2
[AXE.git] / src / filedialog.cpp
1
2 #include "filedialog.h"
3
4 #define OPEN_DLG_OK  100
5 #define OPEN_DLG_CANCEL 101
6
7 #include <algorithm>
8
9 #include <stdio.h>
10
11 #include "directory.xpm"
12 #include "regfile.xpm"
13
14 bool operator < (const file_entry &fe1, const file_entry &fe2)
15 {
16    if (S_ISDIR(fe1.st.st_mode) == S_ISDIR(fe2.st.st_mode))
17    {
18       return fe1.name < fe2.name;
19    }
20    else
21    {
22       return S_ISDIR(fe1.st.st_mode);
23    }
24 }
25
26 directory_view::directory_view(window &parent) : table_view(parent, 200, 2)
27 {
28    width(0) = 20;
29    width(1) = 330;
30    head(1)  = " Name ";
31    Resize(360, 220);
32    dir.create(directory_xpm);
33    reg.create(regfile_xpm);
34    cwd = ".";
35 }
36
37 int directory_view::scan()
38 {
39    DIR           *dirstream;
40    struct dirent *entry;
41    unsigned       i;
42
43    d_list.clear();
44    dirstream = opendir(cwd);
45    entry = readdir(dirstream);
46
47    while (entry)
48    {
49       file_entry  file;
50    
51       file.name = entry->d_name;
52       stat(entry->d_name, &file.st);
53       d_list.push_back(file);
54
55       entry = readdir(dirstream);
56    }
57    closedir(dirstream);
58
59    sort(d_list.begin(), d_list.end());
60
61    recreate(d_list.size());
62
63    for (i = 0; i < d_list.size(); i++)
64    {
65       cell(i, 1) = d_list[i].name;
66    }
67
68    return i;
69 }
70
71 //   Change the view's directory and return the new directory pathname
72
73 String directory_view::changedir(String dir)
74 {
75    char   process_dir[PATH_MAX];  //  Remember the process cwd
76    char   destination_dir[PATH_MAX];
77
78    getcwd(process_dir, PATH_MAX);
79
80    chdir(cwd);
81    if (chdir(dir) == -1)
82    {
83       int  slash;
84
85       perror("File selector");
86       slash = dir.rindex('/');
87       dir = dir(0, slash);
88       chdir(dir);
89    }
90    getcwd(destination_dir, PATH_MAX);
91    cwd = destination_dir;
92    scan();
93    redraw();
94
95    chdir(process_dir);           //  Restore the directory we came from
96
97    return cwd;
98 }
99
100 void directory_view::redraw()
101 {
102    int    i;
103    int    y;
104
105    table_view::redraw();
106    y = 22;
107    i = top_row();
108
109    while ((unsigned)i < d_list.size() && (unsigned)y < Size().h)
110    {
111       if (S_ISDIR(d_list[i].st.st_mode))
112       {
113          DrawPixmap(text_normal_gc, 2, y, dir);
114       }
115       else
116       {
117          DrawPixmap(text_normal_gc, 2, y, reg);
118       }
119       i++;
120       y += 20;
121    }
122 }
123
124 file_dialog::file_dialog(int cmd) : managed_window("File Selector")
125 {
126    char   path[PATH_MAX];
127
128    Background(inside_3D);
129    Resize(400, 360);
130
131    OK = new command_button(*this, 20, 300, "OK", OPEN_DLG_OK);
132    OK_command = cmd;
133
134    Cancel = new command_button(*this, 300, 300, "Cancel", OPEN_DLG_CANCEL);
135    Command_WhenClosed(OPEN_DLG_CANCEL);
136
137    diredit = new edit(*this, 20, 20, "");
138    diredit->Resize(360, 20);
139
140    directory_list = new directory_view(*this);
141    directory_list->Move(20, 44);
142    fileedit = new edit(*this, 20, 270, "");
143    fileedit->Resize(360, 20);
144
145    getcwd(path, PATH_MAX);
146    *diredit = String(path);
147    directory_list->changedir(path);
148 }
149
150 int file_dialog::DoCommand(int code)
151 {
152    switch (code)
153    {
154    case OPEN_DLG_OK:
155       Unmap();
156       XApp->DoCommand(OK_command);
157       return 1;
158
159    case OPEN_DLG_CANCEL:
160       Unmap();
161       return 1;
162
163    default:
164       return -1;
165    }
166 }
167
168 void file_dialog::ChildMessage(win_message &msg)
169 {
170
171    if (msg.msg_id == EDIT_ENTERED)
172    {
173       if (msg.from == fileedit)
174       {
175          diredit->SetFocus();
176       }
177       else
178       {
179          *diredit = directory_list->changedir(*diredit);
180          fileedit->SetFocus();
181       }
182    }
183    else if (msg.msg_id == TABLE_ROW_SELECT)
184    {
185       if (directory_list->selected_a_dir())
186       {
187          String newdir;
188
189          newdir = directory_list->cell(directory_list->selected(), 1);
190          *diredit = directory_list->changedir(newdir);
191       }
192       else
193       {
194          *fileedit = directory_list->cell(directory_list->selected(), 1);
195       }
196    }
197 }