Logo Search packages:      
Sourcecode: scidavis version File versions  Download package

TableView.cpp

/***************************************************************************
    File                 : TableView.cpp
    Project              : SciDAVis
    Description          : View class for Table
    --------------------------------------------------------------------
    Copyright            : (C) 2007 Tilman Benkert (thzs*gmx.net)
                           (replace * with @ in the email addresses) 

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *  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.                                    *
 *                                                                         *
 *  This program is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
 *  GNU General Public License for more details.                           *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the Free Software           *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
 *   Boston, MA  02110-1301  USA                                           *
 *                                                                         *
 ***************************************************************************/

#include "table/future_Table.h"
#include "table/TableView.h"
#include "table/TableModel.h"
#include "table/TableItemDelegate.h"
#include "table/tablecommands.h"
#include "table/TableDoubleHeaderView.h"

#include "core/column/Column.h"
#include "core/AbstractFilter.h"
#include "core/datatypes/SimpleCopyThroughFilter.h"
#include "core/datatypes/Double2StringFilter.h"
#include "core/datatypes/String2DoubleFilter.h"
#include "core/datatypes/DateTime2StringFilter.h"
#include "core/datatypes/String2DateTimeFilter.h"

#include <QKeyEvent>
#include <QtDebug>
#include <QHeaderView>
#include <QRect>
#include <QPoint>
#include <QSize>
#include <QFontMetrics>
#include <QFont>
#include <QItemSelectionModel>
#include <QItemSelection>
#include <QShortcut>
#include <QModelIndex>
#include <QGridLayout>
#include <QScrollArea>
#include <QMenu>

#ifndef LEGACY_CODE_0_2_x
00062 TableView::TableView(future::Table *table)
 : d_table(table) 
#else
TableView::TableView(const QString& label, QWidget* parent, const char* name, Qt::WFlags f)
 : MyWidget(label, parent, name, f)
#endif
{
#ifndef LEGACY_CODE_0_2_x
      d_model = new TableModel(table);
      init();
#else
      d_model = NULL;
#endif
}

00077 TableView::~TableView() 
{
      delete d_model;
}

void TableView::setTable(future::Table * table)
{
      d_table = table;
      d_model = new TableModel(table);
      init();
}

00089 void TableView::init()
{
      d_main_layout = new QHBoxLayout(this);
      d_main_layout->setSpacing(0);
      d_main_layout->setContentsMargins(0, 0, 0, 0);
      
      d_view_widget = new TableViewWidget(this);
      d_view_widget->setModel(d_model);
      connect(d_view_widget, SIGNAL(advanceCell()), this, SLOT(advanceCell()));
      d_main_layout->addWidget(d_view_widget);
      
      d_horizontal_header = new TableDoubleHeaderView();
    d_horizontal_header->setClickable(true);
    d_horizontal_header->setHighlightSections(true);
      d_view_widget->setHorizontalHeader(d_horizontal_header);

      d_hide_button = new QToolButton();
      d_hide_button->setArrowType(Qt::RightArrow);
      d_hide_button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));
      d_hide_button->setCheckable(false);
      d_main_layout->addWidget(d_hide_button);
      connect(d_hide_button, SIGNAL(pressed()), this, SLOT(toggleControlTabBar()));
      d_control_tabs = new QWidget();
    ui.setupUi(d_control_tabs);
      d_main_layout->addWidget(d_control_tabs);

      d_delegate = new TableItemDelegate(d_view_widget);
      d_view_widget->setItemDelegate(d_delegate);
      
      d_view_widget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
      d_main_layout->setStretchFactor(d_view_widget, 1);

      setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));

      d_view_widget->setFocusPolicy(Qt::StrongFocus);
      setFocusPolicy(Qt::StrongFocus);
      setFocus();
#if QT_VERSION >= 0x040300
      d_view_widget->setCornerButtonEnabled(true);
