1
0
Files
irix-657m-src/eoe/cmd/xdiff/xdUtil.c
2022-09-29 17:59:04 +03:00

1093 lines
31 KiB
C

/****************************************************************************/
/* xdUtil.c */
/****************************************************************************/
/*
* Utility routines called by the callbacks in xdCallbacks.c
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright (c) 1994 Rudy Wortel. All rights reserved.
*/
/*
* $Source: /proj/irix6.5.7m/isms/eoe/cmd/xdiff/RCS/xdUtil.c,v $
* $Revision: 1.4 $
* $Author: ack $
* $Date: 1995/12/30 02:19:49 $
*/
#include <stdio.h>
#include <xdDiff.h>
#include <xdGUI.h>
#include <xdProto.h>
#include <unistd.h>
/****************************************************************************/
XDattribute *xdGetAttributes (
/*
* Determine the attributes for drawing this difference.
*/
ApplicationData *appData, /*< All application Data. */
XDdiff *diff, /*< Which line are we talking about. */
int side /*< Are we drawing the left or the right. */
)
{ /**************************************************************************/
XDattribute *attr;
switch( diff->selection ){
case XD_SELECTNONE:
switch( diff->type ){
case XD_COMMONTEXT:
attr = &appData->attributes[ XD_COMMON ];
break;
case XD_LEFTTEXT:
if( side == XD_LEFT ){
attr = &appData->attributes[ XD_ONLY ];
}else{
attr = &appData->attributes[ XD_ABSENT ];
}
break;
case XD_RIGHTTEXT:
if( side == XD_RIGHT ){
attr = &appData->attributes[ XD_ONLY ];
}else{
attr = &appData->attributes[ XD_ABSENT ];
}
break;
case XD_CHANGEDTEXT:
attr = &appData->attributes[ XD_CHANGED ];
break;
}
break;
case XD_SELECTLEFT:
if( side == XD_LEFT ){
attr = &appData->attributes[ XD_SELECTED ];
}else{
attr = &appData->attributes[ XD_DELETED ];
}
break;
case XD_SELECTRIGHT:
if( side == XD_LEFT ){
attr = &appData->attributes[ XD_DELETED ];
}else{
attr = &appData->attributes[ XD_SELECTED ];
}
break;
case XD_SELECTNEITHER:
attr = &appData->attributes[ XD_DELETED ];
break;
default:
attr = &appData->attributes[ XD_COMMON ];
break;
}
return attr;
}
/****************************************************************************/
void xdDrawView (
/*
* Draw the overview of the differences in the right side of the window.
*/
ApplicationData *appData /*< All application Data. */
)
{ /**************************************************************************/
Display *display;
Window window;
GC gc;
Dimension windowHeight;
Dimension windowWidth;
Pixel fgc;
Pixel bgc;
double lines2screen;
int maxLines;
Dimension leftOffset, rightOffset;
Dimension oneThird, twoThirds;
Dimension leftTop, leftBottom, rightTop, rightBottom;
XDdiff *topDiff, *bottomDiff;
XDlist *diffs;
XDattribute *attr;
XPoint points[ 5 ];
diffs = &appData->diffs;
maxLines = (diffs->rlines > diffs->llines) ? diffs->rlines : diffs->llines;
if( maxLines == 0 ){
return;
}
gc = appData->gc;
display = appData->display;
window = XtWindow( appData->viewArea );
XtVaGetValues( appData->viewArea,
XmNforeground, &fgc,
XmNbackground, &bgc,
XmNheight, &windowHeight,
XmNwidth, &windowWidth,
0 );
lines2screen = (double) windowHeight / (double) maxLines;
leftOffset = (maxLines - diffs->llines) * lines2screen / 2.0;
rightOffset = (maxLines - diffs->rlines) * lines2screen / 2.0;
oneThird = windowWidth / 3;
twoThirds = 2 * oneThird;
XClearWindow( display, window );
topDiff = diffs->first;
while( topDiff != NULL ){
bottomDiff = topDiff;
while( bottomDiff->next != NULL &&
bottomDiff->next->type == topDiff->type ){
bottomDiff = bottomDiff->next;
}
switch( topDiff->type ){
case XD_CHANGEDTEXT:
case XD_COMMONTEXT:
leftTop = leftOffset + (topDiff->lnuml - 1) * lines2screen;
leftBottom = leftOffset + bottomDiff->lnuml * lines2screen;
rightTop = rightOffset + (topDiff->lnumr - 1) * lines2screen;
rightBottom = rightOffset + (bottomDiff->lnumr) * lines2screen;
attr = xdGetAttributes( appData, topDiff, XD_LEFT );
XSetForeground( display, gc, attr->backgroundColour );
XFillRectangle( display, window, gc,
1, leftTop, oneThird - 1, leftBottom - leftTop );
attr = xdGetAttributes( appData, topDiff, XD_RIGHT );
XSetForeground( display, gc, attr->backgroundColour );
XFillRectangle( display, window, gc,
twoThirds + 1, rightTop,
oneThird - 1, rightBottom - rightTop );
break;
case XD_LEFTTEXT:
leftTop = leftOffset + (topDiff->lnuml - 1) * lines2screen;
leftBottom = leftOffset + bottomDiff->lnuml * lines2screen;
rightTop = rightOffset + topDiff->lnumr * lines2screen;
rightBottom = rightBottom;
attr = xdGetAttributes( appData, topDiff, XD_LEFT );
XSetForeground( display, gc, attr->backgroundColour );
XFillRectangle( display, window, gc,
1, leftTop, oneThird - 1, leftBottom - leftTop );
break;
case XD_RIGHTTEXT:
leftTop = leftOffset + topDiff->lnuml * lines2screen;
leftBottom = leftTop;
rightTop = rightOffset + (topDiff->lnumr - 1) * lines2screen;
rightBottom = rightOffset + (bottomDiff->lnumr) * lines2screen;
attr = xdGetAttributes( appData, topDiff, XD_RIGHT );
XSetForeground( display, gc, attr->backgroundColour );
XFillRectangle( display, window, gc,
twoThirds + 1, rightTop,
oneThird - 1, rightBottom - rightTop );
break;
}
/*
* Draw trim at the top of the ranges. The next range will do the
* bottom
*/
XSetForeground( display, gc, fgc );
XDrawLine( display, window, gc,
1, leftTop, oneThird, leftTop );
XDrawLine( display, window, gc,
oneThird, leftTop, twoThirds, rightTop );
XDrawLine( display, window, gc,
twoThirds, rightTop, windowWidth, rightTop );
topDiff = bottomDiff->next;
}
/* We need to draw the last bottom trim */
XDrawLine( display, window, gc,
oneThird, windowHeight - leftOffset,
twoThirds, windowHeight - rightOffset );
/* draw the trim rectangles on both sides */
XSetForeground( display, gc, fgc );
XDrawRectangle( display, window, gc,
0, leftOffset, oneThird, windowHeight - (2 * leftOffset) - 1 );
XDrawRectangle( display, window, gc,
twoThirds, rightOffset,
oneThird - 1, windowHeight - (2 * rightOffset) - 1 );
XSetForeground( display, gc, appData->matchColour );
/* draw all the marked lines on top */
topDiff = diffs->first;
while( topDiff != NULL ){
if( topDiff->flags & XD_MATCHED_LEFT ){
leftTop = leftOffset + (topDiff->lnuml - 1) * lines2screen;
points[ 0 ].x = oneThird;
points[ 0 ].y = leftTop;
points[ 1 ].x = oneThird - 4;
points[ 1 ].y = leftTop + 4;
points[ 2 ].x = oneThird - 8;
points[ 2 ].y = leftTop;
points[ 3 ].x = oneThird - 4;
points[ 3 ].y = leftTop - 4;
points[ 4 ].x = oneThird;
points[ 4 ].y = leftTop;
XFillPolygon( display, window, gc,
points, 5, Convex, CoordModeOrigin );
}
if( topDiff->flags & XD_MATCHED_RIGHT ){
rightTop = rightOffset + (topDiff->lnumr - 1) * lines2screen;
points[ 0 ].x = twoThirds;
points[ 0 ].y = rightTop;
points[ 1 ].x = twoThirds + 4;
points[ 1 ].y = rightTop + 4;
points[ 2 ].x = twoThirds + 8;
points[ 2 ].y = rightTop;
points[ 3 ].x = twoThirds + 4;
points[ 3 ].y = rightTop - 4;
points[ 4 ].x = twoThirds;
points[ 4 ].y = rightTop;
XFillPolygon( display, window, gc,
points, 5, Convex, CoordModeOrigin );
}
topDiff = topDiff->next;
}
/* draw the pointers */
if( diffs->current->type == XD_RIGHTTEXT ){
leftBottom = leftOffset + diffs->current->lnuml * lines2screen;
}else{
leftBottom = leftOffset + (diffs->current->lnuml - 1) * lines2screen;
}
points[ 0 ].x = oneThird;
points[ 0 ].y = leftBottom;
points[ 1 ].x = oneThird - 8;
points[ 1 ].y = leftBottom + 3;
points[ 2 ].x = oneThird - 8;
points[ 2 ].y = leftBottom - 3;
points[ 3 ].x = oneThird;
points[ 3 ].y = leftBottom;
XSetForeground( display, gc, bgc );
XFillPolygon( display, window, gc, points, 3, Convex, CoordModeOrigin );
if( appData->cursorColour != -1 ){
XSetForeground( display, gc, appData->cursorColour );
}else{
XSetForeground( display, gc, fgc );
}
XDrawLines( display, window, gc, points, 4, CoordModeOrigin );
if( diffs->current->type == XD_LEFTTEXT ){
rightBottom = rightOffset + diffs->current->lnumr * lines2screen;
}else{
rightBottom = rightOffset + (diffs->current->lnumr - 1) * lines2screen;
}
points[ 0 ].x = twoThirds;
points[ 0 ].y = rightBottom;
points[ 1 ].x = twoThirds + 8;
points[ 1 ].y = rightBottom + 3;
points[ 2 ].x = twoThirds + 8;
points[ 2 ].y = rightBottom - 3;
points[ 3 ].x = twoThirds;
points[ 3 ].y = rightBottom;
XSetForeground( display, gc, bgc );
XFillPolygon( display, window, gc, points, 3, Convex, CoordModeOrigin );
if( appData->cursorColour != -1 ){
XSetForeground( display, gc, appData->cursorColour );
}else{
XSetForeground( display, gc, fgc );
}
XDrawLines( display, window, gc, points, 4, CoordModeOrigin );
}
/****************************************************************************/
int expandTabs (
/*
* Expand the tabs to spaces.
*/
char *tabed,
char *buf,
int digits,
int width,
int line
)
{ /**************************************************************************/
char *f;
char *t;
char format[ 100 ];
int spaces;
int count = 0;
if( digits != -1 ){
sprintf( format, "%%%dd:", digits );
sprintf( buf, format, line );
t = &buf[ digits + 1 ];
}else{
t = buf;
}
for( f = tabed; f!=NULL && *f != '\0' && count < 10000; ++f ){
if( *f < ' ' ){
/* control charater */
if( *f == '\t' ){
spaces = width - (t - &buf[ digits + 1 ]) % width;
while( spaces-- && count < 10000){
*t++ = ' ';
count++;
}
}else{
*t++ = '^';
*t++ = '@' + *f;
count++;
count++;
}
}else{
*t++ = *f;
count++;
}
}
*t = '\0';
return t - buf;
}
/****************************************************************************/
void xdDrawText (
/*
* Draw the text in the appropriate window.
*/
ApplicationData *appData, /*< All application Data. */
int side /*< Is it the left or right text. */
)
{ /**************************************************************************/
Display *display;
Window window;
Widget drawingArea;
Widget scroll;
GC gc;
char **text;
Dimension windowHeight;
Dimension windowWidth;
Dimension lineHeight;
Pixel fgc;
Pixel bgc;
int line;
int lines;
int i;
int offset;
int len;
char *p;
char str[ 11000 ]; /* For the very long-lined files people seem to try to diff */
XDattribute *attr;
XDdiff *diff;
if( appData->diffs.rlines == 0 && appData->diffs.llines == 0 ){
return;
}
if( side == XD_LEFT ){
drawingArea = appData->leftWindow;
scroll = appData->leftScroll;
}else{
drawingArea = appData->rightWindow;
scroll = appData->rightScroll;
}
window = XtWindow( drawingArea );
display = appData->display;
gc = appData->gc;
XtVaGetValues( drawingArea,
XmNforeground, &fgc,
XmNbackground, &bgc,
XmNheight, &windowHeight,
XmNwidth, &windowWidth,
0 );
line = 1;
XtVaGetValues( appData->vertScroll, XmNvalue, &line, 0 );
offset = 0;
XtVaGetValues( scroll, XmNvalue, &offset, 0 );
offset *= -appData->maxBounds.width;
lineHeight = appData->maxBounds.ascent + appData->maxBounds.descent;
lines = windowHeight / lineHeight;
diff = xdFindDiff( &appData->diffs, line );
for( i = 0; i < lines; ++i ){
if( (line + i - 1) > appData->diffs.lines || diff == NULL ){
break;
}
p = (side == XD_LEFT) ? diff->left : diff->right;
attr = xdGetAttributes( appData, diff, side );
XSetForeground( display, gc, attr->backgroundColour );
XFillRectangle( display, window, gc,
0, (lineHeight * i), windowWidth, lineHeight );
if( diff == appData->diffs.current ){
if( side == XD_LEFT && (diff->flags & XD_MATCHED_LEFT) ){
XSetForeground( display, gc, appData->matchColour );
}else if( side == XD_RIGHT && (diff->flags & XD_MATCHED_RIGHT) ){
XSetForeground( display, gc, appData->matchColour );
}else{
XSetForeground( display, gc, appData->cursorColour );
}
XDrawRectangle( display, window, gc,
0, (lineHeight * i), windowWidth - 1, lineHeight - 1 );
}
if( p != NULL ){
XSetForeground( display, gc, attr->foregroundColour );
len = expandTabs( p, str,
(appData->lineNumbers) ? appData->diffs.digits : -1,
appData->tabWidth,
(side == XD_LEFT) ? diff->lnuml : diff->lnumr );
if( attr->font != NULL ){
XSetFont( display, gc, attr->font->fid );
}
XDrawString( display, window, gc, offset,
(lineHeight * i) + appData->maxBounds.ascent, str, len );
}
diff = diff->next;
}
/* Clear the remaining area if any. */
len = windowHeight - (lineHeight * i);
if( len > 0 ){
XClearArea( display, window,
0, (lineHeight * i) + 1, windowWidth - 1, len, False );
}
}
/****************************************************************************/
Boolean xdFileWritable (
/*
* Determine if we can write to one of the two files.
*/
ApplicationData *appData, /*< All application Data. */
int side /*< Is it the left or right text. */
)
{ /**************************************************************************/
Boolean writable;
char *file;
writable = False;
if( side == XD_LEFT ){
file = appData->diffs.lfile;
}else{
file = appData->diffs.rfile;
}
if( file != NULL && access( file, W_OK ) == 0 ){
writable = True;
}
return writable;
}
/****************************************************************************/
void xdSetMessageLine (
/*
* Change the text in the message line. NULL means clear the text.
*/
ApplicationData *appData, /*< All application Data. */
char *messageName /*< Message name. */
)
{ /**************************************************************************/
XmString message;
char *text;
if( messageName == NULL ){
text = " ";
}else{
text = xdGetDefault( appData->display, appData->appClass, messageName );
if( text == NULL ){
text = messageName;
}
}
message = XmStringCreate( text, XmSTRING_DEFAULT_CHARSET );
if( message != NULL ){
XtVaSetValues( appData->messageLine,
XmNlabelString, message,
0 );
XmStringFree( message );
}
}
/****************************************************************************/
void xdResizeSliders (
/*
* After an event that changes the number of lines or the size of the
* displayed region this will adjust the vertical slider to reflect the
* change.
*/
ApplicationData *appData /*< All application Data. */
)
{ /**************************************************************************/
Dimension windowHeight;
double fract;
int lineHeight;
int value;
int size;
int max;
int min;
XtVaGetValues( appData->leftWindow,
XmNheight, &windowHeight,
0 );
XtVaGetValues( appData->vertScroll,
XmNvalue, &value,
XmNmaximum, &max,
XmNminimum, &min,
0 );
lineHeight = appData->maxBounds.ascent + appData->maxBounds.descent;
fract = (windowHeight / lineHeight) / (double) appData->diffs.lines;
fract = (fract > 1.0) ? 1.0 : fract;
/* deal with those nasty boundary conditions */
size = fract * appData->diffs.lines;
if( size < 1 ){
size = 1;
}
if( value > (appData->diffs.lines - size) ){
value = appData->diffs.lines - size + 1;
}
if( value < min ){
value = min;
}
max = (appData->diffs.lines == 0) ? 2 : appData->diffs.lines + 1,
XtVaSetValues( appData->vertScroll,
XmNmaximum, max,
XmNsliderSize, size,
XmNvalue, value,
0 );
}
/****************************************************************************/
void xdMoveToCurrentLine (
/*
* Update the display to center the current line.
*/
ApplicationData *appData /*< All application Data. */
)
{ /**************************************************************************/
int value;
int size;
value = 1;
XtVaGetValues( appData->vertScroll,
XmNvalue, &value,
XmNsliderSize, &size,
0 );
value = appData->diffs.current->index - size / 2;
if( value < 1 ){
value = 1;
}else if( value > (appData->diffs.lines - size) ){
value = appData->diffs.lines - size + 1;
}
XtVaSetValues( appData->vertScroll,
XmNvalue, value,
0 );
xdDrawText( appData, XD_LEFT );
xdDrawText( appData, XD_RIGHT );
xdDrawView( appData );
xdSetMessageLine( appData, NULL );
}
/****************************************************************************/
void xdFindLine (
/*
* Move the pointer to the desired line number.
*/
ApplicationData *appData, /*< All application Data. */
int line, /*< Desired line. */
int side /*< Is it the left or right text. */
)
{ /**************************************************************************/
XDdiff *diff;
diff = appData->diffs.first;
while( diff != NULL ){
if( side == XD_LEFT ){
if( diff->lnuml == line ){
break;
}
}else{
if( diff->lnumr == line ){
break;
}
}
diff = diff->next;
}
if( diff != NULL ){
appData->diffs.current = diff;
xdMoveToCurrentLine( appData );
}
}
/****************************************************************************/
void xdFindMatch (
/*
* Move the pointer to the next or previous match.
*/
ApplicationData *appData, /*< All application Data. */
int direction /*< Goto the previous or next diff. */
)
{ /**************************************************************************/
XDdiff *diff;
int value;
int size;
int max;
int min;
int line;
value = 1;
XtVaGetValues( appData->vertScroll,
XmNvalue, &value,
XmNsliderSize, &size,
0 );
if( appData->diffs.current->index >= value &&
appData->diffs.current->index < (value + size) ){
diff = appData->diffs.current;
}else{
diff = xdFindDiff( &appData->diffs, value + size / 2 );
}
if( diff != NULL ){
diff = (direction == XD_PREV) ? diff->prev : diff->next;
while( diff != NULL && (diff->flags & XD_MATCHED_MASK) == 0 ){
diff = (direction == XD_PREV) ? diff->prev : diff->next;
}
}
if( diff == NULL ){
if( direction == XD_PREV ){
appData->diffs.current = appData->diffs.first;
}else{
appData->diffs.current = appData->diffs.last;
}
}else{
appData->diffs.current = diff;
}
xdMoveToCurrentLine( appData );
}
/****************************************************************************/
void xdFindDifference (
/*
* Move the pointer to the next or previous difference.
*/
ApplicationData *appData, /*< All application Data. */
Boolean unselected, /*< Look for unselected regions. */
int direction /*< Goto the previous or next diff. */
)
{ /**************************************************************************/
XDdiff *diff;
int value;
int size;
int max;
int min;
int line;
value = 1;
XtVaGetValues( appData->vertScroll,
XmNvalue, &value,
XmNsliderSize, &size,
0 );
if( appData->diffs.current->index >= value &&
appData->diffs.current->index < (value + size) ){
diff = appData->diffs.current;
}else{
diff = xdFindDiff( &appData->diffs, value + size / 2 );
}
if( diff != NULL ){
if( diff->type != XD_COMMONTEXT ){
while( diff != NULL && diff->type == appData->diffs.current->type ){
diff = (direction == XD_PREV) ? diff->prev : diff->next;
}
}
while( diff != NULL ){
if( diff->type != XD_COMMONTEXT ){
if( unselected == True ){
if( diff->selection == XD_SELECTNONE ){
break;
}
}else{
break;
}
}
diff = (direction == XD_PREV) ? diff->prev : diff->next;
}
}
if( diff == NULL ){
if( direction == XD_PREV ){
appData->diffs.current = appData->diffs.first;
}else{
appData->diffs.current = appData->diffs.last;
}
}else{
appData->diffs.current = diff;
}
xdMoveToCurrentLine( appData );
}
/****************************************************************************/
void xdSelectGlobal (
/*
* Make the given selection to all differences in the list.
*/
ApplicationData *appData, /*< All application Data. */
int selection /*< Select the right, left or neither. */
)
{ /**************************************************************************/
XDdiff *diff;
for( diff = appData->diffs.first; diff != NULL; diff = diff->next ){
if( diff->type != XD_COMMONTEXT ){
diff->selection = selection;
}
}
xdDrawText( appData, XD_LEFT );
xdDrawText( appData, XD_RIGHT );
xdDrawView( appData );
xdSetMessageLine( appData, NULL );
}
/****************************************************************************/
void xdSelectRegion (
/*
* Make the given selection to all differences in the region.
*/
ApplicationData *appData, /*< All application Data. */
int selection /*< Select the right, left or neither. */
)
{ /**************************************************************************/
XDdiff *diff;
diff = appData->diffs.current;
if( diff != NULL && diff->type != XD_COMMONTEXT ){
do{
diff->selection = selection;
diff = diff->prev;
}while( diff != NULL && diff->type == appData->diffs.current->type );
diff = appData->diffs.current;
do{
diff->selection = selection;
diff = diff->next;
}while( diff != NULL && diff->type == appData->diffs.current->type );
}
xdDrawText( appData, XD_LEFT );
xdDrawText( appData, XD_RIGHT );
xdDrawView( appData );
xdSetMessageLine( appData, NULL );
}
/****************************************************************************/
void xdSelectLine (
/*
* Make the given selection for the current line.
*/
ApplicationData *appData, /*< All application Data. */
int selection /*< Select the right, left or neither. */
)
{ /**************************************************************************/
XDdiff *diff;
diff = appData->diffs.current;
if( diff != NULL && diff->type != XD_COMMONTEXT ){
diff->selection = selection;
}
xdDrawText( appData, XD_LEFT );
xdDrawText( appData, XD_RIGHT );
xdDrawView( appData );
xdSetMessageLine( appData, NULL );
}
/****************************************************************************/
int xdSetCurrentDifference (
/*
* Return the line number of the difference at the y coordinate given.
*/
ApplicationData *appData, /*< All application Data. */
int eventY /*< Y cordinate of a button event. */
)
{ /**************************************************************************/
XDdiff *diff;
int topLine;
int line;
int lineHeight;
topLine = 1;
XtVaGetValues( appData->vertScroll, XmNvalue, &topLine, 0 );
lineHeight = appData->maxBounds.ascent + appData->maxBounds.descent;
line = topLine + (eventY / lineHeight);
if( line <= appData->diffs.lines ){
diff = xdFindDiff( &appData->diffs, line );
appData->diffs.current = diff;
}else{
line = -1;
}
return line;
}
/****************************************************************************/
Boolean xdCheckAllSelected (
/*
* If any difference does not have a selection then a message shown on the
* message line. Return whether or not all differences have a selection.
*/
ApplicationData *appData
)
{ /**************************************************************************/
int allSelected;
XDdiff *unselected;
unselected = xdAnyUnselected( &appData->diffs );
if( unselected == NULL ){
allSelected = True;
}else{
appData->diffs.current = unselected;
xdMoveToCurrentLine( appData );
XBell(appData->display, 100);
xdSetMessageLine( appData, xdGetDefault( appData->display,
appData->appClass, "msgNoSelection" ) );
allSelected = False;
}
return allSelected;
}
/****************************************************************************/
int xdSaveFile (
/*
* Write the differences to the specified file.
*/
ApplicationData *appData, /*< All application data. */
char *fileName, /*< Write to this file. */
int side /*< Which side to take for common text. */
)
{ /**************************************************************************/
int status;
char text[ 1000 ];
char *format;
status = xdWriteFile( fileName, &appData->diffs, side );
if( status == EOF ){
format = xdGetDefault(
appData->display, appData->appClass, "msgWriteFailed" );
}else{
format = xdGetDefault(
appData->display, appData->appClass, "msgWriteSucceeded" );
}
sprintf( text, format, (fileName == NULL) ? "<stdout>" : fileName );
xdSetMessageLine( appData, text );
return status;
}
/****************************************************************************/
Boolean xdSetCursorOnScreen (
/*
* If the cursor line is not within the range of the view then move it
* so that it is. Return True if the cursor was moved.
*/
ApplicationData *appData /*< All application data. */
)
{ /**************************************************************************/
XDdiff *diff;
Boolean movedCursor;
int index;
int topLine;
int size;
movedCursor = False;
if( appData->diffs.current != NULL ){
XtVaGetValues( appData->vertScroll,
XmNvalue, &topLine,
XmNsliderSize, &size,
0 );
index = appData->diffs.current->index;
diff = NULL;
if( index < topLine ){
diff = xdFindDiff( &appData->diffs, topLine );
movedCursor = True;
}else if( index >= topLine + size ){
diff = xdFindDiff( &appData->diffs, topLine + size - 1 );
movedCursor = True;
}
if( diff != NULL ){
appData->diffs.current = diff;
}
}
return movedCursor;
}
/****************************************************************************/
void xdMoveCursor (
/*
* Move the cursor by the specified number of lines. Stop if you get
* to the end.
*/
ApplicationData *appData, /*< All application data. */
int lines /*< How many line to move. */
)
{ /**************************************************************************/
XDdiff *diff;
if( appData->diffs.current != NULL ){
diff = appData->diffs.current;
while( lines != 0 ){
if( lines > 0 ){
--lines;
if( diff->next != NULL ){
diff = diff->next;
}
}else{
++lines;
if( diff->prev != NULL ){
diff = diff->prev;
}
}
}
appData->diffs.current = diff;
xdMoveToCurrentLine( appData );
xdDrawView( appData );
xdDrawText( appData, XD_LEFT );
xdDrawText( appData, XD_RIGHT );
xdSetMessageLine( appData, NULL );
}
}