2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $TOG: DtApp.C /main/12 1998/08/25 12:58:57 mgreess $ */
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. *
31 // User Interface headers
34 #include "DtSetModList.h"
36 #include "DtWorkArea.h"
37 #include "DtPrtJobIcon.h"
38 #include "DtPrinterIcon.h"
39 #include "DtPrtProps.h"
40 #include "Application.h"
46 #include "PrintSubSys.h"
47 #include "ParseJobs.h"
49 // Command Execution header
54 #include "dtprintinfomsg.h"
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
63 extern "C" { extern int seteuid(uid_t); }
67 #define TITLE(message, app_name) \
69 sprintf(title, message, app_name)
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";
81 DtApp::DtApp(char *progname, int *argc, char **argv) :
82 Application(progname, "Dtprintinfo", argc, argv)
86 old_dbsearchpath = NULL;
88 single_printer = NULL;
89 app_mode = SINGLE_PRINTER;
90 char *app_name = MESSAGE(ApplicationName2L);
91 if (!((lang = getenv("LANG")) && *lang))
93 home = getenv("HOME");
94 if (!home || *home == '\0')
96 struct passwd *pwInfo = getpwuid(getuid());
97 home = strdup(pwInfo->pw_dir);
101 printer_dir = new char[strlen(home) + strlen(PRINTERS_DIR) + 2];
102 sprintf(printer_dir, "%s/%s", home, PRINTERS_DIR);
104 for (i = 0; i < *argc; i++)
106 if (!strcmp(argv[i], "-edit"))
108 app_name = MESSAGE(ApplicationName3L);
109 app_mode = CONFIG_PRINTERS;
112 else if (!strcmp(argv[i], "-all"))
114 app_name = MESSAGE(ApplicationName1L);
115 app_mode = PRINT_MANAGER;
120 Process *procs = new Process();
121 pid_t pid = getppid();
122 char *c = procs->Command(pid);
124 if (NULL != c && 0 == strncmp(c, "dtexec", 6))
126 if (app_mode == CONFIG_PRINTERS)
128 pid = procs->Parent(pid);
129 c = procs->Command(pid);
130 old_uid = procs->UID(pid);
131 if (!strncmp(c, "dtaction", 8))
133 pid = procs->Parent(pid);
134 c = procs->Command(pid);
135 old_uid = procs->UID(pid);
136 if (!strncmp(c, "dtexec", 6))
138 pid = procs->Parent(pid);
139 c = procs->Command(pid);
140 old_uid = procs->UID(pid);
146 // This is a workaround to avoid a bug in dtsession or dtaction.
147 // We should be fixing the problem there.
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.
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);
168 if (app_mode == CONFIG_PRINTERS)
172 fprintf(stderr, MESSAGE(RootUserL), progname, "-edit");
173 fprintf(stderr, "\n");
176 char *lang = getenv("LANG");
177 char *DBSearchPath = getenv("DTDATABASESEARCHPATH");
178 old_dbsearchpath = STRDUP(DBSearchPath);
180 if (!(lang && *lang))
182 if (DBSearchPath && *DBSearchPath)
184 buf = new char[strlen(DBSearchPath) + strlen(lang) + 50];
185 sprintf(buf, "DTDATABASESEARCHPATH=/etc/dt/appconfig/types/%s,%s",
190 buf = new char[strlen(DBSearchPath) + strlen(lang) + 50];
191 sprintf(buf, "DTDATABASESEARCHPATH=/etc/dt/appconfig/types/%s", lang);
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),
206 window = new DtMainW("Printers", this, app_name, SCROLLED_ICON_LIST,
207 SINGLE_SELECT, OpenClose, NULL, PreferenceCB, NULL,
208 MESSAGE(PrinterMenuL), MESSAGE(PrinterAcceleratorL),
210 window->Initialize();
211 window->ApplicationData = NULL;
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);
222 // Save print job's class name for registering GUI actions
223 PrintJob *dummy_printjob;
225 if (app_mode != CONFIG_PRINTERS)
227 dummy_printjob = new PrintJob(NULL, "_FOO", NULL, NULL, NULL, NULL, NULL);
228 className = (char *) dummy_printjob->ObjectClassName();
230 // Add Print Job Actions
231 AddActions(dummy_printjob);
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();
238 // Add GUI actions for queue
239 if (app_mode == PRINT_MANAGER)
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));
247 if (getuid() == 0 && dummy_queue->NumActions())
249 window->DtAddSep(className1);
250 AddActions(dummy_queue);
255 // Add GUI actions for queue
256 if (app_mode != CONFIG_PRINTERS)
258 if (app_mode == PRINT_MANAGER)
260 window->DtAddSep(className1);
261 window->DtAddAction(MESSAGE(HideChoiceL), className1, (char *)HIDE,
262 ActionCB, window, MESSAGE(HideMnemonicL));
264 //window->DtAddAction(MESSAGE(RenameChoiceL), className1, (char *)RENAME,
265 //ActionCB, window, MESSAGE(RenameMnemonicL));
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");
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)
283 window->DtAddSep(className1);
284 window->DtAddAction(MESSAGE(HelpChoiceL), className1, (char *)HELP,
285 ActionCB, window, MESSAGE(HelpMnemonicL), "F1");
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");
297 if (app_mode == PRINT_MANAGER)
299 Button *find = new Button(window->fileMenu, MESSAGE(FindChoiceL),
300 PUSH_BUTTON, FindCB, window,
301 MESSAGE(FindMnemonicL),
302 MESSAGE(FindAcceleratorL),
303 MESSAGE(FindAcceleratorKeySeq));
305 Button *filter = new Button(window->viewMenu, MESSAGE(ModifyShowChoiceL),
306 PUSH_BUTTON, ModifyCB, window,
307 MESSAGE(ModifyShowMnemonicL));
309 // Add a time out to add queues, this way the UI is visible within secs
310 ApplicationData = window;
311 AddTimeOut(AddQueues, this, 0);
317 delete [] printer_dir;
320 void DtApp::SaveYourSelf()
322 if (app_mode == CONFIG_PRINTERS)
327 char *value = window->setPrefD->ShowOnlyMyJobs() ? "1" : "0";
328 Save("ShowOnlyMine", value);
330 value = window->setPrefD->ShowStatusLine() ? "1" : "0";
331 Save("ShowMessageLine", value);
333 value = window->setPrefD->ShowDetailsLabel() ? "1" : "0";
334 Save("ShowDetailsLabel", value);
336 value = window->setPrefD->ShowStatusFlags() ? "1" : "0";
337 Save("ShowProblemFlag", value);
340 sprintf(interval, "%d", window->setPrefD->UpdateInterval());
341 Save("UpdateInterval", interval);
343 switch (window->container->IconView())
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;
350 Save("Representation", value);
352 if (app_mode == PRINT_MANAGER)
355 DtPrinterIcon **queues;
356 char *attribute = (char*) malloc(100);
357 queues = (DtPrinterIcon **) window->container->Children();
358 for (i = 0; i < window->container->NumChildren(); i++)
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);
371 char *DtApp::SessionFile()
373 if (app_mode == SINGLE_PRINTER)
376 return (char *)single_printer->QueueObj()->Name();
380 else if (app_mode == PRINT_MANAGER)
386 void DtApp::UpdateStatusLine()
391 message = (char*) malloc(200);
392 msg2 = (char*) malloc(100);
394 if (app_mode == CONFIG_PRINTERS)
396 sprintf(message, MESSAGE(EditLangL), lang);
397 window->status_line->Name(message);
399 else if (app_mode == SINGLE_PRINTER)
403 char *details = MESSAGE(UpL);
405 if (single_printer->PrintQueueUp() == false)
406 details = MESSAGE(DownL);
410 Queue *queue = single_printer->QueueObj();
412 for (i = 0; i < queue->NumberDevices(); i++)
413 if (single_printer->PrintDeviceUp(i) == false)
415 details = MESSAGE(DownL);
420 if (single_printer->PrintDeviceUp() == false)
421 details = MESSAGE(DownL);
423 Container *rc = single_printer->JobContainer();
424 if (window->setPrefD->ShowOnlyMyJobs() && rc)
426 if (rc->FindByName(MESSAGE(EmptyL)))
427 window->status_line->Name(details);
430 sprintf(msg2, MESSAGE(JobsL), rc->NumChildren());
431 sprintf(message, "%s %s", details, msg2);
432 window->status_line->Name(message);
436 window->status_line->Name(details);
439 window->status_line->Name(MESSAGE(NoDefaultPrinter1L));
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)
448 sprintf(msg2, MESSAGE(PrintersHiddenL),
449 window->container->NumChildren(), n_visible);
450 if (window->setPrefD->ShowOnlyMyJobs())
452 sprintf(message, "%s %s", msg2, MESSAGE(ShowingMyJobsL));
453 window->status_line->Name(message);
456 window->status_line->Name(msg2);
463 void DtApp::InitQueueDetails(BaseUI *obj, void *data)
465 ((DtPrinterIcon *)obj)->Update();
466 DtApp *app = (DtApp *)data;
467 app = (DtApp *)app->Parent();
472 int n_siblings = obj->NumSiblings();
473 int i = obj->Order() + 1;
476 BaseUI **siblings = obj->Siblings();
477 siblings[i]->AddTimeOut(InitQueueDetails, data, 3000);
479 if (app->app_mode == SINGLE_PRINTER)
480 app->UpdateStatusLine();
483 void DtApp::RemoteStatusCB(BaseUI *obj, char *output, int)
485 DtPrinterIcon *printer_icon = (DtPrinterIcon *)obj->Parent();
486 Queue *queue = printer_icon->QueueObj();
487 queue->ParseRemoteStatus(output);
488 printer_icon->PrintDeviceUp(queue->RemoteUp());
490 printer_icon->Open(true);
493 void DtApp::TurnOffHourGlass(BaseUI *obj, void *)
495 DtMainW *window = (DtMainW *) obj;
496 window->WorkingCursor(false);
499 void DtApp::ShowStatusDialog(DtPrinterIcon *printer_icon)
501 Queue *queue = printer_icon->QueueObj();
502 Attribute **attributes = queue->Attributes();
506 if (printer_icon->PrintQueueUp() == false)
507 len = strlen(MESSAGE(PrinterDownL)) + strlen(queue->Name());
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;
515 if (printer_icon->PrintDeviceUp() == false)
516 len += strlen(MESSAGE(DeviceDownL)) + strlen(attributes[1]->DisplayValue);
518 message = new char[len + 2];
520 if (printer_icon->PrintQueueUp() == false)
522 sprintf(message, MESSAGE(PrinterDownL), queue->Name());
523 strcat(message, "\n");
526 for (i = 0; i < queue->NumberDevices(); i++)
527 if (printer_icon->PrintDeviceUp(i) == false)
529 len = strlen(message);
530 sprintf(message + len, MESSAGE(DeviceDownL),
531 attributes[1 + i]->DisplayValue);
532 strcat(message, "\n");
535 len = strlen(message);
536 if (printer_icon->PrintDeviceUp() == false)
537 sprintf(message + len, MESSAGE(DeviceDownL), attributes[1]->DisplayValue);
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,
545 dialog->Visible(true);
549 void DtApp::OpenClose(void *data, BaseUI *obj)
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)
555 DtMainW *window = (DtMainW *) data;
556 ((DtApp *)window->Parent())->OpenClose(obj);
559 void DtApp::OpenClose(BaseUI *obj)
564 DtPrinterIcon *printer_icon;
568 if (app_mode == CONFIG_PRINTERS)
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);
583 if (!STRCMP(obj->Category(), STATUS_FLAG))
585 printer_icon = (DtPrinterIcon *)obj->Parent();
586 ShowStatusDialog(printer_icon);
590 printer_icon = (DtPrinterIcon *)obj;
591 queue = printer_icon->QueueObj();
592 rc = printer_icon->JobContainer();
593 if (obj->Open() == true)
595 char *message = new char[100];
596 boolean prev_open = false;
598 sprintf(message, MESSAGE(UpdatingL), obj->Name());
601 rc = printer_icon->CreateContainer();
602 rc->AddTimeOut(UpdatePrintJobs, window, Frequency);
605 prev_open = rc->Visible();
606 if (printer_icon->Visible())
608 if (queue->IsRemote() && printer_icon->waitForChildren == false)
610 if (printer_icon->updating == false)
612 int sockfd = ConnectToPrintServer(queue->Server(), connect_timeout);
615 SendPrintJobStatusReguest(sockfd, queue->RemotePrinter());
616 printer_icon->updating = true;
617 if (prev_open == false)
620 rc->UpdateMessage(message);
623 printer_icon->UpdateExpand();
624 rc->Thread(sockfd, RemoteStatusCB, 512);
629 queue->ParseRemoteStatus("");
630 printer_icon->PrintDeviceUp(false);
633 printer_icon->updating = false;
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();
646 BaseUI *empty_label = rc->FindByName(MESSAGE(EmptyL));
651 empty_label = new LabelObj(rc, MESSAGE(EmptyL));
652 icons = (DtPrtJobIcon **)rc->Children();
657 else if (empty_label)
661 icons = (DtPrtJobIcon **)rc->Children();
665 // Change children first, then delete or create icons
669 for (i = 0; i < n_icons; i++)
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)))
679 if (found_it == false)
682 icons = (DtPrtJobIcon **)rc->Children();
687 for (i = 0; i < n_icons; i++)
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)))
698 icons[i]->PrintJobObj(jobs[j]);
701 DtPrtJobIcon *tmp = new DtPrtJobIcon(window, rc, jobs[j], i + 1);
703 icons = (DtPrtJobIcon **)rc->Children();
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++)
722 sprintf(number, "%d", i + 1);
723 icons[i]->TopString(number);
725 if (window->setPrefD->ShowOnlyMyJobs())
727 if (getuid() == 0) // check to see if we are root
728 ShowUserJobs(obj, "root", true);
730 ShowUserJobs(obj, getenv("LOGNAME"), true);
732 window->WorkingCursor(false);
734 if (app_mode == PRINT_MANAGER)
736 if (window->findD && window->findD->Visible())
737 window->findD->UpdatePositions(printer_icon);
742 else if (app_mode != SINGLE_PRINTER)
745 rc->DeleteChildren();
746 queue->DeleteChildren();
750 printer_icon->UpdateExpand();
753 void DtApp::ActionCB(void *data, BaseUI *obj, char *actionReferenceName)
755 DtMainW *window = (DtMainW *) data;
756 ((DtApp *)window->Parent())->ActionCB(obj, actionReferenceName);
759 void DtApp::ActionCB(BaseUI *obj, char *actionReferenceName)
761 if (!strcmp(actionReferenceName, EXIT))
765 else if (!strcmp(actionReferenceName, FIND))
769 else if (!strcmp(actionReferenceName, HELP))
771 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST ||
772 obj->UIClass() == CONTAINER)
773 window->DisplayHelp((char *)PRINTER_ID);
775 window->DisplayHelp((char *)PRINTJOB_ID);
777 else if (!strcmp(actionReferenceName, PROPERTY))
779 if (app_mode == CONFIG_PRINTERS ||
780 obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
782 ((DtPrinterIcon *)obj)->DisplayProps();
784 else if (obj->UIClass() == CONTAINER)
785 ((DtPrinterIcon *)obj->Parent())->DisplayProps();
787 ((DtPrtJobIcon *)obj)->DisplayProps();
789 else if (!strcmp(actionReferenceName, OPEN))
791 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
793 if (obj->Open() == false)
798 if (obj->Parent()->Open() == false)
799 obj->Parent()->Open(true);
802 else if (!strcmp(actionReferenceName, CLOSE))
804 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
807 obj->Parent()->Open(false);
809 else if (!strcmp(actionReferenceName, RENAME))
811 Dialog *info = new Dialog(window, "Print Manager - Rename",
812 "NOT IMPLEMENTED", INFORMATION);
815 else if (!strcmp(actionReferenceName, HIDE))
817 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
820 obj->Parent()->Visible(false);
821 if (window->setModList && window->setModList->Visible())
822 window->setModList->Reset();
828 if (obj->Parent()->UISubClass() == SCROLLED_ICON_LIST)
829 object = ((DtPrinterIcon *)obj)->QueueObj();
831 object = (BaseObj *)obj->ApplicationData;
832 int save_id = obj->UniqueID();
833 if (!strcmp(actionReferenceName, CANCEL_PRINT_JOB))
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();
849 if (window->container->ObjectExists(save_id) == false)
851 Dialog *dialog = new Dialog(window, (char *)window->Name(),
852 MESSAGE(NotFoundMessageL), INFORMATION,
854 dialog->Visible(true);
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))
862 PrintJob *me = (PrintJob *) object;
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
868 if (!(strcmp(me->JobNumber(), MESSAGE(NotAvailableL))))
871 (void) object->HasAction(actionReferenceName, &action);
872 char *title = new char [strlen(MESSAGE(FailedActionTitleL)) +
873 strlen(window->Name()) +
874 strlen(action->DisplayName) + 1];
876 sprintf(title, MESSAGE(FailedActionTitleL), window->Name(),
877 action->DisplayName);
879 char *message = new char [strlen(MESSAGE(FailedMessageL)) +
880 strlen(action->DisplayName) +
881 strlen(object->DisplayName()) +
882 strlen(MESSAGE(NoRemoteCancelL)) + 1];
884 sprintf(message, MESSAGE(FailedMessageL),
885 action->DisplayName, object->DisplayName(),
886 MESSAGE(NoRemoteCancelL));
888 Dialog *dialog = new Dialog(window, title, message, ERROR,
890 dialog->Visible(true);
897 BaseUI *parent = obj->Parent();
898 // If command was successful, remove icon
899 if (object->LastActionStatus() == 0)
902 if (parent->NumChildren() == 0)
903 new LabelObj((AnyUI *)parent, MESSAGE(EmptyL));
907 IconObj **children = (IconObj **)parent->Children();
908 for (i = 0; i < parent->NumChildren(); i++)
911 sprintf(number, "%d", i + 1);
912 children[i]->TopString(number);
915 if (app_mode == PRINT_MANAGER)
917 if (window->findD && window->findD->Visible())
918 window->findD->UpdatePositions(parent->Parent());
922 else // This is a queue action, so update status flag
924 ((DtPrinterIcon *)obj)->Update();
925 if (app_mode == SINGLE_PRINTER)
929 if (object->LastActionStatus() != 0)
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());
945 Dialog *dialog = new Dialog(window, title, message, ERROR,
947 dialog->Visible(true);
954 void DtApp::UpdatePrintJobs(BaseUI *obj, // the print list box
957 DtMainW *window = (DtMainW *) data;
958 if (((DtApp *)window->Parent())->save_state)
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)
965 obj->AddTimeOut(UpdatePrintJobs, data, Frequency);
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)
976 obj->AddTimeOut(UpdatePrintJobs, data, Frequency);
980 // Queue Icon (parent) is visible, so update it
983 if (obj->Visible() == false)
985 // The jobs list box is not visible, so add a timeout and return
986 obj->AddTimeOut(UpdatePrintJobs, window, Frequency);
990 if (obj->Parent()->Open() == true)
992 if (icon->updating == false)
993 OpenClose(window, obj->Parent());
995 obj->AddTimeOut(UpdatePrintJobs, window, Frequency);
998 char *DtApp::GetBottomString(BaseObj *job, boolean need_details)
1000 static char string[200];
1001 if (window->setPrefD->ShowOnlyMyJobs())
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));
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));
1022 strcpy(string, job->AttributeValue((char *)OWNER));
1027 void DtApp::HandleShowDetailsLabelPreferenceRequest(IconStyle style)
1030 DtPrinterIcon **queues = (DtPrinterIcon **)window->container->Children();
1031 for (i = 0; i < window->container->NumChildren(); i++)
1032 queues[i]->ShowDetailsLabel(style, queues[i]->Visible());
1035 void DtApp::HandleDetailsPreferenceRequest(boolean details_on)
1038 BaseUI **queues = window->container->Children();
1039 for (i = 0; i < window->container->NumChildren(); i++)
1041 BaseUI *jobs_container = (BaseUI *)queues[i]->ApplicationData;
1042 if (!jobs_container)
1045 IconObj **jobs = (IconObj **)jobs_container->Children();
1047 for (j = 0; j < jobs_container->NumChildren(); j++)
1048 if (jobs[j]->UIClass() == ICON)
1050 BaseObj *job = (BaseObj *)jobs[j]->ApplicationData;
1051 char *bottomString = GetBottomString(job, details_on);
1052 jobs[j]->BottomString(bottomString);
1057 boolean DtApp::ShowUserJob(DtPrtJobIcon *_job, char *user_name)
1059 BaseObj *job = _job->PrintJobObj();
1060 char *owner = job->AttributeValue((char *)OWNER);
1061 char *s = strchr(owner, '@');
1063 if (s && s != owner)
1064 show_it = !strncmp(user_name, owner, (int)(s - owner)) ? true : false;
1066 show_it = !strcmp(user_name, owner) ? true : false;
1070 void DtApp::ShowUserJobs(BaseUI *queue, char *user_name, boolean flag)
1072 BaseUI *jobs_container = (BaseUI *)queue->ApplicationData;
1073 if (!jobs_container)
1076 DtPrtJobIcon **jobs = (DtPrtJobIcon **)jobs_container->Children();
1078 jobs_container->BeginUpdate();
1079 for (j = 0; j < jobs_container->NumChildren(); j++)
1080 if (jobs[j]->UIClass() == ICON)
1083 jobs[j]->Visible(ShowUserJob(jobs[j], user_name));
1085 jobs[j]->Visible(true);
1087 ((DtPrinterIcon *)queue)->ShowDetailsLabel(queue->IconView(),
1089 jobs_container->EndUpdate();
1092 void DtApp::HandleShowOnlyMinePreferenceRequest(boolean flag)
1096 BaseUI **queues = window->container->Children();
1097 if (getuid() == 0) // check to see if we are root
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);
1107 void DtApp::PreferenceCB(void *data, PreferenceRequest req, char *value)
1109 DtMainW *window = (DtMainW *)data;
1110 ((DtApp *)window->Parent())->PreferenceCB(req, value);
1113 void DtApp::PreferenceCB(PreferenceRequest req, char *value)
1118 HandleDetailsPreferenceRequest(true);
1121 HandleDetailsPreferenceRequest(false);
1123 case STATUS_LINE_ON:
1124 window->container->AttachBottom(window->status_line);
1126 case STATUS_LINE_OFF:
1127 window->container->AttachBottom();
1129 case STATUS_FLAG_ON:
1130 case STATUS_FLAG_OFF:
1133 DtPrinterIcon **queues;
1134 queues = (DtPrinterIcon **) window->container->Children();
1135 for (i = 0; i < window->container->NumChildren(); i++)
1136 queues[i]->Update();
1139 case SHOW_ONLY_MINE_ON:
1140 case SHOW_ONLY_MINE_OFF:
1141 HandleShowOnlyMinePreferenceRequest(window->setPrefD->ShowOnlyMyJobs());
1144 case SHOW_DETAILS_LABEL_ON:
1145 case SHOW_DETAILS_LABEL_OFF:
1146 HandleShowDetailsLabelPreferenceRequest(DETAILS);
1148 case UPDATE_INTERVAL_CHANGED:
1149 Frequency = (long) value * 1000;
1154 void DtApp::FilterCB(void *data)
1156 static DtMainW *window = NULL;
1160 window = (DtMainW *)data;
1161 while (window->UIClass() != MAIN_WINDOW)
1162 window = (DtMainW *)window->Parent();
1164 ((DtApp *)window->Parent())->FilterCB((BaseUI *)data);
1167 void DtApp::FilterCB(BaseUI *container)
1169 BaseUI **queue_list = container->Children();
1172 BaseUI **queues = window->container->Children();
1173 window->WorkingCursor(true);
1174 window->container->BeginUpdate();
1176 for (i = 0; i < container->NumChildren(); i++)
1177 queues[i]->Visible(queue_list[i]->Selected());
1179 window->container->EndUpdate();
1180 window->WorkingCursor(false);
1183 void DtApp::ModifyCB(void *data)
1185 DtMainW *window = (DtMainW *) data;
1186 if (!window->setModList)
1188 TITLE(MESSAGE(ModifyShowTitleL), window->Name());
1189 window->setModList = new DtSetModList(window, title,
1190 window->container, FilterCB);
1192 window->setModList->Visible(true);
1195 boolean DtApp::SelectPrintJobs(BaseUI *obj)
1197 if (obj->Parent()->UIClass() == CONTAINER &&
1198 obj->Parent()->UISubClass() == SCROLLED_HORIZONTAL_ROW_COLUMN)
1200 if (obj->UIClass() == LABEL)
1204 static DtMainW *window = NULL;
1207 window = (DtMainW *)obj;
1208 while (window->UIClass() != MAIN_WINDOW)
1209 window = (DtMainW *)window->Parent();
1211 DtApp *app = (DtApp *)window->Parent();
1212 if (getuid() == 0) // check to see if we are root
1214 if (window->setPrefD->ShowOnlyMyJobs())
1215 return app->ShowUserJob((DtPrtJobIcon *)obj, "root");
1216 else if (window->findD->MatchAnyUser())
1219 return app->ShowUserJob((DtPrtJobIcon *)obj, "root");
1222 return app->ShowUserJob((DtPrtJobIcon *)obj, getenv("LOGNAME"));
1229 void DtApp::FindCB(void *data)
1231 DtMainW *window = (DtMainW *) data;
1234 TITLE(MESSAGE(FindTitleL), window->Name());
1235 window->findD = new DtFindD(window, title, SelectPrintJobs);
1237 window->findD->Visible(true);
1240 void DtApp::RestoreApp()
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);
1250 window->setPrefD->Representation(LARGE_ICON);
1252 value = Restore("ShowProblemFlag");
1253 boolean flag = !STRCMP(value, "0") ? false : true;
1254 window->setPrefD->ShowStatusFlags(flag);
1256 value = Restore("ShowMessageLine");
1257 flag = !STRCMP(value, "0") ? false : true;
1258 window->setPrefD->ShowStatusLine(flag);
1260 value = Restore("ShowOnlyMine");
1261 flag = !STRCMP(value, "1") ? true : false;
1262 window->setPrefD->ShowOnlyMyJobs(flag);
1264 value = Restore("ShowDetailsLabel");
1265 flag = !STRCMP(value, "0") ? false : true;
1266 window->setPrefD->ShowDetailsLabel(flag);
1267 window->setPrefD->Apply();
1270 if (value = Restore("UpdateInterval"))
1272 interval = atoi(value);
1273 if (interval < 5 || interval > 300)
1276 window->setPrefD->UpdateInterval(interval);
1278 window->setPrefD->Apply();
1280 if (app_mode == PRINT_MANAGER)
1283 DtPrinterIcon **queues;
1284 char *attribute = new char[100];
1285 queues = (DtPrinterIcon **) window->container->Children();
1286 for (i = 0; i < window->container->NumChildren(); i++)
1288 sprintf(attribute, "%s.Visible", queues[i]->QueueObj()->Name());
1289 value = Restore(attribute);
1290 if (!STRCMP(value, "0"))
1291 queues[i]->Visible(false);
1294 sprintf(attribute, "%s.Open", queues[i]->QueueObj()->Name());
1295 value = Restore(attribute);
1296 if (!STRCMP(value, "1"))
1297 queues[i]->Open(true);
1305 single_printer->Open(true);
1309 void DtApp::UpdateQueues()
1311 window->PointerShape(HOUR_GLASS_CURSOR);
1312 window->container->BeginUpdate();
1313 window->status_line->Name(MESSAGE(SearchingL));
1316 PrintSubSystem *prt;
1317 if (window->ApplicationData)
1319 prt = (PrintSubSystem *) window->ApplicationData;
1320 prt->DeleteChildren();
1321 window->container->DeleteChildren();
1325 // Connect to Print SubSystem
1326 prt = new PrintSubSystem(NULL);
1327 window->ApplicationData = prt;
1329 int n_queues = prt->NumChildren();
1332 window->container->EndUpdate();
1333 window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
1335 Dialog *dialog = new Dialog(window, (char *)Name(),
1336 MESSAGE(FoundNoPrintersL),
1337 INFORMATION, MESSAGE(OKL));
1338 dialog->Visible(true);
1342 // Get Print Subsystem children, (these are queues)
1343 Queue **queues = (Queue **)prt->Children();
1345 BaseUI *lpdest = NULL;
1346 char *LPDEST = getenv("LPDEST");
1347 if (app_mode == SINGLE_PRINTER)
1350 // First check printer on command line
1353 for (j = 0; j < n_queues; j++)
1354 if (!STRCMP(argv[2], queues[j]->Name()))
1360 // Next check LPDEST printer
1361 if (found == -1 && LPDEST && *LPDEST)
1363 for (j = 0; j < n_queues; j++)
1364 if (!STRCMP(LPDEST, queues[j]->Name()))
1370 // If a printer is still not found, use system default
1374 char *cmd = "lsallq | grep -v ^bsh\\$ | head -1";
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 }'";
1382 char *cmd = "env LANG=C lpstat -d | awk '$1 != \"no\" {print $NF}'";
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()))
1399 window->container->EndUpdate();
1400 window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
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,
1408 dialog->Visible(true);
1411 window->ApplicationData = NULL;
1414 single_printer = new DtPrinterIcon(window, window->container,
1415 queues[found], app_mode);
1416 single_printer->updating = false;
1421 for (i = 0; i < n_queues; i++)
1424 DtPrinterIcon *icon = new DtPrinterIcon(window, window->container,
1425 queues[i], app_mode);
1426 icon->updating = false;
1429 boolean call_reload_actions = false;
1430 DtPrinterIcon **printers = (DtPrinterIcon **)window->container->Children();
1432 for (i = 0; i < window->container->NumChildren(); i++)
1434 if (printers[i]->PrintActionExists() == false)
1436 printers[i]->CreateActionFile();
1437 call_reload_actions = true;
1440 if (call_reload_actions)
1442 window->status_line->Name(MESSAGE(UpdatingActionsL));
1444 system("/usr/dt/bin/dtaction ReloadActions&");
1447 window->container->EndUpdate();
1448 window->PointerShape(LEFT_SLANTED_ARROW_CURSOR);
1449 if (app_mode != CONFIG_PRINTERS)
1451 AddTimeOut(RestoreAppCB, this, 0);
1452 printers[0]->AddTimeOut(InitQueueDetails, window, 3000);
1456 void DtApp::RestoreAppCB(BaseUI *obj, void *)
1458 ((DtApp *)obj)->RestoreApp();
1461 void DtApp::AddQueues(BaseUI *obj, void *)
1463 ((DtApp *)obj)->UpdateQueues();
1466 void DtApp::AddActions(BaseObj *dummy)
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);