forked from osmocom/wireshark
RTP Stream Analysis: Process more streams than two, audio save removed
This commit is contained in:
parent
fe7bf413fc
commit
2b072b8e76
|
@ -77,6 +77,7 @@
|
|||
#include <ui/qt/models/pref_models.h>
|
||||
#include "rtp_stream_dialog.h"
|
||||
#include "voip_calls_dialog.h"
|
||||
#include "rtp_analysis_dialog.h"
|
||||
|
||||
class AccordionFrame;
|
||||
class ByteViewTab;
|
||||
|
@ -250,6 +251,7 @@ private:
|
|||
QPointer<VoipCallsDialog> voip_calls_dialog_; // Singleton pattern used
|
||||
QPointer<VoipCallsDialog> sip_calls_dialog_; // Singleton pattern used
|
||||
QPointer<RtpPlayerDialog> rtp_player_dialog_; // Singleton pattern used
|
||||
QPointer<RtpAnalysisDialog> rtp_analysis_dialog_; // Singleton pattern used
|
||||
|
||||
void freeze();
|
||||
void thaw();
|
||||
|
@ -312,9 +314,6 @@ signals:
|
|||
void framesSelected(QList<int>);
|
||||
|
||||
void captureActive(int);
|
||||
void replaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void addRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void removeRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void selectRtpStream(rtpstream_id_t *id);
|
||||
void deselectRtpStream(rtpstream_id_t *id);
|
||||
|
||||
|
@ -367,6 +366,9 @@ public slots:
|
|||
void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpStreamsDialogSelectRtpStream(rtpstream_id_t *id);
|
||||
void rtpStreamsDialogDeselectRtpStream(rtpstream_id_t *id);
|
||||
|
||||
|
@ -686,6 +688,7 @@ private slots:
|
|||
void openTelephonyRtpStreamsDialog();
|
||||
void openTelephonyRtpPlayerDialog();
|
||||
void openTelephonyVoipCallsDialog(bool all_flows);
|
||||
void openTelephonyRtpAnalysisDialog();
|
||||
void on_actionTelephonyVoipCalls_triggered();
|
||||
void on_actionTelephonyGsmMapSummary_triggered();
|
||||
void statCommandLteMacStatistics(const char *arg, void *);
|
||||
|
|
|
@ -3311,12 +3311,6 @@ void MainWindow::openTelephonyRtpPlayerDialog()
|
|||
|
||||
connect(rtp_player_dialog_, SIGNAL(goToPacket(int)),
|
||||
packet_list_, SLOT(goToPacket(int)));
|
||||
connect(this, SIGNAL(replaceRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
rtp_player_dialog_, SLOT(replaceRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(this, SIGNAL(addRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
rtp_player_dialog_, SLOT(addRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(this, SIGNAL(removeRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
rtp_player_dialog_, SLOT(removeRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
}
|
||||
rtp_player_dialog_->show();
|
||||
}
|
||||
|
@ -3356,6 +3350,23 @@ void MainWindow::openTelephonyVoipCallsDialog(bool all_flows)
|
|||
dlg->show();
|
||||
}
|
||||
|
||||
void MainWindow::openTelephonyRtpAnalysisDialog()
|
||||
{
|
||||
if (!rtp_analysis_dialog_) {
|
||||
rtp_analysis_dialog_ = new RtpAnalysisDialog(*this, capture_file_);
|
||||
|
||||
connect(rtp_analysis_dialog_, SIGNAL(goToPacket(int)),
|
||||
packet_list_, SLOT(goToPacket(int)));
|
||||
connect(rtp_analysis_dialog_, SIGNAL(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(rtp_analysis_dialog_, SIGNAL(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(rtp_analysis_dialog_, SIGNAL(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
}
|
||||
rtp_analysis_dialog_->show();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionTelephonyVoipCalls_triggered()
|
||||
{
|
||||
openTelephonyVoipCallsDialog(false);
|
||||
|
@ -3447,7 +3458,6 @@ void MainWindow::openTelephonyRtpStreamsDialog()
|
|||
{
|
||||
if (!rtp_stream_dialog_) {
|
||||
rtp_stream_dialog_ = new RtpStreamDialog(*this, capture_file_);
|
||||
|
||||
connect(rtp_stream_dialog_, SIGNAL(packetsMarked()),
|
||||
packet_list_, SLOT(redrawVisiblePackets()));
|
||||
connect(rtp_stream_dialog_, SIGNAL(goToPacket(int)),
|
||||
|
@ -3462,8 +3472,12 @@ void MainWindow::openTelephonyRtpStreamsDialog()
|
|||
this, SLOT(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(rtp_stream_dialog_, SIGNAL(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(this, SIGNAL(selectRtpStream(rtpstream_id_t *)), rtp_stream_dialog_, SLOT(selectRtpStream(rtpstream_id_t *)));
|
||||
connect(this, SIGNAL(deselectRtpStream(rtpstream_id_t *)), rtp_stream_dialog_, SLOT(deselectRtpStream(rtpstream_id_t *)));
|
||||
connect(rtp_stream_dialog_, SIGNAL(rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(rtp_stream_dialog_, SIGNAL(rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(rtp_stream_dialog_, SIGNAL(rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
}
|
||||
rtp_stream_dialog_->show();
|
||||
}
|
||||
|
@ -3475,16 +3489,8 @@ void MainWindow::on_actionTelephonyRtpStreams_triggered()
|
|||
|
||||
void MainWindow::on_actionTelephonyRtpStreamAnalysis_triggered()
|
||||
{
|
||||
RtpAnalysisDialog *rtp_analysis_dialog = new RtpAnalysisDialog(*this, capture_file_);
|
||||
connect(rtp_analysis_dialog, SIGNAL(goToPacket(int)),
|
||||
packet_list_, SLOT(goToPacket(int)));
|
||||
connect(rtp_analysis_dialog, SIGNAL(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(rtp_analysis_dialog, SIGNAL(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
connect(rtp_analysis_dialog, SIGNAL(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)),
|
||||
this, SLOT(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)));
|
||||
rtp_analysis_dialog->show();
|
||||
openTelephonyRtpAnalysisDialog();
|
||||
rtp_analysis_dialog_->findRtpStreams();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionTelephonyRTSPPacketCounter_triggered()
|
||||
|
@ -4061,31 +4067,49 @@ void MainWindow::activatePluginIFToolbar(bool)
|
|||
void MainWindow::rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos)
|
||||
{
|
||||
openTelephonyRtpPlayerDialog();
|
||||
emit replaceRtpStreams(stream_infos);
|
||||
rtp_player_dialog_->replaceRtpStreams(stream_infos);
|
||||
}
|
||||
|
||||
void MainWindow::rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos)
|
||||
{
|
||||
openTelephonyRtpPlayerDialog();
|
||||
emit addRtpStreams(stream_infos);
|
||||
rtp_player_dialog_->addRtpStreams(stream_infos);
|
||||
}
|
||||
|
||||
void MainWindow::rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos)
|
||||
{
|
||||
openTelephonyRtpPlayerDialog();
|
||||
emit removeRtpStreams(stream_infos);
|
||||
rtp_player_dialog_->removeRtpStreams(stream_infos);
|
||||
}
|
||||
|
||||
void MainWindow::rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos)
|
||||
{
|
||||
openTelephonyRtpAnalysisDialog();
|
||||
rtp_analysis_dialog_->replaceRtpStreams(stream_infos);
|
||||
}
|
||||
|
||||
void MainWindow::rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos)
|
||||
{
|
||||
openTelephonyRtpAnalysisDialog();
|
||||
rtp_analysis_dialog_->addRtpStreams(stream_infos);
|
||||
}
|
||||
|
||||
void MainWindow::rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos)
|
||||
{
|
||||
openTelephonyRtpAnalysisDialog();
|
||||
rtp_analysis_dialog_->removeRtpStreams(stream_infos);
|
||||
}
|
||||
|
||||
void MainWindow::rtpStreamsDialogSelectRtpStream(rtpstream_id_t *id)
|
||||
{
|
||||
openTelephonyRtpStreamsDialog();
|
||||
emit selectRtpStream(id);
|
||||
rtp_stream_dialog_->selectRtpStream(id);
|
||||
}
|
||||
|
||||
void MainWindow::rtpStreamsDialogDeselectRtpStream(rtpstream_id_t *id)
|
||||
{
|
||||
openTelephonyRtpStreamsDialog();
|
||||
emit deselectRtpStream(id);
|
||||
rtp_stream_dialog_->deselectRtpStream(id);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,9 +20,12 @@
|
|||
#include "ui/tap-rtp-common.h"
|
||||
#include "ui/tap-rtp-analysis.h"
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QMenu>
|
||||
#include <QTreeWidget>
|
||||
#include <QLabel>
|
||||
#include <QFile>
|
||||
#include <QCheckBox>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#include "wireshark_dialog.h"
|
||||
|
||||
|
@ -32,6 +35,26 @@ class RtpAnalysisDialog;
|
|||
|
||||
class QCPGraph;
|
||||
class QTemporaryFile;
|
||||
class QDialogButtonBox;
|
||||
|
||||
typedef struct {
|
||||
rtpstream_info_t stream;
|
||||
QVector<double> *time_vals;
|
||||
QVector<double> *jitter_vals;
|
||||
QVector<double> *diff_vals;
|
||||
QVector<double> *delta_vals;
|
||||
QTreeWidget *tree_widget;
|
||||
QLabel *statistics_label;
|
||||
QString *tab_name;
|
||||
QCPGraph *jitter_graph;
|
||||
QCPGraph *diff_graph;
|
||||
QCPGraph *delta_graph;
|
||||
QHBoxLayout *graphHorizontalLayout;
|
||||
QCheckBox *stream_checkbox;
|
||||
QCheckBox *jitter_checkbox;
|
||||
QCheckBox *diff_checkbox;
|
||||
QCheckBox *delta_checkbox;
|
||||
} tab_info_t;
|
||||
|
||||
class RtpAnalysisDialog : public WiresharkDialog
|
||||
{
|
||||
|
@ -40,6 +63,24 @@ class RtpAnalysisDialog : public WiresharkDialog
|
|||
public:
|
||||
explicit RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, rtpstream_info_t *stream_fwd = 0, rtpstream_info_t *stream_rev = 0);
|
||||
~RtpAnalysisDialog();
|
||||
/**
|
||||
* @brief Common routine to add a "Analyze" button to a QDialogButtonBox.
|
||||
* @param button_box Caller's QDialogButtonBox.
|
||||
* @return The new "Analyze" button.
|
||||
*/
|
||||
static QPushButton *addAnalyzeButton(QDialogButtonBox *button_box, QDialog *dialog);
|
||||
|
||||
/** Replace/Add/Remove an RTP streams to analyse.
|
||||
* Requires array of rtpstream_info_t.
|
||||
* Each item must have filled items: src_addr, src_port, dest_addr,
|
||||
* dest_port, ssrc, packet_count, setup_frame_number, and start_rel_time.
|
||||
*
|
||||
* @param rtpstream struct with rtpstream info
|
||||
*/
|
||||
void replaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void addRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void removeRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void findRtpStreams();
|
||||
|
||||
signals:
|
||||
void goToPacket(int packet_num);
|
||||
|
@ -58,102 +99,54 @@ protected slots:
|
|||
private slots:
|
||||
void on_actionGoToPacket_triggered();
|
||||
void on_actionNextProblem_triggered();
|
||||
void on_fJitterCheckBox_toggled(bool checked);
|
||||
void on_fDiffCheckBox_toggled(bool checked);
|
||||
void on_fDeltaCheckBox_toggled(bool checked);
|
||||
void on_rJitterCheckBox_toggled(bool checked);
|
||||
void on_rDiffCheckBox_toggled(bool checked);
|
||||
void on_rDeltaCheckBox_toggled(bool checked);
|
||||
void on_actionSaveAudioUnsync_triggered();
|
||||
void on_actionSaveForwardAudioUnsync_triggered();
|
||||
void on_actionSaveReverseAudioUnsync_triggered();
|
||||
void on_actionSaveAudioSyncStream_triggered();
|
||||
void on_actionSaveForwardAudioSyncStream_triggered();
|
||||
void on_actionSaveReverseAudioSyncStream_triggered();
|
||||
void on_actionSaveAudioSyncFile_triggered();
|
||||
void on_actionSaveForwardAudioSyncFile_triggered();
|
||||
void on_actionSaveReverseAudioSyncFile_triggered();
|
||||
void on_actionSaveCsv_triggered();
|
||||
void on_actionSaveForwardCsv_triggered();
|
||||
void on_actionSaveReverseCsv_triggered();
|
||||
void on_actionSaveOneCsv_triggered();
|
||||
void on_actionSaveAllCsv_triggered();
|
||||
void on_actionSaveGraph_triggered();
|
||||
void on_buttonBox_helpRequested();
|
||||
void showStreamMenu(QPoint pos);
|
||||
void graphClicked(QMouseEvent *event);
|
||||
void closeTab(int index);
|
||||
void rowCheckboxChanged(int checked);
|
||||
void singleCheckboxChanged(int checked);
|
||||
|
||||
private:
|
||||
Ui::RtpAnalysisDialog *ui;
|
||||
enum StreamDirection { dir_both_, dir_forward_, dir_reverse_ };
|
||||
enum SyncType { sync_unsync_, sync_sync_stream_, sync_sync_file_ };
|
||||
enum StreamDirection { dir_all_, dir_one_ };
|
||||
int tab_seq;
|
||||
|
||||
/* Save Audio Errors */
|
||||
bool sae_stopped_;
|
||||
bool sae_file_error_;
|
||||
bool sae_unsupported_codec_;
|
||||
bool sae_unsupported_rate_;
|
||||
bool sae_other_error_;
|
||||
|
||||
int num_streams_;
|
||||
|
||||
rtpstream_info_t fwd_statinfo_;
|
||||
rtpstream_info_t rev_statinfo_;
|
||||
QVector<tab_info_t *> tabs_;
|
||||
|
||||
QPushButton *player_button_;
|
||||
|
||||
QTemporaryFile *fwd_tempfile_;
|
||||
QTemporaryFile *rev_tempfile_;
|
||||
|
||||
// Graph data for QCustomPlot
|
||||
QList<QCPGraph *>graphs_;
|
||||
QVector<double> fwd_time_vals_;
|
||||
QVector<double> fwd_jitter_vals_;
|
||||
QVector<double> fwd_diff_vals_;
|
||||
QVector<double> fwd_delta_vals_;
|
||||
|
||||
QVector<double> rev_time_vals_;
|
||||
QVector<double> rev_jitter_vals_;
|
||||
QVector<double> rev_diff_vals_;
|
||||
QVector<double> rev_delta_vals_;
|
||||
|
||||
rtpstream_tapinfo_t tapinfo_;
|
||||
QString err_str_;
|
||||
tap_rtp_error_type_t save_payload_error_;
|
||||
|
||||
QMenu stream_ctx_menu_;
|
||||
QMenu graph_ctx_menu_;
|
||||
|
||||
void findStreams();
|
||||
|
||||
// Tap callbacks
|
||||
static void tapReset(void *tapinfo_ptr);
|
||||
static tap_packet_status tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *rtpinfo_ptr);
|
||||
static void tapDraw(void *tapinfo_ptr);
|
||||
|
||||
void resetStatistics();
|
||||
void addPacket(bool forward, packet_info *pinfo, const struct _rtp_info *rtpinfo);
|
||||
void savePayload(QTemporaryFile *tmpfile, tap_rtp_stat_t *statinfo, packet_info *pinfo, const struct _rtp_info *rtpinfo);
|
||||
void addPacket(tab_info_t *tab, packet_info *pinfo, const struct _rtp_info *rtpinfo);
|
||||
void updateStatistics();
|
||||
void updateGraph();
|
||||
|
||||
void showPlayer();
|
||||
|
||||
size_t convert_payload_to_samples(unsigned int payload_type, const gchar *payload_type_names[256], QTemporaryFile *tempfile, uint8_t *pd_out, size_t expected_nchars, struct _GHashTable *decoders_hash);
|
||||
bool saveAudioAUSilence(size_t total_len, QFile *save_file, gboolean *stop_flag);
|
||||
bool saveAudioAUUnidir(tap_rtp_stat_t &statinfo, const gchar *payload_type_names[256], QTemporaryFile *tempfile, QFile *save_file, int64_t header_end, gboolean *stop_flag, gboolean interleave, size_t prefix_silence);
|
||||
bool saveAudioAUBidir(tap_rtp_stat_t &fwd_statinfo, tap_rtp_stat_t &rev_statinfo, const gchar *fwd_payload_type_names[256], const gchar *rev_payload_type_names[256], QTemporaryFile *fwd_tempfile, QTemporaryFile *rev_tempfile, QFile *save_file, int64_t header_end, gboolean *stop_flag, size_t prefix_silence_fwd, size_t prefix_silence_rev);
|
||||
bool saveAudioAU(StreamDirection direction, QFile *save_file, gboolean *stop_flag, RtpAnalysisDialog::SyncType sync);
|
||||
bool saveAudioRAW(StreamDirection direction, QFile *save_file, gboolean *stop_flag);
|
||||
void saveAudio(StreamDirection direction, RtpAnalysisDialog::SyncType sync);
|
||||
void saveCsvData(QFile *save_file, QTreeWidget *tree);
|
||||
void saveCsv(StreamDirection direction);
|
||||
|
||||
uint32_t processNode(proto_node *ptree_node, header_field_info *hfinformation, const gchar* proto_field, bool *ok);
|
||||
uint32_t getIntFromProtoTree(proto_tree *protocol_tree, const gchar *proto_name, const gchar *proto_field, bool *ok);
|
||||
|
||||
bool eventFilter(QObject*, QEvent* event);
|
||||
|
||||
void clearSAEErrors();
|
||||
bool isSAEOK();
|
||||
QVector<rtpstream_info_t *>getSelectedRtpStreams();
|
||||
int addTabUI(tab_info_t *new_tab);
|
||||
tab_info_t *getTabInfoForCurrentTab();
|
||||
void deleteTabInfo(tab_info_t *tab_info);
|
||||
void clearLayout(QLayout *layout);
|
||||
};
|
||||
|
||||
#endif // RTP_ANALYSIS_DIALOG_H
|
||||
|
|
|
@ -16,123 +16,11 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="statisticsLabel">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-size:medium; font-weight:600;">Forward</span></p><p><span style=" font-size:medium; font-weight:600;">Reverse</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QTreeWidget" name="forwardTreeWidget">
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Forward</string>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Packet</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Sequence</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Delta (ms)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Jitter (ms)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Skew</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Bandwidth</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Marker</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Status</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="QTreeWidget" name="reverseTreeWidget">
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Reverse</string>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="QWidget" name="graphTab">
|
||||
<attribute name="title">
|
||||
<string>Graph</string>
|
||||
|
@ -141,152 +29,6 @@
|
|||
<item>
|
||||
<widget class="QCustomPlot" name="streamGraph" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="forwardHorizontalLayout" stretch="0,0,0,0,0,1">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fJitterCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Show or hide forward jitter values.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Forward Jitter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fDiffCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Show or hide forward difference values.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Forward Difference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fDeltaCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Show or hide forward delta values.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Forward Delta</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="reverseHorizontalLayout" stretch="0,0,0,0,0,1">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="rJitterCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Show or hide reverse jitter values.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reverse Jitter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="rDiffCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Show or hide reverse difference values.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reverse Difference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="rDeltaCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Show or hide reverse delta values.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reverse Delta</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -336,52 +78,28 @@
|
|||
<string>Open export menu</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAudioUnsync">
|
||||
<property name="text">
|
||||
<string>Unsynchronized Forward and Reverse Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the unsynchronized audio data for both channels.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveForwardAudioUnsync">
|
||||
<property name="text">
|
||||
<string>Unsynchronized Forward Stream Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the unsynchronized forward stream audio data.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveReverseAudioUnsync">
|
||||
<property name="text">
|
||||
<string>Unsynchronized Reverse Stream Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the unsynchronized reverse stream audio data.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveCsv">
|
||||
<property name="text">
|
||||
<string>CSV</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save both tables as CSV.</string>
|
||||
<string>Save tables as CSV.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveForwardCsv">
|
||||
<action name="actionSaveOneCsv">
|
||||
<property name="text">
|
||||
<string>Forward Stream CSV</string>
|
||||
<string>Current Tab Stream CSV</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the forward table as CSV.</string>
|
||||
<string>Save the table on the current tab as CSV.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveReverseCsv">
|
||||
<action name="actionSaveAllCsv">
|
||||
<property name="text">
|
||||
<string>Reverse Stream CSV</string>
|
||||
<string>All Tab Streams CSV</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the reverse table as CSV.</string>
|
||||
<string>Save the table from all tabs as CSV.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveGraph">
|
||||
|
@ -414,54 +132,6 @@
|
|||
<string>N</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAudioSyncStream">
|
||||
<property name="text">
|
||||
<string>Stream Synchronized Forward and Reverse Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the audio data for both channels synchronized to start of earlier stream.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveForwardAudioSyncStream">
|
||||
<property name="text">
|
||||
<string>Stream Synchronized Forward Stream Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the forward stream audio data synchronized to start of earlier stream.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveReverseAudioSyncStream">
|
||||
<property name="text">
|
||||
<string>Stream Synchronized Reverse Stream Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the reverse stream audio data synchronized to start of earlier stream.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveAudioSyncFile">
|
||||
<property name="text">
|
||||
<string>File Synchronized Forward and Reverse Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the audio data for both channels synchronized to start of file.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveForwardAudioSyncFile">
|
||||
<property name="text">
|
||||
<string>File Synchronized Forward Stream Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the forward stream audio data synchronized to start of file.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveReverseAudioSyncFile">
|
||||
<property name="text">
|
||||
<string>File Synchronized Reverse Stream Audio</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Save the reverse stream audio data synchronized to start of file.</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#ifdef QT_MULTIMEDIA_LIB
|
||||
|
||||
#include <epan/dissectors/packet-rtp.h>
|
||||
#include <epan/to_str.h>
|
||||
|
||||
#include <wsutil/report_message.h>
|
||||
#include <wsutil/utf8_entities.h>
|
||||
|
|
|
@ -62,7 +62,6 @@ public:
|
|||
* @param button_box Caller's QDialogButtonBox.
|
||||
* @return The new "Play call" button.
|
||||
*/
|
||||
// XXX We might want to move this to qt_ui_utils.
|
||||
static QPushButton *addPlayerButton(QDialogButtonBox *button_box, QDialog *dialog);
|
||||
|
||||
#ifdef QT_MULTIMEDIA_LIB
|
||||
|
@ -73,7 +72,6 @@ public:
|
|||
|
||||
void setMarkers();
|
||||
|
||||
public slots:
|
||||
/** Replace/Add/Remove an RTP streams to play.
|
||||
* Requires array of rtpstream_info_t.
|
||||
* Each item must have filled items: src_addr, src_port, dest_addr,
|
||||
|
|
|
@ -273,8 +273,7 @@ RtpStreamDialog::RtpStreamDialog(QWidget &parent, CaptureFile &cf) :
|
|||
// this? Perhaps you should volunteer to maintain this code!
|
||||
find_reverse_button_ = ui->buttonBox->addButton(ui->actionFindReverse->text(), QDialogButtonBox::ActionRole);
|
||||
find_reverse_button_->setToolTip(ui->actionFindReverse->toolTip());
|
||||
analyze_button_ = ui->buttonBox->addButton(ui->actionAnalyze->text(), QDialogButtonBox::ActionRole);
|
||||
analyze_button_->setToolTip(ui->actionAnalyze->toolTip());
|
||||
analyze_button_ = RtpAnalysisDialog::addAnalyzeButton(ui->buttonBox, this);
|
||||
prepare_button_ = ui->buttonBox->addButton(ui->actionPrepareFilter->text(), QDialogButtonBox::ActionRole);
|
||||
prepare_button_->setToolTip(ui->actionPrepareFilter->toolTip());
|
||||
player_button_ = RtpPlayerDialog::addPlayerButton(ui->buttonBox, this);
|
||||
|
@ -619,26 +618,6 @@ void RtpStreamDialog::showStreamMenu(QPoint pos)
|
|||
ctx_menu_.popup(ui->streamTreeWidget->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void RtpStreamDialog::on_actionAnalyze_triggered()
|
||||
{
|
||||
rtpstream_info_t *stream_a, *stream_b = NULL;
|
||||
|
||||
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
|
||||
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
|
||||
stream_a = rsti->streamInfo();
|
||||
if (ui->streamTreeWidget->selectedItems().count() > 1) {
|
||||
ti = ui->streamTreeWidget->selectedItems()[1];
|
||||
rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
|
||||
stream_b = rsti->streamInfo();
|
||||
}
|
||||
|
||||
if (stream_a == NULL && stream_b == NULL) return;
|
||||
|
||||
RtpAnalysisDialog *rtp_analysis_dialog = new RtpAnalysisDialog(*this, cap_file_, stream_a, stream_b);
|
||||
connect(rtp_analysis_dialog, SIGNAL(goToPacket(int)), this, SIGNAL(goToPacket(int)));
|
||||
rtp_analysis_dialog->show();
|
||||
}
|
||||
|
||||
void RtpStreamDialog::on_actionCopyAsCsv_triggered()
|
||||
{
|
||||
QString csv;
|
||||
|
@ -807,8 +786,6 @@ void RtpStreamDialog::on_buttonBox_clicked(QAbstractButton *button)
|
|||
on_actionPrepareFilter_triggered();
|
||||
} else if (button == export_button_) {
|
||||
on_actionExportAsRtpDump_triggered();
|
||||
} else if (button == analyze_button_) {
|
||||
on_actionAnalyze_triggered();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -891,6 +868,27 @@ void RtpStreamDialog::rtpPlayerRemove()
|
|||
emit rtpPlayerDialogRemoveRtpStreams(getSelectedRtpStreams());
|
||||
}
|
||||
|
||||
void RtpStreamDialog::rtpAnalysisReplace()
|
||||
{
|
||||
if (ui->streamTreeWidget->selectedItems().count() < 1) return;
|
||||
|
||||
emit rtpAnalysisDialogReplaceRtpStreams(getSelectedRtpStreams());
|
||||
}
|
||||
|
||||
void RtpStreamDialog::rtpAnalysisAdd()
|
||||
{
|
||||
if (ui->streamTreeWidget->selectedItems().count() < 1) return;
|
||||
|
||||
emit rtpAnalysisDialogAddRtpStreams(getSelectedRtpStreams());
|
||||
}
|
||||
|
||||
void RtpStreamDialog::rtpAnalysisRemove()
|
||||
{
|
||||
if (ui->streamTreeWidget->selectedItems().count() < 1) return;
|
||||
|
||||
emit rtpAnalysisDialogRemoveRtpStreams(getSelectedRtpStreams());
|
||||
}
|
||||
|
||||
void RtpStreamDialog::displayFilterSuccess(bool success)
|
||||
{
|
||||
if (success && ui->displayFilterCheckBox->isChecked()) {
|
||||
|
|
|
@ -29,6 +29,8 @@ class RtpStreamDialog : public WiresharkDialog
|
|||
public:
|
||||
explicit RtpStreamDialog(QWidget &parent, CaptureFile &cf);
|
||||
~RtpStreamDialog();
|
||||
void selectRtpStream(rtpstream_id_t *id);
|
||||
void deselectRtpStream(rtpstream_id_t *id);
|
||||
|
||||
signals:
|
||||
// Tells the packet list to redraw. An alternative might be to add a
|
||||
|
@ -40,14 +42,18 @@ signals:
|
|||
void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
void rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
|
||||
|
||||
public slots:
|
||||
void selectRtpStream(rtpstream_id_t *id);
|
||||
void deselectRtpStream(rtpstream_id_t *id);
|
||||
void displayFilterSuccess(bool success);
|
||||
void rtpPlayerReplace();
|
||||
void rtpPlayerAdd();
|
||||
void rtpPlayerRemove();
|
||||
void rtpAnalysisReplace();
|
||||
void rtpAnalysisAdd();
|
||||
void rtpAnalysisRemove();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
@ -94,7 +100,6 @@ private slots:
|
|||
void on_buttonBox_helpRequested();
|
||||
void on_buttonBox_clicked(QAbstractButton *button);
|
||||
void on_actionExportAsRtpDump_triggered();
|
||||
void on_actionAnalyze_triggered();
|
||||
void captureEvent(CaptureEvent e);
|
||||
void on_displayFilterCheckBox_toggled(bool checked);
|
||||
void on_todCheckBox_toggled(bool checked);
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <QFontMetrics>
|
||||
#include <QMap>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
|
||||
|
@ -170,6 +171,78 @@ QIcon StockIcon::colorIcon(const QRgb bg_color, const QRgb fg_color, const QStri
|
|||
return color_icon;
|
||||
}
|
||||
|
||||
// Create a triangle icon filled with the specified color.
|
||||
QIcon StockIcon::colorIconTriangle(const QRgb bg_color, const QRgb fg_color)
|
||||
{
|
||||
QList<int> sizes = QList<int>() << 12 << 16 << 24 << 32 << 48;
|
||||
QIcon color_icon;
|
||||
|
||||
foreach (int size, sizes) {
|
||||
QPixmap pm(size, size);
|
||||
QPainter painter(&pm);
|
||||
QPainterPath triangle;
|
||||
pm.fill();
|
||||
painter.fillRect(0, 0, size-1, size-1, Qt::transparent);
|
||||
painter.setPen(fg_color);
|
||||
painter.setBrush(QColor(bg_color));
|
||||
triangle.moveTo(0, size-1);
|
||||
triangle.lineTo(size-1, size-1);
|
||||
triangle.lineTo((size-1)/2, 0);
|
||||
triangle.closeSubpath();
|
||||
painter.fillPath(triangle, QColor(bg_color));
|
||||
|
||||
color_icon.addPixmap(pm);
|
||||
}
|
||||
return color_icon;
|
||||
}
|
||||
|
||||
// Create a cross icon filled with the specified color.
|
||||
QIcon StockIcon::colorIconCross(const QRgb bg_color, const QRgb fg_color)
|
||||
{
|
||||
QList<int> sizes = QList<int>() << 12 << 16 << 24 << 32 << 48;
|
||||
QIcon color_icon;
|
||||
|
||||
foreach (int size, sizes) {
|
||||
QPixmap pm(size, size);
|
||||
QPainter painter(&pm);
|
||||
QPainterPath cross;
|
||||
pm.fill();
|
||||
painter.fillRect(0, 0, size-1, size-1, Qt::transparent);
|
||||
painter.setPen(QPen(QBrush(bg_color), 3));
|
||||
painter.setBrush(QColor(fg_color));
|
||||
cross.moveTo(0, 0);
|
||||
cross.lineTo(size-1, size-1);
|
||||
cross.moveTo(0, size-1);
|
||||
cross.lineTo(size-1, 0);
|
||||
painter.drawPath(cross);
|
||||
|
||||
color_icon.addPixmap(pm);
|
||||
}
|
||||
return color_icon;
|
||||
}
|
||||
|
||||
// Create a circle icon filled with the specified color.
|
||||
QIcon StockIcon::colorIconCircle(const QRgb bg_color, const QRgb fg_color)
|
||||
{
|
||||
QList<int> sizes = QList<int>() << 12 << 16 << 24 << 32 << 48;
|
||||
QIcon color_icon;
|
||||
|
||||
foreach (int size, sizes) {
|
||||
QPixmap pm(size, size);
|
||||
QPainter painter(&pm);
|
||||
QRect border(2, 2, size - 3, size - 3);
|
||||
pm.fill();
|
||||
painter.fillRect(0, 0, size-1, size-1, Qt::transparent);
|
||||
painter.setPen(QPen(QBrush(bg_color), 3));
|
||||
painter.setBrush(QColor(fg_color));
|
||||
painter.setBrush(QColor(bg_color));
|
||||
painter.drawEllipse(border);
|
||||
|
||||
color_icon.addPixmap(pm);
|
||||
}
|
||||
return color_icon;
|
||||
}
|
||||
|
||||
void StockIcon::fillIconNameMap()
|
||||
{
|
||||
// Note that some of Qt's standard pixmaps are awful. We shouldn't add an
|
||||
|
|
|
@ -29,6 +29,9 @@ public:
|
|||
explicit StockIcon(const QString icon_name);
|
||||
|
||||
static QIcon colorIcon(const QRgb bg_color, const QRgb fg_color, const QString glyph = QString());
|
||||
static QIcon colorIconTriangle(const QRgb bg_color, const QRgb fg_color);
|
||||
static QIcon colorIconCross(const QRgb bg_color, const QRgb fg_color);
|
||||
static QIcon colorIconCircle(const QRgb bg_color, const QRgb fg_color);
|
||||
|
||||
private:
|
||||
void fillIconNameMap();
|
||||
|
|
Loading…
Reference in New Issue