[PC-BSD Commits] r16469 - pcbsd-projects/pc-mounttray

svn at pcbsd.org svn at pcbsd.org
Thu Apr 19 17:56:38 PDT 2012


Author: kenmoore
Date: 2012-04-20 00:56:38 +0000 (Fri, 20 Apr 2012)
New Revision: 16469

Modified:
   pcbsd-projects/pc-mounttray/mountTray.cpp
   pcbsd-projects/pc-mounttray/mountTray.h
Log:
Add devd detection and menu action slots. pc-mounttray is almost ready for testing, just needs a bit more polish.



Modified: pcbsd-projects/pc-mounttray/mountTray.cpp
===================================================================
--- pcbsd-projects/pc-mounttray/mountTray.cpp	2012-04-19 19:31:23 UTC (rev 16468)
+++ pcbsd-projects/pc-mounttray/mountTray.cpp	2012-04-20 00:56:38 UTC (rev 16469)
@@ -26,19 +26,18 @@
   trayIcon->setIcon(QIcon(":icons/USBgrey.png"));
   trayIcon->show();
   
-  //Start the refresh loop on a 10 minute timer
-  //QTimer::singleShot(1000,this,SLOT(refreshTray() ));
+  //Startup the devd wathing process
+  
+  //Do an initial scan of the devices with dmesg
+  initialDeviceScan();
+  
   qDebug() << "pc-mounttray: starting up";
   
-  //Probe the initial USB devices that are connected/mounted
-  numMount = 0; //Number of devices mounted
-  numAvail = 0; //Number of devices available/connected
-  
   //Update the tray icon
   showDeviceNotification(0,QAction("",this));
 }
 
