[rkward-cvs] SF.net SVN: rkward:[3547] trunk/rkward
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Wed May 11 17:51:25 UTC 2011
Revision: 3547
http://rkward.svn.sourceforge.net/rkward/?rev=3547&view=rev
Author: tfry
Date: 2011-05-11 17:51:25 +0000 (Wed, 11 May 2011)
Log Message:
-----------
Add 'carbon copy' feature.
Modified Paths:
--------------
trunk/rkward/ChangeLog
trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp
trunk/rkward/rkward/rbackend/rcommand.h
trunk/rkward/rkward/rbackend/rcommandstack.cpp
trunk/rkward/rkward/rbackend/rinterface.cpp
trunk/rkward/rkward/rbackend/rinterface.h
trunk/rkward/rkward/rbackend/rkrbackend.cpp
trunk/rkward/rkward/rbackend/rkrbackend.h
trunk/rkward/rkward/settings/rksettingsmoduleoutput.cpp
trunk/rkward/rkward/settings/rksettingsmoduleoutput.h
trunk/rkward/rkward/windows/rkwindowcatcher.cpp
Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/ChangeLog 2011-05-11 17:51:25 UTC (rev 3547)
@@ -1,7 +1,8 @@
+- R commands and their output can be "carbon copied" to the output window # TODO: Add a dialog for this in the 'Run' Menu
- On Windows, RKWard will detect, and offer to disable "native" file system dialogs
- Object browsers that show only the global environment now hide the ".GlobalEnv" item
- Fixed: Function argument hints would not be shown in some corner cases
-- Added function rk.print.code() to write highlighted R code to the output window # TODO: Next, implement the 'carbon copy' feature
+- Added function rk.print.code() to write highlighted R code to the output window
- Box plot plugin gains support for grouped outcome data
- Fixed: Pressing Ctrl+C would not reset syntactically incomplete commands in the R console
- Crosstabs N to 1 plugin gains options to compute proportions and margins (thanks to Andrés Necochea)
Modified: trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp 2011-05-11 17:51:25 UTC (rev 3547)
@@ -160,7 +160,7 @@
command.append (code_property->calculate ());
command.append (code_property->printout ());
command.append ("})\n");
- RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::DirectToOutput | RCommand::ObjectListUpdate), component->commandChain ());
+ RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::CCOutput | RCommand::ObjectListUpdate), component->commandChain ());
// re-run link
// This should be run in a separate command, in case the above command bails out with an error. Even in that case, the re-run link should be printed.
@@ -172,7 +172,7 @@
}
// separator line
command.append (".rk.make.hr()\n");
- RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::DirectToOutput | RCommand::ObjectListUpdate), component->commandChain ());
+ RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::ObjectListUpdate | RCommand::Silent), component->commandChain ());
if (auto_close_box->isChecked ()) cancel ();
}
Modified: trunk/rkward/rkward/rbackend/rcommand.h
===================================================================
--- trunk/rkward/rkward/rbackend/rcommand.h 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/rbackend/rcommand.h 2011-05-11 17:51:25 UTC (rev 3547)
@@ -68,6 +68,7 @@
QString is, that additionally we store information on whether the output was "normal", "warning", or an "error". */
struct ROutput {
enum ROutputType {
+ NoOutput, /**< No output. Rarely used. */
Output, /**< normal output */
Warning, /**< R warning */
Error /**< R error */
@@ -135,19 +136,21 @@
although partially exclusive. See \ref UsingTheInterfaceToR for a overview of what these are used for. TODO: find out, why Canceled is in here, and document that fact. */
enum CommandTypes {
User=1, /**< Command was created directly by the user (e.g. in the console or in a command editor window) */
- Plugin=2, /**< Command comes from a plugin */
- App=8, /**< Command comes from the application (e.g. loading / saving the workspace */
- Sync=16, /**< Command is used to sync data to or from R-space. Typically used in the editor classes */
- EmptyCommand=32, /**< Command is empty and will not be processed (an empty command may be used as a "marker") */
- Console=64, /**< Command originated in the console. These commands will get some extra treatment in RKwatch */
- Internal=128, /**< Command is meant to be used in the backend, only. Do not use outside rbackend classes! */
- GetIntVector=512, /**< Try to fetch result as an array of integers */
- GetStringVector=1024, /**< Try to fetch result as an array of chars */
- GetRealVector=2048, /**< Try to fetch result as an array of doubles */
- GetStructuredData=4096, /**< Try to fetch result as an RData structure */
- DirectToOutput=8192, /**< Append command output to the HTML-output file */
- ObjectListUpdate=16384, /**< The command may change the list of objects available. Do an update */
- QuitCommand=32768 /**< The R backend should be killed */
+ Plugin=1 << 1, /**< Command comes from a plugin */
+ App=1 << 2, /**< Command comes from the application (e.g. loading / saving the workspace */
+ Sync=1 << 3, /**< Command is used to sync data to or from R-space. Typically used in the editor classes */
+ EmptyCommand=1 << 4, /**< Command is empty and will not be processed (an empty command may be used as a "marker") */
+ Console=1 << 5, /**< Command originated in the console. These commands will get some extra treatment in RKwatch */
+ Internal=1 << 6, /**< Command is meant to be used in the backend, only. Do not use outside rbackend classes! */
+ Silent=1 << 7, /**< Command can be interrupted, but is otherwise an internal command. In particular it should not be carbon copied to the output. */
+ GetIntVector=1 << 8, /**< Try to fetch result as an array of integers */
+ GetStringVector=1 << 9, /**< Try to fetch result as an array of chars */
+ GetRealVector=1 << 10, /**< Try to fetch result as an array of doubles */
+ GetStructuredData=1 << 11, /**< Try to fetch result as an RData structure */
+ CCOutput=1 << 12, /**< Append command output to the HTML-output file */
+ CCCommand=1 << 13, /**< Append the command itself to the HTML-output file */
+ ObjectListUpdate=1 << 14, /**< The command may change the list of objects available. Do an update */
+ QuitCommand=1 << 15 /**< The R backend should be killed */
};
enum CommandStatus {
Running=1, /**< command is currently running */
Modified: trunk/rkward/rkward/rbackend/rcommandstack.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rcommandstack.cpp 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/rbackend/rcommandstack.cpp 2011-05-11 17:51:25 UTC (rev 3547)
@@ -344,7 +344,7 @@
if (command->type () & RCommand::Sync) ret += 'S';
if (command->type () & RCommand::EmptyCommand) ret += 'E';
if (command->type () & (RCommand::GetIntVector | RCommand::GetRealVector | RCommand::GetStringVector | RCommand::GetStructuredData)) ret += 'D';
- if (command->type () & RCommand::DirectToOutput) ret += 'O';
+ if (command->type () & RCommand::CCOutput) ret += 'O';
return (ret);
}
if ((index.column () == STATUS_COL) && (role == Qt::DisplayRole)) {
Modified: trunk/rkward/rkward/rbackend/rinterface.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rinterface.cpp 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/rbackend/rinterface.cpp 2011-05-11 17:51:25 UTC (rev 3547)
@@ -95,6 +95,8 @@
previously_idle = false;
locked = 0;
backend_dead = false;
+ num_active_output_record_requests = 0;
+ previous_output_type = ROutput::NoOutput;
// create a fake init command
RCommand *fake = new RCommand (i18n ("R Startup"), RCommand::App | RCommand::Sync | RCommand::ObjectListUpdate, i18n ("R Startup"), this, STARTUP_PHASE2_COMPLETE);
@@ -116,6 +118,7 @@
RInterface::~RInterface(){
RK_TRACE (RBACKEND);
+ if (num_active_output_record_requests) RK_DO (qDebug ("%d requests for recording output still active on interface shutdown", num_active_output_record_requests), RBACKEND, DL_WARNING);
delete flush_timer;
delete window_catcher;
}
@@ -123,9 +126,7 @@
bool RInterface::backendIsIdle () {
RK_TRACE (RBACKEND);
- bool idle;
- idle = (RCommandStack::regular_stack->isEmpty() && (!runningCommand()));
- return (idle);
+ return (RCommandStack::regular_stack->isEmpty() && (!runningCommand()));
}
RCommand *RInterface::popPreviousCommand () {
@@ -362,6 +363,23 @@
RK_DO (qDebug ("output '%s'", qPrintable (output->output)), RBACKEND, DL_DEBUG);
}
+ if (num_active_output_record_requests) {
+ if (output->type >= previous_output_type) {
+ if (!recorded_output.isEmpty ()) recorded_output.append ("</pre>\n");
+
+ if (output->type == ROutput::Output) recorded_output.append ("<pre class=\"output_normal\">");
+ else if (output->type == ROutput::Warning) recorded_output.append ("<pre class=\"output_warning\">");
+ else if (output->type == ROutput::Error) recorded_output.append ("<pre class=\"output_error\">");
+ else {
+ RK_ASSERT (false);
+ recorded_output.append ("<pre>");
+ }
+
+ previous_output_type = output->type;
+ }
+ recorded_output.append (Qt::escape (output->output));
+ }
+
bool first = true;
foreach (RCommand* command, all_current_commands) {
ROutput *coutput = output;
@@ -398,6 +416,10 @@
RK_TRACE (RBACKEND);
if (command->command ().isEmpty ()) command->_type |= RCommand::EmptyCommand;
+ if (RKCarbonCopySettings::shouldCarbonCopyCommand (command)) {
+ command->_type |= RCommand::CCCommand;
+ if (RKCarbonCopySettings::includeOutputInCarbonCopy ()) command->_type |= RCommand::CCOutput;
+ }
RCommandStack::issueCommand (command, chain);
tryNextCommand ();
}
@@ -539,6 +561,20 @@
}
}
}
+ } else if (call == "recordOutput") {
+ // NOTE: requests to record output can overlap (i.e. several can be active at the same time). However, we always clear the buffer, each time a request ends, i.e. then
+ // recorded output does NOT overlap.
+ if (calllist.value (1) == "end") {
+ RK_ASSERT (num_active_output_record_requests > 0);
+ --num_active_output_record_requests;
+ QString dummy = recorded_output;
+ recorded_output.clear ();
+ if (!dummy.isEmpty ()) dummy.append ("</pre>\n");
+ previous_output_type = ROutput::NoOutput;
+ return QStringList (dummy);
+ } else {
+ ++num_active_output_record_requests;
+ }
} else {
return (QStringList ("Error: unrecognized request '" + call + "'."));
}
Modified: trunk/rkward/rkward/rbackend/rinterface.h
===================================================================
--- trunk/rkward/rkward/rbackend/rinterface.h 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/rbackend/rinterface.h 2011-05-11 17:51:25 UTC (rev 3547)
@@ -121,6 +121,9 @@
QString startup_errors;
bool startup_phase2_error;
+ int num_active_output_record_requests;
+ ROutput::ROutputType previous_output_type;
+ QString recorded_output;
friend class RKRBackendProtocolFrontend;
bool backend_dead;
static double na_real;
Modified: trunk/rkward/rkward/rbackend/rkrbackend.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackend.cpp 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/rbackend/rkrbackend.cpp 2011-05-11 17:51:25 UTC (rev 3547)
@@ -301,6 +301,7 @@
}
if (incomplete) RKRBackend::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorIncomplete;
RKRBackend::repl_status.user_command_status = RKRBackend::RKReplStatus::ReplIterationKilled;
+ if (RKRBackend::RKRBackend::repl_status.user_command_parsed_up_to <= 0) RKRBackend::this_pointer->startOutputCapture (); // HACK: No capture active, but commandFinished() will try to end one
Rf_error (""); // to discard the buffer
} else {
RKTransmitNextUserCommandChunk (buf, buflen);
@@ -309,6 +310,7 @@
} else if (RKRBackend::repl_status.user_command_status == RKRBackend::RKReplStatus::UserCommandSyntaxError) {
RKRBackend::this_pointer->current_command->status |= RCommand::Failed | RCommand::ErrorSyntax;
RKRBackend::repl_status.user_command_status = RKRBackend::RKReplStatus::NoUserCommand;
+ if (RKRBackend::RKRBackend::repl_status.user_command_parsed_up_to <= 0) RKRBackend::this_pointer->startOutputCapture (); // HACK: No capture active, but commandFinished() will try to end one
RKRBackend::this_pointer->commandFinished ();
} else if (RKRBackend::repl_status.user_command_status == RKRBackend::RKReplStatus::UserCommandRunning) {
// This can mean three different things:
@@ -398,7 +400,6 @@
}
}
- if (RKRBackend::this_pointer->capturing_messages) RKRBackend::this_pointer->captured_messages.append (RKRBackend::this_pointer->current_locale_codec->toUnicode (buf, buflen));
RKRBackend::this_pointer->handleOutput (RKRBackend::this_pointer->current_locale_codec->toUnicode (buf, buflen), buflen, type == 0 ? ROutput::Output : ROutput::Warning);
}
@@ -647,6 +648,15 @@
// R_ReplIteration calls R_Busy (1) after reading in code (if needed), successfully parsing it, and right before evaluating it.
if (busy) {
if (RKRBackend::repl_status.user_command_status == RKRBackend::RKReplStatus::UserCommandTransmitted) {
+ if (RKRBackend::this_pointer->current_command->type & RCommand::CCCommand) {
+ QByteArray chunk = RKRBackend::repl_status.user_command_buffer.mid (RKRBackend::repl_status.user_command_parsed_up_to, RKRBackend::repl_status.user_command_transmitted_up_to - RKRBackend::repl_status.user_command_parsed_up_to);
+ RKRBackend::this_pointer->printCommand (RKRBackend::this_pointer->current_locale_codec->toUnicode (chunk));
+ }
+ if (RKRBackend::this_pointer->current_command->type & RCommand::CCOutput) {
+ // flush any previous output caputre and start a new one
+ if (RKRBackend::repl_status.user_command_successful_up_to > 0) RKRBackend::this_pointer->printAndClearCapturedMessages (false);
+ RKRBackend::this_pointer->startOutputCapture ();
+ }
RKRBackend::repl_status.user_command_parsed_up_to = RKRBackend::repl_status.user_command_transmitted_up_to;
RKRBackend::repl_status.user_command_status = RKRBackend::RKReplStatus::UserCommandRunning;
}
@@ -660,7 +670,6 @@
current_locale_codec = QTextCodec::codecForLocale ();
r_running = false;
- capturing_messages = false;
current_command = 0;
@@ -1126,10 +1135,8 @@
// running user commands is quite different from all other commands and should have been handled by RReadConsole
RK_ASSERT (!(ctype & RCommand::User));
- if (ctype & RCommand::DirectToOutput) {
- printAndClearCapturedMessages ();
- capturing_messages = true;
- }
+ if (ctype & RCommand::CCCommand) printCommand (command->command);
+ if (ctype & RCommand::CCOutput) startOutputCapture ();
if (ctype & RCommand::QuitCommand) {
R_dot_Last (); // should run while communication with frontend is still possible
@@ -1161,8 +1168,6 @@
repl_status.eval_depth--;
}
- if (ctype & RCommand::DirectToOutput) printAndClearCapturedMessages ();
-
// common error/status handling
if (error != NoError) {
command->status |= RCommand::WasTried | RCommand::Failed;
@@ -1178,18 +1183,34 @@
}
}
-void RKRBackend::printAndClearCapturedMessages () {
+void RKRBackend::printCommand (const QString &command) {
RK_TRACE (RBACKEND);
- if (!captured_messages.isEmpty ()) {
- runDirectCommand (".rk.cat.output (\"<h2>Messages, warnings, or errors:</h2>\\n\")");
- runDirectCommand ("rk.print.literal (" + RKRSharedFunctionality::quote (captured_messages) + ")");
- captured_messages.clear ();
- }
+ QStringList params ("highlightRCode");
+ params.append (command);
+ QString highlighted = handlePlainGenericRequest (params, true).value (0);
+ runDirectCommand (".rk.cat.output (" + RKRSharedFunctionality::quote (highlighted) + ")");
+}
- capturing_messages = false;
+void RKRBackend::startOutputCapture () {
+ RK_TRACE (RBACKEND);
+
+ // TODO: One of those days, we need to revisit output handling. This request could be perfectly async, but unfortunately, in that case, output chunks can sneak in front of it.
+ handlePlainGenericRequest (QStringList ("recordOutput"), true);
}
+void RKRBackend::printAndClearCapturedMessages (bool with_header) {
+ RK_TRACE (RBACKEND);
+
+ QStringList params ("recordOutput");
+ params.append ("end");
+ QString out = handlePlainGenericRequest (params, true).value (0);
+
+ if (out.isEmpty ()) return;
+ if (with_header) runDirectCommand (".rk.cat.output (\"<h2>Messages, warnings, or errors:</h2>\\n\")");
+ runDirectCommand (".rk.cat.output (" + RKRSharedFunctionality::quote (out) + ")");
+}
+
void RKRBackend::run () {
RK_TRACE (RBACKEND);
killed = NotKilled;
@@ -1210,6 +1231,7 @@
}
clearPendingInterrupt (); // Mutex must be unlocked for this!
+ if (current_command->type & RCommand::CCOutput) printAndClearCapturedMessages (current_command->type & RCommand::Plugin);
current_command->status -= (current_command->status & RCommand::Running);
current_command->status |= RCommand::WasTried;
Modified: trunk/rkward/rkward/rbackend/rkrbackend.h
===================================================================
--- trunk/rkward/rkward/rbackend/rkrbackend.h 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/rbackend/rkrbackend.h 2011-05-11 17:51:25 UTC (rev 3547)
@@ -174,9 +174,9 @@
void run ();
static void scheduleInterrupt ();
- bool capturing_messages;
- QString captured_messages;
- void printAndClearCapturedMessages ();
+ void startOutputCapture ();
+ void printAndClearCapturedMessages (bool with_header);
+ void printCommand (const QString &command);
QMutex all_current_commands_mutex;
QList<RCommandProxy*> current_commands_to_cancel;
Modified: trunk/rkward/rkward/settings/rksettingsmoduleoutput.cpp
===================================================================
--- trunk/rkward/rkward/settings/rksettingsmoduleoutput.cpp 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/settings/rksettingsmoduleoutput.cpp 2011-05-11 17:51:25 UTC (rev 3547)
@@ -2,7 +2,7 @@
rksettingsmoduleoutput - description
-------------------
begin : Fri Jul 30 2004
- copyright : (C) 2004, 2010 by Thomas Friedrichsmeier
+ copyright : (C) 2004, 2010, 2011 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -33,6 +33,115 @@
#include "../debug.h"
// static members
+bool RKCarbonCopySettings::cc_globally_enabled;
+bool RKCarbonCopySettings::cc_console_commands;
+bool RKCarbonCopySettings::cc_script_commands;
+bool RKCarbonCopySettings::cc_app_plugin_commands;
+bool RKCarbonCopySettings::cc_command_output;
+QList<RKCarbonCopySettings*> RKCarbonCopySettings::instances;
+
+RKCarbonCopySettings::RKCarbonCopySettings (QWidget* parent) : QWidget (parent) {
+ RK_TRACE (SETTINGS);
+
+ QVBoxLayout *main_vbox = new QVBoxLayout (this);
+ cc_globally_enabled_box = new QGroupBox (i18n ("Carbon copy commands to output"), this);
+ cc_globally_enabled_box->setCheckable (true);
+ connect (cc_globally_enabled_box, SIGNAL (clicked(bool)), this, SLOT (settingChanged()));
+ main_vbox->addWidget (cc_globally_enabled_box);
+
+ QVBoxLayout *group_layout = new QVBoxLayout (cc_globally_enabled_box);
+ cc_console_commands_box = new QCheckBox (i18n ("Commands entered in the console"), cc_globally_enabled_box);
+ connect (cc_console_commands_box, SIGNAL (clicked(bool)), this, SLOT (settingChanged()));
+ group_layout->addWidget (cc_console_commands_box);
+
+ cc_script_commands_box = new QCheckBox (i18n ("Commands run via the 'Run' menu"), cc_globally_enabled_box);
+ connect (cc_script_commands_box, SIGNAL (clicked(bool)), this, SLOT (settingChanged()));
+ group_layout->addWidget (cc_script_commands_box);
+
+ cc_app_plugin_commands_box = new QCheckBox (i18n ("Commands originating from dialogs and plugins"), cc_globally_enabled_box);
+ connect (cc_app_plugin_commands_box, SIGNAL (clicked(bool)), this, SLOT (settingChanged()));
+ group_layout->addWidget (cc_app_plugin_commands_box);
+
+ cc_command_output_box = new QCheckBox (i18n ("Also carbon copy the command ouptut"), cc_globally_enabled_box);
+ connect (cc_command_output_box, SIGNAL (clicked(bool)), this, SLOT (settingChanged()));
+ group_layout->addWidget (cc_command_output_box);
+
+ cc_globally_enabled_box->setLayout (group_layout);
+
+ update ();
+ instances.append (this);
+}
+
+RKCarbonCopySettings::~RKCarbonCopySettings () {
+ RK_TRACE (SETTINGS);
+
+ instances.removeAll (this);
+}
+
+void RKCarbonCopySettings::update() {
+ RK_TRACE (SETTINGS);
+
+ cc_globally_enabled_box->setChecked (cc_globally_enabled);
+ cc_console_commands_box->setChecked (cc_console_commands);
+ cc_script_commands_box->setChecked (cc_script_commands);
+ cc_app_plugin_commands_box->setChecked (cc_app_plugin_commands);
+ cc_command_output_box->setChecked (cc_command_output);
+}
+
+void RKCarbonCopySettings::saveSettings (KConfig *config) {
+ RK_TRACE (SETTINGS);
+
+ KConfigGroup cg = config->group ("Carbon Copy Settings");
+ cg.writeEntry ("CC enabled", cc_globally_enabled);
+ cg.writeEntry ("CC console commands", cc_console_commands);
+ cg.writeEntry ("CC script commands", cc_script_commands);
+ cg.writeEntry ("CC app/plugin commands", cc_app_plugin_commands);
+ cg.writeEntry ("CC command output", cc_command_output);
+}
+
+void RKCarbonCopySettings::loadSettings (KConfig *config) {
+ RK_TRACE (SETTINGS);
+
+ KConfigGroup cg = config->group ("Carbon Copy Settings");
+ cc_globally_enabled = cg.readEntry ("CC enabled", false);
+ cc_console_commands = cg.readEntry ("CC console commands", true);
+ cc_script_commands = cg.readEntry ("CC script commands", false);
+ cc_app_plugin_commands = cg.readEntry ("CC app/plugin commands", false);
+ cc_command_output = cg.readEntry ("CC command output", true);
+}
+
+bool RKCarbonCopySettings::shouldCarbonCopyCommand (const RCommand *command) {
+ RK_TRACE (SETTINGS);
+
+ if (!cc_globally_enabled) return false;
+ if (command->type () & (RCommand::Silent | RCommand::Sync)) return false;
+ if (command->type () & RCommand::Console) return cc_console_commands;
+ if (command->type () & RCommand::User) return cc_script_commands;
+ if (command->type () & (RCommand::App | RCommand::Plugin)) return cc_app_plugin_commands;
+ return false;
+}
+
+void RKCarbonCopySettings::settingChanged () {
+ RK_TRACE (SETTINGS);
+
+ emit (changed ());
+}
+
+void RKCarbonCopySettings::applyChanges() {
+ RK_TRACE (SETTINGS);
+
+ cc_globally_enabled = cc_globally_enabled_box->isChecked ();
+ cc_console_commands = cc_console_commands_box->isChecked ();
+ cc_script_commands = cc_script_commands_box->isChecked ();
+ cc_app_plugin_commands = cc_app_plugin_commands_box->isChecked ();
+ cc_command_output = cc_command_output_box->isChecked ();
+
+ foreach (RKCarbonCopySettings *sibling, instances) {
+ if (sibling != this) sibling->update ();
+ }
+}
+
+// static members
bool RKSettingsModuleOutput::auto_show;
bool RKSettingsModuleOutput::auto_raise;
QString RKSettingsModuleOutput::graphics_type;
@@ -49,11 +158,11 @@
QVBoxLayout* group_layout = new QVBoxLayout (group);
group_layout->addWidget (auto_show_box = new QCheckBox (i18n ("show window on new output"), group));
auto_show_box->setChecked (auto_show);
- connect (auto_show_box, SIGNAL (stateChanged (int)), this, SLOT (boxChanged (int)));
+ connect (auto_show_box, SIGNAL (stateChanged (int)), this, SLOT (boxChanged()));
group_layout->addWidget (auto_raise_box = new QCheckBox (i18n ("raise window on new output"), group));
auto_raise_box->setChecked (auto_raise);
auto_raise_box->setEnabled (auto_show);
- connect (auto_raise_box, SIGNAL (stateChanged (int)), this, SLOT (boxChanged (int)));
+ connect (auto_raise_box, SIGNAL (stateChanged (int)), this, SLOT (boxChanged()));
main_vbox->addWidget (group);
@@ -69,12 +178,12 @@
graphics_type_box->addItem (i18n ("JPG"), QString ("\"JPG\""));
graphics_type_box->setCurrentIndex (graphics_type_box->findData (graphics_type));
graphics_type_box->setEditable (false);
- connect (graphics_type_box, SIGNAL (currentIndexChanged (int)), this, SLOT (boxChanged (int)));
+ connect (graphics_type_box, SIGNAL (currentIndexChanged (int)), this, SLOT (boxChanged()));
h_layout->addSpacing (2*RKGlobals::spacingHint ());
h_layout->addWidget (new QLabel (i18n ("JPG quality"), group));
h_layout->addWidget (graphics_jpg_quality_box = new KIntSpinBox (1, 100, 1, graphics_jpg_quality, group));
graphics_jpg_quality_box->setEnabled (graphics_type == "\"JPG\"");
- connect (graphics_jpg_quality_box, SIGNAL (valueChanged (int)), this, SLOT (boxChanged (int)));
+ connect (graphics_jpg_quality_box, SIGNAL (valueChanged (int)), this, SLOT (boxChanged()));
h_layout->addStretch ();
h_layout = new QHBoxLayout (group);
@@ -85,11 +194,15 @@
h_layout->addWidget (new QLabel (i18n ("Height:"), group));
h_layout->addWidget (graphics_height_box = new KIntSpinBox (1, INT_MAX, 1, graphics_height, group));
h_layout->addStretch ();
- connect (graphics_width_box, SIGNAL (valueChanged (int)), this, SLOT (boxChanged (int)));
- connect (graphics_height_box, SIGNAL (valueChanged (int)), this, SLOT (boxChanged (int)));
+ connect (graphics_width_box, SIGNAL (valueChanged (int)), this, SLOT (boxChanged()));
+ connect (graphics_height_box, SIGNAL (valueChanged (int)), this, SLOT (boxChanged()));
main_vbox->addWidget (group);
+ cc_settings = new RKCarbonCopySettings (this);
+ connect (cc_settings, SIGNAL (changed()), this, SLOT (boxChanged()));
+ main_vbox->addWidget (cc_settings);
+
main_vbox->addStretch ();
}
@@ -97,7 +210,7 @@
RK_TRACE (SETTINGS);
}
-void RKSettingsModuleOutput::boxChanged (int) {
+void RKSettingsModuleOutput::boxChanged () {
RK_TRACE (SETTINGS);
change ();
auto_raise_box->setEnabled (auto_show_box->isChecked ());
@@ -129,6 +242,8 @@
for (QStringList::const_iterator it = commands.begin (); it != commands.end (); ++it) {
RKGlobals::rInterface ()->issueCommand (*it, RCommand::App, QString::null, 0, 0, commandChain ());
}
+
+ cc_settings->applyChanges ();
}
void RKSettingsModuleOutput::save (KConfig *config) {
@@ -147,6 +262,8 @@
cg.writeEntry ("graphics_width", graphics_width);
cg.writeEntry ("graphics_height", graphics_height);
cg.writeEntry ("graphics_jpg_quality", graphics_jpg_quality);
+
+ RKCarbonCopySettings::saveSettings (config);
}
void RKSettingsModuleOutput::loadSettings (KConfig *config) {
@@ -159,6 +276,8 @@
graphics_width = cg.readEntry ("graphics_width", 480);
graphics_height = cg.readEntry ("graphics_height", 480);
graphics_jpg_quality = cg.readEntry ("graphics_jpg_quality", 75);
+
+ RKCarbonCopySettings::loadSettings (config);
}
//static
Modified: trunk/rkward/rkward/settings/rksettingsmoduleoutput.h
===================================================================
--- trunk/rkward/rkward/settings/rksettingsmoduleoutput.h 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/settings/rksettingsmoduleoutput.h 2011-05-11 17:51:25 UTC (rev 3547)
@@ -2,7 +2,7 @@
rksettingsmoduleoutput - description
-------------------
begin : Fri Jul 30 2004
- copyright : (C) 2004, 2010 by Thomas Friedrichsmeier
+ copyright : (C) 2004, 2010, 2011 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -22,12 +22,53 @@
#include <QStringList>
class QCheckBox;
+class QGroupBox;
class QComboBox;
class KIntSpinBox;
+class RCommand;
/**
+Allows to configure which types of commands should be "carbon copied" to the output window. Like the RKSettingsModules classes, this class encapsulates both, the setting itself,
+and a widget to configure the settings.
@author Thomas Friedrichsmeier
*/
+class RKCarbonCopySettings : public QWidget {
+ Q_OBJECT
+public:
+ RKCarbonCopySettings (QWidget* parent);
+ ~RKCarbonCopySettings ();
+
+ static void saveSettings (KConfig *config);
+ static void loadSettings (KConfig *config);
+
+ static bool shouldCarbonCopyCommand (const RCommand *command);
+ static bool includeOutputInCarbonCopy () { return (cc_globally_enabled && cc_command_output); };
+ void applyChanges ();
+signals:
+ void changed ();
+private slots:
+ void settingChanged ();
+private:
+ // There can be multiple instances of this widget, which need to be kept in sync.
+ static QList<RKCarbonCopySettings*> instances;
+ void update ();
+
+ QGroupBox *cc_globally_enabled_box;
+ QCheckBox *cc_console_commands_box;
+ QCheckBox *cc_script_commands_box;
+ QCheckBox *cc_app_plugin_commands_box;
+ QCheckBox *cc_command_output_box;
+
+ static bool cc_globally_enabled;
+ static bool cc_console_commands;
+ static bool cc_script_commands;
+ static bool cc_app_plugin_commands;
+ static bool cc_command_output;
+};
+
+/**
+ at author Thomas Friedrichsmeier
+*/
class RKSettingsModuleOutput : public RKSettingsModule {
Q_OBJECT
public:
@@ -49,7 +90,7 @@
static bool autoShow () { return auto_show; };
static bool autoRaise () { return auto_raise; };
public slots:
- void boxChanged (int);
+ void boxChanged ();
private:
QCheckBox *auto_show_box;
QCheckBox *auto_raise_box;
@@ -57,6 +98,7 @@
KIntSpinBox *graphics_width_box;
KIntSpinBox *graphics_height_box;
KIntSpinBox *graphics_jpg_quality_box;
+ RKCarbonCopySettings *cc_settings;
static bool auto_show;
static bool auto_raise;
Modified: trunk/rkward/rkward/windows/rkwindowcatcher.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkwindowcatcher.cpp 2011-05-11 17:50:33 UTC (rev 3546)
+++ trunk/rkward/rkward/windows/rkwindowcatcher.cpp 2011-05-11 17:51:25 UTC (rev 3547)
@@ -369,7 +369,7 @@
void RKCaughtX11Window::copyDeviceToOutput () {
RK_TRACE (MISC);
- 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", device_number), error_dialog);
+ RKGlobals::rInterface ()->issueCommand ("dev.set (" + QString::number (device_number) + ")\ndev.copy (device=rk.graph.on)\nrk.graph.off ()", RCommand::App | RCommand::CCOutput, i18n ("Copy contents of graphics device number %1 to output", device_number), error_dialog);
}
void RKCaughtX11Window::printDevice () {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the rkward-tracker
mailing list