[rkward-cvs] SF.net SVN: rkward:[4320] trunk/rkward/rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Thu Sep 27 15:11:47 UTC 2012


Revision: 4320
          http://rkward.svn.sourceforge.net/rkward/?rev=4320&view=rev
Author:   tfry
Date:     2012-09-27 15:11:46 +0000 (Thu, 27 Sep 2012)
Log Message:
-----------
Factor out history functionality into a separate class. Will also be used in debugger console, shortly.

Modified Paths:
--------------
    trunk/rkward/rkward/misc/CMakeLists.txt
    trunk/rkward/rkward/rkconsole.cpp
    trunk/rkward/rkward/rkconsole.h

Added Paths:
-----------
    trunk/rkward/rkward/misc/rkcommandhistory.cpp
    trunk/rkward/rkward/misc/rkcommandhistory.h

Modified: trunk/rkward/rkward/misc/CMakeLists.txt
===================================================================
--- trunk/rkward/rkward/misc/CMakeLists.txt	2012-09-27 09:27:50 UTC (rev 4319)
+++ trunk/rkward/rkward/misc/CMakeLists.txt	2012-09-27 15:11:46 UTC (rev 4320)
@@ -18,6 +18,7 @@
    rkstandardicons.cpp
    rkstandardactions.cpp
    rkxmlguisyncer.cpp
+   rkcommandhistory.cpp
    )
 
 QT4_AUTOMOC(${misc_STAT_SRCS})