#endif

      d_view_widget->setSelectionMode(QAbstractItemView::ExtendedSelection);

      QHeaderView * v_header = d_view_widget->verticalHeader();
      // Remark: ResizeToContents works in Qt 4.2.3 but is broken in 4.3.0
      // Should be fixed in 4.3.1 though, see:
      // http://trolltech.com/developer/task-tracker/index_html?method=entry&id=165567
      v_header->setResizeMode(QHeaderView::ResizeToContents);
      v_header->setMovable(false);
      d_horizontal_header->setResizeMode(QHeaderView::Interactive);
      d_horizontal_header->setMovable(true);
      connect(d_horizontal_header, SIGNAL(sectionMoved(int,int,int)), this, SLOT(handleHorizontalSectionMoved(int,int,int)));
      connect(d_horizontal_header, SIGNAL(sectionDoubleClicked(int)), this, SLOT(handleHorizontalHeaderDoubleClicked(int)));
      
      d_horizontal_header->setDefaultSectionSize(future::Table::defaultColumnWidth());

      v_header->installEventFilter(this);
      d_horizontal_header->installEventFilter(this);
      d_view_widget->installEventFilter(this);

      connect(d_model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), d_view_widget, 
            SLOT(updateHeaderGeometry(Qt::Orientation,int,int)) ); 
      connect(d_model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), this, 
            SLOT(handleHeaderDataChanged(Qt::Orientation,int,int)) ); 
      connect(d_table, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)),
                  this, SLOT(handleAspectDescriptionChanged(const AbstractAspect*)));
      connect(d_table, SIGNAL(aspectAdded(const AbstractAspect*)),
                  this, SLOT(handleAspectAdded(const AbstractAspect*)));
      connect(d_table, SIGNAL(aspectAboutToBeRemoved(const AbstractAspect*,int)),
                  this, SLOT(handleAspectAboutToBeRemoved(const AbstractAspect*,int)));

      rereadSectionSizes();
      
      // keyboard shortcuts
      QShortcut * sel_all = new QShortcut(QKeySequence(tr("Ctrl+A", "Table: select all")), d_view_widget);
      connect(sel_all, SIGNAL(activated()), d_view_widget, SLOT(selectAll()));

      connect(ui.type_box, SIGNAL(currentIndexChanged(int)), this, SLOT(updateFormatBox()));
      connect(ui.format_box, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTypeInfo()));
      connect(ui.digits_box, SIGNAL(valueChanged(int)), this, SLOT(updateTypeInfo()));
      connect(ui.previous_column_button, SIGNAL(clicked()), this, SLOT(goToPreviousColumn()));
      connect(ui.next_column_button, SIGNAL(clicked()), this, SLOT(goToNextColumn()));
      retranslateStrings();

      QItemSelectionModel * sel_model = d_view_widget->selectionModel();

      connect(sel_model, SIGNAL(currentColumnChanged(const QModelIndex&, const QModelIndex&)), 
            this, SLOT(currentColumnChanged(const QModelIndex&, const QModelIndex&)));
      connect(sel_model, SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
            this, SLOT(selectionChanged(const QItemSelection&,const QItemSelection&)));
      connect(ui.button_set_description, SIGNAL(pressed()), 
            this, SLOT(applyDescription()));
      connect(ui.button_set_type, SIGNAL(pressed()),
            this, SLOT(applyType()));
}

void TableView::rereadSectionSizes()
{
      disconnect(d_horizontal_header, SIGNAL(sectionResized(int, int, int)), this, SLOT(handleHorizontalSectionResized(int, int, int)));

      int cols = d_table->columnCount();
      for (int i=0; i<cols; i++)
            d_horizontal_header->resizeSection(i, d_table->columnWidth(i));
            
      connect(d_horizontal_header, SIGNAL(sectionResized(int, int, int)), this, SLOT(handleHorizontalSectionResized(int, int, int)));
}

void TableView::setColumnWidth(int col, int width) 
{ 
      d_horizontal_header->resizeSection(col, width);
}

int TableView::columnWidth(int col) const 
{ 
      return d_horizontal_header->sectionSize(col);
}

void TableView::handleHorizontalSectionResized(int logicalIndex, int oldSize, int newSize)
{
      static bool inside = false;
      d_table->setColumnWidth(logicalIndex, newSize);
      if (inside) return;
      inside = true;

      int cols = d_table->columnCount();
      for (int i=0; i<cols; i++)
            if(isColumnSelected(i, true)) 
                  d_horizontal_header->resizeSection(i, newSize);

      inside = false;
}

00221 void TableView::changeEvent(QEvent * event)
{
      if (event->type() == QEvent::LanguageChange) 
            retranslateStrings();
      MyWidget::changeEvent(event); 
}

void TableView::retranslateStrings()
{
      d_hide_button->setToolTip(tr("Show/hide control tabs"));
    ui.retranslateUi(d_control_tabs);

      ui.type_box->clear();
      ui.type_box->addItem(tr("Numeric"), QVariant(int(SciDAVis::Numeric)));
      ui.type_box->addItem(tr("Text"), QVariant(int(SciDAVis::Text)));
      ui.type_box->addItem(tr("Month names"), QVariant(int(SciDAVis::Month)));
      ui.type_box->addItem(tr("Day names"), QVariant(int(SciDAVis::Day)));
      ui.type_box->addItem(tr("Date and time"), QVariant(int(SciDAVis::DateTime)));

      ui.type_box->setCurrentIndex(0);

      // TODO: implement formula stuff
      //ui.formula_info->document()->setPlainText("not implemented yet");
}
      
00246 void TableView::advanceCell()
{
      QModelIndex idx = d_view_widget->currentIndex();
    if(idx.row()+1 >= d_table->rowCount())
      {
            int new_size = d_table->rowCount()+1;
            d_table->setRowCount(new_size);
      }
      d_view_widget->setCurrentIndex(idx.sibling(idx.row()+1, idx.column()));
}

void TableView::goToCell(int row, int col)
{
      QModelIndex index = d_model->index(row, col);
      d_view_widget->scrollTo(index);
      d_view_widget->setCurrentIndex(index);
}

void TableView::selectAll()
{
      d_view_widget->selectAll();
}

void TableView::deselectAll()
{
      d_view_widget->clearSelection();
}

void TableView::toggleControlTabBar() 
{ 
      d_control_tabs->setVisible(!d_control_tabs->isVisible());
      if(d_control_tabs->isVisible())
            d_hide_button->setArrowType(Qt::RightArrow);
      else
            d_hide_button->setArrowType(Qt::LeftArrow);
}

void TableView::handleHorizontalSectionMoved(int index, int from, int to)
{
      static bool inside = false;
      if(inside) return;

      Q_ASSERT(index == from);

      inside = true;
      d_view_widget->horizontalHeader()->moveSection(to, from);
      inside = false;
      d_table->moveColumn(from, to);
}

void TableView::handleHorizontalHeaderDoubleClicked(int index)
{
      Q_UNUSED(index);
      showControlDescriptionTab();
}

00302 bool TableView::areCommentsShown() const
{
      return d_horizontal_header->areCommentsShown();
}

void TableView::toggleComments()
{
      showComments(!areCommentsShown());
}

00312 void TableView::showComments(bool on)
{
      d_horizontal_header->showComments(on);
      update();
}

void TableView::currentColumnChanged(const QModelIndex & current, const QModelIndex & previous)
{
      Q_UNUSED(previous);
      int col = current.column();   
      if(col < 0 || col >= d_table->columnCount()) return;
      setColumnForControlTabs(col);
}

void TableView::setColumnForControlTabs(int col)
{
      if(col < 0 || col >= d_table->columnCount()) return;
      Column *col_ptr = d_table->column(col);

      QString str = tr("Current column:\nName: %1\nPosition: %2")\
            .arg(col_ptr->name()).arg(col+1);
            
      ui.name_edit->setText(col_ptr->name());
      ui.comment_box->document()->setPlainText(col_ptr->comment());
      ui.type_box->setCurrentIndex(ui.type_box->findData((int)col_ptr->columnMode()));
      switch(col_ptr->columnMode()) {
            case SciDAVis::Numeric:
                  {
                        Double2StringFilter * filter = static_cast<Double2StringFilter*>(col_ptr->outputFilter());
                        ui.format_box->setCurrentIndex(ui.format_box->findData(filter->numericFormat()));
                        ui.digits_box->setValue(filter->numDigits());
                        break;
                  }
            case SciDAVis::Month:
            case SciDAVis::Day:
            case SciDAVis::DateTime:
                  {
                        DateTime2StringFilter * filter = static_cast<DateTime2StringFilter*>(col_ptr->outputFilter());
                        ui.format_box->setCurrentIndex(ui.format_box->findData(filter->format()));
                        break;
                  }
            default:
                  break;
      }
      ui.formula_box->setText(col_ptr->formula(0));
}

