00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef WSCOUT_GUI_TRACE_HXX_
00024 # define WSCOUT_GUI_TRACE_HXX_
00025
00026 # include <QtGui/QScrollBar>
00027 # include <boost/foreach.hpp>
00028
00029 # include "wscout_gui_trace.hh"
00030
00031 namespace wscout
00032 {
00033
00034 namespace gui
00035 {
00036
00037 inline
00038 Trace::Trace(wpl::pcap::indexed_file<>* trace, QWidget* parent):
00039 QAbstractScrollArea (parent),
00040 trace_ (0),
00041 swap_content_ (false),
00042 view_ (viewport()),
00043 last_selected_ (-1)
00044 {
00045 update_timer_.setSingleShot(true);
00046 connect(&update_timer_, SIGNAL(timeout()), SLOT(update()));
00047 setTrace(trace);
00048 }
00049
00050 inline
00051 Trace::Trace(const Trace& t):
00052 QAbstractScrollArea (),
00053 trace_ (0),
00054 swap_content_ (false),
00055 view_ (viewport()),
00056 pos_ (t.pos_),
00057 selection_ (t.selection_),
00058 last_selected_ (t.last_selected_)
00059 {
00060 update_timer_.setSingleShot(true);
00061 connect(&update_timer_, SIGNAL(timeout()), SLOT(update()));
00062 if (const wpl::pcap::indexed_file<>* p = t.trace())
00063 setTrace(new wpl::pcap::indexed_file<> (*p));
00064 }
00065
00066 inline
00067 void
00068 Trace::setTrace(wpl::pcap::indexed_file<>* trace)
00069 {
00070 if (trace_ == trace)
00071 return;
00072
00073 delete trace_;
00074 trace_ = trace;
00075
00076 verticalScrollBar()->setRange(0, lastPosition());
00077 setPosition(0);
00078 emit traceChanged();
00079 }
00080
00081 inline
00082 const wpl::pcap::indexed_file<>*
00083 Trace::trace() const
00084 {
00085 return trace_;
00086 }
00087
00088 inline
00089 wpl::pcap::indexed_file<>*
00090 Trace::trace()
00091 {
00092 return trace_;
00093 }
00094
00095 inline
00096 int
00097 Trace::position() const
00098 {
00099 return pos_;
00100 }
00101
00102 inline
00103 int
00104 Trace::lastPosition() const
00105 {
00106 return trace_ ? trace_->size() - 1 : -1;
00107 }
00108
00109 inline
00110 QString
00111 Trace::positionString(int p) const
00112 {
00113 if (not trace_)
00114 return tr("N/A");
00115 if (trace_->size() == 0)
00116 return tr("0 / 0 (100%)");
00117 if (p < 0)
00118 p = position();
00119
00120 const int n = lastPosition();
00121 const int r = int (float (p + 1) / float (n + 1) * 100.);
00122
00123 return tr("#%1 / %2 (%3%)").arg(p + 1).arg(n + 1).arg(r);
00124 }
00125
00126 inline
00127 bool
00128 Trace::swapContent() const
00129 {
00130 return swap_content_;
00131 }
00132
00133 inline
00134 int
00135 Trace::lastLeftClicked() const
00136 {
00137 return
00138 trace_ and
00139 0 <= last_left_clicked_ and last_left_clicked_ < int (trace_->size()) ?
00140 last_left_clicked_ : -1;
00141 }
00142
00143 inline
00144 void
00145 Trace::startUpdateTimer(int ms)
00146 {
00147 if (not update_timer_.isActive())
00148 update_timer_.start(ms);
00149 }
00150
00151 inline
00152 Trace::selection::range::range(int a, int b):
00153 std::pair<int, int> (std::min(a, b), std::max(a, b))
00154 {
00155 }
00156
00157 inline
00158 void
00159 Trace::selection::clear()
00160 {
00161 ranges_.clear();
00162 }
00163
00164 inline
00165 bool
00166 Trace::selection::contains(int i) const
00167 {
00168 BOOST_FOREACH(const range& r, ranges_)
00169 {
00170 if (i <= r.second)
00171 return i >= r.first;
00172 }
00173 return false;
00174 }
00175
00176 inline
00177 std::ostream&
00178 Trace::selection::print(std::ostream& os) const
00179 {
00180 bool first = true;
00181
00182 os << '{';
00183 BOOST_FOREACH(const range& r, ranges_)
00184 {
00185 if (first)
00186 first = false;
00187 else
00188 os << ", ";
00189 os << r.first << '-' << r.second;
00190 }
00191 return os << '}';
00192 }
00193
00194 inline
00195 Trace::selection&
00196 Trace::selection::toggle(int i)
00197 {
00198 int lo = 0;
00199 iterator it = ranges_.begin();
00200
00201 while (it != ranges_.end() and i > it->second)
00202 {
00203 lo = it->second;
00204 ++it;
00205 }
00206 if (it == ranges_.end())
00207 {
00208 if (ranges_.back().second == i - 1)
00209 ++(ranges_.back().second);
00210 else
00211 ranges_.push_back(range (i, i));
00212 }
00213 else if (i == it->second)
00214 {
00215 --(it->second);
00216 cleanup(it);
00217 }
00218 else if (i < it->first - 1)
00219 ranges_.insert(it, range (i, i));
00220 else if (i == it->first - 1)
00221 --(it->first);
00222 else if (i == it->first)
00223 {
00224 ++(it->first);
00225 cleanup(it);
00226 }
00227 else
00228 {
00229 ranges_.insert(it, range(it->first, i - 1));
00230 it->first = i + 1;
00231 }
00232 return *this;
00233 }
00234
00235 inline
00236 Trace::selection&
00237 Trace::selection::operator = (int i)
00238 {
00239 return *this = range (i, i);
00240 }
00241
00242 inline
00243 Trace::selection&
00244 Trace::selection::operator = (const range& r)
00245 {
00246 clear();
00247 ranges_.push_back(r);
00248 return *this;
00249 }
00250
00251 inline
00252 const Trace::selection::list_of_ranges&
00253 Trace::selection::ranges() const
00254 {
00255 return ranges_;
00256 }
00257
00258 inline
00259 void
00260 Trace::selection::cleanup(iterator& it)
00261 {
00262 if (it->first > it->second)
00263 ranges_.erase(it);
00264 }
00265
00266 }
00267
00268 }
00269
00270 #endif // ! WSCOUT_GUI_TRACE_HXX_