Added: trunk/rkward/rkward/misc/rkcommandhistory.cpp
===================================================================
--- trunk/rkward/rkward/misc/rkcommandhistory.cpp	                        (rev 0)
+++ trunk/rkward/rkward/misc/rkcommandhistory.cpp	2012-09-27 15:11:46 UTC (rev 4320)
@@ -0,0 +1,127 @@
+/***************************************************************************
+                          rkcommandhistory  -  description
+                             -------------------
+    begin                : Thu Sep 27
+    copyright            : (C) 2012 by Thomas Friedrichsmeier
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "rkcommandhistory.h"
+#include "../settings/rksettingsmoduleconsole.h"
+
+#include "../debug.h"
+
+RKCommandHistory::RKCommandHistory (bool allow_empty, bool allow_dupes) {
+	RK_TRACE (MISC);
+
+	current_position = 0;
+	RKCommandHistory::allow_empty = allow_empty;
+	RKCommandHistory::allow_dupes = allow_dupes;
+}
+
+RKCommandHistory::~RKCommandHistory () {
+	RK_TRACE (MISC);
+}
+
+bool RKCommandHistory::up (bool context_sensitive, const QString& current_context) {
+	RK_TRACE (MISC);
+
+	int new_pos;
+	if (context_sensitive) {
+		QString filter = current_context;
+		if (filter == current ()) {	// user is just browsing through the list. Use previous filter string
+			filter = _current_context;
+		} else {	// line appears edited. Use as new filter
+			_current_context = filter;
+		}
+
+		new_pos = -1;
+		for (int i = qMin (current_position - 1, history.size () - 1); i >= 0; --i) {
+			if (history[i].startsWith (filter)) {
+				new_pos = i;
+				break;
+			}
+		}
+	} else {
+		new_pos = current_position - 1;
+	}
+
+	if (new_pos >= 0) {
+		if (current_position == (history.size ())) {	// on last line (and going up)? Auto append current context
+			editing_line = current_context;
+		}
+		current_position = new_pos;
+		return true;
+	}
+	return false;
+}
+
+bool RKCommandHistory::down (bool context_sensitive, const QString& current_context) {
+	RK_TRACE (MISC);
+
+	int new_pos;
+	if (context_sensitive) {
+		QString filter = current_context;
+		if (filter == current ()) {	// user is just browsing through the list. Use previous filter string
+			filter = _current_context;
+		} else {	// line appears edited. Use as new filter
+			_current_context = filter;
+		}
+
+		new_pos = history.size ();
+		for (int i = current_position + 1; i < history.size (); ++i) {
+			if (history[i].startsWith (filter)) {
+				new_pos = i;
+				break;
+			}
+		}
+	} else {
+		new_pos = current_position + 1;
+	}
+
+	if (new_pos <= history.size ()) {
+		current_position = new_pos;
+		return true;
+	}
+	return false;
+}
+
+void RKCommandHistory::trim () {
+	if (RKSettingsModuleConsole::maxHistoryLength ()) {
+		for (uint ui = history.size (); ui > RKSettingsModuleConsole::maxHistoryLength (); --ui) {
+			history.pop_front ();
+		}
+	}
+}
+
+
+void RKCommandHistory::append (const QString& new_line) {
+	RK_TRACE (MISC);
+
+	if (allow_empty || (!new_line.isEmpty ())) {
+		if (allow_dupes || (new_line != history.value (history.size () - 1))) {
+			history.append (new_line);
+			trim ();
+		}
+	}
+	goToEnd ();
+}
+
+void RKCommandHistory::setHistory (const QStringList& _history, bool append) {
+	RK_TRACE (MISC);
+
+	if (append) history.append (_history);
+	else history = _history;
+
+	trim ();
+	goToEnd ();
+}

Added: trunk/rkward/rkward/misc/rkcommandhistory.h
===================================================================
--- trunk/rkward/rkward/misc/rkcommandhistory.h	                        (rev 0)
+++ trunk/rkward/rkward/misc/rkcommandhistory.h	2012-09-27 15:11:46 UTC (rev 4320)
@@ -0,0 +1,47 @@
+/***************************************************************************
+                          rkcommandhistory  -  description
+                             -------------------
+    begin                : Thu Sep 27
+    copyright            : (C) 2012 by Thomas Friedrichsmeier
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef RKCOMMANDHISTORY_H
+#define RKCOMMANDHISTORY_H
+
+#include <QStringList>
+
+/** Simple class to manage a history of command strings (esp. for the RKConsole) */
+class RKCommandHistory {
+public:
+	RKCommandHistory (bool allow_empty, bool allow_dupes);
+	~RKCommandHistory ();
+
+	bool up (bool context_sensitive = false, const QString& current_context = QString ());
+	bool down (bool context_sensitive = false, const QString& current_context = QString ());
+	QString current () const { return history.value (current_position, editing_line); };
+	void append (const QString& new_line);
+	void goToEnd () { editing_line.clear (); current_position = history.size (); }
+
+	QStringList getHistory () const { return history; }
+	void setHistory (const QStringList& _history, bool append=false);
+private:
+	void trim ();
+	bool allow_empty;
+	bool allow_dupes;
+	int current_position;
+	QString _current_context;
+	QString editing_line;
+	QStringList history;
+};
+
+#endif
\ No newline at end of file

Modified: trunk/rkward/rkward/rkconsole.cpp
===================================================================
--- trunk/rkward/rkward/rkconsole.cpp	2012-09-27 09:27:50 UTC (rev 4319)
+++ trunk/rkward/rkward/rkconsole.cpp	2012-09-27 15:11:46 UTC (rev 4320)
@@ -62,7 +62,7 @@
 // static
 RKConsole* RKConsole::main_console = 0;
 
