~ubuntu-branches/ubuntu/karmic/rkward/karmic

« back to all changes in this revision

Viewing changes to rkward/windows/rkworkplace.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Friedrichsmeier
  • Date: 2006-11-06 16:30:00 UTC
  • mfrom: (1.2.1 upstream) (3.1.1 feisty)
  • Revision ID: james.westby@ubuntu.com-20061106163000-qi8ju75eqecrfay7
* new upstream release
* depend on either php4-cli or php5-cli

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                          rkworkplace  -  description
 
3
                             -------------------
 
4
    begin                : Thu Sep 21 2006
 
5
    copyright            : (C) 2006 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 "rkworkplace.h"
 
19
 
 
20
#include <kparts/partmanager.h>
 
21
#include <kmessagebox.h>
 
22
#include <klocale.h>
 
23
#include <kiconloader.h>
 
24
 
 
25
#include "detachedwindowcontainer.h"
 
26
#include "rkcommandeditorwindow.h"
 
27
#include "rkhtmlwindow.h"
 
28
#include "rkworkplaceview.h"
 
29
#include "../core/robject.h"
 
30
#include "../core/rcontainerobject.h"
 
31
#include "../core/robjectlist.h"
 
32
#include "../dataeditor/rkeditor.h"
 
33
#include "../dataeditor/rkeditordataframe.h"
 
34
#include "../dataeditor/rkeditordataframepart.h"
 
35
#include "../settings/rksettingsmoduleoutput.h"
 
36
#include "../rbackend/rinterface.h"
 
37
#include "../rbackend/rcommand.h"
 
38
#include "../rkglobals.h"
 
39
#include "../rkward.h"
 
40
 
 
41
#include "../debug.h"
 
42
 
 
43
#define RESTORE_WORKPLACE_COMMAND 1
 
44
 
 
45
// static
 
46
RKWorkplace *RKWorkplace::main_workplace = 0;
 
47
 
 
48
RKWorkplace::RKWorkplace (QWidget *parent) : QObject (parent) {
 
49
        RK_TRACE (APP);
 
50
        RK_ASSERT (main_workplace == 0);
 
51
 
 
52
        main_workplace = this;
 
53
        wview = new RKWorkplaceView (parent);
 
54
}
 
55
 
 
56
RKWorkplace::~RKWorkplace () {
 
57
        RK_TRACE (APP);
 
58
 
 
59
//      closeAll ();    // not needed, as the windows will autodelete themselves using QObject mechanism. Of course, closeAll () should be called *before* quitting.
 
60
}
 
61
 
 
62
void RKWorkplace::attachWindow (RKMDIWindow *window) {
 
63
        RK_TRACE (APP);
 
64
        RK_ASSERT (windows.find (window) != windows.end ());            // This should not happen for now.
 
65
 
 
66
        window->state = RKMDIWindow::Attached;
 
67
        view ()->addPage (window);
 
68
 
 
69
        RK_ASSERT (window->getPart ());
 
70
        RKwardApp::getApp ()->partManager ()->addPart (window->getPart ());
 
71
}
 
72
 
 
73
void RKWorkplace::detachWindow (RKMDIWindow *window) {
 
74
        RK_TRACE (APP);
 
75
        RK_ASSERT (windows.find (window) != windows.end ());            // Can't detach a window that is not attached
 
76
 
 
77
        window->state = RKMDIWindow::Detached;
 
78
 
 
79
        RK_ASSERT (window->getPart ());
 
80
        RKwardApp::getApp ()->partManager ()->removePart (window->getPart ());
 
81
        view ()->removePage (window);
 
82
 
 
83
        DetachedWindowContainer *detached = new DetachedWindowContainer (window);
 
84
        detached->show ();
 
85
}
 
86
 
 
87
void RKWorkplace::addWindow (RKMDIWindow *window) {
 
88
        RK_TRACE (APP);
 
89
 
 
90
        windows.append (window);
 
91
        connect (window, SIGNAL (destroyed (QObject *)), this, SLOT (windowDestroyed (QObject *)));
 
92
        attachWindow (window);
 
93
}
 
94
 
 
95
bool RKWorkplace::openScriptEditor (const KURL &url, bool use_r_highlighting, bool read_only, const QString &force_caption) {
 
96
        RK_TRACE (APP);
 
97
 
 
98
        RKCommandEditorWindow *editor = new RKCommandEditorWindow (view (), use_r_highlighting);
 
99
 
 
100
        if (!url.isEmpty ()) {
 
101
                if (!editor->openURL (url, use_r_highlighting, read_only)) {
 
102
                        delete editor;
 
103
                        KMessageBox::messageBox (view (), KMessageBox::Error, i18n ("Unable to open \"%1\"").arg (url.prettyURL ()), i18n ("Could not open command file"));
 
104
                        return false;
 
105
                }
 
106
        }
 
107
 
 
108
        if (!force_caption.isEmpty ()) editor->setCaption (force_caption);
 
109
        addWindow (editor);
 
110
        return true;
 
111
}
 
