📄 xrolo.c
字号:
/**** xrolo.c ****//*********************************************************************** Copyright (c) 1991, 1992 Iris Computing Laboratories.** This software is provided for demonstration purposes only. As* freely-distributed, modifiable source code, this software carries* absolutely no warranty. Iris Computing Laboratories disclaims* all warranties for this software, including any implied warranties* of merchantability and fitness, and shall not be liable for* damages of any type resulting from its use.* Permission to use, copy, modify, and distribute this source code* for any purpose and without fee is hereby granted, provided that* the above copyright and this permission notice appear in all copies* and supporting documentation, and provided that Iris Computing* Laboratories not be named in advertising or publicity pertaining* to the redistribution of this software without specific, written* prior permission.**********************************************************************//********************************************************************`xrolodex' implements a simple rolodex application. It is composedof the following modules: `xrolo.c' -- widget creation for the top-level interface, plus callbacks and support functions. `xrolo.db.c' -- rolodex entry manipulation functions and the state of the database. `xrolo.help.t' -- a module for providing help system text. `xrolo.index.c' -- the rolodex index manipulation functions. `streamdb.c' -- a stream- or byte-oriented database object. `strstr.c' -- a string search module. `ctrlpanel.c' -- a control panel pseudo-widget. `editor.c' -- a self-contained editor pseudo-widget. `listshell.c' -- a list selection box pseudo-widget. `dialog.c' -- a dialog box pseudo-widget. `help.c' -- a generalized help system. `motif.c' -- OSF/Motif miscellaneous functions.See these modules for more details.Note that this implementation contains source code specificallydesigned to provide conversation, sometimes debate, as well asexamples that motivate discussion of certain techniques in bothlecture and laboratory settings. For example, we use onedialog box, `messageDialog' to display different messages(efficient), but in another case, we use two dialog boxes in anonmodal situation simply to distinguish between the context inwhich their callbacks are activated (not as efficient).********************************************************************/#include "xrolo.h"/*Private functions:*/static Widget create_main_menu_bar();static CtrlPanel create_entry_control_panel();static void create_dialogs();static int check_for_unsaved_changes();static void load_next_rolodex_entry();static void load_previous_rolodex_entry();static void new_entry();static int save_current_text();static void insert_new_db_entry();static void save_current_db_entry();static void find_entry_containing_text_forward();static void find_entry_containing_text_reverse();static void open_rolodex_file(), save_as_rolodex_file();static void do_save_as_operation();static void save_first_time();static void update_current_entry();static int is_rolodex_active();static void initialize_critical_variables();static void cleanup_and_exit();static void user_message();static void initialize_shell_icons();static void handle_close_buttons();/*Private callbacks:*/static void Open(), Save(), SaveAs(), Quit(), Exit();static void Next(), Previous(), First(), Last();static void Index(), Find(), Sort();static void NewIns(), NewAdd(), Copy(), Delete(), Undelete();static void EntryModified(), IndexSelection();static void InsensitiveSearch(), SensitiveSearch();static void FileSelectionOK(), FileSelectionCancel();static void OverwriteOK(), OverwriteCancel();static void SaveUnsavedChanges(), DiscardUnsavedChanges(), CancelUnsavedChanges();static void FindForward(), FindReverse(), FindDismiss();static void Close(), UnmanageWindow(), UnmapWindow(), DialogCancel();/*Private globals (can be modified):*/static char *delimiter; /* see resources */static char *save_as_filename = NULL;static Pixmap icon_pixmap;/*Private globals (global for callback convenience only -- never modified):*/static CtrlPanel entryPanel;static Editor entryEditWindow;static ListShell entryIndex;static Dialog openUnsavedDialog, quitUnsavedDialog, overwriteDialog, messageDialog;static Widget databaseLabel, fileSelectionDialog;static Widget findShell, findText;/*Private globals (these variables maintain the state of rolodex entries):*/static int editing_new_entry = FALSE;static EntryDB current_entry = NULL; /* opaque usage as indicator variable */static EntryDB temp_entry = NULL; /* opaque usage as indicator variable */static int entry_modified = FALSE;static int first_time = TRUE;static int case_sensitive_search = FALSE;/*Private character set, passed to other modules:*/static XmStringCharSet char_set = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET;/*Private resource globals (set during start-up):*/static XtResource resources[] = { {XtNviewportMenuBar, XtCViewportMenuBar, XtRBoolean, sizeof(Boolean), XtOffset(ApplicationDataPtr, viewport_menubar), XtRImmediate, (XtPointer) FALSE}, {XtNviewportRows, XtCViewportRows, XtRInt, sizeof(int), XtOffset(ApplicationDataPtr, viewport_rows), XtRImmediate, (XtPointer) xrolo_DEFAULT_VIEWPORT_ROWS}, {XtNviewportColumns, XtCViewportColumns, XtRInt, sizeof(int), XtOffset(ApplicationDataPtr, viewport_columns), XtRImmediate, (XtPointer) xrolo_DEFAULT_VIEWPORT_COLUMNS}, {XtNindexRows, XtCIndexRows, XtRInt, sizeof(int), XtOffset(ApplicationDataPtr, index_rows), XtRImmediate, (XtPointer) xrolo_DEFAULT_INDEX_ROWS}, {XtNindexColumns, XtCIndexColumns, XtRInt, sizeof(int), XtOffset(ApplicationDataPtr, index_columns), XtRImmediate, (XtPointer) xrolo_DEFAULT_INDEX_COLUMNS}, {XtNcenterDialogs, XtCCenterDialogs, XtRBoolean, sizeof(Boolean), XtOffset(ApplicationDataPtr, center_dialogs), XtRImmediate, (XtPointer) TRUE}, {XtNentryDelimiter, XtCEntryDelimiter, XtRString, sizeof(String), XtOffset(ApplicationDataPtr, delimiter), XtRString, xrolo_DEFAULT_DELIMITER}, {XtNdirectoryMask, XtCDirectoryMask, XtRString, sizeof(String), XtOffset(ApplicationDataPtr, dir_mask), XtRString, ""}, /* default is home directory; see create_dialogs() */};/*main() creates a top-level window from a system of managerwidgets, using several pseudo-widgets for the control panel,the edit area for rolodex entries, and the index facility.*/void main(argc, argv)int argc;char *argv[];{ Arg args[10]; int i; XtAppContext app; Widget topLevel, mainWindow, mainMenuBar; static XtCallbackRec text_mod_cb_list[] = { {EntryModified, (XtPointer) NULL}, {(XtCallbackProc) NULL, (XtPointer) NULL}, }; ApplicationData resource_data; char *icon_name; if ((argc == 2 && strcmp(argv[1], "-help") == 0)) { printf("\nusage: xrolodex [<filename>] [-iconName <icon name>]\n\n"); exit(0); } topLevel = XtAppInitialize(&app, xrolo_APP_CLASS, (XrmOptionDescList) NULL, 0, &argc, argv, (String *) NULL, (ArgList) NULL, 0); if (argc > 4) { printf("\nusage: xrolodex [<filename>] [-iconName <icon name>]\n"); exit(0); } XtGetApplicationResources(topLevel, &resource_data, resources, XtNumber(resources), NULL, 0); delimiter = resource_data.delimiter; /* set the global */ i = 0; XtSetArg(args[i], XmNhorizontalSpacing, (XtArgVal) 5); i++; XtSetArg(args[i], XmNverticalSpacing, (XtArgVal) 5); i++; mainWindow = XtCreateManagedWidget("mainWindow", xmFormWidgetClass, topLevel, args, i); mainMenuBar = create_main_menu_bar(mainWindow); i = 0; XtSetArg(args[i], XmNleftAttachment, (XtArgVal) XmATTACH_FORM); i++; XtSetArg(args[i], XmNrightAttachment, (XtArgVal) XmATTACH_FORM); i++; XtSetArg(args[i], XmNtopAttachment, (XtArgVal) XmATTACH_WIDGET); i++; XtSetArg(args[i], XmNtopWidget, (XtArgVal) mainMenuBar); i++; XtSetArg(args[i], XmNlabelString, XmStringCreateLtoR(" ", char_set)); i++; databaseLabel = XtCreateManagedWidget("databaseLabel", xmLabelWidgetClass, mainWindow, args, i); entryPanel = create_entry_control_panel(mainWindow); i = 0; XtSetArg(args[i], XmNleftAttachment, (XtArgVal) XmATTACH_FORM); i++; XtSetArg(args[i], XmNtopAttachment, (XtArgVal) XmATTACH_WIDGET); i++; XtSetArg(args[i], XmNtopWidget, (XtArgVal) databaseLabel); i++; XtSetArg(args[i], XmNbottomAttachment, (XtArgVal) XmATTACH_FORM); i++; XtSetValues(ctrlPanel_instance(entryPanel), args, i); entryEditWindow = editor_create(mainWindow, xrolo_APP_CLASS, "entryEditWindow", resource_data.viewport_rows, resource_data.viewport_columns, 40, editor_SCROLL_DEFAULT, "", char_set, "xrolodex", "Editor/Viewport Search and Replace", editor_WIN_MGR_DECOR, resource_data.viewport_menubar ? editor_MENU_BAR : editor_POPUP_MENU); i = 0; XtSetArg(args[i], XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET); i++; XtSetArg(args[i], XmNleftWidget, (XtArgVal) ctrlPanel_instance(entryPanel)); i++; XtSetArg(args[i], XmNrightAttachment, (XtArgVal) XmATTACH_FORM); i++; XtSetArg(args[i], XmNtopAttachment, (XtArgVal) XmATTACH_WIDGET); i++; XtSetArg(args[i], XmNtopWidget, (XtArgVal) databaseLabel); i++; XtSetArg(args[i], XmNbottomAttachment, (XtArgVal) XmATTACH_FORM); i++; XtSetValues(editor_instance(entryEditWindow), args, i); i = 0; XtSetArg(args[i], XmNmodifyVerifyCallback, text_mod_cb_list); i++; XtSetValues(editor_edit(entryEditWindow), args, i); /* the list selection box's items will be added later: */ entryIndex = listShell_create(topLevel, xrolo_APP_CLASS, "entryIndex", NULL, char_set, resource_data.index_columns, resource_data.index_rows, listShell_NO_STAY_UP, listShell_WIN_MGR_DECOR); listShell_add_callback(entryIndex, IndexSelection, 0); xrolo_index_create(entryIndex); create_dialogs(app, topLevel, &resource_data); help_create_dialog(topLevel, xrolo_APP_CLASS, xrolo_help_rows, xrolo_help_columns, char_set); if (argc == 4 && strcmp(argv[2], "-iconName") == 0) icon_name = argv[3]; else if (argc == 3 && strcmp(argv[1], "-iconName") == 0) icon_name = argv[2]; else icon_name = NULL; initialize_shell_icons(topLevel, icon_name); XtRealizeWidget(topLevel); XtRealizeWidget(findShell); help_realize(); editor_realize(entryEditWindow); listShell_realize(entryIndex); dialog_realize(openUnsavedDialog); dialog_realize(quitUnsavedDialog); dialog_realize(overwriteDialog); dialog_realize(messageDialog); handle_close_buttons(topLevel); if (argc > 1 && strcmp(argv[1], "-iconName") != 0 && strlen(argv[1]) > 0) open_rolodex_file(argv[1]);#ifdef SCREEN_SHOT while (True) { XEvent event; XtAppNextEvent(app, &event); if (event.type == ButtonPress && event.xbutton.button == 2) { XUngrabPointer(XtDisplay(topLevel), CurrentTime); XUngrabKeyboard(XtDisplay(topLevel), CurrentTime); } XtDispatchEvent(&event); }#else XtAppMainLoop(app);#endif} /* main *//*create_main_menu_bar() creates the application-level menu bar,including pull-down menus and menu entries.*/static Widget create_main_menu_bar(parent)Widget parent;{ static menu_entry file_menu[] = { {menu_ENTRY, "Open...", "menuOpenButton", Open, NULL, NULL, NULL}, {menu_ENTRY, "Save", "menuSaveButton", Save, NULL, NULL, NULL}, {menu_ENTRY, "Save As...", "menuSaveAsButton", SaveAs, NULL, NULL, NULL}, {menu_ENTRY, "Quit", "menuQuitButton", Quit, NULL, NULL, NULL}, {menu_ENTRY, "Exit", "menuExitButton", Exit, NULL, NULL, NULL}, {menu_END, NULL, NULL, NULL, NULL, NULL, NULL}, }; static menu_entry edit_menu[] = { {menu_ENTRY, "New/Ins", "menuInsButton", NewIns, NULL, NULL, NULL}, {menu_ENTRY, "New/Add", "menuAddButton", NewAdd, NULL, NULL, NULL}, {menu_ENTRY, "Copy", "menuCopyButton", Copy, NULL, NULL, NULL}, {menu_ENTRY, "Delete", "menuDeleteButton", Delete, NULL, NULL, NULL}, {menu_ENTRY, "Undelete", "menuUndeleteButton", Undelete, NULL, NULL, NULL}, {menu_END, NULL, NULL, NULL, NULL, NULL, NULL}, }; static menu_entry find_menu[] = { {menu_ENTRY, "Find Entry...", "menuFindEntryButton", Find, NULL, NULL, NULL}, {menu_ENTRY, "Index...", "menuIndexButton", Index, NULL, NULL, NULL}, {menu_END, NULL, NULL, NULL, NULL, NULL, NULL}, }; static menu_entry sort_menu[] = { {menu_ENTRY, "Ascending", "menuAscendingButton", Sort, (XtPointer) xrolo_ASCEND, NULL, NULL}, {menu_ENTRY, "Descending", "menuDescendingButton", Sort, (XtPointer) xrolo_DESCEND, NULL, NULL}, {menu_END, NULL, NULL, NULL, NULL, NULL, NULL}, }; static menu_entry menus[] = { {menu_SUBMENU, "File", "menuFileButton", NULL, NULL, file_menu, NULL}, {menu_SUBMENU, "Edit", "menuEditButton", NULL, NULL, edit_menu, NULL}, {menu_SUBMENU, "Find", "menuFindButton", NULL, NULL, find_menu, NULL}, {menu_SUBMENU, "Sort", "menuSortButton", NULL, NULL, sort_menu, NULL}, {menu_END, NULL, NULL, NULL, NULL, NULL, NULL}, }; static menu_entry help_menu[] = { {menu_ENTRY, "General...", "menuGenHelpButton", Help, (XtPointer) 0, NULL, NULL}, {menu_ENTRY, "Files...", "menuFileHelpButton", Help, (XtPointer) 1, NULL, NULL}, {menu_ENTRY, "Edit Entries...", "menuEditHelpButton", Help, (XtPointer) 2, NULL, NULL}, {menu_ENTRY, "Find Entries...", "menuFindHelpButton", Help, (XtPointer) 3, NULL, NULL}, {menu_ENTRY, "Sort Entries...", "menuSortHelpButton", Help, (XtPointer) 4, NULL, NULL}, {menu_ENTRY, "Control Panel...", "menuPanelHelpButton", Help, (XtPointer) 5, NULL, NULL}, {menu_ENTRY, "Editor...", "menuEditorHelpButton", Help, (XtPointer) 6, NULL, NULL}, {menu_ENTRY, "Info...", "menuInfoHelpButton", Help, (XtPointer) 7, NULL, NULL}, {menu_END, NULL, NULL, NULL, NULL, NULL, NULL}, }; Arg args[10]; int i; Widget mainMenuBar; i = 0; XtSetArg(args[i], XmNleftAttachment, (XtArgVal) XmATTACH_FORM); i++; XtSetArg(args[i], XmNrightAttachment, (XtArgVal) XmATTACH_FORM); i++; XtSetArg(args[i], XmNtopAttachment, (XtArgVal) XmATTACH_FORM); i++; mainMenuBar = XmCreateMenuBar(parent, "mainMenuBar", args, i); XtManageChild(mainMenuBar); create_menus(mainMenuBar, menus, char_set); help_create_pulldown_menu(mainMenuBar, help_menu, xrolo_help_data, char_set); return mainMenuBar;} /* create_main_menu_bar *//*create_entry_control_panel() creates the control panel that'sused to manipulate rolodex entries in the rolodex window.*/static CtrlPanel create_entry_control_panel(parent)Widget parent;{ static CtrlPanelItem items[] = { {"First", NULL, First, NULL}, {"Last", NULL, Last, NULL}, {"", NULL, NULL, NULL}, /* separator */ {"Previous", NULL, Previous, NULL}, {"Next", NULL, Next, NULL}, {"", NULL, NULL, NULL}, /* separator */ {"New/Ins", NULL, NewIns, NULL}, {"Copy", NULL, Copy, NULL}, {"", NULL, NULL, NULL}, /* separator */ {"Index...", NULL, Index, NULL}, {NULL, NULL, NULL, NULL}, }; CtrlPanel entryControlPanel; entryControlPanel = ctrlPanel_create(parent, "entryControlPanel", items, char_set, ctrlPanel_VERTICAL); return entryControlPanel;} /* create_entry_control_panel *//*create_dialogs() creates the dialog boxes used for promptingfor filenames, for prompts related to unsaved changes tothe rolodex file, and the find-entry window.*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -