home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / fed0217s.zip / source / boxcoll.cpp < prev    next >
C/C++ Source or Header  |  2001-11-12  |  14KB  |  635 lines

  1. /*
  2. ** Module   :BOXCOLL.CPP
  3. ** Abstract :Edit box collection
  4. **
  5. ** Copyright (C) Sergey I. Yevtushenko
  6. ** Copyright (C) Dmitry Froloff
  7. **
  8. ** Log: Mon  16/06/1997     Created
  9. **      Tue  17/04/2001     Added mouse support
  10. */
  11.  
  12. #include <string.h>
  13. #include <stdio.h>
  14.  
  15. #include <fio.h>
  16. #include <stddlg.h>
  17. #include <keynames.h>
  18. #include <version.h>
  19. #include <rx.h>
  20.  
  21. #define INCL_DOS
  22. #define INCL_MOU
  23. #include <os2.h>
  24.  
  25. #define MK_CLR(clr)     (app_pal[CL_APPLICATION_START+(clr)])
  26.  
  27. static void APIENTRY thTimer(ULONG data)
  28. {
  29.     EditBoxCollection* pEdit = (EditBoxCollection*) data;
  30.     int i = 0;
  31.  
  32.     if(!pEdit)
  33.         return;
  34.  
  35.     PMObj pm;
  36.  
  37.     while(!pEdit->isDown())
  38.     {
  39.         DosSleep(100);
  40.  
  41.         i++;
  42.  
  43.         if(i == 10)
  44.         {
  45.             pEdit->lock();
  46.             pEdit->SendKey("kbTimer");
  47.             pEdit->draw();
  48.             pEdit->unlock();
  49.             i = 0;
  50.         }
  51.     }
  52. }
  53.  
  54. static void APIENTRY thMouse(ULONG data)
  55. {
  56.     MOUEVENTINFO Event;
  57.     USHORT MouHandle = 0;
  58.     USHORT ReadType = 1;
  59.     APIRET rc;
  60.  
  61.     PMObj pm;
  62.  
  63.     EditBoxCollection* pEdit = (EditBoxCollection*) data;
  64.  
  65.     rc = MouOpen( 0L, &MouHandle );
  66.  
  67.     if(rc)
  68.         return;
  69.  
  70.     rc = MouDrawPtr(MouHandle);
  71.  
  72.     while(!pEdit->isDown())
  73.     {
  74.         rc = MouReadEventQue(&Event, &ReadType, MouHandle);
  75.  
  76.         if(Event.fs & iMouseMask)
  77.         {
  78.             pEdit->lock();
  79.  
  80.             if(pEdit->current())
  81.             {
  82.                 pEdit->track_beg();
  83.  
  84.                 if(iSenseShift)
  85.                 {
  86.                     if(kiLastKey.skey & shShift)
  87.                         pEdit->current()->mark();
  88.                     else
  89.                         pEdit->current()->unmark();
  90.                 }
  91.  
  92.                 pEdit->SetMouse(Event.row, Event.col);
  93.                 pEdit->track_end();
  94.  
  95.                 pEdit->draw();
  96.             }
  97.             pEdit->unlock();
  98.         }
  99.     }
  100.  
  101.     MouClose(MouHandle);
  102. }
  103.  
  104. static void APIENTRY thPipe(ULONG data)
  105. {
  106.     EditBoxCollection* pEdit = (EditBoxCollection*) data;
  107.  
  108.     if(!pEdit)
  109.         return;
  110.  
  111.     PMObj pm;
  112.  
  113.     while(!pEdit->isDown())
  114.     {
  115.         if(!pEdit->npFED.IsValid())
  116.         {
  117.             DosSleep(200);
  118.             pEdit->npFED.Open(cPipe);
  119.         }
  120.         else
  121.         {
  122.             char* s = 0;
  123.  
  124.             do
  125.             {
  126.                 s = pEdit->npFED.ReadMsg();
  127.  
  128. //printf("%d - %d - %d\n", s, pEdit->npFED.IsValid(), pEdit->isDown());
  129.  
  130.  
  131.                 if(!s || !pEdit->npFED.IsValid() || pEdit->isDown())
  132.                     break;
  133.  
  134.                 char* p = s;
  135.  
  136. //printf("[%s]\n", s);
  137.  
  138.                 if(!memicmp(p, "open ", 5))
  139.                 {
  140.                     p += 5;
  141.  
  142.                     while(__issp(*p))
  143.                         p++;
  144.  
  145.                     if(!*p)
  146.                         break;
  147.  
  148.                     pEdit->lock();
  149.                     pEdit->doOpenFile(p);
  150.                     pEdit->draw();
  151.                     pEdit->unlock();
  152.                     break;
  153.                 }
  154.  
  155.                 if(!memicmp(p, "cursor ", 7))
  156.                 {
  157.                     p += 7;
  158.  
  159.                     while(__issp(*p))
  160.                         p++;
  161.  
  162.                     if(!*p)
  163.                         break;
  164.  
  165.                     pEdit->lock();
  166.                     pEdit->set_xy(p);
  167.                     pEdit->draw();
  168.                     pEdit->unlock();
  169.                     break;
  170.                 }
  171.                              // kbPipe =
  172.                 if(!memicmp(p, "execute ", 8))
  173.                 {
  174.                     memcpy(p, "kbPipe =", 8);
  175.                     pEdit->lock();
  176.                     pEdit->CompileKey(p, 6);
  177.                     pEdit->SendKey("kbPipe");
  178.                     pEdit->draw();
  179.                     pEdit->unlock();
  180.                     break;
  181.                 }
  182.  
  183. //printf("no match!\n", s);
  184.  
  185.                 //Future extensions may go here..
  186.             }
  187.             while(0);
  188.  
  189.             delete s;
  190.         }
  191.     }
  192. }
  193.  
  194. Initor::Initor()
  195. {
  196.     vio_init();
  197.     InitREXX();
  198. }
  199.  
  200. EditBoxCollection::EditBoxCollection():Collection(10,2),
  201.                                        init(), keys(), prof_keys(), npFED(cPipe)
  202. {
  203.     cur_box   = 0;
  204.     shutdown  = 0;
  205.     recording = 0;
  206.  
  207.     head = tail = 0;
  208.     tTID = (TID)-1;
  209.     mTID = (TID)-1;
  210.     pTID = (TID)-1;
  211.  
  212.     DosCreateMutexSem(0, &hMtx, 0, 0);
  213.     DosCreateThread(&tTID, thTimer, (ULONG)this, 0, 0x80000);
  214.     DosCreateThread(&mTID, thMouse, (ULONG)this, 0, 0x80000);
  215.     DosCreateThread(&pTID, thPipe , (ULONG)this, 0, 0x80000);
  216.  
  217.     Clipboard = new Buffer;
  218.     Clipboard->add_line(new Line);
  219.  
  220.     load_profile(0);    //Global profile
  221.     load_profile(1);    //Local profile
  222.  
  223.     if(!keys.Count())
  224.     {
  225.         shutdown = 1;
  226.     }
  227.  
  228.     open();
  229. }
  230.  
  231. void EditBoxCollection::lock()
  232. {
  233.     DosRequestMutexSem(hMtx, (ULONG)-1);
  234. }
  235.  
  236. void EditBoxCollection::unlock()
  237. {
  238.     DosReleaseMutexSem(hMtx);
  239. }
  240.  
  241. void EditBoxCollection::CompileKey(char* str, int j)
  242. {
  243.     keys.InsKey(str, j);
  244. }
  245.  
  246. void EditBoxCollection::Done()
  247. {
  248.     lock();
  249.     RemoveAll();
  250.     vio_shutdown();
  251.  
  252. //    DosCloseMutexSem(hMtx);
  253. //    DosWaitThread(&tTID, DCWW_WAIT);
  254. //    DosWaitThread(&pTID, DCWW_WAIT);
  255. //    DosWaitThread(&mTID, DCWW_WAIT);
  256.  
  257. #ifdef PRINT_HEAP_STATS
  258.     void print_heap_stat(void);
  259.     print_heap_stat();
  260. #endif
  261. }
  262.  
  263. void EditBoxCollection::Free(Ptr p)
  264. {
  265.     delete (EditBox*)p;
  266. }
  267.  
  268. void EditBoxCollection::SendKey(char *key)
  269. {
  270.     KeyInfo k;
  271.  
  272.     k.skey = shIsCtrl;
  273.     strcpy(k.KeyName, key);
  274.     Dispatcher(k);
  275. }
  276.  
  277. void EditBoxCollection::SetMouse(int new_row, int new_col)
  278. {
  279.     current()->put_mouse(*current(), new_row, new_col);
  280. }
  281.  
  282. EditBox* EditBoxCollection::current()
  283. {
  284.     return GetBox(cur_box);
  285. }
  286.  
  287. EditBox* EditBoxCollection::next()
  288. {
  289.     cur_box++;
  290.     if(cur_box >= Count())
  291.         cur_box = 0;
  292.     return current();
  293. }
  294.  
  295. EditBox* EditBoxCollection::prev()
  296. {
  297.     cur_box--;
  298.     if(cur_box < 0)
  299.         cur_box = Count()-1;
  300.     return current();
  301. }
  302.  
  303. EditBox* EditBoxCollection::select(int new_cur)
  304. {
  305.     if(new_cur < Count())
  306.         cur_box = new_cur;
  307.     return current();
  308. }
  309.  
  310. EditBox* EditBoxCollection::locate(int num)
  311. {
  312.     for(int i = 0; i < Count(); i++)
  313.     {
  314.         if(GetBox(i)->number() == num)
  315.         {
  316.             select(i);
  317.             break;
  318.         }
  319.     }
  320.     return current();
  321. }
  322.  
  323. void EditBoxCollection::select(EditBox* new_box)
  324. {
  325.     for(int i = 0; i < Count(); i++)
  326.     {
  327.         if(new_box == GetBox(i))
  328.         {
  329.             select(i);
  330.             break;
  331.         }
  332.     }
  333. }
  334.  
  335. EditBox* EditBoxCollection::open()
  336. {
  337.     EditBox* new_box = new EditBox(0,0, Rows - 1, Cols);
  338.  
  339.     if(iUpperStatus)
  340.         new_box->row++;
  341.  
  342.     Add(new_box);
  343.     return new_box;
  344. }
  345.  
  346. void EditBoxCollection::close()
  347. {
  348.     EditBox* box = (EditBox *)Remove(cur_box);
  349.     delete box;
  350.  
  351.     if(!Count())
  352.         open();
  353. }
  354.  
  355. int EditBoxCollection::opened(char *fname)
  356. {
  357.     char* _cname = get_full_name(fname);
  358.  
  359.     for(int i = 0; i < Count(); i++)
  360.     {
  361.         if(!__cstrcmp(GetBox(i)->get_name(), _cname))
  362.         {
  363.             delete _cname;
  364.             return i;
  365.         }
  366.     }
  367.     delete _cname;
  368.     return -1;
  369. }
  370.  
  371. void EditBoxCollection::draw()
  372. {
  373.     if(!current())
  374.         return;
  375.  
  376.     current()->draw();
  377.  
  378.     char* str = statusline;
  379.     char* ptr = cName;
  380.  
  381.     if(!str || !ptr)
  382.         return;
  383.  
  384.     int fminlen = 0;
  385.  
  386.     for(;*str; str++)
  387.     {
  388.         if(*str == '%')
  389.         {
  390.             char *out = 0;
  391.             int minlen = 0;
  392.             str++;
  393.  
  394.             if(!*str)
  395.                 break;
  396.  
  397.             while(__isdd(*str))
  398.             {
  399.                 minlen *= 10;
  400.                 minlen += *str++ - '0';
  401.             }
  402.  
  403.             switch(*str)
  404.             {
  405.                 case 'n': out = cvt_num(current()->number(), 0);            break;
  406.                 case 'r': out = cvt_num(current()->get_edit_row(), minlen); break;
  407.                 case 'c': out = cvt_num(current()->get_edit_col(), minlen); break;
  408.                 case 'd': out = cvt_num(current()->get_cur_char(), minlen); break;
  409.                 case 'p': out = cvt_num(current()->get_rel_pos() , minlen); break;
  410.                 case 'x': out = xcvt_char(current()->get_cur_char());       break;
  411.                 case 'h': out = Parser::NameByKey(current()->get_hiliting()); break;
  412.                 case 'l': out = current()->get_cur_cp();                    break;
  413.  
  414.                 case 'a': *ptr++ = (current()->get_auto_indent() ? 'I':' '); break;
  415.                 case 'u': *ptr++ = (current()->get_changed() ? '*':' ');     break;
  416.                 case 't': *ptr++ = (current()->get_unix() ? 'U':'D');        break;
  417.                 case 'm': *ptr++ = (current()->get_column_block() ? 'C':'S');break;
  418.  
  419.                 case 'f': out = current()->get_fmt_name(minlen, '░');
  420.                           fminlen = minlen;
  421.                           break;
  422.  
  423.                 case 'w':
  424.                     if(!(current()->ww_get() & WW_STATE))
  425.                         *ptr++ = ' ';
  426.                     else
  427.                         *ptr++ = (current()->ww_get() & WW_MERGE ? 'M':'W');
  428.                     break;
  429.  
  430.                 default:
  431.                     if(*str)
  432.                         *ptr++ = *str;
  433.                     break;
  434.             }
  435.  
  436.             if(out)
  437.                 while(*out)
  438.                     *ptr++ = *out++;
  439.             continue;
  440.         }
  441.         *ptr++ = *str;
  442.     }
  443.     *ptr = 0;
  444.  
  445.     int sRow = (iUpperStatus) ? (0):(Rows - 1);
  446.  
  447.     vio_print2(sRow, 0, cName, Cols, MK_CLR(CL_STATUSLINE));
  448.  
  449.     if(recording)
  450.         vio_print2(sRow, Cols - 1, "R", 1, 0xF0);
  451.  
  452.     strcpy(cName, "FED-");
  453.     strcat(cName, current()->get_fmt_name(fminlen));
  454.     set_title(cName);
  455. }
  456.  
  457. int EditBoxCollection::check_save()
  458. {
  459.     if(!current())
  460.         return 0;
  461.  
  462.     EditBox* cur = current();
  463.  
  464.     do
  465.     {
  466.         if(current()->get_changed())
  467.         {
  468.             draw();
  469.  
  470.             int rc = AChoice(5, 5, Yes_No, "Save?");
  471.  
  472.             switch(rc)
  473.             {
  474.                 case -1:
  475.                 case  2:
  476.                     select(cur);
  477.                     return -1;
  478.                 case  0:
  479.  
  480.                     if(current()->is_untitled())
  481.                     {
  482.                         rc = FileDialog(5, 5, cName, 2);
  483.                         if(!rc)
  484.                             current()->save_as(cName);
  485.                         else
  486.                             return -1;
  487.                     }
  488.                     if(current()->save())
  489.                     {
  490.                         MessageBox("Error saving file!");
  491.                         return -1;
  492.                     }
  493.             }
  494.         }
  495.         else
  496.             current()->save(); //Indeed just put EA and ignore error
  497.  
  498.         next();
  499.     }
  500.     while(current() != cur);
  501.     return 0;
  502. }
  503.  
  504. void EditBoxCollection::search_proc()
  505. {
  506.     if(!current())
  507.         return;
  508.  
  509.     if(strchr(Flags, 'g') || strchr(Flags, 'G'))    //Global search
  510.         doFileBegin();
  511.  
  512.     int rc = current()->search(Flags, Search);
  513.  
  514.     if(!rc)
  515.     {
  516.         if(iVSearch)
  517.             MessageBox("\n No occurences found! \n");
  518.         return;
  519.     }
  520.  
  521.     if(rc && (strchr(Flags, 'r') || strchr(Flags, 'R')))
  522.     {
  523.         // Replace mode
  524.         if((strchr(Flags, 'n') ||
  525.             strchr(Flags, 'N'))) //Noask
  526.         {
  527.             do
  528.             {
  529.                 current()->replace(Replace);
  530.             }
  531.             while(current()->search(Flags, Search));
  532.  
  533.             if(iVSearch)
  534.                 MessageBox("\n Done. \n");
  535.         }
  536.         else //Confirmation
  537.         {
  538.             do
  539.             {
  540.                 int rr;
  541.                 int cc;
  542.  
  543.                 if(current()->get_cur_row() < (Rows - 7))
  544.                     rr = current()->get_cur_row() + 2;
  545.                 else
  546.                     rr = current()->get_cur_row() - 7;
  547.  
  548.                 if(current()->get_cur_col() < (Cols - 12))
  549.                     cc = current()->get_cur_col();
  550.                 else
  551.                     cc = current()->get_cur_col() - 12;
  552.  
  553.                 draw();
  554.  
  555.                 rc = AChoice(rr, cc, Yes_No, "Replace?");
  556.                 if(rc == 0)
  557.                     current()->replace(Replace);
  558.                 if(rc == 2 || rc == -1)
  559.                     break;
  560.             }
  561.             while(current()->search(Flags, Search));
  562.  
  563.             if(rc != 2 && rc != -1 && iVSearch)
  564.                 MessageBox("\n Done. \n");
  565.         }
  566.     }
  567. }
  568.  
  569. void EditBoxCollection::track_beg()
  570. {
  571.     for(int i = 0; i < Count(); i++)
  572.     {
  573.         GetBox(i)->track_beg();
  574.     }
  575. }
  576.  
  577. void EditBoxCollection::track_end()
  578. {
  579.     for(int i = 0; i < Count(); i++)
  580.     {
  581.         GetBox(i)->track_end();
  582.     }
  583. }
  584.  
  585. void EditBoxCollection::track_cancel()
  586. {
  587.     for(int i = 0; i < Count(); i++)
  588.     {
  589.         GetBox(i)->track_cancel();
  590.     }
  591. }
  592.  
  593. void EditBoxCollection::usual_key(KeyInfo& k)
  594. {
  595.     if(current()->get_mark_state())
  596.         current()->clear(*current());
  597.  
  598.     if(current()->get_ins_mode())
  599.         current()->ins_char(*current(), k.key);
  600.     else
  601.         current()->replace_char(*current(), k.key);
  602. }
  603.  
  604. void EditBoxCollection::set_xy(char *ptr)
  605. {
  606.     int cX = 0;
  607.     int cY = 0;
  608.  
  609.     if(!current())
  610.         return;
  611.  
  612.     while(*ptr && __isdd(*ptr))
  613.     {
  614.         cX *= 10;
  615.         cX += *ptr - '0';
  616.         ptr++;
  617.     }
  618.  
  619.     if(*ptr)
  620.         ptr++;
  621.  
  622.     while(*ptr && __isdd(*ptr))
  623.     {
  624.         cY *= 10;
  625.         cY += *ptr - '0';
  626.         ptr++;
  627.     }
  628.  
  629.     if(cX > 0)
  630.         current()->goto_line(*current(), cX - 1);
  631.     if(cY > 0)
  632.         current()->goto_col(*current(), cY - 1);
  633. }
  634.  
  635.