[rkward-cvs] SF.net SVN: rkward: [2278] branches/KDE4_port
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Fri Nov 30 15:37:55 UTC 2007
Revision: 2278
http://rkward.svn.sourceforge.net/rkward/?rev=2278&view=rev
Author: tfry
Date: 2007-11-30 07:37:55 -0800 (Fri, 30 Nov 2007)
Log Message:
-----------
Finish implementing script blocks (totatlly different to the first attempt)
Modified Paths:
--------------
branches/KDE4_port/ChangeLog
branches/KDE4_port/rkward/windows/rkcommandeditorwindow.cpp
branches/KDE4_port/rkward/windows/rkcommandeditorwindow.h
branches/KDE4_port/rkward/windows/rkcommandeditorwindowpart.rc
branches/KDE4_port/rkward/windows/rkworkplace.cpp
Modified: branches/KDE4_port/ChangeLog
===================================================================
--- branches/KDE4_port/ChangeLog 2007-11-30 01:02:22 UTC (rev 2277)
+++ branches/KDE4_port/ChangeLog 2007-11-30 15:37:55 UTC (rev 2278)
@@ -1,3 +1,4 @@
+- ability to mark arbitrary "blocks" in script editor and run them with a shortcut
- make sure that R only handles SIGSEV, when the R thread is active. Should give better backtraces and less hangs
- object viewer was redesigned to use space better, and only fetch the print-representation when needed
- more icons added
Modified: branches/KDE4_port/rkward/windows/rkcommandeditorwindow.cpp
===================================================================
--- branches/KDE4_port/rkward/windows/rkcommandeditorwindow.cpp 2007-11-30 01:02:22 UTC (rev 2277)
+++ branches/KDE4_port/rkward/windows/rkcommandeditorwindow.cpp 2007-11-30 15:37:55 UTC (rev 2278)
@@ -37,13 +37,14 @@
#include <QClipboard>
#include <klocale.h>
-#include <kmenubar.h>
+#include <kmenu.h>
#include <kmessagebox.h>
#include <kfiledialog.h>
#include <kaction.h>
#include <kstandardaction.h>
#include <klibloader.h>
#include <kactioncollection.h>
+#include <kactionmenu.h>
#include "../misc/rkcommonfunctions.h"
#include "../misc/rkstandardicons.h"
@@ -71,6 +72,7 @@
}
#define GET_HELP_URL 1
+#define NUM_BLOCK_RECORDS 6
RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, bool use_r_highlighting) : RKMDIWindow (parent, RKMDIWindow::CommandEditorWindow) {
RK_TRACE (COMMANDEDITOR);
@@ -103,7 +105,6 @@
connect (m_doc, SIGNAL (modifiedChanged (KTextEditor::Document*)), this, SLOT (updateCaption (KTextEditor::Document*))); // of course most of the time this causes a redundant call to updateCaption. Not if a modification is undone, however.
connect (m_doc, SIGNAL (textChanged (KTextEditor::Document*)), this, SLOT (tryCompletionProxy (KTextEditor::Document*)));
connect (m_view, SIGNAL (selectionChanged(KTextEditor::View*)), this, SLOT (selectionChanged(KTextEditor::View*)));
- connect (m_view, SIGNAL (cursorPositionChanged(KTextEditor::View*,const KTextEditor::Cursor&)), this, SLOT (cursorPositionChanged(KTextEditor::View*,const KTextEditor::Cursor&)));
// somehow the katepart loses the context menu each time it loses focus
connect (m_view, SIGNAL (focusIn(KTextEditor::View*)), this, SLOT (focusIn(KTextEditor::View*)));
completion_timer = new QTimer (this);
@@ -125,16 +126,9 @@
hinter = new RKFunctionArgHinter (this, m_view);
}
- top_block_range = 0;
- last_active_block = 0;
smart_iface = qobject_cast<KTextEditor::SmartInterface*> (m_doc);
- if (smart_iface) {
- top_block_range = smart_iface->newSmartRange (m_doc->documentRange());
- top_block_range->setInsertBehavior (KTextEditor::SmartRange::ExpandLeft | KTextEditor::SmartRange::ExpandRight);
- smart_iface->addHighlightToView (m_view, top_block_range);
- } else {
- RK_ASSERT (false);
- }
+ initBlocks ();
+ RK_ASSERT (smart_iface);
updateCaption (); // initialize
QTimer::singleShot (0, this, SLOT (setPopupMenu ()));
@@ -150,27 +144,87 @@
RK_TRACE (COMMANDEDITOR);
action_run_all = RKStandardActions::runAll (ac, "run_all", this, SLOT (runAll()));
-#warning TODO: move to RKStandardActions
- action_run_block = ac->addAction ("run_block", this, SLOT (runBlock()));
- action_run_block->setText (i18n ("Run this block"));
- action_run_block->setEnabled (false);
action_run_selection = RKStandardActions::runSelection (ac, "run_selection", this, SLOT (runSelection()));
action_run_selection->setEnabled (false);
action_run_line = RKStandardActions::runLine (ac, "run_line", this, SLOT (runLine()));
action_help_function = RKStandardActions::functionHelp (ac, "function_reference", this, SLOT (showHelp()));
- action_mark_block = ac->addAction ("mark_block", this, SLOT (markBlock()));
- action_mark_block->setText (i18n ("Mark selection as block"));
- action_mark_block->setEnabled (false);
- action_unmark_block = ac->addAction ("unmark_block", this, SLOT (unmarkBlock()));
- action_unmark_block->setText (i18n ("Unmark this block"));
- action_unmark_block->setEnabled (false);
+ actionmenu_run_block = new KActionMenu (i18n ("Run block"), this);
+ actionmenu_run_block->setDelayed (false); // KDE4: TODO does not work correctly in the tool bar.
+ ac->addAction ("run_block", actionmenu_run_block);
+ connect (actionmenu_run_block->menu(), SIGNAL (aboutToShow()), this, SLOT (clearUnusedBlocks()));
+ actionmenu_mark_block = new KActionMenu (i18n ("Mark selection as block"), this);
+ ac->addAction ("mark_block", actionmenu_mark_block);
+ connect (actionmenu_mark_block->menu(), SIGNAL (aboutToShow()), this, SLOT (clearUnusedBlocks()));
+ actionmenu_unmark_block = new KActionMenu (i18n ("Unmark block"), this);
+ ac->addAction ("unmark_block", actionmenu_unmark_block);
+ connect (actionmenu_unmark_block->menu(), SIGNAL (aboutToShow()), this, SLOT (clearUnusedBlocks()));
QAction* action_configure = ac->addAction ("configure_commandeditor", this, SLOT (configure()));
action_configure->setText (i18n ("Configure Script Editor"));
}
+void RKCommandEditorWindow::initBlocks () {
+ RK_TRACE (COMMANDEDITOR);
+ RK_ASSERT (block_records.isEmpty ());
+
+ KActionCollection* ac = getPart ()->actionCollection ();
+
+ int i = 0;
+ QColor colors[NUM_BLOCK_RECORDS];
+ colors[i++] = QColor (255, 0, 0);
+ colors[i++] = QColor (0, 255, 0);
+ colors[i++] = QColor (0, 0, 255);
+ colors[i++] = QColor (255, 255, 0);
+ colors[i++] = QColor (255, 0, 255);
+ colors[i++] = QColor (0, 255, 255);
+ RK_ASSERT (i == NUM_BLOCK_RECORDS);
+
+ // sorry for those idiotic shortcuts, but I just could not find any decent unused ones
+ i = 0;
+ QKeySequence shortcuts[NUM_BLOCK_RECORDS];
+ shortcuts[i++] = QKeySequence (Qt::AltModifier | Qt::ShiftModifier | Qt::Key_F1);
+ shortcuts[i++] = QKeySequence (Qt::AltModifier | Qt::ShiftModifier | Qt::Key_F2);
+ shortcuts[i++] = QKeySequence (Qt::AltModifier | Qt::ShiftModifier | Qt::Key_F3);
+ shortcuts[i++] = QKeySequence (Qt::AltModifier | Qt::ShiftModifier | Qt::Key_F4);
+ shortcuts[i++] = QKeySequence (Qt::AltModifier | Qt::ShiftModifier | Qt::Key_F5);
+ shortcuts[i++] = QKeySequence (Qt::AltModifier | Qt::ShiftModifier | Qt::Key_F6);
+ RK_ASSERT (i == NUM_BLOCK_RECORDS);
+
+ for (i = 0; i < NUM_BLOCK_RECORDS; ++i) {
+ BlockRecord record;
+
+ QColor shaded = colors[i];
+ shaded.setAlpha (30);
+ record.attribute = KTextEditor::Attribute::Ptr (new KTextEditor::Attribute ());
+ record.attribute->clearProperty (KTextEditor::Attribute::BackgroundFillWhitespace);
+ record.attribute->setBackground (shaded);
+
+ QPixmap colorsquare (16, 16);
+ colorsquare.fill (colors[i]);
+ QIcon icon (colorsquare);
+
+ record.mark = ac->addAction ("markblock" + QString::number (i), this, SLOT (markBlock()));
+ record.mark->setIcon (icon);
+ record.mark->setData (i);
+ actionmenu_mark_block->addAction (record.mark);
+ record.unmark = ac->addAction ("unmarkblock" + QString::number (i), this, SLOT (unmarkBlock()));
+ record.unmark->setIcon (icon);
+ record.unmark->setData (i);
+ actionmenu_unmark_block->addAction (record.unmark);
+ record.run = ac->addAction ("runblock" + QString::number (i), this, SLOT (runBlock()));
+ record.run->setShortcut (shortcuts[i]);
+ record.run->setIcon (icon);
+ record.run->setData (i);
+ actionmenu_run_block->addAction (record.run);
+
+ block_records.append (record);
+ removeBlock (i, true); // initialize to empty
+ }
+ RK_ASSERT (block_records.size () == NUM_BLOCK_RECORDS);
+}
+
void RKCommandEditorWindow::focusIn (KTextEditor::View* v) {
RK_TRACE (COMMANDEDITOR);
RK_ASSERT (v == m_view);
@@ -399,84 +453,108 @@
void RKCommandEditorWindow::runBlock () {
RK_TRACE (COMMANDEDITOR);
-#warning implement
+ QAction* action = qobject_cast<QAction*>(sender ());
+ if (!action) {
+ RK_ASSERT (false);
+ return;
+ }
+
+ clearUnusedBlocks (); // this block might have been removed meanwhile
+ int index = action->data ().toInt ();
+ RK_ASSERT ((index >= 0) && (index < block_records.size ()));
+ if (block_records[index].active) {
+ QString command = m_doc->text (*(block_records[index].range));
+ if (command.isEmpty ()) return;
+
+ RKConsole::pipeUserCommand (new RCommand (command, RCommand::User, QString::null));
+ }
}
void RKCommandEditorWindow::markBlock () {
RK_TRACE (COMMANDEDITOR);
+ QAction* action = qobject_cast<QAction*>(sender ());
+ if (!action) {
+ RK_ASSERT (false);
+ return;
+ }
+
+ int index = action->data ().toInt ();
+ RK_ASSERT ((index >= 0) && (index < block_records.size ()));
if (m_view->selection ()) {
- KTextEditor::SmartRange* range = smart_iface->newSmartRange (m_view->selectionRange (), top_block_range, KTextEditor::SmartRange::ExpandRight);
- range->addWatcher (this);
-
- highlightBlock (range, true);
+ addBlock (index, m_view->selectionRange ());
} else {
RK_ASSERT (false);
}
}
-void RKCommandEditorWindow::highlightBlock (KTextEditor::SmartRange* block, bool active) {
+void RKCommandEditorWindow::unmarkBlock () {
RK_TRACE (COMMANDEDITOR);
- if (!block) return;
- if (!block->isValid ()) return;
+ QAction* action = qobject_cast<QAction*>(sender ());
+ if (!action) {
+ RK_ASSERT (false);
+ return;
+ }
- QColor color;
- if (active) color = QColor (255, 255, 30);
- else color = QColor (255, 255, 180);
-
- KTextEditor::Attribute::Ptr attribute (new KTextEditor::Attribute());
- attribute->setBackground (color);
- block->setAttribute (attribute);
+ int index = action->data ().toInt ();
+ RK_ASSERT ((index >= 0) && (index < block_records.size ()));
+ removeBlock (index);
}
-void RKCommandEditorWindow::unmarkBlock () {
+void RKCommandEditorWindow::clearUnusedBlocks () {
RK_TRACE (COMMANDEDITOR);
- KTextEditor::SmartRange* block = currentBlock ();
- RK_ASSERT (block);
- delete block;
- last_active_block = 0;
-
- // update state
- cursorPositionChanged (m_view, m_view->cursorPosition ());
+ for (int i = 0; i < block_records.size (); ++i) {
+ if (block_records[i].active) {
+// TODO: do we need to check whether the range was deleted? Does the katepart do such evil things?
+ if (!block_records[i].range->isValid () || block_records[i].range->isEmpty ()) {
+ removeBlock (i, true);
+ }
+ }
+ }
}
-void RKCommandEditorWindow::cursorPositionChanged (KTextEditor::View* view, const KTextEditor::Cursor &) {
+void RKCommandEditorWindow::addBlock (int index, const KTextEditor::Range& range) {
RK_TRACE (COMMANDEDITOR);
- RK_ASSERT (view == m_view);
+ RK_ASSERT ((index >= 0) && (index < block_records.size ()));
- KTextEditor::SmartRange* new_block = currentBlock ();
- if (new_block) {
- action_run_block->setEnabled (true);
- action_unmark_block->setEnabled (true);
- } else {
- action_run_block->setEnabled (false);
- action_unmark_block->setEnabled (false);
- }
+ clearUnusedBlocks ();
+ removeBlock (index);
- if (new_block != last_active_block) {
- highlightBlock (last_active_block, false);
- highlightBlock (new_block, true);
-#warning the kateview repainting is no good
- }
- last_active_block = new_block;
+ KTextEditor::SmartRange* srange = smart_iface->newSmartRange (range);
+ srange->setInsertBehavior (KTextEditor::SmartRange::ExpandRight);
+
+ QString actiontext = i18n ("%1 (Active)", index + 1);
+ block_records[index].range = srange;
+ srange->setAttribute (block_records[index].attribute);
+ block_records[index].active = true;
+ block_records[index].mark->setText (actiontext);
+ block_records[index].unmark->setText (actiontext);
+ block_records[index].unmark->setEnabled (true);
+ block_records[index].run->setText (actiontext);
+ block_records[index].run->setEnabled (true);
+
+ smart_iface->addHighlightToView (m_view, srange);
}
-KTextEditor::SmartRange* RKCommandEditorWindow::currentBlock() const {
+void RKCommandEditorWindow::removeBlock (int index, bool was_deleted) {
RK_TRACE (COMMANDEDITOR);
+ RK_ASSERT ((index >= 0) && (index < block_records.size ()));
- KTextEditor::Range active_range = KTextEditor::Range (m_view->cursorPosition (), m_view->cursorPosition ());
- if (m_view->selection ()) {
- active_range = m_view->selectionRange ();
+ if (!was_deleted) {
+ smart_iface->removeHighlightFromView (m_view, block_records[index].range);
+ delete (block_records[index].range);
}
- KTextEditor::SmartRange* active_block = top_block_range->mostSpecificRange (active_range);
- if (active_block && (active_block != top_block_range) && active_block->isValid () && !active_block->isEmpty()) {
- return active_block;
- } else {
- return 0;
- }
+ QString actiontext = i18n ("%1 (Unused)", index + 1);
+ block_records[index].range = 0;
+ block_records[index].active = false;
+ block_records[index].mark->setText (actiontext);
+ block_records[index].unmark->setText (actiontext);
+ block_records[index].unmark->setEnabled (false);
+ block_records[index].run->setText (actiontext);
+ block_records[index].run->setEnabled (false);
}
void RKCommandEditorWindow::selectionChanged (KTextEditor::View* view) {
@@ -485,26 +563,10 @@
if (view->selection ()) {
action_run_selection->setEnabled (true);
-
- KTextEditor::Range selrange = view->selectionRange ();
- bool intersects_existing_block = false;
- QList<KTextEditor::SmartRange*> blocks = top_block_range->childRanges ();
- for (int i = 0; i < blocks.size (); ++i) {
- KTextEditor::SmartRange* range = blocks[i];
- if (range->isEmpty () || !range->isValid ()) {
- if (range == last_active_block) last_active_block = 0;
- delete range; // Needed?
- continue;
- }
- if (range->overlaps (selrange)) {
- intersects_existing_block = true;
- break;
- }
- }
- action_mark_block->setEnabled (!intersects_existing_block);
+ actionmenu_mark_block->setEnabled (true);
} else {
action_run_selection->setEnabled (false);
- action_mark_block->setEnabled (false);
+ actionmenu_mark_block->setEnabled (false);
}
}
Modified: branches/KDE4_port/rkward/windows/rkcommandeditorwindow.h
===================================================================
--- branches/KDE4_port/rkward/windows/rkcommandeditorwindow.h 2007-11-30 01:02:22 UTC (rev 2277)
+++ branches/KDE4_port/rkward/windows/rkcommandeditorwindow.h 2007-11-30 15:37:55 UTC (rev 2278)
@@ -27,7 +27,6 @@
#include <ktexteditor/codecompletioninterface.h>
#include <ktexteditor/smartrange.h>
#include <ktexteditor/smartinterface.h>
-#include <ktexteditor/rangefeedback.h>
#include <kurl.h>
#include "../windows/rkmdiwindow.h"
@@ -37,6 +36,7 @@
class QFrame;
class QLabel;
class QAction;
+class KActionMenu;
class RKCommandEditorWindow;
class KActionCollection;
@@ -118,7 +118,7 @@
@author Pierre Ecochard
*/
-class RKCommandEditorWindow : public RKMDIWindow, public RKScriptContextProvider, public KTextEditor::SmartRangeWatcher {
+class RKCommandEditorWindow : public RKMDIWindow, public RKScriptContextProvider {
// we need the Q_OBJECT thing for some inherits ("RKCommandEditorWindow")-calls in rkward.cpp.
Q_OBJECT
public:
@@ -169,34 +169,27 @@
void runLine ();
/** run the entire script */
void runAll ();
-/** run the current block */
- void runBlock ();
/** invoke the settings page for the command editor */
void configure ();
-/** mark current selection as a block */
- void markBlock ();
-/** unmark current block */
- void unmarkBlock ();
-
/** selection has changed. Enable / disable actions accordingly */
void selectionChanged (KTextEditor::View* view);
-/** cursor position has changed. Enable / disable actions accordingly */
- void cursorPositionChanged (KTextEditor::View* view, const KTextEditor::Cursor &new_position);
protected:
/** reimplemented from RKMDIWindow: give the editor window a chance to object to being closed (if unsaved) */
void closeEvent (QCloseEvent *e);
+private slots:
+/** mark current selection as a block */
+ void markBlock ();
+/** unmark a block */
+ void unmarkBlock ();
+/** run a block */
+ void runBlock ();
+ void clearUnusedBlocks ();
private:
- KTextEditor::SmartRange* currentBlock() const;
- KTextEditor::SmartRange* last_active_block;
-
- void highlightBlock (KTextEditor::SmartRange* block, bool active);
-
KTextEditor::Document *m_doc;
KTextEditor::View *m_view;
KTextEditor::CodeCompletionInterface *cc_iface;
KTextEditor::SmartInterface *smart_iface;
- KTextEditor::SmartRange *top_block_range;
RKFunctionArgHinter *hinter;
RKCodeCompletionModel *completion_model;
@@ -206,12 +199,25 @@
void initializeActions (KActionCollection* ac);
- QAction* action_mark_block;
- QAction* action_unmark_block;
+ struct BlockRecord {
+ KTextEditor::SmartRange* range;
+ bool active;
+ KTextEditor::Attribute::Ptr attribute;
+ QAction* mark;
+ QAction* unmark;
+ QAction* run;
+ };
+ QVector<BlockRecord> block_records;
+ void initBlocks ();
+ void addBlock (int index, const KTextEditor::Range& range);
+ void removeBlock (int index, bool was_deleted=false);
+ KActionMenu* actionmenu_mark_block;
+ KActionMenu* actionmenu_unmark_block;
+ KActionMenu* actionmenu_run_block;
+
QAction* action_run_all;
QAction* action_run_selection;
- QAction* action_run_block;
QAction* action_run_line;
QAction* action_help_function;
Modified: branches/KDE4_port/rkward/windows/rkcommandeditorwindowpart.rc
===================================================================
--- branches/KDE4_port/rkward/windows/rkcommandeditorwindowpart.rc 2007-11-30 01:02:22 UTC (rev 2277)
+++ branches/KDE4_port/rkward/windows/rkcommandeditorwindowpart.rc 2007-11-30 15:37:55 UTC (rev 2278)
@@ -13,9 +13,10 @@
<Menu name="run"><text>&Run</text>
<Action name="run_line"/>
<Action name="run_selection"/>
- <Action name="run_block"/>
<Action name="run_all"/>
<Separator/>
+ <Action name="run_block"/>
+ <Separator/>
</Menu>
<Menu name="settings"><text>&Settings</text>
<Action name="configure_commandeditor"></Action>
@@ -28,6 +29,8 @@
<Action name="run_line"/>
<Action name="run_selection"/>
<Action name="run_all"/>
+ <Separator/>
+ <Action name="run_block"/>
</ToolBar>
<Menu name="ktexteditor_popup">
<Merge/>
@@ -37,8 +40,9 @@
<Menu name="run"><text>&Run</text>
<Action name="run_line"/>
<Action name="run_selection"/>
+ <Action name="run_all"/>
+ <Separator/>
<Action name="run_block"/>
- <Action name="run_all"/>
</Menu>
<Action name="function_reference"/>
<Separator/>
Modified: branches/KDE4_port/rkward/windows/rkworkplace.cpp
===================================================================
--- branches/KDE4_port/rkward/windows/rkworkplace.cpp 2007-11-30 01:02:22 UTC (rev 2277)
+++ branches/KDE4_port/rkward/windows/rkworkplace.cpp 2007-11-30 15:37:55 UTC (rev 2278)
@@ -249,7 +249,7 @@
void RKWorkplace::refreshOutputWindow () {
RK_TRACE (APP);
- RKOutputWindow *window = RKOutputWindow::refreshOutput (RKSettingsModuleOutput::autoShow (), RKSettingsModuleOutput::autoRaise (), false);
+ RKOutputWindow *window = RKOutputWindow::refreshOutput (RKSettingsModuleOutput::autoShow (), RKSettingsModuleOutput::autoRaise (), true);
if (window) {
if (!windows.contains (window)) {
addWindow (window);
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