📄 view.c
字号:
view_expand_item(view, view->ciSelect);
/* find the nearest row in the new view */
ViewEnter();
row = view_findrow(view, number, bRight);
ViewLeave();
/* scroll this row to top of window */
if (row >= 0) {
SendMessage(view->hwnd, TM_TOPROW, TRUE, row);
}
}
/***************************************************************************
* Function: view_findchange
*
* Purpose:
*
* Find the next changed - ie non-same - row in a given direction.
* For outline mode we find the next STATE_DIFFER. For expand mode, we
* find the next section
*/
long
view_findchange(VIEW view, long startrow, BOOL bForward)
{
long i;
if (view == NULL) {
return(0);
}
ViewEnter();
if (bForward) {
if (startrow >= view->rows) {
ViewLeave();
return(-1);
}
if (!view->bExpand) {
/* look for next compitem with an expandable state*/
for (i = startrow; i < view->rows; i++) {
if (compitem_getstate(view->pItems[i]) == STATE_DIFFER) {
ViewLeave();
return(i);
}
}
/* none found */
ViewLeave();
return(-1);
} else {
/*
* find the next line that matches, then go on to the
* next line that does not match
*
*/
for (i= startrow; i < view->rows; i++) {
if (section_getstate(view->pLines[i].section)
== STATE_SAME) {
break;
}
}
for ( ; i < view->rows; i++) {
if (section_getstate(view->pLines[i].section)
!= STATE_SAME) {
ViewLeave();
return(i);
}
}
ViewLeave();
return(-1);
}
} else {
/* same search backwards */
if (startrow <= 0) {
ViewLeave();
return(-1);
}
if (view->bExpand) {
/* search backwards for first row that is not
* changed (has state SAME). then carry on for
* the next changed row.
*/
for (i = startrow; i >= 0; i--) {
if (section_getstate(view->pLines[i].section)
== STATE_SAME) {
break;
}
}
for ( ; i >= 0; i--) {
if (section_getstate(view->pLines[i].section)
!= STATE_SAME) {
ViewLeave();
return(i);
}
}
ViewLeave();
return(-1);
} else {
for (i = startrow; i >= 0; i--) {
if(compitem_getstate(view->pItems[i]) == STATE_DIFFER) {
ViewLeave();
return(i);
}
}
ViewLeave();
return(-1);
}
}
}
/***************************************************************************
* Function: view_findrow
*
* Purpose:
*
* Find the new row number for the line numbered 'number'
* or the nearest line if possible. If bRight is true, number is
* a right file number; otherwise it is a left file number.
*
* We must be in expand mode
*/
int
view_findrow(VIEW view, int number, BOOL bRight)
{
int i;
if (!view->bExpand) {
return(0);
}
for (i = 0; i < view->rows; i++) {
if (bRight) {
if (view->pLines[i].nr_right == number) {
/* found the exact number */
return(i);
} else if (view->pLines[i].nr_right > number) {
/* passed our line -stop here */
return(i);
}
} else {
if (view->pLines[i].nr_left == number) {
/* found the exact number */
return(i);
} else if (view->pLines[i].nr_left > number) {
/* passed our line -stop here */
return(i);
}
}
}
return(-1);
}
/***************************************************************************
* Function: view_freemappings
*
* Purpose:
*
* Free memory associated with the expand mode or outline mode mappings
* called whenever we rebuild the mapping, and on deletion
*/
void
view_freemappings(VIEW view)
{
if (view->pLines) {
gmem_free(hHeap, (LPSTR) view->pLines,
view->rows * sizeof(VIEWLINE));
view->pLines = NULL;
} else if (view->pItems) {
/* previous outline mapping array is still there - free it
* before we build a new one
*/
gmem_free(hHeap, (LPSTR) view->pItems,
view->rows * sizeof(COMPLIST));
view->pItems = NULL;
}
}
/***************************************************************************
* Function: view_outline_opt
*
* Purpose:
*
* Build a view outline to map one row to a COMPITEM handle by traversing
* the list of COMPITEMs obtained from our complist.
* Optionally tell the table class to redraw (if bRedraw), and if so,
* scroll the new table to select the row that represents the
* file we were expanding, if possible
*/
void
view_outline_opt(VIEW view, BOOL bRedraw)
{
int prev_row = -1; /* the row nr of the previously-expanded row*/
int i; /* nr of includable items */
LIST li;
COMPITEM ci;
int state;
TableSelection select;
/*
* check that view_setcomplist has already been called. if not,
* nothing to do
*/
if (view->cl == NULL) {
return;
}
ViewEnter();
/* clear the mode flag and free up memory associated with expand mode */
view->bExpand = FALSE;
view_freemappings(view);
/* traverse the list of compitems counting up the number of
* includable items
*/
li = complist_getitems(view->cl);
ci = (COMPITEM) List_First(li);
for (i = 0; ci != NULL; ci = (COMPITEM) List_Next(ci)) {
state = compitem_getstate(ci);
if (((outline_include & INCLUDE_SAME) && (state == STATE_SAME)) ||
((outline_include & INCLUDE_DIFFER) && (state == STATE_DIFFER)) ||
((outline_include & INCLUDE_LEFTONLY) && (state == STATE_FILELEFTONLY)) ||
((outline_include & INCLUDE_RIGHTONLY) && (state == STATE_FILERIGHTONLY))) {
i++;
}
}
/* allocate an array big enough for all of these */
view->pItems = (COMPITEM FAR *) gmem_get(hHeap, i * sizeof(COMPITEM));
view->rows = i;
/* keep track of the column widths */
view->maxtag = 0;
view->maxrest = 0;
/* loop through again filling the array, and at the same time looking
* out for the handle of the previously expanded item
*/
ci = (COMPITEM) List_First(li);
for (i = 0; ci != NULL; ci = (COMPITEM) List_Next(ci)) {
state = compitem_getstate(ci);
if (((outline_include & INCLUDE_SAME) && (state == STATE_SAME)) ||
((outline_include & INCLUDE_DIFFER) && (state == STATE_DIFFER)) ||
((outline_include & INCLUDE_LEFTONLY) && (state == STATE_FILELEFTONLY)) ||
((outline_include & INCLUDE_RIGHTONLY) && (state == STATE_FILERIGHTONLY))) {
view->pItems[i] = ci;
if (ci == view->ciSelect) {
prev_row = i;
}
/* check the column widths in characters */
view->maxtag = max(view->maxtag,
lstrlen(compitem_gettext_tag(ci)));
view->maxrest = max(view->maxrest,
lstrlen(compitem_gettext_result(ci)));
i++;
}
}
ViewLeave();
/* inform table of new layout of table - force refresh */
if (bRedraw) {
SendMessage(view->hwnd, TM_NEWLAYOUT, 0, (DWORD) view);
/* scroll to and highlight the row that represents the file
* we were previously expanding
*/
if (prev_row != -1) {
select.startrow = prev_row;
select.startcell = 0;
select.nrows = 1;
select.ncells = 1;
SendMessage(view->hwnd, TM_SELECT, 0,
(DWORD) (LPSTR) &select);
}
}
}
/***************************************************************************
* Function: view_expand_item
*
* Purpose:
*
* Expand a view - given the handle to the compitem to expand.
*
* Called from view_expand, and also to re-do an expanded view
* after options change in view_changediffoptions and _changeviewoptions
*
* We get the composite section list from the compitem,
* and pick out all the sections that are includable (according
* to the global option expand_mode: we include all sections, or
* just those in one side left or right). Once we know the count of rows,
* allocate the mapping array: in each element of the array we keep
* a handle to the section for that row (to get the state and hence the
* tag text), and a handle to the line within that section (for the line text).
*
* We no longer insist on only expanding text files that differ - if the
* compitem can give us a composite section list, we will map it.
*
* We need to be able to give a line number for a line, in either of
* the original files according to which option is in force. Each section
* can give us its base line number (number of first line in section) in
* each of the two files or 0 if not present, and we track these here.
*
* MUST BE INSIDE CSView BEFORE CALLING HERE.
*/
BOOL
view_expand_item(VIEW view, COMPITEM ci)
{
LIST li;
SECTION sh;
LINE line1, line2;
int i, base_left, base_right, state;
/* remember the compitem we are expanding */
view->ciSelect = ci;
/* get the composite section list */
li = compitem_getcomposite(view->ciSelect);
if (li == NULL) {
ViewLeave();
return FALSE;
}
/* switch modes and free the current mapping
*
* NOTE: must do this AFTER the compitem_getcomposite,
* since that can fail: if it fails it could put up a
* message box, and that could cause a queued paint message
* to be processed, which would cause us to use these mappings
* and gpfault if they had been cleared first.
*/
view->bExpand = TRUE;
view_freemappings(view);
/* loop through totalling the lines in sections
* that we should include
*/
view->rows = 0;
for (sh = (SECTION) List_First(li); sh != NULL;
sh = (SECTION) List_Next(sh)) {
state = section_getstate(sh);
if (expand_mode == IDM_RONLY) {
if ((state == STATE_LEFTONLY) ||
(state == STATE_MOVEDLEFT)) {
continue;
}
} else if (expand_mode == IDM_LONLY) {
if ((state == STATE_RIGHTONLY) ||
(state == STATE_MOVEDRIGHT)) {
continue;
}
}
/* include all lines in this section */
view->rows += section_getlinecount(sh);
}
/* allocate the memory for the mapping array */
view->pLines = (PVIEWLINE) gmem_get(hHeap, view->rows * sizeof(VIEWLINE));
/* loop through the sections again filling in the mapping array */
i = 0;
view->maxtag = 5;
view->maxrest = 0;
for (sh = (SECTION) List_First(li); sh != NULL;
sh = (SECTION) List_Next(sh)) {
state = section_getstate(sh);
if (expand_mode == IDM_RONLY) {
if ((state == STATE_LEFTONLY) ||
(state == STATE_MOVEDLEFT)) {
continue;
}
} else if (expand_mode == IDM_LONLY) {
if ((state == STATE_RIGHTONLY) ||
(state == STATE_MOVEDRIGHT)) {
continue;
}
}
/* find the base line number in each file */
base_left = section_getleftbasenr(sh);
base_right = section_getrightbasenr(sh);
/* add each line in section to the view. section_getfirst()
* returns us to a handle that is in a list. We can
* call List_Next and will eventually get to the
* line returned by section_getlast(). Sections always have
* at least one line
*/
line1 = section_getfirstline(sh);
line2 = section_getlastline(sh);
for (; line1 != NULL; line1 = (LINE) List_Next(line1)) {
view->pLines[i].line = line1;
view->pLines[i].section = sh;
/* calculate the line number for this line by
* incrementing the base nr for this section
*/
view->pLines[i].nr_left = base_left;
if (base_left != 0) {
base_left++;
}
view->pLines[i].nr_right = base_right;
if (base_right != 0) {
base_right++;
}
/* increment index into view */
i++;
/* check the column widths */
view->maxrest = max(view->maxrest,
(line_gettabbedlength(line1, 8)));
/* end of section ? */
if (line1 == line2) {
break;
}
}
}
/* We must NOT hold a critical section here as SendMessage may hang */
ViewLeave();
/*inform table window of revised mapping */
SendMessage(view->hwnd, TM_NEWLAYOUT, 0, (DWORD) view);
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -