/* --------------- memopad.c ----------- */ #include "dflat.h" extern DBOX PrintSetup; char DFlatApplication[] = "MemoPad"; static char Untitled[] = "Untitled"; static int wndpos; static int MemoPadProc(WINDOW, MESSAGE, PARAM, PARAM); static void NewFile(WINDOW); static void SelectFile(WINDOW); static void PadWindow(WINDOW, char *); static void OpenPadWindow(WINDOW, char *); static void LoadFile(WINDOW); static void PrintPad(WINDOW); static void SaveFile(WINDOW, int); static void DeleteFile(WINDOW); static int EditorProc(WINDOW, MESSAGE, PARAM, PARAM); static char *NameComponent(char *); static int PrintSetupProc(WINDOW, MESSAGE, PARAM, PARAM); static void FixTabMenu(void); #ifndef TURBOC void Calendar(WINDOW); #endif void BarChart(WINDOW); char **Argv; static int CancelPrint; #define CHARSLINE 80 #define LINESPAGE 66 void main(int argc, char *argv[]) { WINDOW wnd; init_messages(); Argv = argv; wnd = CreateWindow(APPLICATION, "D-Flat MemoPad " VERSION, 0, 0, -1, -1, &MainMenu, NULL, MemoPadProc, MOVEABLE | SIZEABLE | HASBORDER | HASSTATUSBAR ); SendMessage(wnd, SETFOCUS, TRUE, 0); while (argc > 1) { PadWindow(wnd, argv[1]); --argc; argv++; } while (dispatch_message()) ; } /* ------ open text files and put them into editboxes ----- */ static void PadWindow(WINDOW wnd, char *FileName) { int ax, criterr = 1; struct ffblk ff; char path[64]; char *cp; CreatePath(path, FileName, FALSE, FALSE); cp = path+strlen(path); CreatePath(path, FileName, TRUE, FALSE); while (criterr == 1) { ax = findfirst(path, &ff, 0); criterr = TestCriticalError(); } while (ax == 0 && !criterr) { strcpy(cp, ff.ff_name); OpenPadWindow(wnd, path); ax = findnext(&ff); } } /* ------- window processing module for the memopad application window ----- */ static int MemoPadProc(WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2) { int rtn; switch (msg) { case CREATE_WINDOW: rtn = DefaultWndProc(wnd, msg, p1, p2); if (cfg.InsertMode) SetCommandToggle(&MainMenu, ID_INSERT); if (cfg.WordWrap) SetCommandToggle(&MainMenu, ID_WRAP); FixTabMenu(); return rtn; case COMMAND: switch ((int)p1) { case ID_NEW: NewFile(wnd); return TRUE; case ID_OPEN: SelectFile(wnd); return TRUE; case ID_SAVE: SaveFile(inFocus, FALSE); return TRUE; case ID_SAVEAS: SaveFile(inFocus, TRUE); return TRUE; case ID_DELETEFILE: DeleteFile(inFocus); return TRUE; case ID_PRINTSETUP: DialogBox(wnd, &PrintSetup, TRUE, PrintSetupProc); return TRUE; case ID_PRINT: PrintPad(inFocus); return TRUE; case ID_TAB2: cfg.Tabs = 2; FixTabMenu(); return TRUE; case ID_TAB4: cfg.Tabs = 4; FixTabMenu(); return TRUE; case ID_TAB6: cfg.Tabs = 6; FixTabMenu(); return TRUE; case ID_TAB8: cfg.Tabs = 8; FixTabMenu(); return TRUE; case ID_CANCEL: if ((int)p2 == 0) CancelPrint = TRUE; return TRUE; case ID_CALENDAR: #ifndef TURBOC Calendar(wnd); #endif return TRUE; case ID_BARCHART: BarChart(wnd); return TRUE; case ID_ABOUT: MessageBox( "About D-Flat and the MemoPad", " ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n" " ³ ÜÜÜ ÜÜÜ Ü ³\n" " ³ Û Û Û Û Û ³\n" " ³ Û Û Û Û Û ³\n" " ³ Û Û Û Û Û Û ³\n" " ³ ßßß ßßß ßß ³\n" " ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ\n" "D-Flat implements the SAA/CUA\n" "interface in a public domain\n" "C language library originally\n" "published in Dr. Dobb's Journal\n" " ------------------------ \n" "MemoPad is a multiple document\n" "editor that demonstrates D-Flat"); return TRUE; default: break; } break; default: break; } return DefaultWndProc(wnd, msg, p1, p2); } /* --- The New command. Open an empty editor window --- */ static void NewFile(WINDOW wnd) { OpenPadWindow(wnd, Untitled); } /* --- The Open... command. Select a file --- */ static void SelectFile(WINDOW wnd) { char FileName[64]; if (OpenFileDialogBox("*.PAD", FileName)) { /* --- see if the document is already in a window --- */ WINDOW wnd1 = GetFirstChild(wnd); while (wnd1 != NULL) { if (stricmp(FileName, wnd1->extension) == 0) { SendMessage(wnd1, SETFOCUS, TRUE, 0); SendMessage(wnd1, RESTORE, 0, 0); return; } wnd1 = GetNextChild(wnd, wnd1); } OpenPadWindow(wnd, FileName); } } /* --- open a document window and load a file --- */ static void OpenPadWindow(WINDOW wnd, char *FileName) { static WINDOW wnd1 = NULL; struct stat sb; char *Fname = FileName; char *ermsg; if (strcmp(FileName, Untitled)) { if (stat(FileName, &sb)) { if ((ermsg = malloc(strlen(FileName)+20)) != NULL) { strcpy(ermsg, "No such file as\n"); strcat(ermsg, FileName); ErrorMessage(ermsg); free(ermsg); } return; } Fname = NameComponent(FileName); } wndpos += 2; if (wndpos == 20) wndpos = 2; wnd1 = CreateWindow(EDITBOX, Fname, (wndpos-1)*2, wndpos, 10, 40, NULL, wnd, EditorProc, SHADOW | MINMAXBOX | CONTROLBOX | VSCROLLBAR | HSCROLLBAR | MOVEABLE | HASBORDER | SIZEABLE | MULTILINE ); if (strcmp(FileName, Untitled)) { if ((wnd1->extension = malloc(strlen(FileName)+1)) != NULL) { strcpy(wnd1->extension, FileName); LoadFile(wnd1); } } SendMessage(wnd1, SETFOCUS, TRUE, 0); } /* --- Load the notepad file into the editor text buffer --- */ static void LoadFile(WINDOW wnd) { char *Buf = NULL; int recptr = 0; FILE *fp; if ((fp = fopen(wnd->extension, "rt")) != NULL) { while (!feof(fp)) { if ((Buf = realloc(Buf, recptr+150)) == NULL) break; fgets(Buf+recptr, 150, fp); recptr += strlen(Buf+recptr); } fclose(fp); if (Buf != NULL) { SendMessage(wnd, SETTEXT, (PARAM) Buf, 0); free(Buf); } } } /* --- print the current notepad --- */ static void PrintPad(WINDOW wnd) { unsigned char *text; FILE *prn; int LineCtr = 0, CharCtr = 0; if (*cfg.PrinterPort) { if ((prn = fopen(cfg.PrinterPort, "wt")) != NULL) { /* ---- get the address of the editor text ----- */ text = GetText(wnd); CancelPrint = FALSE; CancelBox(GetParent(wnd), "Printing..."); /* ------- print the notepad text --------- */ while (*text) { int i; dispatch_message(); if (CancelPrint) if (YesNoBox("Cancel Printing?")) break; CancelPrint = FALSE; if (*text == '\n' || CharCtr == cfg.RightMargin) { fputs("\r\n", prn); LineCtr++; if (LineCtr == cfg.BottomMargin) { fputc('\f', prn); for (i = 0; i < cfg.TopMargin; i++) fputc('\n', prn); LineCtr = cfg.TopMargin; } CharCtr = 0; if (*text == '\n') { text++; continue; } } if (CharCtr == 0) { for (i = 0; i < cfg.LeftMargin; i++) { fputc(' ', prn); CharCtr++; } } CharCtr++; fputc(*text++, prn); } CloseCancelBox(); /* ------- follow with a form feed? --------- */ if (YesNoBox("Form Feed?")) fputc('\f', prn); fclose(prn); } else ErrorMessage("Cannot open printer file"); } else ErrorMessage("No printer selected"); } /* ---------- save a file to disk ------------ */ static void SaveFile(WINDOW wnd, int Saveas) { FILE *fp; if (wnd->extension == NULL || Saveas) { char FileName[64]; if (SaveAsDialogBox(FileName)) { if (wnd->extension != NULL) free(wnd->extension); if ((wnd->extension = malloc(strlen(FileName)+1)) != NULL) { strcpy(wnd->extension, FileName); AddTitle(wnd, NameComponent(FileName)); SendMessage(wnd, BORDER, 0, 0); } } else return; } if (wnd->extension != NULL) { WINDOW mwnd = MomentaryMessage("Saving the file"); if ((fp = fopen(wnd->extension, "wt")) != NULL) { fwrite(GetText(wnd), strlen(GetText(wnd)), 1, fp); fclose(fp); wnd->TextChanged = FALSE; } SendMessage(mwnd, CLOSE_WINDOW, 0, 0); } } /* -------- delete a file ------------ */ static void DeleteFile(WINDOW wnd) { if (wnd->extension != NULL) { if (strcmp(wnd->extension, Untitled)) { char *fn = NameComponent(wnd->extension); if (fn != NULL) { char msg[30]; sprintf(msg, "Delete %s?", fn); if (YesNoBox(msg)) { unlink(wnd->extension); SendMessage(wnd, CLOSE_WINDOW, 0, 0); } } } } } /* ------ display the row and column in the statusbar ------ */ static void ShowPosition(WINDOW wnd) { char status[30]; sprintf(status, "Line:%4d Column: %2d", wnd->CurrLine, wnd->CurrCol); SendMessage(GetParent(wnd), ADDSTATUS, (PARAM) status, 0); } /* ----- window processing module for the editboxes ----- */ static int EditorProc(WINDOW wnd,MESSAGE msg,PARAM p1,PARAM p2) { int rtn; switch (msg) { case SETFOCUS: if ((int)p1) { wnd->InsertMode = GetCommandToggle(&MainMenu, ID_INSERT); wnd->WordWrapMode = GetCommandToggle(&MainMenu, ID_WRAP); } rtn = DefaultWndProc(wnd, msg, p1, p2); if ((int)p1 == FALSE) SendMessage(GetParent(wnd), ADDSTATUS, 0, 0); else ShowPosition(wnd); return rtn; case KEYBOARD_CURSOR: rtn = DefaultWndProc(wnd, msg, p1, p2); ShowPosition(wnd); return rtn; case COMMAND: switch ((int) p1) { case ID_SEARCH: SearchText(wnd); return TRUE; case ID_REPLACE: ReplaceText(wnd); return TRUE; case ID_SEARCHNEXT: SearchNext(wnd); return TRUE; case ID_CUT: CopyToClipboard(wnd); SendMessage(wnd, COMMAND, ID_DELETETEXT, 0); SendMessage(wnd, PAINT, 0, 0); return TRUE; case ID_COPY: CopyToClipboard(wnd); ClearTextBlock(wnd); SendMessage(wnd, PAINT, 0, 0); return TRUE; case ID_PASTE: PasteFromClipboard(wnd); SendMessage(wnd, PAINT, 0, 0); return TRUE; case ID_HELP: DisplayHelp(wnd, "MEMOPADDOC"); return TRUE; case ID_WRAP: wnd->WordWrapMode = GetCommandToggle(&MainMenu, ID_WRAP); cfg.WordWrap = wnd->WordWrapMode; return TRUE; case ID_INSERT: wnd->InsertMode = GetCommandToggle(&MainMenu, ID_INSERT); cfg.InsertMode = wnd->InsertMode; SendMessage(NULL, SHOW_CURSOR, wnd->InsertMode, 0); return TRUE; default: break; } break; case CLOSE_WINDOW: if (wnd->TextChanged) { char *cp = malloc(25+strlen(GetTitle(wnd))); SendMessage(wnd, SETFOCUS, TRUE, 0); if (cp != NULL) { strcpy(cp, GetTitle(wnd)); strcat(cp, "\nText changed. Save it?"); if (YesNoBox(cp)) SendMessage(GetParent(wnd), COMMAND, ID_SAVE, 0); free(cp); } } wndpos = 0; if (wnd->extension != NULL) { free(wnd->extension); wnd->extension = NULL; } break; default: break; } return DefaultWndProc(wnd, msg, p1, p2); } /* -- point to the name component of a file specification -- */ static char *NameComponent(char *FileName) { char *Fname; if ((Fname = strrchr(FileName, '\\')) == NULL) if ((Fname = strrchr(FileName, ':')) == NULL) Fname = FileName-1; return Fname + 1; } static char *ports[] = { "Lpt1", "Lpt2", "Lpt3", "Com1", "Com2", "Com3", "Com4", NULL }; static int PrintSetupProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2) { int rtn, i = 0, mar; char marg[10]; WINDOW cwnd; switch (msg) { case CREATE_WINDOW: rtn = DefaultWndProc(wnd, msg, p1, p2); PutItemText(wnd, ID_PRINTERPORT, cfg.PrinterPort); while (ports[i] != NULL) PutComboListText(wnd, ID_PRINTERPORT, ports[i++]); for (mar = CHARSLINE; mar >= 0; --mar) { sprintf(marg, "%3d", mar); PutItemText(wnd, ID_LEFTMARGIN, marg); PutItemText(wnd, ID_RIGHTMARGIN, marg); } for (mar = LINESPAGE; mar >= 0; --mar) { sprintf(marg, "%3d", mar); PutItemText(wnd, ID_TOPMARGIN, marg); PutItemText(wnd, ID_BOTTOMMARGIN, marg); } cwnd = ControlWindow(&PrintSetup, ID_LEFTMARGIN); SendMessage(cwnd, LB_SETSELECTION, CHARSLINE-cfg.LeftMargin, 0); cwnd = ControlWindow(&PrintSetup, ID_RIGHTMARGIN); SendMessage(cwnd, LB_SETSELECTION, CHARSLINE-cfg.RightMargin, 0); cwnd = ControlWindow(&PrintSetup, ID_TOPMARGIN); SendMessage(cwnd, LB_SETSELECTION, LINESPAGE-cfg.TopMargin, 0); cwnd = ControlWindow(&PrintSetup, ID_BOTTOMMARGIN); SendMessage(cwnd, LB_SETSELECTION, LINESPAGE-cfg.BottomMargin, 0); return rtn; case COMMAND: if ((int) p1 == ID_OK && (int) p2 == 0) { GetItemText(wnd, ID_PRINTERPORT, cfg.PrinterPort, 4); cwnd = ControlWindow(&PrintSetup, ID_LEFTMARGIN); cfg.LeftMargin = CHARSLINE - SendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); cwnd = ControlWindow(&PrintSetup, ID_RIGHTMARGIN); cfg.RightMargin = CHARSLINE - SendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); cwnd = ControlWindow(&PrintSetup, ID_TOPMARGIN); cfg.TopMargin = LINESPAGE - SendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); cwnd = ControlWindow(&PrintSetup, ID_BOTTOMMARGIN); cfg.BottomMargin = LINESPAGE - SendMessage(cwnd, LB_CURRENTSELECTION, 0, 0); } break; default: break; } return DefaultWndProc(wnd, msg, p1, p2); } static void FixTabMenu(void) { char *cp = GetCommandText(&MainMenu, ID_TABS); if (cp != NULL) { cp = strchr(cp, '('); if (cp != NULL) { *(cp+1) = cfg.Tabs + '0'; if (GetClass(inFocus) == POPDOWNMENU) SendMessage(inFocus, PAINT, 0, 0); } } } void PrepFileMenu(void *w, struct Menu *mnu) { WINDOW wnd = w; DeactivateCommand(&MainMenu, ID_SAVE); DeactivateCommand(&MainMenu, ID_SAVEAS); DeactivateCommand(&MainMenu, ID_DELETEFILE); DeactivateCommand(&MainMenu, ID_PRINT); if (wnd != NULL && GetClass(wnd) == EDITBOX) { if (isMultiLine(wnd)) { ActivateCommand(&MainMenu, ID_SAVE); ActivateCommand(&MainMenu, ID_SAVEAS); ActivateCommand(&MainMenu, ID_DELETEFILE); ActivateCommand(&MainMenu, ID_PRINT); } } } void PrepSearchMenu(void *w, struct Menu *mnu) { WINDOW wnd = w; DeactivateCommand(&MainMenu, ID_SEARCH); DeactivateCommand(&MainMenu, ID_REPLACE); DeactivateCommand(&MainMenu, ID_SEARCHNEXT); if (wnd != NULL && GetClass(wnd) == EDITBOX) { if (isMultiLine(wnd)) { ActivateCommand(&MainMenu, ID_SEARCH); ActivateCommand(&MainMenu, ID_REPLACE); ActivateCommand(&MainMenu, ID_SEARCHNEXT); } } } void PrepEditMenu(void *w, struct Menu *mnu) { WINDOW wnd = w; DeactivateCommand(&MainMenu, ID_CUT); DeactivateCommand(&MainMenu, ID_COPY); DeactivateCommand(&MainMenu, ID_CLEAR); DeactivateCommand(&MainMenu, ID_DELETETEXT); DeactivateCommand(&MainMenu, ID_PARAGRAPH); DeactivateCommand(&MainMenu, ID_PASTE); DeactivateCommand(&MainMenu, ID_UNDO); if (wnd != NULL && GetClass(wnd) == EDITBOX) { if (isMultiLine(wnd)) { if (TextBlockMarked(wnd)) { ActivateCommand(&MainMenu, ID_CUT); ActivateCommand(&MainMenu, ID_COPY); ActivateCommand(&MainMenu, ID_CLEAR); ActivateCommand(&MainMenu, ID_DELETETEXT); } ActivateCommand(&MainMenu, ID_PARAGRAPH); if (!TestAttribute(wnd, READONLY) && Clipboard != NULL) ActivateCommand(&MainMenu, ID_PASTE); if (wnd->DeletedText != NULL) ActivateCommand(&MainMenu, ID_UNDO); } } }