1 /* $TOG: DtApp.C /main/12 1998/08/25 12:58:57 mgreess $ */
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. *
9 // User Interface headers
12 #include "DtSetModList.h"
14 #include "DtWorkArea.h"
15 #include "DtPrtJobIcon.h"
16 #include "DtPrinterIcon.h"
17 #include "DtPrtProps.h"
18 #include "Application.h"
24 #include "PrintSubSys.h"
25 #include "ParseJobs.h"
27 // Command Execution header
32 #include "dtprintinfomsg.h"
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
41 extern "C" { extern int seteuid(uid_t); }
45 #define TITLE(message, app_name) \
47 sprintf(title, message, app_name)
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";
59 DtApp::DtApp(char *progname, int *argc, char **argv) :
60 Application(progname, "Dtprintinfo", argc, argv)
64 old_dbsearchpath = NULL;
66 single_printer = NULL;
67 app_mode = SINGLE_PRINTER;
68 char *app_name = MESSAGE(ApplicationName2L);
69 if (!((lang = getenv("LANG")) && *lang))
71 home = getenv("HOME");
72 if (!home || *home == '\0')
74 struct passwd *pwInfo = getpwuid(getuid());
75 home = strdup(pwInfo->pw_dir);
79 printer_dir = new char[strlen(home) + strlen(PRINTERS_DIR) + 2];
80 sprintf(printer_dir, "%s/%s", home, PRINTERS_DIR);
82 for (i = 0; i < *argc; i++)
84 if (!strcmp(argv[i], "-edit"))
86 app_name = MESSAGE(ApplicationName3L);
87 app_mode = CONFIG_PRINTERS;
90 else if (!strcmp(argv[i], "-all"))
92 app_name = MESSAGE(ApplicationName1L);
93 app_mode = PRINT_MANAGER;
98 Process *procs = new Process();
99 pid_t pid = getppid();
100 char *c = procs->Command(pid);
102 if (NULL != c && 0 == strncmp(c, "dtexec", 6))
104 if (app_mode == CONFIG_PRINTERS)
106 pid = procs->Parent(pid);
107 c = procs->Command(pid);
108 old_uid = procs->UID(pid);
109 if (!strncmp(c, "dtaction", 8))
111 pid = procs->Parent(pid);
112 c = procs->Command(pid);
113 old_uid = procs->UID(pid);
114 if (!strncmp(c, "dtexec", 6))
116 pid = procs->Parent(pid);
117 c = procs->Command(pid);
118 old_uid = procs->UID(pid);
124 // This is a workaround to avoid a bug in dtsession or dtaction.
125 // We should be fixing the problem there.
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.
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);
146 if (app_mode == CONFIG_PRINTERS)
150 fprintf(stderr, MESSAGE(RootUserL), progname, "-edit");
151 fprintf(stderr, "\n");
154 char *lang = getenv("LANG");
155 char *DBSearchPath = getenv("DTDATABASESEARCHPATH");
156 old_dbsearchpath = STRDUP(DBSearchPath);
158 if (!(lang && *lang))
160 if (DBSearchPath && *DBSearchPath)
162 buf = new char[strlen(DBSearchPath) + strlen(lang) + 50];
163 sprintf(buf, "DTDATABASESEARCHPATH=/etc/dt/appconfig/types/%s,%s",
168 buf = new char[strlen(DBSearchPath) + strlen(lang) + 50];
169 sprintf(buf, "DTDATABASESEARCHPATH=/etc/dt/appconfig/types/%s", lang);
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),
184 window = new DtMainW("Printers", this, app_name, SCROLLED_ICON_LIST,
185 SINGLE_SELECT, OpenClose, NULL, PreferenceCB, NULL,
186 MESSAGE(PrinterMenuL), MESSAGE(PrinterAcceleratorL),
188 window->Initialize();
189 window->ApplicationData = NULL;
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);
200 // Save print job's class name for registering GUI actions
201 PrintJob *dummy_printjob;
203 if (app_mode != CONFIG_PRINTERS)
205 dummy_printjob = new PrintJob(NULL, "_FOO", NULL, NULL, NULL, NULL, NULL);
206 className = (char *) dummy_printjob->ObjectClassName();
208 // Add Print Job Actions
209 AddActions(dummy_printjob);
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();
216 // Add GUI actions for queue
217 if (app_mode == PRINT_MANAGER)
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));
225 if (getuid() == 0 && dummy_queue->NumActions())
227 window->DtAddSep(className1);
228 AddActions(dummy_queue);
233 // Add GUI actions for queue
234 if (app_mode != CONFIG_PRINTERS)
236 if (app_mode == PRINT_MANAGER)
238 window->DtAddSep(className1);
239 window->DtAddAction(MESSAGE(HideChoiceL), className1, (char *)HIDE,
240 ActionCB, window, MESSAGE(HideMnemonicL));
242 //window->DtAddAction(MESSAGE(RenameChoiceL), className1, (char *)RENAME,
243 //ActionCB, window, MESSAGE(RenameMnemonicL));
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");
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)
261 window->DtAddSep(className1);
262 window->DtAddAction(MESSAGE(HelpChoiceL), className1, (char *)HELP,
263 ActionCB, window, MESSAGE(HelpMnemonicL), "F1");
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");
275 if (app_mode == PRINT_MANAGER)
277 Button *find = new Button(window->fileMenu, MESSAGE(FindChoiceL),
278 PUSH_BUTTON, FindCB, window,
279 MESSAGE(FindMnemonicL),
280 MESSAGE(FindAcceleratorL),
281 MESSAGE(FindAcceleratorKeySeq));
283 Button *filter = new Button(window->viewMenu, MESSAGE(ModifyShowChoiceL),
284 PUSH_BUTTON, ModifyCB, window,
285 MESSAGE(ModifyShowMnemonicL));
287 // Add a time out to add queues, this way the UI is visible within secs
288 ApplicationData = window;
289 AddTimeOut(AddQueues, this, 0);
295 delete [] printer_dir;
298 void DtApp::SaveYourSelf()
300 if (app_mode == CONFIG_PRINTERS)
305 char *value = window->setPrefD->ShowOnlyMyJobs() ? "1" : "0";
306 Save("ShowOnlyMine", value);
308 value = window->setPrefD->ShowStatusLine() ? "1" : "0";
309 Save("ShowMessageLine", value);
311 value = window->setPrefD->ShowDetailsLabel() ? "1" : "0";
312 Save("ShowDetailsLabel", value);
314 value = window->setPrefD->ShowStatusFlags() ? "1" : "0";
315 Save("ShowProblemFlag", value);
318 sprintf(interval, "%d", window->setPrefD->UpdateInterval());
319 Save("UpdateInterval", interval);
321 switch (window->container->IconView())
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;
328 Save("Representation", value);
330 if (app_mode == PRINT_MANAGER)
333 DtPrinterIcon **queues;
334 char *attribute = (char*) malloc(100);
335 queues = (DtPrinterIcon **) window->container->Children();
336 for (i = 0; i < window->container->NumChildren(); i++)
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);
349 char *DtApp::SessionFile()
351 if (app_mode == SINGLE_PRINTER)
354 return (char *)single_printer->QueueObj()->Name();
358 else if (app_mode == PRINT_MANAGER)
364 void DtApp::UpdateStatusLine()
369 message = (char*) malloc(200);
370 msg2 = (char*) malloc(100);
372 if (app_mode == CONFIG_PRINTERS)
374 sprintf(message, MESSAGE(EditLangL), lang);
375 window->status_line->Name(message);
377 else if (app_mode == SINGLE_PRINTER)
381 char *details = MESSAGE(UpL);
383 if (single_printer->PrintQueueUp() == false)
384 details = MESSAGE(DownL);
388 Queue *queue = single_printer->QueueObj();
390 for (i = 0; i < queue->NumberDevices(); i++)
391 if (single_printer->PrintDeviceUp(i) == false)
393 details = MESSAGE(DownL);
398 if (single_printer->PrintDeviceUp() == false)
399 details = MESSAGE(DownL);
401 Container *rc = single_printer->JobContainer();
402 if (window->setPrefD->ShowOnlyMyJobs() && rc)
404 if (rc->FindByName(MESSAGE(EmptyL)))
405 window->status_line->Name(details);
408 sprintf(msg2, MESSAGE(JobsL), rc->NumChildren());
409 sprintf(message, "%s %s", details, msg2);
410 window->status_line->Name(message);
414 window->status_line->Name(details);
417 window->status_line->Name(MESSAGE(NoDefaultPrinter1L));
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)
426 sprintf(msg2, MESSAGE(PrintersHiddenL),
427 window->container->NumChildren(), n_visible);
428 if (window->setPrefD->ShowOnlyMyJobs())
430 sprintf(message, "%s %s", msg2, MESSAGE(ShowingMyJobsL));
431 window->status_line->Name(message);
434 window->status_line->Name(msg2);
441 void DtApp::InitQueueDetails(BaseUI *obj, void *data)
443 ((DtPrinterIcon *)obj)->Update();
444 DtApp *app = (DtApp *)data;
445 app = (DtApp *)app->Parent();
450 int n_siblings = obj->NumSiblings();
451 int i = obj->Order() + 1;
454 BaseUI **siblings = obj->Siblings();
455 siblings[i]->AddTimeOut(InitQueueDetails, data, 3000);
457 if (app->app_mode == SINGLE_PRINTER)
458 app->UpdateStatusLine();
461 void DtApp::RemoteStatusCB(BaseUI *obj, char *output, int)
463 DtPrinterIcon *printer_icon = (DtPrinterIcon *)obj->Parent();
464 Queue *queue = printer_icon->QueueObj();
465 queue->ParseRemoteStatus(output);
466 printer_icon->PrintDeviceUp(queue->RemoteUp());
468 printer_icon->Open(true);
471 void DtApp::TurnOffHourGlass(BaseUI *obj, void *)
473 DtMainW *window = (DtMainW *) obj;
474 window->WorkingCursor(false);
477 void DtApp::ShowStatusDialog(DtPrinterIcon *printer_icon)
479 Queue *queue = printer_icon->QueueObj();
480 Attribute **attributes = queue->Attributes();
484 if (printer_icon->PrintQueueUp() == false)
485 len = strlen(MESSAGE(PrinterDownL)) + strlen(queue->Name());
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;
493 if (printer_icon->PrintDeviceUp() == false)
494 len += strlen(MESSAGE(DeviceDownL)) + strlen(attributes[1]->DisplayValue);
496 message = new char[len + 2];
498 if (printer_icon->PrintQueueUp() == false)
500 sprintf(message, MESSAGE(PrinterDownL), queue->Name());
501 strcat(message, "\n");
504 for (i = 0; i < queue->NumberDevices(); i++)
505 if (printer_icon->PrintDeviceUp(i) == false)
507 len = strlen(message);
508 sprintf(message + len, MESSAGE(DeviceDownL),
509 attributes[1 + i]->DisplayValue);
510 strcat(message, "\n");
513 len = strlen(message);
514 if (printer_icon->PrintDeviceUp() == false)
515 sprintf(message + len, MESSAGE(DeviceDownL), attributes[1]->DisplayValue);
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,
523 dialog->Visible(true);
527 void DtApp::OpenClose(void *data, BaseUI *obj)
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)
533 DtMainW *window = (DtMainW *) data;
534 ((DtApp *)window->Parent())->OpenClose(obj);
537 void DtApp::OpenClose(BaseUI *obj)
542 DtPrinterIcon *printer_icon;
546 if (app_mode == CONFIG_PRINTERS)
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);
561 if (!STRCMP(obj->Category(), STATUS_FLAG))
563 printer_icon = (DtPrinterIcon *)obj->Parent();
564 ShowStatusDialog(printer_icon);
568 printer_icon = (DtPrinterIcon *)obj;
569 queue = printer_icon->QueueObj();
570 rc = printer_icon->JobContainer();
571 if (obj->Open() == true)
573 char *message = new char[100];
574 boolean prev_open = false;
576 sprintf(message, MESSAGE(UpdatingL), obj->Name());
579 rc = printer_icon->CreateContainer();
580 rc->AddTimeOut(UpdatePrintJobs, window, Frequency);
583 prev_open = rc->Visible();
584 if (printer_icon->Visible())
586 if (queue->IsRemote() && printer_icon->waitForChildren == false)
588 if (printer_icon->updating == false)
590 int sockfd = ConnectToPrintServer(queue->Server(), connect_timeout);
593 SendPrintJobStatusReguest(sockfd, queue->RemotePrinter());
594 printer_icon->updating = true;
595 if (prev_open == false)
598 rc->UpdateMessage(message);
601 printer_icon->UpdateExpand();
602 rc->Thread(sockfd, RemoteStatusCB, 512);
607 queue->ParseRemoteStatus("");
608 printer_icon->PrintDeviceUp(false);
611 printer_icon->updating = false;
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();
624 BaseUI *empty_label = rc->FindByName(MESSAGE(EmptyL));
629 empty_label = new LabelObj(rc, MESSAGE(EmptyL));
630 icons = (DtPrtJobIcon **)rc->Children();
635 else if (empty_label)
639 icons = (DtPrtJobIcon **)rc->Children();
643 // Change children first, then delete or create icons
647 for (i = 0; i < n_icons; i++)
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)))
657 if (found_it == false)
660 icons = (DtPrtJobIcon **)rc->Children();
665 for (i = 0; i < n_icons; i++)
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)))
676 icons[i]->PrintJobObj(jobs[j]);
679 DtPrtJobIcon *tmp = new DtPrtJobIcon(window, rc, jobs[j], i + 1);
681 icons = (DtPrtJobIcon **)rc->Children();
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++)
700 sprintf(number, "%d", i + 1);
701 icons[i]->TopString(number);
703 if (window->setPrefD->ShowOnlyMyJobs())
705 if (getuid() == 0) // check to see if we are root
706 ShowUserJobs(obj, "root", true);
708 ShowUserJobs(obj, getenv("LOGNAME"), true);
710 window->WorkingCursor(false);
712 if (app_mode == PRINT_MANAGER)
714 if (window->findD && window->findD->Visible())
715 window->findD->UpdatePositions(printer_icon);
720 else if (app_mode != SINGLE_PRINTER)
723 rc->DeleteChildren();
724 queue->DeleteChildren();
728 printer_icon->UpdateExpand();
731 void DtApp::ActionCB(void *data, BaseUI *obj, char *actionReferenceName)
733 DtMainW *window = (DtMainW *) data;
734 ((DtApp *)window->Parent())->ActionCB(obj, actionReferenceName);
737 void DtApp::ActionCB(BaseUI *obj, char *actionReferenceName)
739 if (!strcmp(actionReferenceName, EXIT))
743 else if (!strcmp(actionReferenceName, FIND))
747 else if (!strcmp(actionReferenceName, HELP))
749 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST ||
750 obj->UIClass() == CONTAINER)
751 window->DisplayHelp((char *)PRINTER_ID);
753 window->DisplayHelp((char *)PRINTJOB_ID);
755 else if (!strcmp(actionReferenceName, PROPERTY))
757 if (app_mode == CONFIG_PRINTERS ||
758 obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
760 ((DtPrinterIcon *)obj)->DisplayProps();
762 else if (obj->UIClass() == CONTAINER)
763 ((DtPrinterIcon *)obj->Parent())->DisplayProps();
765 ((DtPrtJobIcon *)obj)->DisplayProps();
767 else if (!strcmp(actionReferenceName, OPEN))
769 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
771 if (obj->Open() == false)
776 if (obj->Parent()->Open() == false)
777 obj->Parent()->Open(true);
780 else if (!strcmp(actionReferenceName, CLOSE))
782 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
785 obj->Parent()->Open(false);
787 else if (!strcmp(actionReferenceName, RENAME))
789 Dialog *info = new Dialog(window, "Print Manager - Rename",
790 "NOT IMPLEMENTED", INFORMATION);
793 else if (!strcmp(actionReferenceName, HIDE))
795 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
798 obj->Parent()->Visible(false);
799 if (window->setModList && window->setModList->Visible())
800 window->setModList->Reset();
806 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
807 object = ((DtPrinterIcon *)obj)->QueueObj();
809 object = (BaseObj *)obj->ApplicationData;
810 int save_id = obj->UniqueID();
811 if (!strcmp(actionReferenceName, CANCEL_PRINT_JOB))
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();
827 if (window->container->ObjectExists(save_id) == false)
829 Dialog *dialog = new Dialog(window, (char *)window->Name(),
830 MESSAGE(NotFoundMessageL), INFORMATION,
832 dialog->Visible(true);
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))
840 PrintJob *me = (PrintJob *) object;
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
846 if (!(strcmp(me->JobNumber(), MESSAGE(NotAvailableL))))
849 (void) object->HasAction(actionReferenceName, &action);
850 char *title = new char [strlen(MESSAGE(FailedActionTitleL)) +
851 strlen(window->Name()) +
852 strlen(action->DisplayName) + 1];
854 sprintf(title, MESSAGE(FailedActionTitleL), window->Name(),
855 action->DisplayName);
857 char *message = new char [strlen(MESSAGE(FailedMessageL)) +
858 strlen(action->DisplayName) +
859 strlen(object->DisplayName()) +
860 strlen(MESSAGE(NoRemoteCancelL)) + 1];
862 sprintf(message, MESSAGE(FailedMessageL),
863 action->DisplayName, object->DisplayName(),
864 MESSAGE(NoRemoteCancelL));
866 Dialog *dialog = new Dialog(window, title, message, ERROR,
868 dialog->Visible(true);
875 BaseUI *parent = obj->Parent();
876 // If command was successful, remove icon
877 if (object->LastActionStatus() == 0)
880 if (parent->NumChildren() == 0)
881 new LabelObj((AnyUI *)parent, MESSAGE(EmptyL));
885 IconObj **children = (IconObj **)parent->Children();
886 for (i = 0; i < parent->NumChildren(); i++)
889 sprintf(number, "%d", i + 1);
890 children[i]->TopString(number);
893 if (app_mode == PRINT_MANAGER)
895 if (window->findD && window->findD->Visible())
896 window->findD->UpdatePositions(parent->Parent());
900 else // This is a queue action, so update status flag
902 ((DtPrinterIcon *)obj)->Update();
903 if (app_mode == SINGLE_PRINTER)
907 if (object->LastActionStatus() != 0)
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());
923 Dialog *dialog = new Dialog(window, title, message, ERROR,
925 dialog->Visible(true);
932 void DtApp::UpdatePrintJobs(BaseUI *obj, // the print list box
935 DtMainW *window = (DtMainW *) data;
936 if (((DtApp *)window->Parent())->save_state)
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)
943 obj->AddTimeOut(UpdatePrintJobs, data, Frequency);
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)
954 obj->AddTimeOut(UpdatePrintJobs, data, Frequency);
958 // Queue Icon (parent) is visible, so update it
961 if (obj->Visible() == false)
963 // The jobs list box is not visible, so add a timeout and return
964 obj->AddTimeOut(UpdatePrintJobs, window, Frequency);
968 if (obj->Parent()->Open() == true)
970 if (icon->updating == false)
971 OpenClose(window, obj->Parent());
973 obj->AddTimeOut(UpdatePrintJobs, window, Frequency);
976 char *DtApp::GetBottomString(BaseObj *job, boolean need_details)
978 static char string[200];
979 if (window->setPrefD->ShowOnlyMyJobs())
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));
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));
1000 strcpy(string, job->AttributeValue((char *)OWNER));
1005 void DtApp::HandleShowDetailsLabelPreferenceRequest(IconStyle style)
1008 DtPrinterIcon **queues = (DtPrinterIcon **)window->container->Children();
1009 for (i = 0; i < window->container->NumChildren(); i++)
1010 queues[i]->ShowDetailsLabel(style, queues[i]->Visible());
1013 void DtApp::HandleDetailsPreferenceRequest(boolean details_on)
1016 BaseUI **queues = window->container->Children();
1017 for (i = 0; i < window->container->NumChildren(); i++)
1019 BaseUI *jobs_container = (BaseUI *)queues[i]->ApplicationData;
1020 if (!jobs_container)
1023 IconObj **jobs = (IconObj **)jobs_container->Children();
1025 for (j = 0; j < jobs_container->NumChildren(); j++)
1026 if (jobs[j]->UIClass() == ICON)
1028 BaseObj *job = (BaseObj *)jobs[j]->ApplicationData;
1029 char *bottomString = GetBottomString(job, details_on);
1030 jobs[j]->BottomString(bottomString);
1035 boolean DtApp::ShowUserJob(DtPrtJobIcon *_job, char *user_name)
1037 BaseObj *job = _job->PrintJobObj();
1038 char *owner = job->AttributeValue((char *)OWNER);
1039 char *s = strchr(owner, '@');
1041 if (s && s != owner)
1042 show_it = !strncmp(user_name, owner, (int)(s - owner)) ? true : false;
1044 show_it = !strcmp(user_name, owner) ? true : false;
1048 void DtApp::ShowUserJobs(BaseUI *queue, char *user_name, boolean flag)
1050 BaseUI *jobs_container = (BaseUI *)queue->ApplicationData;
1051 if (!jobs_container)
1054 DtPrtJobIcon **jobs = (DtPrtJobIcon **)jobs_container->Children();
1056 jobs_container->BeginUpdate();
1057 for (j = 0; j < jobs_container->NumChildren(); j++)
1058 if (jobs[j]->UIClass() == ICON)
1061 jobs[j]->Visible(ShowUserJob(jobs[j], user_name));
1063 jobs[j]->Visible(true);
1065 ((DtPrinterIcon *)queue)->ShowDetailsLabel(queue->IconView(),
1067 jobs_container->EndUpdate();
1070 void DtApp::HandleShowOnlyMinePreferenceRequest(boolean flag)
1074 BaseUI **queues = window->container->Children();
1075 if (getuid() == 0) // check to see if we are root
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);
1085 void DtApp::PreferenceCB(void *data, PreferenceRequest req, char *value)
1087 DtMainW *window = (DtMainW *)data;
1088 ((DtApp *)window->Parent())->PreferenceCB(req, value);
1091 void DtApp::PreferenceCB(PreferenceRequest req, char *value)
1096 HandleDetailsPreferenceRequest(true);
1099 HandleDetailsPreferenceRequest(false);
1101 case STATUS_LINE_ON:
1102 window->container->AttachBottom(window->status_line);
1104 case STATUS_LINE_OFF:
1105 window->container->AttachBottom();
1107 case STATUS_FLAG_ON:
1108 case STATUS_FLAG_OFF:
1111 DtPrinterIcon **queues;
1112 queues = (DtPrinterIcon **) window->container->Children();
1113 for (i = 0; i < window->container->NumChildren(); i++)
1114 queues[i]->Update();
1117 case SHOW_ONLY_MINE_ON:
1118 case SHOW_ONLY_MINE_OFF:
1119 HandleShowOnlyMinePreferenceRequest(window->setPrefD->ShowOnlyMyJobs());
1122 case SHOW_DETAILS_LABEL_ON:
1123 case SHOW_DETAILS_LABEL_OFF:
1124 HandleShowDetailsLabelPreferenceRequest(DETAILS);
1126 case UPDATE_INTERVAL_CHANGED:
1127 Frequency = (long) value * 1000;
1132 void DtApp::FilterCB(void *data)
1134 static DtMainW *window = NULL;
1138 window = (DtMainW *)data;
1139 while (window->UIClass() != MAIN_WINDOW)
1140 window = (DtMainW *)window->Parent();
1142 ((DtApp *)window->Parent())->FilterCB((BaseUI *)data);
1145 void DtApp::FilterCB(BaseUI *container)
1147 BaseUI **queue_list = container->Children();
1150 BaseUI **queues = window->container->Children();
1151 window->WorkingCursor(true);
1152 window->container->BeginUpdate();
1154 for (i = 0; i < container->NumChildren(); i++)
1155 queues[i]->Visible(queue_list[i]->Selected());
1157 window->container->EndUpdate();
1158 window->WorkingCursor(false);
1161 void DtApp::ModifyCB(void *data)
1163 DtMainW *window = (DtMainW *) data;
1164 if (!window->setModList)
1166 TITLE(MESSAGE(ModifyShowTitleL), window->Name());
1167 window->setModList = new DtSetModList(window, title,
1168 window->container, FilterCB);
1170 window->setModList->Visible(true);
1173 boolean DtApp::SelectPrintJobs(BaseUI *obj)
1175 if (obj->Parent()->UIClass() == CONTAINER &&
1176 obj->Parent()->UISubClass() == SCROLLED_HORIZONTAL_ROW_COLUMN)
1178 if (obj->UIClass() == LABEL)
1182 static DtMainW *window = NULL;
1185 window = (DtMainW *)obj;
1186 while (window->UIClass() != MAIN_WINDOW)
1187 window = (DtMainW *)window->Parent();
1189 DtApp *app = (DtApp *)window->Parent();
1190 if (getuid() == 0) // check to see if we are root
1192 if (window->setPrefD->ShowOnlyMyJobs())
1193 return app->ShowUserJob((DtPrtJobIcon *)obj, "root");
1194 else if (window->findD->MatchAnyUser())
1197 return app->ShowUserJob((DtPrtJobIcon *)obj, "root");
1200 return app->ShowUserJob((DtPrtJobIcon *)obj, getenv("LOGNAME"));
1207 void DtApp::FindCB(void *data)
1209 DtMainW *window = (DtMainW *) data;
1212 TITLE(MESSAGE(FindTitleL), window->Name());
1213 window->findD = new DtFindD(window, title, SelectPrintJobs);
1215 window->findD->Visible(true);
1218 void DtApp::RestoreApp()
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);
1228 window->setPrefD->Representation(LARGE_ICON);
1230 value = Restore("ShowProblemFlag");
1231 boolean flag = !STRCMP(value, "0") ? false : true;
1232 window->setPrefD->ShowStatusFlags(flag);
1234 value = Restore("ShowMessageLine");
1235 flag = !STRCMP(value, "0") ? false : true;
1236 window->setPrefD->ShowStatusLine(flag);
1238 value = Restore("ShowOnlyMine");
1239 flag = !STRCMP(value, "1") ? true : false;
1240 window->setPrefD->ShowOnlyMyJobs(flag);
1242 value = Restore("ShowDetailsLabel");
1243 flag = !STRCMP(value, "0") ? false : true;
1244 window->setPrefD->ShowDetailsLabel(flag);
1245 window->setPrefD->Apply();
1248 if (value = Restore("UpdateInterval"))
1250 interval = atoi(value);
1251 if (interval < 5 || interval > 300)
1254 window->setPrefD->UpdateInterval(interval);
1256 window->setPrefD->Apply();
1258 if (app_mode == PRINT_MANAGER)
1261 DtPrinterIcon **queues;
1262 char *attribute = new char[100];
1263 queues = (DtPrinterIcon **) window->container->Children();
1264 for (i = 0; i < window->container->NumChildren(); i++)
1266 sprintf(attribute, "%s.Visible", queues[i]->QueueObj()->Name());
1267 value = Restore(attribute);
1268 if (!STRCMP(value, "0"))
1269 queues[i]->Visible(false);
1272 sprintf(attribute, "%s.Open", queues[i]->QueueObj()->Name());
1273 value = Restore(attribute);
1274 if (!STRCMP(value, "1"))
1275 queues[i]->Open(true);
1283 single_printer->Open(true);
1287 void DtApp::UpdateQueues()
1289 window->PointerShape(HOUR_GLASS_CURSOR);
1290 window->container->BeginUpdate();
1291 window->status_line->Name(MESSAGE(SearchingL));
1294 PrintSubSystem *prt;
1295 if (window->ApplicationData)
1297 prt = (PrintSubSystem *) window->ApplicationData;
1298 prt->DeleteChildren();
1299 window->container->DeleteChildren();
1303 // Connect to Print SubSystem
1304 prt = new PrintSubSystem(NULL);
1305 window->ApplicationData = prt;
1307 int n_queues = prt->NumChildren();
1310 window->container->EndUpdate();
1311 window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
1313 Dialog *dialog = new Dialog(window, (char *)Name(),
1314 MESSAGE(FoundNoPrintersL),
1315 INFORMATION, MESSAGE(OKL));
1316 dialog->Visible(true);
1320 // Get Print Subsystem children, (these are queues)
1321 Queue **queues = (Queue **)prt->Children();
1323 BaseUI *lpdest = NULL;
1324 char *LPDEST = getenv("LPDEST");
1325 if (app_mode == SINGLE_PRINTER)
1328 // First check printer on command line
1331 for (j = 0; j < n_queues; j++)
1332 if (!STRCMP(argv[2], queues[j]->Name()))
1338 // Next check LPDEST printer
1339 if (found == -1 && LPDEST && *LPDEST)
1341 for (j = 0; j < n_queues; j++)
1342 if (!STRCMP(LPDEST, queues[j]->Name()))
1348 // If a printer is still not found, use system default
1352 char *cmd = "lsallq | grep -v ^bsh\\$ | head -1";
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 }'";
1360 char *cmd = "env LANG=C lpstat -d | awk '$1 != \"no\" {print $NF}'";
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()))
1377 window->container->EndUpdate();
1378 window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
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,
1386 dialog->Visible(true);
1389 window->ApplicationData = NULL;
1392 single_printer = new DtPrinterIcon(window, window->container,
1393 queues[found], app_mode);
1394 single_printer->updating = false;
1399 for (i = 0; i < n_queues; i++)
1402 DtPrinterIcon *icon = new DtPrinterIcon(window, window->container,
1403 queues[i], app_mode);
1404 icon->updating = false;
1407 boolean call_reload_actions = false;
1408 DtPrinterIcon **printers = (DtPrinterIcon **)window->container->Children();
1410 for (i = 0; i < window->container->NumChildren(); i++)
1412 if (printers[i]->PrintActionExists() == false)
1414 printers[i]->CreateActionFile();
1415 call_reload_actions = true;
1418 if (call_reload_actions)
1420 window->status_line->Name(MESSAGE(UpdatingActionsL));
1422 system("/usr/dt/bin/dtaction ReloadActions&");
1425 window->container->EndUpdate();
1426 window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
1427 if (app_mode != CONFIG_PRINTERS)
1429 AddTimeOut(RestoreAppCB, this, 0);
1430 printers[0]->AddTimeOut(InitQueueDetails, window, 3000);
1434 void DtApp::RestoreAppCB(BaseUI *obj, void *)
1436 ((DtApp *)obj)->RestoreApp();
1439 void DtApp::AddQueues(BaseUI *obj, void *)
1441 ((DtApp *)obj)->UpdateQueues();
1444 void DtApp::AddActions(BaseObj *dummy)
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);