~l3on/ubuntu/precise/rkward/rebuild1

« back to all changes in this revision

Viewing changes to rkward/windows/rkwindowcatcher.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Friedrichsmeier
  • Date: 2008-04-20 21:30:00 UTC
  • mfrom: (1.2.2 upstream) (3.1.9 hardy)
  • Revision ID: james.westby@ubuntu.com-20080420213000-fs4i8efmfc793bnn
new upstream release
closes: #475175
closes: #463348
closes: #475982

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                          rwindowcatcher.cpp  -  description
 
3
                             -------------------
 
4
    begin                : Wed May 4 2005
 
5
    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
 
6
    email                : tfry@users.sourceforge.net
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
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.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include "rkwindowcatcher.h"
 
19
 
 
20
#ifndef DISABLE_RKWINDOWCATCHER
 
21
 
 
22
#include <qlayout.h>
 
23
#include <qvbox.h>
 
24
 
 
25
#include <kmessagebox.h>
 
26
#include <klocale.h>
 
27
#include <kwin.h>
 
28
 
 
29
#include "../rkwardapplication.h"
 
30
#include "rkworkplace.h"
 
31
#include "qxembedcopy.h"
 
32
#include "../debug.h"
 
33
 
 
34
RKWindowCatcher::RKWindowCatcher () {
 
35
        RK_TRACE (MISC);
 
36
}
 
37
 
 
38
RKWindowCatcher::~RKWindowCatcher () {
 
39
        RK_TRACE (MISC);
 
40
}
 
41
 
 
42
void RKWindowCatcher::start (int prev_cur_device) {
 
43
        RK_TRACE (MISC);
 
44
        RK_DO (qDebug ("Window Catcher activated"), RBACKEND, DL_DEBUG);
 
45
 
 
46
        RKWardApplication::getApp ()->startWindowCreationDetection ();
 
47
        last_cur_device = prev_cur_device;
 
48
}
 
49
 
 
50
void RKWindowCatcher::stop (int new_cur_device) {
 
51
        RK_TRACE (MISC);
 
52
        RK_DO (qDebug ("Window Catcher deactivated"), RBACKEND, DL_DEBUG);
 
53
 
 
54
        WId w = RKWardApplication::getApp ()->endWindowCreationDetection ();
 
55
        if (new_cur_device != last_cur_device) {
 
56
                if (w) {
 
57
                        RKWorkplace::mainWorkplace ()->newX11Window (w, new_cur_device);
 
58
                        //new RKCaughtX11Window (w, new_cur_device);
 
59
                } else {
 
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");
 
61
                }
 
62
        }
 
63
        last_cur_device = new_cur_device;
 
64
}
 
65
 
 
66
///////////////////////////////// END RKWindowCatcher //////////////////////////////////
 
67
/**************************************************************************************/
 
68
//////////////////////////////// BEGIN RKCaughtX11Window //////////////////////////////
 
69
 
 
70
 
 
71
#include <qscrollview.h>
 
72
#include <qvbox.h>
 
73
#include <qlabel.h>
 
74
 
 
75
#include <kactionclasses.h>
 
76
#include <kdialogbase.h>
 
77
#include <knuminput.h>
 
78
#include <kiconloader.h>
 
79
 
 
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"
 
86
 
 
87
RKCaughtX11Window::RKCaughtX11Window (WId window_to_embed, int device_number) : RKMDIWindow (0, X11Window) {
 
88
        RK_TRACE (MISC);
 
89
 
 
90
        embedded = window_to_embed;
 
91
        RKCaughtX11Window::device_number = device_number;
 
92
 
 
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);
 
97
 
 
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
 
106
        dynamic_size = true;
 
107
        dynamic_size_action->setChecked (true);
 
108
 
 
109
        QXEmbedCopy *capture = new QXEmbedCopy (xembed_container);
 
110
        capture->setProtocol (QXEmbedCopy::XPLAIN);
 
111
        connect (capture, SIGNAL (embeddedWindowDestroyed ()), this, SLOT (deleteLater ()));
 
112
 
 
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);
 
118
 
 
119
        RKWardApplication::getApp ()->registerNameWatcher (window_to_embed, this);
 
120
}
 
121
 
 
122
RKCaughtX11Window::~RKCaughtX11Window () {
 
123
        RK_TRACE (MISC);
 
124
 
 
125
        RKWardApplication::getApp ()->unregisterNameWatcher (embedded);
 
126
        error_dialog->autoDeleteWhenDone ();
 
127
}
 
128
 
 
129
void RKCaughtX11Window::prepareToBeAttached () {
 
130
        RK_TRACE (MISC);
 
131
 
 
132
        dynamic_size_action->setChecked (false);
 
133
        fixedSizeToggled ();
 
134
        dynamic_size_action->setEnabled (false);
 
135
}
 
136
 
 
137
void RKCaughtX11Window::prepareToBeDetached () {
 
138
        RK_TRACE (MISC);
 
139
 
 
140
        dynamic_size_action->setEnabled (true);
 
141
}
 