-RKConsole::RKConsole (QWidget *parent, bool tool_window, const char *name) : RKMDIWindow (parent, RKMDIWindow::ConsoleWindow, tool_window, name) {
+RKConsole::RKConsole (QWidget *parent, bool tool_window, const char *name) : RKMDIWindow (parent, RKMDIWindow::ConsoleWindow, tool_window, name), commands_history (false, false) {
 	RK_TRACE (APP);
 
 	QVBoxLayout *layout = new QVBoxLayout (this);
@@ -134,8 +134,7 @@
 	clear ();
 	RKCommandHighlighter::setHighlighting (doc, RKCommandHighlighter::RInteractiveSession);
 
-	commands_history = RKSettingsModuleConsole::loadCommandHistory ();
-	commands_history_position = commands_history.constEnd ();
+	commands_history.setHistory (RKSettingsModuleConsole::loadCommandHistory ());
 
 	current_command = 0;
 	current_command_displayed_up_to = 0;
@@ -151,7 +150,7 @@
 	RK_TRACE (APP);
 
 	delete hinter;
-	RKSettingsModuleConsole::saveCommandHistory (commands_history);
+	RKSettingsModuleConsole::saveCommandHistory (commands_history.getHistory ());
 }
 
 QAction* RKConsole::addProxyAction (const QString& actionName, const QString& label) {
@@ -257,8 +256,6 @@
 		return true;
 	}
 
-	command_edited = true; // all other keys are considered as "editing" the current comand
-
 	if (key == Qt::Key_Home) {
 		if (modifier == Qt::ShiftModifier) {
 			int lastline = doc->lines () - 1;
@@ -304,7 +301,7 @@
 		}
 
 		hinter->hideArgHint ();
-		addCommandToHistory (currentEditingLine ());
+		commands_history.append (currentEditingLine ());
 		submitCommand ();
 		return true;
 	} else if (key == Qt::Key_Left){
@@ -578,64 +575,17 @@
 void RKConsole::commandsListUp (bool context_sensitive) {
 	RK_TRACE (APP);
 
-	// if we are at the last line, i.e. not yet navigating the command history, store the current command
-	if (commands_history.constEnd () == commands_history_position) history_editing_line = currentEditingLine ();
-
-	if (context_sensitive) {
-		if (command_edited) {
-			command_history_context = currentEditingLine ();
-			commands_history_position = commands_history.constEnd ();
-			command_edited = false;
-		}
-	} else {
-		command_edited = true;
-	}
-
-	bool found = false;
-	QStringList::const_iterator it = commands_history_position;
-	while (it != commands_history.constBegin ()) {
-		--it;
-	  	if ((!context_sensitive) || (*it).startsWith (command_history_context)) { // we found a match or previous line
-			found = true;
-			break;
-		}
-	}
-
-	if (found) {		// if we did not find a previous matching line, do not touch the commands_history_position
-		commands_history_position = it;
-		setCurrentEditingLine (*commands_history_position);
-	} else {
-		KApplication::kApplication ()->beep ();
-	}
+	bool found = commands_history.up (context_sensitive, currentEditingLine ());
+	if (found) setCurrentEditingLine (commands_history.current ());
+	else KApplication::kApplication ()->beep ();
 }
 
 void RKConsole::commandsListDown (bool context_sensitive) {
 	RK_TRACE (APP);
 
-	if (context_sensitive) {
-		if (command_edited) {
-			command_history_context = currentEditingLine ();
-	  		commands_history_position = commands_history.constEnd ();
-	  		command_edited = false;
-	  		return; // back at bottommost item
-		}
-	} else {
-		command_edited = true;
-	}
-
-	if (commands_history.constEnd () == commands_history_position) {		// already at bottommost item
-		KApplication::kApplication ()->beep ();
-		return;
-	}
-
-	while (++commands_history_position != commands_history.constEnd ()) {
-		if ((!context_sensitive) || (*commands_history_position).startsWith (command_history_context)) { // we found a match or next line
-			break;
-		}
-	}
-
-	if (commands_history.constEnd () == commands_history_position) setCurrentEditingLine (history_editing_line);
-	else setCurrentEditingLine (*commands_history_position);
+	bool found = commands_history.down (context_sensitive, currentEditingLine ());
+	if (found) setCurrentEditingLine (commands_history.current ());
+	else KApplication::kApplication ()->beep ();
 }
 
 void RKConsole::rCommandDone (RCommand *command) {
@@ -655,7 +605,7 @@
 		incomplete_command.clear ();
 	}
 
-	commands_history_position = commands_history.constEnd ();
+	commands_history.goToEnd ();
 	showPrompt ();
 	tryNextInBuffer ();
 }
@@ -794,31 +744,10 @@
 	showPrompt ();
 }
 
