📄 window.c
字号:
/* Create a MainWindow to manage the menubar and text area, set the userData resource to be used by WidgetToWindow to recover the window pointer from the widget id of any of the window's widgets */ XtSetArg(al[ac], XmNuserData, window); ac++; mainWin = XmCreateMainWindow(appShell, "main", al, ac); XtManageChild(mainWin); /* The statsAreaForm holds the stats line and the I-Search line. */ statsAreaForm = XtVaCreateWidget("statsAreaForm", xmFormWidgetClass, mainWin, XmNmarginWidth, STAT_SHADOW_THICKNESS, XmNmarginHeight, STAT_SHADOW_THICKNESS, /* XmNautoUnmanage, False, */ NULL); if(window->showISearchLine || window->showStats) XtManageChild(statsAreaForm); /* NOTE: due to a bug in openmotif 2.1.30, NEdit used to crash when the i-search bar was active, and the i-search text widget was focussed, and the window's width was resized to nearly zero. In theory, it is possible to avoid this by imposing a minimum width constraint on the nedit windows, but that width would have to be at least 30 characters, which is probably unacceptable. Amazingly, adding a top offset of 1 pixel to the toggle buttons of the i-search bar, while keeping the the top offset of the text widget to 0 seems to avoid avoid the crash. */ window->iSearchForm = XtVaCreateWidget("iSearchForm", xmFormWidgetClass, statsAreaForm, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, window->showStats ? XmATTACH_NONE : XmATTACH_FORM, NULL); if(window->showISearchLine) XtManageChild(window->iSearchForm); iSearchLabel = XtVaCreateManagedWidget("iSearchLabel", xmLabelWidgetClass, window->iSearchForm, XmNlabelString, s1=XmStringCreateSimple("Find:"), XmNmarginHeight, 0, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 5, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 1, /* see openmotif note above, for aligment with toggle buttons below */ XmNbottomAttachment, XmATTACH_FORM, NULL); XmStringFree(s1); /* Disable keyboard traversal of the toggle buttons. We were doing this previously by forcing the keyboard focus back to the text widget whenever a toggle changed. That causes an ugly focus flash on screen. It's better just not to go there in the first place. Plus, if the user really wants traversal, it's an X resource so it can be enabled without too much pain and suffering. */ window->iSearchCaseToggle = XtVaCreateManagedWidget("iSearchCaseToggle", xmToggleButtonWidgetClass, window->iSearchForm, XmNlabelString, s1=XmStringCreateSimple("Case"), XmNset, GetPrefSearch() == SEARCH_CASE_SENSE || GetPrefSearch() == SEARCH_REGEX || GetPrefSearch() == SEARCH_CASE_SENSE_WORD, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNtopOffset, 1, /* see openmotif note above */ XmNrightAttachment, XmATTACH_FORM, XmNmarginHeight, 0, XmNtraversalOn, False, NULL); XmStringFree(s1); window->iSearchRegexToggle = XtVaCreateManagedWidget("iSearchREToggle", xmToggleButtonWidgetClass, window->iSearchForm, XmNlabelString, s1=XmStringCreateSimple("RegExp"), XmNset, GetPrefSearch() == SEARCH_REGEX_NOCASE || GetPrefSearch() == SEARCH_REGEX, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNtopOffset, 1, /* see openmotif note above */ XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, window->iSearchCaseToggle, XmNmarginHeight, 0, XmNtraversalOn, False, NULL); XmStringFree(s1); window->iSearchRevToggle = XtVaCreateManagedWidget("iSearchRevToggle", xmToggleButtonWidgetClass, window->iSearchForm, XmNlabelString, s1=XmStringCreateSimple("Rev"), XmNset, False, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNtopOffset, 1, /* see openmotif note above */ XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, window->iSearchRegexToggle, XmNmarginHeight, 0, XmNtraversalOn, False, NULL); XmStringFree(s1); window->iSearchText = XtVaCreateManagedWidget("iSearchText", xmTextWidgetClass, window->iSearchForm, XmNmarginHeight, 1, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, iSearchLabel, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, window->iSearchRevToggle, XmNrightOffset, 5, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 0, /* see openmotif note above */ XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 0, NULL); RemapDeleteKey(window->iSearchText); SetISearchTextCallbacks(window); /* A form to hold the stats line text and line/col widgets */ window->statsLineForm = XtVaCreateWidget("statsLineForm", xmFormWidgetClass, statsAreaForm, XmNshadowThickness, 0, XmNtopAttachment, window->showISearchLine ? XmATTACH_WIDGET : XmATTACH_FORM, XmNtopWidget, window->iSearchForm, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNresizable, False, /* */ NULL); /* A separate display of the line/column number */ window->statsLineColNo = XtVaCreateManagedWidget("statsLineColNo", xmLabelWidgetClass, window->statsLineForm, XmNlabelString, s1=XmStringCreateSimple("L: --- C: ---"), XmNshadowThickness, 0, XmNmarginHeight, 0, XmNmarginTop, 1, /* Help align with statsLine */ XmNtraversalOn, False, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, /* */ NULL); XmStringFree(s1); /* Create file statistics display area. Using a text widget rather than a label solves a layout problem with the main window, which messes up if the label is too long (we would need a resize callback to control the length when the window changed size), and allows users to select file names and line numbers. Colors are copied from parent widget, because many users and some system defaults color text backgrounds differently from other widgets. */ XtVaGetValues(statsAreaForm, XmNbackground, &bgpix, NULL); XtVaGetValues(statsAreaForm, XmNforeground, &fgpix, NULL); stats = XtVaCreateManagedWidget("statsLine", xmTextWidgetClass, window->statsLineForm, XmNbackground, bgpix, XmNforeground, fgpix, XmNshadowThickness, 0, XmNhighlightColor, bgpix, XmNhighlightThickness, 1, /* Setting this to zero causes mysterious problems with lesstif! */ XmNmarginHeight, 0, XmNscrollHorizontal, False, XmNeditMode, XmSINGLE_LINE_EDIT, XmNeditable, False, XmNtraversalOn, False, XmNcursorPositionVisible, False, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, window->statsLineColNo, XmNrightOffset, 3, NULL); window->statsLine = stats; /* Manage the statsLineForm */ if(window->showStats) XtManageChild(window->statsLineForm); /* If the fontList was NULL, use the magical default provided by Motif, since it must have worked if we've gotten this far */ if (window->fontList == NULL) XtVaGetValues(stats, XmNfontList, &window->fontList, NULL); /* Create the menu bar */ menuBar = CreateMenuBar(mainWin, window); window->menuBar = menuBar; XtManageChild(menuBar); /* Create paned window to manage split window behavior */ pane = XtVaCreateManagedWidget("pane", xmPanedWindowWidgetClass, mainWin, XmNseparatorOn, False, XmNspacing, 3, XmNsashIndent, -2, NULL); window->splitPane = pane; XmMainWindowSetAreas(mainWin, menuBar, statsAreaForm, NULL, NULL, pane); /* Patch around Motif's most idiotic "feature", that its menu accelerators recognize Caps Lock and Num Lock as modifiers, and don't trigger if they are engaged */ AccelLockBugPatch(pane, menuBar); /* Create the first, and most permanent text area (other panes may be added & removed, but this one will never be removed */ text = createTextArea(pane, window, rows,cols, GetPrefEmTabDist(PLAIN_LANGUAGE_MODE), GetPrefDelimiters(), GetPrefWrapMargin(), window->showLineNumbers?MIN_LINE_NUM_COLS:0); XtManageChild(text); window->textArea = text; window->lastFocus = text; /* Set the initial colors from the globals. */ SetColors(window, GetPrefColorName(TEXT_FG_COLOR ), GetPrefColorName(TEXT_BG_COLOR ), GetPrefColorName(SELECT_FG_COLOR), GetPrefColorName(SELECT_BG_COLOR), GetPrefColorName(HILITE_FG_COLOR), GetPrefColorName(HILITE_BG_COLOR), GetPrefColorName(LINENO_FG_COLOR), GetPrefColorName(CURSOR_FG_COLOR)); /* Create the right button popup menu (note: order is important here, since the translation for popping up this menu was probably already added in createTextArea, but CreateBGMenu requires window->textArea to be set so it can attach the menu to it (because menu shells are finicky about the kinds of widgets they are attached to)) */ window->bgMenuPane = CreateBGMenu(window); /* Create the text buffer rather than using the one created automatically with the text area widget. This is done so the syntax highlighting modify callback can be called to synchronize the style buffer BEFORE the text display's callback is called upon to display a modification */ window->buffer = BufCreate(); BufAddModifyCB(window->buffer, SyntaxHighlightModifyCB, window); /* Attach the buffer to the text widget, and add callbacks for modify */ TextSetBuffer(text, window->buffer); BufAddModifyCB(window->buffer, modifiedCB, window); /* Designate the permanent text area as the owner for selections */ HandleXSelections(text); /* Set the requested hardware tab distance and useTabs in the text buffer */ BufSetTabDistance(window->buffer, GetPrefTabDist(PLAIN_LANGUAGE_MODE)); window->buffer->useTabs = GetPrefInsertTabs(); /* add the window to the global window list, update the Windows menus */ addToWindowList(window); InvalidateWindowMenus(); /* realize all of the widgets in the new window */ RealizeWithoutForcingPosition(appShell); XmProcessTraversal(text, XmTRAVERSE_CURRENT); /* Make close command in window menu gracefully prompt for close */ AddMotifCloseCallback(appShell, (XtCallbackProc)closeCB, window); #ifndef NO_SESSION_RESTART /* Add wm protocol callback for making nedit restartable by session managers. Doesn't yet handle multiple-desktops or iconifying right. */ if (syAtom == 0) { wmpAtom = XmInternAtom(TheDisplay, "WM_PROTOCOLS", FALSE); syAtom = XmInternAtom(TheDisplay, "WM_SAVE_YOURSELF", FALSE); } XmAddProtocolCallback(appShell, wmpAtom, syAtom, (XtCallbackProc)saveYourselfCB, (XtPointer)window);#endif /* Make window resizing work in nice character heights */ UpdateWMSizeHints(window); /* Set the minimum pane height for the initial text pane */ UpdateMinPaneHeights(window); restoreInsaneVirtualKeyBindings(invalidBindings); return window;}/*** Close an editor window*/void CloseWindow(WindowInfo *window){ int keepWindow; char name[MAXPATHLEN]; /* Free smart indent macro programs */ EndSmartIndent(window); /* Clean up macro references to the doomed window. If a macro is executing, stop it. If macro is calling this (closing its own window), leave the window alive until the macro completes */ keepWindow = !MacroWindowCloseActions(window); #ifndef VMS /* Kill shell sub-process and free related memory */ AbortShellCommand(window);#endif /*VMS*/ /* Unload the default tips files for this language mode if necessary */ UnloadLanguageModeTipsFile(window); /* If a window is closed while it is on the multi-file replace dialog list of any other window (or even the same one), we must update those lists or we end up with dangling references. Normally, there can be only one of those dialogs at the same time (application modal), but LessTif doesn't even (always) honor application modalness, so there can be more than one dialog. */ RemoveFromMultiReplaceDialog(window); /* Destroy the file closed property for this file */ DeleteFileClosedProperty(window); /* if this is the last window, or must be kept alive temporarily because it's running the macro calling us, don't close it, make it Untitled */ if (keepWindow || (WindowList == window && window->next == NULL)) { window->filename[0] = '\0'; UniqueUntitledName(name); CLEAR_ALL_LOCKS(window->lockReasons); window->fileMode = 0; strcpy(window->filename, name); strcpy(window->path, ""); window->ignoreModify = TRUE; BufSetAll(window->buffer, ""); window->ignoreModify = FALSE; window->filenameSet = FALSE; window->fileMissing = TRUE; window->fileChanged = FALSE; window->fileFormat = UNIX_FILE_FORMAT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -