[rkward/frameworks] /: Merge branch 'master' into frameworks
Thomas Friedrichsmeier
thomas.friedrichsmeier at ruhr-uni-bochum.de
Mon Jan 11 20:25:59 UTC 2016
Git commit 924ea47cb379497e8bf3d43b0b509f68b9178b27 by Thomas Friedrichsmeier.
Committed on 11/01/2016 at 20:25.
Pushed by tfry into branch 'frameworks'.
Merge branch 'master' into frameworks
M +8 -0 ChangeLog
M +20 -20 rkward/core/rkvariable.cpp
M +0 -2 rkward/core/rkvariable.h
M +1 -1 rkward/core/robject.h
M +19 -4 rkward/dataeditor/twintable.cpp
M +5 -1 rkward/dataeditor/twintable.h
M +111 -45 rkward/plugin/rkpreviewbox.cpp
M +21 -7 rkward/plugin/rkpreviewbox.h
M +11 -3 rkward/plugin/rkstandardcomponent.cpp
M +3 -1 rkward/plugin/rkstandardcomponent.h
M +169 -39 rkward/plugin/rkstandardcomponentgui.cpp
M +3 -1 rkward/rbackend/rinterface.cpp
M +2 -0 rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
M +5 -25 rkward/settings/rksettingsmoduleplugins.cpp
M +6 -3 rkward/settings/rksettingsmoduleplugins.h
M +73 -5 rkward/windows/rkmdiwindow.cpp
M +13 -1 rkward/windows/rkmdiwindow.h
M +8 -43 rkward/windows/rkwindowcatcher.cpp
M +1 -14 rkward/windows/rkwindowcatcher.h
M +126 -1 rkward/windows/rkworkplace.cpp
M +28 -1 rkward/windows/rkworkplace.h
M +3 -2 rkward/windows/robjectbrowser.cpp
http://commits.kde.org/rkward/924ea47cb379497e8bf3d43b0b509f68b9178b27
diff --cc ChangeLog
index 779d187,9bcc43f..a219040
--- a/ChangeLog
+++ b/ChangeLog
@@@ -1,9 -1,11 +1,17 @@@
+- File selection fields in plugin dialogs remember the last used directory (per session), and check for a valid selection
+- Better handling of text drag-and-drop inside the R console window
+
+--- Version 0.6.5 - XXXXXXXXXXXXXXX
+
+
+ - Fixed: Numerical (display) precision setting was not honored in data editor
+ - Fix several window activation quirks in "Focus follows mouse" mode
+ - File selectors in "Import XYZ" plugins now filter for standard file extensions, by default
+ - Add previews for CSV, SPSS, and Stata import plugins
+ - Allow previews for data, (HTML) output, and custom types of previews
+ - Allow previews to be docked to the dialog window
+ - Implicitly save code preview visibility and size (instead of the former explicit settings)
+ - data.frame objects outside of globalenv() can be opened read-only in an editor window
- Show a warning screen when invoking plugins from the command line (or from clicking an rkward://-link in an external application)
--- Version 0.6.4 - Dec-20-2015
diff --cc rkward/dataeditor/twintable.cpp
index 2d78d98,ecfab36..99a504e
--- a/rkward/dataeditor/twintable.cpp
+++ b/rkward/dataeditor/twintable.cpp
@@@ -193,9 -190,21 +195,21 @@@ void TwinTable::initTable (RKVarEditMod
addNotificationType (RObjectListener::MetaChanged);
listenForObject (object);
objectMetaChanged (object);
- connect (model, SIGNAL (hasDuplicates(QStringList)), this, SLOT (containsDuplicates(QStringList)));
+ connect (model, &RKVarEditModel::hasDuplicates, this, &TwinTable::containsDuplicates);
}
+ void TwinTable::setWindowStyleHint (const QString& hint) {
+ RK_TRACE (EDITOR);
+ if (hint == "preview") { // preview skin: Squeeze header as much as possible
+ metaview->horizontalHeader ()->hide ();
+ metaview->setMinimumHeight (metaview->rowHeight (0));
+ // Now, I just don't understand QSplitter sizing, here... Despite stretch factors being set, metaview continues to be the first to grow.
+ // Forcing minimum heigt of dataview help allocating initial size to the dataview, though.
+ dataview->setMinimumHeight (dataview->rowHeight (0) * 5);
+ }
+ RKMDIWindow::setWindowStyleHint (hint);
+ }
+
void TwinTable::containsDuplicates (const QStringList& dupes) {
RK_TRACE (EDITOR);
diff --cc rkward/dataeditor/twintable.h
index 014e417,a43f566..bb12b42
--- a/rkward/dataeditor/twintable.h
+++ b/rkward/dataeditor/twintable.h
@@@ -30,7 -30,8 +30,8 @@@
class TwinTableMember;
class RKVarEditModel;
class QActionGroup;
-class KAction;
+class QAction;
+ class QSplitter;
/**
*@author Thomas Friedrichsmeier
diff --cc rkward/plugin/rkpreviewbox.cpp
index 4702917,7ffa5bb..919f6c5
--- a/rkward/plugin/rkpreviewbox.cpp
+++ b/rkward/plugin/rkpreviewbox.cpp
@@@ -55,9 -60,9 +60,9 @@@ RKPreviewBox::RKPreviewBox (const QDomE
toggle_preview_box = new QCheckBox (xml->i18nStringAttribute (element, "label", i18n ("Preview"), DL_INFO), this);
vbox->addWidget (toggle_preview_box);
toggle_preview_box->setChecked (preview_active);
- connect (toggle_preview_box, SIGNAL (stateChanged(int)), this, SLOT (changedState(int)));
+ connect (toggle_preview_box, &QCheckBox::stateChanged, this, &RKPreviewBox::changedStateFromUi);
- // status lable
+ // status label
status_label = new QLabel (QString (), this);
vbox->addWidget (status_label);
diff --cc rkward/plugin/rkpreviewbox.h
index 89ba0c1,c5028c9..24222a0
--- a/rkward/plugin/rkpreviewbox.h
+++ b/rkward/plugin/rkpreviewbox.h
@@@ -41,9 -41,9 +41,9 @@@ public
~RKPreviewBox ();
int type () { return ComponentPreviewBox; };
RKComponentPropertyBool *state;
- QVariant value (const QString &modifier=QString ()) { return (state->value (modifier)); };
+ QVariant value (const QString &modifier=QString ()) override;
public slots:
- void changedState (int);
+ void changedStateFromUi ();
void changedState (RKComponentPropertyBase *);
void changedCode (RKComponentPropertyBase *);
void tryPreviewNow ();
diff --cc rkward/plugin/rkstandardcomponentgui.cpp
index 543afe4,6678f40..ee180df
--- a/rkward/plugin/rkstandardcomponentgui.cpp
+++ b/rkward/plugin/rkstandardcomponentgui.cpp
@@@ -18,14 -18,12 +18,12 @@@
#include "rkstandardcomponentgui.h"
#include <klocale.h>
-#include <kaction.h>
+#include <QAction>
#include <kactioncollection.h>
-#include <kurl.h>
+#include <QUrl>
#include <kvbox.h>
- #include <khbox.h>
#include <qtimer.h>
- #include <qlayout.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <QCloseEvent>
@@@ -58,9 -64,14 +64,14 @@@ RKStandardComponentGUI::RKStandardCompo
// code update timer
code_update_timer = new QTimer (this);
code_update_timer->setSingleShot (true);
- connect (code_update_timer, SIGNAL (timeout()), this, SLOT (updateCodeNow()));
+ connect (code_update_timer, &QTimer::timeout, this, &RKStandardComponentGUI::updateCodeNow);
if (!enslaved) {
+ // code display
+ code_display = new RKCommandEditorWindow (0, true, false);
+ code_display->setReadOnly (true);
+ addDockedPreview (code_display, &code_display_visibility, i18n ("Code Preview"), RKSettingsModulePlugins::defaultCodeHeight ());
+
KActionCollection *action_collection = new KActionCollection (this);
action_collection->addAction (KStandardAction::Copy, this, SLOT (copyCode()));
}
@@@ -120,26 -148,68 +148,68 @@@ void RKStandardComponentGUI::createDial
}
vbox->addStretch (2);
- toggle_code_button = new QPushButton (i18n ("Code"), upper_widget);
- toggle_code_button->setCheckable (true);
- connect (toggle_code_button, &QPushButton::clicked, this, &RKStandardComponentGUI::toggleCode);
- vbox->addWidget (toggle_code_button);
- if (enslaved) toggle_code_button->hide ();
-
- // code display
- code_display = new RKCommandEditorWindow (this, true, false);
- code_display->setReadOnly (true);
- code_display->setMinimumHeight (RKSettingsModulePlugins::defaultCodeHeight ());
- code_display->hide ();
+ toggle_code_box = new QCheckBox (i18n ("Code Preview"), upper_widget);
- connect (toggle_code_box, SIGNAL (clicked()), this, SLOT (toggleCode()));
++ connect (toggle_code_box, &QCheckBox::clicked, this, &RKStandardComponentGUI::toggleCode);
+ vbox->addWidget (toggle_code_box);
+ if (enslaved) toggle_code_box->hide ();
- main_vbox->addWidget (upper_widget);
- main_vbox->addWidget (code_display);
+ splitter->addWidget (upper_widget);
+ splitter->setStretchFactor (0, 0); // When resizing the dialog, *and* any preview is visible, effectively resize the preview. Dialog area can be resized via splitter.
+ splitter->setChildrenCollapsible (false); // It's just too difficult to make this consistent, esp. for shrinking the dialog would _also_ be expected to collapse widgets. Besides, this makes it
+ // easier to keep track of which expansions are currently visible.
if (!enslaved && RKSettingsModulePlugins::showCodeByDefault ()) {
- toggle_code_button->setChecked (true); // will trigger showing the code along with the dialog
+ toggle_code_box->setChecked (true); // will trigger showing the code along with the dialog
+ }
+ }
+
+ void RKStandardComponentGUI::finalize () {
+ RK_TRACE (PLUGIN);
+
+ for (int i = 0; i < previews.size (); ++i) {
+ // Add preview to splitter. Also add a title bar to each preview.
+ QWidget *dummy = new QWidget ();
+ QVBoxLayout *vl = new QVBoxLayout (dummy);
+ vl->setContentsMargins (0, 0, 0, 0);
+ QFrame *line = new QFrame (dummy);
+ line->setFrameShape (QFrame::HLine);
+ vl->addWidget (line);
+ QHBoxLayout *hl = new QHBoxLayout ();
+ vl->addLayout (hl);
+ QLabel *lab = new QLabel (i18n ("<b>%1</b>", previews[i].label), dummy);
+ lab->setAlignment (Qt::AlignCenter);
+ QToolButton *tb = new QToolButton (dummy);
+ tb->setAutoRaise (true);
+ tb->setIcon (RKStandardIcons::getIcon (RKStandardIcons::ActionDelete));
+ tb->setProperty ("preview_area", QVariant::fromValue (dummy));
- connect (tb, SIGNAL (clicked()), this, SLOT (previewCloseButtonClicked()));
++ connect (tb, &QAbstractButton::clicked, this, &RKStandardComponentGUI::previewCloseButtonClicked);
+ hl->addStretch ();
+ hl->addWidget (lab);
+ hl->addWidget (tb);
+ hl->addStretch ();
+
+ vl->addWidget (previews[i].area);
+ previews[i].area->show ();
+ previews[i].area = dummy;
+ if (!(previews[i].controller->boolValue ())) dummy->hide ();
+ splitter->insertWidget (i+1, previews[i].area);
+ splitter->setStretchFactor (i+1, 1);
}
}
+ void RKStandardComponentGUI::addDockedPreview (QWidget *area, RKComponentPropertyBool *controller, const QString& label, int sizehint) {
+ RK_TRACE (PLUGIN);
+
+ PreviewArea parea;
+ parea.area = area;
+ parea.controller = controller;
+ parea.sizehint = sizehint;
+ parea.label = label;
+ previews.insert (0, parea);
+
- connect (controller, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (previewVisibilityChanged(RKComponentPropertyBase*)));
++ connect (controller, &RKComponentPropertyBase::valueChanged, this, &RKStandardComponentGUI::previewVisibilityChanged);
+ };
+
void RKStandardComponentGUI::showEvent (QShowEvent *e) {
RK_TRACE (PLUGIN);
diff --cc rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
index 4a3b9ba,693fccb..775f05e
--- a/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
+++ b/rkward/rbackend/rkwarddevice/rkgraphicsdevice_frontendtransmitter.cpp
@@@ -187,9 -187,11 +187,11 @@@ void RKGraphicsDeviceFrontendTransmitte
streamer.instream >> width >> height >> title >> antialias;
device = RKGraphicsDevice::newDevice (devnum, width, height, title, antialias);
RKWorkplace::mainWorkplace ()->newRKWardGraphisWindow (device, devnum+1);
- connect (device, SIGNAL (locatorDone(bool,double,double)), this, SLOT (locatorDone(bool,double,double)));
- connect (device, SIGNAL (newPageConfirmDone(bool)), this, SLOT (newPageConfirmDone(bool)));
- connect (this, SIGNAL (stopInteraction()), device, SLOT (stopInteraction()));
+ connect (device, &RKGraphicsDevice::locatorDone, this, &RKGraphicsDeviceFrontendTransmitter::locatorDone);
+ connect (device, &RKGraphicsDevice::newPageConfirmDone, this, &RKGraphicsDeviceFrontendTransmitter::newPageConfirmDone);
+ connect (this, &RKGraphicsDeviceFrontendTransmitter::stopInteraction, device, &RKGraphicsDevice::stopInteraction);
+ streamer.outstream << (qint32) 1; // dummy reply
+ streamer.writeOutBuffer ();
continue;
} else {
if (devnum) device = RKGraphicsDevice::devices.value (devnum);
diff --cc rkward/settings/rksettingsmoduleplugins.cpp
index e020b14,ca3a98c..c9e2a77
--- a/rkward/settings/rksettingsmoduleplugins.cpp
+++ b/rkward/settings/rksettingsmoduleplugins.cpp
@@@ -78,31 -79,9 +79,9 @@@ RKSettingsModulePlugins::RKSettingsModu
button_group->addButton (button, PreferWizard);
if ((button = button_group->button (interface_pref))) button->setChecked (true);
- connect (button_group, SIGNAL (buttonClicked(int)), this, SLOT (settingChanged()));
+ connect (button_group, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &RKSettingsModulePlugins::settingChanged);
main_vbox->addWidget (button_box);
-
- main_vbox->addSpacing (2*RKGlobals::spacingHint ());
-
-
- QGroupBox *code_frame = new QGroupBox (i18n ("R syntax display (in dialogs)"), this);
- group_layout = new QVBoxLayout (code_frame);
-
- show_code_box = new QCheckBox (i18n ("Code shown by default"), code_frame);
- show_code_box->setChecked (show_code);
- connect (show_code_box, &QCheckBox::stateChanged, this, &RKSettingsModulePlugins::settingChanged);
- group_layout->addWidget (show_code_box);
-
- KHBox *code_size_hbox = new KHBox (code_frame);
- new QLabel (i18n ("Default height of code display (pixels)"), code_size_hbox);
- code_size_box = new RKSpinBox (code_size_hbox);
- code_size_box->setIntMode (20, 5000, code_size);
- connect (code_size_box, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &RKSettingsModulePlugins::settingChanged);
- group_layout->addWidget (code_size_hbox);
-
- main_vbox->addWidget (code_frame);
-
-
main_vbox->addSpacing (2*RKGlobals::spacingHint ());
QPushButton *pluginmap_config_button = new QPushButton (i18n ("Configure Active Plugins"), this);
diff --cc rkward/windows/rkmdiwindow.cpp
index 6c7576e,17be69c..1f08015
--- a/rkward/windows/rkmdiwindow.cpp
+++ b/rkward/windows/rkmdiwindow.cpp
@@@ -22,12 -22,13 +22,13 @@@
#include <qtimer.h>
#include <QEvent>
#include <QPaintEvent>
++#include <QAction>
-#include <kparts/event.h>
+#include <kparts/partactivateevent.h>
#include <kxmlguifactory.h>
#include <kactioncollection.h>
#include <klocale.h>
- #include <QAction>
-#include <kaction.h>
+ #include <kpassivepopup.h>
#include "rkworkplace.h"
#include "rkworkplaceview.h"
@@@ -254,20 -259,44 +259,47 @@@ void RKMDIWindow::paintEvent (QPaintEve
}
}
-void RKMDIWindow::windowActivationChange (bool) {
+void RKMDIWindow::changeEvent (QEvent *event) {
RK_TRACE (APP);
- // NOTE: active is NOT the same as isActive(). Active just means that this window *would* be active, if its toplevel window is active.
- if (active || (!isAttached ())) update ();
+ if (event->type () == QEvent::ActivationChange) {
+ // NOTE: active is NOT the same as isActive(). Active just means that this window *would* be active, if its toplevel window is active.
+ if (active || (!isAttached ())) update ();
+ }
+ QFrame::changeEvent (event);
}
- void RKMDIWindow::slotActivate () {
+ void RKMDIWindow::slotActivateForFocusFollowsMouse () {
RK_TRACE (APP);
+ if (!underMouse ()) return;
+
+ // we can't do without activateWindow(), below. Unfortunately, this has the side effect of raising the window (in some cases). This is not always what we want, e.g. if a
+ // plot window is stacked above this window. (And since this is activation by mouse hover, this window is already visible, by definition!)
+ // So we try a heuristic (imperfect) to find, if there are any other windows stacked above this one, in order to re-raise them above this.
+ QWidgetList toplevels = qApp->topLevelWidgets ();
+ QWidgetList overlappers;
+ QWidget *window = topLevelWidget ();
+ QRect rect = window->frameGeometry ();
+ for (int i = toplevels.size () - 1; i >= 0; --i) {
+ QWidget *tl = toplevels[i];
+ if (!tl->isWindow ()) continue;
+ if (tl == window) continue;
+ if (tl->isHidden ()) continue;
+
+ QRect tlrect = tl->geometry ();
+ QRect intersected = tlrect.intersected (rect);
+ if (!intersected.isEmpty ()) {
+ QWidget *above = qApp->topLevelAt ((intersected.left () +intersected.right ()) / 2, (intersected.top () +intersected.bottom ()) / 2);
+ if (above && (above != window) && (above->isWindow ()) && (!above->isHidden ()) && (overlappers.indexOf (above) < 0)) overlappers.append (above);
+ }
+ }
+
activate (true);
+
+ for (int i = 0; i < overlappers.size (); ++i) {
+ overlappers[i]->raise ();
+ }
}
void RKMDIWindow::enterEvent (QEvent *event) {
@@@ -288,7 -322,37 +325,38 @@@
QFrame::enterEvent (event);
}
+ void RKMDIWindow::setStatusMessage (const QString& message, RCommand *command) {
+ RK_TRACE (MISC);
+
+ if (!status_popup) {
+ status_popup = new KPassivePopup (this);
+ status_popup->setTimeout (0);
- disconnect (status_popup, SIGNAL (clicked()), status_popup, SLOT (hide())); // no auto-hiding, please
++ disconnect (status_popup, SIGNAL (clicked()), status_popup, SLOT (hide())); // no auto-hiding, please, either SIGNAL / SLOT mechanism
++ disconnect (status_popup, static_cast<void (KPassivePopup::*)()>(&KPassivePopup::clicked), status_popup, &QWidget::hide);
+ }
+
- if (command) connect (command->notifier (), SIGNAL (commandFinished (RCommand*)), this, SLOT (clearStatusMessage()));
++ if (command) connect (command->notifier (), &RCommandNotifier::commandFinished, this, &RKMDIWindow::clearStatusMessage);
+ if (!message.isEmpty ()) {
+ status_popup->setView (QString (), message);
+ status_popup->show (this->mapToGlobal (QPoint (20, 20)));
+ } else {
+ status_popup->hide ();
+ }
+ }
+
+ void RKMDIWindow::clearStatusMessage () {
+ RK_TRACE (APP);
+
+ setStatusMessage (QString ());
+ }
+
+ void RKMDIWindow::setWindowStyleHint (const QString& hint) {
+ RK_TRACE (APP);
+
+ if (hint == "preview") no_border_when_active = true;
+ }
+
-void RKMDIWindow::setMetaInfo (const QString& _generic_window_name, const QString& _help_url, RKSettings::SettingsPage _settings_page) {
+void RKMDIWindow::setMetaInfo (const QString& _generic_window_name, const QUrl& _help_url, RKSettings::SettingsPage _settings_page) {
RK_TRACE (APP);
// only meant to be called once
diff --cc rkward/windows/rkmdiwindow.h
index 20c357c,dfa2d4f..8243ec8
--- a/rkward/windows/rkmdiwindow.h
+++ b/rkward/windows/rkmdiwindow.h
@@@ -102,8 -103,14 +104,14 @@@ public
virtual void prepareToBeDetached ();
/** Tool windows will only hide themselves, and ignore the also_delete flag */
virtual bool close (bool also_delete);
+ /** Set a status message to be shown in a popup inside the window. The message persists until the given R command has finished, or until this function is called with an empty string.
+ This should be used, when the information shown is currently out-of-date (e.g. when refreshing a preview / loading a plot from history), _not_ when the window
+ is simply busy (e.g. when saving the current plot to history). */
+ void setStatusMessage (const QString& message, RCommand* command=0);
+ /** Set a style hint for the window. So far the only interpreted style hint is "preview", and not all windows implement it. Base implements hiding of "active" indicator border for "preview"s. */
+ virtual void setWindowStyleHint (const QString& hint);
- bool eventFilter (QObject *watched, QEvent *e);
+ bool eventFilter (QObject *watched, QEvent *e) override;
bool acceptsEventsFor (QObject *object);
/** Whether the window is active. This seems to be more reliable than hasFocus () */
bool isActive ();
@@@ -120,15 -127,16 +128,16 @@@ signals
protected slots:
void showWindowHelp ();
void showWindowSettings ();
+ void clearStatusMessage ();
protected:
void setPart (KParts::Part *p) { part = p; };
- void setMetaInfo (const QString& generic_window_name, const QString& help_url, RKSettings::SettingsPage settings_page=RKSettings::NoPage);
+ void setMetaInfo (const QString& generic_window_name, const QUrl& help_url, RKSettings::SettingsPage settings_page=RKSettings::NoPage);
void initializeActivationSignals ();
- void paintEvent (QPaintEvent *e);
- void windowActivationChange (bool);
+ void paintEvent (QPaintEvent *e) override;
+ void changeEvent (QEvent *event) override;
/** reimplemented from QWidget to emulate focus-follows-mouse behavior */
- void enterEvent (QEvent *event);
+ void enterEvent (QEvent *event) override;
/** @see globalContextProperty() */
void setGlobalContextProperty (const QString& property, const QString& value) { global_context_properties.insert (property, value); };
friend class RKWorkplace;
@@@ -147,8 -156,10 +157,10 @@@ friend class RKToolWindowBar
/** @see globalContextProperty() */
QMap<QString, QString> global_context_properties;
QString generic_window_name;
- QString help_url;
+ QUrl help_url;
RKSettings::SettingsPage settings_page;
+
+ KPassivePopup* status_popup;
};
#endif
diff --cc rkward/windows/rkwindowcatcher.cpp
index f90c452,dfbb613..021e04d
--- a/rkward/windows/rkwindowcatcher.cpp
+++ b/rkward/windows/rkwindowcatcher.cpp
@@@ -289,14 -240,16 +284,16 @@@ void RKCaughtX11Window::doEmbed ()
#elif defined Q_WS_X11
capture = new QX11EmbedContainer (xembed_container);
capture->embedClient (embedded);
- connect (capture, SIGNAL (clientClosed()), this, SLOT (deleteLater()));
+ connect (capture, &QWidget::clientClosed, this, &RKCaughtX11Window::deleteLater);
- RKWardApplication::getApp ()->registerNameWatcher (embedded, this);
+ RKWindowCatcher::registerNameWatcher (embedded, this);
#endif
}
- // make xembed_container resizable, again, now that it actually has a content
- dynamic_size_action->setChecked (true);
- fixedSizeToggled ();
+ if (!isAttached ()) {
+ // make xembed_container resizable, again, now that it actually has a content
+ dynamic_size_action->setChecked (true);
+ fixedSizeToggled ();
+ }
// try to be helpful when the window is too large to fit on screen
QRect dims = window ()->frameGeometry ();
@@@ -313,10 -266,9 +310,9 @@@ RKCaughtX11Window::~RKCaughtX11Window (
close (false);
#ifdef Q_WS_X11
- if (embedded) RKWardApplication::getApp ()->unregisterNameWatcher (embedded);
+ if (embedded) RKWindowCatcher::unregisterNameWatcher (embedded);
#endif
error_dialog->autoDeleteWhenDone ();
- delete status_popup;
}
void RKCaughtX11Window::forceClose () {
diff --cc rkward/windows/rkwindowcatcher.h
index 096ef51,632148d..32b2a02
--- a/rkward/windows/rkwindowcatcher.h
+++ b/rkward/windows/rkwindowcatcher.h
@@@ -205,20 -181,17 +195,17 @@@ private
bool dynamic_size;
KToggleAction *dynamic_size_action;
- KAction *plot_prev_action;
- KAction *plot_next_action;
- KAction *plot_first_action;
- KAction *plot_last_action;
- KAction *plot_force_append_action;
- KAction *plot_remove_action;
- KAction *plot_clear_history_action;
- KAction *plot_properties_action;
+ QAction *plot_prev_action;
+ QAction *plot_next_action;
+ QAction *plot_first_action;
+ QAction *plot_last_action;
+ QAction *plot_force_append_action;
+ QAction *plot_remove_action;
+ QAction *plot_clear_history_action;
+ QAction *plot_properties_action;
KSelectAction *plot_list_action;
- KAction *stop_interaction;
+ QAction *stop_interaction;
- KPassivePopup* status_popup;
- RCommand* status_change_command;
-
int history_length;
int history_position;
};
diff --cc rkward/windows/rkworkplace.cpp
index 6a9aedd,f16f8a0..8c3a4f5
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@@ -220,10 -212,62 +221,62 @@@ void RKWorkplace::detachWindow (RKMDIWi
void RKWorkplace::addWindow (RKMDIWindow *window, bool attached) {
RK_TRACE (APP);
+ // first handle placement overrides
+ if (window_placement_override == RKMDIWindow::Attached) {
+ if (!attached) window->state = RKMDIWindow::Detached; // Ok, yeah. BAD style. But windows that would go to detached by default would not prepareToBeAttached(), without this.
+ // TODO: Create third state: NotManaged
+ attached = true;
+ } else if (window_placement_override == RKMDIWindow::Detached) {
+ attached = false;
+ }
+
+ // style override. Windows may or may not handle this
+ if (!window_style_override.isEmpty ()) window->setWindowStyleHint (window_style_override);
+
+ // next handle name overrides, if any
+ if (!window_name_override.isEmpty ()) {
+ int pos = -1;
+ for (int i = 0; i < named_windows.size (); ++i) {
+ if (named_windows[i].id == window_name_override) {
+ pos = i;
+ break;
+ }
+ }
+ if (pos < 0) { // not yet known: implicit registration -> create corresponing named_window_spec on the fly.
+ registerNamedWindow (window_name_override, 0, attached ? RKWardMainWindow::getMain () : 0);
+ pos = named_windows.size () - 1;
+ }
+
+ NamedWindow &nw = named_windows[pos];
+ if (nw.window != window) {
+ if (nw.window) { // kill existing window (going to be replaced)
+ // TODO: this is not really elegant, yet, as it will change tab-placement (for attached windows), and discard / recreate container (for detached windows)
- disconnect (nw.window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
++ disconnect (nw.window, &QObject::destroyed, this, &RKWorkplace::namedWindowDestroyed);
+ nw.window->deleteLater ();
+ }
+ nw.window = window;
- connect (nw.window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
++ connect (nw.window, &QObject::destroyed, this, &RKWorkplace::namedWindowDestroyed);
+ }
+ named_windows[pos] = nw;
+
+ // add window in the correct area
+ if (nw.parent == RKWardMainWindow::getMain ()) attached = true;
+ else if (nw.parent == 0) attached = false;
+ else { // custom parent
+ window->prepareToBeAttached ();
+ window->setParent (nw.parent);
+ // TODO: do this is somewhat inconsistent. But such windows are not attached to the main workplace view, which makes them rather behave detached.
+ window->state = RKMDIWindow::Detached;
+ // NOTE: The window is _not_ added to the window list/window history in this case.
+ return;
+ }
+ }
+
windows.append (window);
- connect (window, SIGNAL (destroyed(QObject*)), this, SLOT (removeWindow(QObject*)));
- connect (window, SIGNAL (windowActivated(RKMDIWindow*)), history, SLOT (windowActivated(RKMDIWindow*)));
+ connect (window, &QObject::destroyed, this, &RKWorkplace::removeWindow);
+ connect (window, &RKMDIWindow::windowActivated, history, &RKMDIWindowHistory::windowActivated);
if (window->isToolWindow () && !window->tool_window_bar) return;
+
if (attached) attachWindow (window);
else detachWindow (window, false);
}
@@@ -256,10 -300,82 +309,82 @@@ void RKWorkplace::placeInToolWindowBar
else if (needs_registration) attachWindow (window);
}
+ void RKWorkplace::setWindowPlacementOverrides(const QString& placement, const QString& name, const QString& style) {
+ RK_TRACE (APP);
+
+ if (placement == "attached") window_placement_override = RKMDIWindow::Attached;
+ else if (placement == "detached") window_placement_override = RKMDIWindow::Attached;
+ else {
+ RK_ASSERT (placement.isEmpty ());
+ window_placement_override = RKMDIWindow::AnyWindowState;
+ }
+ window_name_override = name;
+ window_style_override = style;
+ }
+
+ void RKWorkplace::registerNamedWindow (const QString& id, QObject* owner, QWidget* parent, RKMDIWindow* window) {
+ RK_TRACE (APP);
+
+ NamedWindow nw;
+ nw.id = id;
+ nw.owner = owner;
+ nw.parent = parent;
+ nw.window = window;
+
+ for (int i = 0; i < named_windows.size (); ++i) {
+ RK_ASSERT (named_windows[i].id != id);
+ }
+
+ named_windows.append (nw);
- if (owner) connect (owner, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowOwnerDestroyed(QObject*)));
- if (window) connect (window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
++ if (owner) connect (owner, &QObject::destroyed, this, &RKWorkplace::namedWindowOwnerDestroyed);
++ if (window) connect (window, &QObject::destroyed, this, &RKWorkplace::namedWindowOwnerDestroyed);
+ }
+
+ RKMDIWindow* RKWorkplace::getNamedWindow (const QString& id) {
+ RK_TRACE (APP);
+
+ for (int i = 0; i < named_windows.size (); ++i) {
+ if (named_windows[i].id == id) {
+ return named_windows[i].window;
+ }
+ }
+
+ return 0;
+ }
+
+ void RKWorkplace::namedWindowDestroyed (QObject* window) {
+ RK_TRACE (APP);
+
+ for (int i = 0; i < named_windows.size (); ++i) {
+ if (named_windows[i].window == window) {
+ if (!named_windows[i].owner) {
+ named_windows.removeAt (i);
+ return;
+ } else {
+ named_windows[i].window = 0;
+ }
+ }
+ }
+ }
+
+ void RKWorkplace::namedWindowOwnerDestroyed (QObject* owner) {
+ RK_TRACE (APP);
+
+ for (int i = 0; i < named_windows.size (); ++i) {
+ if (named_windows[i].owner == owner) {
+ if (named_windows[i].window) {
+ named_windows[i].window->deleteLater ();
+ }
+ named_windows.removeAt (i);
+ return;
+ }
+ }
+ }
+
-bool RKWorkplace::openAnyUrl (const KUrl &url, const QString &known_mimetype, bool force_external) {
+bool RKWorkplace::openAnyUrl (const QUrl &url, const QString &known_mimetype, bool force_external) {
RK_TRACE (APP);
- if (url.protocol () == "rkward") {
+ if (url.scheme () == "rkward") {
if (RKHTMLWindow::handleRKWardURL (url)) return true;
}
KMimeType::Ptr mimetype;
diff --cc rkward/windows/rkworkplace.h
index b91e496,afd8258..6263847
--- a/rkward/windows/rkworkplace.h
+++ b/rkward/windows/rkworkplace.h
@@@ -22,9 -22,8 +22,10 @@@
#include <qstring.h>
#include <qtabwidget.h>
#include <QSplitter>
++#include <QPointer>
-#include <kurl.h>
+#include <QUrl>
+#include <kconfigbase.h>
#include "rkmdiwindow.h"
#include "rktoolwindowlist.h"
@@@ -159,19 -158,29 +160,29 @@@ Has no effect, if RKSettingsModuleGener
static RKMDIWindowHistory *getHistory () { return main_workplace->history; };
void placeToolWindows ();
- void setWorkspaceURL (const KUrl &url, bool keep_config=false);
- KUrl workspaceURL () const { return current_url; };
+ void setWorkspaceURL (const QUrl &url, bool keep_config=false);
+ QUrl workspaceURL () const { return current_url; };
KConfigBase *workspaceConfig ();
- QString portableUrl (const KUrl &url);
+ QString portableUrl (const QUrl &url);
+ /** Register a named area where to place MDI windows. For directing preview windows to a specific location. */
+ void registerNamedWindow (const QString& id, QObject *owner, QWidget* parent, RKMDIWindow *window=0);
+ /** Return the window in the specified named area (can be 0). */
+ RKMDIWindow *getNamedWindow (const QString& id);
+ /** Make the next window to be created appear in a specific location (can be a named window).
+ * @note It is the caller's responsibility to clear the override (by calling setWindowPlacementOverride ()) after the window in question has been created. */
+ void setWindowPlacementOverrides (const QString& placement=QString (), const QString& name=QString (), const QString& style=QString ());
signals:
/** emitted when the workspace Url has changed */
- void workspaceUrlChanged (const KUrl& url);
+ void workspaceUrlChanged (const QUrl &url);
public slots:
/** When windows are attached to the workplace, their QObject::destroyed () signal is connected to this slot. Thereby deleted objects are removed from the workplace automatically */
void removeWindow (QObject *window);
void saveSettings ();
+ private slots:
+ void namedWindowDestroyed (QObject *);
+ void namedWindowOwnerDestroyed (QObject *);
private:
- KUrl current_url;
+ QUrl current_url;
KConfig *_workspace_config;
/** current list of windows. @See getObjectList () */
More information about the rkward-tracker
mailing list