Changeset 14541


Ignore:
Timestamp:
Jun 15, 2015, 9:07:46 PM (6 years ago)
Author:
mikedld
Message:

Torrent properties dialog improvements

Simplify DND checkboxes drawing, this also fixes incorrect drawing on
Mac when file tree widget is inactive.
Do better job calculating column widths for file tree to avoid ellipsis.
Fix file tree sorting order for size and priority columns.
Change key to toggle priorities to Shift+Space instead of Enter/Return?
to avoid conflicts with name editing and default button handling.
Fix selected tracker item background drawing in certain cases.

Location:
trunk/qt
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/qt/DetailsDialog.cc

    r14539 r14541  
    7272
    7373  int
    74   measureViewItem (QAbstractItemView * view, const QString& text)
     74  measureViewItem (QTreeWidget * view, int column, const QString& text)
    7575  {
    76     QStyleOptionViewItemV4 option;
    77     option.features = QStyleOptionViewItemV2::HasDisplay;
    78     option.text = text;
    79     return view->style ()->sizeFromContents (QStyle::CT_ItemViewItem, &option,
    80       QSize (QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), view).width ();
     76    const QTreeWidgetItem * headerItem = view->headerItem ();
     77
     78    const int itemWidth = Utils::measureViewItem (view, text);
     79    const int headerWidth = Utils::measureHeaderItem (view->header (), headerItem->text (column));
     80
     81    return std::max (itemWidth, headerWidth);
    8182  }
    8283}
     
    12461247
    12471248  ui.peersView->setColumnWidth (COL_LOCK, 20);
    1248   ui.peersView->setColumnWidth (COL_UP, measureViewItem (ui.peersView, QLatin1String ("1024 MiB/s")));
    1249   ui.peersView->setColumnWidth (COL_DOWN, measureViewItem (ui.peersView, QLatin1String ("1024 MiB/s")));
    1250   ui.peersView->setColumnWidth (COL_PERCENT, measureViewItem (ui.peersView, QLatin1String ("100%")));
    1251   ui.peersView->setColumnWidth (COL_STATUS, measureViewItem (ui.peersView, QLatin1String ("ODUK?EXI")));
    1252   ui.peersView->setColumnWidth (COL_ADDRESS, measureViewItem (ui.peersView, QLatin1String ("888.888.888.888")));
     1249  ui.peersView->setColumnWidth (COL_UP, measureViewItem (ui.peersView, COL_UP, QLatin1String ("1024 MiB/s")));
     1250  ui.peersView->setColumnWidth (COL_DOWN, measureViewItem (ui.peersView, COL_DOWN, QLatin1String ("1024 MiB/s")));
     1251  ui.peersView->setColumnWidth (COL_PERCENT, measureViewItem (ui.peersView, COL_PERCENT, QLatin1String ("100%")));
     1252  ui.peersView->setColumnWidth (COL_STATUS, measureViewItem (ui.peersView, COL_STATUS, QLatin1String ("ODUK?EXI")));
     1253  ui.peersView->setColumnWidth (COL_ADDRESS, measureViewItem (ui.peersView, COL_ADDRESS, QLatin1String ("888.888.888.888")));
    12531254}
    12541255
  • trunk/qt/DetailsDialog.ui

    r14537 r14541  
    583583       <item>
    584584        <widget class="FileTreeView" name="filesView">
     585         <property name="horizontalScrollBarPolicy">
     586          <enum>Qt::ScrollBarAlwaysOff</enum>
     587         </property>
     588         <property name="alternatingRowColors">
     589          <bool>true</bool>
     590         </property>
     591         <property name="selectionMode">
     592          <enum>QAbstractItemView::ExtendedSelection</enum>
     593         </property>
    585594         <property name="verticalScrollMode">
    586595          <enum>QAbstractItemView::ScrollPerPixel</enum>
     596         </property>
     597         <property name="sortingEnabled">
     598          <bool>true</bool>
    587599         </property>
    588600        </widget>
  • trunk/qt/FileTreeDelegate.cc

    r14537 r14541  
    5858      p.direction = qApp->layoutDirection();
    5959      p.rect = option.rect;
    60       p.rect.setSize (QSize(option.rect.width()-2, option.rect.height()-8));
     60      p.rect.setSize (QSize(option.rect.width() - 4, option.rect.height() - 8));
    6161      p.rect.moveCenter (option.rect.center());
    6262      p.fontMetrics = qApp->fontMetrics();
     
    7171  else if(column == FileTreeModel::COL_WANTED)
    7272    {
    73       QStyleOptionButton o;
    74       o.state = option.state;
    75       o.direction = qApp->layoutDirection();
    76       o.rect.setSize (QSize(20, option.rect.height()));
    77       o.rect.moveCenter (option.rect.center());
    78       o.fontMetrics = qApp->fontMetrics();
    79       switch (index.data().toInt())
    80         {
    81           case Qt::Unchecked: o.state |= QStyle::State_Off; break;
    82           case Qt::Checked:   o.state |= QStyle::State_On; break;
    83           default:            o.state |= QStyle::State_NoChange;break;
    84         }
    85       style->drawControl (QStyle::CE_CheckBox, &o, painter);
     73      QStyleOptionViewItemV4 vi (option);
     74      vi.features |= QStyleOptionViewItemV4::HasCheckIndicator;
     75      QRect checkRect = style->subElementRect (QStyle::SE_ItemViewItemCheckIndicator, &vi, nullptr);
     76      checkRect.moveCenter (option.rect.center ());
     77      drawCheck (painter, vi, checkRect, static_cast<Qt::CheckState> (index.data ().toInt ()));
    8678    }
    8779
  • trunk/qt/FileTreeItem.cc

    r14537 r14541  
    108108      value = Qt::AlignRight + Qt::AlignVCenter;
    109109    }
    110   else if (role == Qt::DisplayRole)
     110  else if (role == Qt::DisplayRole || role == FileTreeModel::SortRole)
    111111    {
    112112      switch(column)
    113        {
    114          case FileTreeModel::COL_NAME:
    115            value.setValue (name());
    116            break;
    117 
    118          case FileTreeModel::COL_SIZE:
    119            value.setValue (sizeString() + QLatin1String ("  "));
    120            break;
    121 
    122          case FileTreeModel::COL_PROGRESS:
    123            value.setValue (progress());
    124            break;
    125 
    126          case FileTreeModel::COL_WANTED:
    127            value.setValue (isSubtreeWanted());
    128            break;
    129 
    130          case FileTreeModel::COL_PRIORITY:
    131            value.setValue (priorityString());
    132            break;
     113        {
     114          case FileTreeModel::COL_NAME:
     115            value.setValue (name());
     116            break;
     117
     118          case FileTreeModel::COL_SIZE:
     119            if (role == Qt::DisplayRole)
     120              value.setValue (sizeString());
     121            else
     122              value.setValue (size ());
     123            break;
     124
     125          case FileTreeModel::COL_PROGRESS:
     126            value.setValue (progress());
     127            break;
     128
     129          case FileTreeModel::COL_WANTED:
     130            value.setValue (isSubtreeWanted());
     131            break;
     132
     133          case FileTreeModel::COL_PRIORITY:
     134            if (role == Qt::DisplayRole)
     135              value.setValue (priorityString());
     136            else
     137              value.setValue (priority ());
     138            break;
    133139        }
    134140    }
     
    173179FileTreeItem::sizeString () const
    174180{
    175   QString str;
    176 
     181  return Formatter::sizeToString (size ());
     182}
     183
     184uint64_t
     185FileTreeItem::size () const
     186{
    177187  if (myChildren.isEmpty())
    178     {
    179       str = Formatter::sizeToString (myTotalSize);
    180     }
    181   else
    182     {
    183       uint64_t have = 0;
    184       uint64_t total = 0;
    185       getSubtreeWantedSize (have, total);
    186       str = Formatter::sizeToString (total);
    187     }
    188 
    189   return str;
     188    return myTotalSize;
     189
     190  uint64_t have = 0;
     191  uint64_t total = 0;
     192  getSubtreeWantedSize (have, total);
     193  return total;
    190194}
    191195
  • trunk/qt/FileTreeItem.h

    r14540 r14541  
    2323{
    2424    Q_DECLARE_TR_FUNCTIONS (FileTreeItem)
     25    Q_DISABLE_COPY (FileTreeItem)
    2526
    2627  public:
     
    7071    double progress () const;
    7172    int priority () const;
     73    uint64_t size () const;
    7274    int isSubtreeWanted () const;
    7375    const QHash<QString,int>& getMyChildRows();
  • trunk/qt/FileTreeModel.h

    r14540 r14541  
    3737      COL_FILE_INDEX,
    3838      NUM_COLUMNS
     39    };
     40
     41    enum Role
     42    {
     43      SortRole = Qt::UserRole
    3944    };
    4045
  • trunk/qt/FileTreeView.cc

    r14537 r14541  
    1515
    1616#include "FileTreeDelegate.h"
     17#include "FileTreeItem.h"
    1718#include "FileTreeModel.h"
    1819#include "FileTreeView.h"
     20#include "Formatter.h"
     21#include "Utils.h"
    1922
    2023FileTreeView::FileTreeView (QWidget * parent, bool isEditable):
     
    2427  myDelegate (new FileTreeDelegate (this))
    2528{
    26   setSortingEnabled (true);
    27   setAlternatingRowColors (true);
    28   setSelectionBehavior (QAbstractItemView::SelectRows);
    29   setSelectionMode (QAbstractItemView::ExtendedSelection);
    3029  myProxy->setSourceModel (myModel);
     30  myProxy->setSortRole (FileTreeModel::SortRole);
     31  myProxy->setSortCaseSensitivity (Qt::CaseInsensitive);
     32
    3133  setModel (myProxy);
    3234  setItemDelegate (myDelegate);
    33   setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
    3435  sortByColumn (FileTreeModel::COL_NAME, Qt::AscendingOrder);
    35   installEventFilter (this);
    3636
    3737  for (int i=0; i<FileTreeModel::NUM_COLUMNS; ++i)
    38     {
    39       setColumnHidden (i, (i<FileTreeModel::FIRST_VISIBLE_COLUMN) || (FileTreeModel::LAST_VISIBLE_COLUMN<i));
    40 
    41 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    42       header()->setResizeMode(i, QHeaderView::Interactive);
    43 #else
    44       header()->setSectionResizeMode(i, QHeaderView::Interactive);
    45 #endif
    46     }
     38    setColumnHidden (i, (i<FileTreeModel::FIRST_VISIBLE_COLUMN) || (FileTreeModel::LAST_VISIBLE_COLUMN<i));
    4739
    4840  connect (this, SIGNAL(clicked(QModelIndex)),
     
    8981}
    9082
    91 bool
    92 FileTreeView::eventFilter (QObject * o, QEvent * event)
     83void
     84FileTreeView::resizeEvent (QResizeEvent * event)
    9385{
    94   // this is kind of a hack to get the last three columns be the
     86  QTreeView::resizeEvent (event);
     87
     88  // this is kind of a hack to get the last four columns be the
    9589  // right size, and to have the filename column use whatever
    9690  // space is left over...
    97   if ((o == this) && (event->type() == QEvent::Resize))
     91
     92  int left = event->size ().width () - 1;
     93  for (int column = FileTreeModel::FIRST_VISIBLE_COLUMN; column <= FileTreeModel::LAST_VISIBLE_COLUMN; ++column)
    9894    {
    99       QResizeEvent * r = static_cast<QResizeEvent*> (event);
    100       int left = r->size().width();
    101       const QFontMetrics fontMetrics(font());
    102       for (int column=FileTreeModel::FIRST_VISIBLE_COLUMN; column<=FileTreeModel::LAST_VISIBLE_COLUMN; ++column)
     95      if (column == FileTreeModel::COL_NAME)
     96        continue;
     97      if (isColumnHidden (column))
     98        continue;
     99
     100      int minWidth = 0;
     101
     102      QStringList itemTexts;
     103      switch (column)
    103104        {
    104           if (column == FileTreeModel::COL_NAME)
    105             continue;
    106           if (isColumnHidden (column))
    107             continue;
     105          case FileTreeModel::COL_SIZE:
     106            for (int s = Formatter::B; s <= Formatter::TB; ++s)
     107              itemTexts << QLatin1String ("999.9 ") +
     108                           Formatter::unitStr (Formatter::MEM, static_cast<Formatter::Size> (s));
     109            break;
    108110
    109           QString header;
    110           if (column == FileTreeModel::COL_SIZE)
    111             header = QLatin1String ("999.9 KiB");
    112           else
    113             header = myModel->headerData (column, Qt::Horizontal).toString();
    114           header += QLatin1String ("    ");
    115           const int width = fontMetrics.size (0, header).width();
    116           setColumnWidth (column, width);
    117             left -= width;
     111          case FileTreeModel::COL_PROGRESS:
     112            itemTexts << QLatin1String ("  100%  ");
     113            break;
     114
     115          case FileTreeModel::COL_WANTED:
     116            minWidth = 20;
     117            break;
     118
     119          case FileTreeModel::COL_PRIORITY:
     120            itemTexts << FileTreeItem::tr ("Low") << FileTreeItem::tr ("Normal") <<
     121                         FileTreeItem::tr ("High") << FileTreeItem::tr ("Mixed");
     122            break;
    118123        }
    119       left -= 20; // not sure why this is necessary.  it works in different themes + font sizes though...
    120       setColumnWidth(FileTreeModel::COL_NAME, std::max(left,0));
     124
     125      int itemWidth = 0;
     126      for (const QString& itemText: itemTexts)
     127        itemWidth = std::max (itemWidth, Utils::measureViewItem (this, itemText));
     128
     129      const QString headerText = myModel->headerData (column, Qt::Horizontal).toString ();
     130      int headerWidth = Utils::measureHeaderItem (this->header (), headerText);
     131
     132      const int width = std::max (minWidth, std::max (itemWidth, headerWidth));
     133      setColumnWidth (column, width);
     134
     135      left -= width;
    121136    }
     137
     138  setColumnWidth (FileTreeModel::COL_NAME, std::max (left, 0));
     139}
     140
     141void
     142FileTreeView::keyPressEvent (QKeyEvent * event)
     143{
     144  QTreeView::keyPressEvent (event);
    122145
    123146  // handle using the keyboard to toggle the
    124147  // wanted/unwanted state or the file priority
    125   else if (event->type () == QEvent::KeyPress && state () != EditingState)
     148
     149  if (state () == EditingState)
     150    return;
     151
     152  if (event->key () == Qt::Key_Space)
    126153    {
    127       switch (static_cast<QKeyEvent*> (event)->key ())
    128         {
    129         case Qt::Key_Space:
    130           for (const QModelIndex& i: selectionModel ()->selectedRows (FileTreeModel::COL_WANTED))
    131             clicked (i);
    132           break;
     154      int column;
    133155
    134         case Qt::Key_Enter:
    135         case Qt::Key_Return:
    136           for (const QModelIndex& i: selectionModel ()->selectedRows (FileTreeModel::COL_PRIORITY))
    137             clicked (i);
    138           break;
    139         }
     156      const Qt::KeyboardModifiers modifiers = event->modifiers ();
     157      if (modifiers == Qt::NoModifier)
     158        column = FileTreeModel::COL_WANTED;
     159      else if (modifiers == Qt::ShiftModifier)
     160        column = FileTreeModel::COL_PRIORITY;
     161      else
     162        return;
     163
     164      for (const QModelIndex& i: selectionModel ()->selectedRows (column))
     165        clicked (i);
    140166    }
    141 
    142   return false;
    143167}
    144168
  • trunk/qt/FileTreeView.h

    r14539 r14541  
    4545
    4646  protected:
    47     // QObject
    48     bool eventFilter (QObject *, QEvent *);
     47    // QWidget
     48    virtual void resizeEvent (QResizeEvent * event);
     49    virtual void keyPressEvent (QKeyEvent * event);
    4950
    5051  private:
  • trunk/qt/TrackerDelegate.cc

    r14537 r14541  
    132132{
    133133  const bool isItemSelected ((option.state & QStyle::State_Selected) != 0);
     134  const bool isItemEnabled ((option.state & QStyle::State_Enabled) != 0);
     135  const bool isItemActive ((option.state & QStyle::State_Active) != 0);
    134136
    135137  QIcon trackerIcon (inf.st.getFavicon());
     
    139141
    140142  painter->save();
     143
     144  if (isItemSelected)
     145    {
     146      QPalette::ColorGroup cg = isItemEnabled ? QPalette::Normal : QPalette::Disabled;
     147      if (cg == QPalette::Normal && !isItemActive)
     148        cg = QPalette::Inactive;
     149
     150      painter->fillRect (option.rect, option.palette.brush (cg, QPalette::Highlight));
     151    }
    141152
    142153  trackerIcon.paint (painter, layout.iconRect, Qt::AlignCenter, isItemSelected ? QIcon::Selected : QIcon::Normal, QIcon::On);
  • trunk/qt/Utils.cc

    r14539 r14541  
    1313#endif
    1414
     15#include <QAbstractItemView>
    1516#include <QApplication>
    1617#include <QColor>
     
    1920#include <QFileDialog>
    2021#include <QFileInfo>
     22#include <QHeaderView>
    2123#include <QIcon>
    2224#include <QInputDialog>
     
    205207}
    206208
     209int
     210Utils::measureViewItem (QAbstractItemView * view, const QString& text)
     211{
     212  QStyleOptionViewItemV4 option;
     213  option.initFrom (view);
     214  option.features = QStyleOptionViewItemV2::HasDisplay;
     215  option.text = text;
     216  option.textElideMode = Qt::ElideNone;
     217  option.font = view->font ();
     218
     219  return view->style ()->sizeFromContents (QStyle::CT_ItemViewItem, &option,
     220    QSize (QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), view).width ();
     221}
     222
     223int
     224Utils::measureHeaderItem (QHeaderView * view, const QString& text)
     225{
     226  QStyleOptionHeader option;
     227  option.initFrom (view);
     228  option.text = text;
     229  option.sortIndicator = view->isSortIndicatorShown () ? QStyleOptionHeader::SortDown :
     230    QStyleOptionHeader::None;
     231
     232  return view->style ()->sizeFromContents (QStyle::CT_HeaderSection, &option,
     233    QSize (QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), view).width ();
     234}
     235
    207236QColor
    208237Utils::getFadedColor (const QColor& color)
  • trunk/qt/Utils.h

    r14539 r14541  
    1616#include <QString>
    1717
     18class QAbstractItemView;
    1819class QColor;
     20class QHeaderView;
    1921class QIcon;
    2022
     
    3436      rect.adjust (dx1, 0, -dx2, 0);
    3537    }
     38
     39    static int measureViewItem (QAbstractItemView * view, const QString& text);
     40    static int measureHeaderItem (QHeaderView * view, const QString& text);
    3641
    3742    static QColor getFadedColor (const QColor& color);
Note: See TracChangeset for help on using the changeset viewer.