-void RKConsole::addCommandToHistory (const QString &command) {
-	RK_TRACE (APP);
-	if ((!command.isEmpty ()) && (commands_history.isEmpty () || commands_history.last() != command)) { // don't add empty or duplicate lines
-		commands_history.append (command);
-	}
-
-	if (RKSettingsModuleConsole::maxHistoryLength ()) {
-		uint c = commands_history.count ();
-		for (uint ui = c; ui > RKSettingsModuleConsole::maxHistoryLength (); --ui) {
-			commands_history.pop_front ();
-		}
-	}
-
-	history_editing_line = QString ();
-	commands_history_position = commands_history.constEnd ();
-	command_edited = false;
-}
-
 void RKConsole::setCommandHistory (const QStringList &new_history, bool append) {
 	RK_TRACE (APP);
 
-	if (append) commands_history.append (new_history);
-	else commands_history = new_history;
-
-	addCommandToHistory (QString ());	// side-effect of checking history length
+	commands_history.setHistory (new_history, append);
 }
 
 void RKConsole::userLoadHistory (const KUrl &_url) {
@@ -1012,7 +941,7 @@
 		QStringList lines = command_string.split ('\n', QString::SkipEmptyParts);
 		if ((RKSettingsModuleConsole::addPipedCommandsToHistory() == RKSettingsModuleConsole::AlwaysAdd) || (lines.count () == 1)) {
 			for (int i = 0; i < lines.count (); ++i) {
-				addCommandToHistory (lines[i]);
+				commands_history.append (lines[i]);
 			}
 		}
 	}

Modified: trunk/rkward/rkward/rkconsole.h
===================================================================
--- trunk/rkward/rkward/rkconsole.h	2012-09-27 09:27:50 UTC (rev 4319)
+++ trunk/rkward/rkward/rkconsole.h	2012-09-27 15:11:46 UTC (rev 4320)
@@ -26,6 +26,7 @@
 #include "rbackend/rcommandreceiver.h"
 #include "windows/rkcommandeditorwindow.h"
 #include "windows/rkmdiwindow.h"
+#include "misc/rkcommandhistory.h"
 
 class QEvent;
 class QKeyEvent;
@@ -72,7 +73,7 @@
 /** reimplemnented from RKMDIWindow to clear selection when gaining focus */
 	void activate (bool with_focus=true);
 	void setCommandHistory (const QStringList &new_history, bool append);
-	QStringList commandHistory () const { return commands_history; };
+	QStringList commandHistory () const { return commands_history.getHistory (); };
 protected:
 /** Handle keystrokes before they reach the kate-part. Return TRUE if we want the kate-part to ignore it
 \param e the QKeyEvent */
@@ -90,15 +91,7 @@
 	void insertCompletion (int line_num, int word_start, int word_end, const QString &completion);
 	QString incomplete_command;
 /** A list to store previous commands */
-	QStringList commands_history;
-/** current position in the commands history */
-	QStringList::const_iterator commands_history_position;
-/** A flag to indicate whether the command was edited while scrolling in the history */ 
-	bool command_edited;
-/** The last line in the history is special, in that it is stored before it is submitted, but not permanently so */
-	QString history_editing_line;
-/** The context to look out for, if doing a context search in the command history */
-	QString command_history_context;
+	RKCommandHistory commands_history;
 /** Sets the cursor position to the end of the last line. */
 	void cursorAtTheEnd ();
 /** Submits the current command */
@@ -117,8 +110,6 @@
 /** Try to submit the next chunk of the input buffer. */
 	void tryNextInBuffer ();
 	void showPrompt ();
-/** Add given command to command history. Also checks, wether the history is longer than max length, and chops it if so. */
-	void addCommandToHistory (const QString &command);
 
 	QString prefix;
 /** This string stores the regular prefix printed at the beginning of each line. */

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