All, Here is a brief synopsis of the changes I logged into the tree last Sunday night. It is highly desirable that we specify a generic interface to be implemented by all different view types. This will allow the application (WcurveApp class) and document (WcurveDoc class) to treat all views as the generic type and be unconcerned with the particular details of each one. This will also allow us to add new view types into the system with very little churn to exsisting code...and given the exploratory nature of this project it is likely that such additions will be required. In Java it would be extremely easy, we could just declare an abstract interface, and declare that all view types implement it. As it stands however we are using C++ and need to use some kind of multiple inheritance in order to allow us to subclass existing QT widgets and also specify our own personal interface. Currently there are two concrete view types, PlotView and SequenceView. PlotView derives from QGLWidget and SequenceView derives from QTextView. QGLWidget and QTextView each in turn derive from QWidget. You have an inheritance hierarchy similar to this: QWidget /\ /\ / \ / \ QGLWidget QTextView /|\ /|\ | | PlotView SequenceView It would appear that at first glance we can use QWidget as our generic interface, and indeed there are several QWidget operations that the application needs access to (show(), setFocus(), isActiveWindow()..etc). The problem however is that in order to implement the Observer pattern and other functionality such as printing there are other operations that the generic interface needs to implement. Ideally we would setup the following architecture: QWidget /\ /|\ /\ -------/ | \----------- | | | | WcurveView | QGLWidget /\ /\ QTextView /|\ -----/ \------ /|\ | | | | PlotView SequenceView Each concrete type derives from its widget and the WcurveView interface. We could access each type through its WcurveView interface and still have access to the QWidget operations we need. The problem with this however is that if you do not specify the inheritance as virtual, C++ constructs 2 Qwidget objects everytime a concrete view is created, one for WcurveView, and one for the QT widget we derive from (QGLWidget or QTextView). The QWidget that is constructed for the WcurveView has no useful feature (Its a grey box) but that is the one we would have access to. TrollTech hasn't declared the inheritance in any of its specialized QT Widgets as virtual so this isn't an option....what we are left with is the following heirarchy: QWidget /\ /\ -------/ \----------- | | | WcurveView | QGLWidget /\ /\ QTextView /|\ -----/ \------ /|\ | | | | PlotView SequenceView There are now two issues left to solve: 1. How do we access the QWidget operations we need through the WcurveView interface? 2.How do we take the Qwidget objects that the windowActivated() and other similar signals produce and cast them to WcurveViews. This is the final solution I arrived at...and if you can think of an improvement, let me know...cause this still has kind of a funky smell to it. Issue 1 solution Declare all of the QWidget operations we need as pure virtual operations in WcurveView.h and then implement them in the Concrete types as calls to the corresponding operations in the QT Widget superclasses: class WcurveView{ . . . virtual void setCaption(QString) = 0; virtual bool isActiveWindow() = 0; virtual bool close() = 0; virtual void showMaximized() = 0; virtual void setFocus() = 0; virtual void show() = 0; virtual void installEventFilter ( const QObject * obj ) = 0; . . . } class PlotView :public QGLWidget, public WcurveView { . . . void setCaption(QString str){QGLWidget::setCaption(str);} bool isActiveWindow(){return QGLWidget::isActiveWindow();} bool close(){return QGLWidget::close();} void showMaximized(){QGLWidget::showMaximized();} void setFocus(){QGLWidget::setFocus();} void show(){QGLWidget::show();} void installEventFilter ( const QObject * obj) {QGLWidget::installEventFilter(obj);} . . . } Issue 2 Solution Implement a method resolveViewType() in WcurveApp that can take a Qwidget, downcast it to the proper concrete type and then cast it back to a WcurveView: /** changes all control settings to newly selected view */ void WcurveApp::slotUpdateControls(QWidget *w){ //do nothing if the window that gained focus isn't a good view WcurveView *view = resolveViewType(w); if(!view) return; //update the controls using *view . . . . } /** takes a Qwidget and performs the necessary hocus-pocus to turn it into a WcurveView */ WcurveView* WcurveApp::resolveViewType(QWidget *view){ if(PlotView *plot = dynamic_cast<PlotView*>(view)) return (WcurveView *) plot; else if(SequenceView *seq = dynamic_cast<SequenceView*>(view)) return (WcurveView *) seq; else return NULL; } Whew.....! Well that is it in a nutshell. I still need to abstract out the fileview code into its own class for us to truly minimize churn when adding a new view. I'm doing that next. Once that is done I am going to add the ChaosView type...and will record the LOC affected. The metric will hopefully be miniscule and I will annouce it here. L8r, Joe Ruscio