1
/***************************************************************************
2
rwindowcatcher.cpp - description
5
copyright : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
6
email : tfry@users.sourceforge.net
7
***************************************************************************/
9
/***************************************************************************
11
* This program is free software; you can redistribute it and/or modify *
12
* it under the terms of the GNU General Public License as published by *
13
* the Free Software Foundation; either version 2 of the License, or *
14
* (at your option) any later version. *
16
***************************************************************************/
18
#include "rkwindowcatcher.h"
20
#ifndef DISABLE_RKWINDOWCATCHER
25
#include <kmessagebox.h>
29
#include "../rkwardapplication.h"
30
#include "rkworkplace.h"
31
#include "qxembedcopy.h"
34
RKWindowCatcher::RKWindowCatcher () {
38
RKWindowCatcher::~RKWindowCatcher () {
42
void RKWindowCatcher::start (int prev_cur_device) {
44
RK_DO (qDebug ("Window Catcher activated"), RBACKEND, DL_DEBUG);
46
RKWardApplication::getApp ()->startWindowCreationDetection ();
47
last_cur_device = prev_cur_device;
50
void RKWindowCatcher::stop (int new_cur_device) {
52
RK_DO (qDebug ("Window Catcher deactivated"), RBACKEND, DL_DEBUG);
54
WId w = RKWardApplication::getApp ()->endWindowCreationDetection ();
55
if (new_cur_device != last_cur_device) {
57
RKWorkplace::mainWorkplace ()->newX11Window (w, new_cur_device);
58
//new RKCaughtX11Window (w, new_cur_device);
60
KMessageBox::information (0, i18n ("You have created a new X11 device window in R. Usually, RKWard tries to detect such windows, to take control of them, and add a menu-bar to them. This time, however, RKWard failed to detect, which window was created, and so can not embed it.\nIf you created the window on a different screen or X11 display, that is to be expected. You might want to consider changing options(\"display\"), then.\nIf you can see the X11 window on the same screen as this message, then RKWard should do better. In this case, please contact us at rkward-devel@lists.sourceforge.net with details on your setup, so we can try to fix this in future versions of RKWard."), i18n ("Could not embed R X11 window"), "failure_to_detect_x11_device");
63
last_cur_device = new_cur_device;
66
///////////////////////////////// END RKWindowCatcher //////////////////////////////////
67
/**************************************************************************************/
68
//////////////////////////////// BEGIN RKCaughtX11Window //////////////////////////////
71
#include <qscrollview.h>
75
#include <kactionclasses.h>
76
#include <kdialogbase.h>
77
#include <knuminput.h>
78
#include <kiconloader.h>
80
#include "../rkglobals.h"
81
#include "../rbackend/rinterface.h"
82
#include "../core/robject.h"
83
#include "../misc/rkprogresscontrol.h"
84
#include "../misc/rksaveobjectchooser.h"
85
#include "../plugin/rkcomponentcontext.h"
87
RKCaughtX11Window::RKCaughtX11Window (WId window_to_embed, int device_number) : RKMDIWindow (0, X11Window) {
90
embedded = window_to_embed;
91
RKCaughtX11Window::device_number = device_number;
93
error_dialog = new RKProgressControl (0, i18n ("An error occurred"), i18n ("An error occurred"), RKProgressControl::DetailedError);
94
setPart (new RKCaughtX11WindowPart (this));
95
initializeActivationSignals ();
96
setFocusPolicy (QWidget::ClickFocus);
98
QVBoxLayout *layout = new QVBoxLayout (this);
99
box_widget = new QVBox (this);
100
layout->addWidget (box_widget);
101
scroll_widget = new QScrollView (this);
102
scroll_widget->setFrameStyle (QFrame::NoFrame);
103
scroll_widget->hide ();
104
layout->addWidget (scroll_widget);
105
xembed_container = new QVBox (box_widget); // QXEmbed can not be reparented (between the box_widget, and the scroll_widget) directly. Therefore we place it into a container, and reparent that instead
107
dynamic_size_action->setChecked (true);
109
QXEmbedCopy *capture = new QXEmbedCopy (xembed_container);
110
capture->setProtocol (QXEmbedCopy::XPLAIN);
111
connect (capture, SIGNAL (embeddedWindowDestroyed ()), this, SLOT (deleteLater ()));
113
KWin::WindowInfo wininfo = KWin::windowInfo (window_to_embed);
114
setGeometry (wininfo.frameGeometry ());
115
setCaption (wininfo.name ());
116
setIcon (SmallIcon ("kcmx")); // looks like an X, here
117
capture->embed (window_to_embed);
119
RKWardApplication::getApp ()->registerNameWatcher (window_to_embed, this);
122
RKCaughtX11Window::~RKCaughtX11Window () {
125
RKWardApplication::getApp ()->unregisterNameWatcher (embedded);
126
error_dialog->autoDeleteWhenDone ();
129
void RKCaughtX11Window::prepareToBeAttached () {
132
dynamic_size_action->setChecked (false);
134
dynamic_size_action->setEnabled (false);
137
void RKCaughtX11Window::prepareToBeDetached () {
140
dynamic_size_action->setEnabled (true);
143
void RKCaughtX11Window::fixedSizeToggled () {
146
if (dynamic_size == dynamic_size_action->isChecked ()) return;
147
dynamic_size = dynamic_size_action->isChecked ();
149
if (dynamic_size_action->isChecked ()) {
150
scroll_widget->removeChild (xembed_container);
151
xembed_container->reparent (box_widget, QPoint (0, 0), true);
152
scroll_widget->hide ();
154
xembed_container->setMinimumSize (5, 5);
155
xembed_container->setMaximumSize (32767, 32767);
157
xembed_container->setFixedSize (xembed_container->size ());
158
xembed_container->reparent (scroll_widget->viewport (), QPoint (0, 0), true);
159
scroll_widget->addChild (xembed_container);
161
scroll_widget->show ();
165
void RKCaughtX11Window::setFixedSize1 () {
168
dynamic_size_action->setChecked (false);
169
fixedSizeToggled (); // apparently KToggleAction::setChecked () does not invoke the slot!
170
xembed_container->setFixedSize (500, 500);
173
void RKCaughtX11Window::setFixedSize2 () {
176
dynamic_size_action->setChecked (false);
177
fixedSizeToggled (); // see setFixedSize1 () above
178
xembed_container->setFixedSize (1000, 1000);
181
void RKCaughtX11Window::setFixedSize3 () {
184
dynamic_size_action->setChecked (false);
185
fixedSizeToggled (); // see setFixedSize1 () above
186
xembed_container->setFixedSize (2000, 2000);
189
void RKCaughtX11Window::setFixedSizeManual () {
192
// TODO: not very pretty, yet
193
KDialogBase *dialog = new KDialogBase (this, 0, true, i18n ("Specify fixed size"), KDialogBase::Ok|KDialogBase::Cancel);
194
QVBox *page = dialog->makeVBoxMainWidget ();
196
QLabel *label = new QLabel (i18n ("Width"), page);
197
KIntSpinBox *width = new KIntSpinBox (5, 32767, 1, xembed_container->width (), 10, page);
198
width->setEditFocus (true);
200
label = new QLabel (i18n ("Height"), page);
201
KIntSpinBox *height = new KIntSpinBox (5, 32767, 1, xembed_container->height (), 10, page);
205
if (dialog->result () == QDialog::Accepted) {
206
dynamic_size_action->setChecked (false);
207
fixedSizeToggled (); // see setFixedSize1 () above
209
xembed_container->setFixedSize (width->value (), height->value ());
215
void RKCaughtX11Window::activateDevice () {
218
RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ')', RCommand::App, i18n ("Activate graphics device number %1").arg (QString::number (device_number)), error_dialog);
221
void RKCaughtX11Window::copyDeviceToOutput () {
224
RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ")\ndev.copy (device=rk.graph.on)\nrk.graph.off ()", RCommand::App | RCommand::DirectToOutput, i18n ("Copy contents of graphics device number %1 to output").arg (QString::number (device_number)), error_dialog);
227
void RKCaughtX11Window::printDevice () {
230
RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ")\ndev.print ()", RCommand::App, i18n ("Print contents of graphics device number %1").arg (QString::number (device_number)), error_dialog);
233
void RKCaughtX11Window::copyDeviceToRObject () {
236
// TODO: not very pretty, yet
237
KDialogBase *dialog = new KDialogBase (this, 0, true, i18n ("Specify R object"), KDialogBase::Ok|KDialogBase::Cancel);
238
QVBox *page = dialog->makeVBoxMainWidget ();
240
RKSaveObjectChooser *chooser = new RKSaveObjectChooser (page, "my.plot", i18n ("Specify the R object name, you want to save the graph to"));
241
connect (chooser, SIGNAL (okStatusChanged (bool)), dialog, SLOT (enableButtonOK (bool)));
242
if (!chooser->isOk ()) dialog->enableButtonOK (false);
246
if (dialog->result () == QDialog::Accepted) {
247
RK_ASSERT (chooser->isOk ());
249
QString name = chooser->validizedSelectedObjectName ();
251
RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ")\n" + RObject::rQuote (name) + " <- recordPlot ()", RCommand::App | RCommand::ObjectListUpdate, i18n ("Save contents of graphics device number %1 to object '%2'").arg (QString::number (device_number)).arg (name), error_dialog);
257
void RKCaughtX11Window::duplicateDevice () {
260
RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ")\ndev.copy (device=x11)", RCommand::App, i18n ("Duplicate graphics device number %1").arg (QString::number (device_number)), error_dialog);
264
///////////////////////////////// END RKCaughtX11Window ///////////////////////////////
265
/**************************************************************************************/
266
//////////////////////////////// BEGIN RKCaughtX11WindowPart //////////////////////////
269
RKCaughtX11WindowPart::RKCaughtX11WindowPart (RKCaughtX11Window *window) : KParts::Part (0) {
272
KInstance* instance = new KInstance ("rkward");
273
setInstance (instance);
276
RKCaughtX11WindowPart::window = window;
278
setXMLFile ("rkcatchedx11windowpart.rc");
280
window->dynamic_size_action = new KToggleAction (i18n ("Draw area follows size of window"), 0, window, SLOT (fixedSizeToggled ()), actionCollection (), "toggle_fixed_size");
282
new KAction (i18n ("Set fixed size 500x500"), 0, window, SLOT (setFixedSize1 ()), actionCollection (), "set_fixed_size_1");
283
new KAction (i18n ("Set fixed size 1000x1000"), 0, window, SLOT (setFixedSize2 ()), actionCollection (), "set_fixed_size_2");
284
new KAction (i18n ("Set fixed size 2000x2000"), 0, window, SLOT (setFixedSize3 ()), actionCollection (), "set_fixed_size_3");
285
new KAction (i18n ("Set specified fixed size..."), 0, window, SLOT (setFixedSizeManual ()), actionCollection (), "set_fixed_size_manual");
287
new KAction (i18n ("Make active"), 0, window, SLOT (activateDevice ()), actionCollection (), "device_activate");
288
new KAction (i18n ("Copy to output"), 0, window, SLOT (copyDeviceToOutput ()), actionCollection (), "device_copy_to_output");
289
new KAction (i18n ("Print"), 0, window, SLOT (printDevice ()), actionCollection (), "device_print");
290
new KAction (i18n ("Store as R object..."), 0, window, SLOT (copyDeviceToRObject ()), actionCollection (), "device_copy_to_r_object");
291
new KAction (i18n ("Duplicate"), 0, window, SLOT (duplicateDevice ()), actionCollection (), "device_duplicate");
293
// initialize context for plugins
294
RKContextMap *context = RKComponentMap::getContext ("x11");
295
if (!context) return;
296
RKContextHandler *context_handler = context->makeContextHandler (this);
297
insertChildClient (context_handler);
298
RKComponentPropertyInt *devnum_property = new RKComponentPropertyInt (this, false, 0);
299
devnum_property->setIntValue (window->device_number);
300
context_handler->addChild ("devnum", devnum_property);
303
RKCaughtX11WindowPart::~RKCaughtX11WindowPart () {
307
#include "rkwindowcatcher.moc"
309
#endif // DISABLE_RKWINDOWCATCHER