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