summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2012-09-08 20:34:36 +0200
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2012-09-08 20:34:36 +0200
commit328ff6d979c028ecba9c57d12c1e75637be20396 (patch)
tree1373b766c7a1b0a6551816f105ee7447c0f602ae
parent4f99dd4264f9aaaccbf3da6bba37d5b2c7eb6f32 (diff)
downloadrockbox-328ff6d979c028ecba9c57d12c1e75637be20396.zip
rockbox-328ff6d979c028ecba9c57d12c1e75637be20396.tar.gz
rockbox-328ff6d979c028ecba9c57d12c1e75637be20396.tar.bz2
rockbox-328ff6d979c028ecba9c57d12c1e75637be20396.tar.xz
Add "Eject" button to main window.
Since especially Windows puts the eject functionality behind an icon in the systray which is usually hidden and doesn't complain if a USB drive is unplugged without ejecting it first ejecting such a device might not be obvious to everyone. Add a button to the main window allowing to eject the selected player. Currently only implemented for Windows. Change-Id: I785ac1482cda03a1379cf6d0fd0d9a0ff8130092
-rw-r--r--rbutil/rbutilqt/base/utils.cpp60
-rw-r--r--rbutil/rbutilqt/base/utils.h1
-rw-r--r--rbutil/rbutilqt/icons/media-eject.pngbin0 -> 628 bytes
-rw-r--r--rbutil/rbutilqt/rbutilqt.cpp22
-rw-r--r--rbutil/rbutilqt/rbutilqt.h1
-rw-r--r--rbutil/rbutilqt/rbutilqt.qrc1
-rw-r--r--rbutil/rbutilqt/rbutilqtfrm.ui77
7 files changed, 135 insertions, 27 deletions
diff --git a/rbutil/rbutilqt/base/utils.cpp b/rbutil/rbutilqt/base/utils.cpp
index 3821b67..cffa4b1 100644
--- a/rbutil/rbutilqt/base/utils.cpp
+++ b/rbutil/rbutilqt/base/utils.cpp
@@ -692,3 +692,63 @@ QStringList Utils::findRunningProcess(QStringList names)
qDebug() << "[Utils] Found listed processes running:" << found;
return found;
}
+
+
+/** Eject device from PC.
+ * Request the OS to eject the player.
+ * @param device mountpoint of the device
+ * @return true on success, fals otherwise.
+ */
+bool Utils::ejectDevice(QString device)
+{
+#if defined(Q_OS_WIN32)
+ /* See http://support.microsoft.com/kb/165721 on the procedure to eject a
+ * device. */
+ bool success = false;
+ int i;
+ HANDLE hdl;
+ DWORD bytesReturned;
+ TCHAR volume[8];
+
+ /* CreateFile */
+ _stprintf(volume, _TEXT("\\\\.\\%c:"), device.toAscii().at(0));
+ hdl = CreateFile(volume, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, 0, NULL);
+ if(hdl == INVALID_HANDLE_VALUE)
+ return false;
+
+ /* lock volume to make sure no other application is accessing the volume.
+ * Try up to 10 times. */
+ for(i = 0; i < 10; i++) {
+ if(DeviceIoControl(hdl, FSCTL_LOCK_VOLUME,
+ NULL, 0, NULL, 0, &bytesReturned, NULL))
+ break;
+ /* short break before retry */
+ Sleep(100);
+ }
+ if(i < 10) {
+ /* successfully locked, now dismount */
+ if(DeviceIoControl(hdl, FSCTL_DISMOUNT_VOLUME,
+ NULL, 0, NULL, 0, &bytesReturned, NULL)) {
+ /* make sure media can be removed. */
+ PREVENT_MEDIA_REMOVAL pmr;
+ pmr.PreventMediaRemoval = false;
+ if(DeviceIoControl(hdl, IOCTL_STORAGE_MEDIA_REMOVAL,
+ &pmr, sizeof(PREVENT_MEDIA_REMOVAL),
+ NULL, 0, &bytesReturned, NULL)) {
+ /* eject the media */
+ if(DeviceIoControl(hdl, IOCTL_STORAGE_EJECT_MEDIA,
+ NULL, 0, NULL, 0, &bytesReturned, NULL))
+ success = true;
+ }
+ }
+ }
+ /* close handle */
+ CloseHandle(hdl);
+ return success;
+
+#endif
+ return false;
+}
+
diff --git a/rbutil/rbutilqt/base/utils.h b/rbutil/rbutilqt/base/utils.h
index 185c032..db52bfb 100644
--- a/rbutil/rbutilqt/base/utils.h
+++ b/rbutil/rbutilqt/base/utils.h
@@ -50,6 +50,7 @@ public:
static QString resolveDevicename(QString path);
static QString resolveMountPoint(QString device);
static QStringList findRunningProcess(QStringList names);
+ static bool ejectDevice(QString device);
};
#endif
diff --git a/rbutil/rbutilqt/icons/media-eject.png b/rbutil/rbutilqt/icons/media-eject.png
new file mode 100644
index 0000000..2084067
--- /dev/null
+++ b/rbutil/rbutilqt/icons/media-eject.png
Binary files differ
diff --git a/rbutil/rbutilqt/rbutilqt.cpp b/rbutil/rbutilqt/rbutilqt.cpp
index 62a4f58..aa0c365 100644
--- a/rbutil/rbutilqt/rbutilqt.cpp
+++ b/rbutil/rbutilqt/rbutilqt.cpp
@@ -110,6 +110,11 @@ RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
RegCloseKey(hk);
}
#endif
+
+#if !defined(Q_OS_WIN32)
+ /* eject funtionality is only implemented on W32 right now. */
+ ui.buttonEject->setEnabled(false);
+#endif
updateDevice();
downloadInfo();
@@ -142,6 +147,7 @@ RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(configDialog()));
connect(ui.actionE_xit, SIGNAL(triggered()), this, SLOT(shutdown()));
connect(ui.buttonChangeDevice, SIGNAL(clicked()), this, SLOT(configDialog()));
+ connect(ui.buttonEject, SIGNAL(clicked()), this, SLOT(eject()));
connect(ui.buttonTalk, SIGNAL(clicked()), this, SLOT(createTalkFiles()));
connect(ui.buttonCreateVoice, SIGNAL(clicked()), this, SLOT(createVoiceFile()));
connect(ui.buttonVoice, SIGNAL(clicked()), this, SLOT(installVoice()));
@@ -733,3 +739,19 @@ void RbUtilQt::changeEvent(QEvent *e)
}
}
+void RbUtilQt::eject(void)
+{
+ QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
+ if(Utils::ejectDevice(mountpoint)) {
+ QMessageBox::information(this, tr("Device ejected"),
+ tr("Device successfully ejected. "
+ "You may now disconnect the player from the PC."));
+ }
+ else {
+ QMessageBox::critical(this, tr("Ejecting failed"),
+ tr("Ejecting the device failed. Please make sure no programs "
+ "are accessing files on the device. If ejecting still "
+ "fails please use your computers eject funtionality."));
+ }
+}
+
diff --git a/rbutil/rbutilqt/rbutilqt.h b/rbutil/rbutilqt/rbutilqt.h
index 1db1004..350aca1 100644
--- a/rbutil/rbutilqt/rbutilqt.h
+++ b/rbutil/rbutilqt/rbutilqt.h
@@ -79,6 +79,7 @@ class RbUtilQt : public QMainWindow
void help(void);
void sysinfo(void);
void trace(void);
+ void eject(void);
void configDialog(void);
void updateDevice(void);
void updateSettings(void);
diff --git a/rbutil/rbutilqt/rbutilqt.qrc b/rbutil/rbutilqt/rbutilqt.qrc
index 5305a98..d1eea68 100644
--- a/rbutil/rbutilqt/rbutilqt.qrc
+++ b/rbutil/rbutilqt/rbutilqt.qrc
@@ -19,6 +19,7 @@
<file>icons/edit-find.png</file>
<file>icons/font_btn.png</file>
<file>icons/go-next.png</file>
+ <file>icons/media-eject.png</file>
<file>icons/network-idle.png</file>
<file>icons/package-x-generic.png</file>
<file>icons/preferences-desktop-locale.png</file>
diff --git a/rbutil/rbutilqt/rbutilqtfrm.ui b/rbutil/rbutilqt/rbutilqtfrm.ui
index 85da42e..65348da 100644
--- a/rbutil/rbutilqt/rbutilqtfrm.ui
+++ b/rbutil/rbutilqt/rbutilqtfrm.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>650</width>
- <height>550</height>
+ <height>399</height>
</rect>
</property>
<property name="windowTitle">
@@ -31,24 +31,25 @@
<string>Device</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="1" column="2">
- <widget class="QLabel" name="labelMountpoint">
- <property name="text">
- <string>mountpoint unknown or invalid</string>
+ <item row="0" column="0" rowspan="3">
+ <widget class="QLabel" name="labelPlayerPic">
+ <property name="lineWidth">
+ <number>1</number>
</property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="labelMountpointTitle">
<property name="text">
- <string>Mountpoint:</string>
+ <string/>
</property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="labelDevice">
- <property name="text">
- <string>device unknown or invalid</string>
+ <property name="pixmap">
+ <pixmap resource="rbutilqt.qrc">:/icons/rockbox-32.png</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="margin">
+ <number>3</number>
</property>
</widget>
</item>
@@ -65,6 +66,13 @@
</property>
</widget>
</item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="labelDevice">
+ <property name="text">
+ <string>device unknown or invalid</string>
+ </property>
+ </widget>
+ </item>
<item row="0" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -78,24 +86,39 @@
</property>
</spacer>
</item>
- <item row="0" column="0" rowspan="2">
- <widget class="QLabel" name="labelPlayerPic">
+ <item row="0" column="4">
+ <widget class="QPushButton" name="buttonChangeDevice">
<property name="text">
- <string/>
+ <string>&amp;Change</string>
</property>
- <property name="scaledContents">
- <bool>true</bool>
+ <property name="icon">
+ <iconset resource="rbutilqt.qrc">
+ <normaloff>:/icons/edit-find.png</normaloff>:/icons/edit-find.png</iconset>
</property>
</widget>
</item>
- <item row="0" column="4" rowspan="2">
- <widget class="QPushButton" name="buttonChangeDevice">
+ <item row="1" column="4" rowspan="2">
+ <widget class="QPushButton" name="buttonEject">
<property name="text">
- <string>&amp;Change</string>
+ <string>&amp;Eject</string>
</property>
<property name="icon">
<iconset resource="rbutilqt.qrc">
- <normaloff>:/icons/edit-find.png</normaloff>:/icons/edit-find.png</iconset>
+ <normaloff>:/icons/media-eject.png</normaloff>:/icons/media-eject.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelMountpointTitle">
+ <property name="text">
+ <string>Mountpoint:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="labelMountpoint">
+ <property name="text">
+ <string>mountpoint unknown or invalid</string>
</property>
</widget>
</item>
@@ -130,7 +153,7 @@
<item row="1" column="0" colspan="2">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
- <number>7</number>
+ <number>0</number>
</property>
<widget class="QWidget" name="selective">
<attribute name="title">
@@ -388,7 +411,7 @@
<x>0</x>
<y>0</y>
<width>650</width>
- <height>23</height>
+ <height>21</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">