/************************************************************************** Displays menu on header by right clicking **************************************************************************/ void plr_widget::display_header_menu(const QPoint &) { struct player_dlg_column *pcol; QMenu hideshowColumn(this); hideshowColumn.setTitle(_("Column visibility")); QList<QAction *> actions; for (int i = 0; i < list_model->columnCount(); ++i) { QAction *myAct = hideshowColumn.addAction( list_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); myAct->setCheckable(true); myAct->setChecked(!isColumnHidden(i)); actions.append(myAct); } QAction *act = hideshowColumn.exec(QCursor::pos()); if (act) { int col = actions.indexOf(act); Q_ASSERT(col >= 0); pcol = &player_dlg_columns[col]; pcol->show = !pcol->show; setColumnHidden(col, !isColumnHidden(col)); if (!isColumnHidden(col) && columnWidth(col) <= 5) setColumnWidth(col, 100); } }
void Playlist::resizeColumns() { int visibleRatio = 0; int resizableArea = size().width() - 4; if (verticalScrollBar()->isVisible()) { resizableArea -= verticalScrollBar()->size().width(); } // Resize fixed columns first, and then compute the remaining width for (int c = 0; c < columnCount(); c++) { if (!isColumnHidden(c)) { int ratio = horizontalHeaderItem(c)->data(Qt::UserRole+2).toInt(); // Fixed column if (ratio == 0) { this->resizeColumnToContents(c); resizableArea -= columnWidth(c) - 1; } visibleRatio += ratio; } } for (int c = 0; c < columnCount(); c++) { int ratio = horizontalHeaderItem(c)->data(Qt::UserRole+2).toInt(); // Resizable column if (ratio != 0) { int s = resizableArea * ratio / visibleRatio ; if (!isColumnHidden(c)) { this->setColumnWidth(c, s); } } } }
void DiveListView::setupUi(){ QSettings settings; static bool firstRun = true; if(firstRun) backupExpandedRows(); settings.beginGroup("ListWidget"); /* if no width are set, use the calculated width for each column; * for that to work we need to temporarily expand all rows */ expandAll(); for (int i = DiveTripModel::NR; i < DiveTripModel::COLUMNS; i++) { if(isColumnHidden(i)) continue; QVariant width = settings.value(QString("colwidth%1").arg(i)); if (width.isValid()) setColumnWidth(i, width.toInt()); else setColumnWidth(i, 100); } settings.endGroup(); if(firstRun) restoreExpandedRows(); else collapseAll(); firstRun = false; }
/** * @brief Toggles the visibility of the column on or off. * If a signal is sent, the column name is derived from QAction::text(). Because of this, * You can only connect signals from a QAction to this slot. * @param column The name of the column to toggle */ void DatabaseList::toggleColumn(const QString column) { QSettings settings; QAction* actionUsed = (QAction*)sender(); QString columnName = column; // If we recieved a signal, find the column name from the sender if(actionUsed != 0) columnName = actionUsed->text(); // Loop through the columns looking for the one we want for(int i = 0; i < mDatabaseModel->columnCount(); i++) { if(mDatabaseModel->headerData(i, Qt::Horizontal).toString() == columnName) { // Toggle the visibility of the column if(isColumnHidden(i)) { setColumnWidth(i, settings.value("SongView/ColumnSize" + QString::number(i)).toInt()); showColumn(i); } else { settings.setValue("SongView/ColumnSize" + QString::number(i), columnWidth(i)); hideColumn(i); } } } };
/** Toggle the selected column from the context menu. */ void Playlist::toggleSelectedColumn(QAction *action) { int columnIndex = action->data().toInt(); this->setColumnHidden(columnIndex, !isColumnHidden(columnIndex)); this->resizeColumns(); this->saveColumnsState(); }
/************************************************************************** Hides columns in plr widget, depending on info from plr_list **************************************************************************/ void plr_widget::hide_columns() { for (int col = 0; col < list_model->columnCount(); col++) { if(!list_model->hide_data(col).toBool()){ setColumnHidden(col, !isColumnHidden(col)); } } }
void OperationTable::resizeColumns() { double width = this->width() - verticalHeader()->width();; if( resizeList.count() < columnCount() ) { int c = 0; for(int i = 0; i < columnCount(); i++) { if( isColumnHidden(i) ) continue; c++; } int w = ceil( width/c * 0.976 ); for(int i = 0; i < columnCount(); i++) { if( isColumnHidden(i) ) continue; setColumnWidth( i, w ); } return; } for(int i = 0; i < columnCount(); i++) { if( isColumnHidden(i) ) continue; int w1 = fontMetrics().width( horizontalHeaderItem(i)->text() ) * 1.5; int w2 = ceil( width*resizeList.at(i)/100 ); if( w2 >= w1 ) setColumnWidth( i, w2 ); else setColumnWidth( i, w1 ); } }
DiveListView::~DiveListView() { QSettings settings; settings.beginGroup("ListWidget"); for (int i = DiveTripModel::NR; i < DiveTripModel::COLUMNS; i++){ if (isColumnHidden(i)) continue; settings.setValue(QString("colwidth%1").arg(i), columnWidth(i)); } settings.endGroup(); }
void UTableRecycleBin::showContextMenuHorizontalHeader(QPoint p) { if(bShowContextMenuHorizontalHeader) { QList <QAction *> list = contextMenuHorizontalHeader->actions(); for(int i = 0; i < list.count(); i++) { QAction *action = list.at(i); action->setChecked(!isColumnHidden(i + 1)); } contextMenuHorizontalHeader->exec(mapToGlobal(p)); } }
void QxFileSystemView::resizeColumnsToContents() { /*int numVisible = 0; for (int k = 0; k < model()->columnCount(); ++k) numVisible += !isColumnHidden(k);*/ for (int k = 0; k < model()->columnCount(); ++k) { if (!isColumnHidden(k)) { /* if (numVisible == 1) { QTreeView::setColumnWidth(k, width()); break; } else*/ QTreeView::resizeColumnToContents(k); } } }
void DeviceExplorerView::initActions() { ISCORE_ASSERT(model()); const int n = model()->columnCount(); m_actions.reserve(n); for(int i = 0; i < n; ++i) { QAction* a = new QAction(model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(), this); a->setCheckable(true); a->setChecked(!isColumnHidden(i)); connect(a, SIGNAL(toggled(bool)), this, SLOT(columnVisibilityChanged(bool))); m_actions.append(a); } }
void OperationTable::copy() { QTableWidgetSelectionRange range = selectedRange(); QString str; for(int i = 0; i < range.rowCount(); i++) { for(int j = 0; j < range.columnCount(); j++) { if( isColumnHidden( range.leftColumn() + j ) ) continue; str += this->text( range.topRow() + i, range.leftColumn() + j ); if( j < range.columnCount()-1 ) str += "\t"; } if( i < range.rowCount() - 1 ) str += "\n"; } QApplication::clipboard()->setText(str); }
void LkInputTableView::setModel(QAbstractItemModel *m_model){ QTableView::setModel(m_model); this->setContextMenuPolicy(Qt::ActionsContextMenu); this->actions().clear(); for(int i=0; i < this->model()->columnCount(); i++){ int data = this->model()->headerData(i, Qt::Horizontal, Qt::UserRole).toInt(); if(data == hideColumnFlag) QTableView::hideColumn(i); else { QString text = this->model()->headerData(i, Qt::Horizontal).toString(); QAction *openAct = new QAction(text, this); openAct->setCheckable(true); openAct->setChecked(!isColumnHidden(i)); openAct->setData(i); openAct->setStatusTip(text); connect(openAct, SIGNAL(triggered(bool)), this, SLOT(on_action(bool))); this->addAction(openAct); } } }
void TreeWidget::keyPressEvent( QKeyEvent *e ) { QModelIndexList i = selectionModel()->selectedRows(); if( hasFocus() && !i.isEmpty() && i[0].isValid() ) { switch( e->key() ) { case Qt::Key_Delete: if( !isColumnHidden( 3 ) ) { Q_EMIT remove( i[0].row() ); e->accept(); } break; case Qt::Key_Return: openFile( i[0] ); e->accept(); break; default: break; } } QTreeWidget::keyPressEvent( e ); }
void KFLogTreeWidget::createShowColMenu() { if( header()->count() == 0 || showColMenu != 0 ) { return; } showColMenu = new QMenu(this); showColMenu->setTitle( tr("Toggle columns") ); showColMenu->setToolTip(tr("Toggle visibility of table columns")); menuActionGroup = new QActionGroup(this); menuActionGroup->setExclusive( false ); QAction *action = new QAction( tr("Show all columns"), this ); action->setData( -1 ); menuActionGroup->addAction( action ); showColMenu->addAction( action ); showColMenu->addSeparator(); QTreeWidgetItem* hi = headerItem(); for( int i = 0; i < header()->count(); i++ ) { QAction *action = new QAction( hi->text(i), this ); action->setCheckable( true ); action->setChecked( isColumnHidden(i) == false ); action->setData( i ); menuActionGroup->addAction( action ); showColMenu->addAction( action ); } connect( menuActionGroup, SIGNAL(triggered(QAction *)), SLOT(slotMenuActionTriggered( QAction *)) ); }
void ItemViewWidget::saveState() { if (!m_isInitialized) { return; } const QString name = objectName(); const QString suffix = QLatin1String("ViewWidget"); const QString type = (name.endsWith(suffix) ? name.left(name.size() - suffix.size()) : name); if (type.isEmpty()) { return; } Settings settings(SessionsManager::getWritableDataPath(QLatin1String("views.ini"))); settings.beginGroup(type); QStringList columns; for (int i = 0; i < getColumnCount(); ++i) { const int section = m_headerWidget->logicalIndex(i); if (section >= 0 && !isColumnHidden(section)) { columns.append(QString::number(section)); } } settings.setValue(QLatin1String("columns"), columns.join(QLatin1Char(','))); settings.setValue(QLatin1String("sortColumn"), ((m_sortColumn >= 0) ? QVariant(m_sortColumn) : QVariant())); settings.setValue(QLatin1String("sortOrder"), ((m_sortColumn >= 0) ? QVariant((m_sortOrder == Qt::AscendingOrder) ? QLatin1String("ascending") : QLatin1String("descending")) : QVariant())); settings.save(); }
TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *main_window) : QTreeView(parent) , main_window(main_window) { setUniformRowHeights(true); // Load settings bool column_loaded = loadSettings(); // Create and apply delegate listDelegate = new TransferListDelegate(this); setItemDelegate(listDelegate); // Create transfer list model listModel = new TorrentModel(this); nameFilterModel = new TransferListSortModel(); nameFilterModel->setDynamicSortFilter(true); nameFilterModel->setSourceModel(listModel); nameFilterModel->setFilterKeyColumn(TorrentModel::TR_NAME); nameFilterModel->setFilterRole(Qt::DisplayRole); nameFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive); setModel(nameFilterModel); // Visual settings setRootIsDecorated(false); setAllColumnsShowFocus(true); setSortingEnabled(true); setSelectionMode(QAbstractItemView::ExtendedSelection); setItemsExpandable(false); setAutoScroll(true); setDragDropMode(QAbstractItemView::DragOnly); #if defined(Q_OS_MAC) setAttribute(Qt::WA_MacShowFocusRect, false); #endif header()->setStretchLastSection(false); // Default hidden columns if (!column_loaded) { setColumnHidden(TorrentModel::TR_ADD_DATE, true); setColumnHidden(TorrentModel::TR_SEED_DATE, true); setColumnHidden(TorrentModel::TR_UPLIMIT, true); setColumnHidden(TorrentModel::TR_DLLIMIT, true); setColumnHidden(TorrentModel::TR_TRACKER, true); setColumnHidden(TorrentModel::TR_AMOUNT_DOWNLOADED, true); setColumnHidden(TorrentModel::TR_AMOUNT_UPLOADED, true); setColumnHidden(TorrentModel::TR_AMOUNT_DOWNLOADED_SESSION, true); setColumnHidden(TorrentModel::TR_AMOUNT_UPLOADED_SESSION, true); setColumnHidden(TorrentModel::TR_AMOUNT_LEFT, true); setColumnHidden(TorrentModel::TR_TIME_ELAPSED, true); setColumnHidden(TorrentModel::TR_SAVE_PATH, true); setColumnHidden(TorrentModel::TR_COMPLETED, true); setColumnHidden(TorrentModel::TR_RATIO_LIMIT, true); setColumnHidden(TorrentModel::TR_SEEN_COMPLETE_DATE, true); setColumnHidden(TorrentModel::TR_LAST_ACTIVITY, true); setColumnHidden(TorrentModel::TR_TOTAL_SIZE, true); } //Ensure that at least one column is visible at all times bool atLeastOne = false; for (unsigned int i = 0; i<TorrentModel::NB_COLUMNS; i++) { if (!isColumnHidden(i)) { atLeastOne = true; break; } } if (!atLeastOne) setColumnHidden(TorrentModel::TR_NAME, false); //When adding/removing columns between versions some may //end up being size 0 when the new version is launched with //a conf file from the previous version. for (unsigned int i = 0; i<TorrentModel::NB_COLUMNS; i++) if (!columnWidth(i)) resizeColumnToContents(i); setContextMenuPolicy(Qt::CustomContextMenu); // Listen for list events connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(torrentDoubleClicked(QModelIndex))); connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(displayListMenu(const QPoint &))); header()->setContextMenuPolicy(Qt::CustomContextMenu); connect(header(), SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(displayDLHoSMenu(const QPoint &))); connect(header(), SIGNAL(sectionMoved(int, int, int)), this, SLOT(saveSettings())); connect(header(), SIGNAL(sectionResized(int, int, int)), this, SLOT(saveSettings())); connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(saveSettings())); editHotkey = new QShortcut(QKeySequence("F2"), this, SLOT(renameSelectedTorrent()), 0, Qt::WidgetShortcut); deleteHotkey = new QShortcut(QKeySequence::Delete, this, SLOT(deleteSelectedTorrents()), 0, Qt::WidgetShortcut); #ifdef QBT_USES_QT5 // This hack fixes reordering of first column with Qt5. // https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777 QTableView unused; unused.setVerticalHeader(header()); header()->setParent(this); unused.setVerticalHeader(new QHeaderView(Qt::Horizontal)); #endif }
void FieldView::contextMenuEvent(QContextMenuEvent* event) { QMenu menu(this); QModelIndex index = currentIndex(); if(index.isValid()) { menu.addAction(m_applyValueOnSelection); menu.addAction(m_applyValueOnAllLines); menu.addSeparator(); menu.addAction(m_defineCode); if(nullptr != m_canvasList) { menu.addSeparator(); menu.addAction(m_delItem); } } auto showSubMenu = menu.addMenu(tr("Show")); showSubMenu->addAction(m_showAllGroup); showSubMenu->addAction(m_showEsteticGroup); showSubMenu->addAction(m_showIdGroup); showSubMenu->addAction(m_showValueGroup); showSubMenu->addAction(m_showGeometryGroup); auto hideSubMenu = menu.addMenu(tr("Show/Hide")); auto columnCount = m_model->columnCount(QModelIndex()); for(int i = 0; i < columnCount;++i) { auto name = m_model->headerData(i,Qt::Horizontal,Qt::DisplayRole).toString(); auto act = hideSubMenu->addAction(name); act->setCheckable(true); act->setChecked(!isColumnHidden(i)); connect(act, SIGNAL(triggered(bool)) , m_mapper, SLOT(map())); m_mapper->setMapping(act,i); } QAction* act = menu.exec(event->globalPos()); if(act == m_delItem) { auto itemData = static_cast<Field*>(index.internalPointer()); DeleteFieldCommand* deleteCommand = new DeleteFieldCommand(itemData,m_canvasList->at(*m_currentPage),m_model,*m_currentPage); m_undoStack->push(deleteCommand); } else if( m_applyValueOnAllLines == act) { applyValue(index,false); } else if(m_applyValueOnSelection == act) { applyValue(index,true); } else if(m_defineCode == act) { defineItemCode(index); } else if(m_resetCode == act) { if(!index.isValid()) return; Field* field = m_model->getFieldFromIndex(index); if(nullptr != field) { field->setGeneratedCode(QStringLiteral("")); } } }
bool QTable::qt_invoke( int _id, QUObject* _o ) { switch ( _id - staticMetaObject()->slotOffset() ) { case 0: setNumRows((int)static_QUType_int.get(_o+1)); break; case 1: setNumCols((int)static_QUType_int.get(_o+1)); break; case 2: setShowGrid((bool)static_QUType_bool.get(_o+1)); break; case 3: hideRow((int)static_QUType_int.get(_o+1)); break; case 4: hideColumn((int)static_QUType_int.get(_o+1)); break; case 5: showRow((int)static_QUType_int.get(_o+1)); break; case 6: showColumn((int)static_QUType_int.get(_o+1)); break; case 7: static_QUType_bool.set(_o,isRowHidden((int)static_QUType_int.get(_o+1))); break; case 8: static_QUType_bool.set(_o,isColumnHidden((int)static_QUType_int.get(_o+1))); break; case 9: setColumnWidth((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2)); break; case 10: setRowHeight((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2)); break; case 11: adjustColumn((int)static_QUType_int.get(_o+1)); break; case 12: adjustRow((int)static_QUType_int.get(_o+1)); break; case 13: setColumnStretchable((int)static_QUType_int.get(_o+1),(bool)static_QUType_bool.get(_o+2)); break; case 14: setRowStretchable((int)static_QUType_int.get(_o+1),(bool)static_QUType_bool.get(_o+2)); break; case 15: static_QUType_bool.set(_o,isColumnStretchable((int)static_QUType_int.get(_o+1))); break; case 16: static_QUType_bool.set(_o,isRowStretchable((int)static_QUType_int.get(_o+1))); break; case 17: setSorting((bool)static_QUType_bool.get(_o+1)); break; case 18: swapRows((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2)); break; case 19: swapRows((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2),(bool)static_QUType_bool.get(_o+3)); break; case 20: swapColumns((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2)); break; case 21: swapColumns((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2),(bool)static_QUType_bool.get(_o+3)); break; case 22: swapCells((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2),(int)static_QUType_int.get(_o+3),(int)static_QUType_int.get(_o+4)); break; case 23: setLeftMargin((int)static_QUType_int.get(_o+1)); break; case 24: setTopMargin((int)static_QUType_int.get(_o+1)); break; case 25: setCurrentCell((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2)); break; case 26: clearSelection(); break; case 27: clearSelection((bool)static_QUType_bool.get(_o+1)); break; case 28: setColumnMovingEnabled((bool)static_QUType_bool.get(_o+1)); break; case 29: setRowMovingEnabled((bool)static_QUType_bool.get(_o+1)); break; case 30: setReadOnly((bool)static_QUType_bool.get(_o+1)); break; case 31: setRowReadOnly((int)static_QUType_int.get(_o+1),(bool)static_QUType_bool.get(_o+2)); break; case 32: setColumnReadOnly((int)static_QUType_int.get(_o+1),(bool)static_QUType_bool.get(_o+2)); break; case 33: setDragEnabled((bool)static_QUType_bool.get(_o+1)); break; case 34: static_QUType_bool.set(_o,dragEnabled()); break; case 35: insertRows((int)static_QUType_int.get(_o+1)); break; case 36: insertRows((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2)); break; case 37: insertColumns((int)static_QUType_int.get(_o+1)); break; case 38: insertColumns((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2)); break; case 39: removeRow((int)static_QUType_int.get(_o+1)); break; case 40: removeRows((const QMemArray<int>&)*((const QMemArray<int>*)static_QUType_ptr.get(_o+1))); break; case 41: removeColumn((int)static_QUType_int.get(_o+1)); break; case 42: removeColumns((const QMemArray<int>&)*((const QMemArray<int>*)static_QUType_ptr.get(_o+1))); break; case 43: editCell((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2)); break; case 44: editCell((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2),(bool)static_QUType_bool.get(_o+3)); break; case 45: setRowLabels((const QStringList&)*((const QStringList*)static_QUType_ptr.get(_o+1))); break; case 46: setColumnLabels((const QStringList&)*((const QStringList*)static_QUType_ptr.get(_o+1))); break; case 47: columnWidthChanged((int)static_QUType_int.get(_o+1)); break; case 48: rowHeightChanged((int)static_QUType_int.get(_o+1)); break; case 49: columnIndexChanged((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2),(int)static_QUType_int.get(_o+3)); break; case 50: rowIndexChanged((int)static_QUType_int.get(_o+1),(int)static_QUType_int.get(_o+2),(int)static_QUType_int.get(_o+3)); break; case 51: columnClicked((int)static_QUType_int.get(_o+1)); break; case 52: doAutoScroll(); break; case 53: doValueChanged(); break; case 54: updateGeometriesSlot(); break; default: return QScrollView::qt_invoke( _id, _o ); } return TRUE; }
void ExtendedTableWidget::copy(const bool withHeaders) { QModelIndexList indices = selectionModel()->selectedIndexes(); // Remove all indices from hidden columns, because if we don't we might copy data from hidden columns as well which is very // unintuitive; especially copying the rowid column when selecting all columns of a table is a problem because pasting the data // won't work as expected. QMutableListIterator<QModelIndex> i(indices); while (i.hasNext()) { if (isColumnHidden(i.next().column())) i.remove(); } // Abort if there's nothing to copy if (indices.isEmpty()) return; SqliteTableModel* m = qobject_cast<SqliteTableModel*>(model()); // Clear internal copy-paste buffer m_buffer.clear(); // If a single cell is selected, copy it to clipboard if (!withHeaders && indices.size() == 1) { QImage img; QVariant data = m->data(indices.first(), Qt::EditRole); if (img.loadFromData(data.toByteArray())) { // If it's an image, copy the image data to the clipboard qApp->clipboard()->setImage(img); return; } else { // It it's not an image, check if it's an empty field if (data.toByteArray().isEmpty()) { // The field is either NULL or empty. Those are are handled via the internal copy-paste buffer qApp->clipboard()->setText(QString()); // Calling clear() alone doesn't seem to work on all systems qApp->clipboard()->clear(); m_buffer.push_back(QByteArrayList{data.toByteArray()}); return; } // The field isn't empty. Copy the text to the clipboard without quoting (for general plain text clipboard) qApp->clipboard()->setText(data.toByteArray()); return; } } // If we got here, there are multiple selected cells, or copy with headers was requested. // In this case, we copy selected data into internal copy-paste buffer and then // we write a table both in HTML and text formats to the system clipboard. // Copy selected data into internal copy-paste buffer int last_row = indices.first().row(); QByteArrayList lst; for(int i=0;i<indices.size();i++) { if(indices.at(i).row() != last_row) { m_buffer.push_back(lst); lst.clear(); } lst << indices.at(i).data(Qt::EditRole).toByteArray(); last_row = indices.at(i).row(); } m_buffer.push_back(lst); QString result; QString htmlResult = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"; htmlResult.append("<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"); htmlResult.append("<title></title>"); // The generator-stamp is later used to know whether the data in the system clipboard is still ours. // In that case we will give precedence to our internal copy buffer. QString now = QDateTime::currentDateTime().toString("YYYY-MM-DDTHH:mm:ss.zzz"); m_generatorStamp = QString("<meta name=\"generator\" content=\"%1\"><meta name=\"date\" content=\"%2\">").arg(QApplication::applicationName().toHtmlEscaped(), now); htmlResult.append(m_generatorStamp); // TODO: is this really needed by Excel, since we use <pre> for multi-line cells? htmlResult.append("<style type=\"text/css\">br{mso-data-placement:same-cell;}</style></head><body><table>"); int currentRow = indices.first().row(); const QString fieldSepHtml = "</td><td>"; const QString rowSepHtml = "</td></tr><tr><td>"; const QString fieldSepText = "\t"; const QString rowSepText = "\r\n"; // Table headers if (withHeaders) { htmlResult.append("<tr><th>"); int firstColumn = indices.front().column(); for(int i = firstColumn; i <= indices.back().column(); i++) { QByteArray headerText = model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toByteArray(); if (i != firstColumn) { result.append(fieldSepText); htmlResult.append("</th><th>"); } result.append(escapeCopiedData(headerText)); htmlResult.append(headerText); } result.append(rowSepText); htmlResult.append("</th></tr>"); } // Table data rows for(const QModelIndex& index : indices) { // Separators. For first cell, only opening table row tags must be added for the HTML and nothing for the text version. if (indices.first() == index) htmlResult.append("<tr><td>"); else if (index.row() != currentRow) { result.append(rowSepText); htmlResult.append(rowSepHtml); } else { result.append(fieldSepText); htmlResult.append(fieldSepHtml); } currentRow = index.row(); QImage img; QVariant data = index.data(Qt::EditRole); // Table cell data: image? Store it as an embedded image in HTML and as base 64 in text version if (img.loadFromData(data.toByteArray())) { QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); img.save(&buffer, "PNG"); buffer.close(); QString imageBase64 = ba.toBase64(); htmlResult.append("<img src=\"data:image/png;base64,"); htmlResult.append(imageBase64); result.append(QString()); htmlResult.append("\" alt=\"Image\">"); } else { QByteArray text; if (!m->isBinary(index)) text = data.toByteArray(); // Table cell data: text if (text.contains('\n') || text.contains('\t')) htmlResult.append("<pre>" + QString(text).toHtmlEscaped() + "</pre>"); else htmlResult.append(QString(text).toHtmlEscaped()); result.append(escapeCopiedData(text)); } } QMimeData *mimeData = new QMimeData; mimeData->setHtml(htmlResult + "</td></tr></table></body></html>"); mimeData->setText(result); qApp->clipboard()->setMimeData(mimeData); }
Playlist::Playlist(QWidget *parent) : QTableWidget(parent), track(-1) { // Initialize values for the Header (label and horizontal resize mode) QStringList labels = (QStringList() << "#" << tr("Title") << tr("Album") << tr("Length") << tr("Artist") << tr("Rating") << tr("Year")); const QStringList untranslatedLabels = (QStringList() << "#" << "Title" << "Album" << "Length" << "Artist" << "Rating" << "Year"); // Test: 0 = Fixed, n>0 = real ratio for each column const QList<int> ratios(QList<int>() << 0 << 5 << 4 << 1 << 3 << 0 << 0); this->setColumnCount(labels.size()); this->setColumnHidden(5, true); this->setColumnHidden(6, true); this->setShowGrid(false); Settings *settings = Settings::getInstance(); this->setStyleSheet(settings->styleSheet(this)); this->verticalScrollBar()->setStyleSheet(settings->styleSheet(this->verticalScrollBar())); this->setAlternatingRowColors(settings->colorsAlternateBG()); // Select only one row, not cell by cell this->setSelectionMode(QAbstractItemView::ExtendedSelection); this->setSelectionBehavior(QAbstractItemView::SelectRows); this->setItemDelegate(new NoFocusItemDelegate(this)); /// test this->setAcceptDrops(true); verticalHeader()->setVisible(false); this->setHorizontalHeader(new QHeaderView(Qt::Horizontal, this)); horizontalHeader()->setStyleSheet(settings->styleSheet(horizontalHeader())); horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); horizontalHeader()->setHighlightSections(false); horizontalHeader()->setMovable(true); this->installEventFilter(horizontalHeader()); // Context menu on header of columns QList<QAction*> actionColumns; columns = new QMenu(this); for (int i = 0; i < labels.size(); i++) { QString label = labels.at(i); QTableWidgetItem *item = new QTableWidgetItem(label); // Stores original text to switch between translations on the fly // Might evolve latter, start to be "unreadable" item->setData(Qt::UserRole+1, untranslatedLabels.at(i)); item->setData(Qt::UserRole+2, ratios.at(i)); this->setHorizontalHeaderItem(i, item); // Match actions with columns using index of labels QAction *actionColumn = new QAction(label, this); actionColumn->setData(i); actionColumn->setEnabled(actionColumn->text() != tr("Title")); actionColumn->setCheckable(true); actionColumn->setChecked(!isColumnHidden(i)); actionColumns.append(actionColumn); // Then populate the context menu columns->addAction(actionColumn); } // Load columns state QByteArray state = settings->value("playlistColumnsState").toByteArray(); if (!state.isEmpty()) { horizontalHeader()->restoreState(state); for (int i = 0; i < horizontalHeader()->count(); i++) { bool hidden = horizontalHeader()->isSectionHidden(i); setColumnHidden(i, hidden); columns->actions().at(i)->setChecked(!hidden); } } // Link this playlist with the Settings instance to change fonts at runtime connect(settings, SIGNAL(currentFontChanged()), this, SLOT(highlightCurrentTrack())); // Change track // no need to cast parent as a TabPlaylist instance connect(this, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), parent, SLOT(changeTrack(QTableWidgetItem*))); // Hide the selected column in context menu connect(horizontalHeader(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showColumnsMenu(QPoint))); connect(columns, SIGNAL(triggered(QAction*)), this, SLOT(toggleSelectedColumn(QAction*))); connect(horizontalHeader(), SIGNAL(sectionMoved(int,int,int)), this, SLOT(saveColumnsState(int,int,int))); }
TrackerList::TrackerList(PropertiesWidget *properties) : QTreeWidget() , m_properties(properties) { // Set header // Must be set before calling loadSettings() otherwise the header is reset on restart setHeaderLabels(headerLabels()); // Load settings loadSettings(); // Graphical settings setRootIsDecorated(false); setAllColumnsShowFocus(true); setItemsExpandable(false); setSelectionMode(QAbstractItemView::ExtendedSelection); header()->setStretchLastSection(false); // Must be set after loadSettings() in order to work // Ensure that at least one column is visible at all times if (visibleColumnsCount() == 0) setColumnHidden(COL_URL, false); // To also mitigate the above issue, we have to resize each column when // its size is 0, because explicitly 'showing' the column isn't enough // in the above scenario. for (unsigned int i = 0; i < COL_COUNT; ++i) if ((columnWidth(i) <= 0) && !isColumnHidden(i)) resizeColumnToContents(i); // Context menu setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showTrackerListMenu(QPoint))); // Header context menu header()->setContextMenuPolicy(Qt::CustomContextMenu); connect(header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayToggleColumnsMenu(const QPoint&))); // Set DHT, PeX, LSD items m_DHTItem = new QTreeWidgetItem({ "", "** [DHT] **", "", "0", "", "", "0" }); insertTopLevelItem(0, m_DHTItem); setRowColor(0, QColor("grey")); m_PEXItem = new QTreeWidgetItem({ "", "** [PeX] **", "", "0", "", "", "0" }); insertTopLevelItem(1, m_PEXItem); setRowColor(1, QColor("grey")); m_LSDItem = new QTreeWidgetItem({ "", "** [LSD] **", "", "0", "", "", "0" }); insertTopLevelItem(2, m_LSDItem); setRowColor(2, QColor("grey")); // Set static items alignment m_DHTItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter)); m_PEXItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter)); m_LSDItem->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter)); m_DHTItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); m_PEXItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); m_LSDItem->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); m_DHTItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); m_PEXItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); m_LSDItem->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); m_DHTItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); m_PEXItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); m_LSDItem->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); // Set header alignment headerItem()->setTextAlignment(COL_TIER, (Qt::AlignRight | Qt::AlignVCenter)); headerItem()->setTextAlignment(COL_RECEIVED, (Qt::AlignRight | Qt::AlignVCenter)); headerItem()->setTextAlignment(COL_SEEDS, (Qt::AlignRight | Qt::AlignVCenter)); headerItem()->setTextAlignment(COL_PEERS, (Qt::AlignRight | Qt::AlignVCenter)); headerItem()->setTextAlignment(COL_DOWNLOADED, (Qt::AlignRight | Qt::AlignVCenter)); // Set hotkeys m_editHotkey = new QShortcut(Qt::Key_F2, this, SLOT(editSelectedTracker()), 0, Qt::WidgetShortcut); connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(editSelectedTracker())); m_deleteHotkey = new QShortcut(QKeySequence::Delete, this, SLOT(deleteSelectedTrackers()), 0, Qt::WidgetShortcut); m_copyHotkey = new QShortcut(QKeySequence::Copy, this, SLOT(copyTrackerUrl()), 0, Qt::WidgetShortcut); // This hack fixes reordering of first column with Qt5. // https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777 QTableView unused; unused.setVerticalHeader(header()); header()->setParent(this); unused.setVerticalHeader(new QHeaderView(Qt::Horizontal)); }