142
 
 
143
void RKCaughtX11Window::fixedSizeToggled () {
 
144
        RK_TRACE (MISC);
 
145
 
 
146
        if (dynamic_size == dynamic_size_action->isChecked ()) return;
 
147
        dynamic_size = dynamic_size_action->isChecked ();
 
148
 
 
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 ();
 
153
                box_widget->show ();
 
154
                xembed_container->setMinimumSize (5, 5);
 
155
                xembed_container->setMaximumSize (32767, 32767);
 
156
        } else {
 
157
                xembed_container->setFixedSize (xembed_container->size ());
 
158
                xembed_container->reparent (scroll_widget->viewport (), QPoint (0, 0), true);
 
159
                scroll_widget->addChild (xembed_container);
 
160
                box_widget->hide ();
 
161
                scroll_widget->show ();
 
162
        }
 
163
}
 
164
 
 
165
void RKCaughtX11Window::setFixedSize1 () {
 
166
        RK_TRACE (MISC);
 
167
 
 
168
        dynamic_size_action->setChecked (false);
 
169
        fixedSizeToggled ();            // apparently KToggleAction::setChecked () does not invoke the slot!
 
170
        xembed_container->setFixedSize (500, 500);
 
171
}
 
172
 
 
173
void RKCaughtX11Window::setFixedSize2 () {
 
174
        RK_TRACE (MISC);
 
175
 
 
176
        dynamic_size_action->setChecked (false);
 
177
        fixedSizeToggled ();            // see setFixedSize1 () above
 
178
        xembed_container->setFixedSize (1000, 1000);
 
179
}
 
180
 
 
181
void RKCaughtX11Window::setFixedSize3 () {
 
182
        RK_TRACE (MISC);
 
183
 
 
184
        dynamic_size_action->setChecked (false);
 
185
        fixedSizeToggled ();            // see setFixedSize1 () above
 
186
        xembed_container->setFixedSize (2000, 2000);
 
187
}
 
188
 
 
189
void RKCaughtX11Window::setFixedSizeManual () {
 
190
        RK_TRACE (MISC);
 
191
 
 
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 ();
 
195
 
 
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);
 
199
 
 
200
        label = new QLabel (i18n ("Height"), page);
 
201
        KIntSpinBox *height = new KIntSpinBox (5, 32767, 1, xembed_container->height (), 10, page);
 
202
 
 
203
        dialog->exec ();
 
204
 
 
205
        if (dialog->result () == QDialog::Accepted) {
 
206
                dynamic_size_action->setChecked (false);
 
207
                fixedSizeToggled ();            // see setFixedSize1 () above
 
208
 
 
209
                xembed_container->setFixedSize (width->value (), height->value ());
 
210
        }
 
211
 
 
212
        delete dialog;
 
213
}
 
214
 
 
215
void RKCaughtX11Window::activateDevice () {
 
216
        RK_TRACE (MISC);
 
217
 
 
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);
 
219
}
 
220
 
 
221
void RKCaughtX11Window::copyDeviceToOutput () {
 
222
        RK_TRACE (MISC);
 
223
 
 
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);
 
225
}
 
226
 
 
227
void RKCaughtX11Window::printDevice () {
 
228
        RK_TRACE (MISC);
 
229
 
 
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);
 
231
}
 
232
 
 
233
void RKCaughtX11Window::copyDeviceToRObject () {
 
234
        RK_TRACE (MISC);
 
235
 
 
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 ();
 
239
 
 
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);
 
243
 
 
244
        dialog->exec ();
 
245
 
 
246
        if (dialog->result () == QDialog::Accepted) {
 
247
                RK_ASSERT (chooser->isOk ());
 
248
 
 
249
                QString name = chooser->validizedSelectedObjectName ();
 
250
 
 
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);
 
252
        }
 
253
 
 
254
        delete dialog;
 
255
}
 
256
 
 
257
void RKCaughtX11Window::duplicateDevice () {
 
258
        RK_TRACE (MISC);
 
259
 
 
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);
 
261
}
 
262
 
 
263
 
 
264
///////////////////////////////// END RKCaughtX11Window ///////////////////////////////
 
265
/**************************************************************************************/
 
266
//////////////////////////////// BEGIN RKCaughtX11WindowPart //////////////////////////
 
267
 
 
268
 
 
269
RKCaughtX11WindowPart::RKCaughtX11WindowPart (RKCaughtX11Window *window) : KParts::Part (0) {
 
270
        RK_TRACE (MISC);
 
271
 
 
272
        KInstance* instance = new KInstance ("rkward");
 
273
        setInstance (instance);
 
274
 
 
275
        setWidget (window);
 
276
        RKCaughtX11WindowPart::window = window;
 
277
 
 
278
        setXMLFile ("rkcatchedx11windowpart.rc");
 
279
 
 
280
        window->dynamic_size_action = new KToggleAction (i18n ("Draw area follows size of window"), 0, window, SLOT (fixedSizeToggled ()), actionCollection (), "toggle_fixed_size");
 
281
 
 
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");
 
286
 
 
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");
 
292
 
 
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);
 
301
}
 
302
 
 
303
RKCaughtX11WindowPart::~RKCaughtX11WindowPart () {
 
304
        RK_TRACE (MISC);
 
305
}
 
306
 
 
307
#include "rkwindowcatcher.moc"
 
308
 
 
309
#endif // DISABLE_RKWINDOWCATCHER