112
 
 
113
void RKWorkplace::openHelpWindow (const KURL &url) {
 
114
        RK_TRACE (APP);
 
115
 
 
116
        RKHelpWindow *hw = new RKHelpWindow (view ());
 
117
        if (!url.isEmpty ()) {
 
118
                hw->openURL (url);
 
119
        }
 
120
 
 
121
        addWindow (hw);
 
122
}
 
123
 
 
124
void RKWorkplace::openOutputWindow (const KURL &url) {
 
125
        RK_TRACE (APP);
 
126
 
 
127
        RKOutputWindow::refreshOutput (true, true);
 
128
        if (windows.find (RKOutputWindow::getCurrentOutput ()) == windows.end ()) {
 
129
                addWindow (RKOutputWindow::getCurrentOutput ());
 
130
        }
 
131
}
 
132
 
 
133
void RKWorkplace::newOutput () {
 
134
        RK_TRACE (APP);
 
135
        RKOutputWindow::refreshOutput (RKSettingsModuleOutput::autoShow (), RKSettingsModuleOutput::autoRaise ());
 
136
        if (RKSettingsModuleOutput::autoShow ()) {
 
137
                if (windows.find (RKOutputWindow::getCurrentOutput ()) == windows.end ()) {
 
138
                        addWindow (RKOutputWindow::getCurrentOutput ());
 
139
                }
 
140
        }
 
141
}
 
142
 
 
143
bool RKWorkplace::canEditObject (RObject *object) {
 
144
        RK_TRACE (APP);
 
145
        
 
146
        if (object->isDataFrame ()) {
 
147
                return true;
 
148
        } else if (object->isVariable () && object->getContainer ()->isDataFrame ()) {
 
149
                return true;
 
150
        }
 
151
        return false;
 
152
}
 
153
 
 
154
RKEditor *RKWorkplace::editObject (RObject *object, bool initialize_to_empty) {
 
155
        RK_TRACE (APP);
 
156
 
 
157
        RObject *iobj = object;
 
158
        RKEditor *ed = 0;
 
159
        RKEditorDataFramePart *part = 0;
 
160
        RKEditor *existing_editor = object->objectOpened ();
 
161
        if (!existing_editor) {
 
162
                if (object->isDataFrame ()) {
 
163
                        part = new RKEditorDataFramePart (0);           // TODO: reverse creation logic, just as in the other classes!
 
164
                        ed = part->getEditor ();
 
165
                        // TODO: add child objects, too?
 
166
                        ed->openObject (object, initialize_to_empty);
 
167
                } else if (object->isVariable () && object->getContainer ()->isDataFrame ()) {
 
168
                        existing_editor = object->getContainer ()->objectOpened ();
 
169
                        if (!existing_editor) {
 
170
                                iobj = object->getContainer ();
 
171
                                part = new RKEditorDataFramePart (0);
 
172
                                ed = part->getEditor ();
 
173
                                // TODO: add child objects, too?
 
174
                                ed->openObject (iobj, initialize_to_empty);
 
175
                                // ed->focusObject (obj);
 
176
                        }
 
177
                }
 
178
 
 
179
                if (ed) {
 
180
                        ed->setCaption (iobj->getShortName ());         // TODO: move to editor
 
181
                        ed->setIcon (SmallIcon ("spreadsheet"));
 
182
                        addWindow (ed);
 
183
                        ed->setFocus ();                // somehow we need to call this explicitely
 
184
                }
 
185
        }
 
186
 
 
187
        if (existing_editor) {          // not strictly an else. existing_editor may be reset inside the above if
 
188
                if (existing_editor->isAttached ()) {
 
189
                        view ()->setActivePage (existing_editor);
 
190
                } else {
 
191
                        object->getContainer ()->objectOpened ()->show ();
 
192
                        object->getContainer ()->objectOpened ()->raise ();
 
193
                }
 
194
        }
 
195
        
 
196
        return ed;
 
197
}
 
198
 
 
199
void RKWorkplace::flushAllData () {
 
200
        RK_TRACE (APP);
 
201
 
 
202
        for (RKWorkplaceObjectList::const_iterator it = windows.constBegin (); it != windows.constEnd (); ++it) {
 
203
                if ((*it)->type == RKMDIWindow::DataEditorWindow) {
 
204
                        static_cast<RKEditor *> (*it)->flushChanges ();
 
205
                }
 
206
        }
 
207
}
 
208
 
 
209
void RKWorkplace::closeWindow (RKMDIWindow *window) {
 
210
        RK_TRACE (APP);
 
211
        RK_ASSERT (windows.find (window) != windows.end ());
 
212
 
 
213
        window->close (true);           // all the rest should happen in windowDestroyed ()
 
214
}
 