-void MountTray::showDeviceNotification(int ident, QAction device){
+void MountTray::showDeviceNotification(int ident){
   //ident: 0-refresh icon only, 1-device connected, 2-device mounted, 3-device unmounted, 4-device disconnected
 
   if(ident==0){
@@ -78,23 +77,21 @@
   
 }
 
-QAction MountTray::newDeviceAction(QString deviceLocation){
+QAction MountTray::newDeviceAction(QString deviceLocation, QString deviceName){
   //Turn a device location into a QAction for use in this program
   
   QAction newdev = new QAction(this);
   newdev.setWhatsThis(deviceLocation);
   newdev.setCheckable(TRUE);
   
-  //ping the device to get the information
+  newdev.setText(deviceName);
   
-  //Device Name
-  qDebug() << "Device name detection needs to be written";
-  QString devname = "USB Device";
-  newdev.setText(devname);
-  
   //Check if device is mounted
-  qDebug() << "Mount check code needs to be written";
-  newdev.setChecked(FALSE);
+  if(QFile::exists("/dev/"+deviceName) ){
+    newdev.setChecked(TRUE);
+  }else{
+    newdev.setChecked(FALSE);
+  }
   
 }
 
@@ -244,11 +241,8 @@
 }
 
 
-void MountTray::refreshTray(){
-  //---DO NOT CALL THIS FUNCTION MANUALLY: AUTOMATICALLY REFRESHES---
-  
-  //Search through all the USB devices in /dev and and link all the umass devices into the Tray
-  // -- This ensures that the internal lists do not get out of sync with the system
+void MountTray::initialDeviceScan(){
+  //Load all the devices plugged in before the program started up
   trayIconMenu = new QMenu;
   trayIconMenu->clear();
   devList->clear();
@@ -256,11 +250,31 @@
   numMount = 0;
   
   //Scan for all the "umass" devices and add them to the device list
-   qDebug() << "Still need to add USB device detection";
-   //Parse out the "dmesg | grep umass" command - does not find the device names though....
-   
-   
+  qDebug() << "Still need to add USB device detection";
+  //Parse out the "dmesg | grep umass" command - does not find the device names though....
+  QStringList output = Utils::runShellCommandSearch("dmesg","umass");
+  QSringList devs;
+  for(int i=0; i<output.length(); i++){
+    QString line = output[i];
+    if( !line.startsWith("umass") ){
+      if(line.contains("removing device") || line.contains("lost device")){
+        //Device Removed (format: line=([device]:...... )
+        QString dev = line.section(":",0,0).section("(",1,1)
+        devs.removeAll(dev);
+      }else if(line.contains("at umass") ){
+        QString dev = line.section(" ",0,0,QString::SectionSkipEmpty);
+        devs << dev;
+      }
+    }
+  }
   
+  //If there are any devices connected, create actions for them and add them to the list
+  for(int i=0; i<devs.length(); i++){
+    QAction newdevice = newDeviceAction(devs[i], "USB_Device_"+i);
+    
+    devList << newdevice;
+  }
+ 
   //Add all the elements in the saved list to the menu
   for(int i=0; i<devList.length(); i++){
     trayIconMenu->addAction( devlist[i] );
@@ -271,8 +285,8 @@
   trayIconMenu->addAction( tr("Close Tray"), this, SLOT(closeTray()) );
   
   //Setup the signal/slot connection
-  trayIconMenu-> //clear any existing connections
-  connect(trayIconMenu, SIGNAL(triggered(QAction)), this, SLOT(deviceClicked(QAction)) );
+  trayIconMenu->disconnect(); //clear any existing connections
+  connect(trayIconMenu, SIGNAL(triggered(QAction)), this, SLOT(menuDeviceToggled(QAction)) );
   
   //Apply the menu to the Tray
   trayIcon->setContextMenu(trayIconMenu);
@@ -280,7 +294,6 @@
   //Update the tray icon
   showDeviceNotification(0,QAction("",this));
   
-  QTimer::singleShot(600000,this,SLOT(refreshTray() )); //10 minute refresh timer
 }
 
 //void MountTray::slotTrayActivated(QSystemTrayIcon::ActivationReason reason) {
@@ -289,8 +302,101 @@
    //}
 //}
 
+void MountTray::startupDevdProc(){
+  devdProc = new QProcess(this);
+  connect(devdProc, SIGNAL(readyReadStandardOutput()), this, SLOT(newDevdMessage()) );
+  
+  devdProc->start("cat /var/run/devd.pipe");
+  
+}
+
+void MountTray::newDevdMessage(){
+  //Since messages generally come in groups, save all the output for a couple seconds before doing anything
+  QString line = devdProc->readAllStandardOutput();
+  if(devdOutput.isEmpty()){
+    QTimer::singleShot(3000,this,SLOT(parseDevdOutput()) ); //Wait 3 seconds to catch all the output from devd
+  }
+  devdOutput << line.split("\n");
+}
+
+void MoutTray::parseDevdOutput(){
+
+  //Parse the output to find whether a device has been added/removed
+  bool isAttached = FALSE;
+  bool isUmass = FALSE;
+  QStringList cdev;
+  for(int i=0; i<devdOutput.length(); i++){
+    if( devdOutput[i].startsWith("+umass") ){
+      isAttached = TRUE;
+      isUmass = TRUE;
+    }else if(devdOutput[i].startsWith("-umass") ){
+      isAttached = FALSE;
+      isUMass = TRUE;
+    }
+    if(devdOutput[i].startsWith("!system=") ){
+      cdev << devdOutput[i].section("cdev=",1,1).simplified();
+    }
+  }
+  //If a USB mass storage device found
+  if(isUmass){
+    QString dev, devname, fstype;
+    
+    //Try to find the device, device name, and filesystem type
+    for(int i=0; i<cdev.length(); i++){
+      if( !cdev[i].startsWith("usb/") && !cdev.startsWith("ugen") && !cdev.startsWith("pass") ){
+        if( cdev[i].contains("/") && !QFile::exists("/dev/"+cdev[i].section("/",0,0)) ){
+          fstype = cdev[i].section("/",0,0,QString::SectionSkipEmpty);
+          devname = cdev[i].section("/",1,1,QString::SectionSkipEmpty);
+        }else if( !cdev.contains("/") ){
+          if(isAttached && QFile::exists("/dev/"+cdev[i]) ){
+            dev = cdev[i];
+          }else if( !isAttached && (findDeviceInList(newDeviceAction(cdev[i],"")) != -1) ){
+            dev = cdev[i];
+          }
+        }
+      }
+    
+    }
+    //Create the action for the device if a device detected
+    if(!dev.isEmpty() ){
+      if(isAttached){
+        if( updateDeviceList( 1 ,newDeviceAction(dev,devname) ) ){
+          showDeviceNotification(1);
+        }
+      }else{
+        if( updateDeviceList( 4 ,newDeviceAction(dev,devname) ) ){
+          showDeviceNotification(4);
+        }
+      }
+    }
+    
+  } // end if umass detected
+  
+  //Finished with the saved devd Output, clear it to prepare for another signal
+  devdOutput.clear();
+}
+
+void MountTray::menuDeviceToggled(QAction device){
+  int index = findDeviceInList(device);
+  
+  if( isMounted(device) ){
+    //Unmount the device
+    if( updateDeviceList(3,devList[index]) ){
+      showDeviceNotification(3);
+    }
+  }else{
+    //Mount the device
+    if( updateDeviceList(2,devList[index]) ){
+      showDeviceNotification(2);
+    }
+  }
+  
+}
+
 void MountTray::closeTray(){
   qDebug() << "pc-mounttray: closing down";
+  //Kill the devd watching process
+  devdProc->terminate();
   //Close down the application
   exit(0);
 }

Modified: pcbsd-projects/pc-mounttray/mountTray.h
===================================================================
--- pcbsd-projects/pc-mounttray/mountTray.h	2012-04-19 19:31:23 UTC (rev 16468)
+++ pcbsd-projects/pc-mounttray/mountTray.h	2012-04-20 00:56:38 UTC (rev 16469)
@@ -23,23 +23,27 @@
    virtual ~MountTray() {};
    
 private slots:
-  void refreshTray();
   void closeTray();
   void slotSingleInstance();
+  void MenuDeviceToggled(QAction);
   //void slotTrayActivated(QSystemTrayIcon::ActivationReason);
   
 private:
+  QProcess *devdProc;
+  QStringList devdOutput;
   int numMount, numAvail;
   QSystemTrayIcon* trayIcon;
   QMenu* trayIconMenu;
   QList<QAction> devList;
-  void showDeviceNotification(int, QAction);
+  void showDeviceNotification(int);
+  void initialDeviceScan();
   bool isMounted(QAction);
   bool isConnected(QAction);
   bool updateDeviceList(int, QAction);
   int findDeviceInList(QAction);
   bool mountDevice(QAction);
   bool unmountDevice(QAction);
-  QAction newDeviceAction(QString);
+  QAction newDeviceAction(QString,QString);
+  void startupDevdProc();
   
 };



More information about the Commits mailing list