[education/rkward] /: Fix status bar no longer showing up, but also use better placement, and show more tips.

Thomas Friedrichsmeier null at kde.org
Sun Mar 20 09:05:12 GMT 2022


Git commit 68738964f1252a9375b6dc17851a335ac4e1a97c by Thomas Friedrichsmeier.
Committed on 20/03/2022 at 09:04.
Pushed by tfry into branch 'master'.

Fix status bar no longer showing up, but also use better placement, and show more tips.

M  +1    -0    ChangeLog
M  +7    -7    rkward/dataeditor/twintable.cpp
M  +1    -1    rkward/misc/rkstandardactions.cpp
M  +1    -1    rkward/rkconsole.cpp
M  +44   -33   rkward/rkward.cpp
M  +1    -2    rkward/rkward.h
M  +2    -2    rkward/windows/rkcommandeditorwindow.cpp
M  +2    -2    rkward/windows/rkhtmlwindow.cpp
M  +3    -3    rkward/windows/rktoplevelwindowgui.cpp
M  +9    -2    rkward/windows/rkworkplace.cpp
M  +4    -1    rkward/windows/rkworkplace.h

https://invent.kde.org/education/rkward/commit/68738964f1252a9375b6dc17851a335ac4e1a97c

diff --git a/ChangeLog b/ChangeLog
index 76a77813..e2ebe0cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@ TODOS for autotests:
   - Check and update the standards files
   - Use options(warn=1), in order to get warnings into the test?
 
+- Space-saving placement of main window status bar, and display more tips in it
 - Fixed: Intial graphics window size would be (mostly) ignored
 - Fix some buglets around closing on-screen devices
 - Implement new R graphics functions: gradients, patterns, clip paths
diff --git a/rkward/dataeditor/twintable.cpp b/rkward/dataeditor/twintable.cpp
index 1eb2a662..7359b1c9 100644
--- a/rkward/dataeditor/twintable.cpp
+++ b/rkward/dataeditor/twintable.cpp
@@ -106,22 +106,22 @@ void TwinTable::initActions () {
 	RK_TRACE (EDITOR);
 
 	editCut = actionCollection ()->addAction (KStandardAction::Cut, "cut", this, SLOT(cut()));
-	editCut->setStatusTip (i18n("Cuts the selected section and puts it to the clipboard"));
+	editCut->setWhatsThis(i18n("Cuts the selected section and puts it to the clipboard"));
 	editCopy = actionCollection ()->addAction (KStandardAction::Copy, "copy", this, SLOT(copy()));
-	editCopy->setStatusTip (i18n("Copies the selected section to the clipboard"));
+	editCopy->setWhatsThis(i18n("Copies the selected section to the clipboard"));
 //	editor->editActions ()->addAction (editCopy);	// this is a read-only action, not an "edit" action
 	editPaste = actionCollection ()->addAction (KStandardAction::Paste, "paste", this, SLOT(paste()));
-	editPaste->setStatusTip (i18n("Pastes the clipboard contents to current position"));
+	editPaste->setWhatsThis(i18n("Pastes the clipboard contents to current position"));
 
 	editPasteToTable = actionCollection ()->addAction ("paste_to_table", this, SLOT(pasteToTable()));
 	editPasteToTable->setText (i18n("Paste inside table"));
 	editPasteToTable->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionPasteInsideTable));
-	editPasteToTable->setStatusTip (i18n("Pastes the clipboard contents to current position, but not beyond the table's boundaries"));
+	editPasteToTable->setWhatsThis(i18n("Pastes the clipboard contents to current position, but not beyond the table's boundaries"));
 
 	editPasteToSelection = actionCollection ()->addAction ("paste_to_selection", this, SLOT(pasteToSelection()));
 	editPasteToSelection->setText (i18n("Paste inside selection"));
 	editPasteToSelection->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionPasteInsideSelection));
-	editPasteToSelection->setStatusTip (i18n("Pastes the clipboard contents to current position, but not beyond the boundaries of the current selection"));
+	editPasteToSelection->setWhatsThis(i18n("Pastes the clipboard contents to current position, but not beyond the boundaries of the current selection"));
 
 	// header menus
 	action_insert_col_left = actionCollection ()->addAction ("insert_col_left", this, SLOT (insertColumn()));
