// cursor is at the top or bottom edge of the viewport. One scroll per 0.2 s
SyntheticMouseEvent::SyntheticMouseEvent()
: timeout(200), restart_timeout(true),
- x_old(-1), y_old(-1), min_scrollbar_old(-1.0), max_scrollbar_old(-1.0)
+ x_old(-1), y_old(-1), min_scrollbar_old(-1), max_scrollbar_old(-1)
{}
: buffer_view_(0), lyx_view_(0),
cursor_visible_(false),
need_resize_(false), schedule_redraw_(false),
- preedit_lines_(1), completer_(new GuiCompleter(this))
+ preedit_lines_(1), completer_(new GuiCompleter(this, this)),
+ context_target_pos_()
{
}
GuiWorkArea::GuiWorkArea(Buffer & buffer, GuiView & gv)
- : buffer_view_(0), lyx_view_(0),
+ : buffer_view_(0), read_only_(buffer.isReadonly()), lyx_view_(0),
cursor_visible_(false),
need_resize_(false), schedule_redraw_(false),
- preedit_lines_(1), completer_(new GuiCompleter(this))
+ preedit_lines_(1), completer_(new GuiCompleter(this, this)),
+ context_target_pos_()
{
setGuiView(gv);
setBuffer(buffer);
}
screen_ = QPixmap(viewport()->width(), viewport()->height());
+ // With Qt4.5 a mouse event will happen before the first paint event
+ // so make sure that the buffer view has an up to date metrics.
+ buffer_view_->resize(viewport()->width(), viewport()->height());
cursor_ = new frontend::CursorWidget();
cursor_->hide();
delete buffer_view_;
delete cursor_;
// Completer has a QObject parent and is thus automatically destroyed.
+ // See #4758.
// delete completer_;
}
void GuiWorkArea::setBuffer(Buffer & buffer)
{
delete buffer_view_;
- buffer_view_ = new BufferView(buffer),
+ buffer_view_ = new BufferView(buffer);
buffer.workAreaManager().add(this);
// HACK: Prevents an additional redraw when the scrollbar pops up
void GuiWorkArea::setFullScreen(bool full_screen)
{
buffer_view_->setFullScreen(full_screen);
+ setFrameStyle(QFrame::NoFrame);
if (full_screen) {
setFrameStyle(QFrame::NoFrame);
if (lyxrc.full_screen_scrollbar)
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- } else {
-#ifdef Q_WS_MACX
- setFrameStyle(QFrame::NoFrame);
-#else
- setFrameStyle(QFrame::Box);
-#endif
+ } else
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- }
}
}
-void GuiWorkArea::redraw()
+void GuiWorkArea::redraw(bool update_metrics)
{
if (!isVisible())
// No need to redraw in this case.
// No need to do anything if this is the current view. The BufferView
// metrics are already up to date.
- if (lyx_view_ != guiApp->currentView()
+ if (update_metrics || lyx_view_ != guiApp->currentView()
|| lyx_view_->currentWorkArea() != this) {
// FIXME: it would be nice to optimize for the off-screen case.
buffer_view_->updateMetrics();
if (lyxerr.debugging(Debug::WORKAREA))
buffer_view_->coordCache().dump();
+
+ setReadOnly(buffer_view_->buffer().isReadonly());
}
void GuiWorkArea::processKeySym(KeySymbol const & key, KeyModifier mod)
{
- if (lyx_view_->isFullScreen() && lyx_view_->menuBar()->isVisible()) {
+ if (lyx_view_->isFullScreen() && lyx_view_->menuBar()->isVisible()
+ && lyxrc.full_screen_menubar) {
// FIXME HACK: we should not have to do this here. See related comment
// in GuiView::event() (QEvent::ShortcutOverride)
lyx_view_->menuBar()->hide();
// we better stop the blinking cursor...
// the cursor gets restarted in GuiView::restartCursor()
stopBlinkingCursor();
-
- theLyXFunc().setLyXView(lyx_view_);
- theLyXFunc().processKeySym(key, mod);
+ guiApp->processKeySym(key, mod);
}
{
// Handle drag&drop
if (cmd0.action == LFUN_FILE_OPEN) {
- lyx_view_->dispatch(cmd0);
+ DispatchResult dr;
+ lyx_view_->dispatch(cmd0, dr);
return;
}
- theLyXFunc().setLyXView(lyx_view_);
-
FuncRequest cmd;
if (cmd0.action == LFUN_MOUSE_PRESS) {
void GuiWorkArea::contextMenuEvent(QContextMenuEvent * e)
{
- QPoint pos = e->pos();
+ QPoint pos;
+ if (e->reason() == QContextMenuEvent::Mouse)
+ // the position is set on mouse press
+ pos = context_target_pos_;
+ else
+ pos = e->pos();
+ Cursor const & cur = buffer_view_->cursor();
+ if (e->reason() == QContextMenuEvent::Keyboard && cur.inTexted()) {
+ // Do not access the context menu of math right in front of before
+ // the cursor. This does not work when the cursor is in text.
+ Inset * inset = cur.paragraph().getInset(cur.pos());
+ if (inset && inset->asInsetMath())
+ --pos.rx();
+ else if (cur.pos() > 0) {
+ Inset * inset = cur.paragraph().getInset(cur.pos() - 1);
+ if (inset)
+ ++pos.rx();
+ }
+ }
docstring name = buffer_view_->contextMenu(pos.x(), pos.y());
if (name.empty()) {
QAbstractScrollArea::contextMenuEvent(e);
void GuiWorkArea::focusInEvent(QFocusEvent * e)
{
- /*
- LYXERR(Debug::DEBUG, "GuiWorkArea::focusInEvent(): " << this << std::endl);
- GuiWorkArea * old_gwa = theGuiApp()->currentView()->currentWorkArea();
- if (old_gwa)
- old_gwa->stopBlinkingCursor();
- lyx_view_->setCurrentWorkArea(this);
- */
-
+ LYXERR(Debug::DEBUG, "GuiWorkArea::focusInEvent(): " << this << endl);
if (lyx_view_->currentWorkArea() != this)
lyx_view_->setCurrentWorkArea(this);
void GuiWorkArea::focusOutEvent(QFocusEvent * e)
{
- LYXERR(Debug::DEBUG, "GuiWorkArea::focusOutEvent(): " << this << std::endl);
+ LYXERR(Debug::DEBUG, "GuiWorkArea::focusOutEvent(): " << this << endl);
stopBlinkingCursor();
QAbstractScrollArea::focusOutEvent(e);
}
return;
}
+ if (e->button() == Qt::RightButton)
+ context_target_pos_ = e->pos();
+
inputContext()->reset();
FuncRequest const cmd(LFUN_MOUSE_PRESS, e->x(), e->y(),
scroll_value *= delta;
// Take into account user preference.
- scroll_value *= lyxrc.mouse_wheel_speed;
+ scroll_value = int(scroll_value * lyxrc.mouse_wheel_speed);
LYXERR(Debug::SCROLLING, "wheelScrollLines = " << lines
<< " delta = " << delta << " scroll_value = " << scroll_value
<< " page_step = " << page_step);
KeySymbol sym;
setKeySymbol(&sym, ev);
- processKeySym(sym, q_key_state(ev->modifiers()));
- ev->accept();
+ if (sym.isOK()) {
+ processKeySym(sym, q_key_state(ev->modifiers()));
+ ev->accept();
+ } else {
+ ev->ignore();
+ }
}
if (need_resize_) {
screen_ = QPixmap(viewport()->width(), viewport()->height());
resizeBufferView();
- hideCursor();
- showCursor();
+ if (cursor_visible_) {
+ hideCursor();
+ showCursor();
+ }
}
QPainter pain(viewport());
{
QRect cur_r(0, 0, 0, 0);
switch (query) {
- // this is the CJK-specific composition window position.
+ // this is the CJK-specific composition window position and
+ // the context menu position when the menu key is pressed.
case Qt::ImMicroFocus:
cur_r = cursor_->rect();
if (preedit_lines_ != 1)
cur_r.moveLeft(10);
- cur_r.moveBottom(cur_r.bottom() + cur_r.height() * preedit_lines_);
+ cur_r.moveBottom(cur_r.bottom()
+ + cur_r.height() * (preedit_lines_ - 1));
// return lower right of cursor in LyX.
return cur_r;
default:
}
-void GuiWorkArea::setReadOnly(bool)
+void GuiWorkArea::setReadOnly(bool read_only)
{
+ if (read_only_ == read_only)
+ return;
+ read_only_ = read_only;
updateWindowTitle();
if (this == lyx_view_->currentWorkArea())
lyx_view_->updateDialogs();
stopBlinkingCursor();
if (view().currentWorkArea() != this)
return;
- LASSERT(view().currentMainWorkArea(), /* */);
+ // No problem if currentMainWorkArea() is 0 (setCurrentWorkArea()
+ // tolerates it and shows the background logo), what happens if
+ // an EmbeddedWorkArea is closed after closing all document WAs
view().setCurrentWorkArea(view().currentMainWorkArea());
}
#ifdef Q_WS_MACX
setStyle(&noTabFrameMacStyle);
#endif
+#if QT_VERSION < 0x040500
+ lyxrc.single_close_tab_button = true;
+#endif
QPalette pal = palette();
pal.setColor(QPalette::Active, QPalette::Button,
tb->setContextMenuPolicy(Qt::CustomContextMenu);
connect(tb, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(showContextMenu(const QPoint &)));
+#if QT_VERSION >= 0x040500
+ connect(tb, SIGNAL(tabCloseRequested(int)),
+ this, SLOT(closeTab(int)));
+#endif
setUsesScrollButtons(true);
}
}
if (lyxrc.full_screen_tabbar)
- showBar(!full_screen && count()>1);
+ showBar(!full_screen && count() > 1);
}
{
tabBar()->setEnabled(show);
tabBar()->setVisible(show);
- closeBufferButton->setVisible(show);
+ closeBufferButton->setVisible(show && lyxrc.single_close_tab_button);
+#if QT_VERSION >= 0x040500
+ setTabsClosable(!lyxrc.single_close_tab_button);
+#endif
}
if (currentWorkArea() && currentWorkArea()->isFullScreen())
setFullScreen(true);
else
- // Hide tabbar if there's only one tab.
+ // Show tabbar only if there's more than one tab.
showBar(count() > 1);
- } else {
+ } else
lastWorkAreaRemoved();
- }
updateTabTexts();
return;
GuiWorkArea * wa = dynamic_cast<GuiWorkArea *>(widget(i));
LASSERT(wa, return);
- BufferView & bv = wa->bufferView();
- bv.cursor().fixIfBroken();
- bv.updateMetrics();
wa->setUpdatesEnabled(true);
- wa->redraw();
+ wa->redraw(true);
wa->setFocus();
///
currentWorkAreaChanged(wa);
LYXERR(Debug::GUI, "currentTabChanged " << i
- << "File" << bv.buffer().absFileName());
+ << " File: " << wa->bufferView().buffer().absFileName());
}
void TabWorkArea::closeCurrentBuffer()
{
- if (clicked_tab_ != -1)
- setCurrentIndex(clicked_tab_);
- else
- // Before dispatching the LFUN we should be sure this
- // is the current workarea.
- currentWorkAreaChanged(currentWorkArea());
-
- lyx::dispatch(FuncRequest(LFUN_BUFFER_CLOSE));
+ GuiWorkArea * wa;
+ if (clicked_tab_ == -1)
+ wa = currentWorkArea();
+ else {
+ wa = dynamic_cast<GuiWorkArea *>(widget(clicked_tab_));
+ LASSERT(wa, /**/);
+ }
+ wa->view().closeWorkArea(wa);
}
-void TabWorkArea::closeCurrentTab()
+void TabWorkArea::hideCurrentTab()
{
+ GuiWorkArea * wa;
if (clicked_tab_ == -1)
- removeWorkArea(currentWorkArea());
+ wa = currentWorkArea();
else {
- GuiWorkArea * wa = dynamic_cast<GuiWorkArea *>(widget(clicked_tab_));
+ wa = dynamic_cast<GuiWorkArea *>(widget(clicked_tab_));
LASSERT(wa, /**/);
- removeWorkArea(wa);
}
+ wa->view().hideWorkArea(wa);
}
+
+void TabWorkArea::closeTab(int index)
+{
+ on_currentTabChanged(index);
+ GuiWorkArea * wa;
+ if (index == -1)
+ wa = currentWorkArea();
+ else {
+ wa = dynamic_cast<GuiWorkArea *>(widget(index));
+ LASSERT(wa, /**/);
+ }
+ wa->view().closeWorkArea(wa);
+}
+
+
///
class DisplayPath {
public:
DisplayPath(int tab, FileName const & filename)
: tab_(tab)
{
- filename_ = toqstr(filename.onlyFileNameWithoutExt());
+ filename_ = (filename.extension() == "lyx") ?
+ toqstr(filename.onlyFileNameWithoutExt())
+ : toqstr(filename.onlyFileName());
postfix_ = toqstr(filename.absoluteFilePath()).
split("/", QString::SkipEmptyParts);
postfix_.pop_back();
// show tab popup
QMenu popup;
popup.addAction(QIcon(getPixmap("images/", "hidetab", "png")),
- qt_("Hide tab"), this, SLOT(closeCurrentTab()));
+ qt_("Hide tab"), this, SLOT(hideCurrentTab()));
popup.addAction(QIcon(getPixmap("images/", "closetab", "png")),
qt_("Close tab"), this, SLOT(closeCurrentBuffer()));
popup.exec(tabBar()->mapToGlobal(pos));
: QTabBar(parent)
{
setAcceptDrops(true);
+#if QT_VERSION >= 0x040500
+ setTabsClosable(!lyxrc.single_close_tab_button);
+#endif
}