#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 "interpret.h"
#include "rangeset.h"
#include "highlightData.h"
#include "../util/clearcase.h"
#include "../util/misc.h"
#include "../util/fileUtils.h"
#include "../util/utils.h"
#include "../util/fileUtils.h"
#include "../util/DialogF.h"
#include "../util/dragAndDrop.h"
#include "../Xlt/BubbleButtonP.h"
#include "../Microline/XmL/Folder.h"
#include "../util/nedit_malloc.h"
#include "../util/textfield.h"
#include "../util/fontsel.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <langinfo.h>
#include <sys/param.h>
#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/Separator.h>
#include <Xm/Text.h>
#include <Xm/ToggleB.h>
#include <Xm/PushB.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>
#include <Xm/SelectioB.h>
#include <Xm/List.h>
#include <Xm/Protocols.h>
#include <Xm/ScrolledW.h>
#include <Xm/ScrollBar.h>
#include <Xm/PrimitiveP.h>
#include <Xm/Frame.h>
#include <Xm/CascadeB.h>
#ifndef __sun
#include <Xm/DropDown.h>
#else
Widget XmCreateDropDown(Widget parent, String name, ArgList args, Cardinal argcount);
#endif
#ifdef EDITRES
#include <X11/Xmu/Editres.h>
#endif
#ifdef HAVE_DEBUG_H
#include "../debug.h"
#endif
#define PANE_MIN_HEIGHT 39
#define STAT_SHADOW_THICKNESS 1
#define close_width
11
#define close_height
11
static unsigned char close_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x8c, 0x01, 0xdc, 0x01, 0xf8, 0x00, 0x70, 0x00,
0xf8, 0x00, 0xdc, 0x01, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00};
#define close_m_width
17
#define close_m_height
17
static unsigned char close_m_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x00,
0x38, 0x38, 0x00, 0x70, 0x1c, 0x00, 0xe0, 0x0e, 0x00, 0xc0, 0x07, 0x00,
0x80, 0x03, 0x00, 0xc0, 0x07, 0x00, 0xe0, 0x0e, 0x00, 0x70, 0x1c, 0x00,
0x38, 0x38, 0x00, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00 };
#define close_l_width
23
#define close_l_height
23
static unsigned char close_l_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f,
0xf8, 0x80, 0x0f, 0xf8, 0xc1, 0x0f, 0xf8, 0xe3, 0x0f, 0xf0, 0xf7, 0x07,
0xe0, 0xff, 0x03, 0xc0, 0xff, 0x01, 0x80, 0xff, 0x00, 0x00, 0x7f, 0x00,
0x80, 0xff, 0x00, 0xc0, 0xff, 0x01, 0xe0, 0xff, 0x03, 0xf0, 0xf7, 0x07,
0xf8, 0xe3, 0x0f, 0xf8, 0xc1, 0x0f, 0xf8, 0x80, 0x0f, 0x78, 0x00, 0x0f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
#define isrcFind_width
11
#define isrcFind_height
11
static unsigned char isrcFind_bits[] = {
0xe0, 0x01, 0x10, 0x02, 0xc8, 0x04, 0x08, 0x04, 0x08, 0x04, 0x00, 0x04,
0x18, 0x02, 0xdc, 0x01, 0x0e, 0x00, 0x07, 0x00, 0x03, 0x00};
#define isrcFind_m_width
17
#define isrcFind_m_height
17
static unsigned char isrcFind_m_bits[] = {
0x00, 0x1f, 0x00, 0x80, 0x3f, 0x00, 0xc0, 0x60, 0x00, 0x60, 0xc0, 0x00,
0x20, 0x8e, 0x00, 0x20, 0x80, 0x00, 0x20, 0x80, 0x00, 0x00, 0x80, 0x00,
0x00, 0xc0, 0x00, 0xe0, 0x60, 0x00, 0xf0, 0x38, 0x00, 0xf8, 0x1e, 0x00,
0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x0f, 0x00, 0x00,
0x07, 0x00, 0x00 };
#define isrcFind_l_width
23
#define isrcFind_l_height
23
static unsigned char isrcFind_l_bits[] = {
0x00, 0xe0, 0x01, 0x00, 0xf8, 0x07, 0x00, 0x1c, 0x0e, 0x00, 0x0e, 0x1c,
0x00, 0x07, 0x38, 0x00, 0xe3, 0x31, 0x80, 0xe1, 0x61, 0x80, 0x01, 0x60,
0x80, 0x01, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38,
0x80, 0x07, 0x1c, 0xc0, 0x07, 0x0e, 0xe0, 0xc7, 0x07, 0xf0, 0xc7, 0x01,
0xf8, 0x03, 0x00, 0xfc, 0x01, 0x00, 0xfe, 0x00, 0x00, 0x7f, 0x00, 0x00,
0x3f, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x0f, 0x00, 0x00 };
#define isrcClear_width
11
#define isrcClear_height
11
static unsigned char isrcClear_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x84, 0x01, 0xc4, 0x00, 0x64, 0x00,
0xc4, 0x00, 0x84, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00};
#define isrcClear_m_width
17
#define isrcClear_m_height
17
static unsigned char isrcClear_m_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x00,
0x18, 0x30, 0x00, 0x18, 0x18, 0x00, 0x18, 0x0c, 0x00, 0x18, 0x06, 0x00,
0x18, 0x03, 0x00, 0x18, 0x06, 0x00, 0x18, 0x0c, 0x00, 0x18, 0x18, 0x00,
0x18, 0x30, 0x00, 0x18, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00 };
#define isrcClear_l_width
23
#define isrcClear_l_height
23
static unsigned char isrcClear_l_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x30, 0x00, 0x02, 0x30, 0x00, 0x03, 0x30, 0x80, 0x03, 0x30, 0xc0, 0x01,
0x30, 0xe0, 0x00, 0x30, 0x70, 0x00, 0x30, 0x38, 0x00, 0x30, 0x1c, 0x00,
0x30, 0x38, 0x00, 0x30, 0x70, 0x00, 0x30, 0xe0, 0x00, 0x30, 0xc0, 0x01,
0x30, 0x80, 0x03, 0x30, 0x00, 0x03, 0x30, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
extern void _XmDismissTearOff(Widget, XtPointer, XtPointer);
static void hideTooltip(Widget tab);
static Pixmap createBitmapWithDepth(Widget w,
char *data,
unsigned int width,
unsigned int height);
static void createSearchForm(WindowInfo *window);
static WindowInfo *getNextTabWindow(WindowInfo *window,
int direction,
int crossWin,
int wrap);
static Widget addTab(Widget folder,
const char *string);
static int compareWindowNames(
const void *windowA,
const void *windowB);
static int getTabPosition(Widget tab);
static Widget manageToolBars(Widget toolBarsForm);
static void hideTearOffs(Widget menuPane);
static void CloseDocumentWindow(Widget w, WindowInfo *window, XtPointer callData);
static void closeTabCB(Widget w, Widget mainWin,
caddr_t callData);
static void raiseTabCB(Widget w, XtPointer clientData, XtPointer callData);
static 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);
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,
const char *deletedText,
void *cbArg);
static void beginModifyCB(
void *cbArg);
static void endModifyCB(
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, Widget appShell, XtPointer callData);
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 ROWCOLPATCH
static void patchRowCol(Widget w);
static void patchedRemoveChild(Widget child);
#endif
static void refreshMenuBar(WindowInfo *window);
static void cloneDocument(WindowInfo *window, WindowInfo *orgWin);
static void cloneTextPanes(WindowInfo *window, WindowInfo *orgWin);
static UndoInfo *cloneUndoItems(UndoInfo *orgList);
static Widget containingPane(Widget w);
static WindowInfo *inFocusDocument =
NULL;
static WindowInfo *lastFocusDocument =
NULL;
static int DoneWithMoveDocumentDialog;
static int updateLineNumDisp(WindowInfo* window);
static int updateGutterWidth(WindowInfo* window);
static void deleteDocument(WindowInfo *window);
static void cancelTimeOut(XtIntervalId *timer);
static void WindowTakeFocus(Widget shell, WindowInfo *window, XtPointer d);
static void closeInfoBarCB(Widget w, Widget mainWin,
void *callData);
static void jumpToEncErrorCB(Widget w, Widget mainWin, XmComboBoxCallbackStruct *cb);
static void reloadCB(Widget w, Widget mainWin,
void *callData);
static void windowStructureNotifyEventEH(
Widget widget,
XtPointer data,
XEvent *event,
Boolean *dispatch);
static const Dimension
XT_IGNORE_PPOSITION =
32767;
static Atom wm_take_focus;
static int take_focus_atom_is_init =
0;
static Bool CopyDBEntry(
XrmDatabase *db,
XrmBindingList bindings,
XrmQuarkList quarks,
XrmRepresentation *type,
XrmValuePtr value,
XPointer data)
{
XrmDatabase newDB = (XrmDatabase)data;
XrmQPutResource(&newDB, bindings, quarks, *type, value);
return 0;
}
void LoadColorProfileResources(Display *display, ColorProfile *profile)
{
if(profile->resourceFile) {
const char *fpath;
char *fpathFree =
NULL;
if(profile->resourceFile[
0] ==
'/') {
fpath = profile->resourceFile;
}
else {
const char *xneditHome = GetRCFileName(
XNEDIT_HOME);
size_t xneditHomeLen = strlen(xneditHome);
size_t resFileLen = strlen(profile->resourceFile);
fpathFree = NEditMalloc(xneditHomeLen + resFileLen +
1);
memcpy(fpathFree, xneditHome, xneditHomeLen);
memcpy(fpathFree+xneditHomeLen, profile->resourceFile, resFileLen);
fpathFree[xneditHomeLen+resFileLen] =
0;
fpath = fpathFree;
}
XrmDatabase defaultDB = GetDefaultResourceDB();
XrmDatabase newDB = XrmGetStringDatabase(
"");
XrmQuark empty =
NULLQUARK;
XrmEnumerateDatabase(defaultDB, &empty, &empty, XrmEnumAllLevels, CopyDBEntry, (XPointer) newDB);
XrmDatabase resFileDB = XrmGetFileDatabase(fpath);
if(resFileDB) {
XrmMergeDatabases(resFileDB, &newDB);
}
NEditFree(fpathFree);
profile->db = newDB;
}
else {
profile->db = GetDefaultResourceDB();
}
profile->resDBLoaded = True;
}
static Pixmap isrcFind =
0;
static Pixmap isrcClear =
0;
static Pixmap closeTabPixmap =
0;
WindowInfo *CreateWindow(
const char *name,
char *geometry,
int iconic)
{
Widget winShell, mainWin, menuBar, pane, text, stats, statsAreaForm;
Widget closeTabBtn, tabForm, form;
WindowInfo *window;
Pixel bgpix, fgpix;
Arg al[
20];
int ac;
XmString s1;
XmFontList statsFontList;
WindowInfo *win;
char newGeometry[
MAX_GEOM_STRING_LEN];
unsigned int rows, cols;
int x =
0, y =
0, bitmask, showTabBar, state;
ColorProfile *colorProfile = GetDefaultColorProfile();
if(!colorProfile->db) {
LoadColorProfileResources(TheDisplay, colorProfile);
}
XrmSetDatabase(TheDisplay, colorProfile->db);
window = (WindowInfo *)NEditMalloc(
sizeof(WindowInfo));
window->opened = False;
window->colorProfile = colorProfile;
window->wrapModeNoneForced = False;
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->fileUid =
0;
window->fileGid =
0;
window->filenameSet =
FALSE;
window->fileFormat =
UNIX_FILE_FORMAT;
window->lastModTime =
0;
window->fileMissing = True;
strcpy(window->filename, name);
window->encErrors =
NULL;
window->numEncErrors =
0;
window->posEncErrors =
0;
window->encoding[
0] =
'\0';
window->filter =
NULL;
const char *default_encoding = GetPrefDefaultCharset();
if(default_encoding) {
size_t defenc_len = strlen(default_encoding);
if(strlen(default_encoding) <
MAX_ENCODING_LENGTH) {
memcpy(window->encoding, default_encoding, defenc_len+
1);
}
}
window->bom =
FALSE;
window->undo =
NULL;
window->redo =
NULL;
window->undo_batch_begin =
NULL;
window->undo_batch_count =
0;
window->undo_op_batch_size =
0;
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->showInfoBar = False;
window->highlightSyntax = GetPrefHighlightSyntax();
window->highlightCursorLine = GetPrefHighlightCursorLine();
window->indentRainbow = GetPrefIndentRainbow();
window->indentRainbowColors = NEditStrdup(GetPrefIndentRainbowColors());
window->ansiColors = GetPrefAnsiColors();
window->backlightCharTypes =
NULL;
window->backlightChars = GetPrefBacklightChars();
if (window->backlightChars) {
char *cTypes = GetPrefBacklightCharTypes();
if (cTypes && window->backlightChars) {
if ((window->backlightCharTypes = (
char*)NEditMalloc(strlen(cTypes) +
1)))
strcpy(window->backlightCharTypes, cTypes);
}
}
window->modeMessageDisplayed =
FALSE;
window->modeMessage =
NULL;
window->ignoreModify =
FALSE;
window->windowMenuValid =
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->font = FontRef(GetPrefFont());
window->italicFont = FontRef(GetPrefItalicFont());
window->boldFont = FontRef(GetPrefBoldFont());
window->boldItalicFont = FontRef(GetPrefBoldItalicFont());
window->resizeOnFontChange = True;
window->zoom =
0;
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;
window->tab =
NULL;
window->bgMenuUndoItem =
NULL;
window->bgMenuRedoItem =
NULL;
window->device =
0;
window->inode =
0;
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));
}
ac =
0;
XtSetArg(al[ac], XmNtitle, name); ac++;
XtSetArg(al[ac], XmNdeleteResponse, XmDO_NOTHING); ac++;
#ifdef SGI_CUSTOM
if (strncmp(name,
"Untitled",
8) ==
0) {
XtSetArg(al[ac], XmNiconName,
APP_NAME); ac++;
}
else {
XtSetArg(al[ac], XmNiconName, name); ac++;
}
#else
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++;
if (newGeometry[
0] ==
'\0')
{
XtSetArg(al[ac], XtNx,
XT_IGNORE_PPOSITION); ac++;
XtSetArg(al[ac], XtNy,
XT_IGNORE_PPOSITION); ac++;
}
winShell = CreateWidget(TheAppShell,
"textShell",
topLevelShellWidgetClass, al, ac);
window->shell = winShell;
#ifdef EDITRES
XtAddEventHandler (winShell, (EventMask)
0, True,
(XtEventHandler)_XEditResCheckMessages,
NULL);
#endif
#ifndef SGI_CUSTOM
addWindowIcon(winShell);
#endif
XtAddEventHandler(
winShell,
StructureNotifyMask,
False,
(XtEventHandler)windowStructureNotifyEventEH,
window);
XtSetArg(al[ac], XmNuserData, window); ac++;
mainWin = XmCreateMainWindow(winShell,
"main", al, ac);
window->mainWin = mainWin;
XtManageChild(mainWin);
statsAreaForm = XtVaCreateWidget(
"statsAreaForm",
xmFormWidgetClass, mainWin,
XmNmarginWidth,
STAT_SHADOW_THICKNESS,
XmNmarginHeight,
STAT_SHADOW_THICKNESS,
NULL);
window->iSearchForm = XtVaCreateWidget(
"iSearchForm",
xmFormWidgetClass, statsAreaForm,
XmNshadowThickness,
0,
XmNleftAttachment, XmATTACH_FORM,
XmNleftOffset,
STAT_SHADOW_THICKNESS,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset,
STAT_SHADOW_THICKNESS,
XmNrightAttachment, XmATTACH_FORM,
XmNrightOffset,
STAT_SHADOW_THICKNESS,
XmNbottomOffset,
STAT_SHADOW_THICKNESS,
NULL);
if(window->showISearchLine)
XtManageChild(window->iSearchForm);
createSearchForm(window);
tabForm = XtVaCreateWidget(
"tabForm",
xmFormWidgetClass, statsAreaForm,
XmNmarginHeight,
0,
XmNmarginWidth,
0,
XmNspacing,
0,
XmNresizable, False,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNshadowThickness,
0,
NULL);
if (closeTabPixmap ==
0) {
switch(GetPrefCloseIconSize()) {
default: {
closeTabPixmap = createBitmapWithDepth(tabForm,
(
char *)close_bits, close_width, close_height);
break;
}
case 1: {
closeTabPixmap = createBitmapWithDepth(tabForm,
(
char *)close_m_bits, close_m_width, close_m_height);
break;
}
case 2: {
closeTabPixmap = createBitmapWithDepth(tabForm,
(
char *)close_l_bits, close_l_width, close_l_height);
break;
}
}
}
closeTabBtn = XtVaCreateManagedWidget(
"closeTabBtn",
xmPushButtonWidgetClass, tabForm,
XmNmarginHeight,
0,
XmNmarginWidth,
0,
XmNhighlightThickness,
0,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, closeTabPixmap,
XmNshadowThickness,
1,
XmNtraversalOn, False,
XmNrightAttachment, XmATTACH_FORM,
XmNrightOffset,
3,
XmNbottomAttachment, XmATTACH_FORM,
XmNbottomOffset,
3,
NULL);
XtAddCallback(closeTabBtn, XmNactivateCallback, (XtCallbackProc)closeTabCB,
mainWin);
window->tabBar = XtVaCreateManagedWidget(
"tabBar",
xmlFolderWidgetClass, tabForm,
XmNresizePolicy, XmRESIZE_PACK,
XmNleftAttachment, XmATTACH_FORM,
XmNleftOffset,
0,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, closeTabBtn,
XmNrightOffset,
5,
XmNbottomAttachment, XmATTACH_FORM,
XmNbottomOffset,
0,
XmNtopAttachment, XmATTACH_FORM,
NULL);
window->tabMenuPane = CreateTabContextMenu(window->tabBar, window);
AddTabContextMenuAction(window->tabBar);
form = XtVaCreateWidget(
"form",
xmFormWidgetClass, window->tabBar,
XmNheight,
1,
XmNresizable, False,
NULL);
XtAddCallback(window->tabBar, XmNactivateCallback,
raiseTabCB,
NULL);
window->tab = addTab(window->tabBar, name);
window->statsLineForm = XtVaCreateWidget(
"statsLineForm",
xmFormWidgetClass, statsAreaForm,
XmNshadowThickness,
0,
XmNtopAttachment, window->showISearchLine ?
XmATTACH_WIDGET : XmATTACH_FORM,
XmNtopWidget, window->iSearchForm,
XmNrightAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNresizable, False,
NULL);
window->statsLineColNo = XtVaCreateManagedWidget(
"statsLineColNo",
xmLabelWidgetClass, window->statsLineForm,
XmNlabelString, s1=XmStringCreateSimple(
"S: --- L: --- C: ---"),
XmNshadowThickness,
0,
XmNmarginHeight,
2,
XmNtraversalOn, False,
XmNtopAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
NULL);
XmStringFree(s1);
XtVaGetValues(window->statsLineForm, XmNbackground, &bgpix,
NULL);
XtVaGetValues(window->statsLineForm, XmNforeground, &fgpix,
NULL);
stats = XtVaCreateManagedWidget(
"statsLine",
xmTextWidgetClass, window->statsLineForm,
XmNbackground, bgpix,
XmNforeground, fgpix,
XmNshadowThickness,
0,
XmNhighlightColor, bgpix,
XmNhighlightThickness,
0,
XmNmarginHeight,
1,
XmNscrollHorizontal, False,
XmNeditMode, XmSINGLE_LINE_EDIT,
XmNeditable, False,
XmNtraversalOn, False,
XmNcursorPositionVisible, False,
XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNtopWidget, window->statsLineColNo,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, window->statsLineColNo,
XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNbottomWidget, window->statsLineColNo,
XmNrightOffset,
3,
NULL);
window->statsLine = stats;
XtVaGetValues(window->statsLineColNo, XmNfontList, &statsFontList,
NULL);
XtVaSetValues(window->statsLine, XmNfontList, statsFontList,
NULL);
if(window->showStats)
XtManageChild(window->statsLineForm);
window->encodingInfoBar = XtVaCreateWidget(
"infobar",
xmFormWidgetClass,
statsAreaForm,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, window->statsLineForm,
XmNbottomAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
NULL);
ac =
0;
XtSetArg(al[ac], XmNcolumns,
15); ac++;
XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
XtSetArg(al[ac], XmNhighlightThickness,
1); ac++;
window->encInfoBarList = XmCreateDropDownList(
window->encodingInfoBar,
"combobox",
al,
ac);
XtManageChild(window->encInfoBarList);
window->encInfoBarLabel = XtVaCreateManagedWidget(
"ibarlabel",
xmLabelWidgetClass,
window->encodingInfoBar,
XmNleftAttachment, XmATTACH_FORM,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_WIDGET,
XmNbottomWidget, window->encInfoBarList,
NULL);
ac =
0;
XtSetArg(al[ac], XmNcolumns,
15); ac++;
XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
XtSetArg(al[ac], XmNhighlightThickness,
1); ac++;
XtSetArg(al[ac], XmNvalue,
"Errors"); ac++;
window->encInfoErrorList = XmCreateDropDownList(
window->encodingInfoBar,
"combobox",
al,
ac);
XtAddCallback(window->encInfoErrorList, XmNselectionCallback,
(XtCallbackProc)jumpToEncErrorCB, mainWin);
Widget btnClose = XtVaCreateManagedWidget(
"ibarbutton",
xmPushButtonWidgetClass,
window->encodingInfoBar,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, closeTabPixmap,
XmNtopAttachment, XmATTACH_WIDGET,
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_WIDGET,
XmNbottomWidget, window->encInfoBarList,
XmNhighlightThickness,
1,
NULL);
XtAddCallback(btnClose, XmNactivateCallback, (XtCallbackProc)closeInfoBarCB,
mainWin);
s1 = XmStringCreateSimple(
"Reload");
Widget btnReload = XtVaCreateManagedWidget(
"ibarbutton",
xmPushButtonWidgetClass,
window->encodingInfoBar,
XmNlabelString, s1,
XmNtopAttachment, XmATTACH_WIDGET,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, btnClose,
XmNbottomAttachment, XmATTACH_WIDGET,
XmNbottomWidget, window->encInfoBarList,
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNleftWidget, window->encInfoBarList,
XmNhighlightThickness,
1,
NULL);
XtAddCallback(btnReload, XmNactivateCallback, (XtCallbackProc)reloadCB,
mainWin);
XmStringFree(s1);
menuBar = CreateMenuBar(mainWin, window);
window->menuBar = menuBar;
XtManageChild(menuBar);
pane = XtVaCreateManagedWidget(
"pane", xmPanedWindowWidgetClass, mainWin,
XmNseparatorOn, False,
XmNspacing,
3, XmNsashIndent, -
2,
NULL);
window->splitPane = pane;
XmMainWindowSetAreas(mainWin, menuBar, statsAreaForm,
NULL,
NULL, pane);
XtVaSetValues(pane, XmNuserData, window,
NULL);
AccelLockBugPatch(pane, window->menuBar);
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;
SetColorProfile(window, GetDefaultColorProfile());
window->bgMenuPane = CreateBGMenu(window);
InitUserBGMenuCache(&window->userBGMenuCache);
window->buffer = BufCreate();
BufAddModifyCB(window->buffer, SyntaxHighlightModifyCB, window);
TextSetBuffer(text, window->buffer);
BufAddModifyCB(window->buffer, modifiedCB, window);
BufAddBeginModifyCB(window->buffer, beginModifyCB, window);
BufAddEndModifyCB(window->buffer, endModifyCB, window);
HandleXSelections(text);
BufSetTabDistance(window->buffer, GetPrefTabDist(
PLAIN_LANGUAGE_MODE));
window->buffer->useTabs = GetPrefInsertTabs();
addToWindowList(window);
InvalidateWindowMenus();
showTabBar = GetShowTabBar(window);
if (showTabBar)
XtManageChild(tabForm);
manageToolBars(statsAreaForm);
if (showTabBar || window->showISearchLine ||
window->showStats || window->showInfoBar)
{
XtManageChild(statsAreaForm);
}
RealizeWithoutForcingPosition(winShell);
XmProcessTraversal(text, XmTRAVERSE_CURRENT);
AddMotifCloseCallback(winShell, (XtCallbackProc)closeCB, window);
if(!take_focus_atom_is_init) {
wm_take_focus = XmInternAtom(
XtDisplay(winShell),
"WM_TAKE_FOCUS",
0);
take_focus_atom_is_init =
1;
}
XmAddWMProtocolCallback(
winShell,
wm_take_focus,
(XtCallbackProc)WindowTakeFocus,
window);
UpdateWMSizeHints(window);
UpdateMinPaneHeights(window);
CreateFindDlog(window->shell, window);
CreateReplaceDlog(window->shell, window);
CreateReplaceMultiFileDlog(window);
state = NDocuments(window) < NWindows();
for(win=WindowList; win; win=win->next) {
if (IsTopDocument(win)) {
XtSetSensitive(win->moveDocumentItem, state);
XtSetSensitive(win->contextMoveDocumentItem, state);
}
}
return window;
}
static void createSearchForm(WindowInfo *window)
{
XmString s1;
if (isrcFind ==
0) {
switch(GetPrefISrcFindIconSize()) {
default: {
isrcFind = createBitmapWithDepth(window->iSearchForm,
(
char *)isrcFind_bits, isrcFind_width, isrcFind_height);
break;
}
case 1: {
isrcFind = createBitmapWithDepth(window->iSearchForm,
(
char *)isrcFind_m_bits, isrcFind_m_width, isrcFind_m_height);
break;
}
case 2: {
isrcFind = createBitmapWithDepth(window->iSearchForm,
(
char *)isrcFind_l_bits, isrcFind_l_width, isrcFind_l_height);
break;
}
}
}
window->iSearchFindButton = XtVaCreateManagedWidget(
"iSearchFindButton",
xmPushButtonWidgetClass, window->iSearchForm,
XmNlabelString, s1=XmStringCreateSimple(
"Find"),
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, isrcFind,
XmNtraversalOn, False,
XmNmarginHeight,
1,
XmNmarginWidth,
1,
XmNleftAttachment, XmATTACH_FORM,
XmNleftOffset,
0,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset,
1,
XmNbottomAttachment, XmATTACH_FORM,
XmNbottomOffset,
1,
NULL);
XmStringFree(s1);
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,
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,
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,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, window->iSearchRegexToggle,
XmNmarginHeight,
0,
XmNtraversalOn, False,
NULL);
XmStringFree(s1);
if (isrcClear ==
0) {
switch(GetPrefISrcClearIconSize()) {
default: {
isrcClear = createBitmapWithDepth(window->iSearchForm,
(
char *)isrcClear_bits, isrcClear_width, isrcClear_height);
break;
}
case 1: {
isrcClear = createBitmapWithDepth(window->iSearchForm,
(
char *)isrcClear_m_bits, isrcClear_m_width, isrcClear_m_height);
break;
}
case 2: {
isrcClear = createBitmapWithDepth(window->iSearchForm,
(
char *)isrcClear_l_bits, isrcClear_l_width, isrcClear_l_height);
break;
}
}
}
window->iSearchClearButton = XtVaCreateManagedWidget(
"iSearchClearButton",
xmPushButtonWidgetClass, window->iSearchForm,
XmNlabelString, s1=XmStringCreateSimple(
"<x"),
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, isrcClear,
XmNtraversalOn, False,
XmNmarginHeight,
1,
XmNmarginWidth,
1,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, window->iSearchRevToggle,
XmNrightOffset,
2,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset,
1,
XmNbottomAttachment, XmATTACH_FORM,
XmNbottomOffset,
1,
NULL);
XmStringFree(s1);
window->iSearchText = XtVaCreateManagedWidget(
"iSearchText",
XNEtextfieldWidgetClass, window->iSearchForm,
XmNmarginHeight,
1,
XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, window->iSearchFindButton,
XmNrightAttachment, XmATTACH_WIDGET,
XmNrightWidget, window->iSearchClearButton,
XmNtopAttachment, XmATTACH_FORM,
XmNtopOffset,
0,
XmNbottomAttachment, XmATTACH_FORM,
XmNbottomOffset,
0,
NULL);
RemapDeleteKey(window->iSearchText);
SetISearchTextCallbacks(window);
EnableDefaultColorProfileResourceDB(XtDisplay(window->mainWin));
}
static Widget evTab;
static int motion_x;
static int motion_y;
static int pressed_x;
static int pressed_y;
static int drag_enabled =
0;
static void tabClickEH(Widget w, XtPointer clientData, XEvent *event, Boolean *dispatch)
{
if(event->type == MotionNotify) {
motion_x = event->xmotion.x;
motion_y = event->xmotion.y;
if(pressed_x !=
0 && abs(pressed_x - motion_x) >
10) {
drag_enabled =
1;
}
if(drag_enabled) {
int tx, ty;
Window tw;
XTranslateCoordinates(XtDisplay(w), XtWindow(w), XtWindow(XtParent(w)), motion_x, pressed_y, &tx, &ty, &tw);
Widget switchTab = XtWindowToWidget(XtDisplay(w), tw);
if((evTab != switchTab) && switchTab) {
SwitchTabs(evTab, switchTab);
evTab = switchTab;
}
}
}
else if(event->type == ButtonRelease) {
drag_enabled =
0;
pressed_x =
0;
pressed_y =
0;
if(event->xbutton.button ==
2) {
WindowInfo *window = TabToWindow(w);
CloseFileAndWindow(window,
PROMPT_SBC_DIALOG_RESPONSE);
*dispatch = False;
return;
}
}
else if(event->type == ButtonPress) {
evTab = w;
pressed_x = motion_x;
pressed_y = motion_y;
drag_enabled =
0;
if(event->xbutton.button ==
2) {
*dispatch = False;
}
if (BubbleButton_Timer(w)) {
XtRemoveTimeOut(BubbleButton_Timer(w));
BubbleButton_Timer(w) = (XtIntervalId)
NULL;
}
else {
hideTooltip(w);
}
}
}
static Widget addTab(Widget folder,
const char *string)
{
Widget tooltipLabel, tab;
XmString s1;
s1 = XmStringCreateSimple((
char *)string);
tab = XtVaCreateManagedWidget(
"tab",
xrwsBubbleButtonWidgetClass, folder,
XmNlabelString, s1,
XltNbubbleString, s1,
XltNshowBubble, GetPrefToolTips(),
XltNautoParkBubble, True,
XltNslidingBubble, False,
NULL);
XmStringFree(s1);
XtAddEventHandler(tab, PointerMotionMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask, False,
(XtEventHandler)tabClickEH, (XtPointer)
0);
tooltipLabel = XtNameToWidget(tab,
"*BubbleLabel");
XtVaSetValues(tooltipLabel,
XmNbackground, AllocateColor(tab, GetPrefTooltipBgColor()),
XmNforeground, AllocateColor(tab,
NEDIT_DEFAULT_FG),
NULL);
XtVaSetValues(XtParent(tooltipLabel), XmNborderWidth,
1,
NULL);
#ifdef LESSTIF_VERSION
AddTabContextMenuAction(tab);
#endif
return tab;
}
static int compareWindowNames(
const void *windowA,
const void *windowB)
{
int rc;
const WindowInfo *a = *((WindowInfo**)windowA);
const WindowInfo *b = *((WindowInfo**)windowB);
rc = strcmp(a->filename, b->filename);
if (rc !=
0)
return rc;
rc = strcmp(a->path, b->path);
return rc;
}
void SortTabBar(WindowInfo *window)
{
WindowInfo *w;
WindowInfo **windows;
WidgetList tabList;
int i, j, nDoc, tabCount;
if (!GetPrefSortTabs())
return;
nDoc = NDocuments(window);
if (nDoc <
2)
return;
windows = (WindowInfo **)NEditMalloc(
sizeof(WindowInfo *) * nDoc);
for (w=WindowList, i=
0; w!=
NULL; w=w->next) {
if (window->shell == w->shell)
windows[i++] = w;
}
qsort(windows, nDoc,
sizeof(WindowInfo *), compareWindowNames);
XtVaGetValues(window->tabBar, XmNtabWidgetList, &tabList,
XmNtabCount, &tabCount,
NULL);
for (i=
0, j=
0; i<tabCount && j<nDoc; i++) {
if (tabList[i]->core.being_destroyed)
continue;
if (IsTopDocument(windows[j]))
XmLFolderSetActiveTab(window->tabBar, i, False);
windows[j]->tab = tabList[i];
RefreshTabState(windows[j]);
j++;
}
NEditFree(windows);
}
void SwitchTabs(Widget from, Widget to)
{
WindowInfo *winFrom =
NULL;
WindowInfo *winTo =
NULL;
WidgetList tabList;
int tabCount;
for(WindowInfo *w=WindowList;w;w=w->next) {
if(w->tab == from) {
winFrom = w;
}
if(w->tab == to) {
winTo = w;
}
}
winTo->tab = from;
winFrom->tab = to;
RefreshTabState(winTo);
RefreshTabState(winFrom);
XtVaGetValues(winFrom->tabBar, XmNtabWidgetList, &tabList,
XmNtabCount, &tabCount,
NULL);
for(
int i=
0;i<tabCount;i++) {
if(tabList[i]->core.being_destroyed) {
continue;
}
if(tabList[i] == to) {
XmLFolderSetActiveTab(winFrom->tabBar, i, False);
}
}
RaiseDocument(winFrom);
}
WindowInfo *TabToWindow(Widget tab)
{
WindowInfo *win;
for (win=WindowList; win; win=win->next) {
if (win->tab == tab)
return win;
}
return NULL;
}
void CloseWindow(WindowInfo *window)
{
int keepWindow, state;
char name[
MAXPATHLEN];
WindowInfo *win, *topBuf =
NULL, *nextBuf =
NULL;
EndSmartIndent(window);
keepWindow = !MacroWindowCloseActions(window);
AbortShellCommand(window);
UnloadLanguageModeTipsFile(window);
RemoveFromMultiReplaceDialog(window);
DeleteFileClosedProperty(window);
cancelTimeOut(&window->flashTimeoutID);
cancelTimeOut(&window->markTimeoutID);
if (keepWindow || (WindowList == window && window->next ==
NULL)) {
window->filename[
0] =
'\0';
UniqueUntitledName(name);
CLEAR_ALL_LOCKS(window->lockReasons);
window->fileMode =
0;
window->fileUid =
0;
window->fileGid =
0;
strcpy(window->filename, name);
strcpy(window->path,
"");
window->ignoreModify =
TRUE;
BufSetAll(window->buffer,
"");
window->ignoreModify =
FALSE;
window->nMarks =
0;
window->filenameSet =
FALSE;
window->fileMissing =
TRUE;
window->fileChanged =
FALSE;
window->fileFormat =
UNIX_FILE_FORMAT;
window->lastModTime =
0;
window->device =
0;
window->inode =
0;
StopHighlighting(window);
EndSmartIndent(window);
UpdateWindowTitle(window);
UpdateWindowReadOnly(window);
XtSetSensitive(window->closeItem,
FALSE);
XtSetSensitive(window->readOnlyItem,
TRUE);
XmToggleButtonSetState(window->readOnlyItem,
FALSE,
FALSE);
ClearUndoList(window);
ClearRedoList(window);
XmTextSetString(window->statsLine,
"");
UpdateStatsLine(window);
DetermineLanguageMode(window, True);
RefreshTabState(window);
updateLineNumDisp(window);
return;
}
FreeHighlightingData(window);
BufRemoveModifyCB(window->buffer, modifiedCB, window);
BufRemoveModifyCB(window->buffer, SyntaxHighlightModifyCB, window);
#ifdef ROWCOLPATCH
patchRowCol(window->menuBar);
#endif
ClearUndoList(window);
ClearRedoList(window);
if (NDocuments(window) >
1) {
if (MacroRunWindow() && MacroRunWindow() != window
&& MacroRunWindow()->shell == window->shell) {
nextBuf = MacroRunWindow();
RaiseDocument(nextBuf);
}
else if (IsTopDocument(window)) {
nextBuf = getNextTabWindow(window,
1,
0,
0);
RaiseDocument(nextBuf);
}
else {
topBuf = GetTopDocument(window->shell);
}
}
removeFromWindowList(window);
InvalidateWindowMenus();
CheckCloseDim();
XtDestroyWidget(window->tab);
if (nextBuf) {
ShowWindowTabBar(nextBuf);
updateLineNumDisp(nextBuf);
}
else if (topBuf) {
ShowWindowTabBar(topBuf);
updateLineNumDisp(topBuf);
}
win = nextBuf? nextBuf : topBuf;
if (win) {
state = NDocuments(win) >
1;
XtSetSensitive(win->detachDocumentItem, state);
XtSetSensitive(win->contextDetachDocumentItem, state);
}
state = NDocuments(WindowList) < NWindows();
for(win=WindowList; win; win=win->next) {
if (IsTopDocument(win)) {
XtSetSensitive(win->moveDocumentItem, state);
XtSetSensitive(win->contextMoveDocumentItem, state);
}
}
FreeUserBGMenuCache(&window->userBGMenuCache);
if (nextBuf || topBuf) {
deleteDocument(window);
}
else
{
FreeUserMenuCache(window->userMenuCache);
NEditFree(window->backlightCharTypes);
NEditFree(window->indentRainbowColors);
CloseAllPopupsFor(window->shell);
XtDestroyWidget(window->shell);
}
FontUnref(window->font);
FontUnref(window->boldFont);
FontUnref(window->italicFont);
FontUnref(window->boldItalicFont);
NEditFree(window->filter);
if(window->encErrors) {
NEditFree(window->encErrors);
}
NEditFree(window);
}
int GetShowTabBar(WindowInfo *window)
{
if (!GetPrefTabBar())
return False;
else if (NDocuments(window) ==
1)
return !GetPrefTabBarHideOne();
else
return True;
}
void ShowWindowTabBar(WindowInfo *window)
{
if (GetPrefTabBar()) {
if (GetPrefTabBarHideOne())
ShowTabBar(window, NDocuments(window)>
1);
else
ShowTabBar(window, True);
}
else
ShowTabBar(window, False);
}
WindowInfo *FindWindowWithFile(
const char *name,
const char *path)
{
WindowInfo* window;
if (!GetPrefHonorSymlinks())
{
char fullname[
MAXPATHLEN +
1];
struct stat attribute;
strncpy(fullname, path,
MAXPATHLEN);
strncat(fullname, name,
MAXPATHLEN);
fullname[
MAXPATHLEN] =
'\0';
if (
0 == stat(fullname, &attribute)) {
for (window = WindowList; window !=
NULL; window = window->next) {
if (attribute.st_dev == window->device
&& attribute.st_ino == window->inode) {
return window;
}
}
}
}
for (window = WindowList; window !=
NULL; window = window->next) {
if (!strcmp(window->filename, name) && !strcmp(window->path, path)) {
return window;
}
}
return NULL;
}
void SplitPane(WindowInfo *window)
{
short paneHeights[
MAX_PANES+
1];
int insertPositions[
MAX_PANES+
1], topLines[
MAX_PANES+
1];
int horizOffsets[
MAX_PANES+
1];
int i, focusPane, emTabDist, wrapMargin, lineNumCols, totalHeight=
0;
char *delimiters;
Widget text =
NULL;
textDisp *textD, *newTextD;
if (window->nPanes >=
MAX_PANES)
return;
focusPane =
0;
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
insertPositions[i] = TextGetCursorPos(text);
XtVaGetValues(containingPane(text),XmNheight,&paneHeights[i],
NULL);
totalHeight += paneHeights[i];
TextGetScroll(text, &topLines[i], &horizOffsets[i]);
if (text == window->lastFocus)
focusPane = i;
}
XtUnmanageChild(window->splitPane);
XtVaGetValues(window->textArea, textNemulateTabs, &emTabDist,
textNwordDelimiters, &delimiters, textNwrapMargin, &wrapMargin,
textNlineNumCols, &lineNumCols,
NULL);
text = createTextArea(window->splitPane, window,
1,
1, emTabDist,
delimiters, wrapMargin, lineNumCols);
TextSetBuffer(text, window->buffer);
if (window->highlightData !=
NULL)
AttachHighlightToWidget(text, window);
if (window->backlightChars)
{
XtVaSetValues(text, textNbacklightCharTypes,
window->backlightCharTypes,
NULL);
}
XtManageChild(text);
window->textPanes[window->nPanes++] = text;
textD = ((TextWidget)window->textArea)->text.textD;
newTextD = ((TextWidget)text)->text.textD;
XtVaSetValues(text,
XmNforeground, textD->colorProfile->textFgColor.pixel,
XmNbackground, textD->colorProfile->textBgColor.pixel,
NULL);
TextDSetColorProfile(newTextD, textD->colorProfile);
UpdateMinPaneHeights(window);
for (i=window->nPanes; i>focusPane; i--) {
insertPositions[i] = insertPositions[i-
1];
paneHeights[i] = paneHeights[i-
1];
topLines[i] = topLines[i-
1];
horizOffsets[i] = horizOffsets[i-
1];
}
paneHeights[focusPane] = paneHeights[focusPane]/
2;
paneHeights[focusPane+
1] = paneHeights[focusPane];
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
setPaneDesiredHeight(containingPane(text), paneHeights[i]);
}
if (IsTopDocument(window))
XtManageChild(window->splitPane);
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
TextSetCursorPos(text, insertPositions[i]);
TextSetScroll(text, topLines[i], horizOffsets[i]);
setPaneDesiredHeight(containingPane(text),
totalHeight/(window->nPanes+
1));
}
XmProcessTraversal(window->lastFocus, XmTRAVERSE_CURRENT);
XtAppAddTimeOut(XtWidgetToApplicationContext(window->shell),
0,
wmSizeUpdateProc, window);
}
Widget GetPaneByIndex(WindowInfo *window,
int paneIndex)
{
Widget text =
NULL;
if (paneIndex >=
0 && paneIndex <= window->nPanes) {
text = (paneIndex ==
0) ? window->textArea : window->textPanes[paneIndex -
1];
}
return(text);
}
int WidgetToPaneIndex(WindowInfo *window, Widget w)
{
int i;
Widget text;
int paneIndex =
0;
for (i =
0; i <= window->nPanes; ++i) {
text = (i ==
0) ? window->textArea : window->textPanes[i -
1];
if (text == w) {
paneIndex = i;
}
}
return(paneIndex);
}
void ClosePane(WindowInfo *window)
{
short paneHeights[
MAX_PANES+
1];
int insertPositions[
MAX_PANES+
1], topLines[
MAX_PANES+
1];
int horizOffsets[
MAX_PANES+
1];
int i, focusPane;
Widget text;
if (window->nPanes <=
0)
return;
focusPane =
0;
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
insertPositions[i] = TextGetCursorPos(text);
XtVaGetValues(containingPane(text),
XmNheight, &paneHeights[i],
NULL);
TextGetScroll(text, &topLines[i], &horizOffsets[i]);
if (text == window->lastFocus)
focusPane = i;
}
XtUnmanageChild(window->splitPane);
window->nPanes--;
XtUnmanageChild(containingPane(window->textPanes[window->nPanes]));
XtDestroyWidget(containingPane(window->textPanes[window->nPanes]));
if (window->nPanes ==
0)
window->lastFocus = window->textArea;
else if (focusPane > window->nPanes)
window->lastFocus = window->textPanes[window->nPanes-
1];
for (i=focusPane; i<=window->nPanes; i++) {
insertPositions[i] = insertPositions[i+
1];
paneHeights[i] = paneHeights[i+
1];
topLines[i] = topLines[i+
1];
horizOffsets[i] = horizOffsets[i+
1];
}
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
setPaneDesiredHeight(containingPane(text), paneHeights[i]);
}
if (IsTopDocument(window))
XtManageChild(window->splitPane);
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
TextSetCursorPos(text, insertPositions[i]);
TextSetScroll(text, topLines[i], horizOffsets[i]);
}
XmProcessTraversal(window->lastFocus, XmTRAVERSE_CURRENT);
XtAppAddTimeOut(XtWidgetToApplicationContext(window->shell),
0,
wmSizeUpdateProc, window);
}
void ShowLineNumbers(WindowInfo *window,
int state)
{
Widget text;
int i, marginWidth;
unsigned reqCols =
0;
Dimension windowWidth;
WindowInfo *win;
textDisp *textD = ((TextWidget)window->textArea)->text.textD;
if (window->showLineNumbers == state)
return;
window->showLineNumbers = state;
if (state) {
reqCols = updateLineNumDisp(window);
}
else {
XtVaGetValues(window->shell, XmNwidth, &windowWidth,
NULL);
XtVaGetValues(window->textArea,
textNmarginWidth, &marginWidth,
NULL);
XtVaSetValues(window->shell, XmNwidth,
windowWidth - textD->left + marginWidth,
NULL);
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
XtVaSetValues(text, textNlineNumCols,
0,
NULL);
}
}
for (win=WindowList; win; win=win->next) {
if (win->shell != window->shell || win == window)
continue;
win->showLineNumbers = state;
for (i=
0; i<=win->nPanes; i++) {
text = i==
0 ? win->textArea : win->textPanes[i-
1];
XtVaSetValues(text, textNlineNumCols, reqCols,
NULL);
}
}
UpdateWMSizeHints(window);
}
void ShowEncodingInfoBar(WindowInfo *window,
int state)
{
if (window->showInfoBar == state && XtIsManaged(window->encodingInfoBar) == state) {
return;
}
window->showInfoBar = state;
if(state ==
0) {
XtUnmanageChild(window->encodingInfoBar);
showStatsForm(window);
return;
}
char *def = strlen(window->encoding) >
0 ? window->encoding :
NULL;
int arraylen =
22;
XmStringTable encodings = NEditCalloc(arraylen,
sizeof(XmString));
const char *encStr;
int i;
int index =
0;
const char **default_encodings = FileDialogDefaultEncodings();
for(i=
0;(encStr=default_encodings[i]);i++) {
if(i >= arraylen) {
arraylen *=
2;
encodings = NEditRealloc(encodings, arraylen *
sizeof(XmString));
}
encodings[i] = XmStringCreateSimple((
char*)encStr);
if(def) {
if(!strcasecmp(def, encStr)) {
def =
NULL;
index = i;
}
}
}
if(def) {
if(i >= arraylen) {
arraylen +=
2;
encodings = NEditRealloc(encodings, arraylen *
sizeof(XmString));
}
encodings[i] = XmStringCreateSimple(def);
index = i;
i++;
}
XtVaSetValues(
window->encInfoBarList,
XmNitemCount, i,
XmNitems, encodings,
NULL);
XmComboBoxSelectItem(window->encInfoBarList, encodings[index]);
for(
int j=
0;j<i;j++) {
XmStringFree(encodings[j]);
}
NEditFree(encodings);
XtManageChild(window->encodingInfoBar);
showStatsForm(window);
}
void SetEncodingInfoBarLabel(WindowInfo *window,
char *message)
{
XmString s1 = XmStringCreateLocalized(message);
XtVaSetValues(window->encInfoBarLabel, XmNlabelString, s1,
NULL);
XmStringFree(s1);
}
void SetTabDist(WindowInfo *window,
int tabDist)
{
if (window->buffer->tabDist != tabDist) {
int saveCursorPositions[
MAX_PANES +
1];
int saveVScrollPositions[
MAX_PANES +
1];
int saveHScrollPositions[
MAX_PANES +
1];
int paneIndex;
window->ignoreModify = True;
for (paneIndex =
0; paneIndex <= window->nPanes; ++paneIndex) {
Widget w = GetPaneByIndex(window, paneIndex);
textDisp *textD = ((TextWidget)w)->text.textD;
TextGetScroll(w, &saveVScrollPositions[paneIndex], &saveHScrollPositions[paneIndex]);
saveCursorPositions[paneIndex] = TextGetCursorPos(w);
textD->modifyingTabDist =
1;
}
BufSetTabDistance(window->buffer, tabDist);
for (paneIndex =
0; paneIndex <= window->nPanes; ++paneIndex) {
Widget w = GetPaneByIndex(window, paneIndex);
textDisp *textD = ((TextWidget)w)->text.textD;
textD->modifyingTabDist =
0;
TextSetCursorPos(w, saveCursorPositions[paneIndex]);
TextSetScroll(w, saveVScrollPositions[paneIndex], saveHScrollPositions[paneIndex]);
}
window->ignoreModify = False;
}
}
void SetEmTabDist(WindowInfo *window,
int emTabDist)
{
int i;
XtVaSetValues(window->textArea, textNemulateTabs, emTabDist,
NULL);
for (i =
0; i < window->nPanes; ++i) {
XtVaSetValues(window->textPanes[i], textNemulateTabs, emTabDist,
NULL);
}
}
void ShowStatsLine(WindowInfo *window,
int state)
{
WindowInfo *win;
Widget text;
int i;
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
TextDMaintainAbsLineNum(((TextWidget)text)->text.textD, state);
}
window->showStats = state;
showStats(window, state);
for (win=WindowList; win; win=win->next) {
if (win->shell != window->shell || win == window)
continue;
win->showStats = state;
}
}
static void showStats(WindowInfo *window,
int state)
{
if (state) {
XtManageChild(window->statsLineForm);
showStatsForm(window);
}
else {
XtUnmanageChild(window->statsLineForm);
showStatsForm(window);
}
}
static void showTabBar(WindowInfo *window,
int state)
{
if (state) {
XtManageChild(XtParent(window->tabBar));
showStatsForm(window);
}
else {
XtUnmanageChild(XtParent(window->tabBar));
showStatsForm(window);
}
}
void ShowTabBar(WindowInfo *window,
int state)
{
if (XtIsManaged(XtParent(window->tabBar)) == state)
return;
showTabBar(window, state);
}
void ShowISearchLine(WindowInfo *window,
int state)
{
WindowInfo *win;
if (window->showISearchLine == state)
return;
window->showISearchLine = state;
showISearch(window, state);
for (win=WindowList; win; win=win->next) {
if (win->shell != window->shell || win == window)
continue;
win->showISearchLine = state;
}
}
void TempShowISearch(WindowInfo *window,
int state)
{
if (window->showISearchLine)
return;
if (XtIsManaged(window->iSearchForm) != state)
showISearch(window, state);
}
static void showISearch(WindowInfo *window,
int state)
{
if (state) {
XtManageChild(window->iSearchForm);
showStatsForm(window);
}
else {
XtUnmanageChild(window->iSearchForm);
showStatsForm(window);
}
}
static void showStatsForm(WindowInfo *window)
{
Widget statsAreaForm = XtParent(window->statsLineForm);
Widget mainW = XtParent(statsAreaForm);
if (manageToolBars(statsAreaForm)) {
XtUnmanageChild(statsAreaForm);
XtVaSetValues(mainW, XmNcommandWindowLocation,
XmCOMMAND_ABOVE_WORKSPACE,
NULL);
#if XmVersion <
2001
XtVaSetValues(mainW, XmNshowSeparator, True,
NULL);
#endif
XtManageChild(statsAreaForm);
XtVaSetValues(mainW, XmNshowSeparator, False,
NULL);
UpdateStatsLine(window);
}
else {
XtUnmanageChild(statsAreaForm);
XtVaSetValues(mainW, XmNcommandWindowLocation,
XmCOMMAND_BELOW_WORKSPACE,
NULL);
}
UpdateWMSizeHints(window);
}
void SetModeMessage(WindowInfo *window,
const char *message)
{
window->modeMessageDisplayed = True;
NEditFree(window->modeMessage);
window->modeMessage = NEditStrdup(message);
if (!IsTopDocument(window))
return;
XmTextSetString(window->statsLine, (
char*)message);
if (!window->showStats)
showStats(window, True);
}
void ClearModeMessage(WindowInfo *window)
{
if (!window->modeMessageDisplayed)
return;
window->modeMessageDisplayed = False;
NEditFree(window->modeMessage);
window->modeMessage =
NULL;
if (!IsTopDocument(window))
return;
if (!window->showStats)
showStats(window, False);
UpdateStatsLine(window);
}
int NWindows(
void)
{
WindowInfo *win;
int n;
for (win=WindowList, n=
0; win!=
NULL; win=win->next, n++);
return n;
}
void SetAutoIndent(WindowInfo *window, IndentStyle state)
{
int autoIndent = state ==
AUTO_INDENT, smartIndent = state ==
SMART_INDENT;
int i;
if (window->indentStyle ==
SMART_INDENT && !smartIndent)
EndSmartIndent(window);
else if (smartIndent && window->indentStyle !=
SMART_INDENT)
BeginSmartIndent(window, True);
window->indentStyle = state;
XtVaSetValues(window->textArea, textNautoIndent, autoIndent,
textNsmartIndent, smartIndent,
NULL);
for (i=
0; i<window->nPanes; i++)
XtVaSetValues(window->textPanes[i], textNautoIndent, autoIndent,
textNsmartIndent, smartIndent,
NULL);
if (IsTopDocument(window)) {
XmToggleButtonSetState(window->smartIndentItem, smartIndent, False);
XmToggleButtonSetState(window->autoIndentItem, autoIndent, False);
XmToggleButtonSetState(window->autoIndentOffItem,
state ==
NO_AUTO_INDENT, False);
}
}
void SetShowMatching(WindowInfo *window, ShowMatchingStyle state)
{
window->showMatchingStyle = state;
if (IsTopDocument(window)) {
XmToggleButtonSetState(window->showMatchingOffItem,
state ==
NO_FLASH, False);
XmToggleButtonSetState(window->showMatchingDelimitItem,
state ==
FLASH_DELIMIT, False);
XmToggleButtonSetState(window->showMatchingRangeItem,
state ==
FLASH_RANGE, False);
}
}
void UpdateNewOppositeMenu(WindowInfo *window,
int openInTab)
{
XmString lbl;
if ( openInTab )
XtVaSetValues(window->newOppositeItem,
XmNlabelString, lbl=XmStringCreateSimple(
"New Window"),
XmNmnemonic,
'W',
NULL);
else
XtVaSetValues(window->newOppositeItem,
XmNlabelString, lbl=XmStringCreateSimple(
"New Tab"),
XmNmnemonic,
'T',
NULL);
XmStringFree(lbl);
}
void SetFonts(WindowInfo *window,
const char *fontName,
const char *italicName,
const char *boldName,
const char *boldItalicName)
{
NFont *font;
NFont *oldFont;
int i, oldFontWidth, oldFontHeight, fontWidth, fontHeight;
int borderWidth, borderHeight, marginWidth, marginHeight;
int primaryChanged, highlightChanged = False;
Dimension oldWindowWidth, oldWindowHeight, oldTextWidth, oldTextHeight;
Dimension textHeight, newWindowWidth, newWindowHeight;
textDisp *textD = ((TextWidget)window->textArea)->text.textD;
NFont *unrefFont =
NULL;
NFont *unrefItalic =
NULL;
NFont *unrefBold =
NULL;
NFont *unrefBoldItalic =
NULL;
primaryChanged = strcmp(fontName, window->fontName);
if (strcmp(italicName, window->italicFontName)) highlightChanged = True;
if (strcmp(boldName, window->boldFontName)) highlightChanged = True;
if (strcmp(boldItalicName, window->boldItalicFontName))
highlightChanged = True;
if (!primaryChanged && !highlightChanged)
return;
XtVaGetValues(window->shell, XmNwidth, &oldWindowWidth, XmNheight,
&oldWindowHeight,
NULL);
XtVaGetValues(window->textArea, XmNheight, &textHeight,
textNmarginHeight, &marginHeight, textNmarginWidth,
&marginWidth, textNXftFont, &oldFont,
NULL);
oldTextWidth = textD->width + textD->lineNumWidth;
oldTextHeight = textHeight -
2*marginHeight;
for (i=
0; i<window->nPanes; i++) {
XtVaGetValues(window->textPanes[i], XmNheight, &textHeight,
NULL);
oldTextHeight += textHeight -
2*marginHeight;
}
borderWidth = oldWindowWidth - oldTextWidth;
borderHeight = oldWindowHeight - oldTextHeight;
oldFontWidth = oldFont->maxWidth;
oldFontHeight = textD->ascent + textD->descent;
if (primaryChanged) {
strcpy(window->fontName, fontName);
font = FontFromName(TheDisplay, fontName);
if (font ==
NULL) {
printf(
"implement fallback font\n");
}
else {
unrefFont = window->font;
window->font = font;
}
}
if (highlightChanged) {
NFont *newitalic = FontFromName(TheDisplay, italicName);
if(newitalic) {
strcpy(window->italicFontName, italicName);
unrefItalic = window->italicFont;
window->italicFont = newitalic;
}
NFont *newbold = FontFromName(TheDisplay, boldName);
if(newbold) {
strcpy(window->boldFontName, boldName);
unrefBold = window->boldFont;
window->boldFont = newbold;
}
NFont *newbolditalic = FontFromName(TheDisplay, boldItalicName);
if(newbolditalic) {
strcpy(window->boldItalicFontName, boldItalicName);
unrefBoldItalic = window->boldItalicFont;
window->boldItalicFont = newbolditalic;
}
}
if (window->highlightData !=
NULL)
UpdateHighlightStyles(window, False);
if (primaryChanged) {
font = window->font;
XtVaSetValues(window->textArea,
textNXftFont, font,
textNXftBoldFont, window->boldFont,
textNXftItalicFont, window->italicFont,
textNXftBoldItalicFont, window->boldItalicFont,
NULL);
for (i=
0; i<window->nPanes; i++) {
XtVaSetValues(window->textPanes[i],
textNXftFont, font,
textNXftBoldFont, window->boldFont,
textNXftItalicFont, window->italicFont,
textNXftBoldItalicFont, window->boldItalicFont,
NULL);
}
}
if(unrefFont)
if(unrefItalic)
FontUnref(unrefItalic);
if(unrefBold)
FontUnref(unrefBold);
if(unrefBoldItalic)
FontUnref(unrefBoldItalic);
if(window->resizeOnFontChange) {
UpdateWMSizeHints(window);
if (NDocuments(window) ==
1) {
fontWidth = window->font->maxWidth;
fontHeight = textD->ascent + textD->descent;
newWindowWidth = (oldTextWidth*fontWidth) / oldFontWidth + borderWidth;
newWindowHeight = (oldTextHeight*fontHeight) / oldFontHeight +
borderHeight;
XtVaSetValues(window->shell, XmNwidth, newWindowWidth, XmNheight,
newWindowHeight,
NULL);
}
}
UpdateMinPaneHeights(window);
}
void LoadColorProfile(Widget w, ColorProfile *profile)
{
Colormap cmap;
Pixel foreground;
int depth;
XtVaGetValues(w,
XtNcolormap, &cmap,
XtNdepth, &depth,
XtNforeground, &foreground,
NULL);
Display *display = XtDisplay(w);
int i, dummy;
Pixel textFgPix = AllocColor( w, profile->textFg,
&dummy, &dummy, &dummy),
textBgPix = AllocColor( w, profile->textBg,
&dummy, &dummy, &dummy),
selectFgPix = AllocColor( w, profile->selectFg,
&dummy, &dummy, &dummy),
selectBgPix = AllocColor( w, profile->selectBg,
&dummy, &dummy, &dummy),
hiliteFgPix = AllocColor( w, profile->hiliteFg,
&dummy, &dummy, &dummy),
hiliteBgPix = AllocColor( w, profile->hiliteBg,
&dummy, &dummy, &dummy),
lineNoFgPix = AllocColor( w, profile->lineNoFg,
&dummy, &dummy, &dummy),
lineNoBgPix = AllocColor( w, profile->lineNoBg,
&dummy, &dummy, &dummy),
cursorFgPix = AllocColor( w, profile->cursorFg,
&dummy, &dummy, &dummy),
lineHiBgPix = AllocColor( w, profile->lineHiBg,
&dummy, &dummy, &dummy);
textDisp *textD;
profile->textFgColor = PixelToColor(w, textFgPix);
profile->textBgColor = PixelToColor(w, textBgPix);
profile->selectFgColor = PixelToColor(w, selectFgPix);
profile->selectBgColor = PixelToColor(w, selectBgPix);
profile->hiliteFgColor = PixelToColor(w, hiliteFgPix);
profile->hiliteBgColor = PixelToColor(w, hiliteBgPix);
profile->lineNoFgColor = PixelToColor(w, lineNoFgPix);
profile->lineNoBgColor = PixelToColor(w, lineNoBgPix);
profile->cursorFgColor = PixelToColor(w, cursorFgPix);
profile->lineHiBgColor = PixelToColor(w, lineHiBgPix);
if(profile->rainbowColorList) {
ColorList rainbowColors = ParseColorList(profile->rainbowColorList, strlen(profile->rainbowColorList));
profile->rainbowColors = NEditCalloc(rainbowColors.ncolors,
sizeof(XftColor));
for(
int i=
0;i<rainbowColors.ncolors;i++) {
profile->rainbowColors[i] = ParseXftColor(display, cmap, foreground, depth, rainbowColors.colors[i]);
}
profile->numRainbowColors = rainbowColors.ncolors;
free(rainbowColors.colors);
free(rainbowColors.liststr);
}
if(profile->ansiColorList) {
ColorList ansiColors = ParseColorList(profile->ansiColorList, strlen(profile->ansiColorList));
profile->ansiColors = NEditCalloc(ansiColors.ncolors,
sizeof(XftColor));
for(
int i=
0;i<ansiColors.ncolors;i++) {
profile->ansiColors[i] = ParseXftColor(display, cmap, foreground, depth, ansiColors.colors[i]);
}
profile->numAnsiColors = ansiColors.ncolors;
free(ansiColors.colors);
free(ansiColors.liststr);
}
if(!profile->db || !profile->resDBLoaded) {
LoadColorProfileResources(display, profile);
}
if(!profile->stylesLoaded) {
ColorProfileLoadHighlightStyles(profile);
}
profile->colorsLoaded =
TRUE;
}
void SetColorProfile(WindowInfo *window, ColorProfile *profile)
{
if(!profile->colorsLoaded) {
LoadColorProfile(window->textArea, profile);
}
window->colorProfile = profile;
XtVaSetValues(window->textArea,
XmNforeground, profile->textFgColor.pixel,
XmNbackground, profile->textBgColor.pixel,
NULL);
textDisp *textD = ((TextWidget)window->textArea)->text.textD;
TextDSetColorProfile( textD, profile);
for (
int i=
0; i<window->nPanes; i++) {
XtVaSetValues(window->textPanes[i],
XmNforeground, profile->textFgColor.pixel,
XmNbackground, profile->textBgColor.pixel,
NULL);
textD = ((TextWidget)window->textPanes[i])->text.textD;
TextDSetColorProfile( textD, profile);
}
if (window->highlightData !=
NULL)
UpdateHighlightStyles(window, True);
}
void EnableWindowResourceDB(
const WindowInfo *window)
{
if(window->colorProfile && window->colorProfile->db) {
XrmSetDatabase(XtDisplay(window->shell), window->colorProfile->db);
}
}
void SetOverstrike(WindowInfo *window,
int overstrike)
{
int i;
XtVaSetValues(window->textArea, textNoverstrike, overstrike,
NULL);
for (i=
0; i<window->nPanes; i++)
XtVaSetValues(window->textPanes[i], textNoverstrike, overstrike,
NULL);
window->overstrike = overstrike;
}
void SetAutoWrap(WindowInfo *window, WrapStyle state)
{
if(window->wrapModeNoneForced) {
return;
}
int i;
int autoWrap = state ==
NEWLINE_WRAP, contWrap = state ==
CONTINUOUS_WRAP;
XtVaSetValues(window->textArea, textNautoWrap, autoWrap,
textNcontinuousWrap, contWrap,
NULL);
for (i=
0; i<window->nPanes; i++)
XtVaSetValues(window->textPanes[i], textNautoWrap, autoWrap,
textNcontinuousWrap, contWrap,
NULL);
window->wrapMode = state;
if (IsTopDocument(window)) {
XmToggleButtonSetState(window->newlineWrapItem, autoWrap, False);
XmToggleButtonSetState(window->continuousWrapItem, contWrap, False);
XmToggleButtonSetState(window->noWrapItem, state ==
NO_WRAP, False);
}
}
void SetAutoScroll(WindowInfo *window,
int margin)
{
int i;
XtVaSetValues(window->textArea, textNcursorVPadding, margin,
NULL);
for (i=
0; i<window->nPanes; i++)
XtVaSetValues(window->textPanes[i], textNcursorVPadding, margin,
NULL);
}
WindowInfo *WidgetToWindow(Widget w)
{
WindowInfo *window =
NULL;
Widget parent;
while (True) {
if (XtClass(w) == xmPanedWindowWidgetClass)
break;
if (XtClass(w) == topLevelShellWidgetClass) {
WidgetList items;
XtVaGetValues(w, XmNchildren, &items,
NULL);
w = items[
0];
break;
}
parent = XtParent(w);
if (parent ==
NULL)
return NULL;
if (XtClass(parent) == topLevelShellWidgetClass &&
XmIsMainWindow(w))
break;
w = parent;
}
XtVaGetValues(w, XmNuserData, &window,
NULL);
return window;
}
void SetWindowModified(WindowInfo *window,
int modified)
{
if (window->fileChanged ==
FALSE && modified ==
TRUE) {
SetSensitive(window, window->closeItem,
TRUE);
window->fileChanged =
TRUE;
UpdateWindowTitle(window);
RefreshTabState(window);
}
else if (window->fileChanged ==
TRUE && modified ==
FALSE) {
window->fileChanged =
FALSE;
UpdateWindowTitle(window);
RefreshTabState(window);
}
}
static int utf8TitleAtomsInit =
0;
static Atom utf8_string;
static Atom net_wm_name;
static void setUtf8Title(Widget shell,
const char *title) {
Display *dp = XtDisplay(shell);
if(!utf8TitleAtomsInit) {
utf8_string = XInternAtom(dp,
"UTF8_STRING", False);
net_wm_name = XInternAtom(dp,
"_NET_WM_NAME", False);
utf8TitleAtomsInit =
1;
}
XChangeProperty(
dp,
XtWindow(shell),
net_wm_name,
utf8_string,
8,
PropModeReplace,
(
unsigned char*)title,
strlen(title));
}
void UpdateWindowTitle(
const WindowInfo *window)
{
char *iconTitle, *title;
if (!IsTopDocument(window))
return;
title = FormatWindowTitle(window->filename,
window->path,
GetClearCaseViewTag(),
GetPrefServerName(),
window->encoding,
IsServer,
window->filenameSet,
window->lockReasons,
window->fileChanged,
GetPrefTitleFormat());
iconTitle = (
char*)NEditMalloc(strlen(window->filename) +
2);
strcpy(iconTitle, window->filename);
if (window->fileChanged) {
strcat(iconTitle,
"*");
}
if(XNEditDefaultCharsetIsUTF8()) {
setUtf8Title(window->shell, title);
}
XtVaSetValues(window->shell, XmNtitle, title, XmNiconName, iconTitle,
NULL);
if (window->findDlog && XmToggleButtonGetState(window->findKeepBtn)) {
sprintf(title,
"Find (in %s)", window->filename);
XtVaSetValues(XtParent(window->findDlog), XmNtitle, title,
NULL);
}
if (window->replaceDlog && XmToggleButtonGetState(window->replaceKeepBtn)) {
sprintf(title,
"Replace (in %s)", window->filename);
XtVaSetValues(XtParent(window->replaceDlog), XmNtitle, title,
NULL);
}
NEditFree(iconTitle);
InvalidateWindowMenus();
}
void UpdateWindowReadOnly(WindowInfo *window)
{
int i, state;
if (!IsTopDocument(window))
return;
state =
IS_ANY_LOCKED(window->lockReasons);
XtVaSetValues(window->textArea, textNreadOnly, state,
NULL);
for (i=
0; i<window->nPanes; i++)
XtVaSetValues(window->textPanes[i], textNreadOnly, state,
NULL);
XmToggleButtonSetState(window->readOnlyItem, state,
FALSE);
XtSetSensitive(window->readOnlyItem,
!
IS_ANY_LOCKED_IGNORING_USER(window->lockReasons));
}
int GetSimpleSelection(textBuffer *buf,
int *left,
int *right)
{
int selStart, selEnd, isRect, rectStart, rectEnd, lineStart;
if (!BufGetSelectionPos(buf, &selStart, &selEnd, &isRect,
&rectStart, &rectEnd))
return False;
if (isRect) {
lineStart = BufStartOfLine(buf, selStart);
selStart = BufCountForwardDispChars(buf, lineStart, rectStart);
selEnd = BufCountForwardDispChars(buf, lineStart, rectEnd);
}
*left = selStart;
*right = selEnd;
return True;
}
void MakeSelectionVisible(WindowInfo *window, Widget textPane)
{
int left, right, isRect, rectStart, rectEnd, horizOffset;
int scrollOffset, leftX, rightX, y, rows, margin;
int topLineNum, lastLineNum, rightLineNum, leftLineNum, linesToScroll;
textDisp *textD = ((TextWidget)textPane)->text.textD;
int topChar = TextFirstVisiblePos(textPane);
int lastChar = TextLastVisiblePos(textPane);
int targetLineNum;
Dimension width;
if (!BufGetSelectionPos(window->buffer, &left, &right, &isRect,
&rectStart, &rectEnd)) {
left = right = TextGetCursorPos(textPane);
isRect = False;
}
if (!((left >= topChar && right <= lastChar) ||
(left <= topChar && right >= lastChar))) {
XtVaGetValues(textPane, textNrows, &rows,
NULL);
scrollOffset = rows/
3;
TextGetScroll(textPane, &topLineNum, &horizOffset);
if (right > lastChar) {
leftLineNum = topLineNum +
TextDCountLines(textD, topChar, left, False);
targetLineNum = topLineNum + scrollOffset;
if (leftLineNum >= targetLineNum) {
linesToScroll = TextDCountLines(textD, lastChar, right, False) +
scrollOffset;
if (leftLineNum - linesToScroll < targetLineNum)
linesToScroll = leftLineNum - targetLineNum;
TextSetScroll(textPane, topLineNum+linesToScroll, horizOffset);
}
}
else if (left < topChar) {
lastLineNum = topLineNum + rows;
rightLineNum = lastLineNum -
TextDCountLines(textD, right, lastChar, False);
targetLineNum = lastLineNum - scrollOffset;
if (rightLineNum <= targetLineNum) {
linesToScroll = TextDCountLines(textD, left, topChar, False) +
scrollOffset;
if (rightLineNum + linesToScroll > targetLineNum)
linesToScroll = targetLineNum - rightLineNum;
TextSetScroll(textPane, topLineNum-linesToScroll, horizOffset);
}
}
}
if ( TextPosToXY(textPane, left, &leftX, &y) &&
TextPosToXY(textPane, right, &rightX, &y) && leftX <= rightX) {
TextGetScroll(textPane, &topLineNum, &horizOffset);
XtVaGetValues(textPane, XmNwidth, &width, textNmarginWidth, &margin,
NULL);
if (leftX < margin + textD->lineNumLeft + textD->lineNumWidth)
horizOffset -=
margin + textD->lineNumLeft + textD->lineNumWidth - leftX;
else if (rightX > width - margin)
horizOffset += rightX - (width - margin);
TextSetScroll(textPane, topLineNum, horizOffset);
}
UpdateStatsLine(window);
}
static Widget createTextArea(Widget parent, WindowInfo *window,
int rows,
int cols,
int emTabDist,
char *delimiters,
int wrapMargin,
int lineNumCols)
{
Widget text, sw, hScrollBar, vScrollBar, frame;
sw = XtVaCreateManagedWidget(
"scrolledW", xmScrolledWindowWidgetClass,
parent, XmNpaneMaximum,
SHRT_MAX,
XmNpaneMinimum,
PANE_MIN_HEIGHT, XmNhighlightThickness,
0,
NULL);
hScrollBar = XtVaCreateManagedWidget(
"textHorScrollBar",
xmScrollBarWidgetClass, sw, XmNorientation, XmHORIZONTAL,
XmNrepeatDelay,
10,
NULL);
vScrollBar = XtVaCreateManagedWidget(
"textVertScrollBar",
xmScrollBarWidgetClass, sw, XmNorientation, XmVERTICAL,
XmNrepeatDelay,
10,
NULL);
frame = XtVaCreateManagedWidget(
"textFrame", xmFrameWidgetClass, sw,
XmNshadowType, XmSHADOW_IN,
NULL);
text = XtVaCreateManagedWidget(
"text", textWidgetClass, frame,
textNbacklightCharTypes, window->backlightCharTypes,
textNhighlightCursorLine, window->highlightCursorLine,
textNindentRainbow, window->indentRainbow,
textNansiColors, window->ansiColors,
textNrows, rows, textNcolumns, cols,
textNlineNumCols, lineNumCols,
textNemulateTabs, emTabDist,
textNXftFont, window->font,
textNXftBoldFont, window->boldFont,
textNXftItalicFont, window->italicFont,
textNXftBoldItalicFont, window->boldItalicFont,
textNhScrollBar, hScrollBar, textNvScrollBar, vScrollBar,
textNreadOnly,
IS_ANY_LOCKED(window->lockReasons),
textNwordDelimiters, delimiters,
textNwrapMargin, wrapMargin,
textNautoIndent, window->indentStyle ==
AUTO_INDENT,
textNsmartIndent, window->indentStyle ==
SMART_INDENT,
textNautoWrap, window->wrapMode ==
NEWLINE_WRAP,
textNcontinuousWrap, window->wrapMode ==
CONTINUOUS_WRAP,
textNoverstrike, window->overstrike,
textNhidePointer, (Boolean) GetPrefTypingHidesPointer(),
textNcursorVPadding, GetVerticalAutoScroll(),
NULL);
XtVaSetValues(sw, XmNworkWindow, frame, XmNhorizontalScrollBar,
hScrollBar, XmNverticalScrollBar, vScrollBar,
NULL);
XtAddCallback(text, textNfocusCallback, (XtCallbackProc)focusCB, window);
XtAddCallback(text, textNcursorMovementCallback, (XtCallbackProc)movedCB,
window);
XtAddCallback(text, textNdragStartCallback, (XtCallbackProc)dragStartCB,
window);
XtAddCallback(text, textNdragEndCallback, (XtCallbackProc)dragEndCB,
window);
XtAddCallback(text, textNsmartIndentCallback, SmartIndentCB, window);
neditDropWidget(text);
XmAddTabGroup(containingPane(text));
RemapDeleteKey(text);
AddBGMenuAction(text);
TextDMaintainAbsLineNum(((TextWidget)text)->text.textD, window->showStats);
return text;
}
static void movedCB(Widget w, WindowInfo *window, XtPointer callData)
{
TextWidget textWidget = (TextWidget) w;
if (window->ignoreModify)
return;
UpdateStatsLine(window);
FlashMatching(window, w);
CheckForChangesToFile(window);
if (
0 != textWidget->text.cursorBlinkProcID)
{
ResetCursorBlink(textWidget, False);
}
}
static void modifiedCB(
int pos,
int nInserted,
int nDeleted,
int nRestyled,
const char *deletedText,
void *cbArg)
{
WindowInfo *window = (WindowInfo *)cbArg;
int selected = window->buffer->primary.selected;
if (!window->ignoreModify) {
UpdateMarkTable(window, pos, nInserted, nDeleted);
}
if ((window->wasSelected && !selected) ||
(!window->wasSelected && selected)) {
window->wasSelected = selected;
if (IsTopDocument(window)) {
XtSetSensitive(window->printSelItem, selected);
XtSetSensitive(window->cutItem, selected);
XtSetSensitive(window->copyItem, selected);
XtSetSensitive(window->delItem, selected);
XtSetSensitive(window->filterItem, selected);
DimSelectionDepUserMenuItems(window, selected);
if (window->replaceDlog !=
NULL && XtIsManaged(window->replaceDlog))
{
UpdateReplaceActionButtons(window);
}
}
}
if (window->ignoreModify || (nDeleted ==
0 && nInserted ==
0))
return;
updateLineNumDisp(window);
SaveUndoInformation(window, pos, nInserted, nDeleted, deletedText);
if (window->autoSave &&
(window->autoSaveCharCount >
AUTOSAVE_CHAR_LIMIT ||
window->autoSaveOpCount >
AUTOSAVE_OP_LIMIT)) {
WriteBackupFile(window);
window->autoSaveCharCount =
0;
window->autoSaveOpCount =
0;
}
SetWindowModified(window,
TRUE);
if(!window->undo_batch_begin) {
UpdateStatsLine(window);
}
CheckForChangesToFile(window);
window->undo_batch_count++;
}
static void beginModifyCB(
void *cbArg) {
WindowInfo *window = cbArg;
window->undo_batch_begin = window->undo;
window->undo_batch_count =
0;
}
static void endModifyCB(
void *cbArg) {
WindowInfo *window = cbArg;
if(window->undo_batch_begin && window->undo_batch_count >
1) {
window->undo->numOp = window->undo_batch_count;
}
window->undo_batch_begin =
NULL;
window->undo_batch_count =
0;
UpdateStatsLine(window);
}
static void focusCB(Widget w, WindowInfo *window, XtPointer callData)
{
window->lastFocus = w;
UpdateStatsLine(window);
EndISearch(window);
CheckForChangesToFile(window);
}
static void dragStartCB(Widget w, WindowInfo *window, XtPointer callData)
{
window->ignoreModify = True;
}
static void dragEndCB(Widget w, WindowInfo *window, dragEndCBStruct *callData)
{
window->ignoreModify = False;
if (callData->nCharsInserted ==
0)
return;
modifiedCB(callData->startPos, callData->nCharsInserted,
callData->nCharsDeleted,
0, callData->deletedText, window);
}
static void closeCB(Widget w, WindowInfo *window, XtPointer callData)
{
window = WidgetToWindow(w);
if (!WindowCanBeClosed(window)) {
return;
}
CloseDocumentWindow(w, window, callData);
}
#ifndef NO_SESSION_RESTART
static void saveYourselfCB(Widget w, Widget appShell, XtPointer callData)
{
WindowInfo *win, *topWin, **revWindowList;
char geometry[
MAX_GEOM_STRING_LEN];
int argc =
0, maxArgc, nWindows, i;
char **argv;
int wasIconic = False;
int n, nItems;
WidgetList children;
maxArgc =
4;
nWindows =
0;
for (win=WindowList; win!=
NULL; win=win->next) {
maxArgc +=
5;
nWindows++;
}
argv = (
char **)NEditMalloc(maxArgc*
sizeof(
char *));
revWindowList = (WindowInfo **)NEditMalloc(
sizeof(WindowInfo *)*nWindows);
for (win=WindowList, i=nWindows-
1; win!=
NULL; win=win->next, i--)
revWindowList[i] = win;
argv[argc++] = NEditStrdup(ArgV0);
if (IsServer) {
argv[argc++] = NEditStrdup(
"-server");
if (GetPrefServerName()[
0] !=
'\0') {
argv[argc++] = NEditStrdup(
"-svrname");
argv[argc++] = NEditStrdup(GetPrefServerName());
}
}
XtVaGetValues(appShell, XmNchildren, &children,
XmNnumChildren, &nItems,
NULL);
for (n=nItems-
1; n>=
0; n--) {
WidgetList tabs;
int tabCount;
if (strcmp(XtName(children[n]),
"textShell") ||
((topWin = WidgetToWindow(children[n])) ==
NULL))
continue;
getGeometryString(topWin, geometry);
argv[argc++] = NEditStrdup(
"-group");
argv[argc++] = NEditStrdup(
"-geometry");
argv[argc++] = NEditStrdup(geometry);
if (IsIconic(topWin)) {
argv[argc++] = NEditStrdup(
"-iconic");
wasIconic = True;
}
else if (wasIconic) {
argv[argc++] = NEditStrdup(
"-noiconic");
wasIconic = False;
}
XtVaGetValues(topWin->tabBar, XmNtabWidgetList, &tabs,
XmNtabCount, &tabCount,
NULL);
for (i=
0; i< tabCount; i++) {
win = TabToWindow(tabs[i]);
if (win->filenameSet) {
argv[argc] = (
char*)NEditMalloc(strlen(win->path) +
strlen(win->filename) +
1);
sprintf(argv[argc++],
"%s%s", win->path, win->filename);
}
}
}
NEditFree(revWindowList);
XSetCommand(TheDisplay, XtWindow(appShell), argv, argc);
for (i=
0; i<argc; i++)
NEditFree(argv[i]);
NEditFree(argv);
}
void AttachSessionMgrHandler(Widget appShell)
{
static Atom wmpAtom, syAtom =
0;
if (syAtom ==
0) {
wmpAtom = XmInternAtom(TheDisplay,
"WM_PROTOCOLS",
FALSE);
syAtom = XmInternAtom(TheDisplay,
"WM_SAVE_YOURSELF",
FALSE);
}
XmAddProtocolCallback(appShell, wmpAtom, syAtom,
(XtCallbackProc)saveYourselfCB, (XtPointer)appShell);
}
#endif
int IsIconic(WindowInfo *window)
{
unsigned long *property =
NULL;
unsigned long nItems;
unsigned long leftover;
static Atom wmStateAtom =
0;
Atom actualType;
int actualFormat;
int result;
if (wmStateAtom ==
0)
wmStateAtom = XInternAtom(XtDisplay(window->shell),
"WM_STATE", False);
if (XGetWindowProperty(XtDisplay(window->shell), XtWindow(window->shell),
wmStateAtom,
0L,
1L, False, wmStateAtom, &actualType, &actualFormat,
&nItems, &leftover, (
unsigned char **)&property) != Success ||
nItems !=
1 || property ==
NULL)
return FALSE;
result = *property == IconicState;
NEditFree(property);
return result;
}
static void addToWindowList(WindowInfo *window)
{
WindowInfo *temp;
temp = WindowList;
WindowList = window;
window->next = temp;
}
static void removeFromWindowList(WindowInfo *window)
{
WindowInfo *temp;
if (WindowList == window)
WindowList = window->next;
else {
for (temp = WindowList; temp !=
NULL; temp = temp->next) {
if (temp->next == window) {
temp->next = window->next;
break;
}
}
}
}
static int updateGutterWidth(WindowInfo* window)
{
WindowInfo* document;
int reqCols =
MIN_LINE_NUM_COLS;
int newColsDiff =
0;
int maxCols =
0;
for (document = WindowList;
NULL != document; document = document->next) {
if (document->shell == window->shell) {
int lineNumCols, tmpReqCols;
textDisp *textD = ((TextWidget) document->textArea)->text.textD;
XtVaGetValues(document->textArea,
textNlineNumCols, &lineNumCols,
NULL);
if (lineNumCols > maxCols) {
maxCols = lineNumCols;
}
tmpReqCols = textD->nBufferLines <
1
?
1
: (
int) log10((
double) textD->nBufferLines +
1) +
1;
if (tmpReqCols > reqCols) {
reqCols = tmpReqCols;
}
}
}
if (reqCols != maxCols) {
NFont *fs;
Dimension windowWidth;
short fontWidth;
newColsDiff = reqCols - maxCols;
XtVaGetValues(window->textArea, textNXftFont, &fs,
NULL);
fontWidth = fs->maxWidth;
XtVaGetValues(window->shell, XmNwidth, &windowWidth,
NULL);
XtVaSetValues(window->shell,
XmNwidth, (Dimension) windowWidth + (newColsDiff * fontWidth),
NULL);
UpdateWMSizeHints(window);
}
for (document = WindowList;
NULL != document; document = document->next) {
if (document->shell == window->shell) {
Widget text;
int i;
int lineNumCols;
XtVaGetValues(document->textArea,
textNlineNumCols, &lineNumCols,
NULL);
if (lineNumCols == reqCols) {
continue;
}
for (i =
0; i <= document->nPanes; i++) {
text =
0==i ? document->textArea : document->textPanes[i-
1];
XtVaSetValues(text, textNlineNumCols, reqCols,
NULL);
}
}
}
return reqCols;
}
static int updateLineNumDisp(WindowInfo* window)
{
if (!window->showLineNumbers) {
return 0;
}
return updateGutterWidth(window);
}
void UpdateStatsLine(WindowInfo *window)
{
int line, pos, colNum;
int byteLength;
long charCount =
0;
long offset =
0;
unsigned char current;
char * selection;
char *string, *format, slinecol[
42];
Widget statW = window->statsLine;
XmString xmslinecol;
#ifdef SGI_CUSTOM
char *sleft, *smid, *sright;
#endif
if (!IsTopDocument(window))
return;
if (!window->showStats)
return;
pos = TextGetCursorPos(window->lastFocus);
string = (
char*)NEditMalloc(strlen(window->filename) + strlen(window->path) +
45);
format = window->fileFormat ==
DOS_FILE_FORMAT ?
" DOS" :
(window->fileFormat ==
MAC_FILE_FORMAT ?
" Mac" :
"");
int nCursors = TextNumCursors(window->lastFocus);
if (!TextPosToLineAndCol(window->lastFocus, pos, &line, &colNum)) {
sprintf(string,
"%s%s%s %d bytes", window->path, window->filename,
format, window->buffer->length);
if(nCursors ==
1) {
snprintf(slinecol,
42,
"S: --- L: --- C: ---");
}
else {
snprintf(slinecol,
42,
"%d cursors", nCursors);
}
}
else {
if(nCursors ==
1) {
selection = BufGetSelectionText(window->buffer);
if (selection !=
NULL) {
byteLength = strlen(selection);
while (offset < byteLength) {
current = selection[offset];
if(current >=
240) {
offset +=
4;
}
else if(current >=
224) {
offset +=
3;
}
else if(current >
192) {
offset +=
2;
}
else {
offset ++;
}
charCount++;
}
snprintf(slinecol,
42,
"S: %ld L: %d C: %d", charCount, line, colNum);
}
else {
snprintf(slinecol,
42,
"S: --- L: %d C: %d", line, colNum);
}
NEditFree(selection);
}
else {
snprintf(slinecol,
42,
"%d cursors", nCursors);
}
if (window->showLineNumbers)
sprintf(string,
"%s%s%s byte %d of %d", window->path,
window->filename, format, pos,
window->buffer->length);
else
sprintf(string,
"%s%s%s %d bytes", window->path,
window->filename, format, window->buffer->length);
}
xmslinecol = XmStringCreateSimple(slinecol);
XtVaSetValues( window->statsLineColNo,
XmNlabelString, xmslinecol,
NULL );
XmStringFree(xmslinecol);
if (!window->modeMessageDisplayed) {
#ifdef SGI_CUSTOM
smid = strchr(string,
'/');
if ( smid !=
NULL ) {
sleft = smid;
sright = strrchr(string,
'/');
while (strcmp(smid, sright)) {
sleft = smid;
smid = strchr(sleft +
1,
'/');
}
XmTextReplace(statW,
0, XmTextGetLastPosition(statW), sleft +
1);
}
else
XmTextReplace(statW,
0, XmTextGetLastPosition(statW), string);
#else
XmTextReplace(statW,
0, XmTextGetLastPosition(statW), string);
#endif
}
NEditFree(string);
xmslinecol = XmStringCreateSimple(slinecol);
XtVaSetValues(window->statsLineColNo,
XmNlabelString, xmslinecol,
NULL);
XmStringFree(xmslinecol);
}
static Boolean currentlyBusy = False;
static long busyStartTime =
0;
static Boolean modeMessageSet = False;
static long getRelTimeInTenthsOfSeconds()
{
#ifdef __unix__
struct timeval current;
gettimeofday(¤t,
NULL);
return (current.tv_sec*
10 + current.tv_usec/
100000) & 0xFFFFFFFL;
#else
time_t current;
time(¤t);
return (current*
10) & 0xFFFFFFFL;
#endif
}
void AllWindowsBusy(
const char *message)
{
WindowInfo *w;
if (!currentlyBusy)
{
busyStartTime = getRelTimeInTenthsOfSeconds();
modeMessageSet = False;
for (w=WindowList; w!=
NULL; w=w->next)
{
BeginWait(w->shell);
}
}
else if (!modeMessageSet && message &&
getRelTimeInTenthsOfSeconds() - busyStartTime >
10) {
for (w=WindowList; w!=
NULL; w=w->next) {
SetModeMessage(w, message);
}
modeMessageSet = True;
}
BusyWait(WindowList->shell);
currentlyBusy = True;
}
void AllWindowsUnbusy(
void)
{
WindowInfo *w;
for (w=WindowList; w!=
NULL; w=w->next)
{
ClearModeMessage(w);
EndWait(w->shell);
}
currentlyBusy = False;
modeMessageSet = False;
busyStartTime =
0;
}
static void setPaneDesiredHeight(Widget w,
int height)
{
((XmPanedWindowConstraintPtr)w->core.constraints)->panedw.dheight = height;
}
static void setPaneMinHeight(Widget w,
int min)
{
((XmPanedWindowConstraintPtr)w->core.constraints)->panedw.min = min;
}
void UpdateWMSizeHints(WindowInfo *window)
{
Dimension shellWidth, shellHeight, textHeight, hScrollBarHeight;
int marginHeight, marginWidth, totalHeight, nCols, nRows;
NFont *fs;
XftFont *font;
int i, baseWidth, baseHeight, fontHeight, fontWidth;
Widget hScrollBar;
textDisp *textD = ((TextWidget)window->textArea)->text.textD;
XtVaGetValues(window->textArea, textNXftFont, &fs,
NULL);
font = FontDefault(fs);
fontHeight = textD->ascent + textD->descent;
fontWidth = fs->maxWidth;
XtVaGetValues(window->textArea, XmNheight, &textHeight,
textNmarginHeight, &marginHeight, textNmarginWidth, &marginWidth,
NULL);
totalHeight = textHeight -
2*marginHeight;
for (i=
0; i<window->nPanes; i++) {
XtVaGetValues(window->textPanes[i], XmNheight, &textHeight,
textNhScrollBar, &hScrollBar,
NULL);
totalHeight += textHeight -
2*marginHeight;
if (!XtIsManaged(hScrollBar)) {
XtVaGetValues(hScrollBar, XmNheight, &hScrollBarHeight,
NULL);
totalHeight -= hScrollBarHeight;
}
}
XtVaGetValues(window->shell, XmNwidth, &shellWidth,
XmNheight, &shellHeight,
NULL);
nCols = textD->width / fontWidth;
nRows = totalHeight / fontHeight;
baseWidth = shellWidth - nCols * fontWidth;
baseHeight = shellHeight - nRows * fontHeight;
XtVaSetValues(window->shell, XmNwidthInc, fs->maxWidth,
XmNheightInc, fontHeight,
XmNbaseWidth, baseWidth, XmNbaseHeight, baseHeight,
XmNminWidth, baseWidth + fontWidth,
XmNminHeight, baseHeight + (
1+window->nPanes) * fontHeight,
NULL);
RemovePPositionHint(window->shell);
}
void UpdateMinPaneHeights(WindowInfo *window)
{
textDisp *textD = ((TextWidget)window->textArea)->text.textD;
Dimension hsbHeight, swMarginHeight,frameShadowHeight;
int i, marginHeight, minPaneHeight;
Widget hScrollBar;
XtVaGetValues(window->textArea, textNhScrollBar, &hScrollBar,
NULL);
XtVaGetValues(containingPane(window->textArea),
XmNscrolledWindowMarginHeight, &swMarginHeight,
NULL);
XtVaGetValues(XtParent(window->textArea),
XmNshadowThickness, &frameShadowHeight,
NULL);
XtVaGetValues(window->textArea, textNmarginHeight, &marginHeight,
NULL);
XtVaGetValues(hScrollBar, XmNheight, &hsbHeight,
NULL);
minPaneHeight = textD->ascent + textD->descent + marginHeight*
2 +
swMarginHeight*
2 + hsbHeight +
2*frameShadowHeight;
setPaneMinHeight(containingPane(window->textArea), minPaneHeight);
for (i=
0; i<window->nPanes; i++)
setPaneMinHeight(containingPane(window->textPanes[i]),
minPaneHeight);
}
static void addWindowIcon(Widget shell)
{
static Pixmap iconPixmap =
0, maskPixmap =
0;
if (iconPixmap ==
0) {
iconPixmap = XCreateBitmapFromData(TheDisplay,
RootWindowOfScreen(XtScreen(shell)), (
char *)iconBits,
iconBitmapWidth, iconBitmapHeight);
maskPixmap = XCreateBitmapFromData(TheDisplay,
RootWindowOfScreen(XtScreen(shell)), (
char *)maskBits,
iconBitmapWidth, iconBitmapHeight);
}
XtVaSetValues(shell, XmNiconPixmap, iconPixmap, XmNiconMask, maskPixmap,
NULL);
}
void AddSmallIcon(Widget shell)
{
static Pixmap iconPixmap =
0, maskPixmap =
0;
if (iconPixmap ==
0) {
iconPixmap = XCreateBitmapFromData(TheDisplay,
RootWindowOfScreen(XtScreen(shell)), (
char *)n_bits,
n_width, n_height);
maskPixmap = XCreateBitmapFromData(TheDisplay,
RootWindowOfScreen(XtScreen(shell)), (
char *)n_mask,
n_width, n_height);
}
XtVaSetValues(shell, XmNiconPixmap, iconPixmap,
XmNiconMask, maskPixmap,
NULL);
}
static Pixmap createBitmapWithDepth(Widget w,
char *data,
unsigned int width,
unsigned int height)
{
Pixmap pixmap;
Pixel fg, bg;
int depth;
XtVaGetValues (w, XmNforeground, &fg, XmNbackground, &bg,
XmNdepth, &depth,
NULL);
pixmap = XCreatePixmapFromBitmapData(XtDisplay(w),
RootWindowOfScreen(XtScreen(w)), (
char *)data,
width, height, fg, bg, depth);
return pixmap;
}
static void getGeometryString(WindowInfo *window,
char *geomString)
{
int x, y, fontWidth, fontHeight, baseWidth, baseHeight;
unsigned int width, height, dummyW, dummyH, bw, depth, nChild;
Window parent, root, *child, w = XtWindow(window->shell);
Display *dpy = XtDisplay(window->shell);
XGetGeometry(dpy, w, &root, &x, &y, &width, &height, &bw, &depth);
for(;;) {
XQueryTree(dpy, w, &root, &parent, &child, &nChild);
XFree((
char*)child);
if (parent == root)
break;
w = parent;
}
XGetGeometry(dpy, w, &root, &x, &y, &dummyW, &dummyH, &bw, &depth);
XtVaGetValues(window->shell, XmNwidthInc, &fontWidth,
XmNheightInc, &fontHeight, XmNbaseWidth, &baseWidth,
XmNbaseHeight, &baseHeight,
NULL);
width = (width-baseWidth) / fontWidth;
height = (height-baseHeight) / fontHeight;
CreateGeometryString(geomString, x, y, width, height,
XValue | YValue | WidthValue | HeightValue);
}
static void wmSizeUpdateProc(XtPointer clientData, XtIntervalId *id)
{
UpdateWMSizeHints((WindowInfo *)clientData);
}
#ifdef ROWCOLPATCH
static void patchRowCol(Widget w)
{
((XmRowColumnClassRec *)XtClass(w))->composite_class.delete_child =
patchedRemoveChild;
}
static void patchedRemoveChild(Widget child)
{
(*((CompositeWidgetClass)compositeWidgetClass)->composite_class.
delete_child) (child);
}
#endif
void SetHighlightCursorLine(WindowInfo *window, Boolean state)
{
window->highlightCursorLine = state;
XtVaSetValues(window->textArea,
textNhighlightCursorLine, state,
NULL);
for (
int i=
0; i<window->nPanes; i++) {
XtVaSetValues(window->textPanes[i], textNhighlightCursorLine, state,
NULL);
}
}
void SetIndentRainbow(WindowInfo *window, Boolean state)
{
window->indentRainbow = state;
XtVaSetValues(window->textArea,
textNindentRainbow, state,
NULL);
for (
int i=
0; i<window->nPanes; i++) {
XtVaSetValues(window->textPanes[i], textNindentRainbow, state,
NULL);
}
}
void SetAnsiColors(WindowInfo *window, Boolean state)
{
window->ansiColors = state;
XtVaSetValues(window->textArea,
textNansiColors, state,
NULL);
for (
int i=
0; i<window->nPanes; i++) {
XtVaSetValues(window->textPanes[i], textNansiColors, state,
NULL);
}
}
void SetBacklightChars(WindowInfo *window,
char *applyBacklightTypes)
{
int i;
int is_applied = XmToggleButtonGetState(window->backlightCharsItem) ?
1 :
0;
int do_apply = applyBacklightTypes ?
1 :
0;
window->backlightChars = do_apply;
NEditFree(window->backlightCharTypes);
if (window->backlightChars &&
(window->backlightCharTypes = (
char*)NEditMalloc(strlen(applyBacklightTypes)+
1)))
strcpy(window->backlightCharTypes, applyBacklightTypes);
else
window->backlightCharTypes =
NULL;
XtVaSetValues(window->textArea,
textNbacklightCharTypes, window->backlightCharTypes,
NULL);
for (i=
0; i<window->nPanes; i++)
XtVaSetValues(window->textPanes[i],
textNbacklightCharTypes, window->backlightCharTypes,
NULL);
if (is_applied != do_apply)
SetToggleButtonState(window, window->backlightCharsItem, do_apply, False);
}
static Widget manageToolBars(Widget toolBarsForm)
{
Widget topWidget =
NULL;
WidgetList children;
int n, nItems=
0;
XtVaGetValues(toolBarsForm, XmNchildren, &children,
XmNnumChildren, &nItems,
NULL);
for (n=
0; n<nItems; n++) {
Widget tbar = children[n];
if (XtIsManaged(tbar)) {
if (topWidget) {
XtVaSetValues(tbar, XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, topWidget,
XmNbottomAttachment, XmATTACH_NONE,
XmNleftOffset,
STAT_SHADOW_THICKNESS,
XmNrightOffset,
STAT_SHADOW_THICKNESS,
NULL);
}
else {
XtVaSetValues(tbar, XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_NONE,
XmNleftOffset,
STAT_SHADOW_THICKNESS,
XmNtopOffset,
STAT_SHADOW_THICKNESS,
XmNrightOffset,
STAT_SHADOW_THICKNESS,
NULL);
}
topWidget = tbar;
if (n+
1<nItems && !strcmp(XtName(children[n+
1]),
"TOOLBAR_SEP")) {
XtManageChild(children[n+
1]);
}
}
else {
XtVaSetValues(tbar, XmNtopAttachment, XmATTACH_NONE,
XmNbottomAttachment, XmATTACH_FORM,
NULL);
if (n+
1<nItems && !strcmp(XtName(children[n+
1]),
"TOOLBAR_SEP")) {
XtUnmanageChild(children[n+
1]);
}
}
}
if (topWidget) {
if (strcmp(XtName(topWidget),
"TOOLBAR_SEP")) {
XtVaSetValues(topWidget,
XmNbottomAttachment, XmATTACH_FORM,
XmNbottomOffset,
STAT_SHADOW_THICKNESS,
NULL);
}
else {
Widget wgt;
XtVaGetValues(topWidget, XmNtopWidget, &wgt,
NULL);
XtUnmanageChild(topWidget);
XtVaSetValues(wgt,
XmNbottomAttachment, XmATTACH_FORM,
XmNbottomOffset,
STAT_SHADOW_THICKNESS,
NULL);
}
}
return topWidget;
}
static void getTextPaneDimension(WindowInfo *window,
int *nRows,
int *nCols)
{
Widget hScrollBar;
Dimension hScrollBarHeight, paneHeight;
int marginHeight, marginWidth, totalHeight, fontHeight;
textDisp *textD = ((TextWidget)window->textArea)->text.textD;
XtVaGetValues(window->textArea, textNcolumns, nCols,
NULL);
XtVaGetValues(window->textArea, textNhScrollBar, &hScrollBar,
textNmarginHeight, &marginHeight, textNmarginWidth, &marginWidth,
NULL);
XtVaGetValues(hScrollBar, XmNheight, &hScrollBarHeight,
NULL);
XtVaGetValues(window->splitPane, XmNheight, &paneHeight,
NULL);
totalHeight = paneHeight -
2*marginHeight -hScrollBarHeight;
fontHeight = textD->ascent + textD->descent;
*nRows = totalHeight/fontHeight;
}
WindowInfo* CreateDocument(WindowInfo* shellWindow,
const char* name)
{
Widget pane, text;
WindowInfo *window;
int nCols, nRows;
EnableWindowResourceDB(shellWindow);
window = (WindowInfo *)NEditMalloc(
sizeof(WindowInfo));
memcpy(window, shellWindow,
sizeof(WindowInfo));
#if 0
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->showLineNumbers = GetPrefLineNums();
window->showStats = GetPrefStatsLine();
window->showISearchLine = GetPrefISearchLine();
#endif
window->showInfoBar =
FALSE;
window->encErrors =
NULL;
window->numEncErrors =
0;
window->posEncErrors =
0;
window->multiFileReplSelected =
FALSE;
window->multiFileBusy =
FALSE;
window->writableWindows =
NULL;
window->nWritableWindows =
0;
window->fileChanged =
FALSE;
window->fileMissing = True;
window->fileMode =
0;
window->fileUid =
0;
window->fileGid =
0;
window->filenameSet =
FALSE;
window->fileFormat =
UNIX_FILE_FORMAT;
window->lastModTime =
0;
strcpy(window->filename, name);
window->encoding[
0] =
'\0';
window->filter =
NULL;
const char *default_encoding = GetPrefDefaultCharset();
if(default_encoding) {
size_t defenc_len = strlen(default_encoding);
if(strlen(default_encoding) <
MAX_ENCODING_LENGTH) {
memcpy(window->encoding, default_encoding, defenc_len+
1);
}
}
window->undo =
NULL;
window->redo =
NULL;
window->nPanes =
0;
window->autoSaveCharCount =
0;
window->autoSaveOpCount =
0;
window->undoOpCount =
0;
window->undoMemUsed =
0;
window->undo_op_batch_size =
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->highlightSyntax = GetPrefHighlightSyntax();
window->highlightCursorLine = GetPrefHighlightCursorLine();
window->indentRainbow = GetPrefIndentRainbow();
window->indentRainbowColors = NEditStrdup(GetPrefIndentRainbowColors());
window->ansiColors = GetPrefAnsiColors();
window->backlightCharTypes =
NULL;
window->backlightChars = GetPrefBacklightChars();
if (window->backlightChars) {
char *cTypes = GetPrefBacklightCharTypes();
if (cTypes && window->backlightChars) {
if ((window->backlightCharTypes = (
char*)NEditMalloc(strlen(cTypes) +
1)))
strcpy(window->backlightCharTypes, cTypes);
}
}
window->modeMessageDisplayed =
FALSE;
window->modeMessage =
NULL;
window->ignoreModify =
FALSE;
window->windowMenuValid =
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->font = FontRef(GetPrefFont());
window->italicFont = FontRef(GetPrefItalicFont());
window->boldFont = FontRef(GetPrefBoldFont());
window->boldItalicFont = FontRef(GetPrefBoldItalicFont());
window->zoom =
0;
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;
window->tab =
NULL;
window->bgMenuUndoItem =
NULL;
window->bgMenuRedoItem =
NULL;
window->device =
0;
window->inode =
0;
getTextPaneDimension(shellWindow, &nRows, &nCols);
pane = XtVaCreateWidget(
"pane",
xmPanedWindowWidgetClass, window->mainWin,
XmNmarginWidth,
0, XmNmarginHeight,
0, XmNseparatorOn, False,
XmNspacing,
3, XmNsashIndent, -
2,
XmNmappedWhenManaged, False,
NULL);
XtVaSetValues(window->mainWin, XmNworkWindow, pane,
NULL);
XtManageChild(pane);
window->splitPane = pane;
XtVaSetValues(pane, XmNuserData, window,
NULL);
AccelLockBugPatch(pane, window->menuBar);
text = createTextArea(pane, window, nRows, nCols,
GetPrefEmTabDist(
PLAIN_LANGUAGE_MODE), GetPrefDelimiters(),
GetPrefWrapMargin(), window->showLineNumbers?
MIN_LINE_NUM_COLS:
0);
XtManageChild(text);
window->textArea = text;
window->lastFocus = text;
SetColorProfile(window, shellWindow->colorProfile);
window->bgMenuPane = CreateBGMenu(window);
InitUserBGMenuCache(&window->userBGMenuCache);
window->buffer = BufCreate();
BufAddModifyCB(window->buffer, SyntaxHighlightModifyCB, window);
TextSetBuffer(text, window->buffer);
BufAddModifyCB(window->buffer, modifiedCB, window);
HandleXSelections(text);
BufSetTabDistance(window->buffer, GetPrefTabDist(
PLAIN_LANGUAGE_MODE));
window->buffer->useTabs = GetPrefInsertTabs();
window->tab = addTab(window->tabBar, name);
InvalidateWindowMenus();
addToWindowList(window);
#ifdef LESSTIF_VERSION
if (XtIsManaged(XtParent(window->statsLineForm))) {
XtUnmanageChild(XtParent(window->statsLineForm));
XtManageChild(XtParent(window->statsLineForm));
}
#endif
XtVaSetValues(window->mainWin, XmNworkWindow, shellWindow->splitPane,
NULL);
XLowerWindow(TheDisplay, XtWindow(window->splitPane));
XtUnmanageChild(window->splitPane);
XtVaSetValues(window->splitPane, XmNmappedWhenManaged, True,
NULL);
EnableDefaultColorProfileResourceDB(XtDisplay(window->mainWin));
return window;
}
static WindowInfo *getNextTabWindow(WindowInfo *window,
int direction,
int crossWin,
int wrap)
{
WidgetList tabList, tabs;
WindowInfo *win;
int tabCount, tabTotalCount;
int tabPos, nextPos;
int i, n;
int nBuf = crossWin? NWindows() : NDocuments(window);
if (nBuf <=
1)
return NULL;
tabs = (WidgetList)NEditMalloc(
sizeof(Widget) * nBuf);
tabTotalCount =
0;
if (crossWin) {
int n, nItems;
WidgetList children;
XtVaGetValues(TheAppShell, XmNchildren, &children,
XmNnumChildren, &nItems,
NULL);
for (n=
0; n<nItems; n++) {
if (strcmp(XtName(children[n]),
"textShell") ||
((win = WidgetToWindow(children[n])) ==
NULL))
continue;
XtVaGetValues(win->tabBar, XmNtabWidgetList, &tabList,
XmNtabCount, &tabCount,
NULL);
for (i=
0; i< tabCount; i++) {
tabs[tabTotalCount++] = tabList[i];
}
}
}
else {
XtVaGetValues(window->tabBar, XmNtabWidgetList, &tabList,
XmNtabCount, &tabCount,
NULL);
for (i=
0; i< tabCount; i++) {
if (TabToWindow(tabList[i]))
tabs[tabTotalCount++] = tabList[i];
}
}
tabPos =
0;
for (n=
0; n<tabTotalCount; n++) {
if (tabs[n] == window->tab) {
tabPos = n;
break;
}
}
nextPos = tabPos + direction;
if (nextPos >= nBuf) {
if (wrap)
nextPos =
0;
else
nextPos = nBuf -
2;
}
else if (nextPos <
0) {
if (wrap)
nextPos = nBuf -
1;
else
nextPos =
1;
}
win = TabToWindow(tabs[nextPos]);
NEditFree(tabs);
return win;
}
static int getTabPosition(Widget tab)
{
WidgetList tabList;
int i, tabCount;
Widget tabBar = XtParent(tab);
XtVaGetValues(tabBar, XmNtabWidgetList, &tabList,
XmNtabCount, &tabCount,
NULL);
for (i=
0; i< tabCount; i++) {
if (tab == tabList[i])
return i;
}
return -
1;
}
void RefreshTabState(WindowInfo *win)
{
XmString s1, tipString;
char labelString[
2*
MAXPATHLEN+
4];
char *tag = XmFONTLIST_DEFAULT_TAG;
unsigned char alignment;
XtVaGetValues(win->tab, XmNalignment, &alignment,
NULL);
if (alignment != XmALIGNMENT_END) {
snprintf(labelString,
sizeof(labelString),
"%s%s",
win->fileChanged?
"*" :
"",
win->filename);
}
else {
snprintf(labelString,
sizeof(labelString),
"%s%s",
win->filename,
win->fileChanged?
"*" :
"");
}
if (IsTopDocument(win))
tag =
"BOLD";
s1 = XmStringCreateLtoR(labelString, tag);
if (GetPrefShowPathInWindowsMenu() && win->filenameSet) {
strcat(labelString,
" - ");
strcat(labelString, win->path);
}
tipString=XmStringCreateSimple(labelString);
XtVaSetValues(win->tab,
XltNbubbleString, tipString,
XmNlabelString, s1,
NULL);
XmStringFree(s1);
XmStringFree(tipString);
}
typedef struct SaveFilesData {
Widget shell;
int status;
int end;
} SaveFilesData;
void savefiles_save(Widget w, SaveFilesData *data, XtPointer d)
{
data->status =
0;
data->end =
1;
}
void savefiles_dontsave(Widget w, SaveFilesData *data, XtPointer d)
{
data->status =
1;
data->end =
1;
}
void savefiles_cancel(Widget w, SaveFilesData *data, XtPointer d)
{
data->status =
2;
data->end =
1;
}
#define WIDGET_SPACING 5
#define WINDOW_SPACING 8
int SaveFilesDialog(WindowInfo *window)
{
Arg args[
32];
int n =
0;
XmString str;
Widget winShell = window->shell;
Widget dialog = CreateDialogShell(window->shell,
"Save Files", args,
0);
SaveFilesData data;
memset(&data,
0,
sizeof(SaveFilesData));
data.shell = dialog;
AddMotifCloseCallback(dialog, (XtCallbackProc)savefiles_cancel, &data);
n =
0;
XtSetArg(args[
0], XmNshadowThickness,
0); n++;
Widget form = XmCreateForm(dialog,
"form", args, n);
n =
0;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNshadowThickness,
1); n++;
XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
Widget buttons = XmCreateForm(form,
"btnform", args, n);
XtManageChild(buttons);
n =
0;
str = XmStringCreateLocalized(
"Save");
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNleftOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNrightOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
XtSetArg(args[n], XmNrightPosition,
33); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNtopOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNbottomOffset,
WINDOW_SPACING); n++;
Widget btnSave = XmCreatePushButton(buttons,
"button", args, n);
XtManageChild(btnSave);
XmStringFree(str);
n =
0;
str = XmStringCreateLocalized(
"Don''t Save");
XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
XtSetArg(args[n], XmNleftPosition,
33); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
XtSetArg(args[n], XmNrightPosition,
66); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
XtSetArg(args[n], XmNleftOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNrightOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNtopOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNbottomOffset,
WINDOW_SPACING); n++;
Widget btnDontSave = XmCreatePushButton(buttons,
"button", args, n);
XtManageChild(btnDontSave);
XmStringFree(str);
n =
0;
str = XmStringCreateLocalized(
"Cancel");
XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
XtSetArg(args[n], XmNleftPosition,
66); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNtopOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNbottomOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNleftOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNrightOffset,
WINDOW_SPACING); n++;
Widget btnCancel = XmCreatePushButton(buttons,
"button", args, n);
XtManageChild(btnCancel);
XmStringFree(str);
n =
0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNleftWidget, btnDontSave); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNrightWidget, btnCancel); n++;
XtSetArg(args[n], XmNrightOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNtopOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNbottomOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++;
Widget space = XmCreateSeparator(buttons,
"space", args, n);
XtManageChild(space);
n =
0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNbottomWidget, buttons); n++;
XtSetArg(args[n], XmNshadowThickness,
1); n++;
XtSetArg(args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
Widget topForm = XmCreateForm(form,
"frame", args, n);
XtManageChild(topForm);
n =
0;
str = XmStringCreateLocalized(
"Save files before closing?");
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNtopOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNleftOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
Widget label = XmCreateLabel(topForm,
"label", args, n);
XtManageChild(label);
XmStringFree(str);
n =
0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNtopWidget, label); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNtopOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNleftOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNrightOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNbottomOffset,
WINDOW_SPACING); n++;
XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmAS_NEEDED); n++;
XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); n++;
XtSetArg(args[n], XmNshadowThickness,
1); n++;
Widget scrollW = XmCreateScrolledWindow(topForm,
"scrolledwindow", args, n);
XtManageChild(scrollW);
n =
0;
XtSetArg(args[n], XmNshadowThickness,
0); n++;
Widget docForm = XmCreateForm(scrollW,
"form", args, n);
size_t dalloc =
64;
size_t dsize =
0;
Widget *docButtons = NEditCalloc(dalloc,
sizeof(Widget));
n =
0;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNleftOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNtopOffset,
WIDGET_SPACING); n++;
XtSetArg(args[n], XmNset,
1); n++;
int k = n;
Widget topWid =
NULL;
for (WindowInfo *win=WindowList;win;win=win->next) {
if(win->shell == winShell && win->fileChanged) {
n = k;
str = XmStringCreateLocalized(win->filename);
XtSetArg(args[n], XmNlabelString, str); n++;
XtSetArg(args[n], XmNuserData, win); n++;
if(topWid) {
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNtopWidget, topWid); n++;
}
else {
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
}
topWid = XmCreateToggleButton(docForm,
"sfbutton", args, n);
XtManageChild(topWid);
XmStringFree(str);
if(dsize >= dalloc) {
dalloc +=
64;
docButtons = NEditRealloc(docButtons, dalloc *
sizeof(Widget));
}
docButtons[dsize++] = topWid;
}
}
XtManageChild(docForm);
n =
0;
XtVaSetValues(
buttons,
XmNdefaultButton,
btnSave,
XmNcancelButton,
btnCancel,
NULL);
XtAddCallback(
btnSave,
XmNactivateCallback,
(XtCallbackProc)savefiles_save,
&data);
XtAddCallback(
btnDontSave,
XmNactivateCallback,
(XtCallbackProc)savefiles_dontsave,
&data);
XtAddCallback(
btnCancel,
XmNactivateCallback,
(XtCallbackProc)savefiles_cancel,
&data);
if(dsize >
0) {
ManageDialogCenteredOnPointer(form);
XmProcessTraversal(buttons, XmTRAVERSE_CURRENT);
XtAppContext app = XtWidgetToApplicationContext(dialog);
while(!data.end && !XtAppGetExitFlag(app)) {
XEvent event;
XtAppNextEvent(app, &event);
XtDispatchEvent(&event);
}
}
XtUnmapWidget(dialog);
int save = data.status ==
0 ?
YES_SBC_DIALOG_RESPONSE :
NO_SBC_DIALOG_RESPONSE;
if(data.status !=
2) {
for(
int i=
0;i<dsize;i++) {
Boolean set = True;
WindowInfo *win =
NULL;
XtVaGetValues(docButtons[i], XmNset, &set, XmNuserData, &win,
NULL);
int saveDoc = save;
if(!set) {
saveDoc =
NO_SBC_DIALOG_RESPONSE;
}
if(win) {
if(!CloseFileAndWindow(win, saveDoc)) {
data.status =
2;
break;
}
}
}
}
NEditFree(docButtons);
XtDestroyWidget(dialog);
return data.status ==
2 ? True : False;
}
int CloseAllDocumentInWindow(WindowInfo *window)
{
WindowInfo *win;
if (NUnsavedDocuments(window) ==
1) {
return CloseFileAndWindow(window,
PROMPT_SBC_DIALOG_RESPONSE);
}
else {
Widget winShell = window->shell;
WindowInfo *topDocument;
#ifndef OLD_CLOSE_FILE_DIALOG
if(SaveFilesDialog(window)) {
return False;
}
#else
for (win = WindowList; win; ) {
if (win->shell == winShell && win->fileChanged) {
WindowInfo *next = win->next;
if (!CloseFileAndWindow(win,
PROMPT_SBC_DIALOG_RESPONSE))
return False;
win = next;
}
else
win = win->next;
}
#endif
for (win = WindowList; win; win=win->next)
if (win->shell == winShell)
break;
if (win) {
topDocument = GetTopDocument(winShell);
for (win = WindowList; win; ) {
if (win->shell == winShell && win != topDocument) {
WindowInfo *next = win->next;
if (!CloseFileAndWindow(win,
PROMPT_SBC_DIALOG_RESPONSE))
return False;
win = next;
}
else
win = win->next;
}
if (!CloseFileAndWindow(topDocument,
PROMPT_SBC_DIALOG_RESPONSE))
return False;
}
}
return True;
}
static void CloseDocumentWindow(Widget w, WindowInfo *window, XtPointer callData)
{
int nDocuments = NDocuments(window);
if (nDocuments == NWindows()) {
XtCallActionProc(WindowList->lastFocus,
"exit",
((XmAnyCallbackStruct *)callData)->event,
NULL,
0);
}
else {
if (nDocuments ==
1) {
CloseFileAndWindow(window,
PROMPT_SBC_DIALOG_RESPONSE);
}
else {
int resp =
1;
if (GetPrefWarnExit())
resp = DialogF(
DF_QUES, window->shell,
2,
"Close Window",
"Close ALL documents in this window?",
"Close",
"Cancel");
if (resp ==
1)
CloseAllDocumentInWindow(window);
}
}
}
void RefreshMenuToggleStates(WindowInfo *window)
{
WindowInfo *win;
if (!IsTopDocument(window))
return;
XtSetSensitive(window->printSelItem, window->wasSelected);
XtSetSensitive(window->undoItem, window->undo !=
NULL);
XtSetSensitive(window->redoItem, window->redo !=
NULL);
XtSetSensitive(window->printSelItem, window->wasSelected);
XtSetSensitive(window->cutItem, window->wasSelected);
XtSetSensitive(window->copyItem, window->wasSelected);
XtSetSensitive(window->delItem, window->wasSelected);
XmToggleButtonSetState(window->statsLineItem, window->showStats, False);
XmToggleButtonSetState(window->iSearchLineItem, window->showISearchLine, False);
XmToggleButtonSetState(window->lineNumsItem, window->showLineNumbers, False);
XmToggleButtonSetState(window->highlightItem, window->highlightSyntax, False);
XtSetSensitive(window->resetZoomItem, window->zoom ==
0 ? False : True);
XtSetSensitive(window->highlightItem, window->languageMode !=
PLAIN_LANGUAGE_MODE);
XmToggleButtonSetState(window->backlightCharsItem, window->backlightChars, False);
XmToggleButtonSetState(window->highlightCursorLineItem, window->highlightCursorLine, False);
XmToggleButtonSetState(window->indentRainbowItem, window->indentRainbow, False);
XmToggleButtonSetState(window->ansiColorsItem, window->ansiColors, False);
XmToggleButtonSetState(window->saveLastItem, window->saveOldVersion, False);
XmToggleButtonSetState(window->autoSaveItem, window->autoSave, False);
XmToggleButtonSetState(window->overtypeModeItem, window->overstrike, False);
XmToggleButtonSetState(window->matchSyntaxBasedItem, window->matchSyntaxBased, False);
XmToggleButtonSetState(window->readOnlyItem,
IS_USER_LOCKED(window->lockReasons), False);
XtSetSensitive(window->smartIndentItem,
SmartIndentMacrosAvailable(LanguageModeName(window->languageMode)));
SetAutoIndent(window, window->indentStyle);
SetAutoWrap(window, window->wrapMode);
SetShowMatching(window, window->showMatchingStyle);
SetLanguageMode(window, window->languageMode,
FALSE);
XtSetSensitive(window->splitPaneItem, window->nPanes <
MAX_PANES);
XtSetSensitive(window->closePaneItem, window->nPanes >
0);
XtSetSensitive(window->detachDocumentItem, NDocuments(window)>
1);
XtSetSensitive(window->contextDetachDocumentItem, NDocuments(window)>
1);
for (win=WindowList; win; win=win->next)
if (win->shell != window->shell)
break;
XtSetSensitive(window->moveDocumentItem, win !=
NULL);
}
static void refreshMenuBar(WindowInfo *window)
{
RefreshMenuToggleStates(window);
UpdateUserMenus(window);
DimSelectionDepUserMenuItems(window, window->wasSelected);
}
WindowInfo *MarkLastDocument(WindowInfo *window)
{
WindowInfo *prev = lastFocusDocument;
if (window)
lastFocusDocument = window;
return prev;
}
WindowInfo *MarkActiveDocument(WindowInfo *window)
{
WindowInfo *prev = inFocusDocument;
if (window)
inFocusDocument = window;
return prev;
}
void NextDocument(WindowInfo *window)
{
WindowInfo *win;
if (WindowList->next ==
NULL)
return;
win = getNextTabWindow(window,
1, GetPrefGlobalTabNavigate(),
1);
if (win ==
NULL)
return;
if (window->shell == win->shell)
RaiseDocument(win);
else
RaiseFocusDocumentWindow(win, True);
}
void PreviousDocument(WindowInfo *window)
{
WindowInfo *win;
if (WindowList->next ==
NULL)
return;
win = getNextTabWindow(window, -
1, GetPrefGlobalTabNavigate(),
1);
if (win ==
NULL)
return;
if (window->shell == win->shell)
RaiseDocument(win);
else
RaiseFocusDocumentWindow(win, True);
}
void LastDocument(WindowInfo *window)
{
WindowInfo *win;
for(win = WindowList; win; win=win->next)
if (lastFocusDocument == win)
break;
if (!win)
return;
if (window->shell == win->shell)
RaiseDocument(win);
else
RaiseFocusDocumentWindow(win, True);
}
int IsValidWindow(WindowInfo *window)
{
WindowInfo *win;
for(win = WindowList; win; win=win->next)
if (window == win)
return True;
return False;
}
void RaiseDocumentWindow(WindowInfo *window)
{
if (!window)
return;
RaiseDocument(window);
RaiseShellWindow(window->shell, GetPrefFocusOnRaise());
}
void RaiseFocusDocumentWindow(WindowInfo *window, Boolean focus)
{
if (!window)
return;
RaiseDocument(window);
RaiseShellWindow(window->shell, focus);
}
static void redisplayTearOffs(Widget menuPane)
{
WidgetList itemList;
Widget subMenuID;
Cardinal nItems;
int n;
XtVaGetValues(menuPane, XmNchildren, &itemList,
XmNnumChildren, &nItems,
NULL);
for (n=
0; n<(
int)nItems; n++) {
if (XtClass(itemList[n]) == xmCascadeButtonWidgetClass) {
XtVaGetValues(itemList[n], XmNsubMenuId, &subMenuID,
NULL);
redisplayTearOffs(subMenuID);
}
}
if (!XmIsMenuShell(XtParent(menuPane)))
ShowHiddenTearOff(menuPane);
}
static void hideTearOffs(Widget menuPane)
{
WidgetList itemList;
Widget subMenuID;
Cardinal nItems;
int n;
XtVaGetValues(menuPane, XmNchildren, &itemList,
XmNnumChildren, &nItems,
NULL);
for (n=
0; n<(
int)nItems; n++) {
if (XtClass(itemList[n]) == xmCascadeButtonWidgetClass) {
XtVaGetValues(itemList[n], XmNsubMenuId, &subMenuID,
NULL);
hideTearOffs(subMenuID);
}
}
if (!XmIsMenuShell(XtParent(menuPane)))
XtUnmapWidget(XtParent(menuPane));
}
void RaiseDocument(WindowInfo *window)
{
WindowInfo *win, *lastwin;
if (!window || !WindowList)
return;
lastwin = MarkActiveDocument(window);
if (lastwin != window && IsValidWindow(lastwin))
MarkLastDocument(lastwin);
XtVaGetValues(window->mainWin, XmNuserData, &win,
NULL);
if (win == window)
return;
XtVaSetValues(window->mainWin, XmNuserData, window,
NULL);
XtVaSetValues(window->mainWin, XmNworkWindow, window->splitPane,
NULL);
XtManageChild(window->splitPane);
XRaiseWindow(TheDisplay, XtWindow(window->splitPane));
if (window->highlightSyntax && window->highlightData==
NULL)
StartHighlighting(window, False);
hideTearOffs(win->bgMenuPane);
redisplayTearOffs(window->bgMenuPane);
XmLFolderSetActiveTab(window->tabBar,
getTabPosition(window->tab), False);
XmProcessTraversal(window->lastFocus, XmTRAVERSE_CURRENT);
XLowerWindow(TheDisplay, XtWindow(win->splitPane));
XtUnmanageChild(win->splitPane);
RefreshTabState(win);
XmUpdateDisplay(window->splitPane);
RefreshWindowStates(window);
RefreshTabState(window);
hideTearOffs(win->bgMenuPane);
redisplayTearOffs(window->bgMenuPane);
if (window->replaceDlog !=
NULL && XtIsManaged(window->replaceDlog))
{
#ifdef REPLACE_SCOPE
window->replaceScope = win->replaceScope;
#endif
UpdateReplaceActionButtons(window);
}
UpdateWMSizeHints(window);
}
WindowInfo* GetTopDocument(Widget w)
{
WindowInfo *window = WidgetToWindow(w);
return WidgetToWindow(window->shell);
}
Boolean IsTopDocument(
const WindowInfo *window)
{
return window == GetTopDocument(window->shell)? True : False;
}
static void deleteDocument(WindowInfo *window)
{
if (
NULL == window) {
return;
}
XtDestroyWidget(window->splitPane);
}
int NDocuments(WindowInfo *window)
{
WindowInfo *win;
int nDocument =
0;
for (win = WindowList; win; win = win->next) {
if (win->shell == window->shell)
nDocument++;
}
return nDocument;
}
int NUnsavedDocuments(WindowInfo *window)
{
WindowInfo *win;
Widget winShell = window->shell;
int nDocument =
0;
for (win = WindowList; win; win = win->next) {
if(win->shell == winShell && win->fileChanged)
nDocument++;
}
return nDocument;
}
void RefreshWindowStates(WindowInfo *window)
{
int updateStatsFormStatus =
0;
if (!IsTopDocument(window))
return;
if(!window->showInfoBar && XtIsManaged(window->encodingInfoBar)) {
XtUnmanageChild(window->encodingInfoBar);
updateStatsFormStatus =
1;
}
if (window->modeMessageDisplayed) {
XmTextSetString(window->statsLine, window->modeMessage);
}
else {
UpdateStatsLine(window);
}
UpdateWindowReadOnly(window);
UpdateWindowTitle(window);
if (window->modeMessageDisplayed && !XtIsManaged(window->statsLineForm)) {
showStats(window, True);
}
else if (window->showStats && !XtIsManaged(window->statsLineForm)) {
showStats(window, True);
}
else if (!window->showStats && !window->modeMessageDisplayed &&
XtIsManaged(window->statsLineForm)) {
showStats(window, False);
}
else if(updateStatsFormStatus) {
showStatsForm(window);
}
ShowEncodingInfoBar(window, window->showInfoBar);
if (window->shellCmdData || window->macroCmdData)
BeginWait(window->shell);
else
EndWait(window->shell);
if (XtIsManaged(window->statsLineForm)) {
XmTextSetCursorPosition(window->statsLine,
0);
XmTextSetCursorPosition(window->statsLine,
9000);
}
XmUpdateDisplay(window->statsLine);
refreshMenuBar(window);
updateLineNumDisp(window);
}
static void cloneTextPanes(WindowInfo *window, WindowInfo *orgWin)
{
short paneHeights[
MAX_PANES+
1];
int insertPositions[
MAX_PANES+
1], topLines[
MAX_PANES+
1];
int horizOffsets[
MAX_PANES+
1];
int i, focusPane, emTabDist, wrapMargin, lineNumCols, totalHeight=
0;
char *delimiters;
Widget text;
selection sel;
textDisp *textD, *newTextD;
memcpy(&sel, &orgWin->buffer->primary,
sizeof(selection));
if (sel.selected) {
if (sel.rectangular)
BufRectSelect(window->buffer, sel.start, sel.end,
sel.rectStart, sel.rectEnd);
else
BufSelect(window->buffer, sel.start, sel.end);
}
else
BufUnselect(window->buffer);
focusPane =
0;
for (i=
0; i<=orgWin->nPanes; i++) {
text = i==
0 ? orgWin->textArea : orgWin->textPanes[i-
1];
insertPositions[i] = TextGetCursorPos(text);
XtVaGetValues(containingPane(text), XmNheight, &paneHeights[i],
NULL);
totalHeight += paneHeights[i];
TextGetScroll(text, &topLines[i], &horizOffsets[i]);
if (text == orgWin->lastFocus)
focusPane = i;
}
window->nPanes = orgWin->nPanes;
XtVaGetValues(orgWin->textArea, textNemulateTabs, &emTabDist,
textNwordDelimiters, &delimiters, textNwrapMargin, &wrapMargin,
NULL);
lineNumCols = orgWin->showLineNumbers ?
MIN_LINE_NUM_COLS :
0;
XtVaSetValues(window->textArea, textNemulateTabs, emTabDist,
textNwordDelimiters, delimiters, textNwrapMargin, wrapMargin,
textNlineNumCols, lineNumCols,
NULL);
textD = ((TextWidget)window->textArea)->text.textD;
if (window->nPanes) {
XtUnmanageChild(window->splitPane);
for(i=
0; i<orgWin->nPanes; i++) {
text = createTextArea(window->splitPane, window,
1,
1, emTabDist,
delimiters, wrapMargin, lineNumCols);
TextSetBuffer(text, window->buffer);
if (window->highlightData !=
NULL)
AttachHighlightToWidget(text, window);
XtManageChild(text);
window->textPanes[i] = text;
newTextD = ((TextWidget)text)->text.textD;
XtVaSetValues(text, XmNforeground, textD->colorProfile->textFgColor.pixel,
XmNbackground, textD->colorProfile->textBgColor.pixel,
textNansiColorList, window->ansiColorList,
NULL);
TextDSetColorProfile(newTextD, textD->colorProfile);
}
UpdateMinPaneHeights(window);
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
setPaneDesiredHeight(containingPane(text), paneHeights[i]);
}
XtManageChild(window->splitPane);
}
for (i=
0; i<=window->nPanes; i++) {
textDisp *paneTextD;
text = i==
0 ? window->textArea : window->textPanes[i-
1];
TextSetCursorPos(text, insertPositions[i]);
TextSetScroll(text, topLines[i], horizOffsets[i]);
paneTextD = ((TextWidget)text)->text.textD;
TextDSetCursorStyle(paneTextD,
DIM_CURSOR);
TextDUnblankCursor(paneTextD);
}
for (i=
0; i<=window->nPanes; i++) {
text = i==
0 ? window->textArea : window->textPanes[i-
1];
if(i == focusPane) {
window->lastFocus = text;
XmProcessTraversal(text, XmTRAVERSE_CURRENT);
break;
}
}
XtAppAddTimeOut(XtWidgetToApplicationContext(window->shell),
0,
wmSizeUpdateProc, window);
}
static void cloneDocument(WindowInfo *window, WindowInfo *orgWin)
{
const char *orgDocument;
char *params[
4];
int emTabDist;
strcpy(window->path, orgWin->path);
strcpy(window->filename, orgWin->filename);
strcpy(window->encoding, orgWin->encoding);
if(orgWin->filter) {
NEditFree(window->filter);
window->filter = NEditStrdup(orgWin->filter);
}
ShowLineNumbers(window, orgWin->showLineNumbers);
window->ignoreModify = True;
orgDocument = BufAsString(orgWin->buffer);
BufSetAll(window->buffer, orgDocument);
BufSetTabDistance(window->buffer, orgWin->buffer->tabDist);
window->buffer->useTabs = orgWin->buffer->useTabs;
XtVaGetValues(orgWin->textArea, textNemulateTabs, &emTabDist,
NULL);
SetEmTabDist(window, emTabDist);
window->ignoreModify = False;
params[
0] = orgWin->fontName;
params[
1] = orgWin->italicFontName;
params[
2] = orgWin->boldFontName;
params[
3] = orgWin->boldItalicFontName;
XtCallActionProc(window->textArea,
"set_fonts",
NULL, params,
4);
window->zoom = orgWin->zoom;
SetHighlightCursorLine(window, orgWin->highlightCursorLine);
SetIndentRainbow(window, orgWin->indentRainbow);
SetAnsiColors(window, orgWin->ansiColors);
SetBacklightChars(window, orgWin->backlightCharTypes);
window->buffer->rangesetTable =
RangesetTableClone(orgWin->buffer->rangesetTable, window->buffer);
window->languageMode = orgWin->languageMode;
window->highlightSyntax = orgWin->highlightSyntax;
if (window->highlightSyntax)
StartHighlighting(window, False);
window->filenameSet = orgWin->filenameSet;
window->fileFormat = orgWin->fileFormat;
window->lastModTime = orgWin->lastModTime;
window->fileChanged = orgWin->fileChanged;
window->fileMissing = orgWin->fileMissing;
window->lockReasons = orgWin->lockReasons;
window->autoSaveCharCount = orgWin->autoSaveCharCount;
window->autoSaveOpCount = orgWin->autoSaveOpCount;
window->undoOpCount = orgWin->undoOpCount;
window->undoMemUsed = orgWin->undoMemUsed;
window->autoSave = orgWin->autoSave;
window->saveOldVersion = orgWin->saveOldVersion;
window->wrapMode = orgWin->wrapMode;
SetOverstrike(window, orgWin->overstrike);
window->showMatchingStyle = orgWin->showMatchingStyle;
window->matchSyntaxBased = orgWin->matchSyntaxBased;
#if 0
window->showStats = orgWin->showStats;
window->showISearchLine = orgWin->showISearchLine;
window->showLineNumbers = orgWin->showLineNumbers;
window->modeMessageDisplayed = orgWin->modeMessageDisplayed;
window->ignoreModify = orgWin->ignoreModify;
window->windowMenuValid = orgWin->windowMenuValid;
window->flashTimeoutID = orgWin->flashTimeoutID;
window->wasSelected = orgWin->wasSelected;
strcpy(window->fontName, orgWin->fontName);
strcpy(window->italicFontName, orgWin->italicFontName);
strcpy(window->boldFontName, orgWin->boldFontName);
strcpy(window->boldItalicFontName, orgWin->boldItalicFontName);
window->italicFontStruct = orgWin->italicFontStruct;
window->boldFontStruct = orgWin->boldFontStruct;
window->boldItalicFontStruct = orgWin->boldItalicFontStruct;
window->markTimeoutID = orgWin->markTimeoutID;
window->highlightData = orgWin->highlightData;
window->shellCmdData = orgWin->shellCmdData;
window->macroCmdData = orgWin->macroCmdData;
window->smartIndentData = orgWin->smartIndentData;
#endif
window->iSearchHistIndex = orgWin->iSearchHistIndex;
window->iSearchStartPos = orgWin->iSearchStartPos;
window->replaceLastRegexCase = orgWin->replaceLastRegexCase;
window->replaceLastLiteralCase = orgWin->replaceLastLiteralCase;
window->iSearchLastRegexCase = orgWin->iSearchLastRegexCase;
window->iSearchLastLiteralCase = orgWin->iSearchLastLiteralCase;
window->findLastRegexCase = orgWin->findLastRegexCase;
window->findLastLiteralCase = orgWin->findLastLiteralCase;
window->device = orgWin->device;
window->inode = orgWin->inode;
window->fileClosedAtom = orgWin->fileClosedAtom;
orgWin->fileClosedAtom = None;
cloneTextPanes(window, orgWin);
window->undo = cloneUndoItems(orgWin->undo);
window->redo = cloneUndoItems(orgWin->redo);
window->encErrors =
NULL;
window->numEncErrors =
0;
window->posEncErrors =
0;
window->nMarks = orgWin->nMarks;
memcpy(&window->markTable, &orgWin->markTable,
sizeof(Bookmark)*window->nMarks);
window->indentStyle =
NO_AUTO_INDENT;
SetAutoIndent(window, orgWin->indentStyle);
RefreshWindowStates(window);
}
static UndoInfo *cloneUndoItems(UndoInfo *orgList)
{
UndoInfo *head =
NULL, *undo, *clone, *last =
NULL;
for (undo = orgList; undo; undo = undo->next) {
clone = (UndoInfo *)NEditMalloc(
sizeof(UndoInfo));
memcpy(clone, undo,
sizeof(UndoInfo));
if (undo->oldText) {
clone->oldText = (
char*)NEditMalloc(strlen(undo->oldText)+
1);
strcpy(clone->oldText, undo->oldText);
}
clone->next =
NULL;
if (last)
last->next = clone;
else
head = clone;
last = clone;
}
return head;
}
WindowInfo *DetachDocument(WindowInfo *window)
{
WindowInfo *win =
NULL, *cloneWin;
if (NDocuments(window) <
2)
return NULL;
if (IsTopDocument(window)) {
win = getNextTabWindow(window,
1,
0,
0);
RaiseDocument(win);
}
Dimension width, height;
XtVaGetValues(window->shell, XmNwidth, &width, XmNheight, &height,
NULL);
cloneWin = CreateWindow(window->filename,
NULL, False);
XtVaSetValues(cloneWin->shell, XmNwidth, width, XmNheight, height,
NULL);
WindowList = cloneWin->next;
cloneWin->next = window->next;
window->next = cloneWin;
ShowISearchLine(cloneWin, window->showISearchLine);
ShowStatsLine(cloneWin, window->showStats);
cloneDocument(cloneWin, window);
window->fileChanged = False;
CloseFileAndWindow(window,
NO_SBC_DIALOG_RESPONSE);
if (win) {
RefreshWindowStates(win);
}
RefreshWindowStates(cloneWin);
RefreshTabState(cloneWin);
SortTabBar(cloneWin);
return cloneWin;
}
WindowInfo *MoveDocument(WindowInfo *toWindow, WindowInfo *window)
{
WindowInfo *win =
NULL, *cloneWin;
if (NDocuments(window) <
2) {
XtUnmapWidget(window->shell);
}
else if (IsTopDocument(window)) {
win = getNextTabWindow(window,
1,
0,
0);
RaiseDocument(win);
}
cloneWin = CreateDocument(toWindow, window->filename);
ShowTabBar(cloneWin, GetShowTabBar(cloneWin));
cloneDocument(cloneWin, window);
WindowList = cloneWin->next;
cloneWin->next = window->next;
window->next = cloneWin;
window->fileChanged = False;
CloseFileAndWindow(window,
NO_SBC_DIALOG_RESPONSE);
if (win)
RefreshWindowStates(win);
RaiseDocumentWindow(cloneWin);
RefreshTabState(cloneWin);
SortTabBar(cloneWin);
return cloneWin;
}
static void moveDocumentCB(Widget dialog, WindowInfo *window,
XtPointer call_data)
{
XmSelectionBoxCallbackStruct *cbs = (XmSelectionBoxCallbackStruct *) call_data;
DoneWithMoveDocumentDialog = cbs->reason;
}
void MoveDocumentDialog(WindowInfo *window)
{
WindowInfo *win, *targetWin, **shellWinList;
int i, nList=
0, nWindows=
0, ac;
char tmpStr[
2*
MAXPATHLEN];
Widget parent, dialog, listBox, moveAllOption;
XmString *list =
NULL;
XmString popupTitle, s1;
Arg csdargs[
20];
int *position_list, position_count;
nWindows = NWindows();
list = (XmStringTable) NEditMalloc(nWindows *
sizeof(XmString *));
shellWinList = (WindowInfo **) NEditMalloc(nWindows *
sizeof(WindowInfo *));
for (win=WindowList; win; win=win->next) {
if (!IsTopDocument(win) || win->shell == window->shell)
continue;
snprintf(tmpStr,
sizeof(tmpStr),
"%s%s",
win->filenameSet? win->path :
"", win->filename);
list[nList] = XmStringCreateSimple(tmpStr);
shellWinList[nList] = win;
nList++;
}
if (!nList) {
NEditFree(list);
NEditFree(shellWinList);
return;
}
parent = window->shell;
popupTitle = XmStringCreateSimple(
"Move Document");
snprintf(tmpStr,
sizeof(tmpStr),
"Move %s into window of", window->filename);
s1 = XmStringCreateSimple(tmpStr);
ac =
0;
XtSetArg(csdargs[ac], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); ac++;
XtSetArg(csdargs[ac], XmNdialogTitle, popupTitle); ac++;
XtSetArg(csdargs[ac], XmNlistLabelString, s1); ac++;
XtSetArg(csdargs[ac], XmNlistItems, list); ac++;
XtSetArg(csdargs[ac], XmNlistItemCount, nList); ac++;
XtSetArg(csdargs[ac], XmNvisibleItemCount,
12); ac++;
XtSetArg(csdargs[ac], XmNautoUnmanage, False); ac++;
dialog = CreateSelectionDialog(parent,
"moveDocument",csdargs,ac);
XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_TEXT));
XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_SELECTION_LABEL));
XtAddCallback(dialog, XmNokCallback, (XtCallbackProc)moveDocumentCB, window);
XtAddCallback(dialog, XmNapplyCallback, (XtCallbackProc)moveDocumentCB, window);
XtAddCallback(dialog, XmNcancelCallback, (XtCallbackProc)moveDocumentCB, window);
XmStringFree(s1);
XmStringFree(popupTitle);
for (i=
0; i<nList; i++)
XmStringFree(list[i]);
NEditFree(list);
s1 =
MKSTRING(
"Move all documents in this window");
moveAllOption = XtVaCreateWidget(
"moveAll",
xmToggleButtonWidgetClass, dialog,
XmNlabelString, s1,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
XmStringFree(s1);
if (NDocuments(window) >
1)
XtManageChild(moveAllOption);
XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));
s1 =
MKSTRING(
"Move");
XtVaSetValues (dialog, XmNokLabelString, s1,
NULL);
XmStringFree(s1);
listBox = XmSelectionBoxGetChild(dialog, XmDIALOG_LIST);
XmListSelectPos(listBox,
1, True);
DoneWithMoveDocumentDialog =
0;
ManageDialogCenteredOnPointer(dialog);
while (!DoneWithMoveDocumentDialog)
XtAppProcessEvent(XtWidgetToApplicationContext(parent), XtIMAll);
XmListGetSelectedPos(listBox, &position_list, &position_count);
targetWin = shellWinList[position_list[
0]-
1];
NEditFree(position_list);
if (DoneWithMoveDocumentDialog == XmCR_OK) {
if (XmToggleButtonGetState(moveAllOption)) {
for (win = WindowList; win; ) {
if (win != window && win->shell == window->shell) {
WindowInfo *next = win->next;
MoveDocument(targetWin, win);
win = next;
}
else
win = win->next;
}
MoveDocument(targetWin, window);
}
else {
MoveDocument(targetWin, window);
}
}
NEditFree(shellWinList);
XtDestroyWidget(dialog);
}
static void hideTooltip(Widget tab)
{
Widget tooltip = XtNameToWidget(tab,
"*BubbleShell");
if (tooltip)
XtPopdown(tooltip);
}
static void closeTabProc(XtPointer clientData, XtIntervalId *id)
{
CloseFileAndWindow((WindowInfo*)clientData,
PROMPT_SBC_DIALOG_RESPONSE);
}
static void closeTabCB(Widget w, Widget mainWin,
caddr_t callData)
{
XtAppAddTimeOut(XtWidgetToApplicationContext(w),
0,
closeTabProc, GetTopDocument(mainWin));
}
static void raiseTabCB(Widget w, XtPointer clientData, XtPointer callData)
{
XmLFolderCallbackStruct *cbs = (XmLFolderCallbackStruct *)callData;
WidgetList tabList;
Widget tab;
XtVaGetValues(w, XmNtabWidgetList, &tabList,
NULL);
tab = tabList[cbs->pos];
RaiseDocument(TabToWindow(tab));
}
static Widget containingPane(Widget w)
{
return XtParent(XtParent(w));
}
static void cancelTimeOut(XtIntervalId *timer)
{
if (*timer !=
0)
{
XtRemoveTimeOut(*timer);
*timer =
0;
}
}
void SetToggleButtonState(WindowInfo *window, Widget w, Boolean state,
Boolean notify)
{
if (IsTopDocument(window)) {
XmToggleButtonSetState(w, state, notify);
}
}
void SetSensitive(WindowInfo *window, Widget w, Boolean sensitive)
{
if (IsTopDocument(window)) {
XtSetSensitive(w, sensitive);
}
}
void CleanUpTabBarExposeQueue(WindowInfo *window)
{
XEvent event;
XExposeEvent ev;
int count;
if (window ==
NULL)
return;
count=
0;
while (XCheckTypedWindowEvent(TheDisplay, XtWindow(window->tabBar),
Expose, &event))
count++;
if (count) {
ev.type = Expose;
ev.display = TheDisplay;
ev.window = XtWindow(window->tabBar);
ev.x =
0;
ev.y =
0;
ev.width = XtWidth(window->tabBar);
ev.height = XtHeight(window->tabBar);
ev.count =
0;
XSendEvent(TheDisplay, XtWindow(window->tabBar), False,
ExposureMask, (XEvent *)&ev);
}
}
void SetEncoding(WindowInfo *window,
const char *encoding)
{
size_t len = strlen(encoding);
if(len >=
MAX_ENCODING_LENGTH) {
fprintf(stderr,
"Error: Encoding string too large\n");
return;
}
if(encoding == window->encoding) {
return;
}
memcpy(window->encoding, encoding, len);
window->encoding[len] =
'\0';
}
void SetFilter(WindowInfo *window,
const char *filter)
{
if(window->filter == filter) {
return;
}
NEditFree(window->filter);
window->filter = NEditStrdup(filter);
}
#define MIN_FONT_SIZE 2
#define MAX_FONT_SIZE 800
void SetZoom(WindowInfo *window,
int step)
{
int font_sz = window->font->size + step;
int italic_sz = window->italicFont->size + step;
int bold_sz = window->boldFont->size + step;
int bolditalic_sz = window->italicFont->size + step;
if(
font_sz <
MIN_FONT_SIZE || italic_sz <
MIN_FONT_SIZE ||
bold_sz <
MIN_FONT_SIZE || bolditalic_sz <
MIN_FONT_SIZE ||
font_sz >
MAX_FONT_SIZE || italic_sz >
MAX_FONT_SIZE ||
bold_sz >
MAX_FONT_SIZE || bolditalic_sz >
MAX_FONT_SIZE)
{
return;
}
window->zoom += step;
char *font = ChangeFontSize(window->fontName, font_sz);
char *italic = ChangeFontSize(window->italicFontName, italic_sz);
char *bold = ChangeFontSize(window->boldFontName, italic_sz);
char *bolditalic = ChangeFontSize(window->boldItalicFontName, italic_sz);
Boolean rz = window->resizeOnFontChange;
window->resizeOnFontChange = False;
SetFonts(window, font, italic, bold, bolditalic);
window->resizeOnFontChange = rz;
XtSetSensitive(window->resetZoomItem, window->zoom ==
0 ? False : True);
NEditFree(font);
NEditFree(italic);
NEditFree(bold);
NEditFree(bolditalic);
}
void SetEncErrors(WindowInfo *window, EncError *errors,
size_t numErrors)
{
window->encErrors = errors;
window->numEncErrors = numErrors;
if(numErrors ==
0) {
XtVaSetValues(window->encInfoErrorList, XmNitemCount,
0, XmNitems,
NULL,
NULL);
XtUnmanageChild(window->encInfoErrorList);
return;
}
char buf[
256];
XmStringTable strErrors = NEditCalloc(numErrors,
sizeof(XmString));
for(
size_t i=
0;i<numErrors;i++) {
snprintf(buf,
256,
"0x%02X", errors[i].c);
strErrors[i] = XmStringCreateSimple(buf);
}
XtVaSetValues(
window->encInfoErrorList,
XmNitemCount, numErrors,
XmNitems, strErrors,
NULL);
for(
size_t i=
0;i<numErrors;i++) {
XmStringFree(strErrors[i]);
}
NEditFree(strErrors);
XtManageChild(window->encInfoErrorList);
}
static void WindowTakeFocus(Widget shell, WindowInfo *window, XtPointer d)
{
window->opened = True;
XmRemoveWMProtocolCallback(
shell,
wm_take_focus,
(XtCallbackProc)WindowTakeFocus,
window);
}
static void closeInfoBarCB(Widget w, Widget mainWin,
void *callData)
{
WindowInfo *window = GetTopDocument(mainWin);
if(!window) {
return;
}
window->showInfoBar =
FALSE;
XtUnmanageChild(window->encodingInfoBar);
showStatsForm(window);
}
static void jumpToEncErrorCB(Widget w, Widget mainWin, XmComboBoxCallbackStruct *cb)
{
WindowInfo *window = GetTopDocument(mainWin);
if(!window) {
return;
}
if(cb->item_position >= window->numEncErrors) {
return;
}
EncError e = window->encErrors[cb->item_position];
BufSelect(window->buffer, e.pos, e.pos+
3);
MakeSelectionVisible(window, window->lastFocus);
TextSetCursorPos(window->lastFocus, e.pos);
}
static void reloadCB(Widget w, Widget mainWin,
void *callData)
{
WindowInfo *window = GetTopDocument(mainWin);
if(!window) {
return;
}
if(window->fileChanged) {
int b = DialogF(
DF_QUES, window->shell,
2,
"Discard Changes",
"Discard changes to\n%s%s?",
"OK",
"Cancel", window->path,
window->filename);
if(b ==
2) {
return;
}
}
char *encoding =
NULL;
XmString item;
XtVaGetValues(window->encInfoBarList, XmNselectedItem, &item,
NULL);
if(!item) {
return;
}
XmStringGetLtoR(item, XmFONTLIST_DEFAULT_TAG, &encoding);
char *enc = strcmp(encoding,
"detect") ? encoding :
NULL;
RevertToSaved(window, enc);
XmStringFree(item);
XtFree(encoding);
}
static void updateWindowMapStatus(Widget widget, Boolean status) {
for (WindowInfo *w=WindowList; w!=
NULL; w=w->next) {
if(w->shell == widget) {
w->mapped = status;
}
}
}
static void windowStructureNotifyEventEH(
Widget widget,
XtPointer data,
XEvent *event,
Boolean *dispatch)
{
if(event->type == UnmapNotify) {
updateWindowMapStatus(widget, False);
InvalidateWindowMenus();
}
else if(event->type == MapNotify) {
updateWindowMapStatus(widget, True);
InvalidateWindowMenus();
}
}
typedef struct CPDummyWindow {
Widget shell;
Widget mainWin;
Widget form;
Widget menubar;
Widget button;
Widget togglebutton;
Widget label;
Widget textfield1;
Widget textfield2;
Widget textfield3;
Widget scrollbar;
Widget folder;
Widget dropdown;
} CPDummyWindow;
static void clearCompositeWidget(Widget w)
{
WidgetList children;
Cardinal numChildren;
XtVaGetValues(w, XmNchildren, &children, XmNnumChildren, &numChildren,
NULL);
for(
int i=
0;i<numChildren;i++) {
XtUnmanageChild(children[i]);
XtDestroyWidget(children[i]);
}
}
static void UpdateWidgetValues(Widget dst, Widget src)
{
if(dst->core.widget_class == textWidgetClass) {
return;
}
Pixel background, foreground, topShadowColor, bottomShadowColor, highlightColor, armColor;
Pixel selectBG, selectFG, troughColor, blankBackground, inactiveBackground, inactiveForeground;
Dimension shadowThickness, highlightThickness;
XtVaGetValues(src,
XmNbackground, &background,
XmNforeground, &foreground,
XmNtopShadowColor, &topShadowColor,
XmNbottomShadowColor, &bottomShadowColor,
XmNhighlightColor, &highlightColor,
XmNarmColor, &armColor,
XmNshadowThickness, &shadowThickness,
XmNhighlightThickness, &highlightThickness,
XmNselectBackground, &selectBG,
XmNselectForeground, &selectFG,
XmNtroughColor, &troughColor,
XmNblankBackground, &blankBackground,
XmNinactiveBackground, &inactiveBackground,
XmNinactiveForeground, &inactiveForeground,
NULL);
XtVaSetValues(dst,
XmNbackground, background,
XmNforeground, foreground,
XmNtopShadowColor, topShadowColor,
XmNbottomShadowColor, bottomShadowColor,
XmNhighlightColor, highlightColor,
XmNarmColor, armColor,
XmNshadowThickness, shadowThickness,
XmNhighlightThickness, highlightThickness,
XmNselectBackground, selectBG,
XmNselectForeground, selectFG,
XmNtroughColor, troughColor,
XmNblankBackground, blankBackground,
XmNinactiveBackground, inactiveBackground,
XmNinactiveForeground, inactiveForeground,
NULL);
}
static void UpdateWidgetsHierarchy(Widget parent, Widget src, CPDummyWindow *template)
{
UpdateWidgetValues(parent, src);
Widget srcWidgets[] = {
template->label, template->button, template->togglebutton,
template->textfield1, template->textfield2, template->textfield3,
template->scrollbar, template->folder, template->dropdown };
size_t numSrcWidgets =
9;
WidgetList children =
NULL;
Cardinal numChildren =
0;
XtVaGetValues(parent, XmNchildren, &children, XmNnumChildren, &numChildren,
NULL);
for(
int i=
0;i<numChildren;i++) {
Widget dst = children[i];
Widget src = template->togglebutton;
for(
int s=
0;s<numSrcWidgets;s++) {
if(children[i]->core.widget_class == srcWidgets[s]->core.widget_class) {
src = srcWidgets[s];
break;
}
}
UpdateWidgetsHierarchy(dst, src, template);
}
}
static void RecreateTextareaScrollbar(Widget textArea)
{
Widget textAreaFrame = XtParent(textArea);
Widget textAreaScrolledWindow = XtParent(textAreaFrame);
Widget oldHscrollbar =
NULL;
Widget oldVscrollbar =
NULL;
XtVaGetValues(textAreaScrolledWindow, XmNhorizontalScrollBar, &oldHscrollbar, XmNverticalScrollBar, &oldVscrollbar,
NULL);
if(!oldHscrollbar || !oldVscrollbar) {
fprintf(stderr,
"Error: cannot update scrollbars\n");
return;
}
int hincrement, hmin, hmax, hpageIncrement, hsliderSize;
int vincrement, vmin, vmax, vpageIncrement, vsliderSize;
XtVaGetValues(oldHscrollbar, XmNincrement, &hincrement, XmNminimum, &hmin, XmNmaximum, &hmax, XmNpageIncrement, &hpageIncrement, XmNsliderSize, &hsliderSize,
NULL);
XtVaGetValues(oldVscrollbar, XmNincrement, &vincrement, XmNminimum, &vmin, XmNmaximum, &vmax, XmNpageIncrement, &vpageIncrement, XmNsliderSize, &vsliderSize,
NULL);
int hIsManaged = XtIsManaged(oldHscrollbar);
int vIsManaged = XtIsManaged(oldVscrollbar);
XtUnmanageChild(oldHscrollbar);
XtUnmanageChild(oldVscrollbar);
Widget newHscrollbar = XtVaCreateManagedWidget(
"textHorScrollBar",
xmScrollBarWidgetClass, textAreaScrolledWindow, XmNorientation, XmHORIZONTAL,
XmNrepeatDelay,
10,
NULL);
Widget newVscrollbar = XtVaCreateManagedWidget(
"textVertScrollBar",
xmScrollBarWidgetClass, textAreaScrolledWindow, XmNorientation, XmVERTICAL,
XmNrepeatDelay,
10,
NULL);
XtVaSetValues(newHscrollbar, XmNincrement, hincrement, XmNminimum, hmin, XmNmaximum, hmax, XmNpageIncrement, hpageIncrement, XmNsliderSize, hsliderSize,
NULL);
XtVaSetValues(newVscrollbar, XmNincrement, vincrement, XmNminimum, vmin, XmNmaximum, vmax, XmNpageIncrement, vpageIncrement, XmNsliderSize, vsliderSize,
NULL);
XtVaSetValues(textAreaScrolledWindow, XmNhorizontalScrollBar,
newHscrollbar, XmNverticalScrollBar, newVscrollbar,
NULL);
XtVaSetValues(textArea, textNhScrollBar, newHscrollbar, textNvScrollBar, newVscrollbar,
NULL);
if(!hIsManaged) {
XtUnmanageChild(newHscrollbar);
}
if(!vIsManaged) {
XtUnmanageChild(newVscrollbar);
}
}
void ReloadWindowResources(WindowInfo *window, Boolean updateMenuBar)
{
CPDummyWindow dw;
dw.shell = CreateWidget(TheAppShell,
"textShell", topLevelShellWidgetClass,
NULL,
0);
dw.mainWin = XmCreateMainWindow(dw.shell,
"main",
NULL,
0);
dw.menubar = XmCreateMenuBar(dw.mainWin,
"menuBar",
NULL,
0);
dw.form = XmCreateForm(dw.mainWin,
"form",
NULL,
0);
dw.button = XmCreatePushButton(dw.form,
"button",
NULL,
0);
dw.togglebutton = XmCreateToggleButton(dw.form,
"togglebutton",
NULL,
0);
dw.label = XmCreateLabel(dw.form,
"label",
NULL,
0);
dw.textfield1 = XmCreateTextField(dw.form,
"textfield1",
NULL,
0);
dw.textfield2 = XmCreateText(dw.form,
"textfield2",
NULL,
0);
dw.textfield3 = XNECreateTextField(dw.form,
"textfield3",
NULL,
0);
dw.scrollbar = XmCreateScrollBar(dw.form,
"scrollbar",
NULL,
0);
dw.folder = XtVaCreateManagedWidget(
"tabBar", xmlFolderWidgetClass, dw.form,
NULL);
dw.dropdown = XtVaCreateManagedWidget(
"dropDown", xmComboBoxWidgetClass, dw.form,
NULL);
if(updateMenuBar) {
UpdateWidgetValues(window->menuBar, dw.menubar);
RecreateMenuBar(window->mainWin, window->menuBar, window, True);
refreshMenuBar(window);
}
UpdateWidgetValues(window->mainWin, dw.mainWin);
Widget winForm = XtParent(window->iSearchForm);
UpdateWidgetValues(winForm, dw.form);
UpdateWidgetsHierarchy(window->encodingInfoBar, dw.form, &dw);
UpdateWidgetsHierarchy(window->iSearchForm, dw.form, &dw);
clearCompositeWidget(window->iSearchForm);
createSearchForm(window);
Widget tabbar = window->tabBar;
Widget tabform = XtParent(tabbar);
UpdateWidgetValues(tabform, dw.form);
UpdateWidgetsHierarchy(window->statsLineForm, dw.form, &dw);
UpdateWidgetsHierarchy(window->tabBar, dw.folder, &dw);
UpdateWidgetsHierarchy(window->splitPane, dw.form, &dw);
XtDestroyWidget(dw.shell);
}