00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <QTimer>
00029
00030 #include "circuitlistwidget.h"
00031
00032 #define CLOSED_CIRCUIT_REMOVE_DELAY 3000
00033 #define FAILED_CIRCUIT_REMOVE_DELAY 5000
00034 #define CLOSED_STREAM_REMOVE_DELAY 3000
00035 #define FAILED_STREAM_REMOVE_DELAY 4000
00036
00037
00038
00039 CircuitListWidget::CircuitListWidget(QWidget *parent)
00040 : QTreeWidget(parent)
00041 {
00042
00043 setHeaderLabels(QStringList() << tr("Connection") << tr("Status"));
00044
00045
00046 connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
00047 this, SLOT(onSelectionChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
00048 }
00049
00050
00051
00052 void
00053 CircuitListWidget::addCircuit(Circuit circuit)
00054 {
00055
00056 CircuitItem *item = findCircuitItem(circuit.id());
00057
00058 if (!item) {
00059
00060 item = new CircuitItem(circuit);
00061 addTopLevelItem(item);
00062 } else {
00063
00064 item->update(circuit);
00065 }
00066
00067
00068 Circuit::Status status = circuit.status();
00069 if (status == Circuit::Closed) {
00070 scheduleCircuitRemoval(item, CLOSED_CIRCUIT_REMOVE_DELAY);
00071 } else if (status == Circuit::Failed) {
00072 scheduleCircuitRemoval(item, FAILED_CIRCUIT_REMOVE_DELAY);
00073 }
00074 }
00075
00076
00077
00078 void
00079 CircuitListWidget::addStream(Stream stream)
00080 {
00081
00082 StreamItem *item = findStreamItem(stream.id());
00083
00084 if (!item) {
00085 CircuitItem *circuit = findCircuitItem(stream.circuitId());
00086
00087 if (circuit) {
00088 circuit->addStream(new StreamItem(stream));
00089 expandItem(circuit);
00090 }
00091 } else {
00092
00093 item->update(stream);
00094
00095
00096 Stream::Status status = stream.status();
00097 if (status == Stream::Closed) {
00098 scheduleStreamRemoval(item, CLOSED_STREAM_REMOVE_DELAY);
00099 } else if (status == Stream::Failed) {
00100 scheduleStreamRemoval(item, FAILED_STREAM_REMOVE_DELAY);
00101 }
00102 }
00103 }
00104
00105
00106 void
00107 CircuitListWidget::scheduleCircuitRemoval(CircuitItem *circuit, int delay)
00108 {
00109 if (!_circuitRemovalList.contains(circuit)) {
00110 _circuitRemovalList << circuit;
00111 QTimer::singleShot(delay, this, SLOT(removeCircuit()));
00112 }
00113 }
00114
00115
00116 void
00117 CircuitListWidget::scheduleStreamRemoval(StreamItem *stream, int delay)
00118 {
00119 if (!_streamRemovalList.contains(stream)) {
00120 _streamRemovalList << stream;
00121 QTimer::singleShot(delay, this, SLOT(removeStream()));
00122 }
00123 }
00124
00125
00126 void
00127 CircuitListWidget::removeCircuit()
00128 {
00129 if (!_circuitRemovalList.isEmpty()) {
00130 CircuitItem *circuitItem = _circuitRemovalList.takeFirst();
00131 Circuit circuit = circuitItem->circuit();
00132 removeCircuit(circuitItem);
00133 emit circuitRemoved(circuit.id());
00134 }
00135 }
00136
00137
00138 void
00139 CircuitListWidget::removeCircuit(CircuitItem *circuit)
00140 {
00141 if (circuit) {
00142
00143 QList<StreamItem *> streams = circuit->streams();
00144 foreach (StreamItem *stream, streams) {
00145
00146 if (_streamRemovalList.contains(stream)) {
00147
00148
00149 int index = _streamRemovalList.indexOf(stream);
00150 _streamRemovalList.replace(index, (StreamItem *)0);
00151 }
00152
00153
00154 circuit->removeStream(stream);
00155 }
00156
00157 delete takeTopLevelItem(indexOfTopLevelItem(circuit));
00158 }
00159 }
00160
00161
00162 void
00163 CircuitListWidget::removeStream()
00164 {
00165 if (!_streamRemovalList.isEmpty()) {
00166 StreamItem *stream = _streamRemovalList.takeFirst();
00167 removeStream(stream);
00168 }
00169 }
00170
00171
00172 void
00173 CircuitListWidget::removeStream(StreamItem *stream)
00174 {
00175 if (stream) {
00176
00177 CircuitItem *circuit = (CircuitItem *)stream->parent();
00178 if (circuit) {
00179
00180 circuit->removeStream(stream);
00181 } else {
00182
00183 delete stream;
00184 }
00185 }
00186 }
00187
00188
00189 void
00190 CircuitListWidget::clearCircuits()
00191 {
00192 QTreeWidget::clear();
00193 _circuitRemovalList.clear();
00194 _streamRemovalList.clear();
00195 }
00196
00197
00198
00199 CircuitItem*
00200 CircuitListWidget::findCircuitItem(quint64 circid)
00201 {
00202 int numCircs = topLevelItemCount();
00203 for (int i = 0; i < numCircs; i++) {
00204 CircuitItem *circuit = (CircuitItem *)topLevelItem(i);
00205 if (circid == circuit->id()) {
00206 return circuit;
00207 }
00208 }
00209 return 0;
00210 }
00211
00212
00213
00214 StreamItem*
00215 CircuitListWidget::findStreamItem(quint64 streamid)
00216 {
00217 int numCircs = topLevelItemCount();
00218 int numStreams;
00219
00220 for (int i = 0; i < numCircs; i++) {
00221 CircuitItem *circuit = (CircuitItem *)topLevelItem(i);
00222 numStreams = circuit->childCount();
00223
00224 for (int j = 0; j < numStreams; j++) {
00225 StreamItem *stream = (StreamItem *)circuit->child(j);
00226 if (streamid == stream->id()) {
00227 return stream;
00228 }
00229 }
00230 }
00231 return 0;
00232 }
00233
00234
00235 void
00236 CircuitListWidget::onSelectionChanged(QTreeWidgetItem *cur,
00237 QTreeWidgetItem *prev)
00238 {
00239 Q_UNUSED(prev);
00240
00241 if (cur) {
00242 Circuit circuit;
00243
00244 if (!cur->parent()) {
00245
00246 circuit = ((CircuitItem *)cur)->circuit();
00247 } else {
00248
00249 CircuitItem *circItem = (CircuitItem *)cur->parent();
00250 circuit = circItem->circuit();
00251 }
00252
00253
00254 if (circuit.length() > 0) {
00255 emit circuitSelected(circuit);
00256 }
00257 }
00258 }
00259
00260
00261 QList<Circuit>
00262 CircuitListWidget::circuits()
00263 {
00264 int numCircs = topLevelItemCount();
00265 QList<Circuit> circs;
00266
00267 for (int i = 0; i < numCircs; i++) {
00268 CircuitItem *circ = (CircuitItem *)topLevelItem(i);
00269 circs << circ->circuit();
00270 }
00271 return circs;
00272 }
00273