4 * $TOG: RoamCmds.C /main/43 1999/07/13 08:41:44 mgreess $
6 * RESTRICTED CONFIDENTIAL INFORMATION:
8 * The information in this document is subject to special
9 * restrictions in a confidential disclosure agreement between
10 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
11 * document outside HP, IBM, Sun, USL, SCO, or Univel without
12 * Sun's specific written approval. This document and all copies
13 * and derivative works thereof must be returned or destroyed at
16 * Copyright 1993, 1994, 1995 Sun Microsystems, Inc. All rights reserved.
21 * Common Desktop Environment
23 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
24 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
25 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
26 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
27 * (c) Copyright 1995 Digital Equipment Corp.
28 * (c) Copyright 1995 Fujitsu Limited
29 * (c) Copyright 1995 Hitachi, Ltd.
32 * RESTRICTED RIGHTS LEGEND
34 *Use, duplication, or disclosure by the U.S. Government is subject to
35 *restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
36 *Technical Data and Computer Software clause in DFARS 252.227-7013. Rights
37 *for non-DOD U.S. Government Departments and Agencies are as set forth in
38 *FAR 52.227-19(c)(1,2).
40 *Hewlett-Packard Company, 3000 Hanover Street, Palo Alto, CA 94304 U.S.A.
41 *International Business Machines Corp., Route 100, Somers, NY 10589 U.S.A.
42 *Sun Microsystems, Inc., 2550 Garcia Avenue, Mountain View, CA 94043 U.S.A.
43 *Novell, Inc., 190 River Road, Summit, NJ 07901 U.S.A.
44 *Digital Equipment Corp., 111 Powdermill Road, Maynard, MA 01754, U.S.A.
45 *Fujitsu Limited, 1015, Kamikodanaka Nakahara-Ku, Kawasaki 211, Japan
46 *Hitachi, Ltd., 6, Kanda Surugadai 4-Chome, Chiyoda-ku, Tokyo 101, Japan
53 #include <sys/param.h>
55 #include <sys/types.h>
58 #include <X11/Intrinsic.h>
60 #include <Xm/FileSBP.h>
61 #include <Xm/FileSB.h>
63 #include <Xm/ToggleB.h>
64 #include <Xm/PushBG.h>
65 #include <Xm/PanedW.h>
68 #include <Dt/Action.h>
70 #include <Dt/DtPStrings.h>
72 #include <DtMail/IO.hh>
73 #include <DtMail/DtMailError.hh>
75 #include <DtMail/Buffer.hh>
78 #include <DtMail/Buffer.hh>
80 #include <DtMail/OptCmd.h>
81 #include <EUSCompat.h>
82 #include "EUSDebug.hh"
83 #include "Application.h"
84 #include "AttachArea.h"
85 #include "Attachment.h"
87 #include "DmxPrintJob.h"
88 #include "DtMailEditor.hh"
89 #include "DtMailGenDialog.hh"
90 #include "DtMailHelp.hh"
91 #include "DtMailWDM.hh"
92 #include "FindDialog.h"
95 #include "MemUtils.hh"
96 #include "MsgScrollingList.hh"
97 #include "MsgHndArray.hh"
100 #include "RoamMenuWindow.h"
101 #include "SendMsgDialog.h"
102 #include "Undelete.hh"
104 #if defined(NEED_MMAP_WRAPPER)
107 #include <sys/mman.h>
108 #if defined(NEED_MMAP_WRAPPER)
113 extern XtPointer _XmStringUngenerate (
117 XmTextType output_type);
121 #include <sys/file.h>
124 extern forceUpdate( Widget );
127 (char *name, char *label, int active, RoamMenuWindow *window)
128 : NoUndoCmd (name, label, active)
130 _menuwindow = window;
134 SearchCmd::SearchCmd(
138 RoamMenuWindow *window
139 ) : InterruptibleCmd (name, label, active)
141 _menuwindow = window;
147 TaskDoneCallback callback,
151 InterruptibleCmd::execute( callback, clientData );
158 _menuwindow->list()->clearMsgs();
159 _menuwindow->busyCursor();
162 _criteria=( char * )realloc(_criteria, strlen( this->name()) + 1);
163 strcpy(_criteria, this->name());
166 InterruptibleCmd::execute();
173 DtMailEnv mail_error;
175 // Initialize the mail_error.
178 MsgScrollingList *list=_menuwindow->list();
181 // load_headers will retrieve all of the message headers and
182 // add the handles to the list.
184 count = list->load_headers(mail_error);
186 _menuwindow->normalCursor();
189 _menuwindow->message(GETMSG(DT_catd, 3, 46, "Empty container"));
194 list->scroll_to_bottom();
201 // Just print a message that allows us to trace the execution
203 DebugPrintf(1, "%s: undoit\n", name());
207 SearchCmd::updateMessage (char *msg)
209 InterruptibleCmd::updateMessage(msg);
211 #endif /* DEAD_WOOD */
213 CheckForNewMailCmd::CheckForNewMailCmd(
217 RoamMenuWindow *window
218 ) : NoUndoCmd ( name, label, active )
220 _menuwindow = window;
224 CheckForNewMailCmd::doit()
227 // Initialize the mail_error.
229 _menuwindow->checkForMail(error);
233 OpenInboxCmd::OpenInboxCmd(
238 ) : Cmd (name, label, active)
248 RoamMenuWindow *rmw = theRoamApp.inboxWindow();
252 MailSession *ses = theRoamApp.session();
253 ses->activateRMW(rmw);
258 DtMailEnv mail_error;
259 char *mail_file = NULL;
260 DtMailObjectSpace space;
261 DtMail::Session *d_session = theRoamApp.session()->session();
264 d_session->queryImpl(mail_error,
265 d_session->getDefaultImpl(mail_error),
266 DtMailCapabilityInboxName,
271 if (mail_file) _menuWindow->view_mail_file(mail_file, DTM_FALSE);
276 OpenInboxCmd::undoit()
281 // OpenContainerCmd methods implementation.
282 // For the most part, we treat container->open() as a benign thing.
283 // The magic, as we see it, deals with converting the container
285 // For OpenContainerCmd, if no conversion is necessary bingo! it opens.
286 // If conversion is necessary, it punts the work to ConvertContainerCmd.
290 OpenContainerCmd::OpenContainerCmd (
294 RoamMenuWindow *window
295 ) : RoamInterruptibleCmd (name, label, active)
297 _menuWindow = window;
300 // Parent's execute() ends up calling derived class's doit()
302 OpenContainerCmd::execute()
304 RoamInterruptibleCmd::execute();
308 OpenContainerCmd::execute(
309 RoamTaskDoneCallback rtd_callback,
313 RoamInterruptibleCmd::execute(rtd_callback, clientData);
316 // Tell the RMW to open. The RMW may end up calling its convert()
317 // which depends on ConvertContainerCmd's doit...
318 // By the time RMW->open() returns, the conversion would have
320 // This is the case of a RinterruptibleCmd derived class
321 // getting its work done in its doit() in one call.
325 OpenContainerCmd::doit()
329 assert(_menuWindow != NULL);
331 // Initialize the mail_error.
334 _menuWindow->open(error, _open_create_flag, _open_lock_flag);
336 // Post a dialog indicating error and exit?
337 return; // for now. Should exit instead?
343 OpenContainerCmd::undoit()
345 // Just print a message that allows us to trace the execution
347 DebugPrintf(1, "%s: undoit\n", name());
351 OpenContainerCmd::check_if_done()
353 // Have nothing fancy to do here. Since we do not want a dialog
354 // in any case, set it to true...
362 OpenContainerCmd::post_dialog()
364 // Empty. We don't want a dialog on open...
368 OpenContainerCmd::unpost_dialog()
370 // Empty. We don't post, and we don't unpost.
373 OpenContainerCmd::updateMessage (char *msg)
375 RoamInterruptibleCmd::updateMessage(msg);
379 OpenContainerCmd::set_create_lock_flags(
380 DtMailBoolean create,
384 _open_create_flag = create;
385 _open_lock_flag = lock;
389 // ConvertContainerCmd
392 ConvertContainerCmd::ConvertContainerCmd(
396 RoamMenuWindow *window
397 ) : RoamInterruptibleCmd (name, label, active)
399 _menuWindow = window;
401 _num_to_be_converted = 0;
406 ConvertContainerCmd::execute()
409 _dialog = new DtMailWDM("Convert");
412 RoamInterruptibleCmd::execute();
416 ConvertContainerCmd::execute ( RoamTaskDoneCallback rtd_callback,
420 _dialog = new DtMailWDM("Convert");
423 RoamInterruptibleCmd::execute(rtd_callback, clientData);
426 // Here be bigger dragons!
427 // The doit() calls the session->convert().
428 // And returns right away!
429 // the ses->convert() however ends up calling the conv_cb for every
430 // message that it has converted.
431 // So, we now have two loops working in parallel:
432 // 1) the parent()'s execute() class which called this doit() and is now
433 // calling check_if_done() periodically via its workProc;
434 // 2) the session->convert() which is calling the _conv_cb() for every
435 // message that it converts. In the _conv_cb(), we do the following:
436 // a) force update the dialog and see if it was interrupted;
437 // b) if not interrupted, set_convert_data() where we set _done if
438 // we are really done.
442 ConvertContainerCmd::doit()
444 assert(_menuWindow != NULL);
446 MailSession *ses = theRoamApp.session();
447 DtMailEnv mail_error;
449 // Initialize the mail_error.
452 // ses->convert(mail_error, _src, _dest, _conv_cb, _menuWindow);
454 if (mail_error.isSet()) {
455 _menuWindow->postErrorDialog(mail_error);
460 ConvertContainerCmd::set_convert_data(
465 _num_converted = converted;
466 _num_to_be_converted = to_be_converted;
468 if ((_num_converted == _num_to_be_converted) && !_interrupted) {
474 ConvertContainerCmd::get_num_converted()
476 return(_num_converted);
481 ConvertContainerCmd::check_if_done()
486 else if (_num_converted == _num_to_be_converted) {
492 ConvertContainerCmd::updateDialog(
496 forceUpdate(_dialog->baseWidget());
497 _dialog->updateDialog( msg );
501 ConvertContainerCmd::updateAnimation()
503 forceUpdate(_dialog->baseWidget());
504 _dialog->updateAnimation();
508 ConvertContainerCmd::post_dialog()
510 Dimension x, y, wid, ht;
512 char * buf = new char[25];
514 sprintf(buf, "Converted: %3d%", 0);
516 _dialog->post ("Mailer",
518 _menuWindow->baseWidget(),
521 &RoamInterruptibleCmd::interruptCallback );
523 XtVaGetValues(_dialog->baseWidget(),
533 ConvertContainerCmd::unpost_dialog()
539 ConvertContainerCmd::undoit()
541 // Just print a message that allows us to trace the execution
543 DebugPrintf(1, "%s: undoit\n", name());
547 ConvertContainerCmd::set_data(
550 ConversionStatusCB cb
559 ConvertContainerCmd::get_destination_name()
571 RoamMenuWindow *window
572 ) : RoamCmd ( name, label, active, window )
580 _menuwindow->get_find_dialog();
582 // SearchCmd::doit();
587 ChooseCmd::ChooseCmd(
591 RoamMenuWindow *window
592 ) : NoUndoCmd( name, label, active )
594 _menuwindow = window;
603 SelectAllCmd::SelectAllCmd(
607 RoamMenuWindow *window
608 ) : Cmd ( name, label, active )
610 _menuwindow = window;
616 DtMailEnv mail_error;
618 _menuwindow->list()->select_all_and_display_last(mail_error);
622 SelectAllCmd::undoit()
627 DeleteCmd::DeleteCmd(
631 RoamMenuWindow *window
632 ) : Cmd ( name, label, active )
634 _menuwindow = window;
640 _menuwindow->list()->deleteSelected(FALSE);
650 DestroyCmd::DestroyCmd(
654 RoamMenuWindow *window
655 ) : Cmd(name, label, active)
657 _menuwindow = window;
663 // Call Expunge only if there are deleted messages.
665 if (_menuwindow->list()->get_num_deleted_messages()) {
666 _menuwindow->expunge();
675 // Unified Select File Cmd stuff
676 int UnifiedSelectFileCmd::_is_initialized = 0;
677 char *UnifiedSelectFileCmd::_unified_directory = NULL;
678 char *UnifiedSelectFileCmd::_unified_file = NULL;
679 int UnifiedSelectFileCmd::_unified_hidden = 0;
680 int UnifiedSelectFileCmd::_unify_selection = 1;
682 UnifiedSelectFileCmd::UnifiedSelectFileCmd (
692 :SelectFileCmd (name,
697 unifiedFileSelectedCB,
699 unifiedFileCanceledCB,
703 if (! _is_initialized)
705 FORCE_SEGV_DECL(DtMail::Session, m_session);
707 const char *dirname = NULL;
708 const char *expanded_dirname = NULL;
709 const char *value = NULL;
710 char *full_dirname = NULL;
712 _unified_directory = NULL;
713 _unified_file = NULL;
715 _unify_selection = 1;
718 m_session = theRoamApp.session()->session();
721 m_session->mailRc(error)->getValue(error, "filefolder", &dirname);
723 dirname = strdup("~");
726 expanded_dirname = m_session->expandPath(error, dirname);
727 _unified_directory = XtNewString(expanded_dirname);
730 m_session->mailRc(error)->getValue(
732 "dontunifyfileselection",
735 _unify_selection = 0;
737 free((void*) dirname);
738 free((void*) expanded_dirname);
742 _select_file_callback = select_callback;
743 _select_file_client_data = client_data;
744 _genDialog = new DtMailGenDialog("Dialog", parent);
747 UnifiedSelectFileCmd::~UnifiedSelectFileCmd()
749 if (_genDialog) delete _genDialog;
753 UnifiedSelectFileCmd::doit()
755 if (NULL == _fileBrowser)
757 SelectFileCmd::doit();
758 if (NULL != _unified_directory)
759 setDirectory(_unified_directory);
760 if (NULL != _unified_file)
761 setSelected(_unified_file);
762 setHidden(_unified_hidden);
766 if (_unify_selection)
768 if (NULL != _unified_directory)
769 setDirectory(_unified_directory);
770 if (NULL != _unified_file)
771 setSelected(_unified_file);
772 setHidden(_unified_hidden);
774 SelectFileCmd::doit();
779 UnifiedSelectFileCmd::unifiedFileSelectedCB(void *client_data, char *selection)
781 UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
785 self->updateUnifiedData();
786 self->unifiedFileSelected(selection);
791 UnifiedSelectFileCmd::unifiedFileSelected(char *selection)
795 SafePathIsAccessible(error, selection);
798 const char *errmsg = NULL;
802 errmsg = (const char*) error;
803 err = strdup(errmsg);
805 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
806 answer = _genDialog->post_and_return(DTMAILHELPERROR);
807 if (1 == answer) doit();
812 if (_select_file_callback)
813 _select_file_callback(_select_file_client_data, selection);
817 UnifiedSelectFileCmd::unifiedFileCanceledCB(void *client_data, char *)
819 UnifiedSelectFileCmd *self = (UnifiedSelectFileCmd *) client_data;
822 self->updateUnifiedData();
826 UnifiedSelectFileCmd::updateUnifiedData()
828 if (! _unify_selection)
831 if (NULL != _unified_file)
832 XtFree(_unified_file);
833 _unified_file = getSelected();
836 if (NULL != _unified_directory)
837 XtFree(_unified_directory);
838 _unified_directory = getDirectory();
840 _unified_hidden = getHidden();
843 // Unified Select Mailbox Cmd stuff
844 int UnifiedSelectMailboxCmd::_is_initialized = 0;
845 char *UnifiedSelectMailboxCmd::_unified_directory = NULL;
846 char *UnifiedSelectMailboxCmd::_unified_file = NULL;
847 int UnifiedSelectMailboxCmd::_unified_hidden = 0;
848 int UnifiedSelectMailboxCmd::_unify_selection = 1;
850 UnifiedSelectMailboxCmd::UnifiedSelectMailboxCmd (
860 DtMailBoolean only_show_mailboxes)
861 :SelectFileCmd (name,
866 unifiedMailboxSelectedCB,
868 unifiedMailboxCanceledCB,
872 if (! _is_initialized)
874 FORCE_SEGV_DECL(DtMail::Session, m_session);
876 const char *dirname = NULL;
877 const char *expanded_dirname = NULL;
878 const char *value = NULL;
879 char *full_dirname = NULL;
881 _unified_directory = NULL;
882 _unified_file = NULL;
884 _unify_selection = 1;
886 _only_show_mailboxes = only_show_mailboxes;
888 m_session = theRoamApp.session()->session();
891 m_session->mailRc(error)->getValue(error, "folder", &dirname);
893 dirname = strdup("~");
896 expanded_dirname = m_session->expandPath(error, dirname);
897 _unified_directory = XtNewString(expanded_dirname);
900 m_session->mailRc(error)->getValue(
902 "dontunifyfileselection",
905 _unify_selection = 0;
907 free((void*) dirname);
908 free((void*) expanded_dirname);
912 _select_file_callback = select_callback;
913 _select_file_client_data = client_data;
914 _genDialog = new DtMailGenDialog("Dialog", parent);
917 UnifiedSelectMailboxCmd::~UnifiedSelectMailboxCmd()
919 if (_genDialog) delete _genDialog;
923 UnifiedSelectMailboxCmd::doit()
925 if (NULL == _fileBrowser)
927 SelectFileCmd::doit();
928 if (NULL != _unified_directory)
929 setDirectory(_unified_directory);
930 if (NULL != _unified_file)
931 setSelected(_unified_file);
932 setHidden(_unified_hidden);
938 UnifiedSelectMailboxCmd::unifiedMailboxSearchProc,
943 if (_unify_selection)
945 if (NULL != _unified_directory)
946 setDirectory(_unified_directory);
947 if (NULL != _unified_file)
948 setSelected(_unified_file);
949 setHidden(_unified_hidden);
951 SelectFileCmd::doit();
956 extern void _XmOSBuildFileList(
959 #if NeedWidePrototypes
960 unsigned int typeMask,
962 unsigned char typeMask,
963 #endif /* NeedWidePrototypes */
965 unsigned int *pNumEntries,
966 unsigned int *pNumAlloc);
968 extern int _XmOSFileCompare(const void *sp1, const void *sp2);
969 extern char *_XmStringGetTextConcat(XmString string);
973 UnifiedSelectMailboxCmd::unifiedMailboxSearchProc(
977 XmFileSelectionBoxWidget fs =
978 (XmFileSelectionBoxWidget) w;
979 XmFileSelectionBoxCallbackStruct * searchData =
980 (XmFileSelectionBoxCallbackStruct *) sd;
986 unsigned int numFiles;
987 unsigned int numItems = 0;
988 unsigned int numAlloc;
989 XmString * XmStringFileList;
991 XtEnum fileFilterStyle, pathMode;
992 unsigned char fileTypeMask;
994 if (!(dir = _XmStringGetTextConcat(searchData->dir)))
997 if (!(pattern = _XmStringGetTextConcat(searchData->pattern)))
1006 XmNfileTypeMask, &fileTypeMask,
1007 XmNfileFilterStyle, &fileFilterStyle,
1008 XmNpathMode, &pathMode,
1012 dir, pattern, fileTypeMask,
1013 &fileList, &numFiles, &numAlloc);
1015 if (fileList && numFiles)
1017 Boolean showDotFiles = (fileFilterStyle == XmFILTER_NONE);
1020 qsort((void*) fileList, numFiles, sizeof(char*), _XmOSFileCompare);
1022 XmStringFileList = (XmString*) XtMalloc(numFiles*sizeof(XmString));
1025 dirLen = strlen(dir);
1027 while (Index < numFiles)
1029 Boolean isMailBox = 0;
1030 char *dataType = NULL;
1032 dataType = DtDtsFileToDataType(fileList[Index]);
1034 isMailBox = (0 == strcmp(dataType, "DTMAIL_FILE"));
1035 DtDtsFreeDataType(dataType);
1038 (showDotFiles || ((fileList[Index])[dirLen] != '.')) )
1040 if (pathMode == XmPATH_MODE_FULL)
1041 XmStringFileList[numItems++] =
1042 XmStringGenerate(fileList[Index],
1043 XmFONTLIST_DEFAULT_TAG,
1044 XmCHARSET_TEXT, NULL);
1046 XmStringFileList[numItems++] =
1047 XmStringGenerate(&(fileList[Index])[dirLen],
1048 XmFONTLIST_DEFAULT_TAG,
1049 XmCHARSET_TEXT, NULL) ;
1059 XmNfileListItemCount, numItems,
1060 XmNfileListItems, XmStringFileList,
1061 XmNlistUpdated, TRUE,
1066 XtFree( fileList[Index]);
1069 XmStringFree(XmStringFileList[numItems]);
1071 XtFree((char*) XmStringFileList);
1077 XmNfileListItemCount, 0,
1078 XmNfileListItems, NULL,
1079 XmNlistUpdated, TRUE,
1083 XtFree((char *) fileList);
1090 UnifiedSelectMailboxCmd::unifiedMailboxSelectedCB(
1094 UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
1098 self->updateUnifiedData();
1099 self->unifiedMailboxSelected(
1100 self->_select_file_callback,
1101 self->_select_file_client_data,
1107 UnifiedSelectMailboxCmd::unifiedMailboxSelected(
1114 SafePathIsAccessible(error, selection);
1117 const char *errmsg = NULL;
1121 errmsg = (const char*) error;
1122 err = strdup(errmsg);
1124 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 48, "Mailer"), err);
1125 answer = _genDialog->post_and_return(DTMAILHELPERROR);
1126 if (1 == answer) doit();
1131 updateUnifiedData();
1132 if (cb) cb(client_data, selection);
1136 UnifiedSelectMailboxCmd::unifiedMailboxCanceledCB(void *client_data, char *)
1138 UnifiedSelectMailboxCmd *self = (UnifiedSelectMailboxCmd *) client_data;
1141 self->updateUnifiedData();
1145 UnifiedSelectMailboxCmd::updateUnifiedData()
1147 if (! _unify_selection)
1150 if (NULL != _unified_file)
1151 XtFree(_unified_file);
1152 _unified_file = getSelected();
1155 if (NULL != _unified_directory)
1156 XtFree(_unified_directory);
1157 _unified_directory = getDirectory();
1159 _unified_hidden = getHidden();
1162 ContainerMenuCmd::ContainerMenuCmd(
1166 RoamMenuWindow *window,
1168 ) : RoamCmd ( name, label, active, window )
1170 _menuwindow = window;
1171 _container_name = name;
1176 ContainerMenuCmd::doit()
1178 DtMailEnv mail_error;
1180 // Initialize mail_error.
1183 theRoamApp.busyAllWindows(GETMSG(DT_catd, 3, 15, "Saving..."));
1184 _menuwindow->mailbox()->save();
1185 theRoamApp.unbusyAllWindows();
1192 _menuwindow->view_mail_file(_container_name, DTM_FALSE);
1195 _menuwindow->list()->copySelected(
1199 if (mail_error.isSet())
1201 // We had an error in copying the message to a container!
1205 _menuwindow->list()->copySelected(
1209 if (mail_error.isSet())
1211 // We had an error in moving the message to a container!
1217 ContainerMenuCmd::~ContainerMenuCmd()
1222 // Move the messages that are selected in the RoamMenuWindow to the Inbox.
1223 MoveToInboxCmd::MoveToInboxCmd(
1227 RoamMenuWindow *window
1228 ) : RoamCmd (name, label, active, window)
1230 _menuwindow = window;
1234 MoveToInboxCmd::doit()
1236 DtMailEnv mail_error;
1238 // Initialize mail_error.
1241 // Get a handle to the Inbox.
1242 char * mail_file = NULL;
1243 DtMailObjectSpace space;
1244 DtMail::Session * d_session = theRoamApp.session()->session();
1246 d_session->queryImpl(mail_error,
1247 d_session->getDefaultImpl(mail_error),
1248 DtMailCapabilityInboxName,
1251 _menuwindow->list()->copySelected(mail_error, mail_file, TRUE, FALSE);
1252 if (mail_error.isSet()) {
1253 // We had an error in moving the messages to the Inbox!
1257 MoveToInboxCmd::~MoveToInboxCmd()
1261 // Copy the selected messages to the Inbox.
1262 CopyToInboxCmd::CopyToInboxCmd(
1266 RoamMenuWindow *window
1267 ) : RoamCmd (name, label, active, window)
1269 _menuwindow = window;
1273 CopyToInboxCmd::doit()
1275 DtMailEnv mail_error;
1277 // Initialize mail_error.
1280 // Get a handle to the Inbox.
1281 char * mail_file = NULL;
1282 DtMailObjectSpace space;
1283 DtMail::Session * d_session = theRoamApp.session()->session();
1285 d_session->queryImpl(mail_error,
1286 d_session->getDefaultImpl(mail_error),
1287 DtMailCapabilityInboxName,
1290 _menuwindow->list()->copySelected(mail_error, mail_file, FALSE, FALSE);
1291 if (mail_error.isSet()) {
1292 // We ad an error in copying the messages to the Inbox!
1296 CopyToInboxCmd::~CopyToInboxCmd()
1301 // This is hooked up the Undelete button in the Deleted
1302 // Messages List dialog box.
1304 DoUndeleteCmd::DoUndeleteCmd(
1308 UndelFromListDialog *undelDialog
1309 ) : Cmd ( name, label, active )
1311 _undelDialog = undelDialog;
1315 DoUndeleteCmd::doit()
1317 // Undelete the selected messages.
1318 _undelDialog->undelSelected();
1322 DoUndeleteCmd::undoit()
1327 DoUndeleteCmd::~DoUndeleteCmd()
1331 // This is hooked up to the Close button in the Deleted Messages
1334 CloseUndelCmd::CloseUndelCmd(
1338 UndelFromListDialog *undelDialog
1339 ) : Cmd ( name, label, active )
1341 _undelDialog = undelDialog;
1345 CloseUndelCmd::doit()
1347 // Close the dialog.
1348 _undelDialog->popped_down();
1352 CloseUndelCmd::undoit()
1358 CloseUndelCmd::~CloseUndelCmd()
1362 UndeleteCmd::UndeleteCmd (
1366 RoamMenuWindow *window,
1367 Boolean viaDeleteList
1368 ) : ChooseCmd ( name, label, active, window )
1370 _menuwindow = window;
1371 _undelFromList = NULL;
1372 _fromList = viaDeleteList;
1375 UndeleteCmd::~UndeleteCmd()
1382 FORCE_SEGV_DECL(MsgStruct, tmpMS);
1383 MsgScrollingList *list = _menuwindow->list();
1384 MsgHndArray *deleted_messages;
1385 DtMailEnv mail_error;
1387 // Initialize the mail_error.
1392 // Create the Deleted Messages Dialog
1394 if (_undelFromList) {
1395 // Hack for user testing. If the dialog is up, we destroy it.
1396 XtDestroyWidget(_undelFromList->baseWidget());
1398 // if (!_undelFromList) {
1399 _undelFromList = new UndelFromListDialog(
1400 GETMSG(DT_catd, 1, 227, "Mailer - Deleted Messages"),
1402 _undelFromList->initialize();
1404 // Check for existing list of deleted messages
1405 _num_deleted = list->get_num_deleted_messages();
1407 // If there are deleted messages, put them in the Deleted
1410 if (_num_deleted > 0) {
1411 deleted_messages = list->get_deleted_messages();
1412 _undelFromList->loadMsgs(
1416 if (mail_error.isSet()) {
1417 // Post an exception here!
1418 _menuwindow->postErrorDialog(mail_error);
1422 // Display the dialog
1424 _undelFromList->popped_up();
1426 // Although we don't display the Deleted Message Dialog here, we
1427 // need to make sure that it gets updated for the next time
1429 list->undelete_last_deleted();
1435 SaveCmd::SaveCmd ( char *name,
1438 RoamMenuWindow *window
1439 ) : RoamCmd ( name, label, active, window )
1448 assert(_menuwindow->mailbox() != NULL);
1450 #endif /* DEAD_WOOD */
1454 MoveCopyCmd::MoveCopyCmd( char *name,
1457 FileCallback move_callback,
1458 FileCallback copy_callback,
1459 RoamMenuWindow * menu_window,
1461 DtMailBoolean only_show_mailboxes)
1462 : UnifiedSelectMailboxCmd(name,
1464 GETMSG(DT_catd, 1, 89, "Mailer - Other Mailboxes"),
1470 only_show_mailboxes)
1472 _copy_callback = copy_callback;
1473 _menuwindow = menu_window;
1474 _copy_button = NULL;
1475 _move_button = NULL;
1478 MoveCopyCmd::~MoveCopyCmd()
1483 MoveCopyCmd::setDefault(Widget button)
1487 _default_button = button;
1488 XtSetArg( args[0], XmNdefaultButton, _default_button );
1489 XtSetValues( _fileBrowser, args, 1 );
1496 Widget filter_button;
1497 Widget unused_button;
1501 if (!_fileBrowser) {
1502 UnifiedSelectMailboxCmd::doit();
1503 // Customize buttons for MoveCopy dialog
1504 move = XmStringCreateLocalized(GETMSG(DT_catd, 1, 90, "Move"));
1506 filter_button = XtNameToWidget(_fileBrowser, "*Apply");
1507 _move_button = XtNameToWidget(_fileBrowser, "*OK");
1508 action_area = XtParent(_move_button);
1509 unused_button = XtVaCreateWidget(
1511 xmPushButtonWidgetClass, _fileBrowser,
1513 _copy_button = XtVaCreateManagedWidget(
1514 GETMSG(DT_catd, 1, 237, "Copy"),
1515 /*xmPushButtonWidgetClass, _fileBrowser,*/
1516 xmPushButtonGadgetClass, _fileBrowser,
1518 XmStringCreateLocalized(GETMSG(DT_catd, 1, 43, "Copy")),
1520 printHelpId("Copy", _copy_button);
1522 // add help callback
1523 // XtAddCallback(_copy_button, XmNhelpCallback, HelpCB, helpId);
1529 "dtmailViewmainWindowWork-AreapanedWform2RowColumnMoveCopy");
1532 XmNactivateCallback,
1533 &MoveCopyCmd::fileSelectedCallback2,
1536 if (_menuwindow->mailbox()->mailBoxWritable(error) == DTM_FALSE)
1537 XtUnmanageChild(_move_button);
1539 XtManageChild(_move_button);
1541 // XtVaSetValues(_move_button, XmNsensitive, FALSE);
1543 _file_list = XtNameToWidget(_fileBrowser, "*ItemsList");
1546 XmNbrowseSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1550 XmNextendedSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1554 XmNmultipleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1558 XmNsingleSelectionCallback, &MoveCopyCmd::setDefaultButtonCB,
1561 _file_text = XtNameToWidget(_fileBrowser, "*Text");
1562 if (NULL != _file_text)
1565 XmNfocusCallback, &MoveCopyCmd::setDefaultButtonCB,
1571 UnifiedSelectMailboxCmd::doit();
1577 MoveCopyCmd::fileSelectedCallback2 (
1579 XtPointer clientData,
1583 MoveCopyCmd *obj = (MoveCopyCmd *) clientData;
1584 XmFileSelectionBoxCallbackStruct *cb =
1585 (XmFileSelectionBoxCallbackStruct *) callData;
1587 char *dir_str = NULL;
1593 static char selected[MAXPATHLEN+1];
1595 // Bring the file selection dialog down.
1596 XtUnmanageChild ( obj->_fileBrowser );
1599 // Get the file name
1601 XtVaGetValues(obj->_fileBrowser, XmNdirectory, &xmstr, NULL);
1603 dname = (char*) _XmStringUngenerate(
1605 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1608 // Get the file name
1610 XtVaGetValues(obj->_fileBrowser, XmNdirSpec, &xmstr, NULL);
1613 // Extract the first character string matching the default
1614 // character set from the compound string
1615 fname = (char *) _XmStringUngenerate(
1617 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
1619 if (NULL == fname || strlen(fname) == 0)
1622 // If a string was successfully extracted, call
1623 // unifiedMailboxSelected to handle the file.
1625 if (NULL != dname) strcat(selected, dname);
1626 strcat(selected, fname);
1627 obj->updateUnifiedData();
1628 obj->unifiedMailboxSelected(
1629 obj->_copy_callback,
1636 MoveCopyCmd::setDefaultButtonCB(
1638 XtPointer clientData,
1641 MoveCopyCmd *thisCmd = (MoveCopyCmd *) clientData;
1642 thisCmd->setDefault(thisCmd->_default_button);
1646 CopyCmd::CopyCmd( char *name,
1649 RoamMenuWindow *window,
1650 MoveCopyCmd *move_copy_cmd
1651 ) : RoamCmd ( name, label, active, window )
1653 _move_copy_cmd = move_copy_cmd;
1663 _move_copy_cmd->doit();
1664 _move_copy_cmd->setDefault(_move_copy_cmd->getCopyButton());
1668 MoveCmd::MoveCmd( char *name,
1671 RoamMenuWindow *window,
1672 MoveCopyCmd *move_copy_cmd
1673 ) : RoamCmd ( name, label, active, window )
1675 _move_copy_cmd = move_copy_cmd;
1685 _move_copy_cmd->doit();
1686 _move_copy_cmd->setDefault(_move_copy_cmd->getMoveButton());
1694 RoamMenuWindow *window
1695 ) : RoamCmd ( name, label, active, window )
1702 _menuwindow->list()->select_next_item();
1710 RoamMenuWindow *window
1711 ) : RoamCmd ( name, label, active, window )
1718 _menuwindow->list()->select_prev_item();
1722 MessagesCmd::MessagesCmd(
1726 RoamMenuWindow *window
1727 ) : RoamCmd ( name, label, active, window )
1735 Boolean old=_menuwindow->fullHeader();
1736 MsgScrollingList *list=_menuwindow->list();
1738 ( !strcmp( this->name(), "Full Header" ) ? _menuwindow->fullHeader( True ) : _menuwindow->fullHeader( False ) );
1740 if ( old!=_menuwindow->fullHeader() && _menuwindow->msgView() ) {
1741 // list->chooseCurrent();
1745 #endif /* DEAD_WOOD */
1747 PrintCmd::PrintCmd (
1752 RoamMenuWindow *window
1753 ) : ChooseCmd ( name, label, active, window ), _tmp_files(5)
1762 // The entire implementation of print was broken. It has
1763 // be removed until a proper implementation can be provided.
1772 DtActionInvocationID id,
1773 XtPointer clientData,
1782 case DtACTION_INVOKED:
1785 data = (PrintCmd *)clientData;
1786 data->_parent->message("");
1787 data->_unregister_tmp_file(id);
1795 PrintCmd::printjobcb( Widget w, XtPointer client_data, XtPointer )
1797 char *filename = (char *) client_data;
1799 XtRemoveCallback(w, XtNdestroyCallback, &PrintCmd::printjobcb, filename);
1806 PrintCmd::printit( int silent )
1809 char *silent_str = "DTPRINTSILENT";
1810 char *tmpdir = new char[MAXPATHLEN+1];
1811 DtMailEnv mail_error;
1812 MsgScrollingList *list;
1814 DebugPrintf(1, "%s: printit\n", name());
1817 sprintf(tmpdir, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
1818 if ((p = tempnam(tmpdir, "dtmail")) == NULL) {
1825 list = _parent->list();
1827 // Copy selected messages to a temp file
1828 int status = list->copySelected(mail_error, p, FALSE, TRUE);
1829 if (mail_error.isSet())
1831 _parent->postErrorDialog(mail_error);
1835 if (0 != status) return;
1838 DmxPrintJob *pjob = new DmxPrintJob(p,
1839 (silent ? DTM_TRUE : DTM_FALSE),
1842 XtAddCallback(pjob->baseWidget(),
1844 &PrintCmd::printjobcb,
1845 (XtPointer) strdup(p));
1853 PrintCmd::_register_tmp_file(
1855 DtActionInvocationID id
1860 // Allocate struct to hold id and temp file
1861 if ((f = (struct tmp_file *)malloc(sizeof(struct tmp_file))) == NULL) {
1865 // Save file name and action id
1866 f->file = strdup(name);
1869 // Add to list of temp files
1870 _tmp_files.append(f);
1876 PrintCmd::_unregister_tmp_file(
1877 DtActionInvocationID id
1883 // Find the temp file that was used by the Action specified by id
1884 for (n = _tmp_files.length() - 1; n >= 0; n--) {
1887 // Found the file. Unlink and free data structs
1891 // Remove entry from list
1892 _tmp_files.remove(n);
1901 PopupCmd::PopupCmd (
1905 PopupWindow * (RoamMenuWindow::* member) (void),
1906 RoamMenuWindow *myparent
1907 ) : NoUndoCmd ( name, label, active )
1916 PopupWindow *popup=(parent->*pmpopup)();
1919 #endif /* DEAD_WOOD */
1921 // OnItemCmd brings up the Help On Item help.
1922 OnItemCmd::OnItemCmd ( char * name,
1925 UIComponent *window )
1926 : NoUndoCmd (name, label, active)
1934 int status = DtHELP_SELECT_ERROR;
1935 Widget widget = _parent->baseWidget();
1936 Widget selWidget = NULL;
1938 // Display the appropriate help information for the selected item.
1940 status = DtHelpReturnSelectedWidgetId(widget, 0, &selWidget);
1942 switch ((int) status) {
1943 case DtHELP_SELECT_ERROR:
1944 printf("Selection Error, cannot continue\n");
1946 case DtHELP_SELECT_VALID:
1947 while (selWidget != NULL) {
1948 if ((XtHasCallbacks(selWidget, XmNhelpCallback)
1949 == XtCallbackHasSome)) {
1950 XtCallCallbacks((Widget) selWidget, XmNhelpCallback, NULL);
1953 selWidget = XtParent(selWidget);
1957 case DtHELP_SELECT_ABORT:
1958 printf("Selection Aborted by user.\n");
1960 case DtHELP_SELECT_INVALID:
1961 printf("You must select a component within your app.\n");
1970 OnAppCmd::OnAppCmd ( char * name,
1973 UIComponent *window )
1974 : NoUndoCmd (name, label, active)
1982 DisplayMain (_parent->baseWidget(), "Mailer", DTMAILWINDOWID);
1985 TasksCmd::TasksCmd ( char * name,
1988 UIComponent *window )
1989 : NoUndoCmd (name, label, active)
1997 DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_TASKS);
2000 ReferenceCmd::ReferenceCmd ( char * name,
2003 UIComponent *window )
2004 : NoUndoCmd (name, label, active)
2010 ReferenceCmd::doit()
2012 DisplayMain (_parent->baseWidget(), "Mailer", HELP_MAILER_REFERENCE);
2015 UsingHelpCmd::UsingHelpCmd ( char * name,
2018 UIComponent *window )
2019 : NoUndoCmd (name, label, active)
2025 UsingHelpCmd::doit()
2027 DisplayMain (_parent->baseWidget(), "Help4Help", "_HOMETOPIC");
2030 RelNoteCmd::RelNoteCmd ( char * name,
2034 ) : NoUndoCmd (name, label, active )
2046 // _genDialog = new DtMailGenDialog("AboutBox", _parent->baseWidget());
2048 // _genDialog->setToAboutDialog();
2049 // answer = _genDialog->post_and_return(GETMSG(DT_catd, 1, 92, "OK"), NULL);
2051 DisplayMain(_parent->baseWidget(), "Mailer", "_copyright");
2054 RelNoteCmd::~RelNoteCmd()
2060 ClearCmd::ClearCmd (
2064 RoamMenuWindow *window
2065 ) : NoUndoCmd (name, label, active )
2073 // ((FindPopup *) parent->find_popup())->clear_text_values();
2076 StartCmd::StartCmd( char *name,
2078 int active ) : Cmd ( name, label, active )
2085 char *forward= ".forward";
2088 GetPasswordEntry(pwd);
2090 char *forward_filename=new char[strlen(pwd.pw_dir)+1+strlen(forward)+1];
2091 sprintf( forward_filename, "%s/%s", pwd.pw_dir, forward );
2101 ChangeCmd::ChangeCmd(
2105 ) : Cmd (name, label, active )
2113 GetPasswordEntry(pwd);
2115 char *user_name=new char[strlen(pwd.pw_name)+1];
2116 strcpy(user_name,pwd.pw_name);
2131 RoamMenuWindow *window
2132 ) : Cmd (name, label, active )
2140 unlink( parent->forwardFilename() );
2141 parent->title( NULL );
2150 #endif /* DEAD_WOOD */
2158 SendMsgDialog *parent,
2160 : NoUndoCmd( name, label, active )
2163 _default_trans = trans_type;
2169 if (!_parent->isMsgValid())
2172 _parent->send_message( this->name(), _default_trans );
2175 // JT - Added methods below
2177 OpenMsgCmd::OpenMsgCmd(
2181 RoamMenuWindow *window)
2182 : RoamCmd (name, label, active, window)
2189 DtMailEnv mail_error;
2191 // Initialize the mail_error.
2194 _menuwindow->list()->viewInSeparateWindow(mail_error);
2195 if (mail_error.isSet()) {
2196 _menuwindow->postErrorDialog(mail_error);
2201 // Attachment Cmds stuff
2203 SaveAttachCmd::SaveAttachCmd ( char *name,
2207 FileCallback save_callback,
2208 RoamMenuWindow *clientData,
2210 :UnifiedSelectFileCmd (name,
2213 GETMSG(DT_catd, 1, 93, "Save"),
2219 _parent = clientData;
2222 SaveAttachCmd::SaveAttachCmd (
2227 FileCallback save_callback,
2228 ViewMsgDialog *clientData,
2231 :UnifiedSelectFileCmd (name,
2234 GETMSG(DT_catd, 1, 93, "Save"),
2240 _parent = clientData;
2243 SaveAttachCmd::SaveAttachCmd (
2248 FileCallback save_callback,
2249 SendMsgDialog *clientData,
2252 :UnifiedSelectFileCmd (name,
2255 GETMSG(DT_catd, 1, 93, "Save"),
2261 _parent = clientData;
2265 SaveAttachCmd::doit()
2267 UnifiedSelectFileCmd::doit();
2269 DtMailEditor *editor = _parent->get_editor();
2270 AttachArea *aa = editor->attachArea();
2271 XmString attachmentName = aa->getSelectedAttachName();
2272 XtVaSetValues(_fileBrowser, XmNtextString, attachmentName, NULL);
2273 XtAddCallback ( _fileBrowser, XmNapplyCallback,
2274 &SaveAttachCmd::updateCallback,
2277 _name = XmStringCopy(attachmentName);
2278 XmStringFree(attachmentName);
2281 // Attachment Cmds stuff
2284 void SaveAttachCmd::updateCallback(Widget, XtPointer clientData, XtPointer )
2286 SaveAttachCmd *obj = (SaveAttachCmd *)clientData;
2288 XtVaSetValues(obj->_fileBrowser, XmNtextString, obj->_name, NULL);
2291 SaveAsTextCmd::SaveAsTextCmd (
2297 RoamMenuWindow *parent_roam_menu_window,
2300 :UnifiedSelectFileCmd (name,
2303 GETMSG(DT_catd, 1, 95, "Save"),
2309 _text_editor = editor;
2310 _roam_menu_window = parent_roam_menu_window;
2313 SaveAsTextCmd::SaveAsTextCmd (
2322 :UnifiedSelectFileCmd (name,
2325 GETMSG(DT_catd, 1, 95, "Save"),
2331 _text_editor = editor;
2332 _roam_menu_window = NULL;
2336 SaveAsTextCmd::fileCB(void * client_data, char * selection)
2338 SaveAsTextCmd * self = (SaveAsTextCmd *)client_data;
2339 self->saveText(selection);
2343 SaveAsTextCmd::saveText(const char * filename)
2346 char *buf = new char[2048];
2349 // Is it already there?
2350 status = SafeAccess(filename, F_OK);
2354 GETMSG(DT_catd, 3, 47, "%s already exists.\nOverwrite?"),
2357 _genDialog->setToQuestionDialog(GETMSG(DT_catd, 3, 48, "Mailer"), buf);
2358 helpId = DTMAILHELPERROR;
2359 answer = _genDialog->post_and_return(helpId);
2365 if (unlink(filename) < 0)
2368 GETMSG(DT_catd, 3, 49, "Unable to overwrite %s.\n\
2369 Check file permissions and retry."),
2371 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 50, "Mailer"), buf);
2372 helpId = DTMAILHELPNOOVERWRITE;
2373 _genDialog->post_and_return(helpId);
2379 // Create or truncate, and then write the bits.
2380 int fd = SafeOpen(filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
2383 sprintf(buf, GETMSG(DT_catd, 3, 51, "Unable to create %s."), filename);
2384 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
2385 helpId = DTMAILHELPNOCREATE;
2386 _genDialog->post_and_return(helpId);
2391 if (SafeWrite(fd, "\n", 1) < 1)
2394 GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
2396 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 54, "Mailer"), buf);
2397 helpId = DTMAILHELPNOWRITE;
2398 _genDialog->post_and_return(helpId);
2405 if (NULL == _roam_menu_window)
2407 char *text_buf = _text_editor->get_contents();
2408 writeText((XtPointer) fd, text_buf);
2409 XtFree((char*) text_buf);
2412 writeTextFromScrolledList(fd);
2419 SaveAsTextCmd::writeTextFromScrolledList(int fd)
2421 static char buf[2048];
2424 DtMailEnv mail_error;
2425 MsgScrollingList *list;
2426 DmxMailbox *mailbox;
2430 // Create temp file.
2432 char *tmpdir = new char[MAXPATHLEN+1];
2433 sprintf(tmpdir, "%s/%s", getenv("HOME"), DtPERSONAL_TMP_DIRECTORY);
2434 if ((tmppath = tempnam(tmpdir, "dtmail")) == NULL) {
2435 sprintf(buf, GETMSG(DT_catd, 3, 51, "Unable to create %s."), tmpdir);
2436 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 52, "Mailer"), buf);
2437 helpId = DTMAILHELPNOCREATE;
2438 _genDialog->post_and_return(helpId);
2445 list = _roam_menu_window->list();
2448 // Copy the selected messages to a temp file.
2450 int status = list->copySelected(mail_error, tmppath, FALSE, TRUE);
2451 if (mail_error.isSet()) {
2452 _roam_menu_window->postErrorDialog(mail_error);
2456 if (0 != status) return;
2458 mailbox = new DmxMailbox(tmppath);
2459 mailbox->loadMessages();
2460 next_msg = mailbox->firstMessage();
2463 DmxPrintHeadersEnum visible_headers;
2465 if (_roam_menu_window->fullHeader())
2466 visible_headers = DMX_PRINT_HEADERS_ALL;
2468 visible_headers = DMX_PRINT_HEADERS_ABBREV;
2472 &SaveAsTextCmd::writeText,
2474 writeText((XtPointer) fd, "\n\n");
2475 } while ((next_msg = mailbox->nextMessage()) != (DmxMsg *) NULL);
2479 // Clean up the temporary file.
2486 SaveAsTextCmd::writeText(XtPointer filedes, char *text_buf)
2488 long fdl = (long) filedes;
2490 int len = strlen(text_buf);
2492 if (SafeWrite(fd, text_buf, len) < len) {
2499 GETMSG(DT_catd, 3, 53, "Unable to write to %s."),
2501 helpId = DTMAILHELPNOWRITE;
2502 _genDialog->setToErrorDialog(GETMSG(DT_catd, 3, 56, "Mailer"), buf);
2503 _genDialog->post_and_return(helpId);
2509 SaveAsTextCmd::doit()
2511 MsgScrollingList *list;
2513 int *pos_list = NULL;
2516 if (_roam_menu_window &&
2517 (list = _roam_menu_window->list()) &&
2518 (listW = list->get_scrolling_list()))
2520 if (!XmListGetSelectedPos(listW, &pos_list, &pos_count))
2525 DtMailGenDialog *dialog = _roam_menu_window->genDialog();
2527 dialog->setToErrorDialog(
2528 GETMSG(DT_catd, 3, 50, "Mailer"),
2529 GETMSG(DT_catd, 2, 16, "No message selected."));
2530 dialog->post_and_return(NULL);
2536 UnifiedSelectFileCmd::doit();
2540 int pos_selected, last_space;
2542 DtMailHeaderLine header;
2543 DtMailMessageHandle msg_handle;
2544 DtMailHeaderRequest request;
2545 DtMail::MailBox *mbox;
2547 pos_selected = list->get_selected_item();
2548 msg_handle = list->msgno(pos_selected);
2550 request.number_of_names = 1;
2551 request.header_name = (char**) malloc(sizeof(char*));
2552 request.header_name[0] = strdup(DtMailMessageSubject);
2554 mbox = _roam_menu_window->mailbox();
2555 mbox->getMessageSummary(error, msg_handle, request, header);
2557 if (0 != header.header_values[0].length())
2559 const char *orig_subject = *((header.header_values[0])[0]);
2561 int orig_len = strlen(orig_subject);
2562 char *subject = (char*) malloc(orig_len + 1);
2565 for (i=0,j=0,last_space=0; i<orig_len; i++)
2567 if (isspace(orig_subject[i]))
2569 if (last_space < i-1)
2574 else if (orig_subject[i] == '/')
2575 subject[j++] = '\\';
2577 subject[j++] = orig_subject[i];
2581 xms = XmStringCreateLocalized(subject);
2582 XtVaSetValues(_fileBrowser, XmNtextString, xms, NULL);
2588 if (NULL != request.header_name)
2590 if (NULL != request.header_name[0])
2591 free(request.header_name[0]);
2592 free(request.header_name);
2595 mbox->clearMessageSummary(header);
2600 DeleteAttachCmd::DeleteAttachCmd(
2606 ) : Cmd ( name, label, active )
2612 DeleteAttachCmd::doit()
2614 _parent->delete_selected_attachments();
2618 DeleteAttachCmd::undoit()
2622 UndeleteAttachCmd::UndeleteAttachCmd(
2628 ) : Cmd ( name, label, active )
2634 UndeleteAttachCmd::doit()
2636 _parent->undelete_last_deleted_attachment();
2641 UndeleteAttachCmd::undoit()
2645 RenameAttachCmd::RenameAttachCmd (
2650 ) : Cmd ( name, label, active )
2652 Widget renameDialog;
2656 renameDialog = XmCreatePromptDialog(
2663 message = XmStringCreateLocalized(GETMSG(DT_catd, 1, 96, "Empty"));
2664 XtVaSetValues(renameDialog, XmNselectionLabelString, message, NULL);
2665 XmStringFree(message);
2666 XmString ok_str = XmStringCreateLocalized(GETMSG(DT_catd, 1, 97, "Rename"));
2667 XtVaSetValues(XtParent(renameDialog),
2668 XmNtitle, GETMSG(DT_catd, 1, 98, "Mailer - Rename"),
2670 XtVaSetValues(renameDialog,
2671 XmNokLabelString, ok_str,
2674 XmStringFree(ok_str);
2675 XtUnmanageChild(XmSelectionBoxGetChild(renameDialog, XmDIALOG_HELP_BUTTON));
2677 _parent->get_editor()->attachArea()->setRenameDialog(renameDialog);
2678 XtAddCallback(renameDialog, XmNcancelCallback,
2679 &RenameAttachCmd::cancelCallback,
2681 XtAddCallback(renameDialog, XmNokCallback,
2682 &RenameAttachCmd::okCallback,
2686 void RenameAttachCmd::doit()
2688 Widget renameDialog;
2689 XmString oldAttachName = NULL;
2694 if (!_parent->renameAttachmentOK()) {
2698 aa = _parent->get_editor()->attachArea();
2700 oldAttachName = aa->getSelectedAttachName();
2702 if (oldAttachName == NULL) return;
2704 renameDialog = aa->getRenameDialog();
2706 sprintf(buf, GETMSG(DT_catd, 3, 57, "Rename attachment as"));
2708 message = XmStringCreateLocalized(buf);
2710 XtVaSetValues(renameDialog,
2711 XmNselectionLabelString, message,
2712 XmNtextString, oldAttachName,
2716 XmStringFree(message);
2717 XmStringFree(oldAttachName);
2719 XtManageChild(renameDialog);
2720 XtPopup(XtParent(renameDialog), XtGrabNone);
2723 void RenameAttachCmd::undoit()
2725 // Just print a message that allows us to trace the execution
2729 void RenameAttachCmd::cancelCallback (
2731 XtPointer clientData,
2735 RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
2737 obj->cancel( callData );
2740 void RenameAttachCmd::cancel( XtPointer )
2744 aa = _parent->get_editor()->attachArea();
2746 Widget renameDialog = aa->getRenameDialog();
2748 XtUnmanageChild(renameDialog);
2751 void RenameAttachCmd::okCallback (
2753 XtPointer clientData,
2757 RenameAttachCmd *obj = (RenameAttachCmd *) clientData;
2758 obj->ok( callData );
2761 void RenameAttachCmd::ok( XtPointer callData )
2763 XmSelectionBoxCallbackStruct *cbs =
2764 (XmSelectionBoxCallbackStruct *)callData;
2767 aa = _parent->get_editor()->attachArea();
2769 Widget renameDialog = aa->getRenameDialog();
2771 XtUnmanageChild(renameDialog);
2773 aa->setSelectedAttachName(cbs->value);
2777 AttachmentActionCmd::AttachmentActionCmd(
2780 RoamMenuWindow *rmw,
2782 ) : Cmd (name, label, TRUE)
2789 AttachmentActionCmd::AttachmentActionCmd(
2794 ) : Cmd (name, label, TRUE)
2801 AttachmentActionCmd::AttachmentActionCmd(
2806 ) : Cmd (name, label, TRUE)
2815 AttachmentActionCmd::doit()
2817 _parent->invokeAttachmentAction(_index);
2821 AttachmentActionCmd::undoit()
2825 SelectAllAttachsCmd::SelectAllAttachsCmd(
2829 ) : Cmd(name, label, TRUE)
2834 SelectAllAttachsCmd::SelectAllAttachsCmd(
2838 ) : Cmd(name, label, TRUE)
2843 SelectAllAttachsCmd::SelectAllAttachsCmd(
2847 ) : Cmd(name, label, FALSE)
2853 SelectAllAttachsCmd::doit()
2855 _parent->selectAllAttachments();
2859 SelectAllAttachsCmd::undoit()
2864 ShowAttachPaneCmd::ShowAttachPaneCmd(
2867 AbstractEditorParent *aep
2868 ) : ToggleButtonCmd(name, label, TRUE)
2874 ShowAttachPaneCmd::doit()
2877 if (!this->getButtonState()) {
2878 _parent->hideAttachArea();
2880 else { // button is ON
2881 _parent->showAttachArea();
2886 ShowAttachPaneCmd::undoit()
2891 AbbrevHeadersCmd::AbbrevHeadersCmd(
2895 ) : ToggleButtonCmd(name, label, TRUE)
2901 AbbrevHeadersCmd::doit()
2904 if (!this->getButtonState()) {
2905 _parent->fullHeader(TRUE);
2907 else { // button is ON
2908 _parent->fullHeader(FALSE);
2913 AbbrevHeadersCmd::undoit()
2924 : NoUndoCmd(name, label, active)
2926 _compose_dialog = s;
2933 // Call the goAway() method on the SMD. Argument TRUE requests it
2934 // to check if the SMD is dirty. Let it handle the
2935 // case where text may be present in the compose window.
2936 if (!_compose_dialog->isMsgValid())
2939 _compose_dialog->goAway(TRUE);
2943 EditUndoCmd::EditUndoCmd(
2947 AbstractEditorParent *w )
2948 : NoUndoCmd( name, label, active )
2950 editor = w->get_editor()->textEditor();
2956 editor->undo_edit();
2959 EditCutCmd::EditCutCmd(
2963 AbstractEditorParent *w
2965 : NoUndoCmd( name, label, active )
2967 editor = w->get_editor()->textEditor();
2969 // className() is a virtual method
2970 if (w->className() == "SendMsgDialog") {
2971 _compose_dialog = (SendMsgDialog *)w;
2974 _compose_dialog = NULL;
2981 editor->cut_selection();
2983 if (_compose_dialog) {
2985 _compose_dialog->activate_edit_paste();
2986 _compose_dialog->activate_edit_paste_indented();
2987 _compose_dialog->activate_edit_paste_bracketed();
2991 EditCopyCmd::EditCopyCmd(
2995 AbstractEditorParent *w )
2996 : NoUndoCmd( name, label, active )
2998 editor = w->get_editor()->textEditor();
3000 // className() is a virtual method
3001 if (w->className() == "SendMsgDialog") {
3002 _compose_dialog = (SendMsgDialog *)w;
3005 _compose_dialog = NULL;
3012 editor->copy_selection();
3013 if (_compose_dialog) {
3015 _compose_dialog->activate_edit_paste();
3016 _compose_dialog->activate_edit_paste_indented();
3017 _compose_dialog->activate_edit_paste_bracketed();
3021 EditPasteCmd::EditPasteCmd(
3025 AbstractEditorParent *w )
3026 : NoUndoCmd( name, label, active )
3028 editor = w->get_editor()->textEditor();
3032 EditPasteCmd::doit()
3034 editor->paste_from_clipboard();
3037 EditPasteSpecialCmd::EditPasteSpecialCmd(
3041 AbstractEditorParent *w,
3042 Editor::InsertFormat format)
3043 : NoUndoCmd( name, label, active )
3045 editor = w->get_editor()->textEditor();
3046 insert_format = format;
3050 EditPasteSpecialCmd::doit()
3052 editor->paste_special_from_clipboard(insert_format);
3056 EditClearCmd::EditClearCmd(
3060 AbstractEditorParent *w )
3061 : NoUndoCmd( name, label, active )
3063 editor = w->get_editor()->textEditor();
3064 // this->deactivate();
3068 EditClearCmd::doit()
3070 editor->clear_selection();
3072 // _edit_paste->activate();
3075 EditDeleteCmd::EditDeleteCmd(
3079 AbstractEditorParent *w )
3080 : NoUndoCmd( name, label, active )
3082 editor = w->get_editor()->textEditor();
3083 // this->deactivate();
3087 EditDeleteCmd::doit()
3089 editor->delete_selection();
3091 // _edit_paste->deactivate();
3094 EditSelectAllCmd::EditSelectAllCmd(
3098 AbstractEditorParent *w )
3099 : NoUndoCmd( name, label, active )
3101 editor = w->get_editor()->textEditor();
3105 EditSelectAllCmd::doit()
3107 editor->select_all();
3112 WordWrapCmd::WordWrapCmd(
3116 AbstractEditorParent *w
3117 ) : ToggleButtonCmd( name, label, active )
3119 editor = w->get_editor()->textEditor();
3121 * allow the app-defaults setting for WordWrap
3124 Widget _w = editor->get_text_widget();
3127 XtSetArg( args[0], XmNwordWrap, &cur_setting );
3128 XtGetValues( _w, args, 1 );
3129 editor->set_word_wrap(cur_setting);
3135 cur_setting = ((ToggleButtonCmd *)this)->getButtonState();
3136 editor->set_word_wrap(cur_setting);
3140 WordWrapCmd::wordWrap()
3142 return(cur_setting);
3145 FindChangeCmd::FindChangeCmd(
3149 AbstractEditorParent *w )
3150 : NoUndoCmd( name, label, active )
3152 editor = w->get_editor()->textEditor();
3156 FindChangeCmd::doit()
3158 editor->find_change();
3165 AbstractEditorParent *w )
3166 : NoUndoCmd( name, label, active )
3168 editor = w->get_editor()->textEditor();
3182 : NoUndoCmd (name, label, active)
3185 _alias = strdup(name);
3193 XtVaGetValues(_header, XmNvalue, &value, NULL);
3197 char *newvalue = (char *) malloc(strlen(value) + strlen(_alias) + 3);
3198 sprintf(newvalue, "%s, %s", value, _alias);
3199 XtVaSetValues(_header, XmNvalue, newvalue, NULL);
3203 XtVaSetValues(_header, XmNvalue, _alias, NULL);
3208 AliasCmd::~AliasCmd()
3210 free((void*) _alias);
3214 OtherAliasesCmd::OtherAliasesCmd(
3218 : NoUndoCmd (name, label, active)
3223 OtherAliasesCmd::doit()
3225 OptCmd *optCmd = (OptCmd *) theRoamApp.mailOptions();
3226 optCmd->displayAliasesOptionsPane();
3229 OtherAliasesCmd::~OtherAliasesCmd()
3234 FormatCmd::FormatCmd(
3238 AbstractEditorParent *w )
3239 : NoUndoCmd( name, label, active )
3241 editor = w->get_editor()->textEditor();
3250 LogMsgCmd::LogMsgCmd(
3254 SendMsgDialog * send
3255 ) : ToggleButtonCmd( name, label, active )
3257 // Go to props and find out the default, ie. to log or not to log.
3258 // But for now, just look in .mailrc to see if "record" is set.
3261 const char *logfile = NULL;
3270 if (!((ToggleButtonCmd *)this)->getButtonState()) {
3271 // turn off logging for this message
3272 _send->setLogState(DTM_FALSE);
3275 // turn on logging for this message
3276 _send->setLogState(DTM_TRUE);
3282 VacationCmd::VacationCmd(
3285 ) : Cmd (name, label, TRUE)
3288 _forwardFile = ".forward";
3289 _backupSuffix = "..BACKUP";
3295 // Check if a .forward file exists.
3297 _priorVacationRunning = this->priorVacationRunning();
3299 // parse the .vacation.msg file and retain the subject
3301 // They need to be retrieved for display in the dialog.
3303 this->parseVacationMessage();
3307 VacationCmd::~VacationCmd()
3309 if (NULL != _subject)
3310 free((void*) _subject);
3321 static unsigned long
3322 writeToFileDesc(const char * buf, int len, va_list args)
3324 int fd = va_arg(args, int);
3325 int cnt = va_arg(args, int);
3329 status = SafeWrite(fd, buf, len);
3330 } while (status < 0 && errno == EAGAIN);
3336 VacationCmd::startVacation(
3341 int i = this->handleMessageFile(subj, text);
3343 i = this->handleForwardFile();
3350 VacationCmd::stopVacation()
3352 char *forwardfile = new char[MAXPATHLEN+1];
3354 sprintf(forwardfile, "%s/%s", getenv("HOME"), _forwardFile);
3356 // Remove the current .forward file (it has vacation in it)
3357 // Recover and replace the original backup forward file, if
3360 unlink(forwardfile);
3362 this->recoverForwardFile(forwardfile);
3363 delete [] forwardfile;
3367 VacationCmd::priorVacationRunning()
3372 Boolean retval = FALSE;
3373 char *forwardfile = new char[MAXPATHLEN+1];
3375 sprintf(forwardfile, "%s/%s", getenv("HOME"), _forwardFile);
3377 if (SafeAccess(forwardfile, F_OK) != 0) {
3378 delete [] forwardfile;
3382 fd = SafeOpen(forwardfile, O_RDONLY);
3384 buf[sizeof buf -1] = '\0';
3386 while ((len = SafeRead(fd, buf, (sizeof buf) - 1)) > 0) {
3388 if ((strstr(buf, "/usr/bin/vacation")) ||
3389 (strstr(buf, "/usr/ucb/vacation"))) {
3397 delete [] forwardfile;
3402 VacationCmd::handleForwardFile()
3412 Boolean forwardExists;
3413 DtMailGenDialog *dialog;
3415 int error_bufLen = 10000;
3416 char *error_buf = new char[error_bufLen];
3417 char *forwardfile = new char[MAXPATHLEN+1];
3418 char *messagefile = new char[256];
3419 char *buf = new char[2048];
3421 // initialize the error_buf
3422 memset(error_buf, 0, error_bufLen);
3423 memset(buf, 0, 2048);
3427 forwardExists = FALSE;
3430 GetPasswordEntry(pw);
3432 sprintf(forwardfile, "%s/%s", pw.pw_dir, _forwardFile);
3434 if (SafeAccess(forwardfile, F_OK) == 0 ) {
3435 forwardExists = TRUE;
3438 forwardExists = FALSE;
3441 if (forwardExists && !_priorVacationRunning) {
3443 /* STRING_EXTRACTION -
3445 * This confirmation window is brought up when the user
3446 * tries to update the vacation status when the user is
3447 * already using a .forward file.
3449 if (NULL != _dialog)
3452 dialog = theRoamApp.genDialog();
3454 sprintf(error_buf, GETMSG(DT_catd, 1, 102, "You are already using the forwarding facility for\nsomething other than Vacation. While Vacation is\nrunning, Vacation will be appended to this other\nforwarding activity. Is it still OK to start Vacation?\0"));
3456 dialog->setToQuestionDialog(GETMSG(DT_catd, 1, 103, "Mailer"),
3459 helpId = DTMAILHELPOKSTARTVACATION;
3460 answer = dialog->post_and_return(helpId);
3462 if (answer == 2) {// Cancel chosen
3464 delete [] messagefile;
3465 delete [] error_buf;
3466 delete [] forwardfile;
3470 if (this->backupFile(forwardfile) < 0) {
3472 delete [] messagefile;
3473 delete [] error_buf;
3474 delete [] forwardfile;
3478 /* A .forward file is currently in use. Merge vacation
3479 * into this file, rather than overwrite it. To do so,
3480 * set the appropriate variable to indicate mode.
3483 _priorVacationRunning = TRUE;
3485 // Turn on the bit to indicate we are currently using a .forward
3488 else if (forwardExists && _priorVacationRunning) {
3490 /* STRING_EXTRACTION -
3492 * This confirmation window is brought up when the user
3493 * tries to update the vacation status when the user is
3494 * already using a .forward file.
3497 if (NULL != _dialog)
3500 dialog = theRoamApp.genDialog();
3502 sprintf(error_buf, GETMSG(DT_catd, 1, 104, "You are already running the vacation program in your .forward file.\nConsult documentation on how to stop it and remove it from your .forward file.\nTry this command after fixing that problem.\0"));
3504 dialog->setToErrorDialog("Error", error_buf);
3505 helpId = DTMAILHELPREMOVEVACATION;
3506 answer = dialog->post_and_return(helpId);
3509 delete [] messagefile;
3510 delete [] error_buf;
3511 delete [] forwardfile;
3516 // Re-initialize the error_buf
3517 memset(error_buf, 0, error_bufLen);
3519 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
3521 if (forwardExists) {
3522 fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_APPEND | O_CREAT);
3525 fwd_fd = SafeOpen(forwardfile, O_WRONLY | O_CREAT);
3528 if (fwd_fd < 0 ) {// If fwdfile is not writable/appendable
3530 // Put up error dialog indicating fwdfile not writable
3531 /* restore the original .forward file */
3533 this->recoverForwardFile(forwardfile);
3535 delete [] messagefile;
3536 delete [] error_buf;
3537 delete [] forwardfile;
3541 SafeFChmod(fwd_fd, 0644);
3543 // Make buf be forwardfile._backupSuffix.
3544 // Then create a backup file of name buf
3546 strcpy(buf, forwardfile);
3547 strcat(buf, _backupSuffix);
3549 // If we are currently using a .forward then we need to append/prepend
3550 // the vacation command
3554 /* CREATE NEW .forward FILE
3556 * The original .forward file has been renamed to the
3557 * backup file name. We need to open the backup .forward
3558 * file so we can copy from it.
3561 if ((bkup_fd = SafeOpen(buf, O_RDONLY)) < 0) {
3562 /* restore the original .forward file */
3564 this->recoverForwardFile(forwardfile);
3566 delete [] messagefile;
3567 delete [] error_buf;
3568 delete [] forwardfile;
3572 /* COPY OLD .forward TO NEW .forward
3574 * Using mmap is quite fast, so rather than do a while
3575 * loop to copy line by line, we'll use mmap followed by
3579 fsize= (int)lseek(bkup_fd, 0, SEEK_END);
3583 (caddr_t) mmap(0, fsize, PROT_READ, MAP_PRIVATE, bkup_fd, 0);
3586 if (fwdptr == (char *)-1) {
3589 delete [] messagefile;
3590 delete [] error_buf;
3591 delete [] forwardfile;
3597 if (SafeWrite(fwd_fd, fwdptr, fsize) < fsize) {
3600 delete [] messagefile;
3601 delete [] error_buf;
3602 delete [] forwardfile;
3607 /* RELEASE .forward FILE
3609 * Un-mmap the new .forward file
3612 lastchar = fwdptr[fsize-1];
3613 munmap(fwdptr, fsize);
3618 /* APPEND VACATION LINE
3620 * The new .forward file is still open, so append the
3621 * new line below as the last line of the .forward file.
3622 * Check to make sure last character in the file is a
3623 * newline. If it's not, add one so our work goes on
3627 if (lastchar != '\n') {
3628 lseek(fwd_fd, 0, SEEK_END);
3630 if (SafeWrite(fwd_fd, txt, strlen(txt)) < strlen(txt)) {
3633 delete [] messagefile;
3634 delete [] error_buf;
3635 delete [] forwardfile;
3642 * Now, add the vacation line to the next line.
3644 char *append_buf1 = new char[1024*2];
3645 sprintf(append_buf1, "|\" /usr/bin/vacation %s\"\n", pw.pw_name);
3647 if (SafeWrite(fwd_fd, append_buf1, strlen(append_buf1)) <
3648 strlen(append_buf1)) {
3651 delete [] messagefile;
3652 delete [] error_buf;
3653 delete [] forwardfile;
3654 delete [] append_buf1;
3658 delete [] append_buf1;
3663 /* Create known backup file. The known backup
3664 * file allows mailtool to differentiate between
3665 * vacation being started from mailtool, and vacation
3666 * being invoked (the Unix program as opposed to the
3667 * MailTool Vacation menu item) via tty session.
3670 if (!forwardExists) {
3672 if ((bkup_fd = SafeOpen(buf, O_WRONLY | O_APPEND | O_CREAT)) < 0) {
3673 /* restore the original .forward file */
3675 this->recoverForwardFile(forwardfile);
3677 delete [] messagefile;
3678 delete [] error_buf;
3679 delete [] forwardfile;
3684 char *end_text = "User not using forward file\n";
3686 if (SafeWrite(bkup_fd, end_text, strlen(end_text)) <
3690 delete [] messagefile;
3691 delete [] error_buf;
3692 delete [] forwardfile;
3698 if (!forwardExists) {
3700 /* WRITE NEW .forward FILE
3702 * There was no .forward file, so no appending
3703 * must be done. Simply write the standard
3704 * vacation line into the new .forward file.
3707 char *append_buf2 = new char[1024*2];
3709 sprintf(append_buf2, "\\%s, |\" /usr/bin/vacation %s\"\n",
3710 pw.pw_name, pw.pw_name);
3711 if (SafeWrite(fwd_fd, append_buf2, strlen(append_buf2)) <
3712 strlen(append_buf2)) {
3716 delete [] messagefile;
3717 delete [] error_buf;
3718 delete [] forwardfile;
3719 delete [] append_buf2;
3722 delete [] append_buf2;
3728 system("/usr/bin/vacation -I");
3731 delete [] messagefile;
3732 delete [] error_buf;
3733 delete [] forwardfile;
3738 VacationCmd::backupFile(
3742 char *buf = new char[MAXPATHLEN+1];
3745 strcat(buf, _backupSuffix);
3747 if (rename(file, buf) < 0) {
3748 /* STRING_EXTRACTION -
3750 * We tried to make a backup copy of your .forward file, but
3751 * it failed. The first %s is the name of the rename
3752 * target; the second %s is the system error string.
3755 // Put up error dialog
3765 VacationCmd::recoverForwardFile(
3769 char *buf = new char[BUFSIZ+1];
3773 strcat(buf, _backupSuffix);
3775 if (rename(buf, file) < 0) {
3777 /* STRING_EXTRACTION -
3779 * We tried to restore your original .forward file, but could
3780 * not. The first %s is the name of the original .forward file,
3781 * the second %s is the the system error string.
3784 // Handle dialog indicating error in recovering .forward file.
3785 // Error usually caused by starting /usr/bin/vacation outside
3792 if ((fd = SafeOpen(file, O_RDONLY)) == 0) {
3797 buf[sizeof file -1] = '\0';
3798 while (SafeRead(fd, buf, BUFSIZ) != 0) {
3799 if (strstr(buf, "User not using forward file")) {
3812 VacationCmd::subject()
3822 return((char *)_body);
3830 VacationCmd::parseVacationMessage()
3835 DtMailGenDialog *dialog;
3838 char dialog_text[1024*4];
3840 DtMail::Session * d_session = theRoamApp.session()->session();
3843 if (NULL != _dialog)
3846 dialog = theRoamApp.genDialog();
3848 GetPasswordEntry(pw);
3850 char *messagefile = new char[MAXPATHLEN+1];
3851 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
3853 // See if the messagefile exists.
3854 // If it doesn't create one and throw in the text found in the
3855 // properties sheet. If no text found, use default template.
3857 char * fullpath = d_session->expandPath(error, messagefile);
3858 delete [] messagefile;
3861 // Map the file and try to parse it as a message. If it is a message,
3862 // then load it with headers. Otherwise, throw everything into the
3866 fd = SafeOpen(fullpath, O_RDONLY);
3869 if (fd < 0) {// File doesn't exist
3877 if (SafeFStat(fd, &buf) < 0) {
3879 sprintf(dialog_text,
3880 GETMSG(DT_catd, 1, 105, "Cannot open .vacation.msg file -- No write permission."));
3881 dialog->setToQuestionDialog("Mailer", dialog_text);
3882 helpId = DTMAILHELPNOWRITEVACATION;
3883 answer = dialog->post_and_return(helpId);
3892 int page_size = (int)sysconf(_SC_PAGESIZE);
3893 size_t map_size = (int) (buf.st_size +
3894 (page_size - (buf.st_size % page_size)));
3896 if (buf.st_size == 0)
3900 mbuf.size = buf.st_size;
3902 mbuf.buffer = (char *)mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
3904 mbuf.buffer = mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0);
3906 if (mbuf.buffer == (char *)-1) {
3908 mbuf.buffer = new char[mbuf.size];
3909 if (mbuf.buffer == NULL) {
3910 dialog->setToErrorDialog(GETMSG(DT_catd, 3, 59, "No Memory"),
3911 GETMSG(DT_catd, 3, 60, "There is not enough memory to load the existing .vacation.msg file."));
3912 helpId = DTMAILHELPNOLOADVACATION;
3913 answer = dialog->post_and_return(helpId);
3922 if (SafeRead(fd, mbuf.buffer, (unsigned int)mbuf.size) < mbuf.size) {
3923 dialog->setToErrorDialog(GETMSG(DT_catd, 3, 61, "Mailer"),
3924 GETMSG(DT_catd, 3, 62, "The existing .vacation.msg file appears to be corrupt."));
3925 helpId = DTMAILHELPCORRUPTVACATION;
3926 answer = dialog->post_and_return(helpId);
3928 delete [] mbuf.buffer;
3936 // Now we ask the library to parse it. If this fails for any reason, this
3937 // is not a message, so we give up.
3939 DtMail::Message * msg = d_session->messageConstruct(error,
3947 if (error.isSet()) {
3954 DtMail::Envelope * env = msg->getEnvelope(error);
3955 DtMailHeaderHandle hnd;
3959 DtMailValueSeq value;
3961 for (hnd = env->getFirstHeader(error, &name, value);
3962 error.isNotSet() && hnd;
3963 hnd = env->getNextHeader(error, hnd, &name, value)) {
3965 if (!strcmp(name, "Subject") == 0) {
3971 for (int slen = 0; slen < value.length(); slen++) {
3972 max_len += strlen(*(value[slen]));
3975 char * new_str = new char[max_len + (value.length() * 3)];
3977 strcpy(new_str, "");
3978 for (int copy = 0; copy < value.length(); copy++) {
3980 strcat(new_str, " ");
3983 strcat(new_str, *(value[copy]));
3986 _subject = strdup(new_str);
3994 DtMail::BodyPart * bp = msg->getFirstBodyPart(error);
3995 if (error.isNotSet()) {
3996 unsigned long length;
3998 bp->getContents(error,
4008 // Avoid a memory leak.
4016 VacationCmd::handleMessageFile(
4023 DtMailGenDialog *dialog;
4026 char dialog_text[1024*4];
4027 Boolean text_changed = FALSE;
4028 char *messagefile = new char[256];
4030 BufferMemory buf(4096);
4032 if (NULL != _dialog)
4035 dialog = theRoamApp.genDialog();
4037 // Check if a .forward file exists.
4039 GetPasswordEntry(pw);
4041 sprintf(messagefile, "%s/.vacation.msg", pw.pw_dir);
4043 // See if the messagefile exists.
4044 // If it doesn't create one and throw in the text found in the
4045 // properties sheet. If no text found, use default template.
4049 int msg_file_exists = SafeAccess(messagefile, F_OK);
4051 if (_subject == NULL || strcmp(_subject, subj) != 0)
4052 text_changed = TRUE;
4054 else if (_subject != NULL)
4055 text_changed = TRUE;
4057 if (!text_changed) {
4059 if (_body == NULL || strcmp((char*)_body, text) != 0)
4060 text_changed = TRUE;
4062 else if (_body != NULL)
4063 text_changed = TRUE;
4066 if (msg_file_exists >= 0 && text_changed) {
4067 sprintf(dialog_text,
4068 GETMSG(DT_catd, 1, 106, ".vacation.msg file exists. Replace with new text?"));
4069 dialog->setToQuestionDialog("Mailer", dialog_text);
4070 helpId = DTMAILHELPEXISTSVACATION;
4071 answer = dialog->post_and_return(helpId);
4074 // backup the messageFile
4075 this->backupFile(messagefile);
4079 // If the file doesn't exist or if the user has okayed creation
4081 if ((msg_file_exists < 0) || (answer == 1)) {
4083 fd = SafeOpen(messagefile, O_WRONLY | O_CREAT);
4085 sprintf(dialog_text,
4086 GETMSG(DT_catd, 1, 107, "Cannot open .vacation.msg file -- No write permission."));
4087 dialog->setToQuestionDialog("Mailer", dialog_text);
4088 helpId = DTMAILHELPERROR;
4089 answer = dialog->post_and_return(helpId);
4091 // Handle dialog indicating file not writable
4092 delete [] messagefile;
4095 SafeFChmod (fd, 0644);
4099 * This is the default value of the subject field in the
4100 * message that gets returned to the sender when vacation
4103 subj = GETMSG(DT_catd, 1, 108, "I am on vacation");
4105 buf.appendData("Subject: ", 9);
4106 buf.appendData(subj, strlen(subj));
4107 buf.appendData("\nPrecedence: junk\n\n", 19);
4111 _subject = strdup(subj);
4114 text = GETMSG(DT_catd, 1, 109,
4115 "I'm on vacation.\nYour mail regarding \"$SUBJECT\" will be read when I return.\n");
4117 buf.appendData(text, strlen(text));
4118 if (strlen(text) > 0 && text[strlen(text) - 1] != '\n') {
4119 buf.appendData("\n", 1);
4121 _body = strdup(text);
4123 buf.iterate(writeToFileDesc, fd);
4127 delete [] messagefile;