[PC-BSD Commits] r20067 - in pcbsd/branches/9.1/src-qt4/pc-mounttray: . icons

svn at pcbsd.org svn at pcbsd.org
Mon Oct 29 12:04:04 PDT 2012


Author: kenmoore
Date: 2012-10-29 19:04:04 +0000 (Mon, 29 Oct 2012)
New Revision: 20067

Removed:
   pcbsd/branches/9.1/src-qt4/pc-mounttray/icons/USBblue.png
   pcbsd/branches/9.1/src-qt4/pc-mounttray/icons/USBgrey.png
   pcbsd/branches/9.1/src-qt4/pc-mounttray/icons/USBred.png
Modified:
   pcbsd/branches/9.1/src-qt4/pc-mounttray/menuItem.cpp
   pcbsd/branches/9.1/src-qt4/pc-mounttray/menuItem.h
   pcbsd/branches/9.1/src-qt4/pc-mounttray/mountTray.cpp
   pcbsd/branches/9.1/src-qt4/pc-mounttray/mountTray.h
   pcbsd/branches/9.1/src-qt4/pc-mounttray/pc-mounttray.pro
   pcbsd/branches/9.1/src-qt4/pc-mounttray/pc-mounttray.qrc
Log:
MFC the new MountTray with QLocalSocket support to the 9.1 branch



Modified: pcbsd/branches/9.1/src-qt4/pc-mounttray/menuItem.cpp
===================================================================
--- pcbsd/branches/9.1/src-qt4/pc-mounttray/menuItem.cpp	2012-10-29 19:03:49 UTC (rev 20066)
+++ pcbsd/branches/9.1/src-qt4/pc-mounttray/menuItem.cpp	2012-10-29 19:04:04 UTC (rev 20067)
@@ -1,39 +1,64 @@
-/*
-Sub-classed fancy widget for selecting a desktop environment
-*/
-
 #include <pcbsd-utils.h>
 #include "menuItem.h"
 
-MenuItem::MenuItem(QWidget* parent, QString newdevice) : QWidget(parent)
+MenuItem::MenuItem(QWidget* parent, QString newdevice, QString label) : QWidgetAction(parent)
 {
+  MOUNTDIR="/media/";   //Set the direcectory to mount devices in
+  AMFILE= QDir::homePath() + "/.pc-automounttray";   //File to save/load all the devices to be automounted
   //Set the device
   device = newdevice;
-  isSelected = FALSE;
   //Create the layout
   QGridLayout* layout = new QGridLayout();
+  QHBoxLayout* hlayout = new QHBoxLayout();
   //Create the gui items
   devLabel = new QLabel;
+    devLabel->setToolTip(device);
+    
   devIcon = new QLabel;
+    devIcon->setToolTip(device);
   currentSpace = new QProgressBar;
+    currentSpace->setMinimum(0);
   pushMount = new QPushButton;
-  pushChangeLabel = new QPushButton;
   checkAutomount = new QCheckBox;
+    checkAutomount->setChecked( checkSavedAutoMount() );
+    checkAutomount->setText( tr("Auto-mount this device") );
   //Add the widgets to the layout
-  layout->addWidget(devLabel,0,1);
-  layout->addWidget(devIcon,0,0);
-  layout->addWidget(currentSpace,1,0,1,2);
-  layout->addWidget(pushMount,2,0,1,2);
-  layout->addWidget(pushChangeLabel,3,0);
-  layout->addWidget(checkAutoMount,3,1);
+  layout->addWidget(devIcon,0,0,3,1);	
+  hlayout->addWidget(devLabel);
+  hlayout->addWidget(pushMount);
+  layout->addLayout(hlayout,0,1);
+  layout->addWidget(currentSpace,1,1);
+  layout->addWidget(checkAutomount,2,1);
   //Set the layout
-  this->setLayout(layout);
-  
+  frame = new QWidget();
+  frame->setLayout(layout);
+  this->setDefaultWidget(frame);
+  //QString style = "Border: inset "; 
+  //frame->setStyleSheet(style);
   //Connect the signals/slots
   connect(pushMount,SIGNAL(clicked()), this, SLOT(slotMountClicked()));
-  
+  connect(checkAutomount,SIGNAL(toggled(bool)),this,SLOT(slotAutoMountToggled(bool)));
+  //Setup the initial device variables
+  QString nLabel;
+  getDevInfo(newdevice,&devType,&nLabel,&filesystem,&maxSize); //this will set the devType, filesystem, and maxSize variables
+  //Device Label/Name
+  if( (!nLabel.isEmpty() && label.isEmpty()) || (!label.startsWith(nLabel)) ){
+    devLabel->setText(nLabel);  //use auto-detected name if none given initially or a better name auto-detected now
+  }else{
+    devLabel->setText(label);  //use the given label
+  }
+  //Setup the device Icon based on the type
+  if(devType == "USB"){ devIcon->setPixmap(QPixmap(":icons/usb.png")); }
+  else if(devType == "SATA"){ devIcon->setPixmap(QPixmap(":icons/harddrive.png")); }
+  else if(devType == "SD"){ devIcon->setPixmap(QPixmap(":icons/sdcard.png")); }
+  if(devType == "CD9660"){ devIcon->setPixmap(QPixmap(":icons/dvd.png")); }
+  //Start the automount procedure if necessary
+  if(checkAutomount->isChecked()){
+    mountItem();
+  }
   //Update the Item based upon current device status
   updateItem();
+
 }
 
 MenuItem::~MenuItem(){
@@ -42,38 +67,27 @@
 /*
   PUBLIC FUNCTIONS
 */
-void MenuItem::setDeviceName(QString label){
-  devLabel->setText(label);
-}
 
-void MenuItem::setDeviceIcon(QString iconFile){
-  devIcon->setPixmap(QPixmap(iconFile));	
-}
-
 void MenuItem::updateItem(){
   //Update the item visuals, based upon current device status
   if( isConnected() ){
     if( isMounted() ){
       devIcon->setEnabled(TRUE);  //Make the icon full color
+      pushMount->setText(tr("Eject"));
+      pushMount->setIcon(QIcon(":icons/eject.png"));
+      checkAutomount->setVisible(TRUE);
     }else{	  
-      devIcon->setEnabled(FALSE); //Grey out the icon
+      devIcon->setEnabled(FALSE); //Grey out the icon if not mounted
+      pushMount->setText(tr("Mount"));
+      pushMount->setIcon(QIcon(":icons/mount.png"));
+      checkAutomount->setVisible(FALSE);
     }
   }else{
-    emit itemRemoved(this);
+    emit itemRemoved(device);
     return;
   }
-  //Set visibility
-  if( isSelected() ){
-    currentSpace->setVisible(TRUE);
-    pushMount->setVisible(TRUE);
-    pushChangeLabel->setVisible(TRUE);
-    checkAutoMount->setVisible(TRUE);
-  }else{
-    currentSpace->setVisible(FALSE);
-    pushMount->setVisible(FALSE);
-    pushChangeLabel->setVisible(FALSE);
-    checkAutoMount->setVisible(FALSE);
-  }
+  //Set visibility and sizes on progressbar
+  updateSizes();
 }
 	
 //Getters
@@ -82,31 +96,328 @@
 }
 	
 //Device information
