Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtprintinfo / UI / DtFindSet.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: DtFindSet.C /main/5 1998/07/24 16:12:36 mgreess $ */
24 /*                                                                      *
25  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
26  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
27  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
28  * (c) Copyright 1993, 1994 Novell, Inc.                                *
29  */
30
31 #include "DtFindSet.h"
32 #include "DtPrtProps.h"
33 #include "DtMainW.h"
34 #include "Button.h"
35 #include "Container.h"
36 #include "IconObj.h"
37 #include "LabelObj.h"
38 #include "ComboBoxObj.h"
39 #include "HelpSystem.h"
40 #include "Invoke.h"
41
42 #include "dtprintinfomsg.h"
43
44 #include <stdio.h>
45 #include <pwd.h>
46 #include <unistd.h> // This is for the getuid function
47 #include <stdlib.h> // This is for the getenv function
48
49 const char *GET_DIRS = 
50    "lang=${LANG:-C} ; "
51    "for i in $(echo $XMICONSEARCHPATH | sed -e 's/:/ /g' -e s/%L/$lang/g) ; "
52      "do "
53         "dirname $i ; "
54      "done | sort -u";
55
56 // Subclass IconObj in order to disable SetOpen method
57 class FindSetIcon : public IconObj
58 {
59  public:
60
61    FindSetIcon(AnyUI *parent, char *name, char *icon) :
62       IconObj(parent, name, icon) { }
63    boolean SetOpen(boolean) { return true; }
64 };
65
66 DtFindSet::DtFindSet(DtMainW *parent, char *name, CallerCallback _callback)
67         : Dialog(parent, name, MODAL)
68 {
69    mainw = parent;
70    callback = _callback;
71    last_position = -1;
72    helpSystem = NULL;
73    char *output;
74    Invoke *_thread = new Invoke(GET_DIRS, &output);
75    char *s, *s1 = output;
76    s = s1;
77    n_dirs = 0;
78    while (s && (s = strchr(s1, '\n')))
79     {
80       n_dirs++;
81       s1 = s + 1;
82     }
83    if (_thread->status || n_dirs == 0)
84     {
85       delete [] output;
86       struct passwd * pwInfo;
87       char *home = getenv("HOME");
88       if (home == NULL || strlen(home) == 0)
89        {
90          pwInfo = getpwuid(getuid());
91          home = pwInfo->pw_dir;
92        }
93       output = new char[strlen(home) + 80];
94       n_dirs = 3;
95       sprintf(output, "%s/.dt/icons\n"
96                       "/usr/dt/appconfig/icons/C\n"
97                       "/etc/dt/appconfig/icons/C\n", (home[1] ? home : "" ));
98     }
99    dirs = new char *[n_dirs];
100    filenames = new FileNames [n_dirs];
101    s = output;
102    int i;
103    for (i = 0; i < n_dirs; i++)
104     {
105       s1 = s;
106       s = strchr(s, '\n');
107       *s++ = '\0';
108       dirs[i] = strdup(s1);
109       filenames[i] = new FileNamesStruct;
110       filenames[i]->icons = NULL;
111       filenames[i]->read_it = true;
112       filenames[i]->n_icons = 0;
113     }
114    delete [] output;
115    delete _thread;
116
117    comboBox = new ComboBoxObj(this, ComboBoxCB, MESSAGE(IconFoldersL), dirs,
118                               n_dirs);
119
120    icon_label = new LabelObj(this, MESSAGE(IconTitleL));
121    icons = new Container(this, "icons", SCROLLED_WORK_AREA);
122    icons->Height(250);
123    empty = new LabelObj(icons, MESSAGE(EmptyL));
124    empty->Visible(false);
125
126    comboBox->AttachTop(5);
127    comboBox->AttachLeft();
128    comboBox->AttachRight();
129
130    icon_label->AttachTop(comboBox, 10);
131    icon_label->AttachLeft();
132    icon_label->AttachRight();
133    icons->AttachTop(icon_label);
134    icons->AttachRight();
135    icons->AttachLeft();
136    icons->AttachBottom();
137
138    ok = new Button(this, MESSAGE(OKL), PUSH_BUTTON, OkCB, this);
139    cancel = new Button(this, MESSAGE(CancelL), PUSH_BUTTON, CancelCB, this);
140    help = new Button(this, MESSAGE(HelpL), PUSH_BUTTON, HelpCB, this);
141
142    DefaultButton(ok);
143    CancelButton(cancel);
144 }
145
146 DtFindSet::~DtFindSet()
147 {
148    int i;
149    for (i = 0; i < n_dirs; i++)
150     {
151       delete dirs[i];
152       delete filenames[i];
153     }
154    delete []dirs;
155    delete []filenames;
156 }
157
158 void DtFindSet::InitComboBox(BaseUI *obj, void * /*data*/)
159 {
160    DtFindSet *findSet = (DtFindSet *)obj;
161    findSet->Refresh();
162    ComboBoxCB(findSet->comboBox, findSet->dirs[0], 1);
163 }
164
165 boolean DtFindSet::SetVisiblity(boolean flag)
166 {
167    if (last_position == -1)
168       AddTimeOut(&DtFindSet::InitComboBox, NULL, 1000);
169    Dialog::SetVisiblity(flag);
170    return true;
171 }
172
173 void DtFindSet::Reset()
174 {
175 }
176
177 void DtFindSet::Apply()
178 {
179    BaseUI **items;
180    int n_items;
181    icons->Selection(&n_items, &items);
182    if (n_items && callback)
183     {
184       FindSetIcon *icon = (FindSetIcon *)items[0];
185       char *iconfile;
186       if (iconfile = strrchr(icon->IconFile(), '/'))
187          iconfile++;
188       else
189          iconfile = icon->IconFile();
190       (*callback)(caller, iconfile);
191     }
192    delete []items;
193 }
194
195 void DtFindSet::CloseCB()
196 {
197    Reset();
198    Visible(false);
199 }
200
201 void DtFindSet::OkCB(void *data)
202 {
203    DtFindSet *obj = (DtFindSet *) data;
204    
205    obj->Apply();
206    obj->Visible(false);
207 }
208
209 void DtFindSet::ApplyCB(void *data)
210 {
211    DtFindSet *obj = (DtFindSet *) data;
212    obj->Apply();
213 }
214
215 void DtFindSet::CancelCB(void *data)
216 {
217    DtFindSet *obj = (DtFindSet *) data;
218    
219    obj->Reset();
220    obj->Visible(false);
221 }
222
223 void DtFindSet::ResetCB(void *data)
224 {
225    DtFindSet *obj = (DtFindSet *) data;
226    
227    obj->Reset();
228 }
229
230 void DtFindSet::HelpCB(void *data)
231 {
232    DtFindSet *obj = (DtFindSet *) data;
233    obj->HandleHelpRequest();
234 }
235
236 boolean DtFindSet::HandleHelpRequest()
237 {
238    char old_msg[200];
239    strcpy(old_msg, mainw->status_line->Name());
240    mainw->status_line->Name(MESSAGE(GettingHelpL));
241    mainw->WorkingCursor(true);
242
243    if (!helpSystem)
244     {
245       char *title = new char[120];
246
247       sprintf(title, "%s - %s", mainw->Name(), MESSAGE(HelpL));
248
249       helpSystem = new HelpSystem(this, title, "Printmgr", "FindSetDE",
250                                   QUICK_HELP);
251       helpSystem->Visible(true);
252       delete [] title;
253     }
254    else
255     {
256       helpSystem->Visible(true);
257       helpSystem->Refresh();
258       helpSystem->HelpVolume("Printmgr", "FindSetDE");
259     }
260    mainw->status_line->Name(old_msg);
261    mainw->WorkingCursor(false);
262    return true;
263 }
264
265 void DtFindSet::ComboBoxCB(ComboBoxObj *obj, char *dir, int position)
266 {
267    DtFindSet *findSet = (DtFindSet *)obj->Parent();
268    if (findSet->last_position == position)
269       return;
270
271    FileNames filenames;
272    int i;
273    char *buf = new char[400]; // This allows for a directory len of 240 bytes
274
275    findSet->PointerShape(HOUR_GLASS_CURSOR);
276    findSet->icons->BeginUpdate();
277    findSet->icons->SelectAll(false);
278    if (findSet->last_position > 0)
279     {
280       filenames = findSet->filenames[findSet->last_position - 1];
281       FindSetIcon **icon = filenames->icons;
282       for (i = 0; i < filenames->n_icons; i++, icon++)
283          (*icon)->Visible(false);
284     }
285    filenames = findSet->filenames[position - 1];
286    if (filenames->read_it)
287     {
288       sprintf(buf, "cd %s 2> /dev/null ; "
289                    "/bin/ls -1 | grep '\\.l\\.pm$' | "
290                    "sed 's/\\.l\\.pm//g' | "
291                    "while read file ; do "
292                      "if [ -f $file.m.pm -a -f $file.t.pm ] ; "
293                         "then echo $file ; fi ; "
294                    "done", dir);
295
296       char *output;
297       Invoke *_thread = new Invoke(buf, &output);
298       char *s, *s1 = output;
299       s = s1;
300       filenames->n_icons = 0;
301       while (s && (s = strchr(s1, '\n')))
302        {
303          filenames->n_icons++;
304          s1 = s + 1;
305        }
306       if (filenames->n_icons)
307        {
308          s = output;
309          filenames->icons = new FindSetIcon*[filenames->n_icons];
310          for (i = 0; i < filenames->n_icons; i++)
311           {
312             s1 = s;
313             s = strchr(s, '\n');
314             *s++ = '\0';
315             if (!(i % 10))
316              {
317                sprintf(buf, MESSAGE(LoadingIconsL), i, filenames->n_icons);
318                findSet->icons->UpdateMessage(buf);
319              }
320             sprintf(buf, "%s/%s", dir, s1);
321             filenames->icons[i] = new FindSetIcon(findSet->icons, s1, buf);
322           }
323        }
324       delete _thread;
325       delete output;
326       filenames->read_it = false;
327     }
328    else
329     {
330       FindSetIcon **icon = filenames->icons;
331       for (i = 0; i < filenames->n_icons; i++, icon++)
332          (*icon)->Visible(true);
333     }
334    findSet->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
335    findSet->icons->EndUpdate();
336    sprintf(buf, MESSAGE(IconTitleL), filenames->n_icons);
337    findSet->icon_label->Name(buf);
338    if (filenames->n_icons)
339       findSet->empty->Visible(false);
340    else
341       findSet->empty->Visible(true);
342    findSet->last_position = position;
343
344    delete [] buf;
345 }