Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtprintinfo / UI / DtApp.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: DtApp.C /main/12 1998/08/25 12:58:57 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 // User Interface headers
32 #include "DtApp.h"
33 #include "DtMainW.h"
34 #include "DtSetModList.h"
35 #include "DtFindD.h"
36 #include "DtWorkArea.h"
37 #include "DtPrtJobIcon.h"
38 #include "DtPrinterIcon.h"
39 #include "DtPrtProps.h"
40 #include "Application.h"
41 #include "LabelObj.h"
42 #include "Button.h"
43 #include "Sep.h"
44
45 // Object headers
46 #include "PrintSubSys.h"
47 #include "ParseJobs.h"
48
49 // Command Execution header
50 #include "Invoke.h"
51 #include "Process.h"
52
53 // Message header
54 #include "dtprintinfomsg.h"
55
56 #include <stdlib.h> // This is for the getenv function
57 #include <unistd.h> // This is for the getuid function
58 #include <signal.h> // This is for the signal function
59 #include <sys/stat.h>
60 #include <pwd.h>
61
62 #ifdef aix
63 extern "C" { extern int seteuid(uid_t); }
64 #endif
65
66 // For Dialog Titles
67 #define TITLE(message, app_name) \
68    char title[BUFSIZ]; \
69    sprintf(title, message, app_name)
70
71 const char *PROPERTY = "Properties";
72 const char *HELP = "Help";
73 const char *FIND = "Find";
74 const char *EXIT = "Exit";
75 const char *HIDE = "Hide";
76 const char *RENAME = "Rename";
77 const char *OPEN = "Open";
78 const char *CLOSE = "Close";
79 const char *PRINTERS_DIR = ".dt/.Printers";
80
81 DtApp::DtApp(char *progname, int *argc, char **argv) :
82       Application(progname, "Dtprintinfo", argc, argv)
83 {
84    save_state = false;
85    connect_timeout = 15;
86    old_dbsearchpath = NULL;
87    uid_t old_uid;
88    single_printer = NULL;
89    app_mode = SINGLE_PRINTER;
90    char *app_name = MESSAGE(ApplicationName2L);
91    if (!((lang = getenv("LANG")) && *lang))
92       lang = "C";
93    home = getenv("HOME");
94    if (!home || *home == '\0')
95     {
96      struct passwd *pwInfo = getpwuid(getuid());
97      home = strdup(pwInfo->pw_dir);
98     }
99    else
100      home = strdup(home);
101    printer_dir = new char[strlen(home) + strlen(PRINTERS_DIR) + 2];
102    sprintf(printer_dir, "%s/%s", home, PRINTERS_DIR);
103    int i;
104    for (i = 0; i < *argc; i++)
105     {
106       if (!strcmp(argv[i], "-edit"))
107        {
108          app_name = MESSAGE(ApplicationName3L);
109          app_mode = CONFIG_PRINTERS;
110          break;
111        }
112       else if (!strcmp(argv[i], "-all"))
113        {
114          app_name = MESSAGE(ApplicationName1L);
115          app_mode = PRINT_MANAGER;
116          break;
117        }
118     }
119
120    Process *procs = new Process();
121    pid_t pid = getppid();
122    char *c = procs->Command(pid);
123
124    if (NULL != c && 0 == strncmp(c, "dtexec", 6))
125     {
126       if (app_mode == CONFIG_PRINTERS)
127        {
128          pid = procs->Parent(pid);
129          c = procs->Command(pid);
130          old_uid = procs->UID(pid);
131          if (!strncmp(c, "dtaction", 8))
132           {
133             pid = procs->Parent(pid);
134             c = procs->Command(pid);
135             old_uid = procs->UID(pid);
136             if (!strncmp(c, "dtexec", 6))
137              {
138                pid = procs->Parent(pid);
139                c = procs->Command(pid);
140                old_uid = procs->UID(pid);
141              }
142           }
143        }
144       delete procs;
145 #ifdef DEAD_WOOD
146       // This is a workaround to avoid a bug in dtsession or dtaction.
147       // We should be fixing the problem there.
148       //
149       // Fork so that the dtaction grandparent exits.  If we don't the
150       // session manager starts the dtaction process and our dtprintinfo
151       // process, then dtaction process starts the dtprintinfo process and
152       // we have two dtprintinfo processes running when the user logs in.
153
154       // On Novell, we notice that the child is dying when the parent
155       // exits.  Ignore the SIGHUP signal before fork() and life is good.
156       signal(SIGHUP, SIG_IGN);
157
158       if (fork() != 0)
159          exit(0);
160 #endif
161     }
162    else
163     {
164       delete procs;
165       old_uid = getuid();
166     }
167
168    if (app_mode == CONFIG_PRINTERS)
169     {
170       if (getuid() != 0)
171        {
172          fprintf(stderr, MESSAGE(RootUserL), progname, "-edit");
173          fprintf(stderr, "\n");
174          exit(1);
175        }
176       char *lang = getenv("LANG");
177       char *DBSearchPath = getenv("DTDATABASESEARCHPATH");
178       old_dbsearchpath = STRDUP(DBSearchPath);
179       char *buf;
180       if (!(lang && *lang))
181          lang = "C";
182       if (DBSearchPath && *DBSearchPath)
183        {
184          buf = new char[strlen(DBSearchPath) + strlen(lang) + 50];
185          sprintf(buf, "DTDATABASESEARCHPATH=/etc/dt/appconfig/types/%s,%s",
186                  lang, DBSearchPath);
187        }
188       else
189        {
190          buf = new char[strlen(DBSearchPath) + strlen(lang) + 50];
191          sprintf(buf, "DTDATABASESEARCHPATH=/etc/dt/appconfig/types/%s", lang);
192        }
193       putenv(buf);
194     }
195
196    Name(app_name);
197
198    Frequency = 30000;
199
200    if (app_mode == CONFIG_PRINTERS)
201       window = new DtMainW("Printers", this, app_name, SCROLLED_WORK_AREA,
202                            SINGLE_SELECT, OpenClose, NULL, PreferenceCB, NULL,
203                            MESSAGE(PrinterMenuL), MESSAGE(PrinterAcceleratorL),
204                            app_mode);
205    else
206       window = new DtMainW("Printers", this, app_name, SCROLLED_ICON_LIST,
207                            SINGLE_SELECT, OpenClose, NULL, PreferenceCB, NULL,
208                            MESSAGE(PrinterMenuL), MESSAGE(PrinterAcceleratorL),
209                            app_mode);
210    window->Initialize();
211    window->ApplicationData = NULL;
212       
213    if (app_mode == PRINT_MANAGER)
214       window->DtAddAction(MESSAGE(FindChoiceL), (char *)window->Category(),
215                           (char *)FIND, ActionCB, window,
216                           MESSAGE(FindMnemonicL), MESSAGE(FindAcceleratorL));
217    window->DtAddAction(MESSAGE(ExitChoiceL), (char *)window->Category(),
218                        (char *)EXIT, ActionCB, window, MESSAGE(ExitMnemonicL), 
219                        MESSAGE(ExitAcceleratorL));
220    window->RegisterPopup(window->container);
221
222    // Save print job's class name for registering GUI actions
223    PrintJob *dummy_printjob;
224    char *className;
225    if (app_mode != CONFIG_PRINTERS)
226     {
227       dummy_printjob = new PrintJob(NULL, "_FOO", NULL, NULL, NULL, NULL, NULL);
228       className = (char *) dummy_printjob->ObjectClassName();
229
230       // Add Print Job Actions
231       AddActions(dummy_printjob);
232     }
233
234    // Save queue's class name for registering GUI actions
235    Queue *dummy_queue = new Queue(NULL, "_DUMMY_");
236    char *className1 = (char *) dummy_queue->ObjectClassName();
237
238    // Add GUI actions for queue
239    if (app_mode == PRINT_MANAGER)
240     {
241       window->DtAddAction(MESSAGE(OpenChoiceL), className1, (char *)OPEN,
242                           ActionCB, window, MESSAGE(OpenMnemonicL));
243       window->DtAddAction(MESSAGE(CloseChoiceL), className1, (char *)CLOSE,
244                           ActionCB, window, MESSAGE(CloseMnemonicL));
245     }
246    // Add Queue Actions
247    if (getuid() == 0 && dummy_queue->NumActions())
248     {
249       window->DtAddSep(className1);
250       AddActions(dummy_queue);
251     }
252    else
253       delete dummy_queue;
254
255    // Add GUI actions for queue
256    if (app_mode != CONFIG_PRINTERS)
257     {
258       if (app_mode == PRINT_MANAGER)
259        {
260          window->DtAddSep(className1);
261          window->DtAddAction(MESSAGE(HideChoiceL), className1, (char *)HIDE,
262                              ActionCB, window, MESSAGE(HideMnemonicL));
263        }
264       //window->DtAddAction(MESSAGE(RenameChoiceL), className1, (char *)RENAME,
265                             //ActionCB, window, MESSAGE(RenameMnemonicL));
266
267       // Add common GUI actions for print jobs and queues
268       window->DtAddSep(className);
269       if (app_mode == PRINT_MANAGER)
270          window->DtAddSep(className1);
271       window->DtAddAction(MESSAGE(PropertiesChoiceL), className,
272                           (char *)PROPERTY, ActionCB, window,
273                           MESSAGE(PropertiesMnemonicL),
274                           MESSAGE(PropertiesAcceleratorL),
275                           "Ctrl<Key>osfBackSpace");
276     }
277    window->DtAddAction(MESSAGE(PropertiesChoiceL), className1, (char *)PROPERTY,
278                        ActionCB, window, MESSAGE(PropertiesMnemonicL),
279                        MESSAGE(PropertiesAcceleratorL),
280                        "Ctrl<Key>osfBackSpace");
281    if (app_mode == CONFIG_PRINTERS)
282     {
283       window->DtAddSep(className1);
284       window->DtAddAction(MESSAGE(HelpChoiceL), className1, (char *)HELP,
285                           ActionCB, window, MESSAGE(HelpMnemonicL), "F1");
286     }
287    else
288     {
289       window->DtAddSep(className);
290       window->DtAddSep(className1);
291       window->DtAddAction(MESSAGE(HelpChoiceL), className, (char *)HELP,
292                           ActionCB, window, MESSAGE(HelpMnemonicL), "F1");
293       window->DtAddAction(MESSAGE(HelpChoiceL), className1, (char *)HELP,
294                           ActionCB, window, MESSAGE(HelpMnemonicL), "F1");
295     }
296
297    if (app_mode == PRINT_MANAGER)
298     {
299       Button *find = new Button(window->fileMenu, MESSAGE(FindChoiceL),
300                                 PUSH_BUTTON, FindCB, window,
301                                 MESSAGE(FindMnemonicL),
302                                 MESSAGE(FindAcceleratorL),
303                                 MESSAGE(FindAcceleratorKeySeq)); 
304       find->Order(0);
305       Button *filter = new Button(window->viewMenu, MESSAGE(ModifyShowChoiceL),
306                                   PUSH_BUTTON, ModifyCB, window,
307                                   MESSAGE(ModifyShowMnemonicL));
308     }
309    // Add a time out to add queues, this way the UI is visible within secs
310    ApplicationData = window;
311    AddTimeOut(AddQueues, this, 0);
312 }
313
314 DtApp::~DtApp()
315 {
316    free(home);
317    delete [] printer_dir;
318 }
319
320 void DtApp::SaveYourSelf()
321 {
322    if (app_mode == CONFIG_PRINTERS)
323       return;
324
325    save_state = true;
326
327    char *value = window->setPrefD->ShowOnlyMyJobs() ? "1" : "0";
328    Save("ShowOnlyMine", value);
329
330    value = window->setPrefD->ShowStatusLine() ? "1" : "0";
331    Save("ShowMessageLine", value);
332
333    value = window->setPrefD->ShowDetailsLabel() ? "1" : "0";
334    Save("ShowDetailsLabel", value);
335
336    value = window->setPrefD->ShowStatusFlags() ? "1" : "0";
337    Save("ShowProblemFlag", value);
338
339    char interval[9];
340    sprintf(interval, "%d", window->setPrefD->UpdateInterval());
341    Save("UpdateInterval", interval);
342
343    switch (window->container->IconView())
344    {
345    case DETAILS: value = "Details"; break;
346    case NAME_ONLY: value = "NameOnly"; break;
347    case SMALL_ICON: value = "SmallIcon"; break;
348    default: value = "LargeIcon"; break;
349    }
350    Save("Representation", value);
351
352    if (app_mode == PRINT_MANAGER)
353     {
354       int i;
355       DtPrinterIcon **queues;
356       char *attribute = (char*) malloc(100);
357       queues = (DtPrinterIcon **) window->container->Children();
358       for (i = 0; i < window->container->NumChildren(); i++)
359        {
360          value = queues[i]->Visible() ? "1" : "0";
361          sprintf(attribute, "%s.Visible", queues[i]->QueueObj()->Name());
362          Save(attribute, value);
363          value = queues[i]->Open() ? "1" : "0";
364          sprintf(attribute, "%s.Open", queues[i]->QueueObj()->Name());
365          Save(attribute, value);
366        }
367       free(attribute);
368     }
369 }
370
371 char *DtApp::SessionFile()
372 {
373    if (app_mode == SINGLE_PRINTER)
374     {
375       if (single_printer)
376          return (char *)single_printer->QueueObj()->Name();
377       else
378          return "default";
379     }
380    else if (app_mode == PRINT_MANAGER)
381       return "Printmgr";
382    else
383       return "Printcfg";
384 }
385
386 void DtApp::UpdateStatusLine()
387 {
388    char *message;
389    char *msg2;
390
391    message = (char*) malloc(200);
392    msg2 = (char*) malloc(100);
393
394    if (app_mode == CONFIG_PRINTERS)
395     {
396       sprintf(message, MESSAGE(EditLangL), lang);
397       window->status_line->Name(message);
398     }
399    else if (app_mode == SINGLE_PRINTER)
400     {
401       if (single_printer)
402        {
403          char *details = MESSAGE(UpL);
404
405          if (single_printer->PrintQueueUp() == false)
406             details = MESSAGE(DownL);
407          else
408 #ifdef aix
409           {
410             Queue *queue = single_printer->QueueObj();
411             int i;
412             for (i = 0; i < queue->NumberDevices(); i++)
413                if (single_printer->PrintDeviceUp(i) == false)
414                 {
415                   details = MESSAGE(DownL);
416                   break;
417                 }
418           }
419 #else
420          if (single_printer->PrintDeviceUp() == false)
421             details = MESSAGE(DownL);
422 #endif
423          Container *rc = single_printer->JobContainer();
424          if (window->setPrefD->ShowOnlyMyJobs() && rc)
425           {
426             if (rc->FindByName(MESSAGE(EmptyL)))
427                window->status_line->Name(details);
428             else
429              {
430                sprintf(msg2, MESSAGE(JobsL), rc->NumChildren());
431                sprintf(message, "%s  %s", details, msg2);
432                window->status_line->Name(message);
433              }
434           }
435          else
436             window->status_line->Name(details);
437        }
438       else
439          window->status_line->Name(MESSAGE(NoDefaultPrinter1L));
440     }
441    else
442     {
443       int i, n_visible = 0;
444       BaseUI ** children = window->container->Children();
445       for (i = 0; i < window->container->NumChildren(); i++)
446          if (children[i]->Visible() == false)
447             n_visible++;
448       sprintf(msg2, MESSAGE(PrintersHiddenL), 
449               window->container->NumChildren(), n_visible);
450       if (window->setPrefD->ShowOnlyMyJobs())
451        {
452          sprintf(message, "%s  %s", msg2, MESSAGE(ShowingMyJobsL));
453          window->status_line->Name(message);
454        }
455       else
456          window->status_line->Name(msg2);
457     }
458
459    free(message);
460    free(msg2);
461 }
462
463 void DtApp::InitQueueDetails(BaseUI *obj, void *data)
464 {
465    ((DtPrinterIcon *)obj)->Update();
466    DtApp *app = (DtApp *)data;
467    app = (DtApp *)app->Parent();
468
469    if (app->save_state)
470       return;
471
472    int n_siblings = obj->NumSiblings();
473    int i = obj->Order() + 1;
474    if (i < n_siblings)
475     {
476       BaseUI **siblings = obj->Siblings();
477       siblings[i]->AddTimeOut(InitQueueDetails, data, 3000);
478     }
479    if (app->app_mode == SINGLE_PRINTER)
480       app->UpdateStatusLine();
481 }
482
483 void DtApp::RemoteStatusCB(BaseUI *obj, char *output, int)
484 {
485    DtPrinterIcon *printer_icon = (DtPrinterIcon *)obj->Parent();
486    Queue *queue = printer_icon->QueueObj();
487    queue->ParseRemoteStatus(output);
488    printer_icon->PrintDeviceUp(queue->RemoteUp());
489    obj->EndUpdate();
490    printer_icon->Open(true);
491 }
492
493 void DtApp::TurnOffHourGlass(BaseUI *obj, void *)
494 {
495    DtMainW *window = (DtMainW *) obj;
496    window->WorkingCursor(false);
497 }
498
499 void DtApp::ShowStatusDialog(DtPrinterIcon *printer_icon)
500 {
501    Queue *queue = printer_icon->QueueObj();
502    Attribute **attributes = queue->Attributes();
503    char *message;
504    int len = 0;
505
506    if (printer_icon->PrintQueueUp() == false)
507       len = strlen(MESSAGE(PrinterDownL)) + strlen(queue->Name());
508 #ifdef aix
509    int i;
510    for (i = 0; i < queue->NumberDevices(); i++)
511       if (printer_icon->PrintDeviceUp(i) == false)
512          len += strlen(MESSAGE(PrinterDownL)) +
513                 strlen(attributes[1 + i]->DisplayValue) + 2;
514 #else
515    if (printer_icon->PrintDeviceUp() == false)
516       len += strlen(MESSAGE(DeviceDownL)) + strlen(attributes[1]->DisplayValue);
517 #endif
518    message = new char[len + 2];
519    *message = '\0';
520    if (printer_icon->PrintQueueUp() == false)
521     {
522       sprintf(message, MESSAGE(PrinterDownL), queue->Name());
523       strcat(message, "\n");
524     }
525 #ifdef aix
526    for (i = 0; i < queue->NumberDevices(); i++)
527       if (printer_icon->PrintDeviceUp(i) == false)
528        {
529          len = strlen(message);
530          sprintf(message + len, MESSAGE(DeviceDownL), 
531                  attributes[1 + i]->DisplayValue);
532          strcat(message, "\n");
533        }
534 #else
535    len = strlen(message);
536    if (printer_icon->PrintDeviceUp() == false)
537       sprintf(message + len, MESSAGE(DeviceDownL), attributes[1]->DisplayValue);
538 #endif
539    len = strlen(message) - 1;
540    if (*(message + len) == '\n')
541       *(message + len) = '\0';
542    TITLE(MESSAGE(PrinterStatusTitleL), window->Name());
543    Dialog *dialog = new Dialog(window, title, message, INFORMATION,
544                                      MESSAGE(OKL));
545    dialog->Visible(true);
546    delete [] message;
547 }
548
549 void DtApp::OpenClose(void *data, BaseUI *obj)
550 {
551    // Return if object isn't a queue, since we can't show a print job's contents
552    if (obj->Parent()->UISubClass() == SCROLLED_HORIZONTAL_ROW_COLUMN)
553       return;
554
555    DtMainW *window = (DtMainW *) data;
556    ((DtApp *)window->Parent())->OpenClose(obj);
557 }
558
559 void DtApp::OpenClose(BaseUI *obj)
560 {
561    if (save_state)
562       return;
563
564    DtPrinterIcon *printer_icon;
565    Container *rc;
566    Queue *queue;
567
568    if (app_mode == CONFIG_PRINTERS)
569     {
570       printer_icon = (DtPrinterIcon *)obj;
571       queue = printer_icon->QueueObj();
572       char *s = new char[strlen(queue->Name()) + STRLEN(old_dbsearchpath) + 90];
573       sprintf(s, "env DTDATABASESEARCHPATH=%s /usr/dt/bin/dtaction %s_Print &",
574               (old_dbsearchpath ? "" : old_dbsearchpath), queue->Name());
575       window->WorkingCursor(true);
576       window->AddTimeOut(TurnOffHourGlass, NULL, 5000);
577       Invoke *_thread = new Invoke(s, NULL, NULL, old_uid);
578       delete _thread;
579       delete [] s;
580       return;
581     }
582
583    if (!STRCMP(obj->Category(), STATUS_FLAG))
584     {
585       printer_icon = (DtPrinterIcon *)obj->Parent();
586       ShowStatusDialog(printer_icon);
587       return;
588     }
589
590    printer_icon = (DtPrinterIcon *)obj;
591    queue = printer_icon->QueueObj();
592    rc = printer_icon->JobContainer();
593    if (obj->Open() == true)
594     {
595       char *message = new char[100];
596       boolean prev_open = false;
597
598       sprintf(message, MESSAGE(UpdatingL), obj->Name());
599       if (!rc)
600        {
601          rc = printer_icon->CreateContainer();
602          rc->AddTimeOut(UpdatePrintJobs, window, Frequency);
603        }
604       else
605          prev_open = rc->Visible();
606       if (printer_icon->Visible())
607          rc->Visible(true);
608       if (queue->IsRemote() && printer_icon->waitForChildren == false)
609        {
610          if (printer_icon->updating == false)
611           {
612             int sockfd = ConnectToPrintServer(queue->Server(), connect_timeout);
613             if (sockfd != -1)
614              {
615                SendPrintJobStatusReguest(sockfd, queue->RemotePrinter());
616                printer_icon->updating = true;
617                if (prev_open == false)
618                 {
619                   rc->BeginUpdate();
620                   rc->UpdateMessage(message);
621                   rc->Refresh();
622                 }
623                printer_icon->UpdateExpand();
624                rc->Thread(sockfd, RemoteStatusCB, 512);
625                return;
626              }
627             else
628              {
629                queue->ParseRemoteStatus("");
630                printer_icon->PrintDeviceUp(false);
631              }
632           }
633          printer_icon->updating = false;
634        }
635       DtWorkArea *container = (DtWorkArea *)obj->Parent();
636       window->WorkingCursor(true);
637       window->status_line->Name(message);
638       container->Refresh();
639       if (queue->IsRemote() == false || printer_icon->waitForChildren)
640          queue->UpdateChildren();
641       PrintJob ** jobs = (PrintJob **)queue->Children();
642       int n_jobs = queue->NumChildren();
643       DtPrtJobIcon ** icons = (DtPrtJobIcon **)rc->Children();
644       int n_icons = rc->NumChildren();
645
646       BaseUI *empty_label = rc->FindByName(MESSAGE(EmptyL));
647       if (n_jobs == 0)
648        {
649          if (!empty_label)
650           {
651             empty_label = new LabelObj(rc, MESSAGE(EmptyL));
652             icons = (DtPrtJobIcon **)rc->Children();
653           }
654          else
655             n_icons--;
656        }
657       else if (empty_label)
658        {
659          n_icons--;
660          delete empty_label;
661          icons = (DtPrtJobIcon **)rc->Children();
662        }
663
664       int i;
665       // Change children first, then delete or create icons
666       if (n_icons)
667        {
668          int j;
669          for (i = 0; i < n_icons; i++)
670           {
671             boolean found_it = false;
672             for (j = 0; j < n_jobs; j++)
673                if (!strcmp(icons[i]->JobNumber(),
674                            jobs[j]->AttributeValue((char *)JOB_NUMBER)))
675                 {
676                   found_it = true;
677                   break;
678                 }
679             if (found_it == false)
680              {
681                delete icons[i];
682                icons = (DtPrtJobIcon **)rc->Children();
683                n_icons--;
684                i = -1;
685              }
686           }
687          for (i = 0; i < n_icons; i++)
688           {
689             boolean found_it = false;
690             for (j = 0; j < n_jobs; j++)
691                if (!strcmp(icons[i]->JobNumber(),
692                            jobs[j]->AttributeValue((char *)JOB_NUMBER)))
693                 {
694                   found_it = true;
695                   break;
696                 }
697             if (found_it)
698                icons[i]->PrintJobObj(jobs[j]);
699             else
700              {
701                DtPrtJobIcon *tmp = new DtPrtJobIcon(window, rc, jobs[j], i + 1);
702                tmp->Order(i);
703                icons = (DtPrtJobIcon **)rc->Children();
704                n_icons++;
705              }
706           }
707
708        }
709       else
710          i = 0;
711       if (n_jobs < n_icons) // Delete excess icons
712          for (; i < n_icons; i++)
713             delete rc->Children()[n_jobs];
714       else // Create new icons
715          for (; i < n_jobs; i++)
716             new DtPrtJobIcon(window, rc, jobs[i], i + 1);
717       icons = (DtPrtJobIcon **)rc->Children();
718       n_icons = rc->NumChildren();
719       for (i = 0; i < n_jobs; i++)
720        {
721          char number[5];
722          sprintf(number, "%d", i + 1);
723          icons[i]->TopString(number);
724        }
725       if (window->setPrefD->ShowOnlyMyJobs())
726        {
727          if (getuid() == 0) // check to see if we are root
728             ShowUserJobs(obj, "root", true);
729          else
730             ShowUserJobs(obj, getenv("LOGNAME"), true);
731        }
732       window->WorkingCursor(false);
733       UpdateStatusLine();
734       if (app_mode == PRINT_MANAGER)
735         {
736          if (window->findD && window->findD->Visible())
737             window->findD->UpdatePositions(printer_icon);
738         }
739
740       delete [] message;
741     }
742    else if (app_mode != SINGLE_PRINTER)
743     {
744       if (rc)
745          rc->DeleteChildren();
746       queue->DeleteChildren();
747       if (rc)
748          rc->Visible(false);
749     }
750    printer_icon->UpdateExpand();
751 }
752
753 void DtApp::ActionCB(void *data, BaseUI *obj, char *actionReferenceName)
754 {
755    DtMainW *window = (DtMainW *) data;
756    ((DtApp *)window->Parent())->ActionCB(obj, actionReferenceName);
757 }
758
759 void DtApp::ActionCB(BaseUI *obj, char *actionReferenceName)
760 {
761    if (!strcmp(actionReferenceName, EXIT))
762     {
763       exit(0);
764     }
765    else if (!strcmp(actionReferenceName, FIND))
766     {
767       FindCB(window);
768     }
769    else if (!strcmp(actionReferenceName, HELP))
770     {
771       if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST ||
772           obj->UIClass() == CONTAINER)
773          window->DisplayHelp((char *)PRINTER_ID);
774       else
775          window->DisplayHelp((char *)PRINTJOB_ID);
776     }
777    else if (!strcmp(actionReferenceName, PROPERTY))
778     {
779       if (app_mode == CONFIG_PRINTERS ||
780           obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
781        {
782          ((DtPrinterIcon *)obj)->DisplayProps();
783        }
784       else if (obj->UIClass() == CONTAINER)
785          ((DtPrinterIcon *)obj->Parent())->DisplayProps();
786       else
787          ((DtPrtJobIcon *)obj)->DisplayProps();
788     }
789    else if (!strcmp(actionReferenceName, OPEN))
790     {
791        if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
792         {
793           if (obj->Open() == false)
794              obj->Open(true);
795         }
796        else
797         {
798           if (obj->Parent()->Open() == false)
799              obj->Parent()->Open(true);
800         }
801     }
802    else if (!strcmp(actionReferenceName, CLOSE))
803     {
804       if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
805          obj->Open(false);
806       else
807          obj->Parent()->Open(false);
808     }
809    else if (!strcmp(actionReferenceName, RENAME))
810     {
811       Dialog *info = new Dialog(window, "Print Manager - Rename", 
812          "NOT IMPLEMENTED", INFORMATION);
813       info->Visible(true);
814     }
815    else if (!strcmp(actionReferenceName, HIDE))
816     {
817       if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
818          obj->Visible(false);
819       else
820          obj->Parent()->Visible(false);
821       if (window->setModList && window->setModList->Visible())
822          window->setModList->Reset();
823       UpdateStatusLine();
824     }
825    else
826     {
827       BaseObj *object;
828       if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
829          object = ((DtPrinterIcon *)obj)->QueueObj();
830       else
831          object = (BaseObj *)obj->ApplicationData;
832       int save_id = obj->UniqueID();
833       if (!strcmp(actionReferenceName, CANCEL_PRINT_JOB))
834        {
835          char *title = new char[100];
836          sprintf(title, MESSAGE(CancelTitleL), window->Name(), obj->Name());
837          char *message = new char[100];
838          sprintf(message, MESSAGE(CancelQuestionL), obj->Name());
839          Dialog *confirm = new Dialog(window, title, message, QUESTION, 
840                                       MESSAGE(YesL), MESSAGE(NoL));
841          confirm->Visible(true);
842          boolean answer = confirm->Answer();
843          delete confirm;
844          delete title;
845          delete [] message;
846          if (answer == false)
847             return;
848        }
849       if (window->container->ObjectExists(save_id) == false)
850        {
851          Dialog *dialog = new Dialog(window, (char *)window->Name(),
852                                      MESSAGE(NotFoundMessageL), INFORMATION,
853                                      MESSAGE(OKL));
854          dialog->Visible(true);
855          return;
856        }
857       // get object again, just in case a update occurred
858       object = (BaseObj *)obj->ApplicationData;
859       (void) object->SendAction(actionReferenceName);
860       if (!strcmp(actionReferenceName, CANCEL_PRINT_JOB))
861        {
862          PrintJob *me = (PrintJob *) object;
863
864          //  If there was a problem getting the job # from the prt server,
865          //  (if so, _jobNumber will be set to "not Available") put up an 
866          //  error dialog
867
868          if (!(strcmp(me->JobNumber(), MESSAGE(NotAvailableL))))
869          {
870             Action *action;
871             (void) object->HasAction(actionReferenceName, &action);
872             char *title = new char [strlen(MESSAGE(FailedActionTitleL)) +
873                                     strlen(window->Name()) +
874                                     strlen(action->DisplayName) + 1];
875
876             sprintf(title, MESSAGE(FailedActionTitleL), window->Name(),
877                     action->DisplayName);
878
879             char *message = new char [strlen(MESSAGE(FailedMessageL))  +
880                                       strlen(action->DisplayName)      + 
881                                       strlen(object->DisplayName())    + 
882                                       strlen(MESSAGE(NoRemoteCancelL)) + 1];
883
884             sprintf(message, MESSAGE(FailedMessageL),
885                              action->DisplayName, object->DisplayName(), 
886                              MESSAGE(NoRemoteCancelL));
887
888             Dialog *dialog = new Dialog(window, title, message, ERROR,
889                                      MESSAGE(OKL));
890             dialog->Visible(true);
891             delete [] title;
892             delete [] message;
893
894             return;
895          }
896
897          BaseUI *parent = obj->Parent();
898          // If command was successful, remove icon
899          if (object->LastActionStatus() == 0)
900           {
901             delete obj;
902             if (parent->NumChildren() == 0)
903                new LabelObj((AnyUI *)parent, MESSAGE(EmptyL));
904             else
905              {
906                int i;
907                IconObj **children = (IconObj **)parent->Children();
908                for (i = 0; i < parent->NumChildren(); i++)
909                 {
910                   char number[5];
911                   sprintf(number, "%d", i + 1);
912                   children[i]->TopString(number);
913                 }
914              }
915             if (app_mode == PRINT_MANAGER)
916               {
917                if (window->findD && window->findD->Visible())
918                   window->findD->UpdatePositions(parent->Parent());
919               }
920           }
921        }
922       else // This is a queue action, so update status flag
923        {
924          ((DtPrinterIcon *)obj)->Update();
925          if (app_mode == SINGLE_PRINTER)
926             UpdateStatusLine();
927        }
928
929       if (object->LastActionStatus() != 0)
930        {
931          Action *action;
932          (void) object->HasAction(actionReferenceName, &action);
933          char *title = new char [strlen(MESSAGE(FailedActionTitleL)) +
934                                  strlen(window->Name()) +
935                                  strlen(action->DisplayName) + 1];
936          sprintf(title, MESSAGE(FailedActionTitleL), window->Name(),
937                  action->DisplayName);
938          char *message = new char [strlen(object->LastActionOutput()) + 
939                                    strlen(action->DisplayName) + 
940                                    strlen(object->DisplayName()) + 70];
941          sprintf(message, MESSAGE(FailedMessageL),
942                  action->DisplayName, object->DisplayName(), 
943                  object->LastActionOutput());
944
945          Dialog *dialog = new Dialog(window, title, message, ERROR,
946                                      MESSAGE(OKL));
947          dialog->Visible(true);
948          delete []title;
949          delete []message;
950        }
951     }
952 }
953
954 void DtApp::UpdatePrintJobs(BaseUI *obj, // the print list box
955                             void *data)
956 {
957    DtMainW *window = (DtMainW *) data;
958    if (((DtApp *)window->Parent())->save_state)
959       return;
960
961    int Frequency = (int)((DtApp *)window->Parent())->Frequency;
962    // if we are doing a Find operation or have been filtered, return
963    if (window->in_find || obj->Parent()->Visible() == false)
964     {
965       obj->AddTimeOut(UpdatePrintJobs, data, Frequency);
966       return;
967     }
968
969    DtPrinterIcon *icon = (DtPrinterIcon *)obj->Parent();
970    Application *app = (Application *) window->Parent();
971    // Check app's visibility to see if we are iconified or in a different
972    // workspace, also check the icon's visibility to see if it's visible
973    // in the scrolled window.
974    if (app->IsVisible() == false || icon->IsVisible() == false)
975     {
976       obj->AddTimeOut(UpdatePrintJobs, data, Frequency);
977       return;
978     }
979
980    // Queue Icon (parent) is visible, so update it
981    icon->Update();
982
983    if (obj->Visible() == false)
984     {
985       // The jobs list box is not visible, so add a timeout and return
986       obj->AddTimeOut(UpdatePrintJobs, window, Frequency);
987       return;
988     }
989
990    if (obj->Parent()->Open() == true)
991     {
992       if (icon->updating == false)
993          OpenClose(window, obj->Parent());
994     }
995    obj->AddTimeOut(UpdatePrintJobs, window, Frequency);
996 }
997
998 char *DtApp::GetBottomString(BaseObj *job, boolean need_details)
999 {
1000    static char string[200];
1001    if (window->setPrefD->ShowOnlyMyJobs())
1002     {
1003       if (need_details)
1004          sprintf(string, "%s\n%s\n%s\n%s",
1005                  job->AttributeValue((char *)JOB_SIZE),
1006                  job->AttributeValue((char *)JOB_NUMBER),
1007                  job->AttributeValue((char *)TIME_SUBMITTED),
1008                  job->AttributeValue((char *)DATE_SUBMITTED));
1009       else
1010          return NULL;
1011     }
1012    else
1013     {
1014       if (need_details)
1015          sprintf(string, "%s\n%s\n%s\n%s\n%s",
1016                  job->AttributeValue((char *)OWNER),
1017                  job->AttributeValue((char *)JOB_SIZE),
1018                  job->AttributeValue((char *)JOB_NUMBER),
1019                  job->AttributeValue((char *)TIME_SUBMITTED),
1020                  job->AttributeValue((char *)DATE_SUBMITTED));
1021       else
1022          strcpy(string, job->AttributeValue((char *)OWNER));
1023     }
1024    return string;
1025 }
1026
1027 void DtApp::HandleShowDetailsLabelPreferenceRequest(IconStyle style)
1028 {
1029    int i;
1030    DtPrinterIcon **queues = (DtPrinterIcon **)window->container->Children();
1031    for (i = 0; i < window->container->NumChildren(); i++)
1032       queues[i]->ShowDetailsLabel(style, queues[i]->Visible());
1033 }
1034
1035 void DtApp::HandleDetailsPreferenceRequest(boolean details_on)
1036 {
1037    int i;
1038    BaseUI **queues = window->container->Children();
1039    for (i = 0; i < window->container->NumChildren(); i++)
1040     {
1041       BaseUI *jobs_container = (BaseUI *)queues[i]->ApplicationData;
1042       if (!jobs_container)
1043          continue;
1044
1045       IconObj **jobs = (IconObj **)jobs_container->Children();
1046       int j;
1047       for (j = 0; j < jobs_container->NumChildren(); j++)
1048          if (jobs[j]->UIClass() == ICON)
1049           {
1050             BaseObj *job = (BaseObj *)jobs[j]->ApplicationData;
1051             char *bottomString = GetBottomString(job, details_on);
1052             jobs[j]->BottomString(bottomString);
1053           }
1054     }
1055 }
1056
1057 boolean DtApp::ShowUserJob(DtPrtJobIcon *_job, char *user_name)
1058 {
1059    BaseObj *job = _job->PrintJobObj();
1060    char *owner = job->AttributeValue((char *)OWNER);
1061    char *s = strchr(owner, '@');
1062    boolean show_it;
1063    if (s && s != owner)
1064       show_it = !strncmp(user_name, owner, (int)(s - owner)) ? true : false;
1065    else
1066       show_it = !strcmp(user_name, owner) ? true : false;
1067    return show_it;
1068 }
1069
1070 void DtApp::ShowUserJobs(BaseUI *queue, char *user_name, boolean flag)
1071 {
1072    BaseUI *jobs_container = (BaseUI *)queue->ApplicationData;
1073    if (!jobs_container)
1074       return;
1075
1076    DtPrtJobIcon **jobs = (DtPrtJobIcon **)jobs_container->Children();
1077    int j;
1078    jobs_container->BeginUpdate();
1079    for (j = 0; j < jobs_container->NumChildren(); j++)
1080       if (jobs[j]->UIClass() == ICON)
1081        {
1082          if (flag == true)
1083             jobs[j]->Visible(ShowUserJob(jobs[j], user_name));
1084          else
1085             jobs[j]->Visible(true);
1086        }
1087    ((DtPrinterIcon *)queue)->ShowDetailsLabel(queue->IconView(),
1088                                               queue->Visible());
1089    jobs_container->EndUpdate();
1090 }
1091
1092 void DtApp::HandleShowOnlyMinePreferenceRequest(boolean flag)
1093 {
1094    int i;
1095    char *user_name;
1096    BaseUI **queues = window->container->Children();
1097    if (getuid() == 0) // check to see if we are root
1098       user_name = "root";
1099    else
1100       user_name = getenv("LOGNAME");
1101    boolean details_on = window->container->IconView() == DETAILS ? true : false;
1102    for (i = 0; i < window->container->NumChildren(); i++)
1103       ShowUserJobs(queues[i], user_name, flag);
1104    HandleDetailsPreferenceRequest(details_on);
1105 }
1106
1107 void DtApp::PreferenceCB(void *data, PreferenceRequest req, char *value)
1108 {
1109    DtMainW *window = (DtMainW *)data;
1110    ((DtApp *)window->Parent())->PreferenceCB(req, value);
1111 }
1112
1113 void DtApp::PreferenceCB(PreferenceRequest req, char *value)
1114 {
1115    switch (req)
1116    {
1117    case DETAILS_ON:
1118       HandleDetailsPreferenceRequest(true);
1119       break;
1120    case DETAILS_OFF:
1121       HandleDetailsPreferenceRequest(false);
1122       break;
1123    case STATUS_LINE_ON:
1124       window->container->AttachBottom(window->status_line);
1125       break;
1126    case STATUS_LINE_OFF:
1127       window->container->AttachBottom();
1128       break;
1129    case STATUS_FLAG_ON:
1130    case STATUS_FLAG_OFF:
1131       {
1132          int i;
1133          DtPrinterIcon **queues;
1134          queues = (DtPrinterIcon **) window->container->Children();
1135          for (i = 0; i < window->container->NumChildren(); i++)
1136             queues[i]->Update();
1137       }
1138       break;
1139    case SHOW_ONLY_MINE_ON:
1140    case SHOW_ONLY_MINE_OFF:
1141       HandleShowOnlyMinePreferenceRequest(window->setPrefD->ShowOnlyMyJobs());
1142       UpdateStatusLine();
1143       break;
1144    case SHOW_DETAILS_LABEL_ON:
1145    case SHOW_DETAILS_LABEL_OFF:
1146       HandleShowDetailsLabelPreferenceRequest(DETAILS);
1147       break;
1148    case UPDATE_INTERVAL_CHANGED:
1149       Frequency = (long) value * 1000;
1150       break;
1151    }
1152 }
1153
1154 void DtApp::FilterCB(void *data)
1155 {
1156    static DtMainW *window = NULL;
1157
1158    if (!window)
1159     {
1160       window = (DtMainW *)data;
1161       while (window->UIClass() != MAIN_WINDOW)
1162          window = (DtMainW *)window->Parent();
1163     }
1164    ((DtApp *)window->Parent())->FilterCB((BaseUI *)data);
1165 }
1166
1167 void DtApp::FilterCB(BaseUI *container)
1168 {
1169    BaseUI **queue_list = container->Children();
1170
1171    int i;
1172    BaseUI **queues = window->container->Children();
1173    window->WorkingCursor(true);
1174    window->container->BeginUpdate();
1175    window->Refresh();
1176    for (i = 0; i < container->NumChildren(); i++)
1177       queues[i]->Visible(queue_list[i]->Selected());
1178    UpdateStatusLine();
1179    window->container->EndUpdate();
1180    window->WorkingCursor(false);
1181 }
1182
1183 void DtApp::ModifyCB(void *data)
1184 {
1185    DtMainW *window = (DtMainW *) data;
1186    if (!window->setModList)
1187     {
1188       TITLE(MESSAGE(ModifyShowTitleL), window->Name());
1189       window->setModList = new DtSetModList(window, title, 
1190                                             window->container, FilterCB);
1191     }
1192    window->setModList->Visible(true);
1193 }
1194
1195 boolean DtApp::SelectPrintJobs(BaseUI *obj)
1196 {
1197    if (obj->Parent()->UIClass() == CONTAINER &&
1198        obj->Parent()->UISubClass() == SCROLLED_HORIZONTAL_ROW_COLUMN)
1199     {
1200       if (obj->UIClass() == LABEL)
1201          return false;
1202       else
1203        {
1204          static DtMainW *window = NULL;
1205          if (!window)
1206           {
1207             window = (DtMainW *)obj;
1208             while (window->UIClass() != MAIN_WINDOW)
1209                window = (DtMainW *)window->Parent();
1210           }
1211          DtApp *app = (DtApp *)window->Parent();
1212          if (getuid() == 0) // check to see if we are root
1213           {
1214             if (window->setPrefD->ShowOnlyMyJobs())
1215                return app->ShowUserJob((DtPrtJobIcon *)obj, "root");
1216             else if (window->findD->MatchAnyUser())
1217                return true;
1218             else
1219                return app->ShowUserJob((DtPrtJobIcon *)obj, "root");
1220           }
1221          else
1222             return app->ShowUserJob((DtPrtJobIcon *)obj, getenv("LOGNAME"));
1223        }
1224     }
1225    else
1226       return false;
1227 }
1228
1229 void DtApp::FindCB(void *data)
1230 {
1231    DtMainW *window = (DtMainW *) data;
1232    if (!window->findD)
1233     {
1234       TITLE(MESSAGE(FindTitleL), window->Name());
1235       window->findD = new DtFindD(window, title, SelectPrintJobs);
1236     }
1237    window->findD->Visible(true);
1238 }
1239
1240 void DtApp::RestoreApp()
1241 {
1242    char *value = Restore("Representation");
1243    if (!STRCMP(value, "Details"))
1244       window->setPrefD->Representation(DETAILS);
1245    else if (!STRCMP(value, "NameOnly"))
1246       window->setPrefD->Representation(NAME_ONLY);
1247    else if (!STRCMP(value, "SmallIcon"))
1248       window->setPrefD->Representation(SMALL_ICON);
1249    else
1250       window->setPrefD->Representation(LARGE_ICON);
1251
1252    value = Restore("ShowProblemFlag");
1253    boolean flag = !STRCMP(value, "0") ? false : true;
1254    window->setPrefD->ShowStatusFlags(flag);
1255
1256    value = Restore("ShowMessageLine");
1257    flag = !STRCMP(value, "0") ? false : true;
1258    window->setPrefD->ShowStatusLine(flag);
1259
1260    value = Restore("ShowOnlyMine");
1261    flag = !STRCMP(value, "1") ? true : false;
1262    window->setPrefD->ShowOnlyMyJobs(flag);
1263
1264    value = Restore("ShowDetailsLabel");
1265    flag = !STRCMP(value, "0") ? false : true;
1266    window->setPrefD->ShowDetailsLabel(flag);
1267    window->setPrefD->Apply();
1268
1269    int interval = 30;
1270    if (value = Restore("UpdateInterval"))
1271     {
1272       interval = atoi(value);
1273       if (interval < 5 || interval > 300)
1274          interval = 30;
1275     }
1276    window->setPrefD->UpdateInterval(interval);
1277
1278    window->setPrefD->Apply();
1279
1280    if (app_mode == PRINT_MANAGER)
1281     {
1282       int i;
1283       DtPrinterIcon **queues;
1284       char *attribute = new char[100];
1285       queues = (DtPrinterIcon **) window->container->Children();
1286       for (i = 0; i < window->container->NumChildren(); i++)
1287        {
1288          sprintf(attribute, "%s.Visible", queues[i]->QueueObj()->Name());
1289          value = Restore(attribute);
1290          if (!STRCMP(value, "0"))
1291             queues[i]->Visible(false);
1292          else
1293           {
1294             sprintf(attribute, "%s.Open", queues[i]->QueueObj()->Name());
1295             value = Restore(attribute);
1296             if (!STRCMP(value, "1"))
1297                queues[i]->Open(true);
1298           }
1299        }
1300       UpdateStatusLine();
1301       delete attribute;
1302     }
1303    else
1304     {
1305       single_printer->Open(true);
1306     }
1307 }
1308
1309 void DtApp::UpdateQueues()
1310 {
1311    window->PointerShape(HOUR_GLASS_CURSOR);
1312    window->container->BeginUpdate();
1313    window->status_line->Name(MESSAGE(SearchingL));
1314    window->Refresh();
1315
1316    PrintSubSystem *prt;
1317    if (window->ApplicationData)
1318     {
1319       prt = (PrintSubSystem *) window->ApplicationData;
1320       prt->DeleteChildren();
1321       window->container->DeleteChildren();
1322     }
1323    else
1324     {
1325       // Connect to Print SubSystem
1326       prt = new PrintSubSystem(NULL);
1327       window->ApplicationData = prt;
1328     }
1329    int n_queues = prt->NumChildren();
1330    if (n_queues == 0)
1331     {
1332       window->container->EndUpdate();
1333       window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
1334       UpdateStatusLine();
1335       Dialog *dialog = new Dialog(window, (char *)Name(),
1336                                   MESSAGE(FoundNoPrintersL),
1337                                   INFORMATION, MESSAGE(OKL));
1338       dialog->Visible(true);
1339       return;
1340     }
1341
1342    // Get Print Subsystem children, (these are queues)
1343    Queue **queues = (Queue **)prt->Children();
1344
1345    BaseUI *lpdest = NULL;
1346    char *LPDEST = getenv("LPDEST");
1347    if (app_mode == SINGLE_PRINTER)
1348     {
1349       int found = -1, j;
1350       // First check printer on command line
1351       if (argc >= 3)
1352        {
1353          for (j = 0; j < n_queues; j++)
1354             if (!STRCMP(argv[2], queues[j]->Name()))
1355              {
1356                found = j;
1357                break;
1358              }
1359        }
1360       // Next check LPDEST printer
1361       if (found == -1 && LPDEST && *LPDEST)
1362        {
1363          for (j = 0; j < n_queues; j++)
1364             if (!STRCMP(LPDEST, queues[j]->Name()))
1365              {
1366                found = j;
1367                break;
1368              }
1369        }
1370       // If a printer is still not found, use system default
1371       if (found == -1)
1372        {
1373 #ifdef aix
1374          char *cmd = "lsallq | grep -v ^bsh\\$ | head -1";
1375 #else
1376 #ifdef __osf__
1377          /* resolve possible alias using lpstat -v<name> */
1378          char *cmd = "env LANG=C lpstat -v"
1379              "`env LANG=C lpstat -d | awk '$1 != \"no\" {print $NF}'`"
1380              "| awk '{ print $10 }'";
1381 #else
1382          char *cmd = "env LANG=C lpstat -d | awk '$1 != \"no\" {print $NF}'";
1383 #endif
1384 #endif
1385          char *output;
1386          Invoke *_thread = new Invoke(cmd, &output);
1387          strtok(output, "\n");
1388          for (j = 0; j < n_queues; j++)
1389             if (!STRCMP(output, queues[j]->Name()))
1390              {
1391                found = j;
1392                break;
1393              }
1394          delete _thread;
1395          delete output;
1396        }
1397       if (found == -1)
1398        {
1399          window->container->EndUpdate();
1400          window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
1401          UpdateStatusLine();
1402          char *tmp = new char [strlen(MESSAGE(NoDefaultPrinter1L)) +
1403                                strlen(MESSAGE(NoDefaultPrinter2L)) + 5];
1404          sprintf(tmp, "%s\n\n%s", MESSAGE(NoDefaultPrinter1L),
1405                  MESSAGE(NoDefaultPrinter2L));
1406          Dialog *dialog = new Dialog(window, (char *)Name(), tmp, INFORMATION,
1407                                      MESSAGE(OKL));
1408          dialog->Visible(true);
1409          delete prt;
1410          delete [] tmp;
1411          window->ApplicationData = NULL;
1412          return;
1413        }
1414       single_printer = new DtPrinterIcon(window, window->container,
1415                                          queues[found], app_mode);
1416       single_printer->updating = false;
1417     }
1418    else
1419     {
1420       int i;
1421       for (i = 0; i < n_queues; i++)
1422        {
1423          // Create Icon
1424          DtPrinterIcon *icon = new DtPrinterIcon(window, window->container,
1425                                                  queues[i], app_mode);
1426          icon->updating = false;
1427        }
1428     }
1429    boolean call_reload_actions = false;
1430    DtPrinterIcon **printers = (DtPrinterIcon **)window->container->Children();
1431    int i;
1432    for (i = 0; i < window->container->NumChildren(); i++)
1433     {
1434       if (printers[i]->PrintActionExists() == false)
1435        {
1436          printers[i]->CreateActionFile();
1437          call_reload_actions = true;
1438        }
1439     }
1440    if (call_reload_actions)
1441     {
1442       window->status_line->Name(MESSAGE(UpdatingActionsL));
1443       window->Refresh();
1444       system("/usr/dt/bin/dtaction ReloadActions&");
1445     }
1446    UpdateStatusLine();
1447    window->container->EndUpdate();
1448    window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
1449    if (app_mode != CONFIG_PRINTERS)
1450     {
1451       AddTimeOut(RestoreAppCB, this, 0);
1452       printers[0]->AddTimeOut(InitQueueDetails, window, 3000);
1453     }
1454 }
1455
1456 void DtApp::RestoreAppCB(BaseUI *obj, void *)
1457 {
1458    ((DtApp *)obj)->RestoreApp();
1459 }
1460
1461 void DtApp::AddQueues(BaseUI *obj, void *)
1462 {
1463    ((DtApp *)obj)->UpdateQueues();
1464 }
1465
1466 void DtApp::AddActions(BaseObj *dummy)
1467 {
1468    int i;
1469
1470    Action **actions = dummy->Actions();
1471    int n_actions = dummy->NumActions();
1472    for (i = 0; i < n_actions; i++)
1473       window->DtAddAction(actions[i]->DisplayName,
1474                           (char *)dummy->ObjectClassName(),
1475                           actions[i]->ReferenceName, ActionCB, window,
1476                           actions[i]->Nmemonic, actions[i]->AcceleratorText,
1477                           actions[i]->Accelerator);
1478    delete dummy;
1479 }