📄 window.c
字号:
static const char CVSID[] = "$Id: window.c,v 1.84.2.1 2003/08/01 01:26:42 n8gray Exp $";/******************************************************************************** ** window.c -- Nirvana Editor window creation/deletion ** ** Copyright (C) 1999 Mark Edel ** ** This is free software; you can redistribute it and/or modify it under the ** terms of the GNU General Public License as published by the Free Software ** Foundation; either version 2 of the License, or (at your option) any later ** version. ** ** This software is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ** for more details. ** ** You should have received a copy of the GNU General Public License along with ** software; if not, write to the Free Software Foundation, Inc., 59 Temple ** Place, Suite 330, Boston, MA 02111-1307 USA ** ** Nirvana Text Editor ** May 10, 1991 ** ** Written by Mark Edel ** ********************************************************************************/#ifdef HAVE_CONFIG_H#include "../config.h"#endif#include "window.h"#include "textBuf.h"#include "textSel.h"#include "text.h"#include "textDisp.h"#include "textP.h"#include "nedit.h"#include "menu.h"#include "file.h"#include "search.h"#include "undo.h"#include "preferences.h"#include "selection.h"#include "server.h"#include "shell.h"#include "macro.h"#include "highlight.h"#include "smartIndent.h"#include "userCmds.h"#include "nedit.bm"#include "n.bm"#include "windowTitle.h"#include "../util/clearcase.h"#include "../util/misc.h"#include "../util/fileUtils.h"#include "../util/utils.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef VMS#include "../util/VMSparam.h"#else#ifndef __MVS__#include <sys/param.h>#endif#include "../util/clearcase.h"#endif /*VMS*/#include <limits.h>#include <math.h>#include <ctype.h>#include <time.h>#ifdef __unix__#include <sys/time.h>#endif#include <X11/Intrinsic.h>#include <X11/Shell.h>#include <X11/Xatom.h>#include <Xm/Xm.h>#include <Xm/MainW.h>#include <Xm/PanedW.h>#include <Xm/PanedWP.h>#include <Xm/RowColumnP.h>#include <Xm/Text.h>#include <Xm/ToggleB.h>#include <Xm/Form.h>#include <Xm/Label.h>#include <Xm/Protocols.h>#include <Xm/ScrolledW.h>#include <Xm/ScrollBar.h>#include <Xm/PrimitiveP.h>#include <Xm/Frame.h>#ifdef EDITRES#include <X11/Xmu/Editres.h>/* extern void _XEditResCheckMessages(); */#endif /* EDITRES */#ifdef HAVE_DEBUG_H#include "../debug.h"#endif/* Initial minimum height of a pane. Just a fallback in case setPaneMinHeight (which may break in a future release) is not available */#define PANE_MIN_HEIGHT 39/* Thickness of 3D border around statistics and/or incremental search areas below the main menu bar */#define STAT_SHADOW_THICKNESS 1static Widget createTextArea(Widget parent, WindowInfo *window, int rows, int cols, int emTabDist, char *delimiters, int wrapMargin, int lineNumCols);static void showStats(WindowInfo *window, int state);static void showISearch(WindowInfo *window, int state);static void showStatsForm(WindowInfo *window, int state);static void addToWindowList(WindowInfo *window);static void removeFromWindowList(WindowInfo *window);static void focusCB(Widget w, WindowInfo *window, XtPointer callData);static void modifiedCB(int pos, int nInserted, int nDeleted, int nRestyled, char *deletedText, void *cbArg);static void movedCB(Widget w, WindowInfo *window, XtPointer callData);static void dragStartCB(Widget w, WindowInfo *window, XtPointer callData);static void dragEndCB(Widget w, WindowInfo *window, dragEndCBStruct *callData);static void closeCB(Widget w, WindowInfo *window, XtPointer callData);static void saveYourselfCB(Widget w, WindowInfo *window, XtPointer callData);static int isIconic(WindowInfo *window);static void setPaneDesiredHeight(Widget w, int height);static void setPaneMinHeight(Widget w, int min);static void addWindowIcon(Widget shell);static void wmSizeUpdateProc(XtPointer clientData, XtIntervalId *id);static void getGeometryString(WindowInfo *window, char *geomString);#ifdef ROWCOLPATCHstatic void patchRowCol(Widget w);static void patchedRemoveChild(Widget child);#endifstatic unsigned char* sanitizeVirtualKeyBindings();static int sortAlphabetical(const void* k1, const void* k2);static int virtKeyBindingsAreInvalid(const unsigned char* bindings);static void restoreInsaneVirtualKeyBindings(unsigned char* bindings);static Widget containingPane(Widget w);/*** Create a new editor window*/WindowInfo *CreateWindow(const char *name, char *geometry, int iconic){ Widget appShell, mainWin, menuBar, pane, text, stats, statsAreaForm; Widget iSearchLabel; WindowInfo *window; Pixel bgpix, fgpix; Arg al[20]; int ac; XmString s1;#ifdef SGI_CUSTOM char sgi_title[MAXPATHLEN + 14 + SGI_WINDOW_TITLE_LEN] = SGI_WINDOW_TITLE; #endif char newGeometry[MAX_GEOM_STRING_LEN]; unsigned int rows, cols; int x, y, bitmask; static Atom wmpAtom, syAtom = 0; static int firstTime = True; unsigned char* invalidBindings = NULL; if (firstTime) { invalidBindings = sanitizeVirtualKeyBindings(); firstTime = False; } /* Allocate some memory for the new window data structure */ window = (WindowInfo *)XtMalloc(sizeof(WindowInfo)); /* initialize window structure */ /* + Schwarzenberg: should a memset(window, 0, sizeof(WindowInfo)); be added here ? */ window->replaceDlog = NULL; window->replaceText = NULL; window->replaceWithText = NULL; window->replaceWordToggle = NULL; window->replaceCaseToggle = NULL; window->replaceRegexToggle = NULL; window->findDlog = NULL; window->findText = NULL; window->findWordToggle = NULL; window->findCaseToggle = NULL; window->findRegexToggle = NULL; window->replaceMultiFileDlog = NULL; window->replaceMultiFilePathBtn = NULL; window->replaceMultiFileList = NULL; window->multiFileReplSelected = FALSE; window->multiFileBusy = FALSE; window->writableWindows = NULL; window->nWritableWindows = 0; window->fileChanged = FALSE; window->fileMode = 0; window->filenameSet = FALSE; window->fileFormat = UNIX_FILE_FORMAT; window->lastModTime = 0; window->fileMissing = True; strcpy(window->filename, name); window->undo = NULL; window->redo = NULL; window->nPanes = 0; window->autoSaveCharCount = 0; window->autoSaveOpCount = 0; window->undoOpCount = 0; window->undoMemUsed = 0; CLEAR_ALL_LOCKS(window->lockReasons); window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE); window->autoSave = GetPrefAutoSave(); window->saveOldVersion = GetPrefSaveOldVersion(); window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE); window->overstrike = False; window->showMatchingStyle = GetPrefShowMatching(); window->matchSyntaxBased = GetPrefMatchSyntaxBased(); window->showStats = GetPrefStatsLine(); window->showISearchLine = GetPrefISearchLine(); window->showLineNumbers = GetPrefLineNums(); window->highlightSyntax = GetPrefHighlightSyntax(); window->backlightCharTypes = NULL; window->backlightChars = GetPrefBacklightChars(); if (window->backlightChars) { char *cTypes = GetPrefBacklightCharTypes(); if (cTypes && window->backlightChars) { if ((window->backlightCharTypes = XtMalloc(strlen(cTypes) + 1))) strcpy(window->backlightCharTypes, cTypes); } } window->modeMessageDisplayed = FALSE; window->ignoreModify = FALSE; window->windowMenuValid = FALSE; window->prevOpenMenuValid = FALSE; window->flashTimeoutID = 0; window->fileClosedAtom = None; window->wasSelected = FALSE; strcpy(window->fontName, GetPrefFontName()); strcpy(window->italicFontName, GetPrefItalicFontName()); strcpy(window->boldFontName, GetPrefBoldFontName()); strcpy(window->boldItalicFontName, GetPrefBoldItalicFontName()); window->colorDialog = NULL; window->fontList = GetPrefFontList(); window->italicFontStruct = GetPrefItalicFont(); window->boldFontStruct = GetPrefBoldFont(); window->boldItalicFontStruct = GetPrefBoldItalicFont(); window->fontDialog = NULL; window->nMarks = 0; window->markTimeoutID = 0; window->highlightData = NULL; window->shellCmdData = NULL; window->macroCmdData = NULL; window->smartIndentData = NULL; window->languageMode = PLAIN_LANGUAGE_MODE; window->iSearchHistIndex = 0; window->iSearchStartPos = -1; window->replaceLastRegexCase = TRUE; window->replaceLastLiteralCase = FALSE; window->iSearchLastRegexCase = TRUE; window->iSearchLastLiteralCase = FALSE; window->findLastRegexCase = TRUE; window->findLastLiteralCase = FALSE; /* If window geometry was specified, split it apart into a window position component and a window size component. Create a new geometry string containing the position component only. Rows and cols are stripped off because we can't easily calculate the size in pixels from them until the whole window is put together. Note that the preference resource is only for clueless users who decide to specify the standard X geometry application resource, which is pretty useless because width and height are the same as the rows and cols preferences, and specifying a window location will force all the windows to pile on top of one another */ if (geometry == NULL || geometry[0] == '\0') geometry = GetPrefGeometry(); if (geometry == NULL || geometry[0] == '\0') { rows = GetPrefRows(); cols = GetPrefCols(); newGeometry[0] = '\0'; } else { bitmask = XParseGeometry(geometry, &x, &y, &cols, &rows); if (bitmask == 0) fprintf(stderr, "Bad window geometry specified: %s\n", geometry); else { if (!(bitmask & WidthValue)) cols = GetPrefCols(); if (!(bitmask & HeightValue)) rows = GetPrefRows(); } CreateGeometryString(newGeometry, x, y, 0, 0, bitmask & ~(WidthValue | HeightValue)); } /* Create a new toplevel shell to hold the window */ ac = 0;#ifdef SGI_CUSTOM strcat(sgi_title, name); XtSetArg(al[ac], XmNtitle, sgi_title); ac++; XtSetArg(al[ac], XmNdeleteResponse, XmDO_NOTHING); ac++; if (strncmp(name, "Untitled", 8) == 0) { XtSetArg(al[ac], XmNiconName, APP_NAME); ac++; } else { XtSetArg(al[ac], XmNiconName, name); ac++; }#else XtSetArg(al[ac], XmNtitle, name); ac++; XtSetArg(al[ac], XmNdeleteResponse, XmDO_NOTHING); ac++; XtSetArg(al[ac], XmNiconName, name); ac++;#endif XtSetArg(al[ac], XmNgeometry, newGeometry[0]=='\0'?NULL:newGeometry); ac++; XtSetArg(al[ac], XmNinitialState, iconic ? IconicState : NormalState); ac++; appShell = CreateShellWithBestVis(APP_NAME, APP_CLASS, applicationShellWidgetClass, TheDisplay, al, ac); window->shell = appShell;#ifdef EDITRES XtAddEventHandler (appShell, (EventMask)0, True, (XtEventHandler)_XEditResCheckMessages, NULL);#endif /* EDITRES */#ifndef SGI_CUSTOM addWindowIcon(appShell);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -