src/wscout_gui_trace.hxx

00001 /*
00002  * WScout - Lightweight PCAP visualizer.
00003  * Copyright (C) 2007, 2008  Universite Pierre et Marie Curie - Paris 6
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  * MA  02110-1301  USA
00019  *
00020  * Author: Thomas Claveirole <thomas.claveirole@lip6.fr>
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(pcapxx::descriptor<>* 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 pcapxx::descriptor<>* p = t.trace())
00063         setTrace(new pcapxx::descriptor<> (*p));
00064     }
00065 
00066     inline
00067     void
00068     Trace::setTrace(pcapxx::descriptor<>* 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 pcapxx::descriptor<>*
00083     Trace::trace() const
00084     {
00085       return trace_;
00086     }
00087 
00088     inline
00089     pcapxx::descriptor<>*
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     void
00253     Trace::selection::cleanup(iterator& it)
00254     {
00255       if (it->first > it->second)
00256         ranges_.erase(it);
00257     }
00258 
00259   } // End of namespace gui.
00260 
00261 } // End of namespace wscout.
00262 
00263 #endif // ! WSCOUT_GUI_TRACE_HXX_

Generated on Wed Jan 30 19:02:27 2008 for WScout by  doxygen 1.5.4