home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / fed0217s.zip / source / stddlg.cpp < prev    next >
C/C++ Source or Header  |  2000-12-13  |  19KB  |  709 lines

  1. /*
  2. ** Module   :STDDLG.CPP
  3. ** Abstract :Standard dialogs
  4. **
  5. ** Copyright (C) Sergey I. Yevtushenko
  6. **
  7. ** Log: Wed  12/11/1997       Derived from DIALOG.CPP
  8. */
  9.  
  10. #include <string.h>
  11.  
  12. #define INCL_DOS
  13. #define INCL_DOSERRORS
  14. #include <os2.h>
  15.  
  16. #include <stddlg.h>
  17. #include <keynames.h>
  18. #include <version.h>
  19.  
  20. extern EditBoxCollection Editor;
  21.  
  22. //----------------------------------------------------------------------
  23. //
  24. //----------------------------------------------------------------------
  25.  
  26. int AChoice(int r, int c, char **itemlist, char* Hdr)
  27. {
  28.     Dialog dlg(r, c, 1, 1);
  29.     Menu* menu = new Menu(1, 1, itemlist);
  30.     dlg.Ins(menu);
  31.     dlg.rows = menu->rows+2;
  32.     dlg.cols = menu->cols+2;
  33.  
  34.     if(Hdr)
  35.         dlg.Ins(new StaticText(0, 1, 1, dlg.cols - 2, Hdr));
  36.  
  37.     KeyInfo k;
  38.     do
  39.     {
  40.         dlg.draw();
  41.         vio_read_key(&k);
  42.  
  43.         if((k.skey & 0x00FF) == kbEnter || (k.skey & 0x00FF) == kbGrEnter)
  44.             return menu->first_selected();
  45.  
  46.         dlg.do_key(k);
  47.  
  48.         if(menu->selected_by_key())
  49.             return menu->first_selected();
  50.     }
  51.     while(k.skey != (kbEsc | shIsCtrl));
  52.     return -1;
  53. }
  54.  
  55. //----------------------------------------------------------------------
  56. //
  57. //----------------------------------------------------------------------
  58.  
  59. int SearchReplace(int r, int c, char *searchstr, char *replacestr, char* flags)
  60. {
  61.     int _rows = 7;
  62.     int _cols = 68;
  63.  
  64.     if(_rows + r >= Rows)
  65.         _rows = Rows - r - 2;
  66.  
  67.     if(_cols - c >= Cols)
  68.         _cols = Cols - c - 2;
  69.  
  70.     Dialog dlg(r, c, _rows, _cols);
  71.  
  72.     dlg.Ins(new StaticText(1,1,1, 7,"Search  "));
  73.     dlg.Ins(new StaticText(2,1,1, 7,"Replace "));
  74.     dlg.Ins(new StaticText(3,1,1,66,"~R~eplace ~B~ackward ~G~lobal ~I~gnore ~N~o-ask r~E~gexp"));
  75.     EditLine* lsearch  = new EditLine(1,  9, 1, 58);
  76.     EditLine* lreplace = new EditLine(2,  9, 1, 58);
  77.     EditLine* lflags   = new EditLine(3, 52, 1, 15);
  78.  
  79.     lsearch ->set_text(searchstr );
  80.     lreplace->set_text(replacestr);
  81.     lflags  ->set_text(flags     );
  82.  
  83.     dlg.Ins(lsearch );
  84.     dlg.Ins(lreplace);
  85.     dlg.Ins(lflags  );
  86.  
  87.     KeyInfo k;
  88.     do
  89.     {
  90.         dlg.draw();
  91.         vio_read_key(&k);
  92.  
  93.         if(((k.skey & 0x00FF) == kbEnter || (k.skey & 0x00FF) == kbGrEnter) &&
  94.            dlg.in_focus() == lflags)
  95.         {
  96.             lsearch ->get_text(searchstr , 1024);
  97.             lreplace->get_text(replacestr, 1024);
  98.             lflags  ->get_text(flags     ,   32);
  99.             return 0;
  100.         }
  101.         dlg.do_key(k);
  102.     }
  103.     while(k.skey != (kbEsc | shIsCtrl));
  104.     return -1;
  105. }
  106.  
  107. //----------------------------------------------------------------------
  108. //
  109. //----------------------------------------------------------------------
  110.  
  111. static void FillFileList(ListBox* list, char *mask)
  112. {
  113.     HDIR hdirFindHandle     = HDIR_SYSTEM;
  114.     FILEFINDBUF3 FindBuffer = {0};
  115.     ULONG ulResultBufLen    = sizeof(FILEFINDBUF3);
  116.     ULONG ulFindCount       = 1;
  117.     ULONG ulDriveNum        = 0;
  118.     ULONG ulDriveMap        = 1;
  119.     int i;
  120.  
  121.     APIRET rc = NO_ERROR;
  122.  
  123.     list->go_item(0);
  124.     list->RemoveAll();
  125.  
  126. //--------------------------------
  127. // Fill directory list
  128.  
  129.     rc = DosFindFirst((PCH)"*",
  130.                       &hdirFindHandle,
  131.                       MUST_HAVE_DIRECTORY,
  132.                       &FindBuffer,
  133.                       ulResultBufLen,
  134.                       &ulFindCount,
  135.                       FIL_STANDARD);
  136.  
  137.     while(rc == NO_ERROR)
  138.     {
  139.         if(!(  FindBuffer.achName[0]=='.'
  140.           && FindBuffer.achName[1]=='\x00'))
  141.         {
  142.             int pos = list->Count();
  143.             strcpy(cName, "\x10");
  144.             strcat(cName, FindBuffer.achName);
  145.             list->add_at_end(cName);
  146.             list->set_item_key(pos, 1);
  147.         }
  148.         ulFindCount = 1;
  149.  
  150.         rc = DosFindNext(hdirFindHandle,
  151.                          &FindBuffer,
  152.                          ulResultBufLen,
  153.                          &ulFindCount);
  154.  
  155.     }
  156.  
  157.     DosFindClose(hdirFindHandle);
  158.  
  159. //--------------------------------
  160. // Fill filename list
  161.  
  162.     ulFindCount    = 1;
  163.     hdirFindHandle = HDIR_SYSTEM;
  164.  
  165.     rc = DosFindFirst((PCH)mask,
  166.                       &hdirFindHandle,
  167.                       0
  168.                       | FILE_ARCHIVED
  169.                       | FILE_READONLY,
  170.                       &FindBuffer,
  171.                       ulResultBufLen,
  172.                       &ulFindCount,
  173.                       FIL_STANDARD);
  174.     while(rc == NO_ERROR)
  175.     {
  176.         if(!(FindBuffer.attrFile & FILE_DIRECTORY))
  177.         {
  178.             int pos = list->Count();
  179.             strcpy(cName, " ");
  180.             strcat(cName, FindBuffer.achName);
  181.             list->add_at_end(cName);
  182.             list->set_item_key(pos, 0);
  183.         }
  184.  
  185.         ulFindCount = 1;
  186.  
  187.         rc = DosFindNext(hdirFindHandle,
  188.                          &FindBuffer,
  189.                          ulResultBufLen,
  190.                          &ulFindCount);
  191.  
  192.     }
  193.  
  194.     DosFindClose(hdirFindHandle);
  195.  
  196. //--------------------------------
  197. // Fill drives list
  198.  
  199.     rc = DosQueryCurrentDisk(&ulDriveNum, &ulDriveMap);
  200.  
  201.     for(i = 0; i < 26; i++)
  202.     {
  203.         if(ulDriveMap & (1 << i))
  204.         {
  205.             int pos = list->Count();
  206.             cName[0] = '[';
  207.             cName[1] = char('A' + i);
  208.             cName[2] = ']';
  209.             cName[3] = 0;
  210.             list->add_at_end(cName);
  211.             list->set_item_key(pos, 2);
  212.         }
  213.     }
  214. }
  215.  
  216. int FileDialog(int r, int c, char *name, int flags)
  217. {
  218.     int _rows = 20;
  219.     int _cols = 60;
  220.  
  221.     if(_rows + r >= Rows)
  222.         _rows = Rows - r - 2;
  223.  
  224.     if(_cols - c >= Cols)
  225.         _cols = Cols - c - 2;
  226.  
  227.     Dialog dlg(r, c, _rows, _cols);
  228.  
  229.     char *hdr = FileDialogNames[flags & 3];
  230.  
  231.     ListBox *dir_list = new ListBox(4,
  232.                                     1,
  233.                                     dlg.rows - 5,
  234.                                     dlg.cols - 2,
  235.                                     0
  236.                                     //| ListBox::lbMultiSel
  237.                                     | ListBox::lbCanScroll);
  238.  
  239.     EditLine* filename  = new EditLine(2,
  240.                                        1,
  241.                                        1,
  242.                                        dlg.cols - 2);
  243.  
  244.     filename->set_text("*");
  245.  
  246.     StaticText* stTxt1 = new StaticText(filename->row - 1,
  247.                                         filename->col,
  248.                                         1,
  249.                                         filename->cols,
  250.                                         "File Name");
  251.  
  252.     StaticText* stTxt2 = new StaticText(dir_list->row - 1,
  253.                                         dir_list->col,
  254.                                         1,
  255.                                         dir_list->cols,
  256.                                         "Directory list");
  257.  
  258.     StaticText* stTxt3 = new StaticText(0,
  259.                                         (dlg.cols-strlen(hdr)) / 2,
  260.                                         1,
  261.                                         strlen(hdr),
  262.                                         hdr);
  263.     dlg.Ins(stTxt1);
  264.     dlg.Ins(stTxt2);
  265.     dlg.Ins(stTxt3);
  266.     dlg.Ins(filename);
  267.     dlg.Ins(dir_list);
  268.  
  269.     FillFileList(dir_list, filename->line(0)->str);
  270.  
  271.     KeyInfo k;
  272.     do
  273.     {
  274.         dlg.draw();
  275.         vio_read_key(&k);
  276.  
  277.         if((k.skey & 0x00FF) == kbEnter ||
  278.            (k.skey & 0x00FF) == kbGrEnter)
  279.         {
  280.             if(dlg.in_focus() == dir_list)
  281.             {
  282.                 switch(dir_list->get_item_key(dir_list->abs_row()))
  283.                 {
  284.                     case 1:
  285.  
  286.                         //Change directory
  287.                         DosSetCurrentDir((PCH)dir_list->get_item_text(dir_list->abs_row()) + 1);
  288.  
  289.                         //Refill directory list
  290.  
  291.                         filename->set_text("*");
  292.                         FillFileList(dir_list, filename->line(0)->str);
  293.                         continue;
  294.  
  295.                     case 0:
  296.                         {
  297.                             char *s = dir_list->get_item_text(dir_list->abs_row())+1;
  298.                             if(name)
  299.                                 strncpy(name, s, FED_MAXPATH);
  300.                             return 0;
  301.                         }
  302.  
  303.                     case 2:
  304.  
  305.                         //Change current drive
  306.                         {
  307.                             char *dsk_name = (dir_list->get_item_text(dir_list->abs_row()) + 1);
  308.                             DosSetDefaultDisk(*dsk_name - 'A' + 1);
  309.                         }
  310.                         //Refill directory list
  311.                         filename->set_text("*");
  312.                         FillFileList(dir_list, filename->line(0)->str);
  313.                         continue;
  314.                 }
  315.             }
  316.             if(dlg.in_focus() == filename)
  317.             {
  318.                 char *s = filename->line(0)->str;
  319.  
  320.                 while(*s && *s == ' ')
  321.                     s++;
  322.  
  323.                 if(strchr(s, ':'))
  324.                 {
  325.                     //Change current drive
  326.                     {
  327.                         char *dsk_name = s;
  328.                         DosSetDefaultDisk((*dsk_name | 0x20) - 'a' + 1);
  329.                     }
  330.                     //Refill directory list
  331.                     filename->set_text("*");
  332.                     FillFileList(dir_list, filename->line(0)->str);
  333.                     continue;
  334.                 }
  335.  
  336.                 if(strchr(s, '*') || strchr(s, '?'))
  337.                 {
  338.                     //Refresh list
  339.                     FillFileList(dir_list, s);
  340.                 }
  341.                 else
  342.                 {
  343.                     if(name)
  344.                     {
  345.                         strncpy(name, s, FED_MAXPATH);
  346.                         s = name;
  347.                         s += strlen(name);
  348.  
  349.                         while(s > name)
  350.                         {
  351.                             if(*s == ' ')
  352.                             {
  353.                                 *s-- = 0;
  354.                                 continue;
  355.                             }
  356.                             if(!*s)
  357.                             {
  358.                                 s--;
  359.                                 continue;
  360.                             }
  361.                             break;
  362.                         }
  363.                         if(s > name && *name)
  364.                             return 0;
  365.                     }
  366.                     else
  367.                         return 0;
  368.                 }
  369.             }
  370.         }
  371.  
  372.         dlg.do_key(k);
  373.  
  374.         if(dlg.in_focus() == dir_list)
  375.         {
  376.             if(dir_list->get_item_key(dir_list->abs_row()) == 0)
  377.                 filename->set_text(dir_list->get_item_text(dir_list->abs_row())+1);
  378.         }
  379.         if(dlg.in_focus() == filename)
  380.         {
  381.             if(!(k.skey & shIsCtrl) ||
  382.                 k.skey == (kbBksp | shIsCtrl) ||
  383.                 k.skey == (kbDel | shIsCtrl))
  384.             {
  385.                 int candidate = -1;
  386.                 int candidate_len = 0;
  387.                 char *s = filename->line(0)->str;
  388.                 int s_len = strlen(s);
  389.  
  390.                 for(int i = 0; i < dir_list->Count(); i++)
  391.                 {
  392.                     if(dir_list->get_item_key(i) == 2)
  393.                         break; //skip drive names
  394.  
  395.                     char * cstr = dir_list->get_item_text(i)+1;
  396.  
  397.                     int j;
  398.  
  399.                     for(j = 0; j < s_len; j++)
  400.                     {
  401.                         if(__to_lower(s[j]) != __to_lower(cstr[j]))
  402.                             break;
  403.                     }
  404.                     if(j > candidate_len)
  405.                     {
  406.                         candidate_len = j;
  407.                         candidate     = i;
  408.                     }
  409.                 }
  410.                 if(candidate >= 0 && candidate != dir_list->abs_row())
  411.                     dir_list->go_item(candidate);
  412.             }
  413.         }
  414.     }
  415.     while(k.skey != (kbEsc | shIsCtrl));
  416.     return -1;
  417. }
  418.  
  419. //----------------------------------------------------------------------
  420. //
  421. //----------------------------------------------------------------------
  422.  
  423. #define MK_CLR(clr)     (app_pal[CL_APPLICATION_START+(clr)])
  424.  
  425. //----------------------------------------------------------------------
  426. //
  427. //----------------------------------------------------------------------
  428.  
  429. int AskNumber(int r, int c, int *number, char *hdr)
  430. {
  431.     int _rows = 3;
  432.     int _cols = 30;
  433.  
  434.     if(_rows + r >= Rows)
  435.         _rows = Rows - r - 2;
  436.  
  437.     if(_cols - c >= Cols)
  438.         _cols = Cols - c - 2;
  439.  
  440.     Dialog dlg(r, c, _rows, _cols);
  441.     EditLine* in = new EditLine(1,
  442.                                     1,
  443.                                     1,
  444.                                     dlg.cols - 2);
  445.     dlg.Ins(in);
  446.  
  447.     if(hdr)
  448.         dlg.Ins(new StaticText(0, (dlg.cols - strlen(hdr)) / 2, 1, strlen(hdr), hdr));
  449.  
  450.     KeyInfo k;
  451.     do
  452.     {
  453.         dlg.draw();
  454.         vio_read_key(&k);
  455.         if((k.skey & 0x00FF) == kbEnter ||
  456.            (k.skey & 0x00FF) == kbGrEnter)
  457.         {
  458.             char *s = in->line(0)->str;
  459.  
  460.             while(__issp(*s))
  461.                 s++;
  462.             if(!*s)
  463.                 return -1;
  464.             *number = 0;
  465.  
  466.             while(__isdd(*s))
  467.             {
  468.                 *number *= 10;
  469.                 *number += *s - '0';
  470.                 s++;
  471.             }
  472.  
  473.             if(!*number)
  474.                 return -1;
  475.  
  476.             return 0;
  477.         }
  478.         dlg.do_key(k);
  479.     }
  480.     while(k.skey != (kbEsc | shIsCtrl));
  481.  
  482.     return -1;
  483. }
  484.  
  485. int AskString(int r, int c, char** res, char *hdr)
  486. {
  487.     int _rows = 3;
  488.     int _cols = 65;
  489.  
  490.     if(!res)
  491.         return -1;
  492.  
  493.     if(_rows + r >= Rows)
  494.         _rows = Rows - r - 2;
  495.  
  496.     if(_cols - c >= Cols)
  497.         _cols = Cols - c - 2;
  498.  
  499.     if(_rows < 3 || _cols < 65)
  500.         return -1;
  501.  
  502.     Dialog dlg(r, c, _rows, _cols);
  503.  
  504.     EditLine* in = new EditLine(1, 1, 1, dlg.cols - 2);
  505.     dlg.Ins(in);
  506.  
  507.     if(hdr)
  508.         dlg.Ins(new StaticText(0, (dlg.cols - strlen(hdr)) / 2, 1, strlen(hdr), hdr));
  509.  
  510.     KeyInfo k;
  511.     do
  512.     {
  513.         dlg.draw();
  514.         vio_read_key(&k);
  515.         if((k.skey & 0x00FF) == kbEnter ||
  516.            (k.skey & 0x00FF) == kbGrEnter)
  517.         {
  518.             *res = str_dup(in->line(0)->str);
  519.  
  520.             return 0;
  521.         }
  522.         dlg.do_key(k);
  523.     }
  524.     while(k.skey != (kbEsc | shIsCtrl));
  525.  
  526.     return -1;
  527. }
  528.  
  529. int MessageBox(char *text, KeyInfo* lastkey, int timeout)
  530. {
  531.     Dialog dlg(0, 0, 2, 2);
  532.  
  533.     int r = 0;
  534.     int c = 0;
  535.     int len;
  536.     char *ptr;
  537.     char *str;
  538.  
  539.     for(ptr = str = text; *str;)
  540.     {
  541.         while(*str && *str != '\n')
  542.             str++;
  543.  
  544.         if(*str)
  545.         {
  546.             if(*(str - 1) == '\r')
  547.                 *(str - 1) = 0;
  548.             *str++ = 0;
  549.             if(*str == '\r' || *str == '\n')
  550.                 *str++ = 0;
  551.         }
  552.         //
  553.         len = strlen(ptr);
  554.  
  555.         if(len >(Cols - 4))
  556.             len = Cols - 4;
  557.  
  558.         if(len > c)
  559.             c = len;
  560.         dlg.Ins(new StaticText(r + 1, 1, 1, len, ptr));
  561.         //
  562.         ptr = str;
  563.         r++;
  564.     }
  565.  
  566.     if(dlg.rows + r >= Rows)
  567.         r = Rows - dlg.rows - 2;
  568.  
  569.     if(dlg.cols + c >= Cols)
  570.         c = Cols - dlg.cols - 2;
  571.  
  572.     dlg.size(dlg.rows + r, dlg.cols + c);
  573.     dlg.move((Rows - dlg.rows)/2, (Cols - dlg.cols)/2);
  574.  
  575.     if(dlg.row < 0 || dlg.col < 0)
  576.         dlg.move(0, 0);
  577.  
  578.  
  579.     KeyInfo k;
  580.     dlg.draw();
  581.  
  582.     if(!timeout)
  583.     {
  584.         do
  585.         {
  586.             vio_read_key(&k);
  587.         }
  588.         while(!(k.skey & 0x00FF));
  589.  
  590.         if(lastkey)
  591.         {
  592.             *lastkey = k;
  593.         }
  594.     }
  595.     else
  596.     {
  597.         DosSleep(timeout);
  598.         k.skey = 0;
  599.     }
  600.     return k.skey;
  601. }
  602.  
  603. int JumpListBox(PJumpList pList, int r, int c, int nr, int nc)
  604. {
  605.     if(!pList || !pList->Count())
  606.         return -1;
  607.  
  608.     if(r < 2 || r > (Rows - 7))
  609.         r = 2;
  610.     if(c < 2 || c > (Cols - 7))
  611.         c = 2;
  612.  
  613.     if(nr <= 4)
  614.         nr = Rows - 4;
  615.  
  616.     if(nc <= 4)
  617.         nc = Cols - 4;
  618.  
  619.     if((nr + r) > (Rows - 2))
  620.         nr = (Rows - 2) - r;
  621.  
  622.     if((nc + c) > (Cols - 2))
  623.         nc = (Cols - 2) - c;
  624.  
  625.     int iFollow = 0;
  626.  
  627.     Dialog dlg(r, c, nr, nc);
  628.  
  629.     ListBox *list = new ListBox(1, 1, dlg.rows - 2, dlg.cols - 2,
  630.                                 ListBox::lbCanScroll |
  631.                                 ListBox::lbXScroll );
  632.  
  633.     dlg.Ins(list);
  634.  
  635.     for(int i = 0; i < pList->Count(); i++)
  636.     {
  637.         PJumpEntry pEntry = pList->get_entry(i);
  638.         list->add_at_end(pEntry->get_name());
  639.         list->set_item_key(i, (unsigned int)pEntry);
  640.     }
  641.  
  642.     list->go_item(pList->get_last_pos());
  643.  
  644.     KeyInfo k;
  645.  
  646.     int last_pos = list->first_selected();
  647.  
  648.     do
  649.     {
  650.         dlg.draw();
  651.         vio_read_key(&k);
  652.  
  653.         if((k.skey & 0x00FF) == kbEnter ||
  654.            (k.skey & 0x00FF) == kbGrEnter)
  655.         {
  656.             int pos = list->first_selected();
  657.  
  658.             PJumpEntry pEntry = (PJumpEntry)list->get_item_key(pos);
  659.  
  660.             if(!pEntry)
  661.                 return -1;
  662.  
  663.             // Select file if opened or open it
  664.  
  665.             Editor.doOpenFile(pEntry->get_file());
  666.  
  667.             if(pEntry->get_row())
  668.                 Editor.current()->goto_line(*Editor.current(),
  669.                                              pEntry->get_row() - 1);
  670.  
  671.             if(pEntry->get_col())
  672.                 Editor.current()->goto_col(*Editor.current(),
  673.                                             pEntry->get_col() - 1);
  674.  
  675.             pList->set_last_pos(pos);
  676.             return pos;
  677.         }
  678.  
  679.         dlg.do_key(k);
  680.  
  681.         int pos = list->first_selected();
  682.  
  683.         if(iFollow && (last_pos != pos))
  684.         {
  685.             PJumpEntry pEntry = (PJumpEntry)list->get_item_key(pos);
  686.  
  687.             if(!pEntry)
  688.                 continue;
  689.  
  690.             // Select file if opened or open it
  691.  
  692.             Editor.doOpenFile(pEntry->get_file());
  693.  
  694.             if(pEntry->get_row())
  695.                 Editor.current()->goto_line(*Editor.current(),
  696.                                              pEntry->get_row() - 1);
  697.  
  698.             if(pEntry->get_col())
  699.                 Editor.current()->goto_col(*Editor.current(),
  700.                                             pEntry->get_col() - 1);
  701.             //Editor.draw();
  702.         }
  703.     }
  704.     while(k.skey != (kbEsc | shIsCtrl));
  705.  
  706.     return -1;
  707. }
  708.  
  709.