diff --git a/MediaInfoXP.qrc b/MediaInfoXP.qrc
index b5a728a..b002b1d 100644
--- a/MediaInfoXP.qrc
+++ b/MediaInfoXP.qrc
@@ -9,9 +9,11 @@
res/ico_folder.png
res/ico_info.png
res/ico_link.png
+ res/ico_options.png
res/ico_paste.png
res/ico_qt.png
res/ico_quit.png
+ res/ico_shellext.png
res/loading.png
res/logo.png
res/MediaInfo.i386.exe
diff --git a/MediaInfoXP.vcxproj b/MediaInfoXP.vcxproj
index c9e5454..0c7845b 100644
--- a/MediaInfoXP.vcxproj
+++ b/MediaInfoXP.vcxproj
@@ -127,6 +127,7 @@
+
@@ -143,6 +144,7 @@
+
diff --git a/MediaInfoXP.vcxproj.filters b/MediaInfoXP.vcxproj.filters
index 27bf07e..258241c 100644
--- a/MediaInfoXP.vcxproj.filters
+++ b/MediaInfoXP.vcxproj.filters
@@ -48,6 +48,9 @@
Source Files
+
+ Source Files
+
@@ -56,6 +59,9 @@
Header Files
+
+ Header Files
+
diff --git a/gui/Dialog.ui b/gui/Dialog.ui
index 52800cb..9880d70 100644
--- a/gui/Dialog.ui
+++ b/gui/Dialog.ui
@@ -230,12 +230,25 @@
Application
+
+
+
analyzeButton
diff --git a/res/ico_options.png b/res/ico_options.png
new file mode 100644
index 0000000..67de2c6
Binary files /dev/null and b/res/ico_options.png differ
diff --git a/res/ico_shellext.png b/res/ico_shellext.png
new file mode 100644
index 0000000..7b7fbd1
Binary files /dev/null and b/res/ico_shellext.png differ
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index 1000597..fea8a89 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -46,6 +46,7 @@
//Internal
#include "Config.h"
#include "Utils.h"
+#include "ShellExtension.h"
//Macros
#define SET_FONT_BOLD(WIDGET,BOLD) { QFont _font = WIDGET->font(); _font.setBold(BOLD); WIDGET->setFont(_font); }
@@ -105,6 +106,7 @@ CMainWindow::CMainWindow(const QString &tempFolder, QWidget *parent)
connect(ui->actionLink_MediaInfo, SIGNAL(triggered()), this, SLOT(linkTriggered()));
connect(ui->actionLink_Discuss, SIGNAL(triggered()), this, SLOT(linkTriggered()));
connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(showAboutScreen()));
+ connect(ui->actionShellExtension, SIGNAL(toggled(bool)), this, SLOT(updateShellExtension(bool)));
ui->versionLabel->installEventFilter(this);
//Context menu
@@ -192,6 +194,8 @@ void CMainWindow::showEvent(QShowEvent *event)
{
QTimer::singleShot(0, this, SLOT(analyzeFiles()));
}
+
+ QTimer::singleShot(1250, this, SLOT(initShellExtension()));
m_firstShow = false;
}
}
@@ -325,6 +329,7 @@ void CMainWindow::analyzeFiles(void)
ui->actionCopyToClipboard->setEnabled(false);
ui->actionSave->setEnabled(false);
ui->actionOpen->setEnabled(false);
+ ui->menuPreferences->setEnabled(false);
//Show banner
m_floatingLabel->show();
@@ -356,14 +361,20 @@ void CMainWindow::analyzeNextFile(void)
ui->actionOpen->setEnabled(true);
ui->analyzeButton->setEnabled(true);
ui->exitButton->setEnabled(true);
+ ui->menuPreferences->setEnabled(true);
return;
}
const QString filePath = m_pendingFiles.takeFirst();
+ //Generate the command line
+ QStringList commandLine;
+ if(ui->actionVerboseOutput->isChecked()) commandLine << "--Full";
+ commandLine << QDir::toNativeSeparators(filePath);
+
//Start analyziation
qDebug("Analyzing media file:\n%s\n", filePath.toUtf8().constData());
- m_process->start(mediaInfoPath, QStringList() << QDir::toNativeSeparators(filePath));
+ m_process->start(mediaInfoPath, commandLine);
//Wait for process to start
if(!m_process->waitForStarted())
@@ -375,6 +386,7 @@ void CMainWindow::analyzeNextFile(void)
ui->actionOpen->setEnabled(true);
ui->analyzeButton->setEnabled(true);
ui->exitButton->setEnabled(true);
+ ui->menuPreferences->setEnabled(true);
return;
}
@@ -538,6 +550,27 @@ void CMainWindow::processFinished(void)
ui->actionOpen->setEnabled(true);
ui->analyzeButton->setEnabled(true);
ui->exitButton->setEnabled(true);
+ ui->menuPreferences->setEnabled(true);
+}
+
+void CMainWindow::initShellExtension(void)
+{
+ const bool isEnabled = ShellExtension::getEnabled();
+
+ if(isEnabled)
+ {
+ ShellExtension::setEnabled(true);
+ }
+
+ ui->actionShellExtension->blockSignals(true);
+ ui->actionShellExtension->setChecked(isEnabled);
+ ui->actionShellExtension->setEnabled(true);
+ ui->actionShellExtension->blockSignals(false);
+}
+
+void CMainWindow::updateShellExtension(bool checked)
+{
+ ShellExtension::setEnabled(checked);
}
void CMainWindow::linkTriggered(void)
diff --git a/src/MainWindow.h b/src/MainWindow.h
index b937281..f3e9035 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -54,6 +54,8 @@ private slots:
void linkTriggered(void);
void showAboutScreen(void);
void updateSize(void);
+ void initShellExtension(void);
+ void updateShellExtension(bool checked);
protected:
virtual void showEvent(QShowEvent *event);
diff --git a/src/ShellExtension.cpp b/src/ShellExtension.cpp
new file mode 100644
index 0000000..ba8b905
--- /dev/null
+++ b/src/ShellExtension.cpp
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////////
+// MediaInfoXP
+// Copyright (C) 2004-2014 LoRd_MuldeR
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// http://www.gnu.org/licenses/gpl-2.0.txt
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include "ShellExtension.h"
+#include "Utils.h"
+
+#include
+#include
+
+#define MIXP_REGISTRY_KEY "Software\\Classes\\*\\shell\\MediaInfoXP"
+#define MIXP_REGISTRY_VAL "_shellExtEnabled"
+
+bool ShellExtension::getEnabled(void)
+{
+ quint32 value = 0;
+ if(mixp_reg_value_read(mixp_root_user, MIXP_REGISTRY_KEY, MIXP_REGISTRY_VAL, value))
+ {
+ return value;
+ }
+ return false;
+}
+
+bool ShellExtension::setEnabled(bool enabled)
+{
+ if(enabled)
+ {
+ qDebug("Installing the shell extension...");
+ if(mixp_reg_value_write(mixp_root_user, MIXP_REGISTRY_KEY, QString(), tr("Analyze file with MediaInfoXP")))
+ {
+ const QString appPath = QDir::toNativeSeparators(QApplication::applicationFilePath());
+ const QString command = QString().sprintf("\"%ls\" --open \"%%1\"", appPath.utf16());
+ if(mixp_reg_value_write(mixp_root_user, MIXP_REGISTRY_KEY"\\command", QString(), command))
+ {
+ if(mixp_reg_value_write(mixp_root_user, MIXP_REGISTRY_KEY, MIXP_REGISTRY_VAL, 1))
+ {
+ qDebug("Success.\n");
+ mixp_shell_change_notification();
+ return true;
+ }
+ }
+ }
+ qWarning("Failed to install the shell extension!\n");
+ mixp_reg_key_delete(mixp_root_user, MIXP_REGISTRY_KEY);
+ return false;
+ }
+ else
+ {
+ qDebug("Un-installing the shell extension...");
+ if(!mixp_reg_key_delete(mixp_root_user, MIXP_REGISTRY_KEY))
+ {
+ qWarning("Failed to un-install the shell extension!\n");
+ return false;
+ }
+ qDebug("Success.\n");
+ mixp_shell_change_notification();
+ return true;
+ }
+}
diff --git a/src/ShellExtension.h b/src/ShellExtension.h
new file mode 100644
index 0000000..b00d908
--- /dev/null
+++ b/src/ShellExtension.h
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////
+// MediaInfoXP
+// Copyright (C) 2004-2014 LoRd_MuldeR
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// http://www.gnu.org/licenses/gpl-2.0.txt
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include
+
+class ShellExtension : public QObject
+{
+public:
+ static bool getEnabled(void);
+ static bool setEnabled(bool enabled);
+
+private:
+ ShellExtension(void) {}
+ ~ShellExtension(void) {}
+};
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 352df41..b3ce35e 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
//StdLib
#include
@@ -119,8 +120,8 @@ static QString mixp_tryLockFolder(const QString &folderPath, QFile **lockfile)
*/
static const QString &mixp_known_folder(mixp_known_folder_t folder_id)
{
- static const int CSIDL_FLAG_CREATE = 0x8000;
- typedef enum { KF_FLAG_CREATE = 0x00008000 } kf_flags_t;
+ //static const int CSIDL_FLAG_CREATE = 0x8000;
+ //typedef enum { KF_FLAG_CREATE = 0x00008000 } kf_flags_t;
struct
{
@@ -477,6 +478,88 @@ bool mixp_beep(int beepType)
}
}
+/*
+ * Registry root key
+ */
+static HKEY mixp_reg_root(int rootKey)
+{
+ switch(rootKey)
+ {
+ case mixp_root_classes: return HKEY_CLASSES_ROOT; break;
+ case mixp_root_user: return HKEY_CURRENT_USER; break;
+ case mixp_root_machine: return HKEY_LOCAL_MACHINE; break;
+ default: throw "Unknown root reg value was specified!";
+ }
+}
+
+/*
+ * Write registry value
+ */
+bool mixp_reg_value_write(int rootKey, const QString &keyName, const QString &valueName, const quint32 value)
+{
+ bool success = false; HKEY hKey = NULL;
+ if(RegCreateKeyEx(mixp_reg_root(rootKey), QWCHAR(keyName), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
+ {
+ if(RegSetValueEx(hKey, valueName.isEmpty() ? NULL : QWCHAR(valueName), 0, REG_DWORD, reinterpret_cast(&value), sizeof(quint32)) == ERROR_SUCCESS)
+ {
+ success = true;
+ }
+ CloseHandle(hKey);
+ }
+ return success;
+}
+
+/*
+ * Write registry value
+ */
+bool mixp_reg_value_write(int rootKey, const QString &keyName, const QString &valueName, const QString &value)
+{
+ bool success = false; HKEY hKey = NULL;
+ if(RegCreateKeyEx(mixp_reg_root(rootKey), QWCHAR(keyName), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
+ {
+ if(RegSetValueEx(hKey, valueName.isEmpty() ? NULL : QWCHAR(valueName), 0, REG_SZ, reinterpret_cast(value.utf16()), (value.length() + 1) * sizeof(wchar_t)) == ERROR_SUCCESS)
+ {
+ success = true;
+ }
+ CloseHandle(hKey);
+ }
+ return success;
+}
+
+/*
+ * Read registry value
+ */
+bool mixp_reg_value_read(int rootKey, const QString &keyName, const QString &valueName, quint32 &value)
+{
+ bool success = false; HKEY hKey = NULL;
+ if(RegOpenKeyEx(mixp_reg_root(rootKey), QWCHAR(keyName), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ DWORD size = sizeof(quint32), type = -1;
+ if(RegQueryValueEx(hKey, valueName.isEmpty() ? NULL : QWCHAR(valueName), 0, &type, reinterpret_cast(&value), &size) == ERROR_SUCCESS)
+ {
+ success = (type == REG_DWORD);
+ }
+ CloseHandle(hKey);
+ }
+ return success;
+}
+
+/*
+ * Delete registry key
+ */
+bool mixp_reg_key_delete(int rootKey, const QString &keyName)
+{
+ return (RegDeleteTree(mixp_reg_root(rootKey), QWCHAR(keyName)) == ERROR_SUCCESS);
+}
+
+/*
+ * Shell notification
+ */
+void mixp_shell_change_notification(void)
+{
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
+}
+
/*
* Global init
*/
diff --git a/src/Utils.h b/src/Utils.h
index d54ee6b..3c14eaa 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -43,6 +43,15 @@ typedef enum
}
mixp_beep_t;
+//Regsitry root
+typedef enum
+{
+ mixp_root_classes = 0,
+ mixp_root_user = 1,
+ mixp_root_machine = 2,
+}
+mixp_reg_root_t;
+
//Utils
QString mixp_getTempFolder(QFile **lockfile);
bool mixp_clean_folder(const QString &folderPath);
@@ -51,6 +60,13 @@ QDate mixp_get_current_date(void);
mixp_icon_t *mixp_set_window_icon(QWidget *window, const QIcon &icon, const bool bIsBigIcon);
void mixp_free_window_icon(mixp_icon_t *icon);
bool mixp_beep(int beepType);
+void mixp_shell_change_notification(void);
+
+//Regsitry
+bool mixp_reg_value_write(int rootKey, const QString &keyName, const QString &valueName, const quint32 value);
+bool mixp_reg_value_write(int rootKey, const QString &keyName, const QString &valueName, const QString &value);
+bool mixp_reg_value_read(int rootKey, const QString &keyName, const QString &valueName, quint32 &value);
+bool mixp_reg_key_delete(int rootKey, const QString &keyName);
//Init
void _mixp_global_init(void);