[rkward-cvs] rkward/rkward/plugin rkstandardcomponentgui.cpp,NONE,1.1 rkstandardcomponentgui.h,NONE,1.1 Makefile.am,1.14,1.15 rkcomponent.cpp,1.9,1.10 rkcomponent.h,1.10,1.11 rkcomponentproperties.cpp,1.15,1.16 rkinput.h,1.3,1.4 rkpluginbrowser.h,1.3,1.4 rkstandardcomponent.cpp,1.16,1.17 rkstandardcomponent.h,1.8,1.9 rktext.h,1.5,1.6 rkvarslot.cpp,1.20,1.21

Thomas Friedrichsmeier tfry at users.sourceforge.net
Mon Mar 20 00:57:33 UTC 2006


Update of /cvsroot/rkward/rkward/rkward/plugin
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19395/rkward/plugin

Modified Files:
	Makefile.am rkcomponent.cpp rkcomponent.h 
	rkcomponentproperties.cpp rkinput.h rkpluginbrowser.h 
	rkstandardcomponent.cpp rkstandardcomponent.h rktext.h 
	rkvarslot.cpp 
Added Files:
	rkstandardcomponentgui.cpp rkstandardcomponentgui.h 
Log Message:
Wizard interface seems to work based on RKComponent. Second internal milestone reached

Index: rkcomponent.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkcomponent.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** rkcomponent.h	19 Mar 2006 16:41:26 -0000	1.10
--- rkcomponent.h	20 Mar 2006 00:57:31 -0000	1.11
***************
*** 42,53 ****
  		Component = 2002,
  		ComponentVarSelector = 2003,
! 		ComponentVarSlot = 2003,
! 		ComponentFormula = 2004,
! 		ComponentRadio = 2005,
! 		ComponentCheckBox = 2006,
! 		ComponentSpinBox = 2007,
! 		ComponentInput = 2008,
! 		ComponentBrowser = 2009,
! 		ComponentText = 2010,
  		ComponentUser = 3000	/**< for user expansion */
  	};
--- 42,53 ----
  		Component = 2002,
  		ComponentVarSelector = 2003,
! 		ComponentVarSlot = 2004,
! 		ComponentFormula = 2005,
! 		ComponentRadio = 2006,
! 		ComponentCheckBox = 2007,
! 		ComponentSpinBox = 2008,
! 		ComponentInput = 2009,
! 		ComponentBrowser = 2010,
! 		ComponentText = 2011,
  		ComponentUser = 3000	/**< for user expansion */
  	};
***************
*** 72,76 ****
  	void setRequired (bool require) { required = require; };
  protected:
- 	friend class RKComponentBuilder;
  /** simple convenience function to add a child to the map of children */
  	void addChild (const QString &id, RKComponentBase *child);
--- 72,75 ----
***************
*** 96,99 ****
--- 95,108 ----
  /** reimplemented to only return true, if all children are satisfied */
  	bool isValid ();
+ /** The component as a wizardish (multi-page) interface. Default implementation returns false */
+ 	virtual bool isWizardish ();
+ /** If the component isWizardish (), returns true, if it has a next/previous page
+ @param next if true, returns true, if there is a next page (i.e. not at last page). If false, returns true if there is a previous page (i.e. not at first page). False otherwise. Default implementation returns false at all times. */
+ 	virtual bool havePage (bool next);
+ /** go to page
+ @param next if true, go to next (shown) page, if false go to previous (shown) page. Default implementation does nothing */
+ 	virtual void movePage (bool next);
+ /** returns true, if the current page is satisfied (see isWizardish ()). Default implementation returns isSatisfied () */
+ 	virtual bool currentPageSatisfied () { return (isSatisfied ()); };
  public slots:
  /** This handles changes in the default properties (enabledness, visibility, requiredness). You will use similar slots in derived classes to handle
***************
*** 125,130 ****
  	RKComponentPropertyBool *requiredness_property;
  	RKComponent *_parent;
! private:
! 	void setReady (bool ready);
  };
  
--- 134,139 ----
  	RKComponentPropertyBool *requiredness_property;
  	RKComponent *_parent;
! /** usually happens during construction, so you don't need to call this - unless you're RKStandardComponent, and discard the children at some point of time */
! 	void createDefaultProperties ();
  };
  

Index: rkpluginbrowser.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkpluginbrowser.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** rkpluginbrowser.h	19 Mar 2006 16:41:26 -0000	1.3
--- rkpluginbrowser.h	20 Mar 2006 00:57:31 -0000	1.4
***************
*** 42,45 ****
--- 42,46 ----
  	RKComponentPropertyBase *selection;
  	QString value (const QString &modifier) { return (selection->value (modifier)); };
+ 	int type () { return ComponentBrowser; };
  public slots:
  	void textChanged ();

Index: rkvarslot.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkvarslot.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** rkvarslot.cpp	19 Mar 2006 16:41:26 -0000	1.20
--- rkvarslot.cpp	20 Mar 2006 00:57:31 -0000	1.21
***************
*** 164,172 ****
  	// first update the properties
  	if (add_mode) {
! 		ObjectList objlist = source->objectList ();
! 		ObjectList::const_iterator it = objlist.begin ();
! 		while (it != objlist.end ()) {
! 			available->addObjectValue (*it);
! 			++it;
  		}
  	} else {		// remove-mode
--- 164,176 ----
  	// first update the properties
  	if (add_mode) {
! 		if (multi) {
! 			ObjectList objlist = source->objectList ();
! 			ObjectList::const_iterator it = objlist.begin ();
! 			while (it != objlist.end ()) {
! 				available->addObjectValue (*it);
! 				++it;
! 			}
! 		} else {
! 			available->setObjectValue (source->objectValue ());
  		}
  	} else {		// remove-mode

Index: rktext.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rktext.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** rktext.h	19 Mar 2006 16:41:26 -0000	1.5
--- rktext.h	20 Mar 2006 00:57:31 -0000	1.6
***************
*** 38,41 ****
--- 38,42 ----
  	RKComponentPropertyBase *text;
  	QString value (const QString &modifier) { return (text->value (modifier)); };
+ 	int type () { return ComponentText; };
  public slots:
  	void textChanged (RKComponentPropertyBase *);

--- NEW FILE: rkstandardcomponentgui.cpp ---
/***************************************************************************
                          rkstandardcomponentgui  -  description
                             -------------------
    begin                : Sun Mar 19 2006
    copyright            : (C) 2006 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 "rkstandardcomponentgui.h"

#include <klocale.h>

#include <qtimer.h>
#include <qsplitter.h>
#include <qlayout.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qpushbutton.h>
#include <qlabel.h>

#include "../rkcommandeditor.h"
#include "../rbackend/rinterface.h"
#include "../rkglobals.h"
#include "../debug.h"


/////////////////////////////////////// RKStandardComponentGUI ////////////////////////////////////////////////

RKStandardComponentGUI::RKStandardComponentGUI (RKStandardComponent *component, RKComponentPropertyCode *code_property) {
	RK_TRACE (PLUGIN);

	RKStandardComponentGUI::component = component;
	RKStandardComponentGUI::code_property = code_property;
	connect (code_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (codeChanged (RKComponentPropertyBase *)));

	// code update timer
	code_update_timer = new QTimer (this);
	connect (code_update_timer, SIGNAL (timeout ()), this, SLOT (updateCodeNow ()));
}

RKStandardComponentGUI::~RKStandardComponentGUI () {
	RK_TRACE (PLUGIN);
}

void RKStandardComponentGUI::createDialog (bool switchable) {
	RK_TRACE (PLUGIN);

	QGridLayout *main_grid = new QGridLayout (this, 1, 1);
	splitter = new QSplitter (QSplitter::Vertical, this);
	main_grid->addWidget (splitter, 0, 0);
	QWidget *upper_widget = new QWidget (splitter);
	
	QHBoxLayout *hbox = new QHBoxLayout (upper_widget, RKGlobals::marginHint (), RKGlobals::spacingHint ());
	QVBoxLayout *vbox = new QVBoxLayout (hbox, RKGlobals::spacingHint ());

	// build standard elements
	main_widget = new QVBox (upper_widget);
	hbox->addWidget (main_widget);

	// lines
	QFrame *line;
	line = new QFrame (upper_widget);
	line->setFrameShape (QFrame::VLine);
	line->setFrameShadow (QFrame::Plain);	
	hbox->addWidget (line);

	// buttons
	vbox = new QVBoxLayout (hbox, RKGlobals::spacingHint ());
	ok_button = new QPushButton ("Submit", upper_widget);
	connect (ok_button, SIGNAL (clicked ()), this, SLOT (ok ()));
	vbox->addWidget (ok_button);
	
	cancel_button = new QPushButton ("Close", upper_widget);
	connect (cancel_button, SIGNAL (clicked ()), this, SLOT (cancel ()));
	vbox->addWidget (cancel_button);
	vbox->addStretch (1);
	
	help_button = new QPushButton ("Help", upper_widget);
	connect (help_button, SIGNAL (clicked ()), this, SLOT (help ()));
	vbox->addWidget (help_button);
	
	if (switchable) {
		switch_button = new QPushButton ("Use Wizard", upper_widget);
		connect (switch_button, SIGNAL (clicked ()), this, SLOT (switchInterface ()));
		vbox->addWidget (switch_button);
	}
	vbox->addStretch (2);
	
	toggle_code_button = new QPushButton ("Code", upper_widget);
	toggle_code_button->setToggleButton (true);
	toggle_code_button->setOn (true);
	connect (toggle_code_button, SIGNAL (clicked ()), this, SLOT (toggleCode ()));
	vbox->addWidget (toggle_code_button);
	
	// code display
	code_display = new RKCommandEditor (splitter, true);
}

void RKStandardComponentGUI::ok () {
	RK_TRACE (PLUGIN);

	RK_ASSERT (code_property->isValid ());
	
	RCommandChain *chain = RKGlobals::rInterface ()->startChain ();
	RKGlobals::rInterface ()->issueCommand (new RCommand (code_property->preprocess (), RCommand::Plugin | RCommand::DirectToOutput), chain);
	RKGlobals::rInterface ()->issueCommand (new RCommand (code_property->calculate (), RCommand::Plugin | RCommand::DirectToOutput), chain);
	RKGlobals::rInterface ()->issueCommand (new RCommand (code_property->printout (), RCommand::Plugin | RCommand::DirectToOutput), chain);
	RKGlobals::rInterface ()->issueCommand (new RCommand (code_property->cleanup (), RCommand::Plugin | RCommand::DirectToOutput), chain);
	RKGlobals::rInterface ()->closeChain (chain);
}

void RKStandardComponentGUI::cancel () {
	RK_TRACE (PLUGIN);

	hide ();
	component->deleteLater ();
}

void RKStandardComponentGUI::toggleCode () {
	RK_TRACE (PLUGIN);

	code_display->setShown (toggle_code_button->isOn ());
	updateCode ();
}

void RKStandardComponentGUI::help () {
	RK_TRACE (PLUGIN);
}

void RKStandardComponentGUI::closeEvent (QCloseEvent *e) {
	RK_TRACE (PLUGIN);

	e->accept ();
	cancel ();
}

void RKStandardComponentGUI::enableSubmit (bool enable) {
	RK_TRACE (PLUGIN);

	ok_button->setEnabled (enable);
}

void RKStandardComponentGUI::codeChanged (RKComponentPropertyBase *) {
	RK_TRACE (PLUGIN);

	updateCode ();
}

void RKStandardComponentGUI::updateCode () {
	RK_TRACE (PLUGIN);

	if (!code_display->isShown ()) return;
	code_update_timer->start (0, true);
}

void RKStandardComponentGUI::updateCodeNow () {
	RK_TRACE (PLUGIN);

	if (!code_property->isValid ()) {
		code_display->setText (i18n ("Processing. Please wait"));
		RK_DO (qDebug ("code not ready to be displayed: pre %d, cal %d, pri %d, cle %d", !code_property->preprocess ().isNull (), !code_property->calculate ().isNull (), !code_property->printout ().isNull (), !code_property->cleanup ().isNull ()), PLUGIN, DL_DEBUG);
	} else {
		code_display->setText (code_property->preprocess () + code_property->calculate () + code_property->printout () + code_property->cleanup ());
	}
}

///////////////////////////////// RKStandardComponentWizard /////////////////////////////////

RKStandardComponentWizard::RKStandardComponentWizard (RKStandardComponent *component, RKComponentPropertyCode *code_property) : RKStandardComponentGUI (component, code_property) {
	RK_TRACE (PLUGIN);

	submit_enabled = false;
	is_switchable = false;
}

RKStandardComponentWizard::~RKStandardComponentWizard () {
	RK_TRACE (PLUGIN);
}

void RKStandardComponentWizard::updateCode () {
	RK_TRACE (PLUGIN);

	updateState ();
}

void RKStandardComponentWizard::createWizard (bool switchable) {
	RK_TRACE (PLUGIN);

	is_switchable = switchable;
	// create main layout and stack
	QGridLayout *main_grid = new QGridLayout (this, 3, 4, RKGlobals::marginHint (), RKGlobals::spacingHint ());
	main_widget = stack = new RKStandardComponentStack (this);
	main_grid->addMultiCellWidget (stack, 0, 0, 0, 3);

	// build standard elements
	// lines
	QFrame *line;
	line = new QFrame (main_widget);
	line->setFrameShape (QFrame::HLine);
	line->setFrameShadow (QFrame::Plain);
	main_grid->addMultiCellWidget (line, 1, 1, 0, 3);

	// buttons
	cancel_button = new QPushButton ("Cancel", this);
	main_grid->addWidget (cancel_button, 2, 0, Qt::AlignLeft);
	help_button = new QPushButton ("Help", this);
	main_grid->addWidget (help_button, 2, 1, Qt::AlignLeft);
	prev_button = new QPushButton (QString::null, this);
	prev_button->setEnabled (false);
	main_grid->addWidget (prev_button, 2, 2, Qt::AlignRight);
	next_button = new QPushButton (QString::null, this);
	main_grid->addWidget (next_button, 2, 3, Qt::AlignRight);
	connect (next_button, SIGNAL (clicked ()), this, SLOT (next ()));
	connect (prev_button, SIGNAL (clicked ()), this, SLOT (prev ()));
	connect (cancel_button, SIGNAL (clicked ()), this, SLOT (cancel ()));
	connect (help_button, SIGNAL (clicked ()), this, SLOT (help ()));
}

void RKStandardComponentWizard::addLastPage () {
	RK_TRACE (PLUGIN);

	// build the last page
	RKComponent *last_page = stack->addPage (component);
	QVBoxLayout *vbox = new QVBoxLayout (last_page, RKGlobals::spacingHint ());
	QLabel *label = new QLabel (i18n ("Below you can see the command(s) corresponding to the settings you made. Click 'Submit' to run the command(s)."), last_page);
	label->setAlignment (Qt::AlignAuto | Qt::AlignVCenter | Qt::ExpandTabs | Qt::WordBreak);
	code_display = new RKCommandEditor (last_page, true);
	vbox->addWidget (label);
	vbox->addWidget (code_display);

	stack->goToFirstPage ();
	updateState ();
}

void RKStandardComponentWizard::next () {
	RK_TRACE (PLUGIN);

	RK_ASSERT (stack->currentPageSatisfied ());

	if (stack->havePage (true)) {
		stack->movePage (true);
		updateState ();
	} else {
		ok ();
	}
}

void RKStandardComponentWizard::prev () {
	RK_TRACE (PLUGIN);

	if (stack->havePage (false)) {
		stack->movePage (false);
		updateState ();
	} else if (is_switchable) {
		switchInterface ();
	} else {
		RK_ASSERT (false);
	}
}

void RKStandardComponentWizard::updateState () {
	RK_TRACE (PLUGIN);

	if (stack->havePage (true)) {		// not on last page
		next_button->setText (i18n ("Next >"));
		next_button->setEnabled (stack->currentPageSatisfied ());
		if (stack->havePage (false) || (!is_switchable)) {		// not on first page
			prev_button->setText (i18n ("< Back"));
			prev_button->setEnabled (stack->havePage (false));
		} else {
			prev_button->setText (i18n ("Use Dialog"));
			prev_button->setEnabled (true);
		}
	} else {			// on last page
		// do code update when on last page
		if (!stack->havePage (true)) code_update_timer->start (0, true);
		next_button->setText (i18n ("Submit"));
		next_button->setEnabled (submit_enabled);
	}
}

void RKStandardComponentWizard::enableSubmit (bool enable) {
	RK_TRACE (PLUGIN);

	submit_enabled = enable;
}



//////////////////////////////// RKStandardComponentStack ////////////////////////////////////

RKStandardComponentStack::RKStandardComponentStack (QWidget *parent) : QWidgetStack (parent) {
	RK_TRACE (PLUGIN);

	num_pages = current_page = 0;
	current_def = 0;
}

RKStandardComponentStack::~RKStandardComponentStack () {
	RK_TRACE (PLUGIN);

	for (Pages::const_iterator it = pages.constBegin (); it != pages.constEnd (); ++it) {
		delete (*it);
	}
}

bool RKStandardComponentStack::havePage (bool next) {
	RK_TRACE (PLUGIN);

	if (next) {
		return (nextVisiblePage () <= (num_pages-1));
	} else {
		return (previousVisiblePage () >= 0);
	}
}

void RKStandardComponentStack::movePage (bool next) {
	RK_TRACE (PLUGIN);

	int id;
	if (next) {
		id = nextVisiblePage ();
	} else {
		id = previousVisiblePage ();
	}

	if (id < 0) {
		RK_ASSERT (false);
		return;
	}

	current_page = id;
	current_def = pages[id];
	raiseWidget (current_def->page);
}

bool RKStandardComponentStack::currentPageSatisfied () {
	RK_TRACE (PLUGIN);
	if (!current_def) {
		RK_ASSERT (false);
		return false;
	}

	for (PageComponents::const_iterator it = current_def->page_components.constBegin (); it != current_def->page_components.constEnd (); ++it) {
		qDebug ("type %d", (*it)->type ());
		if (!((*it)->isSatisfied ())) {
			qDebug ("is dissatisfied");
			return false;
		}
	}

	return true;
}

void RKStandardComponentStack::goToFirstPage () {
	RK_TRACE (PLUGIN);

	current_page = 0;
	current_def = pages.first ();
	raiseWidget (current_def->page);
}

RKComponent *RKStandardComponentStack::addPage (RKComponent *parent) {
	RK_TRACE (PLUGIN);

	PageDef *def = new PageDef;
	def->page = new RKComponent (parent, this);
	addWidget (def->page);
	pages.append (def);

	current_def = def;
	num_pages++;
	current_page++;

	return def->page;
}

void RKStandardComponentStack::addComponentToCurrentPage (RKComponent *component) {
	RK_TRACE (PLUGIN);
	if (!current_def) {
		RK_ASSERT (false);
		return;
	}

	qDebug ("component added to page %d", current_page);
	current_def->page_components.append (component);
}

int RKStandardComponentStack::previousVisiblePage () {
	RK_TRACE (PLUGIN);

	int prev_page = current_page - 1;
	while (prev_page >= 0) {
		if (pages[prev_page]->page->visibilityProperty ()->boolValue ()) return prev_page;
		--prev_page;
	}

	return prev_page;
}

int RKStandardComponentStack::nextVisiblePage () {
	RK_TRACE (PLUGIN);

	int next_page = current_page + 1;
	while (next_page <= (num_pages-1)) {
		if (pages[next_page]->page->visibilityProperty ()->boolValue ()) return next_page;
		++next_page;
	}

	return next_page;
}

#include "rkstandardcomponentgui.moc"

Index: rkstandardcomponent.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkstandardcomponent.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** rkstandardcomponent.h	19 Mar 2006 18:15:57 -0000	1.8
--- rkstandardcomponent.h	20 Mar 2006 00:57:31 -0000	1.9
***************
*** 25,31 ****
  class RKErrorDialog;
  class RKStandardComponentGUI;
  class ScriptBackend;
  
! /** The standard type of component (i.e. stand-alone), previously known as "plugin". This is the type of component described by an XML-file */
  class RKStandardComponent : public RKComponent {
  	Q_OBJECT
--- 25,34 ----
  class RKErrorDialog;
  class RKStandardComponentGUI;
+ class RKStandardComponentStack;
  class ScriptBackend;
  
! /** The standard type of component (i.e. stand-alone), previously known as "plugin". This is the type of component described by an XML-file
! 
! @author Thomas Friedrichsmeier */
  class RKStandardComponent : public RKComponent {
  	Q_OBJECT
***************
*** 42,47 ****
  /** reimplemented to return true only when the backend is idle*/
  	bool isReady ();
  public slots:
- 	void switchInterfaces ();
  /** this gets called by the script-backend, when it's done. Might enable the
  	submit button or destruct the plugin. */
--- 45,61 ----
  /** reimplemented to return true only when the backend is idle*/
  	bool isReady ();
+ /** reimplemented to return true, if the RKStandardComponent is in Wizard mode */
+ 	bool isWizardish ();
+ /** reimplemented to actually answer the question (if in Wizard mode) */
+ 	bool havePage (bool next);
+ /** reimplemented to actually move the page (if in Wizard mode)  */
+ 	void movePage (bool next);
+ /** reimplemented to actually answer the question (if in Wizard mode) */
+ 	bool currentPageSatisfied ();
+ /** for use by RKComponentBuilder to add a page to a wizardish component */
+ 	RKComponent *addPage ();
+ /** switch from dialog to wizard or vice versa */
+ 	void switchInterface ();
  public slots:
  /** this gets called by the script-backend, when it's done. Might enable the
  	submit button or destruct the plugin. */
***************
*** 54,58 ****
  	void getValue (const QString &id);
  private:
! /** The property holding the generated code. TODO: maybe, de facto, this property should be controlled (but not owned) by the scriptbackend. This way, we'd need less twisted logic inside this class. */
  	RKComponentPropertyCode *code;
  	QString filename;
--- 68,72 ----
  	void getValue (const QString &id);
  private:
! /** The property holding the generated code. Note that this member is tightly controlled by the ScriptBackend */
  	RKComponentPropertyCode *code;
  	QString filename;
***************
*** 60,117 ****
  	RKErrorDialog *error_dialog;
  	RKStandardComponentGUI *gui;
! /** sometimes the plugin can't be destroyed immediately, since, for example the script-backend is
! 	still busy cleaning stuff up. In that case this var is set and the plugin gets destroyed ASAP. */
  	bool created;
  };
  
- #include <qwidget.h>
- 
- class RKCommandEditor;
- class QPushButton;
- class QTimer;
- class QSplitter;
- 
- /** contains the standard GUI elements for a top-level RKStandardComponent
- TODO: differentiate into two classes for dialog and wizard interfaces. For now we ignore the wizard interface */
- class RKStandardComponentGUI : public QWidget {
- 	Q_OBJECT
- public:
- 	RKStandardComponentGUI (RKStandardComponent *component, RKComponentPropertyCode *code_property);
- 	~RKStandardComponentGUI ();
- 
- 	QWidget *mainWidget () { return main_widget; };
- 
- 	void enableSubmit (bool enable);
- 	void updateCode ();
- public slots:
- 	void ok ();
- 	void back ();
- 	void cancel ();
- 	void toggleCode ();
- 	void help ();
- 	void codeChanged (RKComponentPropertyBase *);
- 	void updateCodeNow ();
- private:
- 	QWidget *main_widget;
- 	RKComponentPropertyCode *code_property;
- 	QTimer *code_update_timer;
  
- 	// standard gui-elements
- 	RKCommandEditor *code_display;
- 
- 	// common widgets
- 	QSplitter *splitter;
- 	QPushButton *ok_button;
- 	QPushButton *cancel_button;
- 	QPushButton *help_button;
- 	QPushButton *switch_button;
- 
- 	// widgets for dialog only
- 	QPushButton *toggle_code_button;
- private:
- 	RKStandardComponent *component;
- protected:
- 	void closeEvent (QCloseEvent *e);
- };
  
  /** A helper class used to build and initialize an RKComponent. Most importantly this will keep track of the properties yet to be connected. Used at least by RKStandardComponent.
--- 74,91 ----
  	RKErrorDialog *error_dialog;
  	RKStandardComponentGUI *gui;
! 	RKStandardComponentStack *wizard;
! /** Avoid updating code-display, etc. until the component is fully created */
  	bool created;
+ 	bool createTopLevel (const QDomElement &doc_element, int force_mode=0);
+ 	void buildAndInitialize (const QDomElement &doc_element, const QDomElement &gui_element, QWidget *parent_widget, bool build_wizard);
+ /** used during switchInterfaces () to discard child components, and delete gui if applicable */
+ 	void discard ();
+ protected:
+ 	friend class RKComponentBuilder;
+ /** reimplemented for technical reasons. Additionally registers component children with the component stack if in wizard mode */
+ 	void addChild (const QString &id, RKComponentBase *child);
  };
  
  
  
  /** A helper class used to build and initialize an RKComponent. Most importantly this will keep track of the properties yet to be connected. Used at least by RKStandardComponent.
***************
*** 122,140 ****
  - Builder takes care of connecting properties
  
! Important: For built components with non-zero parent components should call parent_component->addChild () to register them! As an exception, this may be omitted for passive components (e.g. layouting components) that do not specify an id
  
  Reminder to the twisted brain: Typically inside a standard-component, *all* child components, even if nested in layouting components, etc. have the same standard-component as parent! Only embedded full-fledged components are a truely separate unit!
! */
  class RKComponentBuilder {
  public:
! 	RKComponentBuilder (RKComponent *parent_component);
  	~RKComponentBuilder ();
! 	void buildElement (const QDomElement &element, QWidget *parent_widget);
  	void makeConnections ();
! 	RKComponent *component () const { return parent; };
  private:
  /** internal convenience function to schedule a property connection */
  	void addConnection (const QString &client_id, const QString &client_property, const QString &governor_id, const QString &governor_property, bool reconcile, const QDomElement &origin);
! 	RKComponent *parent;
  	struct RKComponentPropertyConnection {
  		QString governor_property;
--- 96,116 ----
  - Builder takes care of connecting properties
  
! Calls parent_component->addChild () for built child-components. As an exception, this may be omitted for passive components (e.g. layouting components) that do not specify an id
  
  Reminder to the twisted brain: Typically inside a standard-component, *all* child components, even if nested in layouting components, etc. have the same standard-component as parent! Only embedded full-fledged components are a truely separate unit!
! 
! @author Thomas Friedrichsmeier */
  class RKComponentBuilder {
  public:
! 	RKComponentBuilder (RKStandardComponent *parent_component);
  	~RKComponentBuilder ();
! 	void buildElement (const QDomElement &element, QWidget *parent_widget, bool allow_pages);
! 	void parseLogic (const QDomElement &element);
  	void makeConnections ();
! 	RKStandardComponent *component () const { return parent; };
  private:
  /** internal convenience function to schedule a property connection */
  	void addConnection (const QString &client_id, const QString &client_property, const QString &governor_id, const QString &governor_property, bool reconcile, const QDomElement &origin);
! 	RKStandardComponent *parent;
  	struct RKComponentPropertyConnection {
  		QString governor_property;

Index: rkinput.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkinput.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** rkinput.h	19 Mar 2006 16:41:26 -0000	1.3
--- rkinput.h	20 Mar 2006 00:57:31 -0000	1.4
***************
*** 40,43 ****
--- 40,44 ----
  	RKComponentPropertyBase *text;
  	QString value (const QString &modifier) { return (text->value (modifier)); };
+ 	int type () { return ComponentInput; };
  public slots:
  	void textChanged ();

Index: Makefile.am
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/Makefile.am,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** Makefile.am	17 Mar 2006 17:27:24 -0000	1.14
--- Makefile.am	20 Mar 2006 00:57:31 -0000	1.15
***************
*** 4,8 ****
  libplugin_a_SOURCES = rkcomponentmap.cpp rkcomponentproperties.cpp rkcomponent.cpp \
  	rkstandardcomponent.cpp rkvarselector.cpp rkvarslot.cpp rkformula.cpp rkradio.cpp \
! 	rkcheckbox.cpp rkpluginspinbox.cpp rkinput.cpp rkpluginbrowser.cpp rktext.cpp
  # rkplugin.cpp \
  #	rkpluginhandle.cpp rkpluginwidget.cpp \
--- 4,9 ----
  libplugin_a_SOURCES = rkcomponentmap.cpp rkcomponentproperties.cpp rkcomponent.cpp \
  	rkstandardcomponent.cpp rkvarselector.cpp rkvarslot.cpp rkformula.cpp rkradio.cpp \
! 	rkcheckbox.cpp rkpluginspinbox.cpp rkinput.cpp rkpluginbrowser.cpp rktext.cpp \
! 	rkstandardcomponentgui.cpp
  # rkplugin.cpp \
  #	rkpluginhandle.cpp rkpluginwidget.cpp \
***************
*** 11,15 ****
  noinst_HEADERS = rkcomponentmap.h rkcomponentproperties.h rkcomponent.h \
  	rkstandardcomponent.h rkvarselector.h rkvarslot.h rkformula.h rkradio.h \
! 	rkcheckbox.h rkpluginspinbox.h rkinput.h rkpluginbrowser.h rktext.h
  # rkplugin.h rkpluginhandle.h \
  # rkpluginwidget.h  \
--- 12,17 ----
  noinst_HEADERS = rkcomponentmap.h rkcomponentproperties.h rkcomponent.h \
  	rkstandardcomponent.h rkvarselector.h rkvarslot.h rkformula.h rkradio.h \
! 	rkcheckbox.h rkpluginspinbox.h rkinput.h rkpluginbrowser.h rktext.h \
! 	rkstandardcomponentgui.h
  # rkplugin.h rkpluginhandle.h \
  # rkpluginwidget.h  \

Index: rkstandardcomponent.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkstandardcomponent.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** rkstandardcomponent.cpp	19 Mar 2006 18:15:57 -0000	1.16
--- rkstandardcomponent.cpp	20 Mar 2006 00:57:31 -0000	1.17
***************
*** 18,38 ****
  #include "rkstandardcomponent.h"
  
- //#include <qdom.h>
- //#include <qfile.h>
  #include <qfileinfo.h>
- //#include <qdialog.h>
  #include <qlayout.h>
  #include <qvbox.h>
  #include <qhbox.h>
  #include <qgroupbox.h>
- //#include <qmap.h>
  #include <qframe.h>
- #include <qpushbutton.h>
- //#include <qregexp.h>
  #include <qtabwidget.h>
- #include <qsplitter.h>
- //#include <qwidgetstack.h>
  #include <qlabel.h>
- #include <qtimer.h>
  #include <qapplication.h>
  
--- 18,29 ----
***************
*** 40,52 ****
  #include <kmessagebox.h>
  
! #include "../rkcommandeditor.h"
  #include "../scriptbackends/phpbackend.h"
  #include "../misc/rkerrordialog.h"
  #include "../misc/xmlhelper.h"
! #include "../rbackend/rinterface.h"
  /*#include "../rkward.h"
  #include "../rkeditormanager.h"
  #include "../rkcommandeditor.h"
- #include "../settings/rksettingsmoduleplugins.h"
  */
  
--- 31,42 ----
  #include <kmessagebox.h>
  
! #include "rkstandardcomponentgui.h"
  #include "../scriptbackends/phpbackend.h"
  #include "../misc/rkerrordialog.h"
  #include "../misc/xmlhelper.h"
! #include "../settings/rksettingsmoduleplugins.h"
  /*#include "../rkward.h"
  #include "../rkeditormanager.h"
  #include "../rkcommandeditor.h"
  */
  
***************
*** 73,76 ****
--- 63,67 ----
  	backend = 0;
  	gui = 0;
+ 	wizard = 0;
  	created = false;
  	addChild ("code", code = new RKComponentPropertyCode (this, true));
***************
*** 104,112 ****
  
  // construct the GUI
! 	// if top-level, construct standard elements
! 	if (!parent_widget) {
  		gui = new RKStandardComponentGUI (this, code);
! 		parent_widget = gui->mainWidget ();
  	}
  
  	// create a builder
--- 95,225 ----
  
  // construct the GUI
! 	if (!parent_component) {					// top-level
! 		if (!createTopLevel (doc_element)) {
! 			RK_ASSERT (false);
! 			return;		// should never happen
! 		}
! 	} else {
! 		bool build_wizard = false;
! 		QDomElement gui_element;
! 		if (parent_component->isWizardish ()) {
! 			build_wizard = true;
! 			gui_element = xml->getChildElement (doc_element, "wizard", DL_WARNING);
! 			if (gui_element.isNull ()) {
! 				gui_element = xml->getChildElement (doc_element, "dialog", DL_WARNING);
! 				build_wizard = false;
! 			}
! 		} else {
! 			QDomElement gui_element = xml->getChildElement (doc_element, "dialog", DL_WARNING);
! 			if (gui_element.isNull ()) {
! 				xml->displayError (&doc_element, "Cannot embed a wizard into a dialog, and no dialog definition available", DL_ERROR);
! 				deleteLater ();
! 				return;
! 			}
! 		}
! 		buildAndInitialize (doc_element, gui_element, parent_widget, build_wizard);
! 	}
! }
! 
! RKStandardComponent::~RKStandardComponent () {
! 	RK_TRACE (PLUGIN);
! 
! 	delete error_dialog;
! 	delete backend;
! }
! 
! bool RKStandardComponent::createTopLevel (const QDomElement &doc_element, int force_mode) {
! 	RK_TRACE (PLUGIN);
! 
! 	XMLHelper* xml = XMLHelper::getStaticHelper ();
! 	bool build_wizard = false;
! 	QDomElement dialog_element;
! 	QDomElement wizard_element;
! 
! 	dialog_element = xml->getChildElement (doc_element, "dialog", DL_INFO);
! 	wizard_element = xml->getChildElement (doc_element, "wizard", DL_INFO);
! 	if (!wizard_element.isNull ()) {
! 		build_wizard = xml->getBoolAttribute (wizard_element, "recommended", false, DL_INFO);
! 	}
! 
! 	if (force_mode == 0) {
! 		if (RKSettingsModulePlugins::getInterfacePreference () == RKSettingsModulePlugins::PreferDialog) {
! 			if (!dialog_element.isNull ()) build_wizard = false;
! 		} else if (RKSettingsModulePlugins::getInterfacePreference () == RKSettingsModulePlugins::PreferWizard) {
! 			if (!wizard_element.isNull ()) build_wizard = true;
! 		}
! 	} else if (force_mode == 1) {
! 		build_wizard = false;
! 		if (dialog_element.isNull ()) {
! 			xml->displayError (&doc_element, "Dialog mode forced, but no dialog element given", DL_ERROR);
! 			deleteLater ();
! 			return false;
! 		}
! 	} else if (force_mode == 2) {
! 		build_wizard = true;
! 		if (wizard_element.isNull ()) {
! 			xml->displayError (&doc_element, "Wizard mode forced, but no wizard element given", DL_ERROR);
! 			deleteLater ();
! 			return false;
! 		}
! 	}
! 
! 	if (build_wizard) {
! 		gui = new RKStandardComponentWizard (this, code);
! 		static_cast<RKStandardComponentWizard *> (gui)->createWizard (!dialog_element.isNull ());
! 		wizard = static_cast<RKStandardComponentWizard *> (gui)->getStack ();
! 		buildAndInitialize (doc_element, wizard_element, gui->mainWidget (), true);
! 		static_cast<RKStandardComponentWizard *> (gui)->addLastPage ();
! 	} else {
  		gui = new RKStandardComponentGUI (this, code);
! 		gui->createDialog (!wizard_element.isNull ());
! 		buildAndInitialize (doc_element, dialog_element, gui->mainWidget (), false);
! 	}
! 
! 	return true;
! }
! 
! void RKStandardComponent::switchInterface () {
! 	RK_TRACE (PLUGIN);
! 
! 	RK_ASSERT (gui);		// this should only ever happen on top level
! 
! 	// open the main description file for parsing (again)
! 	XMLHelper* xml = XMLHelper::getStaticHelper ();
! 	QDomElement doc_element = xml->openXMLFile (filename, DL_ERROR);
! 	int force_mode = 2;
! 	if (isWizardish ()) force_mode = 1;
! 
! 	discard ();
! 
! 	createTopLevel (doc_element, force_mode);
! }
! 
! void RKStandardComponent::discard () {
! 	RK_TRACE (PLUGIN);
! 
! 	created = false;
! 	gui->hide ();
! 	gui->deleteLater ();
! 	gui = 0;
! 	wizard = 0;
! 
! 	for (QDictIterator<RKComponentBase> it (child_map); it.current (); ++it) {
! 		if (it.current () != code) {
! 			if (it.current ()->isProperty ()) {
! 				static_cast<RKComponentPropertyBase *> (it.current ())->deleteLater ();
! 			} else {
! 				static_cast<RKComponent *> (it.current ())->deleteLater ();
! 			}
! 		}
  	}
+ 	child_map.clear ();
+ 	createDefaultProperties ();
+ }
+ 
+ void RKStandardComponent::buildAndInitialize (const QDomElement &doc_element, const QDomElement &gui_element, QWidget *parent_widget, bool build_wizard) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	XMLHelper* xml = XMLHelper::getStaticHelper ();
  
  	// create a builder
***************
*** 114,119 ****
  
  	// go
! 	// TODO: this is wrong! wizard/dialog
! 	builder->buildElement (xml->getChildElement (doc_element, "dialog", DL_ERROR), parent_widget);
  
  	// initialize
--- 227,232 ----
  
  	// go
! 	builder->buildElement (gui_element, parent_widget, build_wizard);
! 	builder->parseLogic (xml->getChildElement (doc_element, "logic", DL_INFO));
  
  	// initialize
***************
*** 127,140 ****
  }
  
- RKStandardComponent::~RKStandardComponent () {
- 	RK_TRACE (PLUGIN);
- 
- 	delete error_dialog;
- 	delete backend;
- }
- 
- void RKStandardComponent::switchInterfaces () {
- 	RK_TRACE (PLUGIN);
- }
  
  void RKStandardComponent::changed () {
--- 240,243 ----
***************
*** 179,186 ****
  }
  
  /////////////////////////////////////// RKComponentBuilder /////////////////////////////////////////
  
  
! RKComponentBuilder::RKComponentBuilder (RKComponent *parent_component) {
  	RK_TRACE (PLUGIN);
  	parent = parent_component;
--- 282,340 ----
  }
  
+ bool RKStandardComponent::isWizardish () {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	return (wizard != 0);
+ }
+ 
+ bool RKStandardComponent::havePage (bool next) {
+ 	RK_TRACE (PLUGIN);
+ 	RK_ASSERT (wizard);
+ 
+ 	return (wizard->havePage (next));
+ }
+ 
+ void RKStandardComponent::movePage (bool next) {
+ 	RK_TRACE (PLUGIN);
+ 	RK_ASSERT (wizard);
+ 
+ 	wizard->movePage (next);
+ }
+ 
+ bool RKStandardComponent::currentPageSatisfied () {
+ 	RK_TRACE (PLUGIN);
+ 	RK_ASSERT (wizard);
+ 
+ 	return (wizard->currentPageSatisfied ());
+ }
+ 
+ RKComponent *RKStandardComponent::addPage () {
+ 	RK_TRACE (PLUGIN);
+ 	RK_ASSERT (wizard);
+ 
+ 	RKComponent *page = wizard->addPage (this);
+ 	return page;
+ }
+ 
+ /** reimplemented for technical reasons. Additionally registers component children with the component stack if in wizard mode */
+ void RKStandardComponent::addChild (const QString &id, RKComponentBase *child) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	if (wizard) {
+ 		if (!child->isProperty ()) {
+ 			wizard->addComponentToCurrentPage (static_cast<RKComponent *>(child));
+ 		}
+ 	}
+ 
+ 	RKComponent::addChild (id, child);
+ }
+ 
+ 
+ 
+ 
  /////////////////////////////////////// RKComponentBuilder /////////////////////////////////////////
  
  
! RKComponentBuilder::RKComponentBuilder (RKStandardComponent *parent_component) {
  	RK_TRACE (PLUGIN);
  	parent = parent_component;
***************
*** 191,195 ****
  }
  
! void RKComponentBuilder::buildElement (const QDomElement &element, QWidget *parent_widget) {
  	RK_TRACE (PLUGIN);
  
--- 345,349 ----
  }
  
! void RKComponentBuilder::buildElement (const QDomElement &element, QWidget *parent_widget, bool allow_pages) {
  	RK_TRACE (PLUGIN);
  
***************
*** 203,218 ****
  		QString id = xml->getStringAttribute (e, "id", "#noid#", DL_INFO);
  
! 	    if (e.tagName () == "row") {
  			QHBox *box = new QHBox (parent_widget);
  			box->setSpacing (RKGlobals::spacingHint ());
! 			buildElement (e, box);
  		} else if (e.tagName () == "column") {
  			QVBox *box = new QVBox (parent_widget);
  			box->setSpacing (RKGlobals::spacingHint ());
! 			buildElement (e, box);
  		} else if (e.tagName () == "frame") {
  			QGroupBox *box = new QGroupBox (1, Qt::Horizontal, e.attribute ("label"), parent_widget);
  			box->setInsideSpacing (RKGlobals::spacingHint ());
! 			buildElement (e, box);
  		} else if (e.tagName () == "tabbook") {
  			QTabWidget *tabbook = new QTabWidget (parent_widget);
--- 357,379 ----
  		QString id = xml->getStringAttribute (e, "id", "#noid#", DL_INFO);
  
! 		if (allow_pages && (e.tagName () == "page")) {
! 			RKComponent *page = component ()->addPage ();
! 			QVBoxLayout *layout = new QVBoxLayout (page);
! 			QVBox *box = new QVBox (page);
! 			box->setSpacing (RKGlobals::spacingHint ());
! 			layout->addWidget (box);
! 			buildElement (e, box, false);
! 		} else if (e.tagName () == "row") {
  			QHBox *box = new QHBox (parent_widget);
  			box->setSpacing (RKGlobals::spacingHint ());
! 			buildElement (e, box, false);
  		} else if (e.tagName () == "column") {
  			QVBox *box = new QVBox (parent_widget);
  			box->setSpacing (RKGlobals::spacingHint ());
! 			buildElement (e, box, false);
  		} else if (e.tagName () == "frame") {
  			QGroupBox *box = new QGroupBox (1, Qt::Horizontal, e.attribute ("label"), parent_widget);
  			box->setInsideSpacing (RKGlobals::spacingHint ());
! 			buildElement (e, box, false);
  		} else if (e.tagName () == "tabbook") {
  			QTabWidget *tabbook = new QTabWidget (parent_widget);
***************
*** 223,227 ****
  					QVBox *tabpage = new QVBox (tabbook);
  					tabpage->setSpacing (RKGlobals::spacingHint ());
! 					buildElement (tab_e, tabpage);
  					tabbook->addTab (tabpage, tab_e.attribute ("label"));
  				}
--- 384,388 ----
  					QVBox *tabpage = new QVBox (tabbook);
  					tabpage->setSpacing (RKGlobals::spacingHint ());
! 					buildElement (tab_e, tabpage, false);
  					tabbook->addTab (tabpage, tab_e.attribute ("label"));
  				}
***************
*** 254,263 ****
  		if (widget) {
  			parent->addChild (id, widget);
- 			// TODO: deal with (multi-page) wizards
- 			// TODO: parse connections
  		}
  	}
  }
  
  void RKComponentBuilder::addConnection (const QString &client_id, const QString &client_property, const QString &governor_id, const QString &governor_property, bool reconcile, const QDomElement &origin) {
  	RK_TRACE (PLUGIN);
--- 415,428 ----
  		if (widget) {
  			parent->addChild (id, widget);
  		}
  	}
  }
  
+ void RKComponentBuilder::parseLogic (const QDomElement &element) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	// TODO
+ }
+ 
  void RKComponentBuilder::addConnection (const QString &client_id, const QString &client_property, const QString &governor_id, const QString &governor_property, bool reconcile, const QDomElement &origin) {
  	RK_TRACE (PLUGIN);
***************
*** 295,439 ****
  
  
- 
- 
- /////////////////////////////////////// RKStandardComponentGUI ////////////////////////////////////////////////
- 
- RKStandardComponentGUI::RKStandardComponentGUI (RKStandardComponent *component, RKComponentPropertyCode *code_property) {
- 	RK_TRACE (PLUGIN);
- 
- 	RKStandardComponentGUI::component = component;
- 	RKStandardComponentGUI::code_property = code_property;
- 	connect (code_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (codeChanged (RKComponentPropertyBase *)));
- 
- 	QGridLayout *main_grid = new QGridLayout (this, 1, 1);
- 	splitter = new QSplitter (QSplitter::Vertical, this);
- 	main_grid->addWidget (splitter, 0, 0);
- 	QWidget *upper_widget = new QWidget (splitter);
- 	
- 	QHBoxLayout *hbox = new QHBoxLayout (upper_widget, RKGlobals::marginHint (), RKGlobals::spacingHint ());
- 	QVBoxLayout *vbox = new QVBoxLayout (hbox, RKGlobals::spacingHint ());
- 
- 	// build standard elements
- 	main_widget = new QVBox (upper_widget);
- 	hbox->addWidget (main_widget);
- 
- 	// lines
- 	QFrame *line;
- 	line = new QFrame (upper_widget);
- 	line->setFrameShape (QFrame::VLine);
- 	line->setFrameShadow (QFrame::Plain);	
- 	hbox->addWidget (line);
- 
- 	// buttons
- 	vbox = new QVBoxLayout (hbox, RKGlobals::spacingHint ());
- 	ok_button = new QPushButton ("Submit", upper_widget);
- 	connect (ok_button, SIGNAL (clicked ()), this, SLOT (ok ()));
- 	vbox->addWidget (ok_button);
- 	
- 	cancel_button = new QPushButton ("Close", upper_widget);
- 	connect (cancel_button, SIGNAL (clicked ()), this, SLOT (cancel ()));
- 	vbox->addWidget (cancel_button);
- 	vbox->addStretch (1);
- 	
- 	help_button = new QPushButton ("Help", upper_widget);
- 	connect (help_button, SIGNAL (clicked ()), this, SLOT (help ()));
- 	vbox->addWidget (help_button);
- 	
- /*	if (wizard_available) {
- 		switch_button = new QPushButton ("Use Wizard", upper_widget);
- 		connect (switch_button, SIGNAL (clicked ()), this, SLOT (switchInterfaces ()));
- 		vbox->addWidget (switch_button);
- 	} */
- 	vbox->addStretch (2);
- 	
- 	toggle_code_button = new QPushButton ("Code", upper_widget);
- 	toggle_code_button->setToggleButton (true);
- 	toggle_code_button->setOn (true);
- 	connect (toggle_code_button, SIGNAL (clicked ()), this, SLOT (toggleCode ()));
- 	vbox->addWidget (toggle_code_button);
- 	
- 	// code display
- 	code_display = new RKCommandEditor (splitter, true);
- 
- 	// code update timer
- 	code_update_timer = new QTimer (this);
- 	connect (code_update_timer, SIGNAL (timeout ()), this, SLOT (updateCodeNow ()));
- }
- 
- RKStandardComponentGUI::~RKStandardComponentGUI () {
- 	RK_TRACE (PLUGIN);
- }
- 
- void RKStandardComponentGUI::ok () {
- 	RK_TRACE (PLUGIN);
- 
- 	RK_ASSERT (code_property->isValid ());
- 	
- 	RCommandChain *chain = RKGlobals::rInterface ()->startChain ();
- 	RKGlobals::rInterface ()->issueCommand (new RCommand (code_property->preprocess (), RCommand::Plugin | RCommand::DirectToOutput), chain);
- 	RKGlobals::rInterface ()->issueCommand (new RCommand (code_property->calculate (), RCommand::Plugin | RCommand::DirectToOutput), chain);
- 	RKGlobals::rInterface ()->issueCommand (new RCommand (code_property->printout (), RCommand::Plugin | RCommand::DirectToOutput), chain);
- 	RKGlobals::rInterface ()->issueCommand (new RCommand (code_property->cleanup (), RCommand::Plugin | RCommand::DirectToOutput), chain);
- 	RKGlobals::rInterface ()->closeChain (chain);
- }
- 
- void RKStandardComponentGUI::back () {
- 	RK_TRACE (PLUGIN);
- }
- 
- void RKStandardComponentGUI::cancel () {
- 	RK_TRACE (PLUGIN);
- 
- 	hide ();
- 	component->deleteLater ();
- }
- 
- void RKStandardComponentGUI::toggleCode () {
- 	RK_TRACE (PLUGIN);
- 
- 	code_display->setShown (toggle_code_button->isOn ());
- 	updateCode ();
- }
- 
- void RKStandardComponentGUI::help () {
- 	RK_TRACE (PLUGIN);
- }
- 
- void RKStandardComponentGUI::closeEvent (QCloseEvent *e) {
- 	RK_TRACE (PLUGIN);
- 
- 	e->accept ();
- 	cancel ();
- }
- 
- void RKStandardComponentGUI::enableSubmit (bool enable) {
- 	RK_TRACE (PLUGIN);
- 
- 	ok_button->setEnabled (enable);
- }
- 
- void RKStandardComponentGUI::codeChanged (RKComponentPropertyBase *) {
- 	RK_TRACE (PLUGIN);
- 
- 	updateCode ();
- }
- 
- void RKStandardComponentGUI::updateCode () {
- 	RK_TRACE (PLUGIN);
- 
- 	if (!code_display->isShown ()) return;
- 	code_update_timer->start (0, true);
- }
- 
- void RKStandardComponentGUI::updateCodeNow () {
- 	RK_TRACE (PLUGIN);
- 
- 	if (!code_property->isValid ()) {
- 		code_display->setText (i18n ("Processing. Please wait"));
- 		RK_DO (qDebug ("code not ready to be displayed: pre %d, cal %d, pri %d, cle %d", !code_property->preprocess ().isNull (), !code_property->calculate ().isNull (), !code_property->printout ().isNull (), !code_property->cleanup ().isNull ()), PLUGIN, DL_DEBUG);
- 	} else {
- 		code_display->setText (code_property->preprocess () + code_property->calculate () + code_property->printout () + code_property->cleanup ());
- 	}
- }
- 
  #include "rkstandardcomponent.moc"
--- 460,462 ----

Index: rkcomponentproperties.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkcomponentproperties.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** rkcomponentproperties.cpp	19 Mar 2006 16:41:26 -0000	1.15
--- rkcomponentproperties.cpp	20 Mar 2006 00:57:31 -0000	1.16
***************
*** 65,68 ****
--- 65,69 ----
  	RK_TRACE (PLUGIN);
  	RKComponentPropertyBase::required = required;
+ 	is_valid = true;
  }
  
