]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiWorkArea.C
comment out debug statement.
[lyx.git] / src / frontends / qt4 / GuiWorkArea.C
index a01f8ecbea63e7ee75e434594c2d67bd9ccb2df9..1cd967474168e7963d768b32e3cfbe8dd41dc84b 100644 (file)
 #include "QLyXKeySym.h"
 #include "qt_helpers.h"
 
+#include "gettext.h"
 #include "LyXView.h"
 
 #include "BufferView.h"
+#include "rowpainter.h"
 #include "debug.h"
 #include "funcrequest.h"
 #include "LColor.h"
+#include "version.h"
+#include "lyxrc.h"
 
+#include "support/filetools.h" // LibFileSearch
 #include "support/os.h"
+#include "support/convert.h"
+
+#include "graphics/GraphicsImage.h"
+#include "graphics/GraphicsLoader.h"
 
 #include <QLayout>
 #include <QMainWindow>
 #include <QMimeData>
 #include <QUrl>
 #include <QDragEnterEvent>
-#include <QPixmap>
 #include <QPainter>
 #include <QScrollBar>
 
 #include <boost/bind.hpp>
 #include <boost/current_function.hpp>
 
-// Abdel (26/06/2006):
-// On windows-XP the UserGuide PageDown scroll test is faster without event pruning (16 s)
-// than with it (23 s).
 #ifdef Q_WS_WIN
- #define USE_EVENT_PRUNING 0
+int const CursorWidth = 2;
 #else
- #define USE_EVENT_PRUNING 0
+int const CursorWidth = 1;
 #endif
 
+
 using std::endl;
 using std::string;
 
 namespace os = lyx::support::os;
 
