📄 view.c
字号:
break;
case 2:
/* main text - line */
pstr = line_gettext(view->pLines[row].line);
break;
}
} else {
/* outline mode */
switch(col) {
case 0:
/* row number - just the line number */
wsprintf((LPTSTR)view->nrtext, "%d", row+1);
pstr = view->nrtext;
break;
case 1:
/* tag */
pstr = compitem_gettext_tag(view->pItems[row]);
break;
case 2:
/* result text */
pstr = compitem_gettext_result(view->pItems[row]);
break;
}
}
ViewLeave();
return(pstr);
}
/***************************************************************************
* Function: view_getlinenr_left
*
* Purpose:
*
* Return the line number that this row had in the original left
* file. 0 if not in expand mode. 0 if this row was not in the left file.
* -(linenr) if this row is a MOVED line, and this is the right file
* copy
*/
int
view_getlinenr_left(VIEW view, long row)
{
int state, line;
if ((view == NULL) || (row >= view->rows) || !view->bExpand) {
return 0;
}
ViewEnter();
state = section_getstate(view->pLines[row].section);
line = view->pLines[row].nr_left;
if (state == STATE_MOVEDRIGHT) {
line = -line;
}
ViewLeave();
return(line);
}
/***************************************************************************
* Function: view_getlinenr_right
*
* Purpose:
*
* Return the line number that this row had in the original right
* file. 0 if not in expand mode. 0 if this row was not in the right file.
* -(linenr) if this row is a MOVED line, and this is the left file
* copy
*/
int
view_getlinenr_right(VIEW view, long row)
{
int state, line;
if ((view == NULL) || (row > view->rows) || !view->bExpand) {
return 0;
}
ViewEnter();
state = section_getstate(view->pLines[row].section);
line = view->pLines[row].nr_right;
if (state == STATE_MOVEDLEFT) {
line = -line;
}
ViewLeave();
return(line);
}
/***************************************************************************
* Function: view_getwidth
*
* Purpose:
*
* Find the maximum width in characters for the given column
*/
int
view_getwidth(VIEW view, int col)
{
if (view == NULL) {
return(0);
}
switch(col) {
case 0:
/* line nr column - always 5 characters wide */
return(5);
case 1:
/* this is a proportional font field, so add on a margin
* for error
*/
return(view->maxtag + (view->maxtag / 20));
case 2:
/* this now includes the tab expansion allowance */
return(view->maxrest);
default:
return(0);
}
}
/***************************************************************************
* Function: view_getrowcount
*
* Purpose:
*
* How many rows are there in this view ?
*/
long
view_getrowcount(VIEW view)
{
if (view == NULL) {
return(0);
}
return(view->rows);
}
/***************************************************************************
* Function: view_getstate
*
* Purpose:
*
* Return the state for the current row. This is used
* to select the text colour for the row
*
* States for sections are obtained from section_getstate (and apply, and
* to all lines in that section. States for compitems are obtained
* from compitem_getstate.
*/
int
view_getstate(VIEW view, long row)
{
int state;
if (view == NULL) {
return(0);
}
ViewEnter();
if (row >= view->rows) {
state = 0;
} else if (view->bExpand) {
/* its a line state that's needed */
state = section_getstate(view->pLines[row].section);
} else {
/* its a compitem state */
state = compitem_getstate(view->pItems[row]);
}
ViewLeave();
return(state);
}
/***************************************************************************
* Function: view_gethandle
*
* Purpose:
*
* Return a handle to the current compitem. In expand mode,
* returns the handle to the compitem we are expanding. In outline
* mode, returns the handle to the compitem for the given row, if valid,
* or NULL otherwise. row is only used if not in expand mode.
*/
COMPITEM
view_getitem(VIEW view, long row)
{
COMPITEM ci;
if (view == NULL) {
return(NULL);
}
ViewEnter();
if (!view->bExpand) {
if ((row >= 0) && (row < view->rows)) {
ci = view->pItems[row];
} else {
ci = NULL;
}
} else {
ci = view->ciSelect;
}
ViewLeave();
return(ci);
}
/***************************************************************************
* Function: view_isexpanded
*
* Purpose:
*
* Return TRUE if the current mapping is expanded mode
*/
BOOL
view_isexpanded(VIEW view)
{
if (view == NULL) {
return(FALSE);
}
return(view->bExpand);
}
/***************************************************************************
* Function: view_getcurrenttag
*
* Purpose:
*
* Return a text string describing the view. This is NULL in outline mode,
* or the tag text for the current compitem in expanded mode
*/
LPSTR
view_getcurrenttag(VIEW view)
{
LPSTR str;
if ((view == NULL) || (!view->bExpand)) {
return(NULL);
} else {
ViewEnter();
str = compitem_gettext_tag(view->ciSelect);
ViewLeave();
return(str);
}
}
/***************************************************************************
* Function: view_newitem
*
* Purpose:
*
* Notify that CompItems have been added to the complist.
*
* Rebuild the view (if in outline mode), and refresh the table. Use
* the table message TM_APPEND if possible (if column widths have not
* change). If we have to do TM_NEWLAYOUT, then ensure we scroll
* back to the right row afterwards.
*
* This causes a Poll() to take place. We return TRUE if an abort is
* pending - in this case, the caller should abandon the scan loop.
*
* Enter the critical section for this function since this can be
* called from the worker thread while the UI thread is using the
* view that we are about to change.
*
* EXCEPT THAT WE DON'T DARE. We cannot ever call SendMessage from the
* worker thread within CSView. If there is conflict, it will hang.
*/
BOOL
view_newitem(VIEW view)
{
int maxtag, maxrest;
long rownr;
if ((view == NULL) || (view->bExpand)) {
/* not in outline mode - nothing to do */
return(Poll());
}
/* save some state about the present mapping */
maxtag = view->maxtag;
maxrest = view->maxrest;
/* re-do the outline mapping, but don't tell the table
* class.
*/
view_outline_opt(view, FALSE);
/* have the column widths changed ? */
if ((maxtag < view->maxtag) || (maxrest < view->maxrest)) {
/* yes - need complete redraw */
/* find the row at the top of the window */
rownr = SendMessage(view->hwnd, TM_TOPROW, FALSE, 0);
/* switch to new mapping */
SendMessage(view->hwnd, TM_NEWLAYOUT, 0, (DWORD) view);
/* return to old row if possible - we know
* that row is still there since we have only added
* rows, and not changed any of the existing mapping
*
* Alas this is no longer true. However the table class
* will defend itself against calls for a bogus top row.
*/
if (rownr >= 0) {
SendMessage(view->hwnd, TM_TOPROW, TRUE, rownr);
}
} else {
/* no - we can just append */
/*
* The mapping may have
* changed since we released the critsec. however we are still
* safe. The table will not allow us to reduce the number of
* rows, so the worst that can happen is that the table will
* think there are too many rows, and the table message handler
* will handle this correctly (return null for the text).
* The only visible effect is therefore that the scrollbar
* position is wrong.
*/
SendMessage(view->hwnd, TM_APPEND, view->rows, (DWORD) view);
}
/* Poll to keep the UI updated on NT. Returns true if abort pending.
*/
return(Poll());
}
/***************************************************************************
* Function: view_changeviewoptions
*
* Purpose:
*
* The view mapping options (eg outline_include, expand_mode) have changed -
* re-do the mapping and then scroll back to the same position in the window
* if possible.
*/
void
view_changeviewoptions(VIEW view)
{
long row;
int state, number;
BOOL bRight;
if (view == NULL) {
return;
}
/* find what row we are currently on. Do this BEFORE we enter CSView */
row = SendMessage(view->hwnd, TM_TOPROW, FALSE, 0);
ViewEnter();
if (!view->bExpand) {
/* outline mode. maintaining current position is
* unimportant
*/
view_outline(view);
ViewLeave();
return;
}
/* expanded mode */
/* save the line number on one side (and remember which side) */
if (row >= view->rows) {
number = -1;
} else {
state = section_getstate(view->pLines[row].section);
if ((state == STATE_MOVEDRIGHT) ||
(state == STATE_RIGHTONLY)) {
bRight = TRUE;
number = view->pLines[row].nr_right;
} else {
bRight = FALSE;
number = view->pLines[row].nr_left;
}
}
/* make the new mapping */
view_expand_item(view, view->ciSelect);
/* find the nearest row in the new view */
if (number >= 0) {
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);
return;
}
}
}
/***************************************************************************
* Function: view_changediffoptions
*
* Purpose:
*
* The compare options have changed - re-do the compare completely
* and make the new mapping. Retain current position in the file.
*/
void
view_changediffoptions(VIEW view)
{
int state, number;
long row;
BOOL bRight;
LIST li;
COMPITEM ci;
if (view == NULL) {
return;
}
/*
* get current row before entering critsec.
*/
row = SendMessage(view->hwnd, TM_TOPROW, FALSE, 0);
ViewEnter();
/* find the current line number so we can go back to it
* (only if we are in expanded mode
*/
if (view->bExpand) {
state = section_getstate(view->pLines[row].section);
if ((state == STATE_MOVEDRIGHT) ||
(state == STATE_RIGHTONLY)) {
bRight = TRUE;
number = view->pLines[row].nr_right;
} else {
bRight = FALSE;
number = view->pLines[row].nr_left;
}
}
/* To force a recompare using the new options, we must
* tell each compitem to discard its current compare result.
* We need to traverse the list of compitems calling this
* for each compare.
*/
li = complist_getitems(view->cl);
for (ci = (COMPITEM) List_First(li); ci != NULL; ci = (COMPITEM) List_Next(ci)) {
compitem_discardsections(ci);
}
/* if we are in outline mode, we have nothing more to do */
if (!view->bExpand) {
ViewLeave();
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -