Set window title according to platform UI

The window title is built from the current file name and its
mofidication state. We use our own code instead of the automatic title
bar provided when windowFileName() is set because

1/ Qt does not keep the full path name
2/ Qt does not yield a nice application name

The "read only" and "version control" status are shown in the status bar:

* for read only we use the tab read only emblem (with the right size)
* for version control, we show the name of the backend (using a new
  vcname() method of the backend).

The iconText() of the view is not updated anymore, since this is
deprecated in Qt5.
This commit is contained in:
Jean-Marc Lasgouttes 2016-09-06 11:17:10 +02:00
parent b95262f487
commit 82808fea04
6 changed files with 87 additions and 43 deletions

View File

@ -41,6 +41,12 @@ LyXVC::LyXVC()
} }
string LyXVC::vcname() const
{
return vcs->vcname();
}
bool LyXVC::fileInVC(FileName const & fn) bool LyXVC::fileInVC(FileName const & fn)
{ {
if (!RCS::findFile(fn).empty()) if (!RCS::findFile(fn).empty())

View File

@ -48,6 +48,8 @@ public:
}; };
/// ///
LyXVC(); LyXVC();
/// Name of the underlying VCS
std::string vcname() const;
/// Is \p fn under version control? /// Is \p fn under version control?
static bool fileInVC(support::FileName const & fn); static bool fileInVC(support::FileName const & fn);
/** Not a good name perhaps. This function should be called whenever /** Not a good name perhaps. This function should be called whenever

View File

@ -38,6 +38,8 @@ public:
VCS(Buffer * b) : vcstatus(NOLOCKING), owner_(b) {} VCS(Buffer * b) : vcstatus(NOLOCKING), owner_(b) {}
virtual ~VCS() {} virtual ~VCS() {}
/// the name of the vc backend
virtual std::string vcname() const = 0;
/// register a file for version control /// register a file for version control
virtual void registrer(std::string const & msg) = 0; virtual void registrer(std::string const & msg) = 0;
/// can this operation be processed in the current VCS? /// can this operation be processed in the current VCS?
@ -150,6 +152,8 @@ public:
/// get file from repo, the caller must ensure that it does not exist locally /// get file from repo, the caller must ensure that it does not exist locally
static bool retrieve(support::FileName const & file); static bool retrieve(support::FileName const & file);
virtual std::string vcname() const { return "RCS"; };
virtual void registrer(std::string const & msg); virtual void registrer(std::string const & msg);
virtual bool renameEnabled(); virtual bool renameEnabled();
@ -234,6 +238,8 @@ public:
/// get file from repo, the caller must ensure that it does not exist locally /// get file from repo, the caller must ensure that it does not exist locally
static bool retrieve(support::FileName const & file); static bool retrieve(support::FileName const & file);
virtual std::string vcname() const { return "CVS"; };
virtual void registrer(std::string const & msg); virtual void registrer(std::string const & msg);
virtual bool renameEnabled(); virtual bool renameEnabled();
@ -373,6 +379,8 @@ public:
/// get file from repo, the caller must ensure that it does not exist locally /// get file from repo, the caller must ensure that it does not exist locally
static bool retrieve(support::FileName const & file); static bool retrieve(support::FileName const & file);
virtual std::string vcname() const { return "SVN"; };
virtual void registrer(std::string const & msg); virtual void registrer(std::string const & msg);
virtual bool renameEnabled(); virtual bool renameEnabled();
@ -481,6 +489,8 @@ public:
/// get file from repo, the caller must ensure that it does not exist locally /// get file from repo, the caller must ensure that it does not exist locally
static bool retrieve(support::FileName const & file); static bool retrieve(support::FileName const & file);
virtual std::string vcname() const { return "GIT"; };
virtual void registrer(std::string const & msg); virtual void registrer(std::string const & msg);
virtual bool renameEnabled(); virtual bool renameEnabled();

View File

@ -110,9 +110,7 @@
#include <QSplitter> #include <QSplitter>
#include <QStackedWidget> #include <QStackedWidget>
#include <QStatusBar> #include <QStatusBar>
#if QT_VERSION >= 0x050000
#include <QSvgRenderer> #include <QSvgRenderer>
#endif
#include <QtConcurrentRun> #include <QtConcurrentRun>
#include <QTime> #include <QTime>
#include <QTimer> #include <QTimer>
@ -553,7 +551,7 @@ GuiView::GuiView(int id)
#endif #endif
#endif #endif
resetWindowTitleAndIconText(); resetWindowTitle();
// use tabbed dock area for multiple docks // use tabbed dock area for multiple docks
// (such as "source" and "messages") // (such as "source" and "messages")
@ -577,6 +575,33 @@ GuiView::GuiView(int id)
connect(&d.processing_thread_watcher_, SIGNAL(finished()), connect(&d.processing_thread_watcher_, SIGNAL(finished()),
busylabel, SLOT(hide())); busylabel, SLOT(hide()));
QFontMetrics const fm(statusBar()->fontMetrics());
int const roheight = max(int(d.normalIconSize), fm.height());
QSize const rosize(roheight, roheight);
QPixmap readonly = QPixmap(rosize);
QString imagedir = "images/";
FileName fname = imageLibFileSearch(imagedir, "emblem-readonly", "svgz");
QSvgRenderer renderer(toqstr(fname.absFileName()));
if (renderer.isValid()) {
readonly.fill(statusBar()->palette().color(QWidget::backgroundRole()));
QPainter painter(&readonly);
renderer.render(&painter);
} else {
readonly = getPixmap("images/", "emblem-readonly", "png").scaled(rosize, Qt::KeepAspectRatio);
}
read_only_ = new QLabel(statusBar());
read_only_->setPixmap(readonly);
read_only_->setScaledContents(true);
read_only_->setAlignment(Qt::AlignCenter);
read_only_->hide();
statusBar()->addPermanentWidget(read_only_);
version_control_ = new QLabel(statusBar());
version_control_->setAlignment(Qt::AlignCenter);
version_control_->setFrameStyle(QFrame::StyledPanel);
version_control_->hide();
statusBar()->addPermanentWidget(version_control_);
statusBar()->setSizeGripEnabled(true); statusBar()->setSizeGripEnabled(true);
updateStatusBar(); updateStatusBar();
@ -1144,14 +1169,36 @@ void GuiView::updateWindowTitle(GuiWorkArea * wa)
if (wa != d.current_work_area_ if (wa != d.current_work_area_
|| wa->bufferView().buffer().isInternal()) || wa->bufferView().buffer().isInternal())
return; return;
setWindowTitle(qt_("LyX: ") + wa->windowTitle()); Buffer const & buf = wa->bufferView().buffer();
setWindowIconText(wa->windowIconText());
#if (QT_VERSION >= 0x040400)
// Sets the path for the window: this is used by OSX to // Sets the path for the window: this is used by OSX to
// allow a context click on the title bar showing a menu // allow a context click on the title bar showing a menu
// with the path up to the file // with the path up to the file
setWindowFilePath(toqstr(wa->bufferView().buffer().absFileName())); setWindowFilePath(toqstr(buf.absFileName()));
// Tell Qt whether the current document is changed
setWindowModified(!buf.isClean());
// Set the windows title
docstring title = buf.fileName().displayName(130) + from_ascii("[*]");
#ifndef Q_WS_MAC
// — U+2014 EM DASH
title += from_ascii(" ") + char_type(0x2014) + from_ascii(" LyX");
#endif #endif
setWindowTitle(toqstr(title));
if (buf.isReadonly())
read_only_->show();
else
read_only_->hide();
if (buf.lyxvc().inUse()) {
version_control_->show();
if (buf.lyxvc().locking())
version_control_->setText(
toqstr(bformat(_("%1$s lock"),
from_ascii(buf.lyxvc().vcname()))));
else
version_control_->setText(toqstr(buf.lyxvc().vcname()));
} else
version_control_->hide();
} }
@ -1196,7 +1243,7 @@ void GuiView::on_lastWorkAreaRemoved()
updateDialog("document", ""); updateDialog("document", "");
updateDialogs(); updateDialogs();
resetWindowTitleAndIconText(); resetWindowTitle();
updateStatusBar(); updateStatusBar();
if (lyxrc.open_buffers_in_tabs) if (lyxrc.open_buffers_in_tabs)
@ -1285,7 +1332,7 @@ bool GuiView::event(QEvent * e)
updateDialog("document", ""); updateDialog("document", "");
updateDialogs(); updateDialogs();
} else { } else {
resetWindowTitleAndIconText(); resetWindowTitle();
} }
setFocus(); setFocus();
return QMainWindow::event(e); return QMainWindow::event(e);
@ -1312,10 +1359,9 @@ bool GuiView::event(QEvent * e)
} }
} }
void GuiView::resetWindowTitleAndIconText() void GuiView::resetWindowTitle()
{ {
setWindowTitle(qt_("LyX")); setWindowTitle(qt_("LyX"));
setWindowIconText(qt_("LyX"));
} }
bool GuiView::focusNextPrevChild(bool /*next*/) bool GuiView::focusNextPrevChild(bool /*next*/)

View File

@ -24,6 +24,7 @@
class QCloseEvent; class QCloseEvent;
class QDragEnterEvent; class QDragEnterEvent;
class QDropEvent; class QDropEvent;
class QLabel;
class QMenu; class QMenu;
class QShowEvent; class QShowEvent;
@ -220,12 +221,12 @@ public Q_SLOTS:
/// idle timeout. /// idle timeout.
/// clear any temporary message and replace with current status. /// clear any temporary message and replace with current status.
void clearMessage(); void clearMessage();
///
void updateWindowTitle(GuiWorkArea * wa);
private Q_SLOTS: private Q_SLOTS:
/// ///
void updateWindowTitle(GuiWorkArea * wa); void resetWindowTitle();
///
void resetWindowTitleAndIconText();
/// ///
void on_currentWorkAreaChanged(GuiWorkArea *); void on_currentWorkAreaChanged(GuiWorkArea *);
@ -455,6 +456,11 @@ private:
/// Request to give focus to minibuffer /// Request to give focus to minibuffer
bool minibuffer_focus_; bool minibuffer_focus_;
/// Statusbar widget that shows read-only status
QLabel * read_only_;
/// Statusbar widget that shows version control status
QLabel * version_control_;
}; };
} // namespace frontend } // namespace frontend

View File

@ -1387,35 +1387,9 @@ QVariant GuiWorkArea::inputMethodQuery(Qt::InputMethodQuery query) const
void GuiWorkArea::updateWindowTitle() void GuiWorkArea::updateWindowTitle()
{ {
docstring maximize_title; d->lyx_view_->updateWindowTitle(this);
docstring minimize_title;
Buffer const & buf = d->buffer_view_->buffer();
FileName const file_name = buf.fileName();
if (!file_name.empty()) {
maximize_title = file_name.displayName(130);
minimize_title = from_utf8(file_name.onlyFileName());
if (buf.lyxvc().inUse()) {
if (buf.lyxvc().locking())
maximize_title += _(" (version control, locking)");
else
maximize_title += _(" (version control)");
}
if (!buf.isClean()) {
maximize_title += _(" (changed)");
minimize_title += char_type('*');
}
if (buf.isReadonly())
maximize_title += _(" (read only)");
}
QString const new_title = toqstr(maximize_title);
if (new_title != windowTitle()) {
QWidget::setWindowTitle(new_title);
QWidget::setWindowIconText(toqstr(minimize_title));
titleChanged(this); titleChanged(this);
} }
}
bool GuiWorkArea::isFullScreen() const bool GuiWorkArea::isFullScreen() const