void TableView::handleAspectDescriptionChanged(const AbstractAspect * aspect)
{
      const Column * col = qobject_cast<const Column*>(aspect);
      if (!col || col->parentAspect() != static_cast<AbstractAspect*>(d_table))
            return;
      ui.add_reference_combobox->setItemText(d_table->columnIndex(col), "col(\"" + col->name() + "\")");
}

void TableView::handleAspectAdded(const AbstractAspect *aspect) {
      const Column * col = qobject_cast<const Column*>(aspect);
      if (!col || col->parentAspect() != static_cast<AbstractAspect*>(d_table))
            return;
      ui.add_reference_combobox->insertItem(d_table->indexOfChild(aspect), "col(\"" + col->name() + "\")");
}

void TableView::handleAspectAboutToBeRemoved(const AbstractAspect *parent, int index) {
      if (parent != d_table)
            return;
      ui.add_reference_combobox->removeItem(index);
}

void TableView::selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
{
      Q_UNUSED(selected);
      Q_UNUSED(deselected);
}

void TableView::updateFormatBox()
{
      int type_index = ui.type_box->currentIndex();
      if(type_index < 0) return; // should never happen
      ui.format_box->clear();
      ui.digits_box->setEnabled(false);
      switch(ui.type_box->itemData(type_index).toInt())
      {
            case SciDAVis::Numeric:
                  ui.digits_box->setEnabled(true);
                  ui.format_box->addItem(tr("Decimal"), QVariant('f'));
                  ui.format_box->addItem(tr("Scientific (e)"), QVariant('e'));
                  ui.format_box->addItem(tr("Scientific (E)"), QVariant('E'));
                  ui.format_box->addItem(tr("Automatic (e)"), QVariant('g'));
                  ui.format_box->addItem(tr("Automatic (E)"), QVariant('G'));
                  break;
            case SciDAVis::Text:
                  ui.format_box->addItem(tr("Text"), QVariant());
                  break;
            case SciDAVis::Month:
                  ui.format_box->addItem(tr("Number without leading zero"), QVariant("M"));
                  ui.format_box->addItem(tr("Number with leading zero"), QVariant("MM"));
                  ui.format_box->addItem(tr("Abbreviated month name"), QVariant("MMM"));
                  ui.format_box->addItem(tr("Full month name"), QVariant("MMMM"));
                  break;
            case SciDAVis::Day:
                  ui.format_box->addItem(tr("Number without leading zero"), QVariant("d"));
                  ui.format_box->addItem(tr("Number with leading zero"), QVariant("dd"));
                  ui.format_box->addItem(tr("Abbreviated day name"), QVariant("ddd"));
                  ui.format_box->addItem(tr("Full day name"), QVariant("dddd"));
                  break;
            case SciDAVis::DateTime:
                  {
                        // TODO: allow adding of the combo box entries here
                        const char * date_strings[] = {
                              "yyyy-MM-dd",     
                              "yyyy/MM/dd", 
                              "dd/MM/yyyy", 
                              "dd/MM/yy", 
                              "dd.MM.yyyy",     
                              "dd.MM.yy",
                              "MM/yyyy",
                              "dd.MM.", 
                              "yyyyMMdd",
                              0
                        };

                        const char * time_strings[] = {
                              "hh",
                              "hh ap",
                              "hh:mm",
                              "hh:mm ap",
                              "hh:mm:ss",
                              "hh:mm:ss.zzz",
                              "hh:mm:ss:zzz",
                              "mm:ss.zzz",
                              "hhmmss",
                              0
                        };
                        int j,i;
                        for(i=0; date_strings[i] != 0; i++)
                              ui.format_box->addItem(QString(date_strings[i]), QVariant(date_strings[i]));
                        for(j=0; time_strings[j] != 0; j++)
                              ui.format_box->addItem(QString(time_strings[j]), QVariant(time_strings[j]));
                        for(i=0; date_strings[i] != 0; i++)
                              for(j=0; time_strings[j] != 0; j++)
                                    ui.format_box->addItem(QString("%1 %2").arg(date_strings[i]).arg(time_strings[j]), 
                                          QVariant(QString(date_strings[i]) + " " + QString(time_strings[j])));
                        break;
                  }
            default:
                  ui.format_box->addItem(QString()); // just for savety to have at least one item in any case
      }
      ui.format_box->setCurrentIndex(0);
}