***************
*** 624,627 ****
--- 625,629 ----
  	RKComponentPropertyRObjects::min_length = min_length;
  	RKComponentPropertyRObjects::max_length = max_length;
+ 	validizeAll ();
  }
  
***************
*** 922,927 ****
  	}
  
  	if (changes) {
- 		checkListLengthValid ();
  		if (!silent) emit (valueChanged (this));
  	}
--- 924,929 ----
  	}
  
+ 	checkListLengthValid ();		// we should do this even if there are no changes in the list. There might have still been changes in the filter!
  	if (changes) {
  		if (!silent) emit (valueChanged (this));
  	}

--- NEW FILE: rkstandardcomponentgui.h ---
/***************************************************************************
                          rkstandardcomponentgui  -  description
                             -------------------
    begin                : Sun Mar 19 2006
    copyright            : (C) 2006 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 RKSTANDARDCOMPONENTGUI_H
#define RKSTANDARDCOMPONENTGUI_H

#include <qwidgetstack.h>

#include "rkstandardcomponent.h"

/** For use in RKStandardComponents that are in wizard mode. Keeps a list of all pages, which page we're currently on, which children need to be satisfied in order to be able to move to the next page, etc.

@author Thomas Friedrichsmeier */
class RKStandardComponentStack: public QWidgetStack {
public:
/** constructor. */
	RKStandardComponentStack (QWidget *parent);
	~RKStandardComponentStack ();
/** see RKStandardComponent::havePage () */
	bool havePage (bool next);
/** see RKStandardComponent::movePage () */
	void movePage (bool next);
/** see RKStandardComponent::currentPageSatisfied () */
	bool currentPageSatisfied ();
/** go to the first page (call after creation) */
	void goToFirstPage ();

/** for use during construction. Adds a new page. Subsequent calls to addComponentToCurrentPage work on the new page. Even the first page has to be added explicitely!
@param parent The RKComponent acting as parent for the newly created page */
	RKComponent *addPage (RKComponent *parent);