+
 namespace lyx {
 
+using support::FileName;
+
 /// return the LyX key state from Qt's
 static key_modifier::state q_key_state(Qt::KeyboardModifiers state)
 {
@@ -90,8 +99,8 @@ static mouse_button::state q_button_state(Qt::MouseButton button)
 }
 
 
-/// retddurn the LyX mouse button state from Qt's
-mouse_button::state q_motion_state(Qt::MouseButton state)
+/// return the LyX mouse button state from Qt's
+mouse_button::state q_motion_state(Qt::MouseButtons state)
 {
        mouse_button::state b = mouse_button::none;
        if (state & Qt::LeftButton)
@@ -106,6 +115,41 @@ mouse_button::state q_motion_state(Qt::MouseButton state)
 
 namespace frontend {
 
+class CursorWidget {
+public:
+       CursorWidget() {}
+
+       void draw(QPainter & painter)
+       {
+               // FIXME: do something depending on the cursor shape.
+               if (show_ && rect_.isValid())
+                       painter.fillRect(rect_, color_);
+       }
+
+       void update(int x, int y, int h, CursorShape shape)
+       {
+               color_ = guiApp->colorCache().get(LColor::cursor);
+               rect_ = QRect(x, y, CursorWidth, h);
+               shape_ = shape;
+       }
+
+       void show(bool set_show = true) { show_ = set_show; }
+       void hide() { show_ = false; }
+
+       QRect const & rect() { return rect_; }
+
+private:
+       ///
+       CursorShape shape_;
+       ///
+       bool show_;
+       ///
+       QColor color_;
+       ///
+       QRect rect_;
+};
+
+
 // This is a 'heartbeat' generating synthetic mouse move events when the
 // cursor is at the top or bottom edge of the viewport. One scroll per 0.2 s
 SyntheticMouseEvent::SyntheticMouseEvent()
@@ -114,18 +158,23 @@ SyntheticMouseEvent::SyntheticMouseEvent()
 {}
 
 
-GuiWorkArea::GuiWorkArea(int w, int h, LyXView & lyx_view)
-       : WorkArea(lyx_view), painter_(this)
+GuiWorkArea::GuiWorkArea(int w, int h, int id, LyXView & lyx_view)
+       : WorkArea(id, lyx_view)
 {
-       setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-       setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+       cursor_ = new frontend::CursorWidget();
+       cursor_->hide();
 
+       setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+       setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setAcceptDrops(true);
-
+       setMouseTracking(true);
        setMinimumSize(100, 70);
 
        viewport()->setAutoFillBackground(false);
-       viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
+       // We don't need double-buffering nor SystemBackground on
+       // the viewport because we have our own backing pixmap.
+       viewport()->setAttribute(Qt::WA_NoSystemBackground);
+
        setFocusPolicy(Qt::WheelFocus);
 
        viewport()->setCursor(Qt::IBeamCursor);
@@ -150,33 +199,17 @@ GuiWorkArea::GuiWorkArea(int w, int h, LyXView & lyx_view)
                << "\n viewport height\t" << viewport()->height()
                << endl;
 
-       if (USE_EVENT_PRUNING) {
-               // This is the keyboard buffering stuff...
-               // I don't see any need for this under windows. The keyboard is reactive
-               // enough...
-
-               if ( !QObject::connect(&step_timer_, SIGNAL(timeout()),
-                       this, SLOT(keyeventTimeout())) )
-                       lyxerr[Debug::GUI] << "ERROR: keyeventTimeout cannot connect!" << endl;
-
-               // Start the timer, one-shot.
-               step_timer_.setSingleShot(true);
-               step_timer_.start(50);
-       }
-
        // Enables input methods for asian languages.
        // Must be set when creating custom text editing widgets.
        setAttribute(Qt::WA_InputMethodEnabled, true);
 }
 
 
-GuiWorkArea::~GuiWorkArea()
-{
-}
-
-
 void GuiWorkArea::setScrollbarParams(int h, int scroll_pos, int scroll_line_step)
 {
+       if (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOn)
+               setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+
        verticalScrollBar()->setTracking(false);
 
        // do what cursor movement does (some grey)
@@ -186,6 +219,7 @@ void GuiWorkArea::setScrollbarParams(int h, int scroll_pos, int scroll_line_step
        verticalScrollBar()->setRange(0, scroll_max_);
        verticalScrollBar()->setSliderPosition(scroll_pos);
        verticalScrollBar()->setSingleStep(scroll_line_step);
+       verticalScrollBar()->setValue(scroll_pos);
 
        verticalScrollBar()->setTracking(true);
 }
@@ -222,6 +256,28 @@ void GuiWorkArea::dropEvent(QDropEvent* event)
 }
 
 
+void GuiWorkArea::focusInEvent(QFocusEvent * /*event*/)
+{
+       // No need to do anything if we didn't change views...
+//     if (theApp() == 0 || &lyx_view_ == theApp()->currentView())
+//             return;
+
+       theApp()->setCurrentView(lyx_view_);
+
+       // FIXME: it would be better to send a signal "newBuffer()"
+       // in BufferList that could be connected to the different tabbars.
+       lyx_view_.updateTab();
+
+       startBlinkingCursor();
+}
+
+
+void GuiWorkArea::focusOutEvent(QFocusEvent * /*event*/)
+{
+       stopBlinkingCursor();
+}
+
+
 void GuiWorkArea::mousePressEvent(QMouseEvent * e)
 {
        if (dc_event_.active && dc_event_ == *e) {
@@ -253,7 +309,7 @@ void GuiWorkArea::mouseReleaseEvent(QMouseEvent * e)
 void GuiWorkArea::mouseMoveEvent(QMouseEvent * e)
 {
        FuncRequest cmd(LFUN_MOUSE_MOTION, e->x(), e->y(),
-                             q_motion_state(e->button()));
+                             q_motion_state(e->buttons()));
 
        // If we're above or below the work area...
        if (e->y() <= 20 || e->y() >= viewport()->height() - 20) {
@@ -350,51 +406,9 @@ void GuiWorkArea::keyPressEvent(QKeyEvent * e)
                << " key=" << e->key()
                << endl;
 
-       if (USE_EVENT_PRUNING) {
-               keyeventQueue_.push(boost::shared_ptr<QKeyEvent>(new QKeyEvent(*e)));
-       }
-       else {
-               boost::shared_ptr<QLyXKeySym> sym(new QLyXKeySym);
-               sym->set(e);
-               processKeySym(sym, q_key_state(e->modifiers()));
-       }
-}
-
-
-// This is used only if USE_EVENT_PRUNING is defined...
-void GuiWorkArea::keyeventTimeout()
-{
-       bool handle_autos = true;
-
-       while (!keyeventQueue_.empty()) {
-               boost::shared_ptr<QKeyEvent> ev = keyeventQueue_.front();
-
-               // We never handle more than one auto repeated
-               // char in a list of queued up events.
-               if (!handle_autos && ev->isAutoRepeat()) {
-                       keyeventQueue_.pop();
-                       continue;
-               }
-
-               boost::shared_ptr<QLyXKeySym> sym(new QLyXKeySym);
-               sym->set(ev.get());
-
-               lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION
-                                  << " count=" << ev->count()
-                                  << " text=" <<  fromqstr(ev->text())
-                                  << " isAutoRepeat=" << ev->isAutoRepeat()
-                                  << " key=" << ev->key()
-                                  << endl;
-
-               processKeySym(sym, q_key_state(ev->modifiers()));
-               keyeventQueue_.pop();
-
-               handle_autos = false;
-       }
-
-       // Restart the timer.
-       step_timer_.setSingleShot(true);
-       step_timer_.start(25);
+       boost::shared_ptr<QLyXKeySym> sym(new QLyXKeySym);
+       sym->set(e);
+       processKeySym(sym, q_key_state(e->modifiers()));
 }
 
 
@@ -414,11 +428,14 @@ void GuiWorkArea::mouseDoubleClickEvent(QMouseEvent * e)
 }
 
 
-void GuiWorkArea::resizeEvent(QResizeEvent *)
+void GuiWorkArea::resizeEvent(QResizeEvent * ev)
 {
+       stopBlinkingCursor();
+       screen_ = QPixmap(ev->size().width(), ev->size().height());
        verticalScrollBar()->setPageStep(viewport()->height());
-       paint_device_ = QPixmap(viewport()->width(), viewport()->height());
+       QAbstractScrollArea::resizeEvent(ev);
        resizeBufferView();
+       startBlinkingCursor();
 }
 
 
@@ -428,127 +445,98 @@ void GuiWorkArea::update(int x, int y, int w, int h)
 }
 
 
-void GuiWorkArea::paintEvent(QPaintEvent * e)
+void GuiWorkArea::doGreyOut(QLPainter & pain)
 {
-       /*
-       lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION
-               << "\n QWidget width\t" << this->width()
-               << "\n QWidget height\t" << this->height()
-               << "\n viewport width\t" << viewport()->width()
-               << "\n viewport height\t" << viewport()->height()
-               << "\n pixmap width\t" << pixmap_->width()
-               << "\n pixmap height\t" << pixmap_->height()
-               << "\n QPaintEvent x\t" << e->rect().x()
-               << "\n QPaintEvent y\t" << e->rect().y()
-               << "\n QPaintEvent w\t" << e->rect().width()
-               << "\n QPaintEvent h\t" << e->rect().height()
-               << endl;
-       */
+       setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+       pain.fillRectangle(0, 0, width(), height(),
+               LColor::bottomarea);
+
+       //if (!lyxrc.show_banner)
+       //      return;
+       lyxerr[Debug::GUI] << "show banner: " << lyxrc.show_banner << endl;
+       /// The text to be written on top of the pixmap
+       QString const text = lyx_version ? QString(lyx_version) : qt_("unknown version");
+       FileName const file = support::libFileSearch("images", "banner", "ppm");
+       if (file.empty())
+               return;
 
-       QPainter q(viewport());
-       q.drawPixmap(e->rect(), paint_device_, e->rect());
+       QPixmap pm(toqstr(file.absFilename()));
+       if (!pm) {
+               lyxerr << "could not load splash screen: '" << file << "'" << endl;
+               return;
+       }
 
-       if (show_vcursor_)
-               q.drawPixmap(cursor_x_, cursor_y_, vcursor_);
+       QFont font;
+       // The font used to display the version info
+       font.setStyleHint(QFont::SansSerif);
+       font.setWeight(QFont::Bold);
+       font.setPointSize(convert<int>(lyxrc.font_sizes[LyXFont::SIZE_LARGE]));
 
-       if (show_hcursor_)
-               q.drawPixmap(cursor_x_, cursor_y_ + cursor_h_ - 1, hcursor_);
-}
+       int const w = pm.width();
+       int const h = pm.height();
 
+       int x = (width() - w) / 2;
+       int y = (height() - h) / 2;
 
-QPixmap GuiWorkArea::copyScreen(int x, int y, int w, int h) const
-{
-       return paint_device_.copy(x, y, w, h);
-}
+       pain.drawPixmap(x, y, pm);
 
+       x += 300;
+       y += 265;
 
-void GuiWorkArea::drawScreen(int x, int y, QPixmap pixmap)
-{
-       QPainter q(&paint_device_);
-       q.drawPixmap(x, y, pixmap);
-       update(x, y, pixmap.width(), pixmap.height());
+       pain.setPen(QColor(255, 255, 0));
+       pain.setFont(font);
+       pain.drawText(x, y, text);
 }
 
 
-void GuiWorkArea::expose(int x, int y, int w, int h)
+void GuiWorkArea::paintEvent(QPaintEvent * ev)
 {
+       QRect const rc = ev->rect(); 
        /*
-       if (x == 0 && y == 0 && w == viewport()->width() && h == viewport()->height()) {
-               viewport()->repaint(x, y, w, h);
-               return;
-       }
+       lyxerr[Debug::PAINTING] << "paintEvent begin: x: " << rc.x()
+               << " y: " << rc.y()
+               << " w: " << rc.width()
+               << " h: " << rc.height() << endl;
        */
 
-       update(x, y, w, h);
+       QPainter pain(viewport());
+       pain.drawPixmap(rc, screen_, rc);
+       cursor_->draw(pain);
 }
 
 
-void GuiWorkArea::showCursor(int x, int y, int h, CursorShape shape)
+void GuiWorkArea::expose(int x, int y, int w, int h)
 {
-       if (!qApp->focusWidget())
-               return;
-
-       show_vcursor_ = true;
+       QLPainter pain(&screen_);
 
-       QColor const & required_color = guiApp->colorCache().get(LColor::cursor);
-
-       if (x==cursor_x_ && y==cursor_y_ && h==cursor_h_
-               && cursor_color_ == required_color
-               && cursor_shape_ == shape) {
-               show_hcursor_ = lshape_cursor_;
-               update(cursor_x_, cursor_y_, cursor_w_, cursor_h_);
+       if (greyed_out_) {
+               lyxerr[Debug::GUI] << "splash screen requested" << endl;
+               doGreyOut(pain);
+               verticalScrollBar()->hide();
+               update(0, 0, width(), height());
                return;
        }
 
-       // Cache the dimensions of the cursor.
-       cursor_x_ = x;
-       cursor_y_ = y;
-       cursor_h_ = h;
-       cursor_color_ = required_color;
-       cursor_shape_ = shape;
-
-       switch (cursor_shape_) {
-       case BAR_SHAPE:
-               // FIXME the cursor width shouldn't be hard-coded!
-               cursor_w_ = 2;
-               lshape_cursor_ = false;
-               break;
-       case L_SHAPE:
-               cursor_w_ = cursor_h_ / 3;
-               lshape_cursor_ = true;
-               break;
-       case REVERSED_L_SHAPE:
-               cursor_w_ = cursor_h_ / 3;
-               cursor_x_ -= cursor_w_ - 1;
-               lshape_cursor_ = true;
-               break;
-       }
-
-       // We cache two pixmaps:
-       // 1 the vertical line of the cursor.
-       // 2 the horizontal line of the L-shaped cursor (if necessary).
-
-       // Draw the new (vertical) cursor.
-       vcursor_ = QPixmap(cursor_w_, cursor_h_);
-       vcursor_.fill(cursor_color_);
+       verticalScrollBar()->show();
+       paintText(*buffer_view_, pain);
+       update(x, y, w, h);
+}
 
-       // Draw the new (horizontal) cursor if necessary.
-       if (lshape_cursor_) {
-               hcursor_ = QPixmap(cursor_w_, 1);
-               hcursor_.fill(cursor_color_);
-               show_hcursor_ = true;
-       }
 
-       update(cursor_x_, cursor_y_, cursor_w_, cursor_h_);
+void GuiWorkArea::showCursor(int x, int y, int h, CursorShape shape)
+{
+       cursor_->update(x, y, h, shape);
+       cursor_->show();
+       viewport()->update(cursor_->rect());
 }
 
 
 void GuiWorkArea::removeCursor()
 {
-       show_vcursor_ = false;
-       show_hcursor_ = false;
-
-       update(cursor_x_, cursor_y_, cursor_w_, cursor_h_);
+       cursor_->hide();
+       //if (!qApp->focusWidget())
+               viewport()->update(cursor_->rect());
 }
 
 
@@ -569,8 +557,7 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
                        key = Qt::Key_AsciiCircum;
                // FIXME: Needs for investigation, this key is not really used,
                // the ctor below just check if key is different from 0.
-               QKeyEvent ev(QEvent::KeyPress, key,
-                       Qt::NoModifier, text);
+               QKeyEvent ev(QEvent::KeyPress, key, Qt::NoModifier, text);
                keyPressEvent(&ev);
        }
        e->accept();