void TableView::updateTypeInfo()
{
      int format_index = ui.format_box->currentIndex();
      int type_index = ui.type_box->currentIndex();

      QString str = tr("Selected column type:\n");
      if(format_index >= 0 && type_index >= 0)
      {
            int type = ui.type_box->itemData(type_index).toInt();
            switch(type)
            {
                  case SciDAVis::Numeric:
                        str += tr("Double precision\nfloating point values\n");
                        ui.digits_box->setEnabled(true);
                        break;
                  case SciDAVis::Text:
                        str += tr("Text\n");
                        break;
                  case SciDAVis::Month:
                        str += tr("Month names\n");
                        break;
                  case SciDAVis::Day:
                        str += tr("Days of the week\n");
                        break;
                  case SciDAVis::DateTime:
                        str += tr("Dates and/or times\n");
                        break;
            }
            str += tr("Example: ");
            switch(type)
            {
                  case SciDAVis::Numeric:
                        str += QString::number(123.1234567890123456, ui.format_box->itemData(format_index).toChar().toLatin1(), ui.digits_box->value());
                        break;
                  case SciDAVis::Text:
                        str += tr("Hello world!\n");
                        break;
                  case SciDAVis::Month:
                        str += QLocale().toString(QDate(1900,1,1), ui.format_box->itemData(format_index).toString());
                        break;
                  case SciDAVis::Day:
                        str += QLocale().toString(QDate(1900,1,1), ui.format_box->itemData(format_index).toString());
                        break;
                  case SciDAVis::DateTime:
                        str += QDateTime(QDate(1900,1,1), QTime(23,59,59,999)).toString(ui.format_box->itemData(format_index).toString());
                        break;
            }
      }
      ui.type_info->setText(str);
}

void TableView::showControlDescriptionTab()
{
      d_control_tabs->setVisible(true);
      d_hide_button->setArrowType(Qt::RightArrow);
      ui.tab_widget->setCurrentIndex(0);
      ui.tab_widget->setFocus();
}

void TableView::showControlTypeTab()
{
      d_control_tabs->setVisible(true);
      d_hide_button->setArrowType(Qt::RightArrow);
      ui.tab_widget->setCurrentIndex(1);
      ui.tab_widget->setFocus();
}

void TableView::showControlFormulaTab()
{
      d_control_tabs->setVisible(true);
      d_hide_button->setArrowType(Qt::RightArrow);
      ui.tab_widget->setCurrentIndex(2);
      ui.tab_widget->setFocus();
}

void TableView::applyDescription()
{
      QItemSelectionModel * sel_model = d_view_widget->selectionModel();
      int index = sel_model->currentIndex().column();
      if(index >= 0)
      {
            // changing the name triggers an update of the UI, which also resets the content of the
            // comment box => need to cache it so name and comment can be changed simultaneously
            QString comment = ui.comment_box->document()->toPlainText();
            d_table->column(index)->setName(ui.name_edit->text());
            d_table->column(index)->setComment(comment);
      }
}

void TableView::applyType()
{
      int format_index = ui.format_box->currentIndex();
      int type_index = ui.type_box->currentIndex();
      if(format_index < 0 && type_index < 0) return;

      SciDAVis::ColumnMode mode = (SciDAVis::ColumnMode)ui.type_box->itemData(type_index).toInt();
      QList<Column*> list = selectedColumns();
      switch(mode)
      {
            case SciDAVis::Numeric:
                  foreach(Column* col, list)
                  {
                        col->setColumnMode(mode);
                        Double2StringFilter * filter = static_cast<Double2StringFilter*>(col->outputFilter());
                        int digits = ui.digits_box->value(); // setNumericFormat causes digits_box to be modified...
                        filter->setNumericFormat(ui.format_box->itemData(format_index).toChar().toLatin1());
                        filter->setNumDigits(digits);
                        // TODO: make sure this is done by a signal from the filter to the column on to the table
      //                d_model->emitColumnChanged(col); 
                        }
                  break;
            case SciDAVis::Text:
                  foreach(Column* col, list)
                        col->setColumnMode(mode);
                  break;
            case SciDAVis::Month:
            case SciDAVis::Day:
            case SciDAVis::DateTime:
                  foreach(Column* col, list)
                  {
                        col->setColumnMode(mode);
                        DateTime2StringFilter * filter = static_cast<DateTime2StringFilter*>(col->outputFilter());
                        filter->setFormat(ui.format_box->itemData(format_index).toString());
                        // TODO: make sure this is done by a signal from the filter to the column on to the table
      //                d_model->emitColumnChanged(col); 
                  }
                  break;
      }
}
            