	void addComponentToCurrentPage (RKComponent *component);
private:
/** pages are NOT the parent of their components (that would be theoretically possible, but a terrible mess, requiring a fully transparent type of RKComponent), hence we keep a manual list for each page */
	typedef QValueList<RKComponent *> PageComponents;
	struct PageDef {
		PageComponents page_components;
		RKComponent *page;
	};
	typedef QValueList<PageDef *> Pages;
	Pages pages;

	int num_pages;
	int current_page;
	PageDef *current_def;		// to save a few lookups

	int previousVisiblePage ();
	int nextVisiblePage ();
};

#include <qwidget.h>

class RKCommandEditor;
class QPushButton;
class QTimer;
class QSplitter;

/** contains the standard GUI elements for a top-level RKStandardComponent. The base class creates a dialog interface. For a wizard interface use RKStandardComponentWizard. You *must* call createDialog () after construction, since I can't virualize this for reasons I don't understand!

@author Thomas Friedrichsmeier */
class RKStandardComponentGUI : public QWidget {
	Q_OBJECT
public:
	RKStandardComponentGUI (RKStandardComponent *component, RKComponentPropertyCode *code_property);
	~RKStandardComponentGUI ();

	QWidget *mainWidget () { return main_widget; };

	void createDialog (bool switchable);
	virtual void enableSubmit (bool enable);
	virtual void updateCode ();
public slots:
	void ok ();
	void cancel ();
	void toggleCode ();
	void help ();
	void codeChanged (RKComponentPropertyBase *);
	void updateCodeNow ();
	void switchInterface () { component->switchInterface (); };
private:
	RKComponentPropertyCode *code_property;