-bool isConnected(){
+bool MenuItem::isConnected(){
   if( QFile::exists(device) ){ return TRUE; }
   else{ return FALSE; }
 }
 
-bool isMounted(){
+bool MenuItem::isMounted(){
   //Check if device is mounted
-  QString chk = Utils::runShellCommandSearch("mount",device->whatsThis());  
-  if(chk.isEmpty() ){ chk = Utils::runShellCommandSearch("mount",device->text().replace(" ","-")); } 
+  QString chk = Utils::runShellCommandSearch("mount",device);  
+  if(chk.isEmpty() ){ chk = Utils::runShellCommandSearch("mount",devLabel->text().replace(" ","-")); } 
 
   if(chk.isEmpty() ){ return FALSE; }
   else{ return TRUE; }
 }
 	
+void MenuItem::getDevInfo(QString dev, QString* type, QString* label, QString* filesystem, QString* maxsize){
+  //Clear the output variables
+  type->clear(); label->clear(); filesystem->clear(); maxsize->clear();
+  //make sure to use the absolute path
+  if(!dev.startsWith("/dev/")){ dev.prepend("/dev/"); }
+  
+  if(!QFile::symLinkTarget(dev).isEmpty()){ return; } //do not follow sym-links
+  //Check for valid device types
+  QStringList validdev, devtype;
+  validdev << "da" << "ad"    << "mmcsd" << "cd"         << "acd";
+  devtype << "USB"<<"SATA"<< "SD"        << "CD9660" << "CD9660";
+  QString node = dev.section("/",-1);
+  QString detType;
+  for(int i=0; i<validdev.length(); i++){
+    if(node.startsWith(validdev[i])){ detType = devtype[i]; break; }
+  }
+  //Make sure we quit before running commands on any invalid device nodes
+  if(detType.isEmpty() || !QFile::exists(dev) ){return;}
+  else{type->append(detType);}
+    
+  //Read the Device Info using "file -s <device>"
+  QString cmd = "file -s "+dev;
+  QString output = Utils::runShellCommand(cmd).join(" ");
+  //qDebug() << "File -s output:" << output;
+  
+  // ** Get the max storage size **
+  QStringList tmp = output.split(",");
+  int kb;
+  //qDebug() << "tmp:" << tmp;
+  if( !tmp.filter("partition ").isEmpty() ){
+    kb = 0; //Do not recognize the base harddrive if there are partitions on it
+    type->clear(); //disable the flag for output
+  }else if( !tmp.filter("last mounted on /").isEmpty() ){
+    kb = 0; //Do not recognize partitions that are currently mounted
+    type->clear(); //disable the type flag for output
+  }else if( !tmp.filter("number of data blocks").isEmpty() ){
+    tmp = tmp.filter("number of data blocks");
+    kb = tmp[0].remove("number of data blocks").simplified().toInt();
+  }else if( !tmp.filter("number of blocks").isEmpty() ){
+    tmp = tmp.filter("number of blocks");
+    kb = tmp[0].remove("number of blocks").simplified().toInt();
+  }else if( !tmp.filter("hidden sectors").isEmpty()){
+    tmp = tmp.filter("hidden sectors");
+    kb = tmp[0].remove("hidden sectors").simplified().toInt();
+  }else if( !tmp.filter("sectors").isEmpty()){
+    tmp = tmp.filter("sectors");
+    //qDebug() << "Det Sectors line:"<<tmp;
+    int num=0;
+    for(int i=0; i<tmp.length(); i++){
+      int n = tmp[i].remove("sectors").section("(",0,0).simplified().toInt();
+      if(n > num){ num = n; }
+    }
+    kb = num;
+  }else{ kb = -1; }
+  maxsize->append( QString::number(kb) );
+  
+  // ** Get the device label **
+  //Get the device label if there is one using glabel
+  QString dlabel;
+  QString shortDev = dev.section("/",-1);
+    QString glout = Utils::runShellCommandSearch("glabel status "+shortDev, shortDev);
+    if(!glout.contains("No such geom:")){
+      QStringList entries = glout.split("  ", QString::SkipEmptyParts); //should be 3 entries, only need the first
+      //qDebug() << " - entries:" << entries;
+      QString lab = entries[0].simplified();
+      //save the device label
+      dlabel = lab.section("/",-1);
+    }
+  //Alternate method to get the device label using the "file -s" output
+  if(dlabel.isEmpty()){
+    dlabel = output.section("label: \"",1,1).section("\"",0,0).simplified(); //device name
+  }
+  //qDebug() <<"Detected Size:"<<kb<<"Label:"<<dlabel;
+  //Set the Device Name/label
+  if(dlabel.isEmpty()){
+    dlabel = *type+"-Device";
+  }
+  label->append(dlabel);
+  
+  // - trim the label out of the output line for filesystem type detection
+  QString devFSsec = output.section("label:",0,0);
+  QString devFSsec2 = output.section("label:",1,3).section(",",1,1,QString::SectionSkipEmpty);
+  
+  // ** Find the filesystem type for the device **
+  QString filesys;
+  QStringList fsdetect, fslabel;
+  fsdetect << "FAT" << "NTFS" << "EXT" << "ISO 9660" << "Unix Fast File system" << "Reiser" << "XFS"; //string to match for a particular filesystem
+  fslabel << "FAT" << "NTFS" << "EXT" << "CD9660" << "UFS" << "REISERFS" << "XFS"; //internal labels for the filesystems
+  for(int i=0; i<fsdetect.length(); i++){
+    if(devFSsec.contains(fsdetect[i]) || devFSsec2.contains(fsdetect[i]) ){
+      filesys = fslabel[i]; 
+    }
+  }
+  //If the filesystem could not be detected or is not supported
+  if(filesys.isEmpty()){ filesys = "UNKNOWN"; }
+  //save the filesystem type
+  filesystem->append(filesys);
+  
+
+}
+
 /*
   PRIVATE FUNCTIONS
 */
 void MenuItem::slotMountClicked(){
   if( isConnected() ){
-    if( isMounted() ){
+    if( !isMounted() ){
       mountItem();
     }else{
       unmountItem();  
     }
   }else{
-    emit itemRemoved(this);	  
+    emit itemRemoved(device);	  
   }
+  updateItem();
 }
+
+void MenuItem::slotAutoMountToggled(bool checked){
+  qDebug() << "Auto-mount toggled for:" << device << checked;
+  QString entry = devLabel->text()+":::"+devType+":::"+filesystem+":::"+maxSize;
+  if(checked){
+    //Add this entry to the auto-mount file
+    QString cmd = "echo \""+entry+"\" >> "+AMFILE;
+    system( cmd.toUtf8() );
+  }else{
+    //Remove this entry from the automount file
+    QString tmpFile = AMFILE+".tmp";
+    QString cmd = "cat "+AMFILE+" | grep -v "+entry+" > "+tmpFile+"; mv "+tmpFile+" "+AMFILE;
+    system( cmd.toUtf8() );
+  }
+}
+
+bool MenuItem::checkSavedAutoMount(){
+  if(QFile::exists(AMFILE)){
+    QString cmd = "cat "+AMFILE;
+    QString search = devLabel->text() +" "+ devType +" "+ filesystem +" "+ maxSize;
+    QString chk = Utils::runShellCommandSearch(cmd, search);
+    if( chk.isEmpty() ){ return FALSE; }
+    else{ return TRUE; }
+  }else{
+    return FALSE;
+  }
+}
+
+void MenuItem::mountItem(){
+  //Mount the device
+  
+  //Create the full path to the mountpoint
+  QString deviceName = devLabel->text();
+  QString mntpoint = MOUNTDIR + deviceName.replace(" ","-"); //take into account spaces in the name
+
+  //Create the fileystem specific command for mounting
+  QString fstype;
+  QString fsopts="";
+  if( filesystem == "FAT" ){ fstype = "mount -t msdosfs"; fsopts = "-o large,-m=644,-M=777"; }
+  else if(filesystem == "NTFS"){ fstype = "ntfs-3g"; }
+  else if(filesystem == "EXT"){ fstype = "mount -t ext2fs"; }
+  else if(filesystem == "CD9660"){ fstype = "mount -t cd9660"; }
+  else if(filesystem == "UFS"){ fstype = "mount -t ufs"; }
+  else if(filesystem == "REISERFS"){ fstype = "mount -t reiserfs"; }
+  else if(filesystem == "XFS"){ fstype = "mount -t xfs"; }
+  else{
+    qDebug() << "Unknown device filesystem:" << device << filesystem << " attempting mount_auto command";
+    fstype = "mount_auto";
+    //QMessageBox::warning(this,tr("Unknown Device Filesystem"),tr("The filesystem on this device is unknown and cannot be mounted at this time") );
+    //return FALSE;
+  }
+  //Make sure the mntpoint is available
+  QDir mpd(mntpoint);
+  if(mpd.exists()){
+    //Remove the existing directory (will work only if it is empty)
+    mpd.cdUp();
+    mpd.rmdir(mntpoint);
+  }
+  //Prepare the commands to run
+  QString cmd1 = "mkdir " + mntpoint;
+  QString cmd2 = fstype + " " +fsopts + " " + device + " " + mntpoint;
+  
+  qDebug() << "Mounting device" << device << "on" << mntpoint << "("<<filesystem<<")";
+  qDebug() << " - command:" << cmd2;
+  
+  bool ok = FALSE;
+  QString result, title;
+  //Run the mounting commands
+  QStringList output = Utils::runShellCommand(cmd1);
+  if( output.join(" ").simplified().isEmpty() ){
+    //directory created, run the next command
+    output = Utils::runShellCommand(cmd2);
+    if( output.join(" ").simplified().isEmpty() ){
+      title = tr("Success");
+      result = QString( tr("%1 mounted at %2") ).arg(deviceName).arg(mntpoint);
+      ok = TRUE;
+    }else{
+      qDebug() << "pc-mounttray: Error mounting device:" << device;
+      qDebug() << " - Error message:" << output;
+      title = QString( tr("Error mounting %1 at %2") ).arg(deviceName).arg(mntpoint);
+      result =  output.join(" ");
+      //Remove the mount point just created
+      Utils::runShellCommand("rmdir "+mntpoint);
+    }
+  }else{
+    qDebug() << "pc-mounttray: Error creating mountpoint:" << mntpoint;
+    qDebug() << " - Error message:" << output;
+    title = QString( tr("Error mounting %1") ).arg(deviceName);
+    result =  QString( tr("Could not create mount point at %1") ).arg(mntpoint);
+  }
+  //Output the proper signals depending upon success
+  if(ok){
+    emit itemMounted(mntpoint);
+    mountpoint = mntpoint;
+  }else{
+    mountpoint.clear();
+  }
+  if( !checkAutomount->isChecked() ){
+    emit newMessage(title, result); //suppress the output message if it was automounted
+  }
+  
+}
+
+void MenuItem::unmountItem(){
+  //Unmount the device
+
+  //Check to see if the current mountpoint exists or if it is somewhere else
+  if( !QFile::exists(mountpoint) ){
+    if( isMounted() ){  //double check that it is actually mounted
+      //mounted someplace else - find it
+      QString output = Utils::runShellCommandSearch("mount",device);
+      mountpoint = output.section(" on ",1,1).section(" (",0,0).replace(" ","-");
+    }else{
+      //it is not mounted to begin with
+      return;
+    }
+  }
+  
+  QString cmd1 = "umount " + mountpoint;
+  QString cmd2 = "rmdir " + mountpoint;
+  qDebug() << "Unmounting device from" << mountpoint;
+  //Run the commands
+  QStringList output;
+  QString result, title;
+  bool ok = FALSE;
+  output = Utils::runShellCommand(cmd1);
+  if(output.join(" ").simplified().isEmpty()){
+    //unmounting successful, remove the mount point directory
+    output = Utils::runShellCommand(cmd2);
+    if(!output.join(" ").simplified().isEmpty()){
+      qDebug() << "pc-mounttray: Error removing mountpoint:" << mountpoint;
+      qDebug() << " - Error message:" << output;
+    }
+    ok = TRUE;
+    title = QString( tr("%1 has been successfully unmounted.") ).arg(devLabel->text());
+    result = tr("It is now safe to remove the device");
+  }else{
+    qDebug() << "pc-mounttray: Error unmounting mountpoint:" << mountpoint;
+    qDebug() << " - Error message:" << output;
+    title = QString( tr("Error: %1 could not be unmounted") ).arg(devLabel->text());
+    result = output.join(" ");
+  }
+  //emit the proper signals
+  if(ok){
+    emit itemUnmounted(device);
+    mountpoint.clear();
+  }
+  emit newMessage(title, result);
+}
+
+void MenuItem::updateSizes(){
+  //this method only works if the device is currently mounted
+  bool ok = FALSE;
+  if(isMounted()){
+    QString cmd = "df "+mountpoint;
+    QStringList output = Utils::runShellCommand(cmd);
+    if(output.length() > 1){
+      //parse the output (1K blocks) and save them
+      QString line = output[1].replace("\t"," ");
+      maxSize = line.section(" ",1,1,QString::SectionSkipEmpty).simplified();
+      currentSize = line.section(" ",2,2,QString::SectionSkipEmpty).simplified();
+      ok=TRUE;
+    }else{
+      maxSize.clear();
+      currentSize.clear();	    
+    }
+  }else{
+    maxSize.clear();
+    currentSize.clear();
+  }
+  //Now setup the display progressbar display
+  if(ok){
+    currentSpace->setMaximum( maxSize.toInt() );
+    currentSpace->setValue( currentSize.toInt() );
+    currentSpace->setVisible(TRUE);
+    //display the actual size available in the tooltip
+    QString diskAvailable = getSizeDisplay( maxSize.toInt() - currentSize.toInt() );
+    currentSpace->setToolTip( QString( tr("%1 of disk space available") ).arg(diskAvailable) );
+  }else{
+    currentSpace->setVisible(FALSE);
+  }
+  	
+}
+
+QString MenuItem::getSizeDisplay(int kb){
+  //convert from KB to human readable output
+  if( kb > 1048576 ){ //display in GB
+    return QString::number( double(int( (kb*100)/1048576 )/100.0) )+"GB";
+  }else if( kb > 1024 ){ //display in MB
+    return QString::number( double(int( (kb*100)/1024 )/100.0) )+"MB";	  
+  }else{ //display in KB
+    return QString::number( kb )+"KB";	  
+  }
+	
+}

Modified: pcbsd/branches/9.1/src-qt4/pc-mounttray/menuItem.h
===================================================================
--- pcbsd/branches/9.1/src-qt4/pc-mounttray/menuItem.h	2012-10-29 19:03:49 UTC (rev 20066)
+++ pcbsd/branches/9.1/src-qt4/pc-mounttray/menuItem.h	2012-10-29 19:04:04 UTC (rev 20067)
@@ -5,7 +5,8 @@
 #ifndef MENU_ITEM_H
 #define MENU_ITEM_H
 
-#include <QWidget>
+#include <QWidgetAction>
+#include <QDir>
 #include <QFile>
 #include <QPushButton>
 #include <QProgressBar>
@@ -14,21 +15,23 @@
 #include <QDebug>
 #include <QLabel>
 
-class MenuItem : public QWidget
+class MenuItem : public QWidgetAction
 {
 	Q_OBJECT
 
   public:
-	MenuItem(QWidget* parent = 0, QString newdevice);
+	MenuItem(QWidget* parent = 0, QString newdevice = "", QString label = "");
 	~MenuItem();
 	
 	QString device;
   	QString devType;
   	QString filesystem;
+        QString mountpoint;
+        QString maxSize;  //number in KB saved as a QString
+        QString currentSize; //number in KB saved as a QString
+        QString AMFILE;
 	
   	//Setters
-	void setDeviceName(QString);
-	void setDeviceIcon(QString);
 	void updateItem();
 	
 	//Getters
@@ -37,28 +40,34 @@
 	//Device information
 	bool isConnected();
 	bool isMounted();
+	//static function for getting a device's info
+	static void getDevInfo(QString, QString*, QString*, QString*, QString*);
         
   private:
+	QWidget *frame;
+	QString MOUNTDIR;
   	QLabel* devLabel;
   	QLabel* devIcon;
   	QProgressBar* currentSpace;
   	QPushButton* pushMount;
-  	QPushButton* pushChangeLabel;
   	QCheckBox* checkAutomount;
-  	bool isSelected;
 
 	void mountItem();
   	void unmountItem();
+        void updateSizes();
+        QString getSizeDisplay(int);
+        bool checkSavedAutoMount();
   	
   private slots:
   	void slotMountClicked();
+        void slotAutoMountToggled(bool);
 	
   signals:
 	//Emits these signals whenever needed
-	void itemMounted(QString mountDir);
-	void itemUnmounted(QString deviceNode);
-	void itemChangeLabel(MenuItem);
-	void itemRemoved(MenuItem);
+	void itemMounted(QString);  	//device node (/dev/da*)
+	void itemUnmounted(QString); 	//device node
+	void itemRemoved(QString);  	//device node
+        void newMessage(QString, QString);	//message to be displayed
 
 };
 #endif

Modified: pcbsd/branches/9.1/src-qt4/pc-mounttray/mountTray.cpp
===================================================================
--- pcbsd/branches/9.1/src-qt4/pc-mounttray/mountTray.cpp	2012-10-29 19:03:49 UTC (rev 20066)
+++ pcbsd/branches/9.1/src-qt4/pc-mounttray/mountTray.cpp	2012-10-29 19:04:04 UTC (rev 20067)
@@ -5,13 +5,8 @@
 #include <QDir>
 #include <QImage>
 #include <QMenu>
-#include <QProcess>
-#include <QToolTip>
-#include <QTextStream>
-#include <QTimer>
 #include <QTranslator>
-#include <QProcessEnvironment>
-#include <iostream>
+//#include <iostream>
 
 #include "mountTray.h"
 #include <pcbsd-hardware.h>
@@ -20,14 +15,14 @@
 void MountTray::programInit()
 {
   qDebug() << "pc-mounttray: starting up";
-  MOUNTDIR = "/media/"; //Directory for all the devices to be mounted
   DEVICEDIR = "/dev/";  //Directory that new devices are discovered
-  AMFILE = QDir::homePath() + "/.pc-automounttray"; //File to save/load all the devices to be automounted
+  MOUNTDIR = "/media/"; //Directory that all devices get mounted to
   getInitialUsername(); //try to detect the non-root user who is running the program with root permissions
   getDefaultFileManager(); //try to detect the default file-manager for opening the mount directory
 
   trayIcon = new QSystemTrayIcon(this);
-  
+  trayIconMenu = new QMenu();
+	
   // Tie the left-click signal to open the context menu
   connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(slotTrayActivated(QSystemTrayIcon::ActivationReason)) );
   
@@ -36,8 +31,8 @@
   trayIcon->show();
   
   //Load the automount file and populate the list
-  qDebug() << "-Loading automount device list:" << AMFILE;
-  loadAutoMountFile();
+  //qDebug() << "-Loading automount device list:" << AMFILE;
+  //loadAutoMountFile();
 
   //Startup the devd watching process
   qDebug() << "-Starting up the DEVD watcher";
@@ -45,42 +40,46 @@
   
   //Do an initial scan of the devices with dmesg
   qDebug() << "-Performing initial device scan";
-  initialDeviceScan();
+  scanInitialDevices();
   
-  //Update the tray icon
-  QAction* junk = new QAction("",this);
-  showDeviceNotification(0,junk);
+  //Update the tray menu and icons
+  updateMenu();
+
   qDebug() << "-Program now ready for use";
 }
 
-void MountTray::showDeviceNotification(int ident, QAction* device){
-  //ident: 0-refresh icon only, 1-device connected, 2-device mounted, 3-device unmounted, 4-device disconnected
-
-  if(ident==0){
-    //no message, only update tray icon
-  }else if(ident==1){
-    //Device connected
-    trayIcon->showMessage( tr("Device Connected"), tr("New device detected"), QSystemTrayIcon::NoIcon,3000 );
-    
-  }else if(ident==2){
-    //Device mounted
-    trayIcon->showMessage( tr("Device Mounted"), QString(tr("Device %1 has been mounted at %2")).arg(device->text()).arg(MOUNTDIR+device->text()), QSystemTrayIcon::NoIcon,3000 );
-    
-  }else if(ident==3){
-    //Device unmounted
-    trayIcon->showMessage( tr("Device Unmounted"), QString(tr("Device %1 may now be safely removed")).arg(device->text()), QSystemTrayIcon::NoIcon,3000 );
-    
-  }else if(ident==4){
-    //Device disconnected
-    //DOn't show a message
-  
-  }else{
-    //Unknown identifier
-    qDebug() << "pc-mounttray: unknown device notification identifier";
-    return;
+void MountTray::updateMenu(){
+  //Clear the menu
+  trayIconMenu->clear();
+  trayIconMenu->disconnect();
+  numAvail = 0;
+  numMount = 0;
+  //Iterate through all the devices and add them as necessary
+  for(int i=0; i<deviceList.length(); i++){
+    if(deviceList[i]->isConnected()) { 
+      trayIconMenu->addAction(deviceList[i]);
+      numAvail++;
+      if(deviceList[i]->isMounted() ){ numMount++; }
+      deviceList[i]->updateItem(); //refresh the item now as well
+    }else{
+      //Remove any devices that are not connected
+      deviceList.removeAt(i);
+      i--; //roll back one to catch the new index values for the list
+    }
   }
+  //Separate the extra options at the end
+  trayIconMenu->addSeparator();
+  //Add the "open media" entry to the list
+  trayIconMenu->addAction( QIcon(":icons/folder.png"), tr("Open Media Directory"), this, SLOT(slotOpenMediaDir()) );
+  trayIconMenu->addSeparator();
+  trayIconMenu->addAction( QIcon(":icons/refresh.png"),tr("Rescan Devices"), this, SLOT(slotRescan()) );
+  //Add the "close tray" entry to the list
+  trayIconMenu->addAction( QIcon(":icons/application-exit.png"), tr("Close Tray"), this, SLOT(closeTray()) );
   
-  //Set the main Tray icon 
+  //Apply the menu to the Tray
+  trayIcon->setContextMenu(trayIconMenu);
+
+  //Update the main icon based upon whether devices have been found
   if(numAvail==0){
     trayIcon->setIcon( QIcon(":icons/CDdevices-inactive.png") );
   }else{
@@ -90,432 +89,73 @@
       trayIcon->setIcon( QIcon(":icons/CDdevices.png") );
     }
   }
-  
 }
 
-QAction* MountTray::newDeviceAction(QString deviceLocation, QString type){
-  //Turn a device location into a QAction for use in this program
-  /* -- SAVED DATA FORMAT WITHIN THE QACTION ---
-    text() -> Device Name (multiple words allowed)
-    whatsThis() -> Device Location (example: /dev/da0 )
-    statusTip() -> Device type and filesystem (example: USB:::msdosfs)
-  */
-  QAction* newdev = new QAction(this);
-  newdev->setCheckable(FALSE); //don't let the menu action be checkable -- looks funny with the icons 
-  
-  //Set the device location
-  if( !deviceLocation.startsWith(DEVICEDIR) ){
-    deviceLocation.prepend(DEVICEDIR);
-  }
-  QString dev = deviceLocation.section("/",-1);
-  newdev->setWhatsThis(deviceLocation);
-
-  //Shortcut for junk actions (to speed up list searches)
-  if(type == "JUNK"){
-    return newdev;	  
-  }
-  
-  //Don't run "file" command on certain devices that are known non-storage devices
-  if(dev.startsWith("pcm") || dev.startsWith("tty") ){
-    return newdev;
-  } 
-
-  //Get the Device Info
-  QString cmd = "file -s "+deviceLocation;
-  QString output = Utils::runShellCommand(cmd).join(" ");
-  //qDebug() << "File -s output:" << output;  
-  // - get the device storage size
-  QStringList tmp = output.split(",");
-  int kb;
-  //qDebug() << "tmp:" << tmp;
-  if( !tmp.filter("number of data blocks").isEmpty() ){
-    tmp = tmp.filter("number of data blocks");
-    kb = tmp[0].remove("number of data blocks").simplified().toInt();
-  }else if( !tmp.filter("number of blocks").isEmpty() ){
-    tmp = tmp.filter("number of blocks");
-    kb = tmp[0].remove("number of blocks").simplified().toInt();
-  }else if( !tmp.filter("sectors ").isEmpty()){
-    tmp = tmp.filter("sectors ");
-    kb = tmp[0].remove("sectors ").section("(",0,0).simplified().toInt();
-  }else{ kb = 1; }
-
-  //Filter out all devices with less than a MB of storage
-  //qDebug() << "kb detected:" << kb;
-  if( (kb < 1024) && (type=="USB") ){
-    return newdev;
-  }
-  // - get the device label
-  QString label = output.section("label: \"",1,1).section("\"",0,0).simplified(); //device name
-  if(label.isEmpty()){
-    //Try another method to find the device label
-
-    QStringList glout = Utils::runShellCommandSearch("glabel list "+dev,"Name:").split("\n");
-    for(int i=0; i<glout.length(); i++){
-      if(!glout[i].contains(dev)){
-        label = glout[i].section("Name:",1,1).section("/",-1).simplified();
-	break;
+void MountTray::scanInitialDevices(){
+  //Scan the /dev/ directory for all valid devices and check them 
+  QDir dir(DEVICEDIR);
+  QStringList allDevs = dir.entryList( QDir::System | QDir::NoDotAndDotDot | QDir::NoSymLinks );
+  //Now that we have a quick and dirty list, lets clean it up 
+  QString dType, dLabel, dFS, dSize;
+  for(int i=0; i<allDevs.length(); i++){
+    //Run it through the device info function to filter out all the "invalid" devices (audio, USB hubs, etc...)
+    MenuItem::getDevInfo(allDevs[i], &dType, &dLabel, &dFS, &dSize);
+    if( !dType.isEmpty() ){ // ignore devices that fail the information check
+      //Allow all filesystems for the moment (could remove UNKNOWN's in the future)
+      //Filter out all devices with basically no storage (1 block ~= 8kB usually)
+      if( dSize.toInt() > 60 ){ 
+        //Add the device to the menu list
+	addDevice(allDevs[i], dLabel);
+      }else if(dSize != "-1"){
+        qDebug() << "Ignoring Device (<60 blocks/sectors):"<<allDevs[i]<<dType<<dLabel<<dFS<<dSize;
       }
     }
   }
-  // - trim the label out of the output line for filesystem type detection
-  QString devFSsec = output.section("label:",0,0);
-  QString devFSsec2 = output.section("label:",1,3).section(",",1,1,QString::SectionSkipEmpty);
-  // - Find the filesystem type for the device
-  QString filesys;
-  QStringList fsdetect, fslabel;
-  fsdetect << "FAT" << "NTFS" << "EXT" << "ISO 9660" << "Unix Fast File system" << "Reiser" << "XFS"; //string to match for a particular filesystem
-  fslabel << "FAT" << "NTFS" << "EXT" << "CD9660" << "UFS" << "REISERFS" << "XFS"; //internal labels for the filesystems
-  for(int i=0; i<fsdetect.length(); i++){
-    if(devFSsec.contains(fsdetect[i]) || devFSsec2.contains(fsdetect[i]) ){
-      filesys = fslabel[i]; 
-    }
-  }
-  //If the filesystem could not be detected or is not supported
-  if(filesys.isEmpty()){
-    filesys = "UNKNOWN"; 
-    //return newdev;
-  }
-
-  //Set the Device type and file system type
-  if(type.isEmpty()){ type = "USB"; }
-  if( filesys == "CD9660" ){ type = "CD/DVD"; }  
-  newdev->setStatusTip( type+":::"+filesys);
-
-  //Set the Device Name
-  if(label.isEmpty()){
-    int num = 0;
-    for(int i=0; i<devList.length(); i++){
-      if( devList[i]->text().contains(type+"-Device-") ){
-	num++;
-      }
-    }
-    label = type+"-Device-"+QString::number(num);
-  }
-  newdev->setText(label);
-
-  //set the default Icon
-  setDeviceIcon(newdev);
-
-  return newdev;
   
 }
 
-void MountTray::setDeviceIcon(QAction* device){
-  bool ismnt = isMounted(device);
-  QString type = device->statusTip().section(":::",0,0);
-  if(type=="USB" && ismnt){
-    device->setIcon( QIcon(":icons/USBblue.png") );
-  }else if( type=="USB" && !ismnt){
-    device->setIcon( QIcon(":icons/USBgrey.png") );
-  }else if( type=="SATA" && ismnt){
-    device->setIcon( QIcon(":icons/CDdevices.png") );
-  }else if( type=="SATA" && !ismnt){
-    device->setIcon( QIcon(":icons/CDdevices-inactive.png") );
-  }else{
-    device->setIcon( QIcon(":icons/CDdevices-inactive.png") );
+int MountTray::findDeviceInList(QString newDev){
+  for(int i=0; i<deviceList.length(); i++){
+    if( deviceList[i]->device == newDev ){ return i; }
   }
-}
-
-bool MountTray::updateDeviceList(int act, QAction* device){
-  //act: 0-verify device  1-add device  2-mount device 3-unmount device 4-remove device 5-mount silently 
-
-  bool status = FALSE;
-  if(act==0){
-    //verify that device is still valid
-    if( isConnected(device) ){
-      status = TRUE;
-    }else{
-      status = updateDeviceList(4, device);
-    }
-    
-  }else if(act==1){
-    //Device connected (add new device entry)
-    if( findDeviceInList(device) == -1 ){
-      device->setToolTip( QString(tr("%1 unmounted - may be removed")).arg(device->whatsThis()) );
-      devList << device;
-      numAvail++;
-      status = TRUE;
-    }
-      
-  }else if(act==2){
-    //Mount device
-    if( mountDevice(device) ){
-      device->setToolTip( QString(tr("%1 mounted at %2")).arg(device->whatsThis()).arg(MOUNTDIR+device->text().replace(" ","-")) );
-      numMount++;
-      status = TRUE;
-    }
-  
-  }else if(act==3){
-    //Unmount device
-    if( unmountDevice(device) ){
-      device->setToolTip( QString(tr("%1 unmounted - may be removed")).arg(device->whatsThis()) );
-      numMount--;
-      status = TRUE;
-    } 
-    
-  }else if(act==4){
-    //Device disconnected
-    int index = findDeviceInList(device);
-    if(index != -1){
-      devList.removeAt(index);
-      numAvail--;
-      status = TRUE;
-    }
-     
-  }else if(act==5){
-    //Mount device silently
-    if( mountDevice(device,FALSE) ){
-      device->setToolTip( QString(tr("%1 mounted at %2")).arg(device->whatsThis()).arg(MOUNTDIR+device->text().replace(" ","-")) );
-      numMount++;
-      status = TRUE;
-    }
- 
-  }else{
-    //Unknown identifier
-    qDebug() << "pc-mounttray: unknown device update identifier";
-  }
-  
-  //update the icon for the device
-  setDeviceIcon(device);
-  
-  return status;
-}
-
-int MountTray::findDeviceInList(QAction* device){
-  for(int i=0; i<devList.length(); i++){
-    if( devList[i]->whatsThis() == device->whatsThis() ){
-      return i;
-    }
-  }
   return -1;
 }
 
-bool MountTray::mountDevice(QAction* devAct,bool openDir){
-  if(isMounted(devAct)){
-    //Device is already mounted
-    return TRUE;
-  }
+void MountTray::addDevice(QString dev, QString label){
+  if(!dev.startsWith(DEVICEDIR)){ dev.prepend(DEVICEDIR); }
   
-  //Mount the device
-  bool status = FALSE;
-  
-  QString dev = devAct->whatsThis();
-  QString mntpoint = MOUNTDIR + devAct->text().replace(" ","-"); //take into account spaces in the name
-  QString dtype = devAct->statusTip().section(":::",0,0);
-  QString fstypedet = devAct->statusTip().section(":::",1,1); 
-  
-  //Create the fileystem specific command for mounting
-  QString fstype;
-  QString fsopts="";
-  if( fstypedet == "FAT" ){ fstype = "mount -t msdosfs"; fsopts = "-o large,-m=644,-M=777"; }
-  else if(fstypedet == "NTFS"){ fstype = "ntfs-3g"; }
-  else if(fstypedet == "EXT"){ fstype = "mount -t ext2fs"; }
-  else if(fstypedet == "CD9660"){ fstype = "mount -t cd9660"; }
-  else if(fstypedet == "UFS"){ fstype = "mount -t ufs"; }
-  else if(fstypedet == "REISERFS"){ fstype = "mount -t reiserfs"; }
-  else if(fstypedet == "XFS"){ fstype = "mount -t xfs"; }
-  else{
-    qDebug() << "Unknown device filesystem:" << dev << fstypedet << " attempting mount_auto command";
-    fstype = "mount_auto";
-    //QMessageBox::warning(this,tr("Unknown Device Filesystem"),tr("The filesystem on this device is unknown and cannot be mounted at this time") );
-    //return FALSE;
+  //Check if the device is already in the list
+  int tot=0;
+  for(int i=0; i<deviceList.length(); i++){
+    if( deviceList[i]->device == dev ){ return; } //already exists, do nothing
+    if( deviceList[i]->getDeviceName().startsWith(label) ){ tot++; }
   }
-  //Make sure the mntpoint is available
-  QDir mpd(mntpoint);
-  if(mpd.exists()){
-    //Remove the existing directory (will work only if it is empty)
-    mpd.cdUp();
-    mpd.rmdir(mntpoint);
-  }
-  //Prepare the commands to run
-  QString cmd1 = "mkdir " + mntpoint;
-  QString cmd2 = fstype + " " +fsopts + " " + dev + " " + mntpoint;
-  
-  qDebug() << "Mounting device" << dev << "on" << mntpoint << "("<<fstypedet<<")";
-  qDebug() << " - command:" << cmd2;
-  //Run the mounting commands
-  QStringList output = Utils::runShellCommand(cmd1);
-  if( output.join(" ").simplified().isEmpty() ){
-    //directory created, run the next command
-    output = Utils::runShellCommand(cmd2);
-    if( output.join(" ").simplified().isEmpty() ){
-      //Mounted successfully
-      if(openDir){ openMediaDir(mntpoint); }//open the mountpoint directory
-      status = TRUE;
-    }else{
-      qDebug() << "pc-mounttray: Error mounting device:" << dev;
-      qDebug() << " - Error message:" << output;
-      //Remove the mount point just created
-      Utils::runShellCommand("rmdir "+mntpoint);
-    }
-  }else{
-    qDebug() << "pc-mounttray: Error creating mountpoint:" << mntpoint;
-    qDebug() << " - Error message:" << output;
-  }
-  
-  return status;
+  //See if the label is unique as well, otherwise add a number to the end to make it unique
+  if(tot > 0 && !label.isEmpty()){ label.append("-"+QString::number(tot)); }
+ 
+  //Create the menu item (will automount if necessary)
+  MenuItem *tmp = new MenuItem(this, dev, label);
+  //connect the signals/slots
+  connect(tmp, SIGNAL(itemMounted(QString)), this, SLOT(openMediaDir(QString)) );
+  connect(tmp, SIGNAL(newMessage(QString,QString)), this, SLOT(slotDisplayPopup(QString,QString)) );
+  connect(tmp, SIGNAL(itemRemoved(QString)), this, SLOT(removeDevice(QString)) );
+  deviceList << tmp;
+  //Update the menu
+  updateMenu();
 }
 
-bool MountTray::unmountDevice(QAction* devAct){
-  //Unmount the device
-  bool status = FALSE;
-  QString mntpoint = MOUNTDIR + devAct->text().replace(" ","-");
-  if( !QFile::exists(mntpoint.remove("\"")) ){
-    if( isMounted(devAct) ){
-      //mounted someplace else - find it
-      QString output = Utils::runShellCommandSearch("mount",devAct->whatsThis());
-      mntpoint = output.section(" on ",1,1).section(" (",0,0).replace(" ","-");
-    }else{
-      //is not mounted to begin with
-      return TRUE;
-    }
-  }
+void MountTray::removeDevice(QString dev){
+  if(!dev.startsWith(DEVICEDIR)){ dev.prepend(DEVICEDIR); }
   
-  QString cmd1 = "umount " + mntpoint;
-  QString cmd2 = "rmdir " + mntpoint;
-  qDebug() << "Unmounting device from" << mntpoint;
-  //Run the commands
-  QStringList output;
-  output = Utils::runShellCommand(cmd1);
-  if(output.join(" ").simplified().isEmpty()){
-    //unmounting successful, remove the mount point directory
-    output = Utils::runShellCommand(cmd2);
-    if(output.join(" ").simplified().isEmpty()){
-      //Directory removed
-      status = TRUE;
-    }else{
-      qDebug() << "pc-mounttray: Error removing mountpoint:" << mntpoint;
-      qDebug() << " - Error message:" << output;
-    }
-  }else{
-    qDebug() << "pc-mounttray: Error unmounting mountpoint:" << mntpoint;
-    qDebug() << " - Error message:" << output;
-  }
-    
-  return status;
+  //Find the device in the list
+  int index = findDeviceInList(dev);
+  if( index == -1 ){ return; } //does not exist, do nothing
+  //Remove the menu entry from the list
+  deviceList.removeAt(index);
+  //Update the menu
+  updateMenu();
 }
 
-bool MountTray::isMounted(QAction* device){
-  //Check if device is mounted
-  QString chk = Utils::runShellCommandSearch("mount",device->whatsThis());  
-  if(chk.isEmpty() ){ chk = Utils::runShellCommandSearch("mount",device->text().replace(" ","-")); } 
-
-  if(chk.isEmpty() ){
-    device->setChecked(FALSE);
-    return FALSE;
-  }else{
-    device->setChecked(TRUE);
-    return TRUE;
-  }
-}
-
-bool MountTray::isConnected(QAction* device){
-  if( QFile::exists( device->whatsThis() ) ){
-    return TRUE;
-  }else{
-    return FALSE;
-  }
-}
-
-
-void MountTray::initialDeviceScan(){
-  //Load all the devices plugged in before the program started up
-  trayIconMenu = new QMenu;
-  trayIconMenu->clear();
-  devList.clear();
-  numAvail = 0;
-  numMount = 0;
-  
-  //Scan for all the connected devices and add them to the device list
-  // -- Parse out the "dmesg" command to search for connected devices
-  QStringList output = Utils::runShellCommand("dmesg");
-  QStringList devs;
-  for(int i=0; i<output.length(); i++){
-    QString line = output[i];
-    //umass devices (careful - USB devices can be connected and disconnected)
-    if( line.contains("umass") ){
-      if(line.contains("removing device entry") || line.contains("lost device")){
-        //Device Removed (format: line=([device]:...... )
-        QString dev = line.section(":",0,0).section("(",1,1);
-        devs.removeAll(dev+":::USB");
-      }else if(line.contains(" at umass") ){
-        QString dev = line.section(" ",0,0,QString::SectionSkipEmpty);
-        devs << dev+":::USB";
-      }
-    }
-    //SATA devices
-    if( line.contains("SATA") && line.contains("device") && !line.contains("controller") ){
-      QString pdev = line.section(":",0,0,QString::SectionSkipEmpty); //parent device
-      if( devs.filter(pdev).length() == 0 ){
-        //Check for child partitions within the parent device
-        int i=1;
-        QString cdev = DEVICEDIR+pdev+"s"+QString::number(i);
-        while( QFile::exists(cdev) ){
-          //qDebug() << "cdev:" << cdev;
-          if( cdev.simplified() != (DEVICEDIR+pdev) ){
-            QString cfile = Utils::runShellCommand("file -s "+cdev).join(" ");
-            if( !cfile.contains(" last mounted on /") ){ //ignore the partition PC-BSD is currently running on
-              if( !devs.contains(cdev+":::SATA") ){ devs << cdev+":::SATA"; }
-
-            }
-          }
-          i++;
-          cdev = DEVICEDIR+pdev+"s"+QString::number(i);
-        }
-      }
-    }
-  }
-  //qDebug() << "devs:"<<devs;
-  //If there are any devices connected, create actions for them and add them to the list
-  for(int i=0; i<devs.length(); i++){
-    if(i==0){ qDebug() << "-Existing devices discovered:"; }
-    QAction* newdevice = newDeviceAction( devs[i].section(":::",0,0), devs[i].section(":::",1,1) );
-    qDebug() << " - "<<newdevice->whatsThis()<<" -> "<<newdevice->text()<<", "<<newdevice->statusTip();
-    updateDeviceList(1, newdevice);
-    if(isMounted(newdevice)){ 
-      numMount++; 
-      newdevice->setToolTip( QString(tr("%1 Mounted")).arg(MOUNTDIR+newdevice->text().replace(" ","-")) );
-    }else{
-      newdevice->setToolTip(tr("Unmounted - May be removed"));
-    }
-    autoMount(newdevice,TRUE);
-  }
-  
-  //Update the Tray Menu
-  updateTrayMenu();
-  //Update the Tray Icon
-  QAction* junk = new QAction("",this);
-  showDeviceNotification(0,junk);
-}
- 
-void MountTray::updateTrayMenu(){
-  trayIconMenu->clear();
-  trayIconMenu->disconnect(); //clear any existing connections  
-  
-  //Add all the elements in the saved list to the menu
-  for(int i=0; i<devList.length(); i++){
-    //Create the submenu for this action and fill it
-    setSubMenu(devList[i]);
-    //Add this item to the main menu
-    trayIconMenu->addAction( devList[i] );
-  }
-  
-  trayIconMenu->addSeparator();
-  //Add the "open media" entry to the list
-  trayIconMenu->addAction( QIcon(":icons/folder.png"), tr("Open Media Directory"), this, SLOT(slotOpenMediaDir()) );
-  //Add the "close tray" entry to the list
-  trayIconMenu->addAction( QIcon(":icons/application-exit.png"), tr("Close Tray"), this, SLOT(closeTray()) );
-  
-  //Apply the menu to the Tray
-  trayIcon->setContextMenu(trayIconMenu);
-  
-  //Update the tray icon
-  QAction* junk = new QAction("",this);
-  showDeviceNotification(0,junk);
-  
-}
-
-
 void MountTray::slotTrayActivated(QSystemTrayIcon::ActivationReason reason) {
    if(reason == QSystemTrayIcon::Trigger) {
      trayIcon->contextMenu()->popup(QCursor::pos());
@@ -524,116 +164,67 @@
 
 
 void MountTray::startupDevdProc(){
-  devdProc = new QProcess(this);
-  connect(devdProc, SIGNAL(readyReadStandardOutput()), this, SLOT(newDevdMessage()) );
-  
-  devdProc->start("cat /var/run/devd.pipe");
-  
+  devdProc = new QLocalSocket(this);
+  devdProc->connectToServer("/var/run/devd.pipe",QIODevice::ReadOnly | QIODevice::Text);
+  if( devdProc->waitForConnected(3000) ){ //Max wait of 3 sec
+    connect(devdProc, SIGNAL(readyRead()), this, SLOT(newDevdMessage()) );
+  }else{
+    qDebug() << " - Could not startup the devd watching process";
+  }
 }
 
 void MountTray::newDevdMessage(){
-  QString tmpline = devdProc->readAllStandardOutput();
   //Make sure there are not multiple lines output at the same time
-  QStringList lList = tmpline.split("\n");
+  QStringList lList;
+  while(devdProc->canReadLine()){
+    lList << devdProc->readLine();
+  }
   //Parse each line seperately
   for(int i=0; i<lList.length(); i++){
     QString line = lList[i];
     bool isAttached=FALSE;
     bool deviceFound=FALSE;
-    QString cdev,cdevtype;
+    QString cdev, cdevtype, dlab, dmax, dfs;
+    int index;
     if(line.startsWith("!system=DEVFS")){
       //qDebug() << line;
       QString type = line.section("type=",1,1).section(" ",0,0).simplified();
       cdev = line.section("cdev=",1,1).section(" ",0,0).simplified();
-      //Only recognize certain device types (mass storage devices)
-      if(cdev.startsWith("da")){  cdevtype="USB"; }
-      else if(cdev.startsWith("mmcsd")){ cdevtype="SD"; }
-      else if(cdev.startsWith("ad")){ cdevtype="SATA"; }
-      else if(cdev.startsWith("cd") || cdev.startsWith("acd")){ cdevtype="CD9660"; }
-      else{ cdevtype.clear(); }
+      cdev.prepend("/dev/");
+      if(type=="CREATE"){ isAttached=TRUE; }
+      MenuItem::getDevInfo(cdev, &cdevtype, &dlab, &dfs, &dmax);
+	    
       //If device is recognized - make sure it is also valid
+      index = findDeviceInList(cdev);
       if( !cdevtype.isEmpty() ){
-        if(type=="CREATE"){ isAttached=TRUE; }
-        //Simple check to make sure that a couple types of devices are never used
-        if(!cdev.contains("/") && !cdev.contains("pass") ){
-          cdev.prepend("/dev/");
-          if( QFile::symLinkTarget(cdev).isEmpty() && isAttached && QFile::exists(cdev) ){
-            deviceFound=TRUE;
-          }
-          else if(!isAttached){
-            //Find out if this device is on the list of currently connected devices
-  	    if( findDeviceInList(newDeviceAction(cdev,"JUNK"))!=-1 ){ deviceFound=TRUE; }
-          }
-        }
-      } // end cdevtype device check
+        if( isAttached && !dlab.isEmpty() && (index == -1) ){ deviceFound = TRUE; }
+	
+      }else if( !isAttached && ( index != -1) ){ deviceFound = TRUE; }
     }
     //Perform action if a device is found
     if(deviceFound){
-      checkDevices(); // this will remove any stale device links
       if(isAttached){
-      	QAction* newdev = newDeviceAction(cdev,cdevtype);  
-        qDebug() << "New device detected:" << newdev->text() << newdev->whatsThis() << newdev->statusTip();
-	if( !newdev->statusTip().isEmpty() ){ //make sure the device is valid
-          if( updateDeviceList( 1 , newdev ) ){
-            showDeviceNotification(1,newdev);
-            autoMount(newdev,FALSE);
-          }
+        qDebug() << "New device detected:" << dlab << cdev << cdevtype << dfs << dmax +" blocks";
+	if(dmax.toInt() > 60){     
+	   addDevice(cdev,dlab);  
+	   QString title = tr("New Device");
+	   QString message = QString( tr("%1 can now be accessed")).arg(dlab);
+	   slotDisplayPopup(title, message);
 	}else{ 
-	  qDebug() << " - Ignoring device (less than 1MB of storage detected)";
+	  qDebug() << " - Ignoring device (less than 60 blocks/sectors detected)";
 	}
       }else{
+	removeDevice(cdev);
         qDebug() << "Device removal detected:" <<  cdev;
       }
-      //Update the Tray menu
-      updateTrayMenu();
     }
   } // end loop over all devd output lines
 }
 
-void MountTray::menuDeviceToggled(QAction* currentAct){
-  //Make sure that the device list is current
-  checkDevices();
-  //Get the parent action (parentAct->submenu->currentAct)
-  //qDebug() << currentAct->whatsThis();
-  QAction* device = newDeviceAction( currentAct->whatsThis() );
-  //qDebug() << device->whatsThis() << device->text() << device->statusTip();
-  int index = findDeviceInList(device);
-  if(index == -1){ return;} //invalid index
-
-  if(currentAct->isCheckable()){ //toggling auto-mount
-    qDebug() << "Auto-mount toggled for device: "<< currentAct->whatsThis()<<currentAct->isChecked();
-    setAutoMount(devList[index],currentAct->isChecked());
-    autoMount(devList[index],FALSE);
-  }else{  //mount or unmount
-    if( isMounted(devList[index]) ){
-      //Unmount the device
-      if( updateDeviceList(3,devList[index]) ){
-        showDeviceNotification(3,devList[index]);
-      }
-    }else{
-      //Mount the device
-      if( updateDeviceList(2,devList[index]) ){
-        showDeviceNotification(2,devList[index]);
-      }
-    }
-  }
-  //Refresh the menu
-  updateTrayMenu();
-}
-
-void MountTray::menuDeviceHovered(QAction* device){
-  //Display tooltip if there is one
-  if(device->toolTip() != device->text()){
-    QToolTip::showText(QCursor::pos(), device->toolTip());
-  }else{
-    QToolTip::showText(QCursor::pos(), ""); 
-  }
-}
-
 void MountTray::closeTray(){
   qDebug() << "pc-mounttray: closing down";
   //Kill the devd watching process
-  devdProc->terminate();
+  devdProc->disconnectFromServer();
   //Close down the application
   exit(0);
 }
@@ -701,102 +292,24 @@
   system( cmd.toUtf8() ); 
 }
 
+void MountTray::slotRescan(){
+  //Display a notification
+  slotDisplayPopup(tr("Please Wait"),tr("Rescanning devices attached to the system"));
+  //Rescan the device list for new devices
+  scanInitialDevices();
+  //Check that all the existing devices still exist
+  for(int i=0; i<deviceList.length(); i++){
+    deviceList[i]->updateItem();
+  }
+}
+
 void MountTray::slotSingleInstance()
 {
   trayIcon->show();
 }
 
-void MountTray::loadAutoMountFile(){
-  QFile file(AMFILE);
-  if(file.exists()){
-    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
-      qDebug() << "Could not open file for reading:" << AMFILE;
-    }else{
-      QTextStream in(&file);
-      while(!in.atEnd()){
-        AMList << in.readLine();
-      }
-    }
-    file.close();
-  }
+void MountTray::slotDisplayPopup(QString title, QString msg){
+  //Display a popup bubble with the given message for 3 seconds
+  trayIcon->contextMenu()->hide(); //close the menu list
+  trayIcon->showMessage(title, msg , QSystemTrayIcon::NoIcon,3000 );
 }
-
-void MountTray::setAutoMount(QAction* device, bool enable){
-  QString listchk = device->text()+":::"+device->statusTip();
-  bool changed=FALSE;
-  if(AMList.contains(listchk) ){
-    if(enable){}//do nothing, already enabled
-    else{ 
-      AMList.removeAll(listchk); 
-      changed=TRUE;
-    } //Remove this entry
-  }else{
-    if(enable){ 
-      AMList << listchk;
-      changed=TRUE;
-    }else{} //do nothing, not enabled already;
-  }
-  //Save the changes to file if needed
-  if(changed){
-    QFile file(AMFILE);
-    if(!file.open(QIODevice::WriteOnly | QIODevice::Text)){
-      qDebug() << "Could not open file for writing:" << AMFILE;
-    }else{
-      QTextStream out(&file);
-      for(int i=0; i<AMList.length(); i++){
-        out << AMList[i] << "\n";
-      }
-    }
-    file.close();
-  }
-
-}
-
-void MountTray::autoMount(QAction* device,bool onStartup){
-  if( isAutoMountEnabled(device) && !isMounted(device) ){
-    if(onStartup){ updateDeviceList(5,device); } //Mount device silently
-    else{ updateDeviceList(2, device); }//mount the device (and open dir)
-  }
-}
-
-bool MountTray::isAutoMountEnabled(QAction* device){
-  QString listchk = device->text()+":::"+device->statusTip();
-  if(AMList.contains(listchk)){ return TRUE; }
-  else{ return FALSE; }
-}
-
-void MountTray::setSubMenu(QAction* device){
-  QMenu* submenu = new QMenu;
-  QString dev = device->whatsThis().section("/",-1);
-  // - mount/unmount
-  QAction* mount = new QAction(this);
-  mount->setWhatsThis(dev);
-  if( isMounted(device) ){
-    mount->setText( QString(tr("Unmount %1")).arg(dev) );
-  }else{
-    mount->setText( QString(tr("Mount %1")).arg(dev) );
-  }
-  submenu->addAction(mount);
-  // - device automount
-  QAction* amchk = new QAction(tr("Auto-mount"),this);
-  amchk->setWhatsThis(dev);
-  amchk->setCheckable(TRUE);
-  amchk->setChecked( isAutoMountEnabled(device) );
-  submenu->addAction(amchk);
-  //Setup the signal/slot connections
-  connect(submenu, SIGNAL(triggered(QAction*)), this, SLOT(menuDeviceToggled(QAction*)) );
-  //connect(submenu, SIGNAL(hovered(QAction*)), this, SLOT(menuDeviceHovered(QAction*)) );
-  //Add the submenu
-  device->setMenu(submenu);
-
-}
-
-void MountTray::checkDevices(){
-  for(int i=0; i<devList.length(); i++){
-    if( !isConnected(devList[i]) ){
-      //Remove the dead device link from the action list
-      updateDeviceList(4,devList[i]);
-      i--; //make sure we account for the new size of the list
-    }
-  }
-}

Modified: pcbsd/branches/9.1/src-qt4/pc-mounttray/mountTray.h
===================================================================
--- pcbsd/branches/9.1/src-qt4/pc-mounttray/mountTray.h	2012-10-29 19:03:49 UTC (rev 20066)
+++ pcbsd/branches/9.1/src-qt4/pc-mounttray/mountTray.h	2012-10-29 19:04:04 UTC (rev 20067)
@@ -1,11 +1,14 @@
+#ifndef MOUNT_TRAY_H
+#define MOUNT_TRAY_H
+
 // QT Includes
 #include <qpair.h>
-#include <QProcess>
 #include <QDialog>
-#include <QFileSystemWatcher>
 #include <QSystemTrayIcon>
 #include <QMenu>
+#include <QLocalSocket>
 
+#include "menuItem.h"
 
 class QString;
 class QPixmap;
@@ -25,39 +28,31 @@
 private slots:
   void closeTray();
   void slotSingleInstance();
-  void menuDeviceToggled(QAction*);
-  void menuDeviceHovered(QAction*);
   void newDevdMessage();
   void slotTrayActivated(QSystemTrayIcon::ActivationReason);
   void slotOpenMediaDir();
-  void autoMount(QAction*,bool onstartup);  
+  void openMediaDir(QString); 
+  void slotDisplayPopup(QString,QString);
+  void removeDevice(QString);
+  void slotRescan();
   
 private:
-  QString MOUNTDIR, DEVICEDIR, USERNAME, FILEMAN, AMFILE;
-  QProcess *devdProc;
-  QStringList AMList;
+  QString MOUNTDIR, DEVICEDIR, USERNAME, FILEMAN;
+  QLocalSocket* devdProc;
   int numMount, numAvail;
   QSystemTrayIcon* trayIcon;
   QMenu* trayIconMenu;
-  QList<QAction*> devList;
-  void showDeviceNotification(int, QAction*);
-  void initialDeviceScan();
-  bool isMounted(QAction*);
-  bool isConnected(QAction*);
-  bool updateDeviceList(int, QAction*);
-  int findDeviceInList(QAction*);
-  bool mountDevice(QAction*,bool openDir=TRUE);
-  bool unmountDevice(QAction*);
-  QAction* newDeviceAction(QString,QString type="USB");
-  void updateTrayMenu();
+  QList<MenuItem*> deviceList;
+
+  void updateMenu();
+  void scanInitialDevices();
+  int findDeviceInList(QString);
+  void addDevice(QString,QString);
   void startupDevdProc();
-  void openMediaDir(QString);
   void setDeviceIcon(QAction*);
   void getInitialUsername();
   void getDefaultFileManager();
-  void loadAutoMountFile();
-  void setAutoMount(QAction*, bool);
-  bool isAutoMountEnabled(QAction*);
-  void setSubMenu(QAction*);
-  void checkDevices();
+
 };
+
+#endif

Modified: pcbsd/branches/9.1/src-qt4/pc-mounttray/pc-mounttray.pro
===================================================================
--- pcbsd/branches/9.1/src-qt4/pc-mounttray/pc-mounttray.pro	2012-10-29 19:03:49 UTC (rev 20066)
+++ pcbsd/branches/9.1/src-qt4/pc-mounttray/pc-mounttray.pro	2012-10-29 19:04:04 UTC (rev 20067)
@@ -1,14 +1,14 @@
 TEMPLATE	= app
 LANGUAGE	= C++
-QT	+= core gui
+QT	+= core gui network
 
 CONFIG	+= qt warn_on release
 
 LIBS    += -lQtSolutions_SingleApplication-head -lpcbsd
 
-HEADERS	+= mountTray.h
+HEADERS	+= mountTray.h menuItem.h
 
-SOURCES	+= main.cpp mountTray.cpp
+SOURCES	+= main.cpp mountTray.cpp menuItem.cpp
 
 RESOURCES += pc-mounttray.qrc
 

Modified: pcbsd/branches/9.1/src-qt4/pc-mounttray/pc-mounttray.qrc
===================================================================
--- pcbsd/branches/9.1/src-qt4/pc-mounttray/pc-mounttray.qrc	2012-10-29 19:03:49 UTC (rev 20066)
+++ pcbsd/branches/9.1/src-qt4/pc-mounttray/pc-mounttray.qrc	2012-10-29 19:04:04 UTC (rev 20067)
@@ -1,11 +1,16 @@
 <RCC>
   <qresource>
-    <file>icons/USBblue.png</file>
-    <file>icons/USBred.png</file>
-    <file>icons/USBgrey.png</file>
+    <file>icons/usb.png</file>
+    <file>icons/dvd.png</file>
+    <file>icons/sdcard.png</file>
     <file>icons/CDdevices.png</file>
     <file>icons/CDdevices-inactive.png</file>
     <file>icons/folder.png</file>
     <file>icons/application-exit.png</file>
+    <file>icons/eject.png</file>
+    <file>icons/mount.png</file>
+    <file>icons/musiccd.png</file>
+    <file>icons/harddrive.png</file>
+    <file>icons/refresh.png</file>
   </qresource>
 </RCC>



More information about the Commits mailing list