215
 
 
216
void RKWorkplace::closeActiveWindow () {
 
217
        RK_TRACE (APP);
 
218
 
 
219
        RKMDIWindow *w = activeAttachedWindow ();
 
220
        if (w) closeWindow (w);
 
221
        else RK_ASSERT (false);         // this is benign, and maybe even ok, but I'd like to see when this happens
 
222
}
 
223
 
 
224
RKWorkplace::RKWorkplaceObjectList RKWorkplace::getObjectList (int type, int state) {
 
225
        RK_TRACE (APP);
 
226
 
 
227
        RKWorkplaceObjectList ret;
 
228
        for (RKWorkplaceObjectList::const_iterator it = windows.constBegin (); it != windows.constEnd (); ++it) {
 
229
                if (((*it)->type & type) && ((*it)->state & state)) {
 
230
                        ret.append ((*it));
 
231
                }
 
232
        }
 
233
        return ret;
 
234
}
 
235
 
 
236
void RKWorkplace::closeAll (int type, int state) {
 
237
        RK_TRACE (APP);
 
238
 
 
239
        RKWorkplaceObjectList list_to_close = getObjectList (type, state);
 
240
        for (RKWorkplaceObjectList::const_iterator it = list_to_close.constBegin (); it != list_to_close.constEnd (); ++it) {
 
241
                closeWindow (*it);
 
242
        }
 
243
}
 
244
 
 
245
void RKWorkplace::windowDestroyed (QObject *object) {
 
246
        RK_TRACE (APP);
 
247
        RKMDIWindow *window = static_cast<RKMDIWindow *> (object);
 
248
 
 
249
        RK_ASSERT (windows.find (window) != windows.end ());
 
250
        if (window->isAttached ()) view ()->removePage (window, true);
 
251
        windows.remove (window);
 
252
}
 
253
 
 
254
RKMDIWindow *RKWorkplace::activeAttachedWindow () {
 
255
        RK_TRACE (APP);
 
256
 
 
257
        return (static_cast<RKMDIWindow *> (view ()->activePage ()));
 
258
}
 
259
 
 
260
void RKWorkplace::activateWindow (RKMDIWindow *window) {
 
261
        RK_TRACE (APP);
 
262
 
 
263
        window->raise ();               // Does this do the trick?
 
264
}
 
265
 
 
266
void RKWorkplace::saveWorkplace (RCommandChain *chain) {
 
267
        RK_TRACE (APP);
 
268
 
 
269
        QString workplace_description = "c (";
 
270
 
 
271
        bool first = true;
 
272
        for (RKWorkplaceObjectList::const_iterator it = windows.constBegin (); it != windows.constEnd (); ++it) {
 
273
                if (first) first = false;
 
274
                else workplace_description.append (", ");
 
275
                workplace_description.append ((*it)->getRDescription ());
 
276
        }
 
277
        workplace_description = ".rk.workplace.save <- " + workplace_description + ")";
 
278
 
 
279
 
 
280
        RKGlobals::rInterface ()->issueCommand (workplace_description, RCommand::App | RCommand::Sync, i18n ("Save Workplace layout"), 0, 0, chain); 
 
281
}
 
282
 
 
283
void RKWorkplace::restoreWorkplace (RCommandChain *chain) {
 
284
        RK_TRACE (APP);
 
285
 
 
286
        RKGlobals::rInterface ()->issueCommand (".rk.workplace.save", RCommand::App | RCommand::Sync | RCommand::GetStringVector, i18n ("Restore Workplace layout"), this, RESTORE_WORKPLACE_COMMAND, chain);
 
287
}
 
288
 
 
289
void RKWorkplace::clearWorkplaceDescription (RCommandChain *chain) {
 
290
        RK_TRACE (APP);
 
291
 
 
292
        RKGlobals::rInterface ()->issueCommand ("remove (.rk.workplace.save)", RCommand::App | RCommand::Sync | RCommand::ObjectListUpdate, QString::null, 0, 0, chain); 
 
293
}
 
294
 
 
295
void RKWorkplace::rCommandDone (RCommand *command) {
 
296
        RK_TRACE (APP);
 
297
 
 
298
        RK_ASSERT (command->getFlags () == RESTORE_WORKPLACE_COMMAND);
 
299
        for (unsigned int i = 0; i < command->getDataLength (); ++i) {
 
300
                QString desc = command->getStringVector ()[i];
 
301
                QString type = desc.section (QChar (':'), 0, 0);
 
302
                QString specification = desc.section (QChar (':'), 1);
 
303
 
 
304
                if (type == "data") {
 
305
                        RObject *object = RObjectList::getObjectList ()->findObject (specification);
 
306
                        if (object) editObject (object, false);
 
307
                } else if (type == "script") {
 
308
                        openScriptEditor (specification);
 
309
                } else if (type == "output") {
 
310
                        openOutputWindow (specification);
 
311
                } else if (type == "help") {
 
312
                        openHelpWindow (specification);
 
313
                } else {
 
314
                        RK_ASSERT (false);
 
315
                }
 
316
        }
 
317
}
 
318
 
 
319
#include "rkworkplace.moc"