	// widgets for dialog only
	QPushButton *toggle_code_button;
	QSplitter *splitter;
	QPushButton *ok_button;
protected:
	void closeEvent (QCloseEvent *e);
	RKStandardComponent *component;
	QTimer *code_update_timer;

	// common widgets
	QWidget *main_widget;
	QPushButton *cancel_button;
	QPushButton *help_button;
	QPushButton *switch_button;
	RKCommandEditor *code_display;
};

/** A wizardish RKStandardComponentGUI. You *must* call createDialog () after construction, and addLastPage () filling the wizard!

@author Thomas Friedrichsmeier */
class RKStandardComponentWizard : public RKStandardComponentGUI {
	Q_OBJECT
public:
	RKStandardComponentWizard (RKStandardComponent *component, RKComponentPropertyCode *code_property);
	~RKStandardComponentWizard ();

	void enableSubmit (bool enable);
	void updateCode ();
	void createWizard (bool switchable);
/** Add a standard last page in the wizard. To confuse everybody, this also initializes the view to the first page */
	void addLastPage ();

	void updateState ();

	RKStandardComponentStack *getStack () { return stack; };
public slots:
	void next ();
	void prev ();
private:
	QPushButton *next_button;
	QPushButton *prev_button;
	bool submit_enabled;
	bool is_switchable;
	RKStandardComponentStack *stack;
};

