All Classes Namespaces Files Functions Variables Enumerations Enumerator
programs/MultiUrgViewer/MultiUrgViewerWidget.cpp
Go to the documentation of this file.
00001 
00010 #include "MultiUrgViewerWidget.h"
00011 #include "UrgStateWidget.h"
00012 #include "DrawWidget.h"
00013 #include "UrgUsbCom.h"
00014 #include "FindComPorts.h"
00015 #include <QShortcut>
00016 #include <QVBoxLayout>
00017 #include <vector>
00018 #include <algorithm>
00019 
00020 using namespace qrk;
00021 using namespace std;
00022 
00023 
00024 struct MultiUrgViewerWidget::pImpl
00025 {
00026   MultiUrgViewerWidget* widget_;
00027   QVBoxLayout layout_;
00028   vector<UrgStateWidget*> urg_state_;
00029   DrawWidget draw_widget_;
00030 
00031 
00032   pImpl(MultiUrgViewerWidget* widget)
00033     : widget_(widget), layout_(widget_)
00034   {
00035   }
00036 
00037 
00038   void initializeForm(void)
00039   {
00040     // フォームの初期化
00041     widget_->setWindowTitle(tr("Multi URG Viewer"));
00042     layout_.setAlignment(Qt::AlignTop);
00043 
00044     connect(&draw_widget_, SIGNAL(quit()), widget_, SLOT(close()));
00045 
00046     // Ctrl-q, Alt-F4 で終了させる
00047     (void) new QShortcut(Qt::CTRL + Qt::Key_Q, widget_, SLOT(close()));
00048     (void) new QShortcut(Qt::ALT + Qt::Key_F4, widget_, SLOT(close()));
00049 
00050     // 最初の UrgState を配置
00051     addUrgState();
00052     rescanDevices();
00053   }
00054 
00055 
00056   void addUrgState(void)
00057   {
00058     if (! urg_state_.empty()) {
00059       UrgStateWidget* last_urg_state = urg_state_.back();
00060       if (! last_urg_state->isConnected()) {
00061         // 最後の UrgState が未接続ならば、追加しない
00062         return;
00063       }
00064     }
00065 
00066     UrgStateWidget* widget = new UrgStateWidget(widget_);
00067     urg_state_.push_back(widget);
00068     layout_.addWidget(widget);
00069   }
00070 
00071 
00072   void deleteUrgState(UrgStateWidget* widget)
00073   {
00074     layout_.removeWidget(widget);
00075 
00076     draw_widget_.disconnected(widget);
00077 
00078     vector<UrgStateWidget*>::iterator p =
00079       std::find(urg_state_.begin(), urg_state_.end(), widget);
00080     if (p != urg_state_.end()) {
00081       urg_state_.erase(p);
00082     }
00083     delete widget;
00084 
00085     addUrgState();
00086     rescanDevices();
00087   }
00088 
00089 
00090   void rescanDevices(void)
00091   {
00092     // デバイス一覧の取得
00093     FindComPorts urg_finder;
00094     urg_finder.addBaseName("/dev/ttyACM");
00095     urg_finder.addBaseName("/dev/tty.usbmodem");
00096     urg_finder.addDriverName("URG Series USB Device Driver");
00097     urg_finder.addDriverName("URG-X002 USB Device Driver");
00098 
00099     vector<string> urg_ports;
00100     urg_finder.find(urg_ports);
00101 
00102     // 接続済みのデバイスを除去する
00103     for (vector<UrgStateWidget*>::iterator it = urg_state_.begin();
00104          it != urg_state_.end(); ++it) {
00105       const string device = (*it)->device();
00106       vector<string>::iterator p =
00107         std::find(urg_ports.begin(), urg_ports.end(), device);
00108       if (p != urg_ports.end()) {
00109         urg_ports.erase(p);
00110       }
00111     }
00112 
00113     // 接続されてないデバイスに対してデバイスを登録
00114     UrgUsbCom urg_usb;
00115     UrgStateWidget* last_urg_state = urg_state_.back();
00116     for (vector<string>::iterator it = urg_ports.begin();
00117          it != urg_ports.end(); ++it) {
00118       if (urg_usb.isUsbCom(it->c_str())) {
00119         *it = *it + " [URG]";
00120       }
00121     }
00122     last_urg_state->setDevices(urg_ports);
00123   }
00124 };
00125 
00126 
00127 MultiUrgViewerWidget::MultiUrgViewerWidget(QWidget* parent)
00128   : QWidget(parent), pimpl(new pImpl(this))
00129 {
00130   pimpl->initializeForm();
00131 }
00132 
00133 
00134 MultiUrgViewerWidget::~MultiUrgViewerWidget(void)
00135 {
00136 }
00137 
00138 
00139 void MultiUrgViewerWidget::deleteUrgState(UrgStateWidget* widget)
00140 {
00141   pimpl->deleteUrgState(widget);
00142 }
00143 
00144 
00145 void MultiUrgViewerWidget::closeEvent(QCloseEvent* event)
00146 {
00147   static_cast<void>(event);
00148 
00149   for (vector<UrgStateWidget*>::iterator it = pimpl->urg_state_.begin();
00150        it != pimpl->urg_state_.end(); ++it) {
00151     (*it)->close();
00152     pimpl->deleteUrgState(*it);
00153   }
00154   pimpl->draw_widget_.close();
00155 }
00156 
00157 
00158 void MultiUrgViewerWidget::rescanDevices(void)
00159 {
00160   pimpl->rescanDevices();
00161 }
00162 
00163 
00164 void MultiUrgViewerWidget::addUrgState(void)
00165 {
00166   pimpl->addUrgState();
00167 }
00168 
00169 
00170 DrawWidget* MultiUrgViewerWidget::drawWidget(void)
00171 {
00172   return &pimpl->draw_widget_;
00173 }