[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Automatic addition of device icons to desktop
From:       Preston Brown <pbrown () brown-house ! net>
Date:       2001-03-22 6:37:46
[Download RAW message or body]

Attached is a patch against KDE 2.1.1 which will attempt (valiantly, but it 
could definitely be improved) to add device icons for removable/user 
controllable devices to the desktop upon startup and whenever /etc/fstab 
changes.  If people like it, I am considering committing to HEAD.

BTW, it was the first bit of KDE programming I have done in awhile.  It felt 
good.

-- 
  Preston Brown
  pbrown@brown-house.net

["kdebase-2.1.1-dynamicdevices.patch" (text/plain)]

? kant/kwrite/Makefile.in
? kant/kwrite/Makefile
Index: kcontrol/konq/rootopts.cpp
===================================================================
RCS file: /home/kde/kdebase/kcontrol/konq/rootopts.cpp,v
retrieving revision 1.50
diff -u -r1.50 rootopts.cpp
--- kcontrol/konq/rootopts.cpp	2001/02/10 21:51:29	1.50
+++ kcontrol/konq/rootopts.cpp	2001/03/22 06:32:55
@@ -128,7 +128,23 @@
                                     " of Macintosh.  This setting is independent of \
                the global top-level"
                                     " menu setting that applies to KDE \
applications.") );  
+#ifdef HAVE_MNTENT_H
   row++;
+  dynamicDevicesBox = new QCheckBox(i18n("Enable Dynamic Desktop Devices"), 
+				    this);
+  lay->addMultiCellWidget(dynamicDevicesBox, row, row, 0, 0);
+  connect(dynamicDevicesBox, SIGNAL(clicked()), this, SLOT(changed()));
+  QWhatsThis::add(dynamicDevicesBox, 
+		  i18n("If you check this option, any"
+		       " removable devices that you have"
+		       " permission to mount will be"
+		       " shown on the desktop. If you add or remove devices,"
+		       " icons will be updated accordingly.<p>"
+		       "This usually includes CD-ROM drives, ZIP"
+		       " drives, etc."));
+#endif
+
+  row++;
   lay->setRowStretch( row, 10 );
   previewListView = new QListView( this );
   previewListView->addColumn( i18n("Show Previews for:") );
@@ -330,6 +346,9 @@
     QStringList previews = g_pConfig->readListEntry("Preview");
     for (KTrader::OfferList::ConstIterator it = plugins.begin(); it != \
                plugins.end(); ++it)
         new PreviewItem(this, previewListView, *it, \
previews.contains((*it)->desktopEntryName())); +#ifdef HAVE_MNTENT_H
+    dynamicDevicesBox->setChecked(g_pConfig->readBoolEntry("DynamicDevices", \
DEFAULT_DYNAMIC_DEVICES)); +#endif
     //
     g_pConfig->setGroup( "Menubar" );
     bool bMenuBar = g_pConfig->readBoolEntry("ShowMenubar", false);
@@ -363,6 +382,9 @@
     VertAlignBox->setChecked(true);
     for (QListViewItem *item = previewListView->firstChild(); item; item = \
item->nextSibling())  static_cast<PreviewItem *>(item)->setOn(false);
+#ifdef HAVE_MNTENT_H
+    dynamicDevicesBox->setChecked(DEFAULT_DYNAMIC_DEVICES);
+#endif
     menuBarBox->setChecked(false);
     leftComboBox->setCurrentItem( NOTHING );
     middleComboBox->setCurrentItem( WINDOWLISTMENU );
@@ -387,6 +409,9 @@
         if ( item->isOn() )
             previews.append( item->pluginName() );
     g_pConfig->writeEntry( "Preview", previews );
+#ifdef HAVE_MNTENT_H
+    g_pConfig->writeEntry( "DynamicDevices", dynamicDevicesBox->isChecked());
+#endif
     g_pConfig->setGroup( "Menubar" );
     g_pConfig->writeEntry("ShowMenubar", menuBarBox->isChecked());
     g_pConfig->setGroup( "Mouse Buttons" );