void TableView::handleHeaderDataChanged(Qt::Orientation orientation, int first, int last)
{
      if(orientation != Qt::Horizontal) return;

      QItemSelectionModel * sel_model = d_view_widget->selectionModel();

      int col = sel_model->currentIndex().column();
      if(col < first || col > last) return;
      setColumnForControlTabs(col);
}

00603 int TableView::selectedColumnCount(bool full)
{
      int count = 0;
      int cols = d_table->columnCount();
      for (int i=0; i<cols; i++)
            if(isColumnSelected(i, full)) count++;
      return count;
}

00612 int TableView::selectedColumnCount(SciDAVis::PlotDesignation pd)
{
      int count = 0;
      int cols = d_table->columnCount();
      for(int i=0; i<cols; i++)
            if( isColumnSelected(i, false) && (d_table->column(i)->plotDesignation() == pd) ) count++;

      return count;
}

00622 bool TableView::isColumnSelected(int col, bool full)
{
      if(full)
            return d_view_widget->selectionModel()->isColumnSelected(col, QModelIndex());
      else
            return d_view_widget->selectionModel()->columnIntersectsSelection(col, QModelIndex());
}

00630 QList<Column*> TableView::selectedColumns(bool full)
{
      QList<Column*> list;
      int cols = d_table->columnCount();
      for (int i=0; i<cols; i++)
            if(isColumnSelected(i, full)) list << d_table->column(i);

      return list;
}

00640 int TableView::selectedRowCount(bool full)
{
      int count = 0;
      int rows = d_table->rowCount();
      for (int i=0; i<rows; i++)
            if(isRowSelected(i, full)) count++;
      return count;
}

00649 bool TableView::isRowSelected(int row, bool full)
{
      if(full)
            return d_view_widget->selectionModel()->isRowSelected(row, QModelIndex());
      else
            return d_view_widget->selectionModel()->rowIntersectsSelection(row, QModelIndex());
}

00657 int TableView::firstSelectedColumn(bool full)
{
      int cols = d_table->columnCount();
      for (int i=0; i<cols; i++)
      {
            if(isColumnSelected(i, full))
                  return i;
      }
      return -1;
}

00668 int TableView::lastSelectedColumn(bool full)
{
      int cols = d_table->columnCount();
      for(int i=cols-1; i>=0; i--)
            if(isColumnSelected(i, full)) return i;

      return -2;
}

00677 int TableView::firstSelectedRow(bool full)
{
      int rows = d_table->rowCount();
      for (int i=0; i<rows; i++)
      {
            if(isRowSelected(i, full))
                  return i;
      }
      return -1;
}

00688 int TableView::lastSelectedRow(bool full)
{
      int rows = d_table->rowCount();
      for(int i=rows-1; i>=0; i--)
            if(isRowSelected(i, full)) return i;

      return -2;
}

00697 IntervalAttribute<bool> TableView::selectedRows(bool full) {
      IntervalAttribute<bool> result;
      int rows = d_table->rowCount();
      for (int i=0; i<rows; i++)
            if (isRowSelected(i, full))
                  result.setValue(i, true);
      return result;
}

00706 bool TableView::isCellSelected(int row, int col)
{
      if(row < 0 || col < 0 || row >= d_table->rowCount() || col >= d_table->columnCount()) return false;

      return d_view_widget->selectionModel()->isSelected(d_model->index(row, col));
}

