home *** CD-ROM | disk | FTP | other *** search
/ Languages Around the World / LanguageWorld.iso / language / japanese / win_prog / win_jwp / select.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-31  |  13.8 KB  |  451 lines

  1. /* Copyright (C) Stephen Chung, 1991-1993.  All rights reserved. */
  2.  
  3. #include "jwp.h"
  4.  
  5.  
  6. static BOOL HasSelection, AtStart;
  7. static POINT OldPoint, LeftPoint, RightPoint;
  8. static POSITION OldPos, LeftPos, RightPos;
  9. static int LastDirection;
  10.  
  11.  
  12.  
  13. #define GETPOS(x) (&UNITOF(x,POSOF(x)) - PARAOF(x)->text)
  14. #define SWAPALL() { \
  15.                     POSITION TempPos; \
  16.                     POINT TempPoint; \
  17.                     TempPos = LeftPos; LeftPos = RightPos; RightPos = TempPos; \
  18.                     TempPoint = LeftPoint; LeftPoint = RightPoint; RightPoint = TempPoint; \
  19.                   }
  20.  
  21.  
  22. static void MoveLeftRight (POSITION *oldpos, int Direction, BOOL abs)
  23. {
  24.     POSITION p = *oldpos;
  25.     int len;
  26.  
  27.     if (abs) {
  28.         if (Direction > 0) {
  29.             len = unitlen(PARAOF(p)->text);
  30.             if (POSOF(p) < len) {
  31.                 POSOF(p)++;
  32.             } else if (PARAOF(p)->next != NULL) {
  33.                 PARAOF(p) = PARAOF(p)->next;
  34.                 POSOF(p) = 0;
  35.             }
  36.         } else {
  37.             if (POSOF(p) > 0) {
  38.                 POSOF(p)--;
  39.             } else {
  40.                 POSOF(p) = -1;
  41.             }
  42.             /*
  43.             } else if (PARAOF(p)->prev != NULL) {
  44.                 PARAOF(p) = PARAOF(p)->prev;
  45.                 POSOF(p) = unitlen(PARAOF(p)->text);
  46.             }
  47.             */
  48.         }
  49.  
  50.         *oldpos = p;
  51.         return;
  52.     }
  53.  
  54.  
  55.     if (Direction > 0) {
  56.         if (POSOF(p) < LINEOF(p)->length) {
  57.             POSOF(p)++;
  58.         } else if (LINEOF(p)->next != NULL) {
  59.             LINEOF(p) = LINEOF(p)->next;
  60.             POSOF(p) = 0;
  61.         } else if (PARAOF(p)->next != NULL) {
  62.             PARAOF(p) = PARAOF(p)->next;
  63.             LINEOF(p) = PARAOF(p)->lines;
  64.             POSOF(p) = 0;
  65.         }
  66.     } else {
  67.         if (POSOF(p) > 0) {
  68.             POSOF(p)--;
  69.         } else {
  70.             POSOF(p) = -1;
  71.         }
  72.         /*
  73.         } else if (LINEOF(p)->prev != NULL) {
  74.             LINEOF(p) = LINEOF(p)->prev;
  75.             POSOF(p) = (LINEOF(p)->length > 0 ? LINEOF(p)->length - 1 : LINEOF(p)->length);
  76.         } else if (PARAOF(p)->prev != NULL) {
  77.             PARAOF(p) = PARAOF(p)->prev;
  78.             LINEOF(p) = PARAOF(p)->lastline;
  79.             POSOF(p) = (LINEOF(p)->length > 0 ? LINEOF(p)->length - 1 : LINEOF(p)->length);
  80.         }
  81.         */
  82.     }
  83.  
  84.     *oldpos = p;
  85. }
  86.  
  87.  
  88.  
  89. void RecordAnchor (FILEOPTIONS *f, POSITION pos, POINT xypos)
  90. {
  91.     POSITION temppos;
  92.  
  93.     HasSelection = (SELPARA1(f) != NULL && SELPARA2(f) != NULL);
  94.  
  95.     if (HasSelection && SELTYPE(f) != SEL_SELECTION) {
  96.         HasSelection = FALSE;
  97.         TurnOffSelection(f);
  98.         CharInput(f, '\0');
  99.     }
  100.  
  101.     OldPos = pos;
  102.     OldPoint = xypos;
  103.  
  104.     if (!HasSelection) return;
  105.  
  106.     /*
  107.     StartGap = (ISKANJI(SELCHAR1(f).kanji) || SELPOS1(f) <= 0 ||
  108.                     ISKANJI(SELPARA1(f)->text[SELPOS1(f) - 1].kanji));
  109.     */
  110.     AtStart = (&SELCHAR1(f) == &UNITOF(OldPos,POSOF(OldPos)));
  111.  
  112.     temppos = OldPos;
  113.     MoveLeftRight (&temppos, -1, FALSE);
  114.  
  115.     if (!AtStart && &SELCHAR2(f) != &UNITOF(temppos,POSOF(temppos)))
  116.         ErrorMessage(global.hwnd, "RecordAnchor: Bad Cursor Position!");
  117. }
  118.  
  119.  
  120.  
  121. void ChangeAnchor (int dx, int dy)
  122. {
  123.     OldPoint.x += dx;
  124.     OldPoint.y += dy;
  125. }
  126.  
  127.  
  128.  
  129. int RelativePosition (POSITION p1, POSITION p2, BOOL abs)
  130. {
  131.     PARAGRAPH far *p;
  132.     ONELINE far *lp;
  133.  
  134.     if (PARAOF(p1) == PARAOF(p2)) {
  135.         if (abs) return (POSOF(p1) - POSOF(p2));
  136.  
  137.         if (LINEOF(p1) == LINEOF(p2)) {
  138.             return (POSOF(p1) - POSOF(p2));
  139.         } else {
  140.             for (lp = LINEOF(p1); lp != NULL; lp = lp->next) {
  141.                 if (lp == LINEOF(p2)) return (-1);
  142.             }
  143.             return (+1);
  144.         }
  145.     }
  146.  
  147.     for (p = PARAOF(p1); p != NULL; p = p->next) {
  148.         if (p == PARAOF(p2)) return (-1);
  149.     }
  150.  
  151.     return (+1);
  152. }
  153.  
  154.  
  155.  
  156. void DropAnchor (FILEOPTIONS *f, POSITION NewPos, POINT NewPoint, int Direction)
  157. {
  158.     int i;
  159.     POSITION DummyPos1, DummyPos2;
  160.  
  161.  
  162.     if (Direction == 0) {
  163.         Direction = RelativePosition(NewPos, OldPos, FALSE);
  164.         if (Direction == 0) return;
  165.     }
  166.  
  167.     LastDirection = Direction;
  168.  
  169.  
  170.     LeftPos = OldPos;       LeftPoint = OldPoint;
  171.     RightPos = NewPos;      RightPoint = NewPoint;
  172.     SELTYPE(f) = SEL_SELECTION;
  173.     SELNOW(f) = FALSE;
  174.  
  175.  
  176.     /* Now the real headache begins! */
  177.  
  178.     if (!HasSelection) {
  179.         if (Direction < 0) {
  180.             SELPARA1(f) = PARAOF(NewPos);   SELPOS1(f) = GETPOS(NewPos);
  181.             MoveLeftRight(&OldPos, -1, FALSE);
  182.             SELPARA2(f) = PARAOF(OldPos);   SELPOS2(f) = GETPOS(OldPos);
  183.             SWAPALL();
  184.         } else {
  185.             SELPARA1(f) = PARAOF(OldPos);   SELPOS1(f) = GETPOS(OldPos);
  186.             MoveLeftRight(&NewPos, -1, FALSE);
  187.             SELPARA2(f) = PARAOF(NewPos);   SELPOS2(f) = GETPOS(NewPos);
  188.         }
  189.     } else if (AtStart) {
  190.         if (Direction > 0) {
  191.             /* Have we gone over the end? */
  192.  
  193.             PARAOF(DummyPos1) = SELPARA2(f);    POSOF(DummyPos1) = SELPOS2(f);
  194.             PARAOF(DummyPos2) = PARAOF(NewPos); POSOF(DummyPos2) = GETPOS(NewPos);
  195.  
  196.             i = RelativePosition(DummyPos2, DummyPos1, TRUE);
  197.  
  198.             if (i > 0) {
  199.                 if (PARAOF(DummyPos2) == PARAOF(DummyPos1) && POSOF(DummyPos2) == POSOF(DummyPos1) + 1) {
  200.                     /* Cancel selection */
  201.                     FlipHighlight(f);
  202.                     SELPARA1(f) = SELPARA2(f) = NULL;
  203.                     SELPOS1(f) = SELPOS2(f) = 0;
  204.                     return;
  205.                 }
  206.  
  207.                 /* Flipped */
  208.                 MoveLeftRight(&DummyPos1, +1, TRUE);
  209.                 MoveLeftRight(&NewPos, -1, FALSE);
  210.                 SELPARA1(f) = PARAOF(DummyPos1); SELPOS1(f) = POSOF(DummyPos1);
  211.                 SELPARA2(f) = PARAOF(NewPos);   SELPOS2(f) = GETPOS(NewPos);
  212.             } else {
  213.                 SELPARA1(f) = PARAOF(NewPos);   SELPOS1(f) = GETPOS(NewPos);
  214.             }
  215.         } else {
  216.             SELPARA1(f) = PARAOF(NewPos);
  217.             SELPOS1(f) = GETPOS(NewPos);
  218.             SWAPALL();
  219.         }
  220.     } else {
  221.         if (Direction > 0) {
  222.             MoveLeftRight(&NewPos, -1, FALSE);
  223.             SELPARA2(f) = PARAOF(NewPos);
  224.             SELPOS2(f) = GETPOS(NewPos);
  225.         } else {
  226.             /* Have we gone over the end? */
  227.  
  228.             PARAOF(DummyPos1) = SELPARA1(f);    POSOF(DummyPos1) = SELPOS1(f);
  229.             PARAOF(DummyPos2) = PARAOF(NewPos); POSOF(DummyPos2) = GETPOS(NewPos);
  230.  
  231.             i = RelativePosition(DummyPos2, DummyPos1, TRUE);
  232.  
  233.             if (i <= 0) {
  234.                 if (PARAOF(DummyPos2) == PARAOF(DummyPos1) && POSOF(DummyPos2) == POSOF(DummyPos1)) {
  235.                     /* Cancel selection */
  236.                     FlipHighlight(f);
  237.                     SELPARA1(f) = SELPARA2(f) = NULL;
  238.                     SELPOS1(f) = SELPOS2(f) = 0;
  239.                     return;
  240.                 }
  241.  
  242.                 /* Flipped */
  243.                 MoveLeftRight(&DummyPos1, -1, TRUE);
  244.                 SELPARA1(f) = PARAOF(NewPos);   SELPOS1(f) = GETPOS(NewPos);
  245.                 SELPARA2(f) = PARAOF(DummyPos1); SELPOS2(f) = POSOF(DummyPos1);
  246.             } else {
  247.                 MoveLeftRight(&NewPos, -1, FALSE);
  248.                 SELPARA2(f) = PARAOF(NewPos);   SELPOS2(f) = GETPOS(NewPos);
  249.             }
  250.             SWAPALL();
  251.         }
  252.     }
  253. }
  254.  
  255.  
  256.  
  257. void ExtendSelection (HWND hwnd, FILEOPTIONS *f)
  258. {
  259.     int i;
  260.     HDC hdc;
  261.     RECT rect;
  262.     POSITION p;
  263.     BOOL StartGap = FALSE   , EndGap = FALSE;
  264.  
  265.  
  266.     if (SELPARA1(f) == NULL || SELPARA2(f) == NULL) return;
  267.  
  268.  
  269.     HideCaret(hwnd);
  270.     hdc = GetDC(hwnd);
  271.  
  272.  
  273.     if (POSOF(LeftPos) < LINEOF(LeftPos)->length && KANJIPOS(LeftPos)) StartGap = TRUE;
  274.     else if (POSOF(LeftPos) <= 0 || KANJIAT(LeftPos,POSOF(LeftPos)-1)) StartGap = TRUE;
  275.  
  276.     if (POSOF(RightPos) < LINEOF(RightPos)->length && KANJIPOS(RightPos)) EndGap = TRUE;
  277.     else if (POSOF(RightPos) > 0 && KANJIAT(RightPos,POSOF(RightPos)-1)) EndGap = TRUE;
  278.  
  279.     if (POSOF(LeftPos) > 0 && CHAROF(LeftPos,POSOF(LeftPos)-1) == '\t') StartGap = FALSE;
  280.     if (POSOF(RightPos) > 0 && CHAROF(RightPos,POSOF(RightPos)-1) == '\t') EndGap = FALSE;
  281.  
  282.     if (LINEOF(RightPos) == LINEOF(LeftPos)) {
  283.         rect.left = LeftPoint.x - (StartGap ? CHARGAP(f) : 0);
  284.         rect.top = LeftPoint.y - LINEOF(OldPos)->height - LINEGAP(f);
  285.         rect.right = RightPoint.x - (EndGap ? (f->leading - CHARGAP(f)) : 0);
  286.         rect.bottom = RightPoint.y + LINEGAP(f);
  287.  
  288.         PatBlt(hdc, rect.left, rect.top,
  289.                 rect.right - rect.left, rect.bottom - rect.top, DSTINVERT);
  290.     } else {
  291.         p = (LastDirection > 0) ? LeftPos : RightPos;
  292.  
  293.         for (;;) {
  294.             if (LastDirection > 0) {
  295.                 if (LINEOF(RightPos) == LINEOF(p)) break;
  296.  
  297.                 rect.left = LeftPoint.x - (StartGap ? CHARGAP(f) : 0);
  298.                 rect.top = LeftPoint.y - LINEOF(p)->height - LINEGAP(f);
  299.                 rect.right = LINEOF(p)->width - f->startx;
  300.                 rect.bottom = rect.top + LINEOF(p)->height + 2 * LINEGAP(f);
  301.  
  302.                 if (LINEOF(p)->length > 0 && KANJIAT(p,LINEOF(p)->length-1))
  303.                     rect.right -= f->leading - CHARGAP(f);
  304.             } else {
  305.                 if (LINEOF(LeftPos) == LINEOF(p)) break;
  306.  
  307.                 rect.left = LEFTMARGIN(p) * BASEWIDTH(f) - f->startx - CHARGAP(f);
  308.                 rect.top = RightPoint.y - LINEOF(p)->height - LINEGAP(f);
  309.                 rect.right = RightPoint.x - (EndGap ? (f->leading - CHARGAP(f)) : 0);
  310.                 rect.bottom = rect.top + LINEOF(p)->height + 2 * LINEGAP(f);
  311.  
  312.                 if (LINEOF(RightPos) == LINEOF(p) && POSOF(RightPos) <= 0)
  313.                     rect.right = rect.left;
  314.             }
  315.  
  316.             if (rect.top > f->height) break;
  317.  
  318.             if (rect.bottom >= 0) {
  319.                 if (LINEOF(p)->length > 0) {
  320.                     PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, DSTINVERT);
  321.                 }
  322.             }
  323.  
  324.             if (LastDirection > 0) {
  325.                 i = PARAOF(p)->spacing;
  326.                 if (!NEXTLINE(p)) {
  327.                     ErrorMessage(global.hwnd, "Can't find end of block!");
  328.                     break;
  329.                 }
  330.                 StartGap = TRUE;
  331.                 LeftPoint.x = LEFTMARGIN(p) * BASEWIDTH(f) - f->startx;
  332.                 LeftPoint.y += LINEOF(p)->height + i;
  333.             } else {
  334.                 i = LINEOF(p)->height;
  335.                 if (!PREVLINE(p)) {
  336.                     ErrorMessage(global.hwnd, "Can't find beginning of block!");
  337.                     break;
  338.                 }
  339.                 EndGap = FALSE;
  340.                 RightPoint.x = LINEOF(p)->width - f->startx;
  341.                 RightPoint.y -= i + PARAOF(p)->spacing;
  342.  
  343.                 if (LINEOF(p)->length > 0 && KANJIAT(p,LINEOF(p)->length-1))
  344.                     RightPoint.x -= f->leading - CHARGAP(f);
  345.             }
  346.         }
  347.  
  348.         if (LeftPoint.y == RightPoint.y) {
  349.             rect.left = LeftPoint.x - (StartGap ? CHARGAP(f) : 0);
  350.             rect.top = LeftPoint.y - LINEOF(p)->height - LINEGAP(f);
  351.             rect.right = LINEOF(p)->width - f->startx;
  352.             rect.bottom = rect.top + LINEOF(p)->height + 2 * LINEGAP(f);
  353.  
  354.             if (LINEOF(p)->length > 0 && KANJIAT(p,LINEOF(p)->length - 1))
  355.                 rect.right -= f->leading - CHARGAP(f);
  356.  
  357.             if (LastDirection > 0 && LINEOF(RightPos) == LINEOF(p)) {
  358.                 if (POSOF(RightPos) > 0) {
  359.                     rect.right = RightPoint.x - (EndGap ? (f->leading - CHARGAP(f)) : 0);
  360.  
  361.                     PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, DSTINVERT);
  362.                 }
  363.             } else if (LastDirection < 0 && LINEOF(LeftPos) == LINEOF(p)) {
  364.                 if (LINEOF(p)->length > 0) {
  365.                     rect.left = LeftPoint.x - (StartGap ? CHARGAP(f) : 0);
  366.  
  367.                     PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, DSTINVERT);
  368.                 }
  369.             } else {
  370.                 ErrorMessage(global.hwnd, "Can't match end of block line!");
  371.             }
  372.         } else {
  373.             ErrorMessage(global.hwnd, "RightPos mismatch: (%d != %d)", LeftPoint.y, RightPoint.y);
  374.         }
  375.     }
  376.  
  377.     ReleaseDC(hwnd, hdc);
  378.     ShowCaret(hwnd);
  379. }
  380.  
  381.  
  382. BOOL InSelection (FILEOPTIONS *f, POSITION pos)
  383. {
  384.     PARAGRAPH far *p;
  385.     ONELINE far *lp;
  386.     BOOL insel = FALSE;
  387.  
  388.     for (p = f->paragraph; p != NULL; p = p->next) {
  389.         if (p == SELPARA1(f) || p == SELPARA2(f)) {
  390.             for (lp = p->lines; lp != NULL; lp = lp->next) {
  391.                 if (lp == LINEOF(pos)) break;
  392.                 if (p == SELPARA1(f) && lp->position <= SELPOS1(f)) {
  393.                     if (lp->next == NULL) {
  394.                         if (lp->position + lp->length >= SELPOS1(f)) insel = TRUE;
  395.                     } else {
  396.                         if (lp->position + lp->length > SELPOS1(f)) insel = TRUE;
  397.                     }
  398.                 }
  399.                 if (p == SELPARA2(f)) {
  400.                     if (lp->next == NULL) {
  401.                         if (lp->position + lp->length >= SELPOS2(f)) insel = FALSE;
  402.                     } else {
  403.                         if (lp->position + lp->length > SELPOS2(f)) insel = FALSE;
  404.                     }
  405.                     break;
  406.                 }
  407.             }
  408.         }
  409.         if (p == PARAOF(pos)) break;
  410.     }
  411.  
  412.     return (insel);
  413. }
  414.  
  415.  
  416. void AbsoluteToPosition (POSITION abs, POSITION *pos)
  417. {
  418.     int offset;
  419.     POSITION p;
  420.     ONELINE far *lp;
  421.  
  422.     if (POSOF(abs) < 0) {       /* Negative position, use at own risk! */
  423.         *pos = abs;
  424.         LINEOF(*pos) = PARAOF(abs)->lines;
  425.         return;
  426.     }
  427.  
  428.     PARAOF(p) = PARAOF(abs);
  429.     POSOF(p) = 0;
  430.  
  431.     for (lp = PARAOF(p)->lines; ; lp = lp->next) {
  432.         if (lp != NULL) {
  433.             LINEOF(p) = lp;
  434.             offset = POS2ABS(p);
  435.         }
  436.  
  437.         if (lp == NULL || offset > POSOF(abs)) {
  438.             if (lp == NULL) {
  439.                 LINEOF(p) = PARAOF(abs)->lastline;
  440.             } else {
  441.                 LINEOF(p) = LINEOF(p)->prev;
  442.             }
  443.             offset = POS2ABS(p);
  444.             POSOF(p) = POSOF(abs) - offset;
  445.             break;
  446.         }
  447.     }
  448.  
  449.     *pos = p;
  450. }
  451.