@@ -149,12 +149,12 @@ void TwinTable::initActions () {
 	action_tb_lock_editing = new KToggleAction (i18nc ("verb: switch to read-only state. Make this short.", "Lock"), this);
 	action_tb_lock_editing->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionLock));
 	action_tb_lock_editing->setActionGroup (lockactions);
-	action_tb_lock_editing->setStatusTip (i18n ("Disable editing (to prevent accidental modification of data)"));
+	action_tb_lock_editing->setWhatsThis(i18n ("Disable editing (to prevent accidental modification of data)"));
 	actionCollection ()->addAction ("lock_editing", action_tb_lock_editing);
 	action_tb_unlock_editing = new KToggleAction (i18nc ("verb: switch to read-write state. Make this short.", "Unlock"), this);
 	action_tb_unlock_editing->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionUnlock));
 	action_tb_unlock_editing->setActionGroup (lockactions);
-	action_tb_unlock_editing->setStatusTip (i18n ("Enable editing"));
+	action_tb_unlock_editing->setWhatsThis(i18n ("Enable editing"));
 	actionCollection ()->addAction ("unlock_editing", action_tb_unlock_editing);
 	connect (action_tb_unlock_editing, &QAction::toggled, this, &TwinTable::enableEditing);
 	// NOTE: No need to connect lock_editing, too, as they are radio-exclusive