00713 void TableView::setCellSelected(int row, int col, bool select)
{
       d_view_widget->selectionModel()->select(d_model->index(row, col), 
                   select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect);
}

00719 void TableView::setCellsSelected(int first_row, int first_col, int last_row, int last_col, bool select)
{
      QModelIndex top_left = d_model->index(first_row, first_col);
      QModelIndex bottom_right = d_model->index(last_row, last_col);
      d_view_widget->selectionModel()->select(QItemSelection(top_left, bottom_right), 
                  select ? QItemSelectionModel::SelectCurrent : QItemSelectionModel::Deselect);
}

00727 void TableView::getCurrentCell(int * row, int * col)
{
      QModelIndex index = d_view_widget->selectionModel()->currentIndex();
      if(index.isValid()) 
      {
            *row = index.row();
            *col = index.column();
      }
      else
      {
            *row = -1;
            *col = -1;
      }
}

00742 bool TableView::eventFilter(QObject * watched, QEvent * event)
{
      QHeaderView * v_header = d_view_widget->verticalHeader();

      if (event->type() == QEvent::ContextMenu) 
      {
            QContextMenuEvent *cm_event = static_cast<QContextMenuEvent *>(event);
            QPoint global_pos = cm_event->globalPos();
            if(watched == v_header) 
                  d_table->showTableViewRowContextMenu(global_pos);
            else if(watched == d_horizontal_header) { 
                  int col = d_horizontal_header->logicalIndexAt(cm_event->pos());
                  if (!isColumnSelected(col, true)) {
                        QItemSelectionModel * sel_model = d_view_widget->selectionModel();
                        sel_model->clearSelection();
                        sel_model->select(QItemSelection(d_model->index(0, col, QModelIndex()),
                                          d_model->index(d_model->rowCount()-1, col, QModelIndex())),
                                    QItemSelectionModel::Select);
                  }
                  d_table->showTableViewColumnContextMenu(global_pos);
            } else if(watched == d_view_widget)
                  d_table->showTableViewContextMenu(global_pos);
            else
                  return MyWidget::eventFilter(watched, event);

            return true;
      } 
      else 
            return MyWidget::eventFilter(watched, event);
}

bool TableView::formulaModeActive() const 
{ 
      return d_model->formulaModeActive(); 
}

void TableView::activateFormulaMode(bool on) 
{ 
      d_model->activateFormulaMode(on); 
}

void TableView::goToNextColumn()
{
      if (d_table->columnCount() == 0) return;

      QModelIndex idx = d_view_widget->currentIndex();
      int col = idx.column()+1;
    if (col >= d_table->columnCount())
            col = 0;
      d_view_widget->setCurrentIndex(idx.sibling(idx.row(), col));
}

void TableView::goToPreviousColumn()
{
      if (d_table->columnCount() == 0) return;

      QModelIndex idx = d_view_widget->currentIndex();
      int col = idx.column()-1;
    if (col < 0)
            col = d_table->columnCount()-1;
      d_view_widget->setCurrentIndex(idx.sibling(idx.row(), col));
}


/* ================== TableViewWidget ================ */

void TableViewWidget::selectAll()
{
      // the original QTableView::selectAll() toggles all cells which is strange behavior IMHO - thzs
      QItemSelectionModel * sel_model = selectionModel();
      QItemSelection sel(model()->index(0, 0, QModelIndex()), model()->index(model()->rowCount()-1, 
            model()->columnCount()-1, QModelIndex()));
      sel_model->select(sel, QItemSelectionModel::Select);
}

00817 void TableViewWidget::updateHeaderGeometry(Qt::Orientation o, int first, int last)
{
      Q_UNUSED(first)
      Q_UNUSED(last)
      if(o != Qt::Horizontal) return;
      horizontalHeader()->setStretchLastSection(true);  // ugly hack (flaw in Qt? Does anyone know a better way?)
      horizontalHeader()->updateGeometry();
      horizontalHeader()->setStretchLastSection(false); // ugly hack part 2
}

00827 void TableViewWidget::keyPressEvent(QKeyEvent * event)
{
    if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
            emit advanceCell();
      QTableView::keyPressEvent(event);
}


Generated by  Doxygen 1.6.0   Back to index