// -*- C++ -*-
/**
- * \file key_state.h
+ * \file KeyModifier.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
/// modifier key states
enum KeyModifier {
- NoModifier = 0, //< no modifiers held
+ NoModifier = 0, //< no modifiers held
ControlModifier = 1, //< control button held
- AltModifier = 2, //< alt/meta key held
- ShiftModifier = 4 //< shift key held
+ AltModifier = 2, //< alt/meta key held
+ ShiftModifier = 4 //< shift key held
};
} // namespace lyx
-#endif // KEY_STATE_H
+#endif // KEYMODIFIER_H
Clipboard.h \
Gui.h \
Selection.h \
- WorkArea.cpp \
WorkArea.h \
WorkAreaManager.cpp \
WorkAreaManager.h \
+++ /dev/null
-/**
- * \file WorkArea.cpp
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author John Levon
- * \author Abdelrazak Younes
- *
- * Full author contact details are available in file CREDITS.
- *
- * Splash screen code added by Angus Leeming
- */
-
-#include <config.h>
-
-#include "frontends/WorkArea.h"
-
-#include "frontends/Application.h"
-#include "frontends/Dialogs.h"
-#include "frontends/FontMetrics.h"
-#include "frontends/LyXView.h"
-#include "frontends/WorkAreaManager.h"
-
-#include "BufferView.h"
-#include "Buffer.h"
-#include "BufferParams.h"
-#include "CoordCache.h"
-#include "Cursor.h"
-#include "debug.h"
-#include "Font.h"
-#include "FuncRequest.h"
-#include "KeySymbol.h"
-#include "Language.h"
-#include "LyXFunc.h"
-#include "LyXRC.h"
-#include "MetricsInfo.h"
-
-#include "gettext.h"
-#include "support/FileName.h"
-#include "support/filetools.h"
-#include "support/ForkedcallsController.h"
-
-#include <boost/noncopyable.hpp>
-#include <boost/bind.hpp>
-#include <boost/current_function.hpp>
-
-using std::endl;
-using std::min;
-using std::max;
-using std::string;
-
-
-namespace {
-
-// All the below connection objects are needed because of a bug in some
-// versions of GCC (<=2.96 are on the suspects list.) By having and assigning
-// to these connections we avoid a segfault upon startup, and also at exit.
-// (Lgb)
-
-boost::signals::connection timecon;
-
-} // anon namespace
-
-namespace lyx {
-
-using support::ForkedcallsController;
-using support::makeDisplayPath;
-using support::onlyFilename;
-
-namespace frontend {
-
-WorkArea::WorkArea(Buffer & buffer, LyXView & lv)
- : buffer_view_(new BufferView(buffer)), lyx_view_(&lv),
- cursor_visible_(false), cursor_timeout_(400)
-{
- buffer.workAreaManager().add(this);
- // Setup the signals
- timecon = cursor_timeout_.timeout
- .connect(boost::bind(&WorkArea::toggleCursor, this));
-
- cursor_timeout_.start();
-}
-
-
-WorkArea::~WorkArea()
-{
- buffer_view_->buffer().workAreaManager().remove(this);
- delete buffer_view_;
-}
-
-
-void WorkArea::close()
-{
- lyx_view_->removeWorkArea(this);
-}
-
-//void WorkArea::setLyXView(LyXView * lyx_view)
-//{
-// lyx_view_ = lyx_view;
-//}
-
-
-BufferView & WorkArea::bufferView()
-{
- return *buffer_view_;
-}
-
-
-BufferView const & WorkArea::bufferView() const
-{
- return *buffer_view_;
-}
-
-
-void WorkArea::stopBlinkingCursor()
-{
- cursor_timeout_.stop();
- hideCursor();
-}
-
-
-void WorkArea::startBlinkingCursor()
-{
- showCursor();
- cursor_timeout_.restart();
-}
-
-
-void WorkArea::redraw()
-{
- if (!isVisible())
- // No need to redraw in this case.
- return;
-
- // No need to do anything if this is the current view. The BufferView
- // metrics are already up to date.
- if (lyx_view_ != theApp()->currentView()) {
- // FIXME: it would be nice to optimize for the off-screen case.
- buffer_view_->updateMetrics();
- buffer_view_->cursor().fixIfBroken();
- }
-
- updateScrollbar();
-
- // update cursor position, because otherwise it has to wait until
- // the blinking interval is over
- if (cursor_visible_) {
- hideCursor();
- showCursor();
- }
-
- ViewMetricsInfo const & vi = buffer_view_->viewMetricsInfo();
-
- LYXERR(Debug::WORKAREA) << "WorkArea::redraw screen" << endl;
-
- int const ymin = std::max(vi.y1, 0);
- int const ymax = vi.p2 < vi.size - 1 ? vi.y2 : height();
-
- expose(0, ymin, width(), ymax - ymin);
-
- //LYXERR(Debug::WORKAREA)
- //<< " ymin = " << ymin << " width() = " << width()
-// << " ymax-ymin = " << ymax-ymin << std::endl;
-
- if (lyxerr.debugging(Debug::WORKAREA))
- buffer_view_->coordCache().dump();
-}
-
-
-void WorkArea::processKeySym(KeySymbol const & key, KeyModifier mod)
-{
- // In order to avoid bad surprise in the middle of an operation, we better stop
- // the blinking cursor.
- stopBlinkingCursor();
-
- theLyXFunc().setLyXView(lyx_view_);
- theLyXFunc().processKeySym(key, mod);
-}
-
-
-void WorkArea::dispatch(FuncRequest const & cmd0, KeyModifier mod)
-{
- // Handle drag&drop
- if (cmd0.action == LFUN_FILE_OPEN) {
- lyx_view_->dispatch(cmd0);
- return;
- }
-
- theLyXFunc().setLyXView(lyx_view_);
-
- FuncRequest cmd;
-
- if (cmd0.action == LFUN_MOUSE_PRESS) {
- if (mod == ShiftModifier)
- cmd = FuncRequest(cmd0, "region-select");
- else if (mod == ControlModifier)
- cmd = FuncRequest(cmd0, "paragraph-select");
- else
- cmd = cmd0;
- }
- else
- cmd = cmd0;
-
- // In order to avoid bad surprise in the middle of an operation, we better stop
- // the blinking cursor.
- if (!(cmd.action == LFUN_MOUSE_MOTION
- && cmd.button() == mouse_button::none))
- stopBlinkingCursor();
-
- buffer_view_->mouseEventDispatch(cmd);
-
- // Skip these when selecting
- if (cmd.action != LFUN_MOUSE_MOTION) {
- lyx_view_->updateLayoutChoice(false);
- lyx_view_->updateToolbars();
- }
-
- // GUI tweaks except with mouse motion with no button pressed.
- if (!(cmd.action == LFUN_MOUSE_MOTION
- && cmd.button() == mouse_button::none)) {
- // Slight hack: this is only called currently when we
- // clicked somewhere, so we force through the display
- // of the new status here.
- lyx_view_->clearMessage();
-
- // Show the cursor immediately after any operation.
- startBlinkingCursor();
- }
-}
-
-
-void WorkArea::resizeBufferView()
-{
- // WARNING: Please don't put any code that will trigger a repaint here!
- // We are already inside a paint event.
- lyx_view_->setBusy(true);
- buffer_view_->resize(width(), height());
- lyx_view_->updateLayoutChoice(false);
- lyx_view_->setBusy(false);
-}
-
-
-void WorkArea::updateScrollbar()
-{
- buffer_view_->updateScrollbar();
- ScrollbarParameters const & scroll_ = buffer_view_->scrollbarParameters();
- setScrollbarParams(scroll_.height, scroll_.position,
- scroll_.lineScrollHeight);
-}
-
-
-void WorkArea::showCursor()
-{
- if (cursor_visible_)
- return;
-
- CursorShape shape = BAR_SHAPE;
-
- Font const & realfont = buffer_view_->cursor().real_current_font;
- BufferParams const & bp = buffer_view_->buffer().params();
- bool const samelang = realfont.language() == bp.language;
- bool const isrtl = realfont.isVisibleRightToLeft();
-
- if (!samelang || isrtl != bp.language->rightToLeft()) {
- shape = L_SHAPE;
- if (isrtl)
- shape = REVERSED_L_SHAPE;
- }
-
- // The ERT language hack needs fixing up
- if (realfont.language() == latex_language)
- shape = BAR_SHAPE;
-
- Font const font = buffer_view_->cursor().getFont();
- FontMetrics const & fm = theFontMetrics(font);
- int const asc = fm.maxAscent();
- int const des = fm.maxDescent();
- int h = asc + des;
- int x = 0;
- int y = 0;
- buffer_view_->cursor().getPos(x, y);
- y -= asc;
-
- // if it doesn't touch the screen, don't try to show it
- if (y + h < 0 || y >= height())
- return;
-
- cursor_visible_ = true;
- showCursor(x, y, h, shape);
-}
-
-
-void WorkArea::hideCursor()
-{
- if (!cursor_visible_)
- return;
-
- cursor_visible_ = false;
- removeCursor();
-}
-
-
-void WorkArea::toggleCursor()
-{
- if (cursor_visible_)
- hideCursor();
- else
- showCursor();
-
- // Use this opportunity to deal with any child processes that
- // have finished but are waiting to communicate this fact
- // to the rest of LyX.
- ForkedcallsController & fcc = ForkedcallsController::get();
- fcc.handleCompletedProcesses();
-
- cursor_timeout_.restart();
-}
-
-void WorkArea::updateWindowTitle()
-{
- docstring maximize_title;
- docstring minimize_title;
-
- Buffer & buf = buffer_view_->buffer();
- string const cur_title = buf.absFileName();
- if (!cur_title.empty()) {
- maximize_title = makeDisplayPath(cur_title, 30);
- minimize_title = from_utf8(onlyFilename(cur_title));
- if (!buf.isClean()) {
- maximize_title += _(" (changed)");
- minimize_title += char_type('*');
- }
- if (buf.isReadonly())
- maximize_title += _(" (read only)");
- }
-
- setWindowTitle(maximize_title, minimize_title);
-}
-
-
-void WorkArea::setReadOnly(bool)
-{
- updateWindowTitle();
- if (this == lyx_view_->currentWorkArea())
- lyx_view_->getDialogs().updateBufferDependent(false);
-}
-
-} // namespace frontend
-} // namespace lyx
#define BASE_WORKAREA_H
#include "frontends/KeyModifier.h"
-#include "frontends/Delegates.h"
-
-#include "support/Timeout.h"
-#include "support/docstring.h"
-
-#undef CursorShape
namespace lyx {
-class Buffer;
class BufferView;
-class FuncRequest;
class KeySymbol;
namespace frontend {
class LyXView;
class Painter;
-/// types of cursor in work area
-enum CursorShape {
- /// normal I-beam
- BAR_SHAPE,
- /// L-shape for locked insets of a different language
- L_SHAPE,
- /// reverse L-shape for RTL text
- REVERSED_L_SHAPE
-};
-
/**
* The work area class represents the widget that provides the
* view onto a document. It is owned by the BufferView, and
{
public:
///
- WorkArea(Buffer & buffer, LyXView & lv);
+ WorkArea() {}
virtual ~WorkArea();
///
- void setLyXView(LyXView & lv) { lyx_view_ = &lv; }
+ virtual void setLyXView(LyXView & lv) = 0;
///
- BufferView & bufferView();
+ virtual BufferView & bufferView() = 0;
///
- BufferView const & bufferView() const;
+ virtual BufferView const & bufferView() const = 0;
- /// \return true if has the keyboard input focus.
+ /// return true if has the keyboard input focus.
virtual bool hasFocus() const = 0;
- /// \return true if has this WorkArea is visible.
+ /// return true if has this WorkArea is visible.
virtual bool isVisible() const = 0;
/// return the width of the work area in pixels
virtual void scheduleRedraw() = 0;
/// redraw the screen, without using existing pixmap
- virtual void redraw();
+ virtual void redraw() = 0;
///
- void stopBlinkingCursor();
- void startBlinkingCursor();
+ virtual void stopBlinkingCursor() = 0;
+ virtual void startBlinkingCursor() = 0;
/// Process Key pressed event.
/// This needs to be public because it is accessed externally by GuiView.
- void processKeySym(KeySymbol const & key, KeyModifier mod);
+ virtual void processKeySym(KeySymbol const & key, KeyModifier mod) = 0;
/// close this work area.
/// Slot for Buffer::closing signal.
- void close();
-
+ virtual void close() = 0;
/// This function is called when the buffer readonly status change.
- virtual void setReadOnly(bool);
+ virtual void setReadOnly(bool) = 0;
/// Update window titles of all users.
- virtual void updateWindowTitle();
-
-protected:
- /// cause the display of the given area of the work area
- virtual void expose(int x, int y, int w, int h) = 0;
-
- /// set title of window.
- /**
- * @param t main window title
- * @param it iconified (short) title
- */
- virtual void setWindowTitle(docstring const & t, docstring const & it) = 0;
-
- ///
- void dispatch(FuncRequest const & cmd0, KeyModifier = NoModifier);
-
- ///
- void resizeBufferView();
- /// hide the visible cursor, if it is visible
- void hideCursor();
- /// show the cursor if it is not visible
- void showCursor();
- /// toggle the cursor's visibility
- void toggleCursor();
- /// hide the cursor
- virtual void removeCursor() = 0;
- /// paint the cursor and store the background
- virtual void showCursor(int x, int y, int h, CursorShape shape) = 0;
- ///
- void updateScrollbar();
-
- ///
- BufferView * buffer_view_;
- ///
- LyXView * lyx_view_;
-
-private:
- /// is the cursor currently displayed
- bool cursor_visible_;
-
- ///
- Timeout cursor_timeout_;
+ virtual void updateWindowTitle() = 0;
};
} // namespace frontend
#include <config.h>
-#include "WorkArea.h"
-
#include "WorkAreaManager.h"
-using std::list;
-
-namespace lyx {
+#include "WorkArea.h"
-extern bool quitting;
+namespace lyx {
namespace frontend {
void WorkAreaManager::add(WorkArea * wa)
void WorkAreaManager::redrawAll()
{
- for (list<WorkArea *>::iterator it = work_areas_.begin();
- it != work_areas_.end(); ) {
+ for (iterator it = work_areas_.begin(); it != work_areas_.end(); ++it)
(*it)->redraw();
- ++it;
- }
}
void WorkAreaManager::setReadOnly(bool on)
{
- for (list<WorkArea *>::iterator it = work_areas_.begin();
- it != work_areas_.end(); ) {
+ for (iterator it = work_areas_.begin(); it != work_areas_.end(); ++it)
(*it)->setReadOnly(on);
- ++it;
- }
}
void WorkAreaManager::updateTitles()
{
- for (list<WorkArea *>::iterator it = work_areas_.begin();
- it != work_areas_.end(); ) {
+ for (iterator it = work_areas_.begin(); it != work_areas_.end(); ++it)
(*it)->updateWindowTitle();
- ++it;
- }
}
} // namespace frontend
class WorkAreaManager
{
public:
+ ///
WorkAreaManager() {}
-
///
void add(WorkArea * wa);
-
///
void remove(WorkArea * wa);
-
///
void redrawAll();
-
///
void closeAll();
-
/// This function is called when the buffer readonly status change.
- virtual void setReadOnly(bool);
-
+ void setReadOnly(bool);
/// Update window titles of all users.
- virtual void updateTitles();
+ void updateTitles();
private:
+ typedef std::list<WorkArea *>::iterator iterator;
+ ///
std::list<WorkArea *> work_areas_;
};
QPixmap * splash_;
};
-};
+} // namespace anon
struct GuiView::GuiViewPrivate
/// in order to catch Tab key press.
bool event(QEvent * e);
bool focusNextPrevChild(bool);
+ ///
+ QRect updateFloatingGeometry();
+
+private:
+ ///
+ struct GuiViewPrivate;
+ GuiViewPrivate & d;
+ ///
QTimer statusbar_timer_;
/// are we quitting by the menu?
bool quitting_by_menu_;
- ///
- QRect updateFloatingGeometry();
///
QRect floatingGeometry_;
};
ToolbarSize toolbarSize_;
-
- struct GuiViewPrivate;
- GuiViewPrivate& d;
};
#include "GuiWorkArea.h"
-#include "GuiApplication.h"
-#include "GuiPainter.h"
-#include "GuiKeySymbol.h"
-#include "qt_helpers.h"
-
-#include "frontends/LyXView.h"
-
#include "Buffer.h"
+#include "BufferParams.h"
#include "BufferView.h"
+#include "CoordCache.h"
#include "Cursor.h"
#include "debug.h"
+#include "Font.h"
#include "FuncRequest.h"
+#include "gettext.h"
+#include "GuiApplication.h"
+#include "GuiKeySymbol.h"
+#include "GuiPainter.h"
+#include "KeySymbol.h"
+#include "Language.h"
#include "LyXFunc.h"
#include "LyXRC.h"
+#include "MetricsInfo.h"
+#include "qt_helpers.h"
#include "version.h"
#include "graphics/GraphicsImage.h"
#include "graphics/GraphicsLoader.h"
+#include "support/FileName.h"
+#include "support/ForkedcallsController.h"
+
+#include "frontends/Application.h"
+#include "frontends/Dialogs.h" // only used in setReadOnly
+#include "frontends/FontMetrics.h"
+#include "frontends/LyXView.h"
+#include "frontends/WorkAreaManager.h"
+
#include <QInputContext>
#include <QLayout>
#include <QMainWindow>
#include <QTabBar>
#include <QTimer>
-#include <boost/current_function.hpp>
#include <boost/bind.hpp>
+#include <boost/current_function.hpp>
#ifdef Q_WS_X11
#include <QX11Info>
#undef NoModifier
using std::endl;
+using std::min;
+using std::max;
using std::string;
namespace lyx {
using support::FileName;
+using support::ForkedcallsController;
+
/// return the LyX mouse button state from Qt's
static mouse_button::state q_button_state(Qt::MouseButton button)
{}
-GuiWorkArea::GuiWorkArea(Buffer & buf, LyXView & lv)
- : WorkArea(buf, lv), need_resize_(false), schedule_redraw_(false),
- preedit_lines_(1)
+
+// All the below connection objects are needed because of a bug in some
+// versions of GCC (<=2.96 are on the suspects list.) By having and assigning
+// to these connections we avoid a segfault upon startup, and also at exit.
+// (Lgb)
+
+static boost::signals::connection timecon;
+
+// HACK: FIXME
+WorkArea::~WorkArea() {}
+
+
+GuiWorkArea::GuiWorkArea(Buffer & buffer, LyXView & lv)
+ : buffer_view_(new BufferView(buffer)), lyx_view_(&lv),
+ cursor_visible_(false), cursor_timeout_(400),
+ need_resize_(false), schedule_redraw_(false),
+ preedit_lines_(1)
{
+ buffer.workAreaManager().add(this);
+ // Setup the signals
+ timecon = cursor_timeout_.timeout
+ .connect(boost::bind(&GuiWorkArea::toggleCursor, this));
+
+ cursor_timeout_.start();
+
screen_ = QPixmap(viewport()->width(), viewport()->height());
cursor_ = new frontend::CursorWidget();
cursor_->hide();
synthetic_mouse_event_.timeout.timeout.connect(
boost::bind(&GuiWorkArea::generateSyntheticMouseEvent,
- this));
+ this));
// Initialize the vertical Scroll Bar
QObject::connect(verticalScrollBar(), SIGNAL(actionTriggered(int)),
}
+
+GuiWorkArea::~GuiWorkArea()
+{
+ buffer_view_->buffer().workAreaManager().remove(this);
+ delete buffer_view_;
+}
+
+
+void GuiWorkArea::close()
+{
+ lyx_view_->removeWorkArea(this);
+}
+
+
+BufferView & GuiWorkArea::bufferView()
+{
+ return *buffer_view_;
+}
+
+
+BufferView const & GuiWorkArea::bufferView() const
+{
+ return *buffer_view_;
+}
+
+
+void GuiWorkArea::stopBlinkingCursor()
+{
+ cursor_timeout_.stop();
+ hideCursor();
+}
+
+
+void GuiWorkArea::startBlinkingCursor()
+{
+ showCursor();
+ cursor_timeout_.restart();
+}
+
+
+void GuiWorkArea::redraw()
+{
+ if (!isVisible())
+ // No need to redraw in this case.
+ return;
+
+ // No need to do anything if this is the current view. The BufferView
+ // metrics are already up to date.
+ if (lyx_view_ != theApp()->currentView()) {
+ // FIXME: it would be nice to optimize for the off-screen case.
+ buffer_view_->updateMetrics();
+ buffer_view_->cursor().fixIfBroken();
+ }
+
+ updateScrollbar();
+
+ // update cursor position, because otherwise it has to wait until
+ // the blinking interval is over
+ if (cursor_visible_) {
+ hideCursor();
+ showCursor();
+ }
+
+ ViewMetricsInfo const & vi = buffer_view_->viewMetricsInfo();
+
+ LYXERR(Debug::WORKAREA) << "WorkArea::redraw screen" << endl;
+
+ int const ymin = std::max(vi.y1, 0);
+ int const ymax = vi.p2 < vi.size - 1 ? vi.y2 : height();
+
+ expose(0, ymin, width(), ymax - ymin);
+
+ //LYXERR(Debug::WORKAREA)
+ //<< " ymin = " << ymin << " width() = " << width()
+// << " ymax-ymin = " << ymax-ymin << std::endl;
+
+ if (lyxerr.debugging(Debug::WORKAREA))
+ buffer_view_->coordCache().dump();
+}
+
+
+void GuiWorkArea::processKeySym(KeySymbol const & key, KeyModifier mod)
+{
+ // In order to avoid bad surprise in the middle of an operation,
+ // we better stop the blinking cursor.
+ stopBlinkingCursor();
+
+ theLyXFunc().setLyXView(lyx_view_);
+ theLyXFunc().processKeySym(key, mod);
+}
+
+
+void GuiWorkArea::dispatch(FuncRequest const & cmd0, KeyModifier mod)
+{
+ // Handle drag&drop
+ if (cmd0.action == LFUN_FILE_OPEN) {
+ lyx_view_->dispatch(cmd0);
+ return;
+ }
+
+ theLyXFunc().setLyXView(lyx_view_);
+
+ FuncRequest cmd;
+
+ if (cmd0.action == LFUN_MOUSE_PRESS) {
+ if (mod == ShiftModifier)
+ cmd = FuncRequest(cmd0, "region-select");
+ else if (mod == ControlModifier)
+ cmd = FuncRequest(cmd0, "paragraph-select");
+ else
+ cmd = cmd0;
+ }
+ else
+ cmd = cmd0;
+
+ // In order to avoid bad surprise in the middle of an operation, we better stop
+ // the blinking cursor.
+ if (!(cmd.action == LFUN_MOUSE_MOTION
+ && cmd.button() == mouse_button::none))
+ stopBlinkingCursor();
+
+ buffer_view_->mouseEventDispatch(cmd);
+
+ // Skip these when selecting
+ if (cmd.action != LFUN_MOUSE_MOTION) {
+ lyx_view_->updateLayoutChoice(false);
+ lyx_view_->updateToolbars();
+ }
+
+ // GUI tweaks except with mouse motion with no button pressed.
+ if (!(cmd.action == LFUN_MOUSE_MOTION
+ && cmd.button() == mouse_button::none)) {
+ // Slight hack: this is only called currently when we
+ // clicked somewhere, so we force through the display
+ // of the new status here.
+ lyx_view_->clearMessage();
+
+ // Show the cursor immediately after any operation.
+ startBlinkingCursor();
+ }
+}
+
+
+void GuiWorkArea::resizeBufferView()
+{
+ // WARNING: Please don't put any code that will trigger a repaint here!
+ // We are already inside a paint event.
+ lyx_view_->setBusy(true);
+ buffer_view_->resize(width(), height());
+ lyx_view_->updateLayoutChoice(false);
+ lyx_view_->setBusy(false);
+}
+
+
+void GuiWorkArea::updateScrollbar()
+{
+ buffer_view_->updateScrollbar();
+ ScrollbarParameters const & scroll_ = buffer_view_->scrollbarParameters();
+ setScrollbarParams(scroll_.height, scroll_.position,
+ scroll_.lineScrollHeight);
+}
+
+
+void GuiWorkArea::showCursor()
+{
+ if (cursor_visible_)
+ return;
+
+ CursorShape shape = BAR_SHAPE;
+
+ Font const & realfont = buffer_view_->cursor().real_current_font;
+ BufferParams const & bp = buffer_view_->buffer().params();
+ bool const samelang = realfont.language() == bp.language;
+ bool const isrtl = realfont.isVisibleRightToLeft();
+
+ if (!samelang || isrtl != bp.language->rightToLeft()) {
+ shape = L_SHAPE;
+ if (isrtl)
+ shape = REVERSED_L_SHAPE;
+ }
+
+ // The ERT language hack needs fixing up
+ if (realfont.language() == latex_language)
+ shape = BAR_SHAPE;
+
+ Font const font = buffer_view_->cursor().getFont();
+ FontMetrics const & fm = theFontMetrics(font);
+ int const asc = fm.maxAscent();
+ int const des = fm.maxDescent();
+ int h = asc + des;
+ int x = 0;
+ int y = 0;
+ buffer_view_->cursor().getPos(x, y);
+ y -= asc;
+
+ // if it doesn't touch the screen, don't try to show it
+ if (y + h < 0 || y >= height())
+ return;
+
+ cursor_visible_ = true;
+ showCursor(x, y, h, shape);
+}
+
+
+void GuiWorkArea::hideCursor()
+{
+ if (!cursor_visible_)
+ return;
+
+ cursor_visible_ = false;
+ removeCursor();
+}
+
+
+void GuiWorkArea::toggleCursor()
+{
+ if (cursor_visible_)
+ hideCursor();
+ else
+ showCursor();
+
+ // Use this opportunity to deal with any child processes that
+ // have finished but are waiting to communicate this fact
+ // to the rest of LyX.
+ ForkedcallsController & fcc = ForkedcallsController::get();
+ fcc.handleCompletedProcesses();
+
+ cursor_timeout_.restart();
+}
+
+
void GuiWorkArea::setScrollbarParams(int h, int scroll_pos, int scroll_line_step)
{
if (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOn)
void GuiWorkArea::mouseDoubleClickEvent(QMouseEvent * ev)
{
- dc_event_ = double_click(ev);
+ dc_event_ = DoubleClick(ev);
QTimer::singleShot(QApplication::doubleClickInterval(), this,
SLOT(doubleClickTimeout()));
FuncRequest cmd(LFUN_MOUSE_DOUBLE,
screen_ = QPixmap(viewport()->width(), viewport()->height());
resizeBufferView();
updateScreen();
- WorkArea::hideCursor();
- WorkArea::showCursor();
+ hideCursor();
+ showCursor();
need_resize_ = false;
}
}
+void GuiWorkArea::updateWindowTitle()
+{
+ docstring maximize_title;
+ docstring minimize_title;
+
+ Buffer & buf = buffer_view_->buffer();
+ FileName const fileName = buf.fileName();
+ if (!fileName.empty()) {
+ maximize_title = fileName.displayName(30);
+ minimize_title = from_utf8(fileName.onlyFileName());
+ if (!buf.isClean()) {
+ maximize_title += _(" (changed)");
+ minimize_title += char_type('*');
+ }
+ if (buf.isReadonly())
+ maximize_title += _(" (read only)");
+ }
+
+ setWindowTitle(maximize_title, minimize_title);
+}
+
+
+void GuiWorkArea::setReadOnly(bool)
+{
+ updateWindowTitle();
+ if (this == lyx_view_->currentWorkArea())
+ lyx_view_->getDialogs().updateBufferDependent(false);
+}
+
+
////////////////////////////////////////////////////////////////////
//
// TabWorkArea
//
////////////////////////////////////////////////////////////////////
-TabWorkArea::TabWorkArea(QWidget * parent): QTabWidget(parent)
+TabWorkArea::TabWorkArea(QWidget * parent) : QTabWidget(parent)
{
QPalette pal = palette();
- pal.setColor(QPalette::Active, QPalette::Button, pal.color(QPalette::Active, QPalette::Window));
- pal.setColor(QPalette::Disabled, QPalette::Button, pal.color(QPalette::Disabled, QPalette::Window));
- pal.setColor(QPalette::Inactive, QPalette::Button, pal.color(QPalette::Inactive, QPalette::Window));
+ pal.setColor(QPalette::Active, QPalette::Button,
+ pal.color(QPalette::Active, QPalette::Window));
+ pal.setColor(QPalette::Disabled, QPalette::Button,
+ pal.color(QPalette::Disabled, QPalette::Window));
+ pal.setColor(QPalette::Inactive, QPalette::Button,
+ pal.color(QPalette::Inactive, QPalette::Window));
QToolButton * closeTabButton = new QToolButton(this);
closeTabButton->setPalette(pal);
#endif
namespace lyx {
+
+class Buffer;
+
namespace frontend {
+class LyXView;
+
+/// types of cursor in work area
+enum CursorShape {
+ /// normal I-beam
+ BAR_SHAPE,
+ /// L-shape for locked insets of a different language
+ L_SHAPE,
+ /// reverse L-shape for RTL text
+ REVERSED_L_SHAPE
+};
+
/// for emulating triple click
-class double_click {
+class DoubleClick {
public:
+ ///
+ DoubleClick() : state(Qt::NoButton), active(false) {}
+ ///
+ DoubleClick(QMouseEvent * e) : state(e->button()), active(true) {}
+ ///
+ bool operator==(QMouseEvent const & e) { return state == e.button(); }
+ ///
+public:
+ ///
Qt::MouseButton state;
+ ///
bool active;
-
- bool operator==(QMouseEvent const & e) {
- return state == e.button();
- }
-
- double_click()
- : state(Qt::NoButton), active(false) {}
-
- double_click(QMouseEvent * e)
- : state(e->button()), active(true) {}
};
/** Qt only emits mouse events when the mouse is being moved, but
double scrollbar_value_old;
};
+
/**
- * Qt-specific implementation of the work area
- * (buffer view GUI)
+ * Implementation of the work area (buffer view GUI)
*/
- class CursorWidget;
+class CursorWidget;
+
class GuiWorkArea : public QAbstractScrollArea, public WorkArea
{
Q_OBJECT
public:
///
GuiWorkArea(Buffer & buffer, LyXView & lv);
+ ///
+ ~GuiWorkArea();
///
bool hasFocus() const { return QAbstractScrollArea::hasFocus(); }
/// hide the cursor
virtual void removeCursor();
+ ///
+ void setLyXView(LyXView & lv) { lyx_view_ = &lv; }
+ ///
+ BufferView & bufferView();
+ ///
+ BufferView const & bufferView() const;
+ ///
+ void redraw();
+ ///
+ void stopBlinkingCursor();
+ ///
+ void startBlinkingCursor();
+ ///
+ void processKeySym(KeySymbol const & key, KeyModifier mod);
+public Q_SLOTS:
+ /// Adjust the LyX buffer view with the position of the scrollbar.
+ /**
+ * The action argument is not used in the the code, it is there
+ * only for the connection to the vertical srollbar signal which
+ * emits an 'int' action.
+ */
+ void adjustViewWithScrollBar(int action = 0);
+ /// timer to limit triple clicks
+ void doubleClickTimeout();
+
+ /// close this work area.
+ /// Slot for Buffer::closing signal.
+ void close();
+ ////
void setWindowTitle(docstring const & t, docstring const & it);
Q_SIGNALS:
void titleChanged(GuiWorkArea *);
private:
+ /// This function is called when the buffer readonly status change.
+ void setReadOnly(bool);
+
+ /// Update window titles of all users.
+ void updateWindowTitle();
///
void focusInEvent(QFocusEvent *);
///
/// IM query
QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-public Q_SLOTS:
- /// Adjust the LyX buffer view with the position of the scrollbar.
- /**
- * The action argument is not used in the the code, it is there
- * only for the connection to the vertical srollbar signal which
- * emits an 'int' action.
- */
- void adjustViewWithScrollBar(int action = 0);
- /// timer to limit triple clicks
- void doubleClickTimeout();
-
-private:
/// The slot connected to SyntheticMouseEvent::timeout.
void generateSyntheticMouseEvent();
+ ///
+ void dispatch(FuncRequest const & cmd0, KeyModifier = NoModifier);
+ ///
+ void resizeBufferView();
+ /// hide the visible cursor, if it is visible
+ void hideCursor();
+ /// show the cursor if it is not visible
+ void showCursor();
+ /// toggle the cursor's visibility
+ void toggleCursor();
+ ///
+ void updateScrollbar();
+ ///
+ BufferView * buffer_view_;
+ ///
+ LyXView * lyx_view_;
+ /// is the cursor currently displayed
+ bool cursor_visible_;
+
+ ///
+ Timeout cursor_timeout_;
///
SyntheticMouseEvent synthetic_mouse_event_;
///
- double_click dc_event_;
+ DoubleClick dc_event_;
///
CursorWidget * cursor_;
bool schedule_redraw_;
///
int preedit_lines_;
-}; //GuiWorkArea
+}; // GuiWorkArea
+
/// A tabbed set of GuiWorkAreas.
class TabWorkArea : public QTabWidget