diff --git a/rkward/misc/rkstandardactions.cpp b/rkward/misc/rkstandardactions.cpp
index c9214dd9..cbcc279b 100644
--- a/rkward/misc/rkstandardactions.cpp
+++ b/rkward/misc/rkstandardactions.cpp
@@ -54,7 +54,7 @@ QAction* RKStandardActions::runCurrent (RKMDIWindow *window, const QObject *rece
 	QAction* ret = window->standardActionCollection ()->addAction ("run_current", receiver, member);
 	if (current_or_line) {
 		ret->setText (i18n ("Run line / selection"));
-		ret->setStatusTip (i18n ("Runs the current selection (if any) or the current line (if there is no selection)"));
+		ret->setWhatsThis(i18n ("Runs the current selection (if any) or the current line (if there is no selection)"));
 		ret->setToolTip (ret->statusTip ());
 	} else {
 		ret->setText (i18n ("Run selection"));
diff --git a/rkward/rkconsole.cpp b/rkward/rkconsole.cpp
index f9572fd8..09808d61 100644
--- a/rkward/rkconsole.cpp
+++ b/rkward/rkconsole.cpp
@@ -198,7 +198,7 @@ QAction* RKConsole::addProxyAction (const QString& actionName, const QString& la
 		ret->setIcon (found->icon ());
 		ret->setIconText (found->iconText ());
 		ret->setToolTip (found->toolTip ());
-		ret->setStatusTip (found->statusTip ());
+		ret->setWhatsThis(found->statusTip ());
 		ret->setCheckable (found->isCheckable ());
 		ret->setChecked (found->isChecked ());
 		// TODO: ideally, we'd also relay enabledness, checked state, etc. That would probably require a separate class,
diff --git a/rkward/rkward.cpp b/rkward/rkward.cpp
index 2d24f9ff..8f6f52eb 100644
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@ -136,13 +136,13 @@ RKWardMainWindow::RKWardMainWindow () : KParts::MainWindow ((QWidget *)0, (Qt::W
 	// call inits to invoke all other construction parts
 	RKStandardIcons::initIcons ();
 	initActions();
-	initStatusBar();
 
 	new RKWorkplace (this);
 	RKWorkplace::mainWorkplace ()->initActions (actionCollection ());
 	setCentralWidget (RKWorkplace::mainWorkplace ());
 	connect (RKWorkplace::mainWorkplace ()->view (), &RKWorkplaceView::captionChanged, this, static_cast<void (RKWardMainWindow::*)(const QString&)>(&RKWardMainWindow::setCaption));
 	connect (RKWorkplace::mainWorkplace (), &RKWorkplace::workspaceUrlChanged, this, &RKWardMainWindow::addWorkspaceUrl);
+	initStatusBar();
 
 	part_manager = new KParts::PartManager (this);
 	// When the manager says the active part changes,
@@ -490,7 +490,7 @@ void RKWardMainWindow::initActions() {
 	new_data_frame = actionCollection ()->addAction ("new_data_frame", this, SLOT (slotNewDataFrame()));
 	new_data_frame->setText (i18n ("Dataset"));
 	new_data_frame->setIcon (RKStandardIcons::getIcon (RKStandardIcons::WindowDataFrameEditor));
-	new_data_frame->setStatusTip (i18n ("Creates new empty dataset and opens it for editing"));
+	new_data_frame->setWhatsThis(i18n ("Creates new empty dataset and opens it for editing"));
 
 	new_command_editor = actionCollection ()->addAction (KStandardAction::New, "new_command_editor", this, SLOT(slotNewCommandEditor()));
 	new_command_editor->setText (i18n ("Script File"));
@@ -499,7 +499,7 @@ void RKWardMainWindow::initActions() {
 	new_output = actionCollection ()->addAction("new_output", this, SLOT(slotNewOutput()));
 	new_output->setText(i18n("Output document"));
 	new_output->setIcon(RKStandardIcons::getIcon(RKStandardIcons::WindowOutput));
-	new_output->setStatusTip(i18n("Creates and activates a new output document"));
+	new_output->setWhatsThis(i18n("Creates and activates a new output document"));
 
 	fileOpenScript = actionCollection()->addAction(KStandardAction::Open, "file_open_script", this, SLOT(slotOpenCommandEditor()));
 	actionCollection()->setDefaultShortcut(fileOpenScript, Qt::ControlModifier + Qt::AltModifier + Qt::Key_O);
@@ -526,31 +526,31 @@ void RKWardMainWindow::initActions() {
 #else
 	action = actionCollection ()->addAction ("import_data", this, SLOT (importData()));
 	action->setText (i18n ("Import Data"));
-	action->setStatusTip (i18n ("Import data from a variety of file formats"));
+	action->setWhatsThis(i18n ("Import data from a variety of file formats"));
 #endif
 #endif
 
 	fileOpenWorkspace = actionCollection ()->addAction (KStandardAction::Open, "file_openx", this, SLOT(slotFileOpenWorkspace()));
 	fileOpenWorkspace->setText (i18n ("Open Workspace..."));
 	actionCollection ()->setDefaultShortcut (fileOpenWorkspace, Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_O);
-	fileOpenWorkspace->setStatusTip (i18n ("Opens an existing document"));
+	fileOpenWorkspace->setWhatsThis(i18n ("Opens an existing document"));
 
 	fileOpenRecentWorkspace = static_cast<KRecentFilesAction*> (actionCollection ()->addAction (KStandardAction::OpenRecent, "file_open_recentx", this, SLOT(askOpenWorkspace(QUrl))));
 	fileOpenRecentWorkspace->setText (i18n ("Open Recent Workspace"));
-	fileOpenRecentWorkspace->setStatusTip (i18n ("Opens a recently used file"));
+	fileOpenRecentWorkspace->setWhatsThis(i18n ("Opens a recently used file"));
 
 	fileSaveWorkspace = actionCollection ()->addAction (KStandardAction::Save, "file_savex", this, SLOT(slotFileSaveWorkspace()));
 	fileSaveWorkspace->setText (i18n ("Save Workspace"));
 	actionCollection ()->setDefaultShortcut (fileSaveWorkspace, Qt::ControlModifier + Qt::AltModifier + Qt::Key_S);
-	fileSaveWorkspace->setStatusTip (i18n ("Saves the actual document"));
+	fileSaveWorkspace->setWhatsThis(i18n ("Saves the actual document"));
 
 	fileSaveWorkspaceAs = actionCollection ()->addAction (KStandardAction::SaveAs, "file_save_asx", this, SLOT(slotFileSaveWorkspaceAs()));
 	actionCollection ()->setDefaultShortcut (fileSaveWorkspaceAs, Qt::ControlModifier + Qt::AltModifier + Qt::ShiftModifier + Qt::Key_S);
 	fileSaveWorkspaceAs->setText (i18n ("Save Workspace As"));
-	fileSaveWorkspaceAs->setStatusTip (i18n ("Saves the actual document as..."));
+	fileSaveWorkspaceAs->setWhatsThis(i18n ("Saves the actual document as..."));
 
 	fileQuit = actionCollection ()->addAction (KStandardAction::Quit, "file_quitx", this, SLOT(close()));
-	fileQuit->setStatusTip (i18n ("Quits the application"));
+	fileQuit->setWhatsThis(i18n ("Quits the application"));
 
 	interrupt_all_commands = actionCollection ()->addAction ("cancel_all_commands", this, SLOT (slotCancelAllCommands()));
 	interrupt_all_commands->setText (i18n ("Interrupt all commands"));
@@ -575,7 +575,7 @@ void RKWardMainWindow::initActions() {
 
 	close_all_editors = actionCollection ()->addAction ("close_all_editors", this, SLOT (slotCloseAllEditors()));
 	close_all_editors->setText (i18n ("Close All Data"));
-	close_all_editors->setStatusTip (i18n ("Closes all open data editors"));
+	close_all_editors->setWhatsThis(i18n ("Closes all open data editors"));
 
 	action = actionCollection ()->addAction (KStandardAction::Close, "window_close", this, SLOT (slotCloseWindow()));
 
@@ -671,6 +671,9 @@ void RKWardMainWindow::partChanged(KParts::Part *part) {
 	if (gui_rebuild_locked) return;
 	if (!part) return;
 	createGUI(part);
+	foreach (QAction *a, actions()) {
+		if (a->statusTip().isEmpty()) a->setStatusTip(a->whatsThis());
+	}
 
 	if (!guiFactory()) {
 		RK_ASSERT (false);
@@ -725,29 +728,37 @@ void RKWardMainWindow::lockGUIRebuild (bool lock) {
 void RKWardMainWindow::initStatusBar () {
 	RK_TRACE (APP);
 
-	statusbar_ready = new QLabel (i18n ("Ready."), statusBar ());
-	statusBar ()->addWidget (statusbar_ready);
-	statusbar_cwd = new KSqueezedTextLabel (statusBar ());
-	statusbar_cwd->setAlignment (Qt::AlignRight);
-	statusbar_cwd->setToolTip (i18n ("Current working directory"));
-	statusBar ()->addWidget (statusbar_cwd, 10);
-	updateCWD ();
-
-	QWidget *box = new QWidget (statusBar ());
-	QHBoxLayout *boxl = new QHBoxLayout (box);
-	boxl->setSpacing (0);
-	statusbar_r_status = new QLabel (" <b>R</b> ", box);
-	statusbar_r_status->setFixedHeight (statusBar ()->fontMetrics ().height () + 2);
-	boxl->addWidget (statusbar_r_status);
-
-	QToolButton* dummy = new QToolButton (box);
-	dummy->setDefaultAction (interrupt_all_commands);
-	dummy->setFixedHeight (statusbar_r_status->height ());
-	dummy->setAutoRaise (true);
-	boxl->addWidget (dummy);
-
-	statusBar ()->addPermanentWidget (box, 0);
-	setRStatus (RInterface::Starting);
+	// The regular status bar is broken in KF5 (since when? At least 5.68.0), but also it takes up too much space.
+	// Instead, we use a right-aligned bar merged into the bottom toolbar -> no space wasted.
+	statusBar()->hide();
+	auto realbar = RKWorkplace::mainWorkplace()->statusBar();
+	connect(statusBar(), &QStatusBar::messageChanged, [this](const QString &message) {
+		if(message.isEmpty()) updateCWD();
+		else statusbar_cwd->setText(message);
+		// realbar->showMessage(message);  // why doesn't this work, instead? Qt 5.12.8
+	});
+
+	statusbar_cwd = new KSqueezedTextLabel();
+	statusbar_cwd->setAlignment(Qt::AlignRight);
+	statusbar_cwd->setToolTip(i18n("Current working directory"));
+	realbar->addWidget(statusbar_cwd, 10);
+	updateCWD();
+
+	auto box = new QWidget();
+	QHBoxLayout *boxl = new QHBoxLayout(box);
+	boxl->setSpacing(0);
+	statusbar_r_status = new QLabel(" <b>R</b> ");
+	statusbar_r_status->setFixedHeight(realbar->fontMetrics().height() + 2);
+	boxl->addWidget(statusbar_r_status);
+
+	QToolButton* dummy = new QToolButton();
+	dummy->setDefaultAction(interrupt_all_commands);
+	dummy->setFixedHeight(statusbar_r_status->height());
+	dummy->setAutoRaise(true);
+	boxl->addWidget(dummy);
+
+	realbar->addPermanentWidget(box, 0);
+	setRStatus(RInterface::Starting);
 }
 
 void RKWardMainWindow::saveOptions () {
diff --git a/rkward/rkward.h b/rkward/rkward.h
index 747b8039..63cb1c4c 100644
--- a/rkward/rkward.h
+++ b/rkward/rkward.h
@@ -2,7 +2,7 @@
                           rkward.h  -  description
                              -------------------
     begin                : Tue Oct 29 20:06:08 CET 2002
-    copyright            : (C) 2002-2020 by Thomas Friedrichsmeier
+    copyright            : (C) 2002-2022 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -149,7 +149,6 @@ private:
 
 	QLabel* statusbar_r_status;
 	KSqueezedTextLabel* statusbar_cwd;
-	QLabel* statusbar_ready;
 	KParts::PartManager *part_manager;
 
 	// QAction pointers to enable/disable actions
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index 21111125..d59ec5da 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -378,7 +378,7 @@ void RKCommandEditorWindow::initializeActions (KActionCollection* ac) {
 
 	action_setwd_to_script = ac->addAction ("setwd_to_script", this, SLOT (setWDToScript()));
 	action_setwd_to_script->setText (i18n ("CD to script directory"));
-	action_setwd_to_script->setStatusTip (i18n ("Change the working directory to the directory of this script"));
+	action_setwd_to_script->setWhatsThis(i18n ("Change the working directory to the directory of this script"));
 	action_setwd_to_script->setToolTip (action_setwd_to_script->statusTip ());
 	action_setwd_to_script->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionCDToScript));
 
@@ -398,7 +398,7 @@ void RKCommandEditorWindow::initializeActions (KActionCollection* ac) {
 	preview_actions[OutputWindow]->setToolTip (i18n ("Preview any output to the RKWard Output Window. This preview will be empty, if there is no call to <i>rk.print()</i> or other RKWard output commands."));
 	for (int i = 0; i < preview_actions.size (); ++i) {
 		preview_actions[i]->setCheckable (true);
-		preview_actions[i]->setStatusTip (preview_actions[i]->toolTip ());
+		preview_actions[i]->setWhatsThis(preview_actions[i]->toolTip ());
 	}
 	action_no_preview->setChecked (true);
 	connect (preview, &RKXMLGUIPreviewArea::previewClosed, this, &RKCommandEditorWindow::discardPreview);
diff --git a/rkward/windows/rkhtmlwindow.cpp b/rkward/windows/rkhtmlwindow.cpp
index d2cb1771..f25f988a 100644
--- a/rkward/windows/rkhtmlwindow.cpp
+++ b/rkward/windows/rkhtmlwindow.cpp
@@ -887,7 +887,7 @@ void RKHTMLWindowPart::initActions () {
 	actionCollection ()->addAction (KStandardAction::SelectAll, "select_all", window->view->pageAction (RKWebPage::SelectAll), SLOT (trigger()));
 	// unfortunately, this will only affect the default encoding, not necessarily the "real" encoding
 	KCodecAction *encoding = new KCodecAction (QIcon::fromTheme("character-set"), i18n ("Default &Encoding"), this, true);
-	encoding->setStatusTip (i18n ("Set the encoding to assume in case no explicit encoding has been set in the page or in the HTTP headers."));
+	encoding->setWhatsThis(i18n ("Set the encoding to assume in case no explicit encoding has been set in the page or in the HTTP headers."));
 	actionCollection ()->addAction ("view_encoding", encoding);
 	connect (encoding, static_cast<void (KCodecAction::*)(QTextCodec *)>(&KCodecAction::triggered), window, &RKHTMLWindow::setTextEncoding);
 
@@ -923,7 +923,7 @@ void RKHTMLWindowPart::initActions () {
 	activate = actionCollection()->addAction("output_activate", window, SLOT(slotActivate()));
 	activate->setText(i18n("Set Output as &Active"));
 	activate->setIcon(QIcon::fromTheme("emblem-favorite"));
-	activate->setStatusTip(i18n("Set this output as the file to append output to."));
+	activate->setWhatsThis(i18n("Set this output as the file to append output to."));
 
 	actionCollection ()->addAction (KStandardAction::Find, "find", window->findbar, SLOT (activate()));
 	QAction* findAhead = actionCollection ()->addAction ("find_ahead", new QAction (i18n ("Find as you type"), this));
diff --git a/rkward/windows/rktoplevelwindowgui.cpp b/rkward/windows/rktoplevelwindowgui.cpp
index 39cbb479..5f393d38 100644
--- a/rkward/windows/rktoplevelwindowgui.cpp
+++ b/rkward/windows/rktoplevelwindowgui.cpp
@@ -73,9 +73,9 @@ RKTopLevelWindowGUI::RKTopLevelWindowGUI(KXmlGuiWindow *for_window) : QObject(fo
 	actionCollection()->addAction(KStandardAction::ReportBug, "report_bug", this, SLOT(reportRKWardBug()));
 	actionCollection()->addAction(KStandardAction::SwitchApplicationLanguage, "switch_application_language", this, SLOT(showSwitchApplicationLanguage()));
 
-	help_invoke_r_help->setStatusTip (i18n ("Shows the R help index"));
-	show_help_search->setStatusTip (i18n ("Shows/raises the R Help Search window"));
-	show_rkward_help->setStatusTip (i18n ("Show help on RKWard"));
+	help_invoke_r_help->setWhatsThis(i18n ("Shows the R help index"));
+	show_help_search->setWhatsThis(i18n ("Shows/raises the R Help Search window"));
+	show_rkward_help->setWhatsThis(i18n ("Show help on RKWard"));
 
 	// window menu
 	// NOTE: enabling / disabling the prev/next actions is not a good idea. It will cause the script windows to "accept" their shortcuts, when disabled
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index 881d54a3..7460e7a5 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -2,7 +2,7 @@
                           rkworkplace  -  description
                              -------------------
     begin                : Thu Sep 21 2006
-    copyright            : (C) 2006-2020 by Thomas Friedrichsmeier
+    copyright            : (C) 2006-2022 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -33,6 +33,7 @@
 #include <QMimeDatabase>
 #include <QVBoxLayout>
 #include <QHBoxLayout>
+#include <QStatusBar>
 
 #include "detachedwindowcontainer.h"
 #include "rkcommandeditorwindow.h"
@@ -62,6 +63,8 @@
 // static
 RKWorkplace *RKWorkplace::main_workplace = 0;
 
+#include <QLabel> // remove ME
+
 RKWorkplace::RKWorkplace (QWidget *parent) : QWidget (parent) {
 	RK_TRACE (APP);
 	RK_ASSERT (main_workplace == 0);
@@ -109,7 +112,11 @@ RKWorkplace::RKWorkplace (QWidget *parent) : QWidget (parent) {
 	tool_window_bars[RKToolWindowList::Bottom]->setSplitter (vert_splitter);
 	vbox->addWidget (tool_window_bars[RKToolWindowList::Top]);
 	vbox->addWidget (vert_splitter);
-	vbox->addWidget (tool_window_bars[RKToolWindowList::Bottom]);
+	auto bottom_box = new QHBoxLayout();
+	vbox->addLayout(bottom_box);
+	bottom_box->addWidget (tool_window_bars[RKToolWindowList::Bottom]);
+	status_bar = new QStatusBar();
+	bottom_box->addWidget(status_bar, 0, Qt::AlignRight);
 
 	KConfigGroup toolbar_config = KSharedConfig::openConfig ()->group ("ToolwindowBars");
 	for (int i = 0; i < TOOL_WINDOW_BAR_COUNT; ++i) tool_window_bars[i]->restoreSize (toolbar_config);
diff --git a/rkward/windows/rkworkplace.h b/rkward/windows/rkworkplace.h
index 492dee79..1d48b2e9 100644
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@ -2,7 +2,7 @@
                           rkworkplace  -  description
                              -------------------
     begin                : Thu Sep 21 2006
-    copyright            : (C) 2006-2020 by Thomas Friedrichsmeier
+    copyright            : (C) 2006-2022 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -42,6 +42,7 @@ class RKGraphicsDevice;
 class KMessageWidget;
 class QWindow;
 class RKOutputDirectory;
+class QStatusBar;
 
 #define TOOL_WINDOW_BAR_COUNT 4
 
@@ -218,6 +219,7 @@ Has no effect, if RKSettingsModuleGeneral::workplaceSaveMode () != RKSettingsMod
 /** Inserts the given message widget above the central area. While technically, the workplace becomes the parent widget of the message widget, it is the caller's responsibility to
  *  delete the widget, when appropriate. */
 	void addMessageWidget (KMessageWidget *message);
+	QStatusBar* statusBar() { return status_bar; };
 
 /** For window splitting: Copy the given window (or, if that is not possible, create a placeholder window), and attach it to the main view. */
 	void splitAndAttachWindow (RKMDIWindow *source);
@@ -260,6 +262,7 @@ private:
 friend class RKToolWindowBar;
 friend class KatePluginIntegrationWindow;
 	void placeInToolWindowBar (RKMDIWindow *window, int position);
+	QStatusBar *status_bar;
 
 	/** Control placement of windows from R */
 	struct NamedWindow {


More information about the rkward-tracker mailing list