summaryrefslogtreecommitdiff
authorjosef <josef>2002-10-28 09:47:21 (UTC)
committer josef <josef>2002-10-28 09:47:21 (UTC)
commit54b9d51694242a1f2e0c1898b05c56114827ca10 (patch) (unidiff)
tree8352d4a219d2547a87662206e4dccb6f1d36f907
parent33834e447ef1313da826c64c6c09953eb3502b69 (diff)
downloadopie-54b9d51694242a1f2e0c1898b05c56114827ca10.zip
opie-54b9d51694242a1f2e0c1898b05c56114827ca10.tar.gz
opie-54b9d51694242a1f2e0c1898b05c56114827ca10.tar.bz2
- ugh, showstopper:
Display is one character wider than expected. While changing this, also replace 40 with vcolumns - dcolumns, so 120 chars etc. could now also be used (once there is a config option for this)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/TEWidget.cpp26
1 files changed, 15 insertions, 11 deletions
diff --git a/noncore/apps/opie-console/TEWidget.cpp b/noncore/apps/opie-console/TEWidget.cpp
index 1c83710..3d010cb 100644
--- a/noncore/apps/opie-console/TEWidget.cpp
+++ b/noncore/apps/opie-console/TEWidget.cpp
@@ -387,974 +387,978 @@ TEWidget::~TEWidget()
387 387
388/* ------------------------------------------------------------------------- */ 388/* ------------------------------------------------------------------------- */
389/* */ 389/* */
390/* Display Operations */ 390/* Display Operations */
391/* */ 391/* */
392/* ------------------------------------------------------------------------- */ 392/* ------------------------------------------------------------------------- */
393 393
394/*! 394/*!
395 attributed string draw primitive 395 attributed string draw primitive
396*/ 396*/
397 397
398void TEWidget::drawAttrStr(QPainter &paint, QRect rect, 398void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
399 QString& str, ca attr, BOOL pm, BOOL clear) 399 QString& str, ca attr, BOOL pm, BOOL clear)
400{ 400{
401 if (pm && color_table[attr.b].transparent) 401 if (pm && color_table[attr.b].transparent)
402 { 402 {
403 paint.setBackgroundMode( TransparentMode ); 403 paint.setBackgroundMode( TransparentMode );
404 if (clear) erase(rect); 404 if (clear) erase(rect);
405 } 405 }
406 else 406 else
407 { 407 {
408 if (blinking) 408 if (blinking)
409 paint.fillRect(rect, color_table[attr.b].color); 409 paint.fillRect(rect, color_table[attr.b].color);
410 else 410 else
411 { 411 {
412 paint.setBackgroundMode( OpaqueMode ); 412 paint.setBackgroundMode( OpaqueMode );
413 paint.setBackgroundColor( color_table[attr.b].color ); 413 paint.setBackgroundColor( color_table[attr.b].color );
414 } 414 }
415 } 415 }
416 416
417 if (color_table[attr.f].bold) 417 if (color_table[attr.f].bold)
418 paint.setPen(QColor( 0x8F, 0x00, 0x00 )); 418 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
419 else 419 else
420 paint.setPen(color_table[attr.f].color); 420 paint.setPen(color_table[attr.f].color);
421 421
422 paint.drawText(rect.x(),rect.y()+font_a, str); 422 paint.drawText(rect.x(),rect.y()+font_a, str);
423 423
424 if (attr.r & RE_UNDERLINE) 424 if (attr.r & RE_UNDERLINE)
425 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); 425 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
426} 426}
427 427
428/*! 428/*!
429 The image can only be set completely. 429 The image can only be set completely.
430 430
431 The size of the new image may or may not match the size of the widget. 431 The size of the new image may or may not match the size of the widget.
432*/ 432*/
433 433
434void TEWidget::setImage(const ca* const newimg, int lines, int columns) 434void TEWidget::setImage(const ca* const newimg, int lines, int columns)
435{ int y,x,len; 435{ int y,x,len;
436 const QPixmap* pm = backgroundPixmap(); 436 const QPixmap* pm = backgroundPixmap();
437 QPainter paint; 437 QPainter paint;
438 setUpdatesEnabled(FALSE); 438 setUpdatesEnabled(FALSE);
439 paint.begin( this ); 439 paint.begin( this );
440HCNT("setImage"); 440HCNT("setImage");
441 441
442 QPoint tL = contentsRect().topLeft(); 442 QPoint tL = contentsRect().topLeft();
443 int tLx = tL.x(); 443 int tLx = tL.x();
444 int tLy = tL.y(); 444 int tLy = tL.y();
445 hasBlinker = FALSE; 445 hasBlinker = FALSE;
446 446
447 int cf = -1; // undefined 447 int cf = -1; // undefined
448 int cb = -1; // undefined 448 int cb = -1; // undefined
449 int cr = -1; // undefined 449 int cr = -1; // undefined
450 450
451 int lins = QMIN(this->lines, QMAX(0,lines )); 451 int lins = QMIN(this->lines, QMAX(0,lines ));
452 int cols = QMIN(this->columns,QMAX(0,columns)); 452 int cols = QMIN(this->columns,QMAX(0,columns));
453 QChar *disstrU = new QChar[cols]; 453 QChar *disstrU = new QChar[cols];
454 454
455//{ static int cnt = 0; printf("setImage %d\n",cnt++); } 455//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
456 for (y = 0; y < lins; y++) 456 for (y = 0; y < lins; y++)
457 { 457 {
458 const ca* lcl = &image[y*this->columns]; 458 const ca* lcl = &image[y*this->columns];
459 const ca* const ext = &newimg[y*columns]; 459 const ca* const ext = &newimg[y*columns];
460 if (!resizing) // not while resizing, we're expecting a paintEvent 460 if (!resizing) // not while resizing, we're expecting a paintEvent
461 for (x = 0; x < cols; x++) 461 for (x = 0; x < cols; x++)
462 { 462 {
463 hasBlinker |= (ext[x].r & RE_BLINK); 463 hasBlinker |= (ext[x].r & RE_BLINK);
464 if (ext[x] != lcl[x]) 464 if (ext[x] != lcl[x])
465 { 465 {
466 cr = ext[x].r; 466 cr = ext[x].r;
467 cb = ext[x].b; 467 cb = ext[x].b;
468 if (ext[x].f != cf) cf = ext[x].f; 468 if (ext[x].f != cf) cf = ext[x].f;
469 int lln = cols - x; 469 int lln = cols - x;
470 disstrU[0] = fontMap(ext[x+0].c); 470 disstrU[0] = fontMap(ext[x+0].c);
471 for (len = 1; len < lln; len++) 471 for (len = 1; len < lln; len++)
472 { 472 {
473 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || 473 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
474 ext[x+len] == lcl[x+len] ) 474 ext[x+len] == lcl[x+len] )
475 break; 475 break;
476 disstrU[len] = fontMap(ext[x+len].c); 476 disstrU[len] = fontMap(ext[x+len].c);
477 } 477 }
478 QString unistr(disstrU,len); 478 QString unistr(disstrU,len);
479 drawAttrStr(paint, 479 drawAttrStr(paint,
480 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 480 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
481 unistr, ext[x], pm != NULL, true); 481 unistr, ext[x], pm != NULL, true);
482 x += len - 1; 482 x += len - 1;
483 } 483 }
484 } 484 }
485 // finally, make `image' become `newimg'. 485 // finally, make `image' become `newimg'.
486 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca)); 486 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
487 } 487 }
488 drawFrame( &paint ); 488 drawFrame( &paint );
489 paint.end(); 489 paint.end();
490 setUpdatesEnabled(TRUE); 490 setUpdatesEnabled(TRUE);
491 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms 491 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
492 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; } 492 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
493 delete [] disstrU; 493 delete [] disstrU;
494} 494}
495 495
496// paint Event //////////////////////////////////////////////////// 496// paint Event ////////////////////////////////////////////////////
497 497
498/*! 498/*!
499 The difference of this routine vs. the `setImage' is, 499 The difference of this routine vs. the `setImage' is,
500 that the drawing does not include a difference analysis 500 that the drawing does not include a difference analysis
501 between the old and the new image. Instead, the internal 501 between the old and the new image. Instead, the internal
502 image is used and the painting bound by the PaintEvent box. 502 image is used and the painting bound by the PaintEvent box.
503*/ 503*/
504 504
505void TEWidget::paintEvent( QPaintEvent* pe ) 505void TEWidget::paintEvent( QPaintEvent* pe )
506{ 506{
507 507
508//{ static int cnt = 0; printf("paint %d\n",cnt++); } 508//{ static int cnt = 0; printf("paint %d\n",cnt++); }
509 const QPixmap* pm = backgroundPixmap(); 509 const QPixmap* pm = backgroundPixmap();
510 QPainter paint; 510 QPainter paint;
511 setUpdatesEnabled(FALSE); 511 setUpdatesEnabled(FALSE);
512 paint.begin( this ); 512 paint.begin( this );
513 paint.setBackgroundMode( TransparentMode ); 513 paint.setBackgroundMode( TransparentMode );
514HCNT("paintEvent"); 514HCNT("paintEvent");
515 515
516 // Note that the actual widget size can be slightly larger 516 // Note that the actual widget size can be slightly larger
517 // that the image (the size is truncated towards the smaller 517 // that the image (the size is truncated towards the smaller
518 // number of characters in `resizeEvent'. The paint rectangle 518 // number of characters in `resizeEvent'. The paint rectangle
519 // can thus be larger than the image, but less then the size 519 // can thus be larger than the image, but less then the size
520 // of one character. 520 // of one character.
521 521
522 QRect rect = pe->rect().intersect(contentsRect()); 522 QRect rect = pe->rect().intersect(contentsRect());
523 523
524 QPoint tL = contentsRect().topLeft(); 524 QPoint tL = contentsRect().topLeft();
525 int tLx = tL.x(); 525 int tLx = tL.x();
526 int tLy = tL.y(); 526 int tLy = tL.y();
527 527
528 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w)); 528 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
529 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h)); 529 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
530 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w)); 530 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
531 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h)); 531 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
532 532
533 /* 533 /*
534 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly, 534 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
535 rect.left(), rect.right(), rect.top(), rect.bottom()); 535 rect.left(), rect.right(), rect.top(), rect.bottom());
536 */ 536 */
537 537
538 // if (pm != NULL && color_table[image->b].transparent) 538 // if (pm != NULL && color_table[image->b].transparent)
539 // erase(rect); 539 // erase(rect);
540 // BL: I have no idea why we need this, and it breaks the refresh. 540 // BL: I have no idea why we need this, and it breaks the refresh.
541 541
542 QChar *disstrU = new QChar[columns]; 542 QChar *disstrU = new QChar[columns];
543 for (int y = luy; y <= rly; y++) 543 for (int y = luy; y <= rly; y++)
544 for (int x = lux; x <= rlx; x++) 544 for (int x = lux; x <= rlx; x++)
545 { 545 {
546 int len = 1; 546 int len = 1;
547 disstrU[0] = fontMap(image[loc(x,y)].c); 547 disstrU[0] = fontMap(image[loc(x,y)].c);
548 int cf = image[loc(x,y)].f; 548 int cf = image[loc(x,y)].f;
549 int cb = image[loc(x,y)].b; 549 int cb = image[loc(x,y)].b;
550 int cr = image[loc(x,y)].r; 550 int cr = image[loc(x,y)].r;
551 while (x+len <= rlx && 551 while (x+len <= rlx &&
552 image[loc(x+len,y)].f == cf && 552 image[loc(x+len,y)].f == cf &&
553 image[loc(x+len,y)].b == cb && 553 image[loc(x+len,y)].b == cb &&
554 image[loc(x+len,y)].r == cr ) 554 image[loc(x+len,y)].r == cr )
555 { 555 {
556 disstrU[len] = fontMap(image[loc(x+len,y)].c); 556 disstrU[len] = fontMap(image[loc(x+len,y)].c);
557 len += 1; 557 len += 1;
558 } 558 }
559 QString unistr(disstrU,len); 559 QString unistr(disstrU,len);
560 drawAttrStr(paint, 560 drawAttrStr(paint,
561 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 561 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
562 unistr, image[loc(x,y)], pm != NULL, false); 562 unistr, image[loc(x,y)], pm != NULL, false);
563 x += len - 1; 563 x += len - 1;
564 } 564 }
565 delete [] disstrU; 565 delete [] disstrU;
566 drawFrame( &paint ); 566 drawFrame( &paint );
567 paint.end(); 567 paint.end();
568 setUpdatesEnabled(TRUE); 568 setUpdatesEnabled(TRUE);
569} 569}
570 570
571void TEWidget::blinkEvent() 571void TEWidget::blinkEvent()
572{ 572{
573 blinking = !blinking; 573 blinking = !blinking;
574 repaint(FALSE); 574 repaint(FALSE);
575} 575}
576 576
577/* ------------------------------------------------------------------------- */ 577/* ------------------------------------------------------------------------- */
578/* */ 578/* */
579/* Resizing */ 579/* Resizing */
580/* */ 580/* */
581/* ------------------------------------------------------------------------- */ 581/* ------------------------------------------------------------------------- */
582 582
583void TEWidget::resizeEvent(QResizeEvent* ev) 583void TEWidget::resizeEvent(QResizeEvent* ev)
584{ 584{
585// printf("resize: %d,%d\n",ev->size().width(),ev->size().height()); 585// printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
586 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h); 586 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
587 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h); 587 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
588 //printf("curren: %d,%d\n",width(),height()); 588 //printf("curren: %d,%d\n",width(),height());
589HCNT("resizeEvent"); 589HCNT("resizeEvent");
590 590
591 // see comment in `paintEvent' concerning the rounding. 591 // see comment in `paintEvent' concerning the rounding.
592 //FIXME: could make a routine here; check width(),height() 592 //FIXME: could make a routine here; check width(),height()
593 assert(ev->size().width() == width()); 593 assert(ev->size().width() == width());
594 assert(ev->size().height() == height()); 594 assert(ev->size().height() == height());
595 595
596 propagateSize(); 596 propagateSize();
597} 597}
598 598
599void TEWidget::propagateSize() 599void TEWidget::propagateSize()
600{ 600{
601 ca* oldimg = image; 601 ca* oldimg = image;
602 int oldlin = lines; 602 int oldlin = lines;
603 int oldcol = columns; 603 int oldcol = columns;
604 makeImage(); 604 makeImage();
605 // we copy the old image to reduce flicker 605 // we copy the old image to reduce flicker
606 int lins = QMIN(oldlin,lines); 606 int lins = QMIN(oldlin,lines);
607 int cols = QMIN(oldcol,columns); 607 int cols = QMIN(oldcol,columns);
608 if (oldimg) 608 if (oldimg)
609 { 609 {
610 for (int lin = 0; lin < lins; lin++) 610 for (int lin = 0; lin < lins; lin++)
611 memcpy((void*)&image[columns*lin], 611 memcpy((void*)&image[columns*lin],
612 (void*)&oldimg[oldcol*lin],cols*sizeof(ca)); 612 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
613 free(oldimg); //FIXME: try new,delete 613 free(oldimg); //FIXME: try new,delete
614 } 614 }
615 else 615 else
616 clearImage(); 616 clearImage();
617 617
618 //NOTE: control flows from the back through the chest right into the eye. 618 //NOTE: control flows from the back through the chest right into the eye.
619 // `emu' will call back via `setImage'. 619 // `emu' will call back via `setImage'.
620 620
621 resizing = TRUE; 621 resizing = TRUE;
622 emit changedImageSizeSignal(lines, columns); // expose resizeEvent 622 emit changedImageSizeSignal(lines, columns); // expose resizeEvent
623 resizing = FALSE; 623 resizing = FALSE;
624} 624}
625 625
626/* ------------------------------------------------------------------------- */ 626/* ------------------------------------------------------------------------- */
627/* */ 627/* */
628/* Scrollbar */ 628/* Scrollbar */
629/* */ 629/* */
630/* ------------------------------------------------------------------------- */ 630/* ------------------------------------------------------------------------- */
631 631
632void TEWidget::scrollChanged(int) 632void TEWidget::scrollChanged(int)
633{ 633{
634 emit changedHistoryCursor(scrollbar->value()); //expose 634 emit changedHistoryCursor(scrollbar->value()); //expose
635} 635}
636 636
637void TEWidget::hscrollChanged(int loc) 637void TEWidget::hscrollChanged(int loc)
638{ 638{
639 hposition = loc; 639 hposition = loc;
640 propagateSize(); 640 propagateSize();
641 update(); 641 update();
642} 642}
643 643
644void TEWidget::setScroll(int cursor, int slines) 644void TEWidget::setScroll(int cursor, int slines)
645{ 645{
646 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 646 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
647 scrollbar->setRange(0,slines); 647 scrollbar->setRange(0,slines);
648 scrollbar->setSteps(1,lines); 648 scrollbar->setSteps(1,lines);
649 scrollbar->setValue(cursor); 649 scrollbar->setValue(cursor);
650 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 650 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
651} 651}
652 652
653void TEWidget::setScrollbarLocation(int loc) 653void TEWidget::setScrollbarLocation(int loc)
654{ 654{
655 if (scrollLoc == loc) return; // quickly 655 if (scrollLoc == loc) return; // quickly
656 scrollLoc = loc; 656 scrollLoc = loc;
657 propagateSize(); 657 propagateSize();
658 update(); 658 update();
659} 659}
660 660
661/* ------------------------------------------------------------------------- */ 661/* ------------------------------------------------------------------------- */
662/* */ 662/* */
663/* Mouse */ 663/* Mouse */
664/* */ 664/* */
665/* ------------------------------------------------------------------------- */ 665/* ------------------------------------------------------------------------- */
666 666
667/*! 667/*!
668 Three different operations can be performed using the mouse, and the 668 Three different operations can be performed using the mouse, and the
669 routines in this section serve all of them: 669 routines in this section serve all of them:
670 670
671 1) The press/release events are exposed to the application 671 1) The press/release events are exposed to the application
672 2) Marking (press and move left button) and Pasting (press middle button) 672 2) Marking (press and move left button) and Pasting (press middle button)
673 3) The right mouse button is used from the configuration menu 673 3) The right mouse button is used from the configuration menu
674 674
675 NOTE: During the marking process we attempt to keep the cursor within 675 NOTE: During the marking process we attempt to keep the cursor within
676 the bounds of the text as being displayed by setting the mouse position 676 the bounds of the text as being displayed by setting the mouse position
677 whenever the mouse has left the text area. 677 whenever the mouse has left the text area.
678 678
679 Two reasons to do so: 679 Two reasons to do so:
680 1) QT does not allow the `grabMouse' to confine-to the TEWidget. 680 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
681 Thus a `XGrapPointer' would have to be used instead. 681 Thus a `XGrapPointer' would have to be used instead.
682 2) Even if so, this would not help too much, since the text area 682 2) Even if so, this would not help too much, since the text area
683 of the TEWidget is normally not identical with it's bounds. 683 of the TEWidget is normally not identical with it's bounds.
684 684
685 The disadvantage of the current handling is, that the mouse can visibly 685 The disadvantage of the current handling is, that the mouse can visibly
686 leave the bounds of the widget and is then moved back. Because of the 686 leave the bounds of the widget and is then moved back. Because of the
687 current construction, and the reasons mentioned above, we cannot do better 687 current construction, and the reasons mentioned above, we cannot do better
688 without changing the overall construction. 688 without changing the overall construction.
689*/ 689*/
690 690
691/*! 691/*!
692*/ 692*/
693 693
694void TEWidget::mousePressEvent(QMouseEvent* ev) 694void TEWidget::mousePressEvent(QMouseEvent* ev)
695{ 695{
696//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 696//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
697 if ( !contentsRect().contains(ev->pos()) ) return; 697 if ( !contentsRect().contains(ev->pos()) ) return;
698 QPoint tL = contentsRect().topLeft(); 698 QPoint tL = contentsRect().topLeft();
699 int tLx = tL.x(); 699 int tLx = tL.x();
700 int tLy = tL.y(); 700 int tLy = tL.y();
701 701
702 word_selection_mode = FALSE; 702 word_selection_mode = FALSE;
703 703
704//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY); 704//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
705 if ( ev->button() == LeftButton) 705 if ( ev->button() == LeftButton)
706 { 706 {
707 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 707 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
708 708
709 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ; 709 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
710 710
711 if (mouse_marks || (ev->state() & ShiftButton)) 711 if (mouse_marks || (ev->state() & ShiftButton))
712 { 712 {
713 emit clearSelectionSignal(); 713 emit clearSelectionSignal();
714 iPntSel = pntSel = pos; 714 iPntSel = pntSel = pos;
715 actSel = 1; // left mouse button pressed but nothing selected yet. 715 actSel = 1; // left mouse button pressed but nothing selected yet.
716 grabMouse( /*crossCursor*/ ); // handle with care! 716 grabMouse( /*crossCursor*/ ); // handle with care!
717 } 717 }
718 else 718 else
719 { 719 {
720 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button 720 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
721 } 721 }
722 } 722 }
723 if ( ev->button() == MidButton ) 723 if ( ev->button() == MidButton )
724 { 724 {
725 emitSelection(); 725 emitSelection();
726 } 726 }
727 if ( ev->button() == RightButton ) // Configure 727 if ( ev->button() == RightButton ) // Configure
728 { 728 {
729 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() ); 729 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
730 } 730 }
731} 731}
732 732
733void TEWidget::mouseMoveEvent(QMouseEvent* ev) 733void TEWidget::mouseMoveEvent(QMouseEvent* ev)
734{ 734{
735 // for auto-hiding the cursor, we need mouseTracking 735 // for auto-hiding the cursor, we need mouseTracking
736 if (ev->state() == NoButton ) return; 736 if (ev->state() == NoButton ) return;
737 737
738 if (actSel == 0) return; 738 if (actSel == 0) return;
739 739
740 // don't extend selection while pasting 740 // don't extend selection while pasting
741 if (ev->state() & MidButton) return; 741 if (ev->state() & MidButton) return;
742 742
743 //if ( !contentsRect().contains(ev->pos()) ) return; 743 //if ( !contentsRect().contains(ev->pos()) ) return;
744 QPoint tL = contentsRect().topLeft(); 744 QPoint tL = contentsRect().topLeft();
745 int tLx = tL.x(); 745 int tLx = tL.x();
746 int tLy = tL.y(); 746 int tLy = tL.y();
747 int scroll = scrollbar->value(); 747 int scroll = scrollbar->value();
748 748
749 // we're in the process of moving the mouse with the left button pressed 749 // we're in the process of moving the mouse with the left button pressed
750 // the mouse cursor will kept catched within the bounds of the text in 750 // the mouse cursor will kept catched within the bounds of the text in
751 // this widget. 751 // this widget.
752 752
753 // Adjust position within text area bounds. See FIXME above. 753 // Adjust position within text area bounds. See FIXME above.
754 QPoint pos = ev->pos(); 754 QPoint pos = ev->pos();
755 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX ); 755 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
756 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w ); 756 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
757 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY ); 757 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
758 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 ); 758 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
759 // check if we produce a mouse move event by this 759 // check if we produce a mouse move event by this
760 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos)); 760 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
761 761
762 if ( pos.y() == tLy+bY+lines*font_h-1 ) 762 if ( pos.y() == tLy+bY+lines*font_h-1 )
763 { 763 {
764 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward 764 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
765 } 765 }
766 if ( pos.y() == tLy+bY ) 766 if ( pos.y() == tLy+bY )
767 { 767 {
768 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback 768 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
769 } 769 }
770 770
771 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); 771 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
772 QPoint ohere; 772 QPoint ohere;
773 bool swapping = FALSE; 773 bool swapping = FALSE;
774 774
775 if ( word_selection_mode ) 775 if ( word_selection_mode )
776 { 776 {
777 // Extend to word boundaries 777 // Extend to word boundaries
778 int i; 778 int i;
779 int selClass; 779 int selClass;
780 780
781 bool left_not_right = ( here.y() < iPntSel.y() || 781 bool left_not_right = ( here.y() < iPntSel.y() ||
782 here.y() == iPntSel.y() && here.x() < iPntSel.x() ); 782 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
783 bool old_left_not_right = ( pntSel.y() < iPntSel.y() || 783 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
784 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); 784 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
785 swapping = left_not_right != old_left_not_right; 785 swapping = left_not_right != old_left_not_right;
786 786
787 // Find left (left_not_right ? from here : from start) 787 // Find left (left_not_right ? from here : from start)
788 QPoint left = left_not_right ? here : iPntSel; 788 QPoint left = left_not_right ? here : iPntSel;
789 i = loc(left.x(),left.y()); 789 i = loc(left.x(),left.y());
790 selClass = charClass(image[i].c); 790 selClass = charClass(image[i].c);
791 while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) 791 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
792 { i--; left.rx()--; } 792 { i--; left.rx()--; }
793 793
794 // Find left (left_not_right ? from start : from here) 794 // Find left (left_not_right ? from start : from here)
795 QPoint right = left_not_right ? iPntSel : here; 795 QPoint right = left_not_right ? iPntSel : here;
796 i = loc(right.x(),right.y()); 796 i = loc(right.x(),right.y());
797 selClass = charClass(image[i].c); 797 selClass = charClass(image[i].c);
798 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) 798 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
799 { i++; right.rx()++; } 799 { i++; right.rx()++; }
800 800
801 // Pick which is start (ohere) and which is extension (here) 801 // Pick which is start (ohere) and which is extension (here)
802 if ( left_not_right ) 802 if ( left_not_right )
803 { 803 {
804 here = left; ohere = right; 804 here = left; ohere = right;
805 } 805 }
806 else 806 else
807 { 807 {
808 here = right; ohere = left; 808 here = right; ohere = left;
809 } 809 }
810 } 810 }
811 811
812 if (here == pntSel && scroll == scrollbar->value()) return; // not moved 812 if (here == pntSel && scroll == scrollbar->value()) return; // not moved
813 813
814 if ( word_selection_mode ) { 814 if ( word_selection_mode ) {
815 if ( actSel < 2 || swapping ) { 815 if ( actSel < 2 || swapping ) {
816 emit beginSelectionSignal( ohere.x(), ohere.y() ); 816 emit beginSelectionSignal( ohere.x(), ohere.y() );
817 } 817 }
818 } else if ( actSel < 2 ) { 818 } else if ( actSel < 2 ) {
819 emit beginSelectionSignal( pntSel.x(), pntSel.y() ); 819 emit beginSelectionSignal( pntSel.x(), pntSel.y() );
820 } 820 }
821 821
822 actSel = 2; // within selection 822 actSel = 2; // within selection
823 pntSel = here; 823 pntSel = here;
824 emit extendSelectionSignal( here.x(), here.y() ); 824 emit extendSelectionSignal( here.x(), here.y() );
825} 825}
826 826
827void TEWidget::mouseReleaseEvent(QMouseEvent* ev) 827void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
828{ 828{
829//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 829//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
830 if ( ev->button() == LeftButton) 830 if ( ev->button() == LeftButton)
831 { 831 {
832 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks); 832 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
833 preserve_line_breaks = TRUE; 833 preserve_line_breaks = TRUE;
834 actSel = 0; 834 actSel = 0;
835 835
836 //FIXME: emits a release event even if the mouse is 836 //FIXME: emits a release event even if the mouse is
837 // outside the range. The procedure used in `mouseMoveEvent' 837 // outside the range. The procedure used in `mouseMoveEvent'
838 // applies here, too. 838 // applies here, too.
839 839
840 QPoint tL = contentsRect().topLeft(); 840 QPoint tL = contentsRect().topLeft();
841 int tLx = tL.x(); 841 int tLx = tL.x();
842 int tLy = tL.y(); 842 int tLy = tL.y();
843 843
844 if (!mouse_marks && !(ev->state() & ShiftButton)) 844 if (!mouse_marks && !(ev->state() & ShiftButton))
845 emit mouseSignal( 3, // release 845 emit mouseSignal( 3, // release
846 (ev->x()-tLx-blX)/font_w + 1, 846 (ev->x()-tLx-blX)/font_w + 1,
847 (ev->y()-tLy-bY)/font_h + 1 ); 847 (ev->y()-tLy-bY)/font_h + 1 );
848 releaseMouse(); 848 releaseMouse();
849 } 849 }
850} 850}
851 851
852void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) 852void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
853{ 853{
854 if ( ev->button() != LeftButton) return; 854 if ( ev->button() != LeftButton) return;
855 855
856 QPoint tL = contentsRect().topLeft(); 856 QPoint tL = contentsRect().topLeft();
857 int tLx = tL.x(); 857 int tLx = tL.x();
858 int tLy = tL.y(); 858 int tLy = tL.y();
859 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 859 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
860 860
861 // pass on double click as two clicks. 861 // pass on double click as two clicks.
862 if (!mouse_marks && !(ev->state() & ShiftButton)) 862 if (!mouse_marks && !(ev->state() & ShiftButton))
863 { 863 {
864 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 864 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
865 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release 865 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
866 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button 866 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
867 return; 867 return;
868 } 868 }
869 869
870 870
871 emit clearSelectionSignal(); 871 emit clearSelectionSignal();
872 QPoint bgnSel = pos; 872 QPoint bgnSel = pos;
873 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 873 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
874 int i = loc(bgnSel.x(),bgnSel.y()); 874 int i = loc(bgnSel.x(),bgnSel.y());
875 iPntSel = bgnSel; 875 iPntSel = bgnSel;
876 876
877 word_selection_mode = TRUE; 877 word_selection_mode = TRUE;
878 878
879 // find word boundaries... 879 // find word boundaries...
880 int selClass = charClass(image[i].c); 880 int selClass = charClass(image[i].c);
881 { 881 {
882 // set the start... 882 // set the start...
883 int x = bgnSel.x(); 883 int x = bgnSel.x();
884 while ( x > 0 && charClass(image[i-1].c) == selClass ) 884 while ( x > 0 && charClass(image[i-1].c) == selClass )
885 { i--; x--; } 885 { i--; x--; }
886 bgnSel.setX(x); 886 bgnSel.setX(x);
887 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() ); 887 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
888 888
889 // set the end... 889 // set the end...
890 i = loc( endSel.x(), endSel.y() ); 890 i = loc( endSel.x(), endSel.y() );
891 x = endSel.x(); 891 x = endSel.x();
892 while( x < columns-1 && charClass(image[i+1].c) == selClass ) 892 while( x < columns-1 && charClass(image[i+1].c) == selClass )
893 { i++; x++ ; } 893 { i++; x++ ; }
894 endSel.setX(x); 894 endSel.setX(x);
895 actSel = 2; // within selection 895 actSel = 2; // within selection
896 emit extendSelectionSignal( endSel.x(), endSel.y() ); 896 emit extendSelectionSignal( endSel.x(), endSel.y() );
897 emit endSelectionSignal(preserve_line_breaks); 897 emit endSelectionSignal(preserve_line_breaks);
898 preserve_line_breaks = TRUE; 898 preserve_line_breaks = TRUE;
899 } 899 }
900} 900}
901 901
902void TEWidget::focusInEvent( QFocusEvent * ) 902void TEWidget::focusInEvent( QFocusEvent * )
903{ 903{
904 904
905 // do nothing, to prevent repainting 905 // do nothing, to prevent repainting
906} 906}
907 907
908 908
909void TEWidget::focusOutEvent( QFocusEvent * ) 909void TEWidget::focusOutEvent( QFocusEvent * )
910{ 910{
911 // do nothing, to prevent repainting 911 // do nothing, to prevent repainting
912} 912}
913 913
914bool TEWidget::focusNextPrevChild( bool next ) 914bool TEWidget::focusNextPrevChild( bool next )
915{ 915{
916 if (next) 916 if (next)
917 return false; // This disables changing the active part in konqueror 917 return false; // This disables changing the active part in konqueror
918 // when pressing Tab 918 // when pressing Tab
919 return QFrame::focusNextPrevChild( next ); 919 return QFrame::focusNextPrevChild( next );
920} 920}
921 921
922 922
923int TEWidget::charClass(char ch) const 923int TEWidget::charClass(char ch) const
924{ 924{
925 // This might seem like overkill, but imagine if ch was a Unicode 925 // This might seem like overkill, but imagine if ch was a Unicode
926 // character (Qt 2.0 QChar) - it might then be sensible to separate 926 // character (Qt 2.0 QChar) - it might then be sensible to separate
927 // the different language ranges, etc. 927 // the different language ranges, etc.
928 928
929 if ( isspace(ch) ) return ' '; 929 if ( isspace(ch) ) return ' ';
930 930
931 static const char *word_characters = ":@-./_~"; 931 static const char *word_characters = ":@-./_~";
932 if ( isalnum(ch) || strchr(word_characters, ch) ) 932 if ( isalnum(ch) || strchr(word_characters, ch) )
933 return 'a'; 933 return 'a';
934 934
935 // Everything else is weird 935 // Everything else is weird
936 return 1; 936 return 1;
937} 937}
938 938
939void TEWidget::setMouseMarks(bool on) 939void TEWidget::setMouseMarks(bool on)
940{ 940{
941 mouse_marks = on; 941 mouse_marks = on;
942 setCursor( mouse_marks ? ibeamCursor : arrowCursor ); 942 setCursor( mouse_marks ? ibeamCursor : arrowCursor );
943} 943}
944 944
945/* ------------------------------------------------------------------------- */ 945/* ------------------------------------------------------------------------- */
946/* */ 946/* */
947/* Clipboard */ 947/* Clipboard */
948/* */ 948/* */
949/* ------------------------------------------------------------------------- */ 949/* ------------------------------------------------------------------------- */
950 950
951#undef KeyPress 951#undef KeyPress
952 952
953void TEWidget::emitSelection() 953void TEWidget::emitSelection()
954// Paste Clipboard by simulating keypress events 954// Paste Clipboard by simulating keypress events
955{ 955{
956#ifndef QT_NO_CLIPBOARD 956#ifndef QT_NO_CLIPBOARD
957 QString text = QApplication::clipboard()->text(); 957 QString text = QApplication::clipboard()->text();
958 if ( ! text.isNull() ) 958 if ( ! text.isNull() )
959 { 959 {
960 text.replace(QRegExp("\n"), "\r"); 960 text.replace(QRegExp("\n"), "\r");
961 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 961 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
962 emit keyPressedSignal(&e); // expose as a big fat keypress event 962 emit keyPressedSignal(&e); // expose as a big fat keypress event
963 emit clearSelectionSignal(); 963 emit clearSelectionSignal();
964 } 964 }
965#endif 965#endif
966} 966}
967 967
968void TEWidget::emitText(QString text) 968void TEWidget::emitText(QString text)
969{ 969{
970 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 970 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
971 emit keyPressedSignal(&e); // expose as a big fat keypress event 971 emit keyPressedSignal(&e); // expose as a big fat keypress event
972} 972}
973 973
974void TEWidget::pasteClipboard( ) 974void TEWidget::pasteClipboard( )
975{ 975{
976 emitSelection(); 976 emitSelection();
977} 977}
978 978
979void TEWidget::setSelection(const QString& t) 979void TEWidget::setSelection(const QString& t)
980{ 980{
981#ifndef QT_NO_CLIPBOARD 981#ifndef QT_NO_CLIPBOARD
982 // Disconnect signal while WE set the clipboard 982 // Disconnect signal while WE set the clipboard
983 QObject *cb = QApplication::clipboard(); 983 QObject *cb = QApplication::clipboard();
984 QObject::disconnect( cb, SIGNAL(dataChanged()), 984 QObject::disconnect( cb, SIGNAL(dataChanged()),
985 this, SLOT(onClearSelection()) ); 985 this, SLOT(onClearSelection()) );
986 986
987 QApplication::clipboard()->setText(t); 987 QApplication::clipboard()->setText(t);
988 988
989 QObject::connect( cb, SIGNAL(dataChanged()), 989 QObject::connect( cb, SIGNAL(dataChanged()),
990 this, SLOT(onClearSelection()) ); 990 this, SLOT(onClearSelection()) );
991#endif 991#endif
992} 992}
993 993
994void TEWidget::onClearSelection() 994void TEWidget::onClearSelection()
995{ 995{
996 emit clearSelectionSignal(); 996 emit clearSelectionSignal();
997} 997}
998 998
999/* ------------------------------------------------------------------------- */ 999/* ------------------------------------------------------------------------- */
1000/* */ 1000/* */
1001/* Keyboard */ 1001/* Keyboard */
1002/* */ 1002/* */
1003/* ------------------------------------------------------------------------- */ 1003/* ------------------------------------------------------------------------- */
1004 1004
1005//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent' 1005//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
1006// due to a bug in `QT' or the ignorance of the author to prevent 1006// due to a bug in `QT' or the ignorance of the author to prevent
1007// repaint events being emitted to the screen whenever one leaves 1007// repaint events being emitted to the screen whenever one leaves
1008// or reenters the screen to/from another application. 1008// or reenters the screen to/from another application.
1009// 1009//
1010// Troll says one needs to change focusInEvent() and focusOutEvent(), 1010// Troll says one needs to change focusInEvent() and focusOutEvent(),
1011// which would also let you have an in-focus cursor and an out-focus 1011// which would also let you have an in-focus cursor and an out-focus
1012// cursor like xterm does. 1012// cursor like xterm does.
1013 1013
1014// for the auto-hide cursor feature, I added empty focusInEvent() and 1014// for the auto-hide cursor feature, I added empty focusInEvent() and
1015// focusOutEvent() so that update() isn't called. 1015// focusOutEvent() so that update() isn't called.
1016// For auto-hide, we need to get keypress-events, but we only get them when 1016// For auto-hide, we need to get keypress-events, but we only get them when
1017// we have focus. 1017// we have focus.
1018 1018
1019void TEWidget::doScroll(int lines) 1019void TEWidget::doScroll(int lines)
1020{ 1020{
1021 scrollbar->setValue(scrollbar->value()+lines); 1021 scrollbar->setValue(scrollbar->value()+lines);
1022} 1022}
1023 1023
1024bool TEWidget::eventFilter( QObject *obj, QEvent *e ) 1024bool TEWidget::eventFilter( QObject *obj, QEvent *e )
1025{ 1025{
1026 if ( (e->type() == QEvent::Accel || 1026 if ( (e->type() == QEvent::Accel ||
1027 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) { 1027 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) {
1028 static_cast<QKeyEvent *>( e )->ignore(); 1028 static_cast<QKeyEvent *>( e )->ignore();
1029 return true; 1029 return true;
1030 } 1030 }
1031 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ ) 1031 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
1032 return FALSE; // not us 1032 return FALSE; // not us
1033 if ( e->type() == QEvent::Wheel) { 1033 if ( e->type() == QEvent::Wheel) {
1034 QApplication::sendEvent(scrollbar, e); 1034 QApplication::sendEvent(scrollbar, e);
1035 } 1035 }
1036 1036
1037#ifdef FAKE_CTRL_AND_ALT 1037#ifdef FAKE_CTRL_AND_ALT
1038 static bool control = FALSE; 1038 static bool control = FALSE;
1039 static bool alt = FALSE; 1039 static bool alt = FALSE;
1040// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:"); 1040// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:");
1041 bool dele=FALSE; 1041 bool dele=FALSE;
1042 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { 1042 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
1043 QKeyEvent* ke = (QKeyEvent*)e; 1043 QKeyEvent* ke = (QKeyEvent*)e;
1044 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat(); 1044 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
1045 switch (ke->key()) { 1045 switch (ke->key()) {
1046 case Key_F9: // let this be "Control" 1046 case Key_F9: // let this be "Control"
1047 control = keydown; 1047 control = keydown;
1048 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state()); 1048 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
1049 dele=TRUE; 1049 dele=TRUE;
1050 break; 1050 break;
1051 case Key_F13: // let this be "Alt" 1051 case Key_F13: // let this be "Alt"
1052 alt = keydown; 1052 alt = keydown;
1053 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state()); 1053 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
1054 dele=TRUE; 1054 dele=TRUE;
1055 break; 1055 break;
1056 default: 1056 default:
1057 if ( control ) { 1057 if ( control ) {
1058 int a = toupper(ke->ascii())-64; 1058 int a = toupper(ke->ascii())-64;
1059 if ( a >= 0 && a < ' ' ) { 1059 if ( a >= 0 && a < ' ' ) {
1060 e = new QKeyEvent(e->type(), ke->key(), 1060 e = new QKeyEvent(e->type(), ke->key(),
1061 a, ke->state()|ControlButton, QChar(a,0)); 1061 a, ke->state()|ControlButton, QChar(a,0));
1062 dele=TRUE; 1062 dele=TRUE;
1063 } 1063 }
1064 } 1064 }
1065 if ( alt ) { 1065 if ( alt ) {
1066 e = new QKeyEvent(e->type(), ke->key(), 1066 e = new QKeyEvent(e->type(), ke->key(),
1067 ke->ascii(), ke->state()|AltButton, ke->text()); 1067 ke->ascii(), ke->state()|AltButton, ke->text());
1068 dele=TRUE; 1068 dele=TRUE;
1069 } 1069 }
1070 } 1070 }
1071 } 1071 }
1072#endif 1072#endif
1073 1073
1074 if ( e->type() == QEvent::KeyPress ) { 1074 if ( e->type() == QEvent::KeyPress ) {
1075 QKeyEvent* ke = (QKeyEvent*)e; 1075 QKeyEvent* ke = (QKeyEvent*)e;
1076 actSel=0; // Key stroke implies a screen update, so TEWidget won't 1076 actSel=0; // Key stroke implies a screen update, so TEWidget won't
1077 // know where the current selection is. 1077 // know where the current selection is.
1078 1078
1079// qDebug("key pressed is 0x%x",ke->key()); 1079// qDebug("key pressed is 0x%x",ke->key());
1080 1080
1081 if( ke->state() == ShiftButton && ke->key() == Key_Tab) { //lets hardcode this sucker 1081 if( ke->state() == ShiftButton && ke->key() == Key_Tab) { //lets hardcode this sucker
1082 1082
1083// qDebug("key pressed 2 is 0x%x",ke->key()); 1083// qDebug("key pressed 2 is 0x%x",ke->key());
1084 emitText("\\"); // expose 1084 emitText("\\"); // expose
1085 } else 1085 } else
1086 emit keyPressedSignal(ke); // expose 1086 emit keyPressedSignal(ke); // expose
1087 ke->accept(); 1087 ke->accept();
1088#ifdef FAKE_CTRL_AND_ALT 1088#ifdef FAKE_CTRL_AND_ALT
1089 if ( dele ) delete e; 1089 if ( dele ) delete e;
1090#endif 1090#endif
1091 return true; // stop the event 1091 return true; // stop the event
1092 } 1092 }
1093 if ( e->type() == QEvent::Enter ) { 1093 if ( e->type() == QEvent::Enter ) {
1094 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()), 1094 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
1095 this, SLOT(onClearSelection()) ); 1095 this, SLOT(onClearSelection()) );
1096 } 1096 }
1097 if ( e->type() == QEvent::Leave ) { 1097 if ( e->type() == QEvent::Leave ) {
1098 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 1098 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
1099 this, SLOT(onClearSelection()) ); 1099 this, SLOT(onClearSelection()) );
1100 } 1100 }
1101 return QFrame::eventFilter( obj, e ); 1101 return QFrame::eventFilter( obj, e );
1102} 1102}
1103 1103
1104/* ------------------------------------------------------------------------- */ 1104/* ------------------------------------------------------------------------- */
1105/* */ 1105/* */
1106/* Frame */ 1106/* Frame */
1107/* */ 1107/* */
1108/* ------------------------------------------------------------------------- */ 1108/* ------------------------------------------------------------------------- */
1109 1109
1110void TEWidget::frameChanged() 1110void TEWidget::frameChanged()
1111{ 1111{
1112 propagateSize(); 1112 propagateSize();
1113 update(); 1113 update();
1114} 1114}
1115 1115
1116/* ------------------------------------------------------------------------- */ 1116/* ------------------------------------------------------------------------- */
1117/* */ 1117/* */
1118/* Sound */ 1118/* Sound */
1119/* */ 1119/* */
1120/* ------------------------------------------------------------------------- */ 1120/* ------------------------------------------------------------------------- */
1121 1121
1122void TEWidget::Bell() 1122void TEWidget::Bell()
1123{ 1123{
1124 QApplication::beep(); 1124 QApplication::beep();
1125} 1125}
1126 1126
1127/* ------------------------------------------------------------------------- */ 1127/* ------------------------------------------------------------------------- */
1128/* */ 1128/* */
1129/* Auxiluary */ 1129/* Auxiluary */
1130/* */ 1130/* */
1131/* ------------------------------------------------------------------------- */ 1131/* ------------------------------------------------------------------------- */
1132 1132
1133void TEWidget::clearImage() 1133void TEWidget::clearImage()
1134// initialize the image 1134// initialize the image
1135// for internal use only 1135// for internal use only
1136{ 1136{
1137 for (int y = 0; y < lines; y++) 1137 for (int y = 0; y < lines; y++)
1138 for (int x = 0; x < columns; x++) 1138 for (int x = 0; x < columns; x++)
1139 { 1139 {
1140 image[loc(x,y)].c = 0xff; //' '; 1140 image[loc(x,y)].c = 0xff; //' ';
1141 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR; 1141 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
1142 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR; 1142 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
1143 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION; 1143 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
1144 } 1144 }
1145} 1145}
1146 1146
1147// Create Image /////////////////////////////////////////////////////// 1147// Create Image ///////////////////////////////////////////////////////
1148 1148
1149void TEWidget::calcGeometry() 1149void TEWidget::calcGeometry()
1150{ 1150{
1151 //FIXME: set rimX == rimY == 0 when running in full screen mode. 1151 //FIXME: set rimX == rimY == 0 when running in full screen mode.
1152 1152
1153 int showhscrollbar = 1; 1153 int showhscrollbar = 1;
1154 int hwidth = 0; 1154 int hwidth = 0;
1155 int dcolumns;
1155 1156
1156 if(vcolumns == 0) showhscrollbar = 0; 1157 if(vcolumns == 0) showhscrollbar = 0;
1157 if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width(); 1158 if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width();
1158 1159
1159 scrollbar->resize(QApplication::style().scrollBarExtent().width(), 1160 scrollbar->resize(QApplication::style().scrollBarExtent().width(),
1160 contentsRect().height() - hwidth); 1161 contentsRect().height() - hwidth);
1161 1162
1162 if(!showhscrollbar) cornerButton()->move(0, 0); 1163 if(!showhscrollbar) cornerButton()->move(0, 0);
1163 else cornerButton()->move(contentsRect().width() - hwidth, contentsRect().height() - hwidth); 1164 else cornerButton()->move(contentsRect().width() - hwidth, contentsRect().height() - hwidth);
1164 1165
1165 1166
1166 if(showhscrollbar == 1)
1167 {
1168 hscrollbar->resize(contentsRect().width() - hwidth, hwidth);
1169 hscrollbar->setRange(0, 40);
1170
1171 QPoint p = contentsRect().bottomLeft();
1172 hscrollbar->move(QPoint(p.x(), p.y() - hwidth));
1173 hscrollbar->show();
1174 }
1175 else hscrollbar->hide();
1176
1177 switch(scrollLoc) 1167 switch(scrollLoc)
1178 { 1168 {
1179 case SCRNONE : 1169 case SCRNONE :
1180 columns = ( contentsRect().width() - 2 * rimX ) / font_w; 1170 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1171 dcolumns = columns;
1181 if(vcolumns) columns = vcolumns; 1172 if(vcolumns) columns = vcolumns;
1182 blX = (contentsRect().width() - (columns*font_w) ) / 2; 1173 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1183 if(showhscrollbar) 1174 if(showhscrollbar)
1184 blX = -hposition * font_w; 1175 blX = -hposition * font_w;
1185 brX = blX; 1176 brX = blX;
1186 scrollbar->hide(); 1177 scrollbar->hide();
1187 break; 1178 break;
1188 case SCRLEFT : 1179 case SCRLEFT :
1189 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1180 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1181 dcolumns = columns;
1190 if(vcolumns) columns = vcolumns; 1182 if(vcolumns) columns = vcolumns;
1191 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1183 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1192 if(showhscrollbar) 1184 if(showhscrollbar)
1193 brX = -hposition * font_w; 1185 brX = -hposition * font_w;
1194 blX = brX + scrollbar->width(); 1186 blX = brX + scrollbar->width();
1195 scrollbar->move(contentsRect().topLeft()); 1187 scrollbar->move(contentsRect().topLeft());
1196 scrollbar->show(); 1188 scrollbar->show();
1197 break; 1189 break;
1198 case SCRRIGHT: 1190 case SCRRIGHT:
1199 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1191 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1192 dcolumns = columns;
1200 if(vcolumns) columns = vcolumns; 1193 if(vcolumns) columns = vcolumns;
1201 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1194 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1202 if(showhscrollbar) 1195 if(showhscrollbar)
1203 blX = -hposition * font_w; 1196 blX = -hposition * font_w;
1204 brX = blX; 1197 brX = blX;
1205 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0)); 1198 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
1206 scrollbar->show(); 1199 scrollbar->show();
1207 break; 1200 break;
1208 } 1201 }
1209 //FIXME: support 'rounding' styles 1202 //FIXME: support 'rounding' styles
1210 lines = ( contentsRect().height() - 2 * rimY ) / font_h; 1203 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
1211 bY = (contentsRect().height() - (lines *font_h)) / 2; 1204 bY = (contentsRect().height() - (lines *font_h)) / 2;
1212 1205
1213 if(showhscrollbar == 1) 1206 if(showhscrollbar == 1)
1214 { 1207 {
1208 hscrollbar->resize(contentsRect().width() - hwidth, hwidth);
1209 hscrollbar->setRange(0, vcolumns - dcolumns);
1210
1211 QPoint p = contentsRect().bottomLeft();
1212 hscrollbar->move(QPoint(p.x(), p.y() - hwidth));
1213 hscrollbar->show();
1214 }
1215 else hscrollbar->hide();
1216
1217 if(showhscrollbar == 1)
1218 {
1215 lines = lines - (hwidth / font_h) - 1; 1219 lines = lines - (hwidth / font_h) - 1;
1216 if(lines < 1) lines = 1; 1220 if(lines < 1) lines = 1;
1217 } 1221 }
1218} 1222}
1219 1223
1220void TEWidget::makeImage() 1224void TEWidget::makeImage()
1221//FIXME: rename 'calcGeometry? 1225//FIXME: rename 'calcGeometry?
1222{ 1226{
1223 calcGeometry(); 1227 calcGeometry();
1224 image = (ca*) malloc(lines*columns*sizeof(ca)); 1228 image = (ca*) malloc(lines*columns*sizeof(ca));
1225 clearImage(); 1229 clearImage();
1226} 1230}
1227 1231
1228// calculate the needed size 1232// calculate the needed size
1229QSize TEWidget::calcSize(int cols, int lins) const 1233QSize TEWidget::calcSize(int cols, int lins) const
1230{ 1234{
1231 int frw = width() - contentsRect().width(); 1235 int frw = width() - contentsRect().width();
1232 int frh = height() - contentsRect().height(); 1236 int frh = height() - contentsRect().height();
1233 int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); 1237 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
1234 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh ); 1238 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
1235} 1239}
1236 1240
1237QSize TEWidget::sizeHint() const 1241QSize TEWidget::sizeHint() const
1238{ 1242{
1239 return size(); 1243 return size();
1240} 1244}
1241 1245
1242void TEWidget::styleChange(QStyle &) 1246void TEWidget::styleChange(QStyle &)
1243{ 1247{
1244 propagateSize(); 1248 propagateSize();
1245} 1249}
1246 1250
1247#ifndef QT_NO_DRAGANDDROP 1251#ifndef QT_NO_DRAGANDDROP
1248 1252
1249/* --------------------------------------------------------------------- */ 1253/* --------------------------------------------------------------------- */
1250/* */ 1254/* */
1251/* Drag & Drop */ 1255/* Drag & Drop */
1252/* */ 1256/* */
1253/* --------------------------------------------------------------------- */ 1257/* --------------------------------------------------------------------- */
1254 1258
1255 1259
1256void TEWidget::dragEnterEvent(QDragEnterEvent* e) 1260void TEWidget::dragEnterEvent(QDragEnterEvent* e)
1257{ 1261{
1258 e->accept(QTextDrag::canDecode(e) || 1262 e->accept(QTextDrag::canDecode(e) ||
1259 QUriDrag::canDecode(e)); 1263 QUriDrag::canDecode(e));
1260} 1264}
1261 1265
1262void TEWidget::dropEvent(QDropEvent* event) 1266void TEWidget::dropEvent(QDropEvent* event)
1263{ 1267{
1264 // The current behaviour when url(s) are dropped is 1268 // The current behaviour when url(s) are dropped is
1265 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd 1269 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
1266 // * in all other cases, just paste 1270 // * in all other cases, just paste
1267 // (for non-local ones, or for a list of URLs, 'cd' is nonsense) 1271 // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
1268 QStrList strlist; 1272 QStrList strlist;
1269 int file_count = 0; 1273 int file_count = 0;
1270 dropText = ""; 1274 dropText = "";
1271 bool bPopup = true; 1275 bool bPopup = true;
1272 1276
1273 if(QUriDrag::decode(event, strlist)) { 1277 if(QUriDrag::decode(event, strlist)) {
1274 if (strlist.count()) { 1278 if (strlist.count()) {
1275 for(const char* p = strlist.first(); p; p = strlist.next()) { 1279 for(const char* p = strlist.first(); p; p = strlist.next()) {
1276 if(file_count++ > 0) { 1280 if(file_count++ > 0) {
1277 dropText += " "; 1281 dropText += " ";
1278 bPopup = false; // more than one file, don't popup 1282 bPopup = false; // more than one file, don't popup
1279 } 1283 }
1280 1284
1281/* 1285/*
1282 KURL url(p); 1286 KURL url(p);
1283 if (url.isLocalFile()) { 1287 if (url.isLocalFile()) {
1284 dropText += url.path(); // local URL : remove protocol 1288 dropText += url.path(); // local URL : remove protocol
1285 } 1289 }
1286 else { 1290 else {
1287 dropText += url.prettyURL(); 1291 dropText += url.prettyURL();
1288 bPopup = false; // a non-local file, don't popup 1292 bPopup = false; // a non-local file, don't popup
1289 } 1293 }
1290*/ 1294*/
1291 1295
1292 } 1296 }
1293 1297
1294 if (bPopup) 1298 if (bPopup)
1295 // m_drop->popup(pos() + event->pos()); 1299 // m_drop->popup(pos() + event->pos());
1296 m_drop->popup(mapToGlobal(event->pos())); 1300 m_drop->popup(mapToGlobal(event->pos()));
1297 else 1301 else
1298 { 1302 {
1299 if (currentSession) { 1303 if (currentSession) {
1300 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1304 currentSession->getEmulation()->sendString(dropText.local8Bit());
1301 } 1305 }
1302// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1306// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1303 } 1307 }
1304 } 1308 }
1305 } 1309 }
1306 else if(QTextDrag::decode(event, dropText)) { 1310 else if(QTextDrag::decode(event, dropText)) {
1307// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1311// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1308 if (currentSession) { 1312 if (currentSession) {
1309 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1313 currentSession->getEmulation()->sendString(dropText.local8Bit());
1310 } 1314 }
1311 // Paste it 1315 // Paste it
1312 } 1316 }
1313} 1317}
1314#endif 1318#endif
1315 1319
1316 1320
1317void TEWidget::drop_menu_activated(int) 1321void TEWidget::drop_menu_activated(int)
1318{ 1322{
1319#ifndef QT_NO_DRAGANDDROP 1323#ifndef QT_NO_DRAGANDDROP
1320 switch (item) 1324 switch (item)
1321 { 1325 {
1322 case 0: // paste 1326 case 0: // paste
1323 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1327 currentSession->getEmulation()->sendString(dropText.local8Bit());
1324// KWM::activate((Window)this->winId()); 1328// KWM::activate((Window)this->winId());
1325 break; 1329 break;
1326 case 1: // cd ... 1330 case 1: // cd ...
1327 currentSession->getEmulation()->sendString("cd "); 1331 currentSession->getEmulation()->sendString("cd ");
1328 struct stat statbuf; 1332 struct stat statbuf;
1329 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 ) 1333 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
1330 { 1334 {
1331 if ( !S_ISDIR(statbuf.st_mode) ) 1335 if ( !S_ISDIR(statbuf.st_mode) )
1332 { 1336 {
1333/* 1337/*
1334 KURL url; 1338 KURL url;
1335 url.setPath( dropText ); 1339 url.setPath( dropText );
1336 dropText = url.directory( true, false ); // remove filename 1340 dropText = url.directory( true, false ); // remove filename
1337*/ 1341*/
1338 } 1342 }
1339 } 1343 }
1340 dropText.replace(QRegExp(" "), "\\ "); // escape spaces 1344 dropText.replace(QRegExp(" "), "\\ "); // escape spaces
1341 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1345 currentSession->getEmulation()->sendString(dropText.local8Bit());
1342 currentSession->getEmulation()->sendString("\n"); 1346 currentSession->getEmulation()->sendString("\n");
1343// KWM::activate((Window)this->winId()); 1347// KWM::activate((Window)this->winId());
1344 break; 1348 break;
1345 } 1349 }
1346#endif 1350#endif
1347} 1351}
1348 1352
1349QPushButton* TEWidget::cornerButton() { 1353QPushButton* TEWidget::cornerButton() {
1350 return m_cornerButton; 1354 return m_cornerButton;
1351} 1355}
1352 1356
1353void TEWidget::setWrapAt(int columns) 1357void TEWidget::setWrapAt(int columns)
1354{ 1358{
1355 vcolumns = columns; 1359 vcolumns = columns;
1356 propagateSize(); 1360 propagateSize();
1357 update(); 1361 update();
1358} 1362}
1359 1363
1360 1364