RiverWare Qt4 Port Completion  >>  RiverWare / Qt3 Compatibility Widget Porting Guide
RiverWare / Porting Q3ListView to Qt4 QTreeWidget
January 20, 2010 -- Phil

Use of RwQListView (a Qt4 QTreeWidget)

This general class provides fairly comprehensive support for porting "flat" Q3ListViews. Additional capabilities to support multiple-level tree views can be added, when we port other those, e.g. the Open Object Dialog's multiple-level slot list. This section describes the changes needed to port Q3ListViews in RiverWare (both direct instances and subclasses) to RwQListView.

----------------

Typical Header File Changes

Includes (in header file)

OLD: 
  #include <Q3ListView>

NEW:
  #include <QTreeWidgetItem>
  class RwQListView;

General:

OLD:
  Q3ListViewItem*

NEW:
  QTreeWidgetItem*

Item Sublcasses:


OLD:
  class MyListViewItem : public Q3ListViewItem

  // virtual from Q3ListViewItem
  int compare (Q3ListViewItem*, int col, bool ascending) const;


New: 
  class MyListViewItem : public QTreeWidgetItem

  // virtual from QTreeWidgetItem
  virtual bool operator< (const QTreeWidgetItem&) const;
  // NOTICE that the parameter is a reference rather than a pointer.

Qt Slot: Item Selection Changed: (no code change)


OLD:
   void myListView_selChanged();

NEW:
   void myListView_selChanged();


Qt Slot: Double Click on Item:


OLD:
   void myListView_doubleClicked (Q3ListViewItem*, const QPoint&, int);

NEW:
   void myListView_doubleClicked (QTreeWidgetItem*, int);

Qt Slot: Context Menu Requested:


OLD:
   void myListView_contextMenuRequested (Q3ListViewItem*, 
                                               const QPoint&, int col);

   // for signal generated from RwQListView
   void myListView_contextMenuRequested (QTreeWidgetItem*, int col,
                                               const QPoint&);


Typical CPP File Changes

Includes (in CPP file):


OLD:
  #ifndef RwQt3UtilsINCLUDED
  #include "RwQt3Utils.hpp"
  #endif

  #include <Q3ListView>
  #include <Q3Header>

NEW:
  #ifndef RwQListViewINCLUDED
  #include "RwQListView.hpp"
  #endif

  #ifndef RwQt4UtilsINCLUDED
  #include "RwQt4Utils.hpp"
  #endif

  #include <QHeaderView>

Instantiating a list (example):


OLD:
   _myListView = new Q3ListView (_myPanel, "_myListView");
   _myListView->setShowSortIndicator (TRUE);
   _myListView->setSelectionMode (Q3ListView::Extended);
   _myListView->setAllColumnsShowFocus (true);

   _myListView->addColumn (tr ("Col0"));
   _myListView->addColumn (tr ("Col1"));
   _myListView->addColumn (tr ("Col2"));

   ...
   _myListView->header()->setLabel (0, tr ("Group "));
   _myListView->header()->setLabel (1, tr ("TimeStep "));
   _myListView->header()->setLabel (2, tr ("Annotation Text "));

NEW:
   _myListView = new RwQListView (this, _myPanel, "_myListView");
   _myListView->setSelectionMode (QAbstractItemView::ExtendedSelection);
   _myListView->setAllColumnsShowFocus (true);

   _myListView->setColumnCount (3);
   ...

   _myListView->headerItem()->setText (0, tr ("Group "));
   _myListView->headerItem()->setText (1, tr ("TimeStep "));
   _myListView->headerItem()->setText (2, tr ("Annotation Text "));

   QHeaderView* hdr = _myListView->header();
   hdr->setResizeMode (0, QHeaderView::ResizeToContents);
   hdr->setResizeMode (1, QHeaderView::ResizeToContents);
   hdr->setResizeMode (2, QHeaderView::ResizeToContents);

Connecting Signals:


OLD:
   connect (_myListView, SIGNAL (selectionChanged()),
            this, SLOT (myListView_selChanged()));

   connect (_myListView, 
      SIGNAL (doubleClicked (Q3ListViewItem*, const QPoint&, int)), this, 
      SLOT (myListView_doubleClicked (Q3ListViewItem*, const QPoint&, int)));

   connect (_myListView, 
      SIGNAL (contextMenuRequested (Q3ListViewItem*, const QPoint&, int)),
      SLOT (myListView_contextMenuRequested (Q3ListViewItem*, 
                                             const QPoint&, int)));

NEW:
   connect (_myListView, SIGNAL (itemSelectionChanged()),
            this, SLOT (myListView_selChanged()));

   connect (_myListView, 
      SIGNAL (itemDoubleClicked (QTreeWidgetItem*, int)), this, 
      SLOT (myListView_doubleClicked (QTreeWidgetItem*, int)));

   connect (_myListView, 
      SIGNAL (itemContextMenuRequested (QTreeWidgetItem*, int, const QPoint&)),
      SLOT (myListView_contextMenuRequested (QTreeWidgetItem*, int,  
                                             const QPoint&)));

Setting item icon (e.g. in column 0):


OLD:
  setPixmap (0, myQPixmap);

NEW:
  setIcon (0, myQPixmap);

Item Comparison Operator (for sorting):


OLD:
   int MyModule::MyListViewItem::compare (
         Q3ListViewItem* lvItem, int col, bool ascending) const
   {
      // Note: ignore the 'ascending' parameter. The QListView does the
      // sort order reversal itself.

      ...

      // default comparison from base class
      return (Q3ListViewItem::compare (lvItem, col, ascending));
   }

NEW:
   bool MyModule::MyListViewItem::operator< (
                                         const QTreeWidgetItem& lvItem) const
   {
      const int col = (treeWidget() ? treeWidget()->sortColumn() : 0);

      ...

      // Note-1: For the custom comparison cases, make sure to return the 
      // "less than" function value (boolean) rather than a (-1,0,1) 
      // comparison int.

      // Note-2: Since the column index is no longer a parameter index,
      // in order to defer to a different column (in the case of equality 
      // of the two items within the current sort column), the comparison 
      // result using the deferred column has to be directly computed 
      // within this implementation rather than deferred to another 
      // invokation of this operator method.
      ...

      // default comparison from base class
      return (QTreeWidgetItem::operator< (lvItem));
   }


Setting a Slot Type Icon, e.g. in column 1


OLD:
   // column 1: Slot Type Icon
   RwQt3Utils::setQListViewItemIconForSlot (this, 1, slot);

NEW:
   // column 1: Slot Type Icon
   RwQt4Utils::setItemIconForSlot (this, 1, slot);

Responding to a deletion notification of data underlying a single item (in the item's implementation).


OLD:
   if (doDelete)
   {
      deleteSlotCallback();

      Q3ListView* lview = listView();
      if (lview)
      {
         lview->takeItem (this);
      }

      // SELF DELETION!
      delete this;
   }

NEW:
   if (doDelete)
   {
      deleteSlotCallback();

      QTreeWidget* tw = treeWidget();
      if (tw)
      {
         const int inx = tw->indexOfTopLevelItem (this);
         if (inx >= 0)
            tw->takeTopLevelItem (inx);
      }

      // SELF DELETION!
      delete this;
   }

Forcing the (or a) selected item to be within the visible window:


OLD:
   // Insure that the selected item is visible (if any).
   RwQt3Utils::ensureFirstSelectedItemInVisibleArea (_myListView);

NEW:
   // Insure that the selected item is visible (if any).
   RwQt4Utils::ensureFirstSelectedItemIsVisible (_myListView);

Getting the single selected item (NULL if there are more than one):


OLD:
   Q3ListViewItem* oneSelItem = 
      RwQt3Utils::singleSelectedItem (_myListView);

NEW:
   QTreeWidgetItem* oneSelItem = 
      RwQt4Utils::singleSelectedItem (_myListView);

Getting the selected item count:


OLD:
  int numSelItems (RwQt3Utils::selectedItemCount (_myListView));

NEW:
  int numSelItems (RwQt4Utils::selectedItemCount (_myListView));

After Adding Items to the list:

There is no longer a need to fit contents, but one can. However, to allow 
icons to be shown in their natural size (and not be made smaller), a call 
to RwQListView::updateIconSize() is needed.

OLD:
   // Grow column to at least fit Column headers
   RwQt3Utils::fitQListViewColsToHeaders (_myListView, true); // growOnly

NEW:
   // Set the RwQListView's QTreeWidget icon size to that of the largest icon
   _myListView->updateIconSize();

Iterating over the selected items of a list.


OLD:
   Q3ListViewItemIterator iter (_myListView,
                               Q3ListViewItemIterator::Selected);

   for (; iter.current(); ++iter)
   {
      Q3ListViewItem* lvItem = iter.current();
      ...
   }

NEW:
   QTreeWidgetItemIterator iter (_myListView,
                                 QTreeWidgetItemIterator::Selected);

   for (; *iter; ++iter)
   {
      QTreeWidgetItem* lvItem (*iter);
      ...
   }

Iterating over all items in the list:


OLD:
   Q3ListViewItemIterator iter (_myListView);
   for (; iter.current(); ++iter)
   {
      Q3ListViewItem* lvItem = iter.current();
      ...
   }

NEW:
   QTreeWidgetItemIterator iter (_myListView);
   for (; *iter; ++iter)
   {
      QTreeWidgetItem* lvItem (*iter);
      ...
   }


Selecting an item:


OLD:
   _myListView->setSelected (lvItem, true);
   RwQt3Utils::ensureItemInVisibleArea (_myListView, lvItem);

NEW:
   lvItem->setSelected (true);
   RwQt4Utils::ensureItemIsVisible (_myListView, lvItem);

--- (end) ---