-fpermissive to allow GCC to compile old C++
[oweals/cde.git] / cde / programs / dtmail / dtmail / AttachCmds.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23  /*
24  *+SNOTICE
25  *
26  *      $TOG: AttachCmds.C /main/8 1999/07/02 14:33:38 mgreess $
27  *
28  *      RESTRICTED CONFIDENTIAL INFORMATION:
29  *      
30  *      The information in this document is subject to special
31  *      restrictions in a confidential disclosure agreement between
32  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
33  *      document outside HP, IBM, Sun, USL, SCO, or Univel without
34  *      Sun's specific written approval.  This document and all copies
35  *      and derivative works thereof must be returned or destroyed at
36  *      Sun's request.
37  *
38  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
39  *
40  *+ENOTICE
41  */
42
43 #include <Xm/Xm.h>
44 #include <Xm/FileSB.h>
45 #include <Xm/SelectioB.h>
46 #include <Xm/MessageB.h>
47 #include <fcntl.h>
48 #include <stdio.h>
49 #include <sys/stat.h>
50 #if defined(USL) || defined(__uxp__)
51 #define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK)
52 #endif
53 #include <sys/types.h>
54 #include <sys/uio.h>
55 #include <unistd.h>
56 #include <stdlib.h>
57 #include <pwd.h>
58 #include "Application.h"
59 #include "AttachArea.h"
60 #include "Attachment.h"
61 #include "Icon.h"
62 #include "AttachCmds.h"
63 #include "InfoDialogManager.h"
64 #ifdef DEAD_WOOD
65 #include "QuestionDialogManager.h"
66 #endif /* DEAD_WOOD */
67 #include "RoamMenuWindow.h"
68 #include <DtMail/DtMailError.hh>
69 #include <DtMail/DtMail.hh>
70 #include "RoamApp.h"
71 #include "ViewMsgDialog.h"
72 #include "MailMsg.h"
73
74
75 extern "C" {
76 extern XtPointer _XmStringUngenerate (
77                                 XmString string,
78                                 XmStringTag tag,
79                                 XmTextType tag_type,
80                                 XmTextType output_type);
81 }
82
83 extern nl_catd  DtMailMsgCat;
84
85 static void okcb(XtPointer);
86
87 AttachAddCmd::AttachAddCmd ( AttachArea *attachArea, 
88                              Widget parent, 
89                              Widget clipWindow, 
90                              char *name, 
91                              char *label,
92                              int active ) : Cmd ( name, label, active )
93 {
94
95     _attachArea = attachArea;
96     _clipWindow = clipWindow;
97     _parent     = parent;
98
99 }
100
101 void AttachAddCmd::doit()
102 {
103     FSState fsstate;
104     Widget fsdialog;
105     char *home;
106     struct passwd *pwd;
107
108     fsdialog = _attachArea->getFsDialog();
109     if(fsdialog == NULL) {
110         fsdialog = XmCreateFileSelectionDialog(_parent, "fsdialog", NULL, 0);
111         XtUnmanageChild(
112                 XmFileSelectionBoxGetChild(fsdialog, XmDIALOG_HELP_BUTTON));
113         XtVaSetValues(XmFileSelectionBoxGetChild(fsdialog, XmDIALOG_LIST),
114             XmNselectionPolicy, XmBROWSE_SELECT,
115             NULL);
116         pwd = getpwuid(getuid());
117         home = pwd->pw_dir;
118         XtVaSetValues(fsdialog,
119             XtVaTypedArg, XmNdirectory, XtRString,
120             home, strlen(home)+1,
121             NULL);
122         _attachArea->setFsDialog(fsdialog);
123         XtAddCallback(fsdialog, XmNcancelCallback, 
124                           &AttachAddCmd::cancelCallback,
125                           (XtPointer) this );
126     }
127     fsstate = _attachArea->getFsState();
128     if(fsdialog) {
129         switch(fsstate) {
130         case ADD:       // Do nothing
131             break;
132         case SAVEAS:
133             // Remove callbacks
134             XtRemoveAllCallbacks(fsdialog, XmNokCallback);
135             // Fall Through
136         case NOTSET:
137             // Install callbacks
138             XtAddCallback(fsdialog, XmNokCallback, 
139                               &AttachAddCmd::okCallback,
140                               (XtPointer) this );
141             break;
142         }
143         XtVaSetValues(XtParent(fsdialog),
144                 XmNtitle, GETMSG(DT_catd, 14, 1, "Add Attachment"),
145                 NULL);
146         XtManageChild(fsdialog);
147     }
148     XtVaSetValues(fsdialog, 
149                     XmNfileTypeMask, XmFILE_REGULAR, 
150                     NULL);
151     _attachArea->setFsState(ADD);
152     _attachArea->activateDeactivate();
153     XRaiseWindow(XtDisplay(fsdialog), XtWindow(XtParent(fsdialog)) );
154 }      
155
156 void AttachAddCmd::undoit()
157 {
158     // Just print a message that allows us to trace the execution
159     
160 }       
161
162 void AttachAddCmd::okCallback ( Widget w, XtPointer clientData, XtPointer callData )
163 {
164     AttachAddCmd *obj = (AttachAddCmd *) clientData;
165
166     obj->ok( w, callData );
167     //XtUnmanageChild( w );
168 }
169
170 void AttachAddCmd::ok( Widget , XtPointer callData )
171 {
172     XmFileSelectionBoxCallbackStruct *cbs = 
173             (XmFileSelectionBoxCallbackStruct *)callData;
174     int count, i;
175     XmStringTable string_table;
176     char *filename;
177
178     XtVaGetValues(XmFileSelectionBoxGetChild(_attachArea->getFsDialog(),
179                         XmDIALOG_LIST),
180         XmNselectedItems, &string_table,
181         XmNselectedItemCount, &count,
182         NULL);
183
184     if(count == 0) {
185         filename = NULL;
186         filename = (char *) _XmStringUngenerate(
187                                         cbs->value, NULL,
188                                         XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
189         if (NULL == filename) return; // internal error
190         add_file(filename);
191     } else {
192         for(i=0;i<count;i++) {
193             filename = NULL;
194             filename = (char *) _XmStringUngenerate(
195                                         string_table[i], NULL,
196                                         XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
197             if (NULL == filename) return; // internal error
198             add_file(filename);
199         }
200     }
201
202 }
203
204 void AttachAddCmd::add_file( char *filename )
205 {
206     int fd;
207     struct stat s;
208 //    ExecState executable;
209     Boolean validtype = TRUE;
210     char *errormsg = new char[512];
211
212     if(stat(filename, &s) == -1) {
213         sprintf(errormsg, 
214                 GETMSG(DT_catd, 14, 2, "Unable to open %s"), 
215                 filename
216         );
217                 
218 //      theInfoDialogManager->post(
219 //                  errormsg,
220 //                  (void *)NULL,
221 //                  okcb);
222         delete [] errormsg;
223         return;
224     }
225
226     if(S_ISFIFO(s.st_mode)) {
227         sprintf(errormsg,
228                 GETMSG(DT_catd, 14, 3,
229                     "Cannot attach FIFO files: %s"), filename
230         );
231         validtype = FALSE;
232     } else if(S_ISCHR(s.st_mode)) {
233         sprintf(errormsg,
234                 GETMSG(DT_catd, 14, 4,
235                     "Cannot attach character special files: %s"), filename
236         );
237         validtype = FALSE;
238     } else if(S_ISDIR(s.st_mode)) {
239         sprintf(errormsg,
240                 GETMSG(DT_catd, 14, 5,
241                     "Cannot attach directories: %s"), filename
242         );
243         validtype = FALSE;
244     } else if(S_ISBLK(s.st_mode)) {
245         sprintf(errormsg,
246                 GETMSG(DT_catd, 14, 6,
247                     "Cannot attach block special files: %s"), filename
248         );
249         validtype = FALSE;
250     } else if(S_ISSOCK(s.st_mode)) {
251         sprintf(errormsg,
252                 GETMSG(DT_catd, 14, 7,
253                     "Cannot attach socket files: %s"), filename
254         );
255         validtype = FALSE;
256     }
257     if(validtype == FALSE) {
258 //      theInfoDialogManager->post(
259 //                  errormsg,
260 //                  (void *)NULL,
261 //                  okcb);
262         delete [] errormsg;
263         return;
264
265     }
266     fd = open(filename, O_RDONLY);
267     if(fd == -1) {
268         sprintf(errormsg, 
269                 GETMSG(DT_catd, 14, 8,
270                     "Unable to open %s"),filename
271         );
272
273 //      theInfoDialogManager->post(
274 //                  errormsg,
275 //                  (void *)NULL,
276 //                  okcb);
277         delete [] errormsg;
278         return;
279     } else {
280         
281         // We open and close this file just to make sure that we can
282         // The attachment constructor must have a valid, openable, file
283         close(fd);
284     }
285
286 //     Attachment *attachment = new Attachment(
287 //                                      _attachArea, 
288 //                                      filename);
289 // 
290 //     attachment->setAttachArea(_attachArea);
291 //     attachment->initialize();
292 //     _attachArea->calcSizeOfAA();
293 // 
294 //     // Call CalcAttachmentPosition() before adding the attachment
295 //     // to the list so that we can successfully find the last attachment
296 //     // in the list
297 //     _attachArea->CalcAttachmentPosition(attachment);
298 //     _attachArea->addToList( attachment );
299     XtFree(filename);
300     _attachArea->CalcLastRow();
301     _attachArea->AdjustCurrentRow();
302     _attachArea->SetScrollBarSize(_attachArea->getLastRow()+1);
303     _attachArea->DisplayAttachmentsInRow(_attachArea->getCurrentRow());
304     delete [] errormsg;
305 }
306
307 void AttachAddCmd::cancelCallback ( Widget, XtPointer clientData, XtPointer callData )
308 {
309     AttachAddCmd *obj = (AttachAddCmd *) clientData;
310
311     obj->cancel( callData );
312 }
313
314 void AttachAddCmd::cancel( XtPointer )
315 {
316     Widget fsdialog = _attachArea->getFsDialog();
317
318     XtUnmanageChild(fsdialog);
319 }
320
321 AttachFetchCmd::AttachFetchCmd ( AttachArea *attachArea, 
322                                  char *name, 
323                                  char *label,
324                                  int active ) : Cmd ( name, label, active )
325 {
326     _attachArea = attachArea;
327 }
328
329 void AttachFetchCmd::doit()
330 {
331 //    int i;
332 //  Attachment **list = _attachArea->getList();
333 //    String contents;
334 //    unsigned long size;
335 //    char error[1024];
336 //    Boolean compressed;
337
338 //    if(_attachArea->get_mailbox()->get_disconnected() == TRUE)
339 //      return;
340 //     for(i=0;i<_attachArea->getIconCount();i++) {
341 //      if(((list[i]->get_ac_state() == ROAM_AVAILABLE) ||
342 //          (list[i]->get_ac_state() == ROAM_CACHED)) &&
343 //         (list[i]->getIcon()->isSelected() == TRUE)) {
344 //          RoamMenuWindow *rmw = 
345 //                      (RoamMenuWindow*)_attachArea->owner()->owner();
346 // 
347 // //       contents = (char * ) _attachArea->get_mailbox()->get_data(
348 // //                               rmw->msgno(),
349 // //                               list[i]->getSection(),
350 // //                               &size,
351 // //                               &compressed);
352 // 
353 //          contents = NULL;
354 //          list[i]->set_compressed(compressed);
355 //          // If contents is NULL then we were unable to get the contents
356 //          if(contents == NULL) {
357 //              sprintf(error, 
358 //                      GETMSG(DT_catd, 14, 9,
359 //                          "File contents unavailable: %s"),
360 //                           list[i]->getLabel()
361 //              );
362 // //           theInfoDialogManager->post(
363 // //               error,
364 // //               (void *)NULL,
365 // //               (DialogCallback)okcb);
366 //              return;
367 //          }
368 //          list[i]->setContents(contents);
369 //          list[i]->setFilesize( size );
370 //          list[i]->set_ac_state(ROAM_LOCAL);
371 // //       if(list[i]->getRow() == _attachArea->getCurrentRow())
372 // //           list[i]->getIcon()->expose((XtPointer)NULL);
373 //      }
374 //     }
375 }      
376
377 void AttachFetchCmd::undoit()
378 {
379     // Just print a message that allows us to trace the execution
380
381 }       
382
383 AttachDeleteCmd::AttachDeleteCmd ( AttachArea *attachArea, 
384                                    char *name, 
385                                    char *label,
386                                    int active ) : Cmd ( name, label, active )
387 {
388     _attachArea = attachArea;
389 }
390
391 void AttachDeleteCmd::doit()
392 {
393 //    int i, j;
394     WidgetList deleteList;
395
396     deleteList = (WidgetList)XtMalloc(sizeof(Widget)*_attachArea->getIconCount());
397 //     Attachment **list = _attachArea->getList();
398 //     for(i=0, j=0;i<_attachArea->getIconCount();i++)
399 //      if(list[i]->getIcon()->isSelected() == TRUE) {
400 //          deleteList[j++] = list[i]->baseWidget();
401 //          list[i]->getIcon()->unselect();
402 //          _attachArea->incDeleteCount();
403 //          _attachArea->setAttachmentsLabel();
404 //          list[i]->deleteIt();
405 //      }
406 //     XtUnmanageChildren(deleteList, j);
407 //     XtFree((char *)deleteList);
408 //     _attachArea->activateDeactivate();
409 //     _attachArea->CalcAllAttachmentPositions();
410 //     _attachArea->CalcLastRow();
411 //     _attachArea->AdjustCurrentRow();
412 //     _attachArea->SetScrollBarSize(_attachArea->getLastRow()+1);
413 //     _attachArea->DisplayAttachmentsInRow(_attachArea->getCurrentRow());
414 }      
415
416 void AttachDeleteCmd::undoit()
417 {
418     // Just print a message that allows us to trace the execution
419     
420 }       
421
422 AttachOpenCmd::AttachOpenCmd ( AttachArea *attachArea, 
423                                char *name, 
424                                char *label,
425                                int active ) : Cmd ( name, label, active )
426 {
427     _attachArea = attachArea;
428 }
429
430 void AttachOpenCmd::doit()
431 {
432 //    int i;
433
434 //     Attachment **list = _attachArea->getList();
435 //     for(i=0;i<_attachArea->getIconCount();i++)
436 //      if(list[i]->getIcon()->isSelected() == TRUE) {
437 //          list[i]->executeOpenMethod();
438 //          // Break after finding a selected file
439 //          break;
440 // 
441 //      }
442     
443 }      
444
445 void AttachOpenCmd::undoit()
446 {
447     // Just print a message that allows us to trace the execution
448     
449 }       
450
451 AttachRenameCmd::AttachRenameCmd ( AttachArea *attachArea, 
452                                    Widget parent, 
453                                    char *name, 
454                                    char *label,
455                                    int active ) : Cmd ( name, label, active )
456 {
457     Widget renameDialog;
458     XmString message;
459
460     _attachArea = attachArea;
461     renameDialog = XmCreatePromptDialog(parent, "renameDialog", NULL, 0);
462     message = XmStringCreateLocalized(attachArea->getRenameMessageString());
463     XtVaSetValues(renameDialog, XmNselectionLabelString, message, NULL);
464     XmStringFree(message);
465     XtVaSetValues(XtParent(renameDialog),
466             XmNtitle, GETMSG(DT_catd, 14, 9, "Mailer - Rename Attachment"),
467             NULL);
468     XtUnmanageChild(
469         XmSelectionBoxGetChild(renameDialog, XmDIALOG_HELP_BUTTON)
470     );
471     _attachArea->setRenameDialog(renameDialog);
472     XtAddCallback(renameDialog, XmNcancelCallback, 
473                       &AttachRenameCmd::cancelCallback,
474                       (XtPointer) this );
475     XtAddCallback(renameDialog, XmNokCallback, 
476                       &AttachRenameCmd::okCallback,
477                       (XtPointer) this );
478 }
479
480 void AttachRenameCmd::doit()
481 {
482     Widget renameDialog;
483
484     renameDialog = _attachArea->getRenameDialog();
485     XtManageChild(renameDialog);
486     XtPopup(XtParent(renameDialog), XtGrabNone);
487 }      
488
489 void AttachRenameCmd::undoit()
490 {
491     // Just print a message that allows us to trace the execution
492     
493 }       
494
495 void AttachRenameCmd::cancelCallback ( Widget, XtPointer clientData, XtPointer callData )
496 {
497     AttachRenameCmd *obj = (AttachRenameCmd *) clientData;
498
499     obj->cancel( callData );
500 }
501
502 void AttachRenameCmd::cancel( XtPointer )
503 {
504     Widget renameDialog = _attachArea->getRenameDialog();
505
506     XtUnmanageChild(renameDialog);
507 }
508
509 void AttachRenameCmd::okCallback ( Widget, XtPointer clientData, XtPointer callData )
510 {
511     AttachRenameCmd *obj = (AttachRenameCmd *) clientData;
512
513     obj->ok( callData );
514 }
515
516 void AttachRenameCmd::ok( XtPointer callData )
517 {
518     XmSelectionBoxCallbackStruct *cbs = 
519             (XmSelectionBoxCallbackStruct *)callData;
520     String label = NULL;
521
522     if(_attachArea->getIconSelectedCount() != 1) {
523 //      theInfoDialogManager->post(
524 //                  GETMSG(DT_catd, 14, 12,
525 //      "Please select only one attachment to rename"),
526 //                  (void *)NULL,
527 //                  okcb);
528         return;
529     }
530 //     Attachment **list = _attachArea->getList();
531 //     for(i=0;i<_attachArea->getIconCount();i++)
532 //      if(list[i]->getIcon()->isSelected()) {
533 //          label = NULL;
534 //          label = (char *) _XmStringUngenerate(
535 //                                      cbs->value, NULL,
536 //                                      XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
537 //          if (NULL == label) return; // internal error
538 //          list[i]->setLabelAndCenter(label);
539 //      }
540 }
541
542 AttachDescriptionCmd::AttachDescriptionCmd ( AttachArea *attachArea, 
543                                              Widget parent, 
544                                              char *name, 
545                                              char *label,
546                                              int active ) 
547                         : Cmd ( name, label, active )
548 {
549     Widget descriptionDialog;
550     XmString message;
551
552     _attachArea = attachArea;
553     descriptionDialog = XmCreatePromptDialog(parent, "descriptionDialog", NULL, 0);
554     message = XmStringCreateLocalized(attachArea->getDescriptionMessageString());
555     XtVaSetValues(descriptionDialog, XmNselectionLabelString, message, NULL);
556     XmStringFree(message);
557     XtVaSetValues(XtParent(descriptionDialog),
558             XmNtitle, GETMSG(DT_catd, 14, 10, "Description"),
559             NULL);
560     XtUnmanageChild(XmSelectionBoxGetChild(descriptionDialog, XmDIALOG_HELP_BUTTON));
561     _attachArea->setDescriptionDialog(descriptionDialog);
562     XtAddCallback(descriptionDialog, XmNcancelCallback, 
563                       &AttachDescriptionCmd::cancelCallback,
564                       (XtPointer) this );
565     XtAddCallback(descriptionDialog, XmNokCallback, 
566                       &AttachDescriptionCmd::okCallback,
567                       (XtPointer) this );
568 }
569
570 void AttachDescriptionCmd::doit()
571 {
572 //     Attachment **list = _attachArea->getList();
573 //     Widget descriptionDialog;
574 //     Widget text;
575 //     int i;
576 // 
577 //     descriptionDialog = _attachArea->getDescriptionDialog();
578 //     text = XmSelectionBoxGetChild(descriptionDialog, XmDIALOG_TEXT);
579 //     for(i=0;i<_attachArea->getIconCount();i++) {
580 //      if(list[i]->getIcon()->isSelected()) {
581 //          XtVaSetValues(text,
582 //              XmNvalue, list[i]->get_description() ?
583 //                          list[i]->get_description() : "",
584 //              NULL);
585 //          break;
586 //      }
587 //     }
588 //    XtManageChild(descriptionDialog);
589 }      
590
591 void AttachDescriptionCmd::undoit()
592 {
593     // Just print a message that allows us to trace the execution
594     
595 }       
596
597 void AttachDescriptionCmd::cancelCallback ( Widget, XtPointer clientData, XtPointer callData )
598 {
599     AttachDescriptionCmd *obj = (AttachDescriptionCmd *) clientData;
600
601     obj->cancel( callData );
602 }
603
604 void AttachDescriptionCmd::cancel( XtPointer )
605 {
606     Widget descriptionDialog = _attachArea->getDescriptionDialog();
607
608     XtUnmanageChild(descriptionDialog);
609 }
610
611 void AttachDescriptionCmd::okCallback ( Widget, XtPointer clientData, XtPointer callData )
612 {
613     AttachDescriptionCmd *obj = (AttachDescriptionCmd *) clientData;
614
615     obj->ok( callData );
616 }
617
618 void AttachDescriptionCmd::ok( XtPointer callData )
619 {
620     XmSelectionBoxCallbackStruct *cbs = 
621             (XmSelectionBoxCallbackStruct *)callData;
622     String label = NULL;
623
624     if(_attachArea->getIconSelectedCount() != 1) {
625 //      theInfoDialogManager->post(
626 //                  GETMSG(DT_catd, 14, 12,
627 //                          "Please select only one attachment to describe"),
628 //                  (void *)NULL,
629 //                  okcb);
630         return;
631     }
632 //     Attachment **list = _attachArea->getList();
633 //     for(i=0;i<_attachArea->getIconCount();i++)
634 //      if(list[i]->getIcon()->isSelected()) {
635 //          label = NULL;
636 //          label = (char *) _XmStringUngenerate(
637 //                                      cbs->value, NULL,
638 //                                      XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
639 //          if (NULL == label) return; // internal error
640 //          list[i]->set_description(label);
641 //      }
642 }
643
644 AttachSaveAsCmd::AttachSaveAsCmd ( AttachArea *attachArea, 
645                                    Widget parent, 
646                                    Widget clipWindow, 
647                                    char *name, 
648                                    char *label,
649                                    int active ) : Cmd ( name, label, active )
650 {
651     _attachArea = attachArea;
652     _clipWindow = clipWindow;
653     _parent     = parent;
654 }
655
656 void AttachSaveAsCmd::doit()
657 {
658     FSState fsstate;
659     Widget fsdialog;
660     struct passwd *pwd;
661     char *home;
662     
663     fsdialog = _attachArea->getFsDialog();
664     if(fsdialog == NULL) {
665         fsdialog = XmCreateFileSelectionDialog(_parent, "fsdialog", NULL, 0);
666         XtUnmanageChild(
667                 XmFileSelectionBoxGetChild(fsdialog, XmDIALOG_HELP_BUTTON));
668         XtVaSetValues(XmFileSelectionBoxGetChild(fsdialog, XmDIALOG_LIST),
669             XmNselectionPolicy, XmBROWSE_SELECT,
670             NULL);
671         pwd = getpwuid(getuid());
672         home = pwd->pw_dir;
673         XtVaSetValues(fsdialog,
674             XtVaTypedArg, XmNdirectory, XtRString,
675             home, strlen(home)+1,
676             NULL);
677         _attachArea->setFsDialog(fsdialog);
678         XtAddCallback(fsdialog, XmNcancelCallback, 
679                           &AttachSaveAsCmd::cancelCallback,
680                           (XtPointer) this );
681     }
682     
683     fsstate = _attachArea->getFsState();
684     if(fsdialog) {
685         switch(fsstate) {
686         case SAVEAS:    // Do nothing
687             break;
688         case ADD:
689             // Remove callbacks
690             XtRemoveAllCallbacks(fsdialog, XmNokCallback);
691             // Fall Through
692         case NOTSET:
693             // Install callbacks
694             XtAddCallback(fsdialog, XmNokCallback, 
695                               &AttachSaveAsCmd::okCallback,
696                               (XtPointer) this );
697             break;
698         }
699         XtVaSetValues(XtParent(fsdialog),
700                 XmNtitle, GETMSG(DT_catd, 14, 11, "Save Attachment As"),
701                 NULL);
702         XtManageChild(fsdialog);
703     }
704     XtVaSetValues(fsdialog, 
705                     XmNfileTypeMask, XmFILE_DIRECTORY, 
706                     NULL);
707     _attachArea->setFsState(SAVEAS);
708     _attachArea->activateDeactivate();
709     XRaiseWindow( XtDisplay(fsdialog), XtWindow(XtParent(fsdialog)) );
710
711 }      
712
713 void AttachSaveAsCmd::undoit()
714 {
715     // Just print a message that allows us to trace the execution
716     
717 }       
718
719 void AttachSaveAsCmd::okCallback ( Widget w, XtPointer clientData, XtPointer callData )
720 {
721     AttachSaveAsCmd *obj = (AttachSaveAsCmd *) clientData;
722
723     obj->ok( callData );
724     XtUnmanageChild( w );
725 }
726
727 void ConfirmCallback( XtPointer)
728 {
729 //     Attachment *attachment = (Attachment *)clientData;
730 //     int fd;
731 //     char error[1024];
732 //     AttachArea *attachArea = attachment->parent();
733 //     String filecontents;
734 //     unsigned long size;
735 //     ssize_t retval;
736 //     Boolean compressed;
737 // 
738 //     RoamMenuWindow *rmw = (RoamMenuWindow *)attachArea->owner()->owner();
739 //     
740 //     switch(attachment->get_ac_state()) {
741 //     case ROAM_LOCAL:
742 //      break;
743 //     case ROAM_AVAILABLE:
744 //     case ROAM_CACHED:
745 // 
746 //      attachment->setContents(NULL);
747 // //                   (char *)
748 // //                   attachArea->get_mailbox()->get_data(
749 // //                   rmw->msgno(),
750 // //                   attachment->getSection(),
751 // //                   &size,
752 // //                   &compressed));
753 //      attachment->set_compressed(compressed);
754 //      attachment->setFilesize( size );
755 //      attachment->set_ac_state(ROAM_LOCAL);
756 // //   attachment->getIcon()->expose((XtPointer)NULL);
757 //      break;
758 //     case ROAM_UNAVAILABLE:
759 // //   theInfoDialogManager->post(
760 // //       GETMSG(DT_catd, 14, 15, "File Contents Unavailable"),
761 // //       (void *)NULL,
762 // //       (DialogCallback)okcb);
763 //          return;
764 //     }
765 //     (void)attachment->open_and_write(attachment->getSaveAsFilename());
766 }
767
768 void AttachSaveAsCmd::ok( XtPointer callData )
769 {
770     XmFileSelectionBoxCallbackStruct *cbs = 
771             (XmFileSelectionBoxCallbackStruct *)callData;
772     char *dirname = NULL;
773 //    struct stat s;
774 //     Attachment **list = _attachArea->getList();
775 //     char error[1024];
776 //     int i, fd;
777 //     SaveFileState sfs = OK;
778 //     char buf[1024];
779 //     String completefilename;
780 //     String filecontents;
781 //     unsigned long size;
782 //     ssize_t retval;
783 //     Boolean compressed;
784 // 
785 //      dirname = NULL;
786 //      dirname = (char *) _XmStringUngenerate(
787 //                                      cbs->value, NULL,
788 //                                      XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
789 //      if (NULL == dirname) return; // internal error
790 //     //
791 //     // If more than one attachment is selected then the selection
792 //     // specification must be a directory and must already exist.
793 //     //
794 //     //if(_attachArea->getIconSelectedCount() != 1) {
795 //      // This should not be able to happen
796 //      //printf("AttachSaveAsCmd::ok: getIconSelectedCount != 1. This can't happen\n");
797 //     //} else {
798 //     for(i=0;i<_attachArea->getIconCount();i++) {
799 //      if(list[i]->getIcon()->isSelected() == TRUE) {
800 //      //
801 //      // If a directory then keep the same file name and write to 
802 //      // that directory
803 //      //
804 //      // If it is a file that does not exist then we will try to
805 //      // create it (later)
806 //      //
807 //      // If the file already exists then we must prompt the user
808 //      // to see if he wants to overwrite the file.
809 //      //
810 //          if(stat(dirname, &s) != -1) {       // The file already exists
811 //              // This shouldn't happen because we make the fsdialog
812 //              // show directories only.  However, the user could enter
813 //              // the name of an existing file.
814 //              if(S_ISREG(s.st_mode)) {
815 //                  // If the user is trying to write multiple attachments
816 //                  // to a single existing file then we barf!
817 //                  if(_attachArea->getIconSelectedCount() != 1) {
818 //                      sprintf(error, 
819 //                              GETMSG(DT_catd, 14, 16, "Cannot create"));
820 //                      sfs = CONFIRM;
821 //                  } else {
822 //                      // The file already exists
823 //                      completefilename = dirname;
824 //                      sprintf(error, 
825 //                              GETMSG(DT_catd, 14, 17,
826 //                                  "File %s exists. Overwrite?"),
827 //                                          completefilename);
828 //                      sfs = CONFIRM;
829 //                  }
830 //              } else if(S_ISDIR(s.st_mode)) {
831 //                  sfs = OK;
832 //                  sprintf(buf, "%s%s", dirname, list[i]->getLabel());
833 //                  completefilename = buf;
834 //                  if(stat(buf, &s) != -1) {   // The file exists
835 //                      if(S_ISREG(s.st_mode)) {
836 //                          sprintf(error, 
837 //                              GETMSG(DT_catd, 14, 18,
838 //              "File %s exists. Overwrite?"), 
839 //                              completefilename);
840 //                          sfs = CONFIRM;
841 //                      } else {
842 //                          // We're trying to overwrite something other
843 //                          // than a regular file. FAIL!
844 //                          sprintf(error, 
845 //              GETMSG(14, 19, "Cannot create"));
846 //                          sfs = CONFIRM;
847 //                      }
848 //                  }
849 //              } else {
850 //                  // The file already exists but is not a regular file
851 //                  completefilename = dirname;
852 //                  sprintf(error,
853 //                          GETMSG(
854 //    DT_catd, 14, 20, "Cannot create %s"), completefilename);
855 //                  sfs = ERR;
856 //              }
857 //          } else {    // The file does not exist. Maybe the user entered
858 //                      // a new file name in an existing directory.
859 //              completefilename = dirname;
860 //          }
861 //          list[i]->setSaveAsFilename(strdup(completefilename));
862 //          switch(sfs) {
863 //          case ERR:
864 // //           theInfoDialogManager->post(
865 // //               error,
866 // //               (void *)NULL,
867 // //               (DialogCallback)okcb);
868 //              break;
869 //          case CONFIRM:
870 // //           theQuestionDialogManager->post(error,
871 // //                                          (XtPointer)list[i],
872 // //                                          ConfirmCallback,
873 // //                                          okcb     // Cancel button
874 // //                                          );
875 //              break;
876 //          case OK:
877 //              RoamMenuWindow *rmw = 
878 //                  (RoamMenuWindow*)_attachArea->owner()->owner();
879 // 
880 //              switch(list[i]->get_ac_state()) {
881 //              case ROAM_LOCAL:
882 //                  break;
883 //              case ROAM_CACHED:
884 //              case ROAM_AVAILABLE:
885 //                  list[i]->setContents(NULL);
886 // 
887 // //                   (char * )_attachArea->get_mailbox()->get_data(
888 // //                           rmw->msgno(),
889 // //                           list[i]->getSection(),
890 // //                           &size,
891 // //                           &compressed));
892 // 
893 //                  list[i]->set_compressed(compressed);
894 //                  list[i]->setFilesize( size );
895 //                  list[i]->set_ac_state(ROAM_LOCAL);
896 // //               list[i]->getIcon()->expose((XtPointer)NULL);
897 //                  break;
898 //              case ROAM_UNAVAILABLE:
899 // //               theInfoDialogManager->post(
900 // //                   GETMSG(DT_catd, 14. 21, "File Contents Unavailable"),
901 // //                   (void *)NULL, (DialogCallback)okcb);
902 //                      return;
903 //              }
904 //              (void)list[i]->open_and_write(completefilename);
905 //              break;
906 //          }
907 //      }
908 //     }
909 //     XtFree(dirname);
910 }
911
912 void AttachSaveAsCmd::cancelCallback ( Widget, XtPointer clientData, XtPointer callData )
913 {
914     AttachSaveAsCmd *obj = (AttachSaveAsCmd *) clientData;
915
916     obj->cancel( callData );
917 }
918
919 void AttachSaveAsCmd::cancel( XtPointer )
920 {
921     XtUnmanageChild(_attachArea->getFsDialog());
922 }
923
924 AttachSelectAllCmd::AttachSelectAllCmd ( AttachArea *attachArea, 
925                                          char *name, 
926                                          char *label,
927                                          int active ) 
928                                 : Cmd ( name, label, active )
929 {
930     _attachArea = attachArea;
931 }
932
933 void AttachSelectAllCmd::doit()
934 {
935 //    int i;
936 //    Boolean disconnected;
937
938 //    Attachment **list = _attachArea->getList();
939 // //    disconnected = _attachArea->get_mailbox()->get_disconnected();
940 //     for(i=0;i<_attachArea->getIconCount();i++) {
941 //      // Select the icon if and only if it is currently:
942 //      //     1) not selected, 2) not deleted, and 3) not disconnected
943 //      if(list[i]->getIcon()->isSelected() == FALSE &&
944 //                      list[i]->isDeleted() == FALSE && 
945 //                      list[i]->get_ac_state() != ROAM_UNAVAILABLE) {
946 //              list[i]->getIcon()->select();
947 //      }
948 //     }
949 }
950
951 void AttachSelectAllCmd::undoit()
952 {
953     // Just print a message that allows us to trace the execution
954     
955 }       
956
957 AttachUndeleteCmd::AttachUndeleteCmd ( AttachArea *attachArea, 
958                                        char *name, 
959                                        char *label,
960                                        int active ) 
961                         : Cmd ( name, label, active )
962 {
963     _attachArea = attachArea;
964 }
965
966 void AttachUndeleteCmd::doit()
967 {
968 //    int i;
969
970 //     Attachment **list = _attachArea->getList();
971 //     for(i=0;i<_attachArea->getIconCount();i++)
972 //      if(list[i]->isDeleted() == TRUE) {
973 //          list[i]->manage();
974 //          _attachArea->decDeleteCount();
975 //          _attachArea->setAttachmentsLabel();
976 //          list[i]->unDeleteIt();
977 //      }
978 // 
979 //     _attachArea->activateDeactivate();
980 //     _attachArea->CalcAllAttachmentPositions();
981 //     _attachArea->CalcLastRow();
982 //     _attachArea->AdjustCurrentRow();
983 //     _attachArea->SetScrollBarSize(_attachArea->getLastRow()+1);
984 //     _attachArea->DisplayAttachmentsInRow(_attachArea->getCurrentRow());
985 }      
986
987 void AttachUndeleteCmd::undoit()
988 {
989     // Just print a message that allows us to trace the execution
990     
991 }       
992
993 AttachUnselectAllCmd::AttachUnselectAllCmd ( AttachArea *attachArea, 
994                                              char *name, 
995                                              char *label,
996                                              int active ) 
997                         : Cmd ( name, label, active )
998 {
999     _attachArea = attachArea;
1000 }
1001
1002 void AttachUnselectAllCmd::doit()
1003 {
1004 //    int i;
1005
1006 //     Attachment **list = _attachArea->getList();
1007 //     for(i=0;i<_attachArea->getIconCount();i++)
1008 //      if(list[i]->getIcon()->isSelected() == TRUE)
1009 //          list[i]->getIcon()->unselect();
1010 }      
1011
1012 void AttachUnselectAllCmd::undoit()
1013 {
1014     // Just print a message that allows us to trace the execution
1015     
1016 }       
1017
1018 AttachInfoCmd::AttachInfoCmd ( AttachArea *attachArea, 
1019                                char *name, 
1020                                char *label,
1021                                int active ) 
1022                         : Cmd ( name, label, active )
1023 {
1024     _attachArea = attachArea;
1025     _info_dialog = NULL;
1026     _attachInfoDialogManager = NULL;
1027 }
1028
1029 void AttachInfoCmd::doit()
1030 {
1031
1032     // Stubbed out. 
1033
1034 //     ViewAttachArea *vaa = (ViewAttachArea *)_attachArea;
1035 //     int i;
1036 // 
1037 //     Attachment **list = _attachArea->getList();
1038 //     for(i=0;i<_attachArea->getIconCount();i++)
1039 //      if(list[i]->getIcon()->isSelected() == TRUE) {
1040 //          vaa->show_info(list[i]);
1041 //          break;
1042 //      }
1043
1044 }
1045
1046 void AttachInfoCmd::undoit()
1047 {
1048     // Just print a message that allows us to trace the execution
1049     
1050 }       
1051
1052 AttachInfoCmd::~AttachInfoCmd()
1053 {
1054     if(_info_dialog)
1055         XtDestroyWidget(_info_dialog);
1056 }
1057
1058 static void okcb( XtPointer )
1059 {
1060     //Empty
1061     // This function exists so that the OK button will appear on the
1062     // Info Dialog. It doesn't have to do anything because the dialog
1063     // automatically pops down. It is for information only.
1064 }