ui->columnTreeWidget->setDropIndicatorShown(true);
ui->columnTreeWidget->setDragDropMode(QAbstractItemView::InternalMove);
+ for (GList *cur = g_list_first(prefs.col_list); cur != NULL && cur->data != NULL; cur = cur->next) {
+ fmt_data *cfmt = (fmt_data *) cur->data;
+ addColumn(cfmt->visible, cfmt->title, cfmt->fmt, cfmt->custom_field, cfmt->custom_occurrence);
+ }
+
+ connect(ui->columnTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(updateWidgets()));
+
+ if (prefs.num_cols > 0) {
+ ui->columnTreeWidget->topLevelItem(0)->setSelected(true);
+ }
+
updateWidgets();
}
item->setText(custom_field_col_, custom_field);
item->setText(custom_occurrence_col_, QString::number(custom_occurrence));
}
+
+ updateWidgets();
}
void ColumnPreferencesFrame::updateWidgets()
{
- ui->columnTreeWidget->clear();
-
- for (GList *cur = g_list_first(prefs.col_list); cur != NULL && cur->data != NULL; cur = cur->next) {
- fmt_data *cfmt = (fmt_data *) cur->data;
- addColumn(cfmt->visible, cfmt->title, cfmt->fmt, cfmt->custom_field, cfmt->custom_occurrence);
- }
-
ui->columnTreeWidget->resizeColumnToContents(visible_col_);
ui->columnTreeWidget->resizeColumnToContents(title_col_);
ui->columnTreeWidget->resizeColumnToContents(type_col_);
+
+ ui->deleteToolButton->setEnabled(ui->columnTreeWidget->selectedItems().count() > 0 && ui->columnTreeWidget->topLevelItemCount() > 1);
}
-void ColumnPreferencesFrame::on_columnTreeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+void ColumnPreferencesFrame::on_columnTreeWidget_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *previous)
{
- ui->deleteToolButton->setEnabled(current ? true : false);
-
if (previous && ui->columnTreeWidget->itemWidget(previous, title_col_)) {
ui->columnTreeWidget->removeItemWidget(previous, title_col_);
}
if (previous && ui->columnTreeWidget->itemWidget(previous, custom_occurrence_col_)) {
ui->columnTreeWidget->removeItemWidget(previous, custom_occurrence_col_);
}
+
+ updateWidgets();
}
void ColumnPreferencesFrame::on_columnTreeWidget_itemActivated(QTreeWidgetItem *item, int column)
void ColumnPreferencesFrame::on_deleteToolButton_clicked()
{
+ if (ui->columnTreeWidget->topLevelItemCount() < 2) return;
+
QTreeWidgetItem *item = ui->columnTreeWidget->currentItem();
if (item) {
ui->columnTreeWidget->invisibleRootItem()->removeChild(item);
}
+
+ updateWidgets();
}
/*
int saved_combo_idx_;
void addColumn(bool visible, const char *title, int fmt, const char *custom_field, int custom_occurrence);
- void updateWidgets(void);
private slots:
- void on_columnTreeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
+ void updateWidgets(void);
+ void on_columnTreeWidget_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *previous);
void on_columnTreeWidget_itemActivated(QTreeWidgetItem *item, int column);
void lineEditDestroyed();
void comboDestroyed();
connect(wsApp, SIGNAL(recentFilesRead()),
packet_list_, SLOT(applyRecentColumnWidths()));
connect(wsApp, SIGNAL(columnsChanged()),
- packet_list_, SLOT(redrawVisiblePackets()));
+ packet_list_, SLOT(columnsChanged()));
connect(wsApp, SIGNAL(recentFilesRead()),
this, SLOT(applyRecentPaneGeometry()));
connect(wsApp, SIGNAL(packetDissectionChanged()),
colnr = column_prefs_add_custom(COL_CUSTOM, capture_file_.capFile()->finfo_selected->hfinfo->name,
capture_file_.capFile()->finfo_selected->hfinfo->abbrev,0);
- packet_list_->redrawVisiblePackets();
+ packet_list_->columnsChanged();
packet_list_->resizeColumnToContents(colnr);
prefs_main_write();
#include <QTreeWidget>
// To do:
-// - Catch column reordering and rebuild the column list accoringly.
// - Use a timer to trigger automatic scrolling.
// If we ever add the ability to open multiple capture files we might be
this, SLOT(showHeaderMenu(QPoint)));
connect(header(), SIGNAL(sectionResized(int,int,int)),
this, SLOT(sectionResized(int,int,int)));
+ connect(header(), SIGNAL(sectionMoved(int,int,int)),
+ this, SLOT(sectionMoved(int,int,int)));
connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(vScrollBarActionTriggered(int)));
}
}
-// Redraw the packet list and detail. Called from many places, including
-// columnsChanged.
+// Redraw the packet list and detail. Called from many places.
// XXX We previously re-selected the packet here, but that seems to cause
// automatic scrolling problems.
void PacketList::redrawVisiblePackets() {
proto_tree_->fillProtocolTree(cap_file_->edt->tree);
}
+ update();
+ header()->update();
+}
+
+// prefs.col_list has changed.
+void PacketList::columnsChanged()
+{
+ if (!cap_file_) return;
+
prefs.num_cols = g_list_length(prefs.col_list);
col_cleanup(&cap_file_->cinfo);
build_column_format_array(&cap_file_->cinfo, prefs.num_cols, FALSE);
+ packet_list_model_->recreateVisibleRows(); // Calls PacketListRecord::resetColumns
setColumnVisibility();
-
- update();
- header()->update();
+ redrawVisiblePackets();
}
// Column widths should
header_actions_[caResolveNames]->setChecked(can_resolve && get_column_resolved(header_ctx_column_));
header_actions_[caResolveNames]->setEnabled(can_resolve);
+ header_actions_[caRemoveColumn]->setEnabled(header_ctx_column_ >= 0 && header()->count() > 2);
+
foreach (QAction *action, show_hide_actions_) {
header_ctx_menu_.removeAction(action);
delete action;
hideColumn(header_ctx_column_);
break;
case caRemoveColumn:
- column_prefs_remove_nth(header_ctx_column_);
- if (!prefs.gui_use_pref_save) {
- prefs_main_write();
+ {
+ if (header()->count() > 2) {
+ column_prefs_remove_nth(header_ctx_column_);
+ columnsChanged();
+ if (!prefs.gui_use_pref_save) {
+ prefs_main_write();
+ }
}
- setColumnVisibility();
- redraw = true;
break;
+ }
default:
break;
}
}
}
+// The user moved a column. Make sure prefs.col_list, the column format
+// array, and the header's visual and logical indices all agree.
+// gtk/packet_list.c:column_dnd_changed_cb
+void PacketList::sectionMoved(int, int, int)
+{
+ GList *new_col_list = NULL;
+ QList<int> saved_sizes;
+
+ // Build a new column list based on the header's logical order.
+ for (int vis_idx = 0; vis_idx < header()->count(); vis_idx++) {
+ int log_idx = header()->logicalIndex(vis_idx);
+ saved_sizes << header()->sectionSize(log_idx);
+
+ void *pref_data = g_list_nth_data(prefs.col_list, log_idx);
+ if (!pref_data) continue;
+
+ new_col_list = g_list_append(new_col_list, pref_data);
+ }
+
+ // Clear and rebuild our (and the header's) model. There doesn't appear
+ // to be another way to reset the logical index.
+ freeze();
+
+ g_list_free(prefs.col_list);
+ prefs.col_list = new_col_list;
+
+ thaw();
+
+ for (int i = 0; i < saved_sizes.length(); i++) {
+ if (saved_sizes[i] < 1) continue;
+ header()->resizeSection(i, saved_sizes[i]);
+ }
+
+ if (!prefs.gui_use_pref_save) {
+ prefs_main_write();
+ }
+
+ wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged);
+}
+
// We need to tell when the user has scrolled the packet list, either to
// the end or anywhere other than the end.
void PacketList::vScrollBarActionTriggered(int)
void setTimeReference();
void unsetAllTimeReferences();
void redrawVisiblePackets();
+ void columnsChanged();
void applyRecentColumnWidths();
private slots:
void headerMenuTriggered();
void columnVisibilityTriggered();
void sectionResized(int col, int, int new_width);
+ void sectionMoved(int, int, int);
void vScrollBarActionTriggered(int);
};