Index: kcontrol/konq/rootopts.h
===================================================================
RCS file: /home/kde/kdebase/kcontrol/konq/rootopts.h,v
retrieving revision 1.22
diff -u -r1.22 rootopts.h
--- kcontrol/konq/rootopts.h	2001/01/09 07:18:31	1.22
+++ kcontrol/konq/rootopts.h	2001/03/22 06:32:55
@@ -53,6 +53,7 @@
         QCheckBox *showHiddenBox;
         QCheckBox *VertAlignBox;
         QCheckBox *menuBarBox;
+	QCheckBox *dynamicDevicesBox;
         QListView *previewListView;
 
         // Combo for the menus
Index: kdesktop/desktop.cc
===================================================================
RCS file: /home/kde/kdebase/kdesktop/desktop.cc,v
retrieving revision 1.217
diff -u -r1.217 desktop.cc
--- kdesktop/desktop.cc	2001/02/08 10:57:58	1.217
+++ kdesktop/desktop.cc	2001/03/22 06:32:56
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.
 */
 
+#include <config.h>
 
 #include <assert.h>
 #include <string.h>
@@ -25,6 +26,10 @@
 #include <unistd.h>
 #include <kcolordrag.h>
 
+#ifdef HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+
 #include <qkeycode.h>
 #include <qpalette.h>
 #include <qdragobject.h>
@@ -68,6 +73,9 @@
 #include <kstdaction.h>
 #include <kglobalsettings.h>
 #include <kpopupmenu.h>
+#include <kdesktopfile.h>
+#include <kdirwatch.h>
+#include <kmimemagic.h>
 
 // root window hack
 #include <X11/X.h>
@@ -98,6 +106,7 @@
 
   m_bAutoStart = auto_start;
   m_bWaitForKded = wait_for_kded;
+  m_etcDirWatcher = 0L;
   KGlobal::locale()->insertCatalogue("kdesktop");
   KGlobal::locale()->insertCatalogue("libkonq"); // needed for apps using libkonq
   m_language = KGlobal::locale()->language();
@@ -310,6 +319,7 @@
 KDesktop::~KDesktop()
 {
   delete m_dirLister;
+  delete m_etcDirWatcher;
   delete bgMgr;
   delete keys;
 }
@@ -325,6 +335,20 @@
     QStringList oldPreview = m_preview;
     m_preview = config->readListEntry( "Preview" );
 
