source: Sophya/trunk/SophyaPI/PI/picons.cc @ 2676

Last change on this file since 2676 was 2676, checked in by ansari, 19 years ago

Modif PIConsole pour envoi de Msg_Cancel pour <Cntrl C> et positionnement curseur lors de rappel de commandes - Reza 19/4/2005

File size: 25.1 KB
Line 
1#include "sopnamsp.h"
2#include "pisysdep.h"
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6#include <ctype.h>
7
8#include PIMENU_H
9#include "picons.h"
10
11
12//++
13// Class        PIConsole
14// Lib          PI
15// include      picons.h
16//
17//      Cette classe fournit une partie des services equivalentes
18//      a une console. Les sorties stdout et stderr peuvent etre
19//      redirigees sur un objet *PIConsole* (Voir "PIApplication").
20//      La classe offre aussi la possibilite de gestion d'un ScrollBar,
21//      ainsi que la saisie et l'edition de commande, avec la gestion
22//      d'un buffer de rappel.
23//
24//      * Bouton-1 : Envoie le message "PIMsg_Active". Permet aussi
25//      la selection d'un rectangle pour le copie/coller
26//      * Bouton-2 : Effectue l'operation Copier/*Coller* sur la ligne
27//      d'edition de commandes.
28//      de commande (convention Xt)
29//      * Bouton-3 : Affiche le menu des options d'affichage.
30//
31//      Gestion du clavier :
32//      * <Alt>O : Affiche le menu des options d'affichage.
33//      * <Alt>V : Copier/*Coller* Copie le texte depuis le buffer copier/coller
34//      sur la ligne d'edition de commande.
35//      * <Alt>A : Selectionne toute la fenetre pour *Copier*/Coller
36//      * <Alt>L : Liste des commandes dans le tampon de rappel.
37//
38//      Commandes d'edition :
39//      * <Ctl>A : Debut de ligne.
40//      * <Ctl>E : Fin de ligne.
41//      * <Ctl>K : Effacement jusqu'en fin de ligne.
42//      * <Ctl>C : Effacement de la ligne et envoi du message PIMsg_Cancel
43//      * Curseur gauche, droite : deplacement curseur
44//      * Cursur Haut,bas : rappel de commande
45//      * Backspace, del : effacement de caracteres
46//      * <Return> : Validation (Envoi du message PIMsg_OK)
47//--
48//++
49// Links        Parents
50// PIBaseWdg
51//--
52
53// #define DEBUG_PICONS 1
54
55//  Le menu qui va servir a changer de fontes, couleurs, ...
56// de bouton-3
57static PIMenu* opmc=NULL;
58static int nb_opmc = 0;
59
60static void ActivatePIConsOptionMenu(PIConsole* par)
61{
62  if (opmc)  delete opmc;
63  opmc = NULL;
64
65  opmc = new PIMenu(par, "OptCons", k_PopupMenu);
66  opmc->AppendItem("SmallFont", 3101);
67  opmc->AppendItem("NormalFont", 3102);
68  opmc->AppendItem("LargeFont", 3103);
69  opmc->AppendItem("25L x 132C", 3301);
70  opmc->AppendItem("20L x 80C", 3302);
71  opmc->AppendItem("10L x 80C", 3303);
72  opmc->AppendItem("5L x 60C", 3304);
73  opmc->AppendItem("Bkg White", 3201);
74  opmc->AppendItem("Bkg Black", 3202);
75  opmc->AppendItem("Black/Yellow", 3203);
76 
77  opmc->SetMsgParent((PIMsgHandler*)par);
78  opmc->Show(); 
79 
80}
81
82/*  --------------------------------------------------------------------------------- */
83/*  ---------  Classe PIConsole : I/O (Ecriture/lecture) texte standard  ------------ */
84/*  --------------------------------------------------------------------------------- */
85
86static int CmdStrLen = 256;
87static int PIVA_Select = 1 << 3;
88
89//  Gestion du scroll-bar
90static int Scb_Width = 14;
91
92
93//++
94// Titre        Constructeur
95//--
96//++
97// PIConsole(PIContainer* par, const char* nom, PIMessage msg, \
98//           int nl, int nc, int sx, int sy, int px, int py, bool scb)
99//      Creation d'un objet PIConsole, avec "nl" lignes et  "nc" colonnes.
100//      "sx,sy" indique la taille de la fenetre. Si "scb==true", un
101//      ScrollBar est cree associe a l'objet PIConsole.
102//--
103
104/* --Methode-- */
105PIConsole::PIConsole(PIContainer* par, const char* nom, PIMessage msg,
106                     int nl, int nc, int sx, int sy, int px, int py, bool scb) :
107PIBaseWdg(par, nom, ((scb)?sx-Scb_Width:sx), sy, px, py) 
108{
109mNL = (nl > 10) ? nl : 10;
110mNC = (nc > 30) ? nc : 30;
111mText = new char[mNL*mNC];
112mAtt = new unsigned char[mNL*mNC];
113mLPo = new int[mNL];
114mStrBuf = new char[mNC+1];
115mCmdStr = new char[CmdStrLen+1];
116mCCP = mCLC = 0;
117mDCOff = 0;
118mScb = NULL;
119
120SetMsg(msg);
121
122int i;
123for(i=0; i<mNL; i++) {
124  mLPo[i] = i*mNC;
125  ClearLine(i);
126  }
127
128mOffL = 0;
129mNCmdL = 0;
130mCmd = "";
131
132// Pile de rappel des commandes
133mRStr = NULL;
134mNComm = NMxRecall = 0;
135mRCindx = mRindx = 0;
136mChangeFg = false;
137
138// Copier/coller
139mCPBuffer = NULL;
140mCPBufLen = 0;
141mCPbeginC =  mCPendC = -1;
142mCPbeginL = mCPendL = -1;
143
144SetPrompt("Cmd> ");
145ClrCmd();
146SelectFont();
147SelFgBgCol();
148mCurL = mNL-mWSzL-1; 
149mCurC = 0;
150
151
152// Pour ajouter un scroll-bar
153AssocScrollBar(par, nom, scb, sx, sy, px, py);
154
155
156ActivateKeyboard();  // Gestion de l'edition
157ActivateButton(1);   //  Action selection / copier - coller
158ActivateMove(1);     //      "    "     " 
159ActivateButton(2);   //      "    "     " 
160// ActivateButton(3);   Pour afficher le menu des options (Fontes/couleur)
161Manage();
162return;
163}
164
165/* --Methode-- */
166PIConsole::~PIConsole()
167{
168delete[] mText;
169delete[] mAtt;
170delete[] mLPo;
171delete[] mStrBuf;
172delete[] mCmdStr;
173if (mScb) delete mScb;
174if (opmc) { delete opmc;  opmc=NULL; }
175}
176
177
178//++
179// Titre        Méthodes
180//      Seule les méthodes les plus usuelles sont décrites ici. Se reporter
181//      au fichier .h pour la liste complete des méthodes
182//      le type "enum PIVAType" est utilise pour definir les attributs
183//      graphiques du texte affiche dans l'objet PIConsole. Les attributs
184//      de texte et de couleur peuvent etre combine a l'aide de l'operateur
185//      ou logique (|)
186//|  PIVA_Def : Attribut par defaut
187//|  PIVA_Bold : Caracteres gras
188//|  PIVA_Ital : Caracteres italiques
189//|  PIVA_Reverse : Caracteres en video inverse
190//|  PIVA_DefCol : Couleur par defaut
191//|  PIVA_Red : couleur rouge
192//|  PIVA_Blue : Couleur bleue
193//|  PIVA_Green : Couleur verte
194//|  PIVA_Yellow : couleur jaune
195//|  PIVA_Magenta : couleur mauve
196//-- 
197
198//++
199// void  AddChar(char c, unsigned char va= PIVA_Def, bool ref=true)
200//      Ajout d'un caractere a la position courante. si "ref==true",
201//      la fenetre est rafraichie. le caractere newline declenche
202//      un retour a la ligne.
203// void  AddStr(const char* strg, unsigned char va= PIVA_Def, bool ref=true);
204//      Ajout d'une chaine de caracteres a partir de la position courante.
205//      si "ref==true", la fenetre est rafraichie. le caractere newline declenche
206//      un retour a la ligne.
207// void  AcceptCmd(bool acc=true, int nrecmx=20)
208//      Active/desactive l'edition de commandes. "nrecmx" indique la profondeur
209//      du tampon de rappel de commandes. Le message associe a l'objet PIConsole
210//      avec la qualificatif "PIMsg_OK" est envoye lors de la validation de la
211//      commande.
212// string  GetCmdString()
213//      Renvoie la chaine de caractere correspondant a la ligne editee.
214//--
215
216/* --Methode-- */
217void PIConsole::AddChar(char c, unsigned char va, bool ref)
218{
219int l1, l2;
220if (mOffL != 0)  // Decalage d'affichage precedant -> Tout rafraichir
221  { l1 = mNL-mWSzL-1; l2 = mNL-1;  SetDispOffset(-1); }
222else l1 = l2 = mCurL; 
223if (c == '\n') {
224  mCurC = 0;
225  mCurL++;   
226  }
227else {
228  mText[mLPo[mCurL]+mCurC] = c;
229  mAtt[mLPo[mCurL]+mCurC] = va;
230  if (++mCurC == mNC) {mCurC = 0;  mCurL++; }
231  }
232
233if (mCurL >= (mNL-mNCmdL) ) { // Il faut scroller
234  ScrollUp(); 
235  mCurL = mNL-mNCmdL-1;
236  l1 = mNL-mWSzL-1; 
237  }
238if (l2 < mCurL) l2 = mCurL;
239if (ref) DisplayLines(mWGrC, l1, l2);
240return;
241}
242
243
244/* --Methode-- */
245void PIConsole::AddStr(const char* strg, unsigned char va, bool ref)
246{
247int l1, l2;
248if (mOffL != 0)  // Decalage d'affichage precedant -> Tout rafraichir
249  { l1 = mNL-mWSzL-1; l2 = mNL-1;  SetDispOffset(-1); }
250else l1 = l2 = mCurL; 
251
252char c;
253while ( (c = *strg) != '\0') {
254  if ( c != '\n' ) {
255    mText[mLPo[mCurL]+mCurC] = c;
256    mAtt[mLPo[mCurL]+mCurC] = va;
257    if (++mCurC == mNC) {mCurC = 0;  mCurL++; }
258    }
259  else { mCurL++; mCurC = 0; } 
260  if (mCurL >= (mNL-mNCmdL) ) { // Il faut scroller
261    ScrollUp(); 
262    mCurL = mNL-mNCmdL-1;
263    l1 = mNL-mWSzL-1; 
264    }
265  strg++;
266  }
267
268if (l2 < mCurL) l2 = mCurL;
269if (ref) DisplayLines(mWGrC, l1, l2);
270return;
271}
272
273/* --Methode-- */
274void PIConsole::SelectFont(PIFontSize sz)
275{
276int asc, desc;
277mWGrC->SelFont(sz);
278mFTaille = sz;
279mFHaut = mWGrC->GetFont().GetFontHeight(asc, desc);
280mFLarg = (int)mWGrC->CalcStringWidth("ABCDEFGHIJ")/10;
281mWSzL = YSize()/mFHaut - 1;
282mWSzC = XSize()/mFLarg - 2;
283mOffL = 0;
284if (mScb) {
285  mScb->SetMinMax(0, NbLines()-1);
286  mScb->SetSlSize(WindNbLines());
287  mScb->SetValue(0);
288  }
289}
290
291
292/* --Methode-- */
293void PIConsole::AutoSize(int nl, int nc)
294{
295if ( (nl < 1) || (nc < 1) ) {
296  nl = mWSzL;   nc = mNC;
297  }
298if (nc > mNC) nc = mNC;
299int dsz[2];
300dsz[0] = (nc+2)*mFLarg - XSize();
301dsz[1] = (nl+1)*mFHaut - YSize();
302Send(Msg(), PIMsg_ResizeRequest, dsz);
303
304mWSzL = YSize()/mFHaut - 1;
305mWSzC = XSize()/mFLarg - 2;
306/*
307if (mScb) {
308  mScb->SetMinMax(0, NbLines()-1);
309  mScb->SetSlSize(WindNbLines());
310  mScb->SetValue(0);
311  }
312  */
313mOffL = 0;
314}
315
316/* --Methode-- */
317void PIConsole::PreferedSize(int& sx, int& sy)
318{
319sx = (mNC+2)*mFLarg;
320sy = (mWSzL+1)*mFHaut;
321return;
322}
323
324/* --Methode-- */
325void PIConsole::AcceptCmd(bool acc, int nmxrec)
326{
327int l1, l2;
328if (acc) {
329  if (mNCmdL)  return;  // Pas de changement d'etat
330  if (mCurL == (mNL-1) ) { l1 = mNL-mWSzL-1; ScrollUp(); mCurL = (mNL-2); }
331  else l1 = mNL-1;
332  mNCmdL = 1;
333  ClrCmd();
334  UpdCmdLine();
335  l2 = mNL-1;
336  if (nmxrec > 0) {
337    NMxRecall = (nmxrec > 5) ? nmxrec : 5;
338    if (mRStr)  delete[] mRStr;
339    mRStr = new string[NMxRecall];
340    mNComm = mRCindx = mRindx = 0;
341    mRStr[0] = "";
342    }
343  }
344else {
345  if (mNCmdL == 0)  return;  // Pas de changement d'etat
346  mNCmdL = 0;
347  ClearLine(mNL-1);
348  ClrCmd();
349  l1 = l2 = mNL-1;
350  delete[] mRStr;
351  mRCindx = mRindx = 0;
352  }
353DisplayLines(mWGrC, l1, l2);
354return;
355}
356
357/* --Methode-- */
358void PIConsole::SetPrompt(const char* prompt)
359{
360strncpy(mPrompt, prompt, 31); 
361mPrompt[31] = '\0';
362return;
363}
364
365/* --Methode-- */
366void PIConsole::SetDispOffset(int ldeb)
367{
368if (ldeb < 0)    { 
369  if (mScb) mScb->SetValue(0); 
370  mOffL = 0;
371  }
372else mOffL = (ldeb < mNL-mWSzL-1) ? ldeb : mNL-mWSzL-1;
373}
374
375
376/* --Methode-- */
377void PIConsole::Resize()
378{
379mWSzL = YSize()/mFHaut - 1;
380mWSzC = XSize()/mFLarg - 2;
381if (mScb) {
382  mScb->SetMinMax(0, NbLines()-1);
383  mScb->SetSlSize(WindNbLines());
384  mScb->SetValue(0);
385  }
386mOffL = 0;
387}
388
389/* --Methode-- */
390void PIConsole::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
391{
392EraseWindow();
393DisplayLines(g, 0, mNL);
394}
395
396
397/* --Methode-- */
398void PIConsole::Keyboard(int key, PIKeyModifier kmod)
399{
400
401if (kmod == PIKM_Alt) {
402  if (key == 'O' || key == 'o') {   // Menu des options
403    ActivatePIConsOptionMenu(this);
404    return;
405    }
406  else if (key == 'A' || key == 'a') {  // Pour tout selectionner
407    mCPbeginC = 0; mCPendC = XSize(); 
408    mCPbeginL = 0;  mCPendL = YSize(); 
409    SaveSelection();
410    return;
411    }
412  else if (key == 'L' || key == 'l') {  // Pour lister le buffer de rappel
413    int nmxrec = (mNComm < NMxRecall) ? mNComm : NMxRecall;
414    if (nmxrec < 1)  return;
415    AddStr("PIConsole - Command history : \n",  PIVA_Def, false);
416    int ridx = mRCindx+nmxrec;
417    int kk;
418    char strg[64];
419    for(kk=0; kk<nmxrec; kk++) {
420      sprintf(strg, "%d- ", mNComm-nmxrec+kk+1);
421      AddStr(strg, PIVA_Def, false);
422      AddStr(mRStr[ridx%nmxrec].c_str(), PIVA_Def, false);
423      AddChar('\n', PIVA_Def, false);
424      ridx++;
425      }
426    AddChar('\n', PIVA_Def, false);
427    Refresh();
428    return;
429    }
430  }
431
432if (mNCmdL < 1)  return;
433
434int k;
435bool fgfk = false;
436
437if (kmod == PIKM_Cntl) {
438  switch (key) {
439    case 1 :  // <Cntl> A  Debut de ligne
440      mCCP = 0;
441      break;
442    case 3 :  // <Cntl> C  On efface la ligne
443      mCCP = mCLC = 0;
444      mCmdStr[mCLC] = '\0';
445      mRindx = mRCindx;
446      mChangeFg = true;
447      Send( Msg(), PIMsg_Cancel, NULL);
448
449      break;
450    case 5 :  // <Cntl> E  Fin de ligne
451      mCCP = mCLC;
452      break;
453    case 11 :  // <Cntl> K  On efface jusqu'en fin de ligne
454      mCLC = mCCP;
455      break;
456    }
457  }
458
459else if (kmod == PIKM_Alt) {
460  if (key == 'V' || key == 'v') RequestSelection();  // Pour coller (copier/coller)
461  }
462
463else if (kmod == PIKM_Blank) {
464  switch (key) {
465    case PIK_Return :   
466    case PIK_Enter :
467      SendCmd();
468      break;
469
470    case PIK_BackSpace :
471    case 127 :    // Touche del
472    case 8 :      // Touche backspace
473      if (mCCP > 0)  { 
474        for(k=mCCP-1; k<mCLC-1; k++)  mCmdStr[k] = mCmdStr[k+1];
475        mCmdStr[mCLC-1] = ' ';   mCCP--;  mCLC--;
476        mChangeFg = true;
477        }
478      //      printf("Keyb()-Debug- Backspace CCP,CLC= %d %d CmdStr= %s (L=%d) \n", mCCP, mCLC,
479      //      mCmdStr, strlen(mCmdStr));
480      break;
481     
482    case PIK_Up :
483    case PIK_Down :
484//      printf("Keyb()-Debug- CursorUp/Down(%d)  Index= %d %d  \n", key, mRindx, mRCindx);
485      if (mNComm > 0) {
486        if (mChangeFg) { 
487          mCmdStr[mCLC] = '\0';
488          mRStr[mRCindx] = mCmdStr;
489          mChangeFg = false;
490          }
491        int nmxrec = ((mNComm+1) < NMxRecall) ? mNComm+1 : NMxRecall;
492        if (key == PIK_Up) { 
493           mRindx --;
494           if (mRindx < 0) mRindx += nmxrec;
495           }
496        else mRindx++;
497        int ridx = mRindx%nmxrec;
498        mCLC = mCCP = mRStr[ridx].length();
499        for(k=0; k< mCLC; k++)  mCmdStr[k] =  mRStr[ridx][k];
500        mCmdStr[mCLC] = '\0';     
501        int mxCC = mWSzC-strlen(mPrompt)-2;
502        if (mCCP >= mxCC) mCCP = mxCC; // On se met le plus loin possible sur la ligne       
503      }
504      break;
505
506    case PIK_Left :
507      if (mCCP > 0)  mCCP--;
508      //      printf("Keyb()-Debug- Left CCP,CLC= %d %d  \n", mCCP, mCLC);
509      break;
510    case PIK_Right :
511      if (mCCP < mCLC)  mCCP++;
512      //      printf("Keyb()-Debug- Right CCP,CLC= %d %d  \n", mCCP, mCLC);
513      break;
514    default :
515      fgfk = true;
516      break;
517    }
518  }
519if ( ( fgfk && (kmod == PIKM_Blank) ) || (kmod == PIKM_Shift)  ) CmdAddChar(key);
520UpdCmdLine();
521// DisplayLines(mNL-1, mNL-1);
522return;
523}
524
525
526/* --Methode-- */
527void PIConsole::But1Press(int x, int y)
528{
529Send(Msg(), PIMsg_Active);
530AssignKeyboard();
531mWGrC->SelGOMode(PI_GOXOR);
532mWGrC->SelForeground(PI_Grey);
533mCPbeginC = x;  mCPbeginL = y;
534mCPendC = mCPendL = -1;
535} 
536
537/* --Methode-- */
538void PIConsole::Ptr1Move(int x, int y)
539{
540if (mCPendC >= 0) mWGrC->DrawBox(mCPbeginC, mCPbeginL, mCPendC-mCPbeginC, mCPendL-mCPbeginL);
541mCPendC = x;  mCPendL = y;
542mWGrC->DrawBox(mCPbeginC, mCPbeginL, mCPendC-mCPbeginC, mCPendL-mCPbeginL);
543}
544 
545/* --Methode-- */
546void PIConsole::But1Release(int x, int y)
547{
548if ( (mCPendC >= 0) && (mCPbeginC >= 0) ) { 
549  mWGrC->DrawBox(mCPbeginC, mCPbeginL, mCPendC-mCPbeginC, mCPendL-mCPbeginL);
550  mCPendC = x;  mCPendL = y;
551  }
552else { 
553  mCPbeginC =  mCPendC = -1;
554  mCPbeginL = mCPendL = -1;
555  }
556mWGrC->SelGOMode(PI_GOCopy);
557mWGrC->SelForeground(mFgC);
558SaveSelection();
559} 
560
561/* --Methode-- */
562void PIConsole::But2Press(int x, int y)
563{
564RequestSelection();  // Pour recuperer la selection = coller (copier/coller)
565} 
566
567/* --Methode-- */
568void PIConsole::But3Press(int x, int y)
569{
570ActivatePIConsOptionMenu(this);
571}
572
573/* --Methode-- */
574void PIConsole::PasteSelection(unsigned int typ, void *pdata, unsigned int l)
575{
576if (typ != PICP_string) return;
577int i;
578char *pc = (char *)pdata;
579for(i=0; i<l; i++) {
580  if ((i > 0) && (pc[i] == '\n'))  SendCmd();
581  else CmdAddChar(pc[i]);
582}
583UpdCmdLine();
584}
585
586/* --Methode-- */
587void PIConsole::SelectionLost()
588{
589// printf("Debug PIConsole::SelectionLost() %lx (L=%d)\n",(long)mCPBuffer, mCPBufLen);
590if (!mCPBuffer) return;
591delete[] mCPBuffer; 
592mCPBuffer = NULL;
593mCPBufLen = 0;
594mCPbeginC =  mCPendC = -1;
595mCPbeginL = mCPendL = -1;
596int i,j;
597int l1,l2;
598l1 = mNL+1; l2 = -1;
599for(i=0; i<mNL; i++)   // On enleve le bit select a tous les caracteres
600  for(j=0; j<mNC; j++) 
601    if ( mAtt[mLPo[i]+j] & PIVA_Select) {
602      if (l1 > i)  l1 = i;
603      if (l2 < i)  l2 = i;
604      mAtt[mLPo[i]+j] &= ~PIVA_Select ;
605    }
606
607if (IsVisible() && l2 > -1)  DisplayLines(mWGrC, l1, l2);
608return;
609}
610
611/* --Methode-- */
612void PIConsole::SelectionTransferEnd()
613{
614// printf("Debug PIConsole::SelectionTransferEnd() -Rien- %lx (L=%d)\n",(long)mCPBuffer, mCPBufLen);
615}
616
617
618/* --Methode-- */
619void * PIConsole::ProvideSelection(unsigned int& typ, unsigned int& len)
620{
621typ = PICP_string;
622len = mCPBufLen;
623return(mCPBuffer);
624}
625
626/* ----------------------------------------------------------------------------- */
627/*    ---------------------- Methodes protected -------------------------        */
628/* ----------------------------------------------------------------------------- */
629
630
631/* --Methode--
632void PIConsole::DebugPrint(int lp)
633{
634printf("PIConsole::DebugPrint() - NL,NC= %d %d - WSzL,C= %d %d Cur= %d %d\n", mNL, mNC,
635        mWSzL, mWSzC, mCurL, mCurC);
636printf(" OffL, NCmdL= %d %d - mCCP, mCLC= %d %d - LPo= %d %d \n",
637        mOffL, mNCmdL, mCCP, mCLC, mLPo[mNL-2], mLPo[mNL-1]);
638
639if (lp == 0)  return;
640int i,j;
641for(j=0; j<mNL; j++) {
642  printf("Line[%d] (%d) = ", j, mLPo[j]);
643  for(i=0; i<mNC; i++)  putchar(mText[mLPo[j]+i]);
644  putchar('\n');
645  }
646return;
647}
648*/
649
650
651/* --Methode-- */
652void PIConsole::AssocScrollBar(PIContainer* par, const char* nom, bool scb, int sx, int sy, int px, int py)
653{
654if (!scb) {
655  mScb = NULL;
656  msgScb = 0;
657  SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
658  return;   
659}
660
661sx -= Scb_Width;
662// SetSize(sx, sy);
663SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
664char name[128];
665strcpy(name,"ScrollBar_");
666strncat(name, nom, 127);
667msgScb = Msg()+55;
668mScb = new PIScrollBar (par, name, msgScb, kSDirDownUp, Scb_Width, sy, px+sx, py);
669mScb->SetBinding(PIBK_free, PIBK_fixed, PIBK_fixed, PIBK_fixed);
670 
671mScb->SetMsgParent(this);
672mScb->SetMinMax(0, NbLines()-1);
673mScb->SetSlSize(WindNbLines());
674mScb->SetValue(0);
675mScb->ActivateDrag(true);
676}
677
678/* --Methode-- */
679void PIConsole::ScrollUp()
680{
681int i,l,kpo;
682l = mNL-1-mNCmdL;
683kpo = mLPo[0];
684for(i=0; i<mNL-mNCmdL-1; i++)   mLPo[i] = mLPo[i+1];
685mLPo[l] = kpo;
686ClearLine(l);
687return;
688}
689
690/* --Methode-- */
691void PIConsole::ClearLine(int l)
692{
693if ((l<0) || (l >= mNL)) return;
694int j;
695for(j=0; j<mNC; j++) {
696  mText[mLPo[l]+j] = ' ';
697  mAtt[mLPo[l]+j] = PIVA_Def;
698  }
699return;
700}
701
702/* --Methode-- */
703void PIConsole::DisplayLines(PIGraphicGen* g, int l1, int l2)
704{
705int j,l,k,l0;
706int x,y;
707
708// DBG printf("PIConsole::DisplayLines(%d %d ) -> %d - %lx \n ", l1, l2,
709//            (int)IsVisible(), (long)XtWindow(XtWdg()));
710
711if (! IsVisible() )   return;
712
713int lva = -1;
714int ccol, cfnt;
715
716PIFontAtt vafat[8] = {PI_RomanFont, PI_BoldFont, PI_ItalicFont,
717                      PI_RomanFont, PI_RomanFont, PI_BoldFont, 
718                      PI_ItalicFont, PI_RomanFont};
719PIColors fgc, bgc, dbgc;
720PIColors col[6] = {PI_Black, PI_Red, PI_Blue, PI_Green, PI_Yellow, PI_Magenta};
721
722g->SelForeground(mFgC);
723g->SelBackground(mBgC);
724fgc =  col[0] = g->GetForeground();
725dbgc = bgc =  g->GetBackground();
726
727int dx = mFLarg;
728int dy = mFHaut/2;
729int dxo2 = dx/2;
730if (dxo2 > 3)  dxo2 = 3;
731int dyo2 = dy/2;
732if (dyo2 > 3)  dyo2 = 3;
733
734g->DrawBox(dxo2, dyo2, (mNC+2)*mFLarg-2*dxo2, (mWSzL+1)*mFHaut-dyo2);
735
736l0 = mNL-mWSzL-mOffL;
737if (l0 < 0) l0 = 0;
738if (l1 < l0) l1 = l0;
739if (++l2 > mNL-mOffL) l2 =  mNL-mOffL;
740
741for(l=l1; l<l2; l++) {
742 y = (l-l0+1)*mFHaut+dy;
743 k = 0;   x = dx;
744 for(j=0; j<mNC; j++) {
745   if (mAtt[mLPo[l]+j] != lva) {
746     if (k > 0) {
747       mStrBuf[k] = '\0';     
748       g->DrawOpaqueString(x, y, mStrBuf);
749       //     printf("l,J,K=%d %d %d - X,Y= %d %d - %s \n", l,j,k,x,y,mStrBuf);
750       x += k*mFLarg;  k = 0; 
751       }
752     lva = mAtt[mLPo[l]+j];
753     cfnt = lva & 15;   //  Index de fonte
754     ccol = lva >> 4;   //  Index de couleur
755     fgc = col[ccol];
756     if (cfnt & PIVA_Select) 
757       { bgc = PI_Grey;   g->SelFont(mFTaille, vafat[cfnt-PIVA_Select]); }
758     else { bgc = dbgc; g->SelFont(mFTaille, vafat[cfnt]); }
759     
760     if (cfnt & PIVA_Reverse) { 
761       g->SelForeground(bgc);
762       g->SelBackground(fgc);
763       }
764     else  { 
765       g->SelForeground(fgc);
766       g->SelBackground(bgc);
767       }
768     }
769   mStrBuf[k] = mText[mLPo[l]+j];
770   k++;
771   }
772   if (k > 0) {
773     mStrBuf[k] = '\0';     
774     g->DrawOpaqueString(x, y, mStrBuf);
775     //     printf("l,J,K=%d %d %d - X,Y= %d %d - %s \n", l,j,k,x,y,mStrBuf);
776   }
777 }
778
779g->SelForeground(fgc);
780g->SelBackground(dbgc);
781return;
782}
783
784/* --Methode-- */
785void PIConsole::UpdCmdLine()
786{
787//  char strg[260];  debug
788int l1,l2;
789l1 = l2 = mNL-1;
790if (mOffL != 0)  // Decalage d'affichage precedant -> Tout rafraichir
791  { l1 = mNL-mWSzL-1; l2 = mNL-1;  SetDispOffset(-1); }
792
793ClearLine(mNL-1);
794int j1,j2,j,jj2;
795j1 = strlen(mPrompt);
796for(j=0; j<j1; j++) {
797  mText[mLPo[mNL-1]+j] = mPrompt[j];
798  mAtt[mLPo[mNL-1]+j] = PIVA_Def;
799//  strg[j] = mPrompt[j];    debug
800  } 
801jj2 = mWSzC-j1;
802if (mDCOff>=mCCP) mDCOff = 0;
803int koff = ((mCCP-mDCOff) >= jj2) ? mCCP-(jj2/2) : mDCOff;
804mDCOff = koff;
805int kmx = mCLC-koff;
806j2 = j1+kmx;
807if (j2 > mWSzC)  j2 = mWSzC;
808int k = koff;
809for(j=j1; j<j2; j++) {
810  mText[mLPo[mNL-1]+j] = mCmdStr[k];
811  mAtt[mLPo[mNL-1]+j] = PIVA_Bold;
812//  strg[j] = mCmdStr[k];   debug
813  k++;
814  } 
815
816// strg[j] = '\0';   Debug
817// printf("UpdCmdLine() %d %d - %s (%d) \n [%d %d %d] %d\n", koff,kmx,strg,j1+mCCP-koff, mWSzC, j1, jj2, mCCP-(jj2/2));
818mAtt[mLPo[mNL-1]+j1+mCCP-koff] = PIVA_Reverse;    // Pour le curseur
819DisplayLines(mWGrC, l1, l2);
820}
821
822/* --Methode-- */
823void PIConsole::ClrCmd() 
824{ 
825mCCP = 0; mCLC = 0; mDCOff = 0;
826mCmdStr[0] = '\0'; 
827} 
828
829/* --Methode-- */
830void PIConsole::SendCmd() 
831{ 
832  mCmdStr[mCLC] = '\0';
833  //      printf("Keyb()-Debug- <CR/Enter> CmdStr= %s (L=%d)\n", mCmdStr, strlen(mCmdStr) );
834  // Gestion de rappel des commandes
835  if (mCLC > 0) {
836    mRStr[mRCindx] = mCmdStr;
837    mRCindx++;  mNComm++;
838    if (mRCindx >= NMxRecall)  mRCindx = 0;
839    mRindx = mRCindx;
840  }
841  mChangeFg = false;
842  mCmd = mCmdStr;
843  ClrCmd();
844  Send( Msg(), PIMsg_OK, NULL);
845  return;
846}
847
848/* --Methode-- */
849void PIConsole::CmdAddChar(int key)
850{
851  int k, kmx;
852  if ( (mCCP < CmdStrLen) && isprint(key) ) {   // Ajout de caracteres
853    if (mCCP < mCLC)  { // Insertion au milieu de la chaine
854      kmx = (mCLC < CmdStrLen) ? mCLC : CmdStrLen-1;
855      //      printf(" ++DBG++ C=%d L=%d MX=%d KMX=%d\n", mCCP, mCLC, CmdStrLen,kmx);
856      for(k=kmx; k>mCCP; k--) mCmdStr[k] = mCmdStr[k-1];   mCLC = kmx+1;     
857      }
858    mCmdStr[mCCP] = key;  mCCP++; 
859    if (mCCP > mCLC)  mCLC = mCCP;
860    mChangeFg = true;
861    }
862}
863
864
865/* --Methode-- */
866void PIConsole::SelFgBgCol(PIColors fc, PIColors bc)
867{
868mFgC = fc; mBgC = bc;
869SetBackgroundColor(bc);
870}
871
872
873/* --Methode-- */
874void PIConsole::SaveSelection()
875{
876int i,j,k,l;
877int l1, l2, nl, nc;
878
879if (mCPbeginC > mCPendC) { j = mCPbeginC; mCPbeginC = mCPendC ; mCPendC = j; }
880if (mCPbeginL > mCPendL) { j = mCPbeginL; mCPbeginL = mCPendL ; mCPendL = j; }
881
882nc = (mCPendC-mCPbeginC)/mFLarg;
883nl = (mCPendL-mCPbeginL)/mFHaut;
884if (nl < 1) nl = 1;  // On selectionne au moins une ligne
885// printf("*DBG* NC=%d NL=%d \n",nc, nl);
886l1 = mNL+1; l2 = -1;
887
888if (mCPBuffer) {
889  delete[] mCPBuffer; 
890  mCPBuffer = NULL;
891  mCPBufLen = 0;
892  for(i=0; i<mNL; i++)   // On enleve le bit select a tous les caracteres
893    for(j=0; j<mNC; j++) 
894      if ( mAtt[mLPo[i]+j] & PIVA_Select) {
895        if (l1 > i)  l1 = i;
896        if (l2 < i)  l2 = i;
897        mAtt[mLPo[i]+j] &= ~PIVA_Select ;
898      }
899  }
900
901// printf("**DBG** Save: C= %d %d  L = %d %d \n", mCPbeginC, mCPendC, mCPbeginL, mCPendL);
902
903
904// On transforme la position sur la fenetre en position en caracteres ds les buffers
905
906mCPbeginC = mCPbeginC/mFLarg-1;
907mCPendC = (int) ( (float)mCPendC/(float)mFLarg-0.8 );
908mCPbeginL = (int) ( (float)mCPbeginL/(float)mFHaut-0.5 ) ;
909mCPendL = (int) ( (float)mCPendL/(float)mFHaut-0.5 ) ;
910if (mCPendL <= mCPbeginL) mCPendL = mCPbeginL+1;  // Au moins une ligne selectionnee
911// printf("..DBG.. C= %d %d  L = %d %d ", mCPbeginC, mCPendC, mCPbeginL, mCPendL);
912j = mNL-mWSzL-mOffL;
913mCPbeginL += j;  mCPendL += j;
914// printf(" -> %d %d \n", mCPbeginL, mCPendL);
915
916if (mCPbeginC < 0) mCPbeginC = 0;
917if (mCPendC > mNC) mCPendC = mNC;
918if (mCPbeginL < 0) mCPbeginL = 0;
919if (mCPendL > mNL) mCPendL = mNL;
920
921if ( (nc > 0) && (nl > 0) ) {
922if (!ClaimSelection()) { 
923  mCPbeginC = mCPendC = -1;
924  mCPbeginL = mCPendL = -1;
925  if (l2 > -1) DisplayLines(mWGrC, l1, l2); 
926  return;
927  }
928  l = (mCPendC-mCPbeginC+1) * (mCPendL-mCPbeginL);
929  if (l < 0) l = 0;
930  mCPBufLen = l;
931  mCPBuffer = new char[l+1]; 
932  k = 0; 
933  for(j=mCPbeginL; j<mCPendL; j++) { 
934    for(i=mCPbeginC; i<mCPendC; i++)  { 
935      mAtt[mLPo[j]+i] |= PIVA_Select;
936      mCPBuffer[k] = mText[mLPo[j]+i]; k++; 
937      }
938    if (j<mCPendL-1) { mCPBuffer[k] = '\n'; k++; }
939    else mCPBuffer[k] =  '\0';
940    }
941  mCPBuffer[l] = '\0';
942  if (l1 > mCPbeginL) l1 = mCPbeginL;
943  if (l2 < (mCPendL-1))  l2 = mCPendL-1;
944  }
945else { 
946  l = 0;   
947  mCPbeginC =  mCPendC = mCPbeginL = mCPendL = -1; 
948  mCPBufLen = 0;
949  mCPBuffer = new char[10]; 
950  mCPBuffer[0] = mCPBuffer[1] = '\0';
951  }
952
953//  printf("*DBG* Save_Display %d %d \n", l1, l2);
954
955if (l2 > -1) DisplayLines(mWGrC, l1, l2);
956}
957
958/* --Methode-- */
959void PIConsole::Process(PIMessage msg, PIMsgHandler* sender, void* data)
960{
961int off;
962// printf("PIConsole::Process() UserMsg()= %d ModMsg= %d \n", (int)UserMsg(msg),
963//        (int)ModMsg(msg) );
964
965if (sender == opmc) { // Menu des options
966  bool fgr = true;
967  switch (UserMsg(msg)) {
968    case 3101 :
969      SelectFont(PI_SmallSizeFont);
970      AutoSize();
971      break;
972    case 3102 :
973      SelectFont(PI_NormalSizeFont);
974      AutoSize();
975      break;
976    case 3103 :
977      SelectFont(PI_LargeSizeFont);
978      AutoSize();
979      break;
980    case 3201 :
981      SelFgBgCol(PI_Black, PI_White);
982      break;
983    case 3202 :
984      SelFgBgCol(PI_White, PI_Black);
985      break;
986    case 3203 :
987      SelFgBgCol(PI_Yellow, PI_Black);
988      break;
989    case 3301 :
990      AutoSize(25, 132);
991      break;
992    case 3302 :
993      AutoSize(20, 80);
994      break;
995    case 3303 :
996      AutoSize(10, 80);
997      break;     
998    case 3304 :
999      AutoSize(5, 60);
1000      break;     
1001    default :
1002      fgr = false;
1003      break;
1004    }
1005  if (fgr) Refresh();
1006  delete opmc;  opmc = NULL;
1007  }
1008// Le traitement du scroll-bar
1009else if (((ModMsg(msg) == PIMsg_DataChanged) || 
1010          (ModMsg(msg) == PIMsg_Drag) ) && (UserMsg(msg) == msgScb) ) {
1011  off = * ((int *)data);
1012//  printf(" PIConsole::Process() From ScrollBar : Off=%d \n ", off);
1013  SetDispOffset(off);
1014  Refresh();
1015  }
1016// Sinon, on retranmet le message
1017else ReSend(msg, sender, data); 
1018}
1019
Note: See TracBrowser for help on using the repository browser.