#endif

Index: rkcomponent.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkcomponent.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** rkcomponent.cpp	19 Mar 2006 16:41:26 -0000	1.9
--- rkcomponent.cpp	20 Mar 2006 00:57:31 -0000	1.10
***************
*** 40,44 ****
  	RK_TRACE (PLUGIN);
  
! 	child_map.insert (id, child);
  }
  
--- 40,44 ----
  	RK_TRACE (PLUGIN);
  
! 	child_map.insert (id, child);		// no overwriting even on duplicate ("#noid#") ids, als this is really a QDict, not a QMap
  }
  
***************
*** 71,82 ****
  	RK_TRACE (PLUGIN);
  
  	addChild ("enabled", enabledness_property = new RKComponentPropertyBool (this, false));
  	connect (enabledness_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
  	addChild ("visible", visibility_property = new RKComponentPropertyBool (this, false));
  	connect (visibility_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
  	addChild ("required", requiredness_property = new RKComponentPropertyBool (this, false));
  	connect (requiredness_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
- 
- 	_parent = parent_component;
  }
  
--- 71,91 ----
  	RK_TRACE (PLUGIN);
  
+ 	createDefaultProperties ();
+ 
+ 	_parent = parent_component;
+ }
+ 
+ void RKComponent::createDefaultProperties () {
+ 	RK_TRACE (PLUGIN);
+ 
  	addChild ("enabled", enabledness_property = new RKComponentPropertyBool (this, false));
+ 	enabledness_property->setBoolValue (true);
  	connect (enabledness_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
  	addChild ("visible", visibility_property = new RKComponentPropertyBool (this, false));
+ 	visibility_property->setBoolValue (true);
  	connect (visibility_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
  	addChild ("required", requiredness_property = new RKComponentPropertyBool (this, false));
+ 	requiredness_property->setBoolValue (true);
  	connect (requiredness_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
  }
  
***************
*** 108,115 ****
  }
  
! void RKComponent::setReady (bool ready) {
  	RK_TRACE (PLUGIN);
  
! 	// TODO
  }
  
--- 117,136 ----
  }
  
! bool RKComponent::isWizardish () {
  	RK_TRACE (PLUGIN);
  
! 	return false;
! }
! 
! bool RKComponent::havePage (bool) {
! 	RK_TRACE (PLUGIN);
! 	RK_ASSERT (false);		// should not be called as isWizardish returns false
! 
! 	return false;
! }
! 
! void RKComponent::movePage (bool) {
! 	RK_TRACE (PLUGIN);
! 	RK_ASSERT (false);		// should not be called as isWizardish returns false
  }
  





More information about the rkward-tracker mailing list