+#ifdef HAVE_MNTENT_H
+    m_bDynamicDevices = config->readBoolEntry("DynamicDevices", \
DEFAULT_DYNAMIC_DEVICES); +    if (m_bDynamicDevices) {
+	// start watching /etc/fstab
+	m_etcDirWatcher = new KDirWatch();
+	m_etcDirWatcher->addDir("/etc");
+	connect(m_etcDirWatcher, SIGNAL(dirty(const QString &)), 
+		SLOT(updateDynamicDevices()));
+
+	// create dynamic device icons if necessary
+	updateDynamicDevices();
+    }
+#endif
+    
     if ( !m_bInit ) { // only when called while running - not on first startup
         m_dirLister->setShowingDotFiles( m_bShowDot );
         keys->readSettings();
@@ -416,6 +440,152 @@
 {
   KonqIconViewWidget::lineupIcons();
   slotSaveIconPositions();
+}
+
+// -----------------------------------------------------------------------------
+
+void KDesktop::updateDynamicDevices()
+{
+    kdDebug() << "KDesktop::updateDynamicDevices()" << endl;
+#ifdef HAVE_MNTENT_H
+    static bool warnAlready = false;
+    static bool bFirst = true;
+    static QDateTime lastFstabModTime;
+
+    if (::access("/etc/fstab", R_OK) == -1) {
+	kdDebug() << "Couldn't open /etc/fstab" << endl;
+	if (!warnAlready) {
+	    KMessageBox::error(this, i18n("Couldn't open /etc/fstab to create dynamic \
devices: %1").arg(strerror(errno))); +	    warnAlready = true;
+	}
+	return;
+    }
+
+    if (bFirst)
+	lastFstabModTime = QFileInfo("/etc/fstab").lastModified();
+
+    if (lastFstabModTime >= QFileInfo("/etc/fstab").lastModified() && !bFirst)
+	return;
+
+    if (bFirst) bFirst = false;
+    lastFstabModTime = QFileInfo("/etc/fstab").lastModified();
+    QDir desktopDir(KGlobalSettings::desktopPath());
+    QStringList dList = desktopDir.entryList(QDir::Files);
+
+    FILE *fp = setmntent("/etc/fstab", "r");
+    struct mntent *mnt_ent;
+
+#define FS_DEVICE mnt_ent->mnt_fsname
+#define FS_MNTPOINT mnt_ent->mnt_dir
+#define FS_TYPE mnt_ent->mnt_type
+#define FS_MNTOPTS mnt_ent->mnt_opts
+    
+    QString fileName;
+    // examine all partitions/devices
+    while ((mnt_ent = getmntent(fp)) != 0) {
+	// build a list of those devices we are interested in.
+	if (hasmntopt(mnt_ent, "owner") ||
+	    hasmntopt(mnt_ent, "user")) {
+	    // found a user controllable device.  Is it on the desktop?
+	    bool found = false;
+	    for (QStringList::Iterator it = dList.begin();
+		 it != dList.end(); ++it) {
+		fileName = desktopDir.absPath() + "/" + *it;
+		if (KMimeMagic::self()->findFileType(fileName)->mimeType() !=
+		    "application/x-desktop")
+		    continue;
+		KDesktopFile devFile(fileName, true);
+		if (devFile.readType() != "FSDevice")
+		    continue;
+		if (devFile.readEntry("Dev") == FS_DEVICE &&
+		    devFile.readEntry("MountPoint") == FS_MNTPOINT) {
+		    found = true;
+		    break;
+		}
+		
+	    }
+	    
+	    if (!found) {
+		// no desktop file for this device found, create one.
+		fileName = desktopDir.absPath() + "/" + 
+		    QFileInfo(FS_MNTPOINT).baseName();
+		KDesktopFile devFile(fileName);
+		devFile.writeEntry("Type", "FSDevice");
+		devFile.writeEntry("Dev", FS_DEVICE);
+		devFile.writeEntry("MountPoint", FS_MNTPOINT);
+		devFile.writeEntry("FSType", FS_TYPE);
+		// heuristic for icon 
+		if (strstr(FS_TYPE, "iso9660") != 0) {
+		    devFile.writeEntry("ReadOnly", true);
+		}
+		if (strstr(FS_MNTPOINT, "cdrom") != 0) {
+		    devFile.writeEntry("Icon", "cdrom_mount");
+		    devFile.writeEntry("UnmountIcon", "cdrom_unmount");
+		} else if (strstr(FS_MNTPOINT, "cdwrite") != 0 ||
+			   strstr(FS_MNTPOINT, "cdrw") != 0) {
+		    devFile.writeEntry("Icon", "cdwriter_mount");
+		    devFile.writeEntry("UnmountIcon", "cdwriter_unmount");
+		} else if (strstr(FS_MNTPOINT, "zip") != 0) {
+		    devFile.writeEntry("Icon", "zip_mount");
+		    devFile.writeEntry("UnmountIcon", "zip_unmount");
+		} else if (strstr(FS_MNTPOINT, "jaz") != 0) {
+		    devFile.writeEntry("Icon", "zip_mount");
+		    devFile.writeEntry("UnmountIcon", "zip_unmount");
+		} else if (strstr(FS_MNTPOINT, "ls120") != 0) {
+		    devFile.writeEntry("Icon", "3floppy_mount");
+		    devFile.writeEntry("UnmountIcon", "3floppy_unmount");
+		} else if (strstr(FS_MNTPOINT, "camera") != 0) {
+		    devFile.writeEntry("Icon", "memory");
+		} else if (strstr(FS_MNTPOINT, "memstick") != 0) {
+		    devFile.writeEntry("Icon", "memory");
+		} else if (strstr(FS_MNTPOINT, "flash") != 0) {
+		    devFile.writeEntry("Icon", "memory");
+		} else if (strstr(FS_MNTPOINT, "floppy") != 0) {
+		    devFile.writeEntry("Icon", "3floppy_mount");
+		    devFile.writeEntry("UnmountIcon", "3floppy_unmount");
+		} else {
+		    // catch all
+		    devFile.writeEntry("Icon", "hdd_mount");
+		    devFile.writeEntry("UnmountIcon", "hdd_unmount");
+		}
+		    
+		devFile.writeEntry("X-KDE-Dynamic-Device", true);
+		devFile.sync(); // write
+		kdDebug() << "Created device icon " << fileName << endl;
+	    } /* !found */
+	    
+	} /* owner/user mount opt */
+    } /* fstab iterator */
+    endmntent(fp);
+    
+    // now go through all desktop devices and remove any that may
+    // have disappeared. Opposite of above.
+    dList = desktopDir.entryList(QDir::Files);
+    for (QStringList::Iterator it = dList.begin();
+	 it != dList.end(); ++it) {
+	fileName = desktopDir.absPath() + "/" + *it;
+	KDesktopFile devFile(fileName, true);
+	bool found = false;
+	fp = setmntent("/etc/fstab", "r"); // already checked, we can access
+
+	while ((mnt_ent = getmntent(fp)) != 0) {
+	    if (devFile.readEntry("Dev") == FS_DEVICE &&
+		devFile.readEntry("MountPoint") == FS_MNTPOINT) {
+		found = true;
+		break;
+	    }
+	} /* fstab iterator */
+	endmntent(fp);
+
+	if (!found && devFile.readBoolEntry("X-KDE-Dynamic-Device", false)) {
+	    desktopDir.remove(*it);
+	    kdDebug() << "Removed device icon " << fileName << endl;
+	}
+	
+    } /* dir iterator */
+#else
+    kdDebug() << "This OS does not support dynamic devices" << endl;
+#endif
 }
 
 // -----------------------------------------------------------------------------
Index: kdesktop/desktop.h
===================================================================
RCS file: /home/kde/kdebase/kdesktop/desktop.h,v
retrieving revision 1.101
diff -u -r1.101 desktop.h
--- kdesktop/desktop.h	2001/02/08 10:57:58	1.101
+++ kdesktop/desktop.h	2001/03/22 06:32:56
@@ -32,6 +32,7 @@
 
 class KonqDirLister;
 class KonqSettings;
+class KDirWatch;
 class QCloseEvent;
 class QDropEvent;
 class QPopupMenu;
@@ -179,6 +180,9 @@
     // set the vroot atom for e.g. xsnow
   void setVRoot();
 
+  // called if dynamic device icons enabled
+  void updateDynamicDevices();
+  
 public slots: // for krootwm
 
   void slotPaste();
@@ -222,6 +226,9 @@
   /** Vertical or Horizontal align of icons on desktop */
   uint m_bVertAlign:1;
 
+  /** Dynamically generate desktop removable desktop devices from /etc/fstab */
+  uint m_bDynamicDevices:1;
+  
   QIconView::Arrangement m_tAlign;
 
   /** Settings - see libkonq/konqsettings.* */
@@ -230,6 +237,9 @@
   /** The directory lister for this URL */
   KonqDirLister* m_dirLister;
 
+  /** If dynamic device icons enabled, this will be used to watch /etc/fstab */
+  KDirWatch *m_etcDirWatcher;
+  
   KGlobalAccel *keys;
   KAccel *m_accel;
 
Index: libkonq/konq_defaults.h
===================================================================
RCS file: /home/kde/kdebase/libkonq/konq_defaults.h,v
retrieving revision 1.21
diff -u -r1.21 konq_defaults.h
--- libkonq/konq_defaults.h	2000/12/02 18:24:41	1.21
+++ libkonq/konq_defaults.h	2001/03/22 06:32:56
@@ -69,3 +69,4 @@
 #define DEFAULT_DESKTOP_IMAGEPREVIEW false
 #define DEFAULT_DESKTOP_TEXTPREVIEW false
 
+#define DEFAULT_DYNAMIC_DEVICES true



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic