[Matroska-cvs] [matroska] r1284 - in trunk/DvdMenuXtractor: . dmxwizard

smssms at matroska.org smssms at matroska.org
Sat Mar 10 22:18:46 CET 2007


Author: smssms
Date: 2007-03-11 00:18:10 +0300 (Sun, 11 Mar 2007)
New Revision: 1284

Added:
   trunk/DvdMenuXtractor/dmxwizard/
   trunk/DvdMenuXtractor/dmxwizard/dmx.ico
   trunk/DvdMenuXtractor/dmxwizard/dmx.rc
   trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.cpp
   trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.h
   trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.ui
   trunk/DvdMenuXtractor/dmxwizard/dmxselectiontree.cpp
   trunk/DvdMenuXtractor/dmxwizard/dmxselectiontree.h
   trunk/DvdMenuXtractor/dmxwizard/dmxwizard.cpp
   trunk/DvdMenuXtractor/dmxwizard/dmxwizard.h
   trunk/DvdMenuXtractor/dmxwizard/dmxwizard.proj
   trunk/DvdMenuXtractor/dmxwizard/dmxwizard.qrc
   trunk/DvdMenuXtractor/dmxwizard/dmxwizard.ui
   trunk/DvdMenuXtractor/dmxwizard/logtextedit.cpp
   trunk/DvdMenuXtractor/dmxwizard/logtextedit.h
   trunk/DvdMenuXtractor/dmxwizard/main.cpp
   trunk/DvdMenuXtractor/dmxwizard/outputreader.cpp
   trunk/DvdMenuXtractor/dmxwizard/outputreader.h
   trunk/DvdMenuXtractor/dmxwizard/selectiontreeitem.cpp
   trunk/DvdMenuXtractor/dmxwizard/selectiontreeitem.h
   trunk/DvdMenuXtractor/dmxwizard/selectiontreesubitem.cpp
   trunk/DvdMenuXtractor/dmxwizard/selectiontreesubitem.h
Log:
Separate projects for CLI and GUI modes

Added: trunk/DvdMenuXtractor/dmxwizard/dmx.ico
===================================================================
(Binary files differ)


Property changes on: trunk/DvdMenuXtractor/dmxwizard/dmx.ico
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/DvdMenuXtractor/dmxwizard/dmx.rc
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmx.rc	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmx.rc	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,2 @@
+IDI_ICON1		ICON		DISCARDABLE	"dmx.ico"
+

Added: trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.cpp
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.cpp	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.cpp	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,46 @@
+#include <QFile>
+#include <QCloseEvent>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QTextStream>
+
+#include "dmxlogwidget.h"
+
+DMXLogWidget::DMXLogWidget(QWidget *parent)
+    : QWidget(parent)
+{
+	ui.setupUi(this);
+	setWindowFlags(windowFlags() | Qt::Tool);
+
+	//setup slots
+	connect(ui.saveButton, SIGNAL(clicked()), this, SLOT(saveButtonClicked()));
+}
+
+DMXLogWidget::~DMXLogWidget()
+{
+
+}
+
+void DMXLogWidget::closeEvent(QCloseEvent *event)
+{
+	emit closed();
+	event->accept();
+}
+
+void DMXLogWidget::saveButtonClicked()
+{
+	QString filename = QFileDialog::getSaveFileName(this, "Save as...");
+
+	if (filename.size())
+	{
+		QFile output (filename);
+		if (!output.open(QIODevice::WriteOnly | QIODevice::Text))
+		{
+			QMessageBox::critical(this, "Error", "Could not open file for writing");
+			return;
+		}
+
+		QTextStream out (&output);
+		out << ui.textEdit->toPlainText();
+	}
+}

Added: trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.h
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.h	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.h	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,28 @@
+#ifndef DMXLOGWIDGET_H
+#define DMXLOGWIDGET_H
+
+#include <QWidget>
+#include "ui_dmxlogwidget.h"
+
+class DMXLogWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+  DMXLogWidget(QWidget *parent = 0);
+  ~DMXLogWidget();
+
+signals:
+	void closed();
+
+protected:
+	virtual void closeEvent(QCloseEvent *event);
+
+private slots:
+	void saveButtonClicked();
+
+private:
+    Ui::DMXLogWidgetClass ui;
+};
+
+#endif // DMXLOGWIDGET_H

Added: trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.ui
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.ui	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxlogwidget.ui	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,118 @@
+<ui version="4.0" >
+ <class>DMXLogWidgetClass</class>
+ <widget class="QWidget" name="DMXLogWidgetClass" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>468</width>
+    <height>213</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Log</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <widget class="LogTextEdit" name="textEdit" >
+     <property name="readOnly" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <widget class="QPushButton" name="clearButton" >
+       <property name="text" >
+        <string>C&amp;lear</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="saveButton" >
+       <property name="text" >
+        <string>&amp;Save</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="closeButton" >
+       <property name="text" >
+        <string>&amp;Close</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <customwidgets>
+  <customwidget>
+   <class>LogTextEdit</class>
+   <extends>QTextEdit</extends>
+   <header>logtextedit.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>clearButton</sender>
+   <signal>clicked()</signal>
+   <receiver>textEdit</receiver>
+   <slot>clear()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>62</x>
+     <y>202</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>39</x>
+     <y>169</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>closeButton</sender>
+   <signal>clicked()</signal>
+   <receiver>DMXLogWidgetClass</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>410</x>
+     <y>192</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>312</x>
+     <y>178</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

Added: trunk/DvdMenuXtractor/dmxwizard/dmxselectiontree.cpp
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxselectiontree.cpp	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxselectiontree.cpp	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,136 @@
+#include "dmxselectiontree.h"
+#include "selectiontreeitem.h"
+#include "selectiontreesubitem.h"
+
+DMXSelectionTree::DMXSelectionTree(QWidget *parent)
+: QTreeWidget(parent), ifoFile_(0)
+{
+	setColumnCount(1);
+	setHeaderLabels(QStringList("DVD"));
+	setAlternatingRowColors(true);
+}
+
+DMXSelectionTree::~DMXSelectionTree()
+{
+	delete ifoFile_;
+	ifoFile_ = 0;
+}
+
+bool DMXSelectionTree::loadIFOFile(const QString &path)
+{
+	clear();
+	setHeaderLabels(QStringList(QString("DVD - %1").arg(path)));
+
+	// reset last file
+	delete ifoFile_;
+	ifoFile_ = DMX::OpenIFOFile(path);
+
+	if (ifoFile_ == 0)
+		return false;
+
+	bool menu = false;
+	SelectionTreeItem *item = 0;
+	SelectionTreeSubItem *subItem = 0;
+	QTreeWidgetItem *videoStreamItem = 0;
+	QTreeWidgetItem *audioTrackItem = 0;
+	QTreeWidgetItem *subtitleTrackItem = 0;
+
+	for (int16_t title = 0; title <= ifoFile_->NumberOfTitles(); ++title)
+	{
+		menu = !title;
+
+		do
+		{
+			item = new SelectionTreeItem(this, title, menu);
+
+			// add video stream item
+			videoStreamItem = new QTreeWidgetItem(item, QStringList("Video Stream"));
+			videoStreamItem->setFlags(videoStreamItem->flags() | Qt::ItemIsTristate);
+			videoStreamItem->setCheckState(0, Qt::Checked);
+
+			// get audio tracks
+			const AudioTrackList& audioTracks = ifoFile_->AudioTracks(title, menu);
+
+			if (audioTracks.size())
+			{
+				audioTrackItem = new QTreeWidgetItem(item, QStringList("Audio Tracks"));
+				audioTrackItem->setFlags(audioTrackItem->flags() | Qt::ItemIsTristate);
+				audioTrackItem->setCheckState(0, Qt::Checked);
+
+				for (size_t index = 0; index < audioTracks.size(); ++index)
+					subItem = new SelectionTreeSubItem(audioTrackItem, *item, index, SelectionTreeSubItem::AUDIO_TRACK);
+			}
+			
+			// get subtitle tracks
+			const SubtitleTrackList& subTracks = ifoFile_->SubsTracks(title, menu);
+
+			if (subTracks.size())
+			{
+				subtitleTrackItem = new QTreeWidgetItem(item, QStringList("Subtitle Tracks"));
+				subtitleTrackItem->setFlags(subtitleTrackItem->flags() | Qt::ItemIsTristate);
+				subtitleTrackItem->setCheckState(0, Qt::Checked);
+
+				for (size_t index = 0; index < subTracks.size(); ++index)
+					subItem = new SelectionTreeSubItem(subtitleTrackItem, *item, index, SelectionTreeSubItem::SUBTITLE_TRACK);
+			}
+			
+			menu = !menu;
+		} while (menu);
+	}
+
+	return true;
+}
+
+DMX::SelectionType DMXSelectionTree::getSelection() const
+{
+	DMX::SelectionType selection;
+	QTreeWidgetItem *trackListItem = 0;
+
+	for (int index = 0; index < topLevelItemCount(); ++index)
+	{
+		// if processing title item
+		if ( SelectionTreeItem *item = dynamic_cast<SelectionTreeItem*>(topLevelItem(index)) )
+		{
+			// if the title item is (partially) checked
+			if (item->checkState(0) != Qt::Unchecked)
+			{
+				// create selection item instance
+				DMXSelectionItem selectionItem(item->title(), item->isMenuItem(), true);
+
+				// check if video stream is selected
+				if ((item->childCount() > 0) && (item->child(0)->checkState(0) == Qt::Unchecked))
+					selectionItem.disableVideo();
+
+				for (int index = 0; index < item->childCount(); ++index)
+				{
+					trackListItem = item->child(index);
+
+					// check if track list item is checked
+					if (item->checkState(0) != Qt::Unchecked)
+					{
+						for (int index = 0; index < trackListItem->childCount(); ++index)
+						{
+							// process track subitem
+							if (SelectionTreeSubItem *subItem = dynamic_cast<SelectionTreeSubItem*>(trackListItem->child(index)))
+							{
+								// if sub item is checked
+								if (subItem->checkState(0) == Qt::Checked)
+								{
+									if (subItem->type() == SelectionTreeSubItem::AUDIO_TRACK)
+										selectionItem.addAudioTrack(subItem->index());
+
+									if (subItem->type() == SelectionTreeSubItem::SUBTITLE_TRACK)
+											selectionItem.addSubtitleTrack(subItem->index());
+								}
+							}
+						}
+					}
+				}
+
+				selection.push_back(selectionItem);
+			}
+		}
+	}
+
+	return selection;
+}

Added: trunk/DvdMenuXtractor/dmxwizard/dmxselectiontree.h
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxselectiontree.h	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxselectiontree.h	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,22 @@
+#ifndef DMX_SELECTIONTREE_H
+#define DMX_SELECTIONTREE_H
+
+#include "dmx.h"
+#include <QTreeWidget>
+
+class DMXSelectionTree : public QTreeWidget
+{
+	Q_OBJECT
+
+public:
+  DMXSelectionTree(QWidget *parent);
+  ~DMXSelectionTree();
+
+	DMX::SelectionType getSelection() const;
+	bool loadIFOFile(const QString& path);
+
+private:
+	IFOFile *ifoFile_;
+};
+
+#endif // DMX_SELECTIONTREE_H

Added: trunk/DvdMenuXtractor/dmxwizard/dmxwizard.cpp
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxwizard.cpp	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxwizard.cpp	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,252 @@
+#include <QSettings>
+#include <QDirModel>
+#include <QFileDialog>
+#include <QCloseEvent>
+
+#include "dmxwizard.h"
+
+DMXWizard::DMXWizard(QWidget *parent)
+	: QDialog(parent), logWidget_(0)
+{
+	ui.setupUi(this);
+	
+	// hide image labels
+	ui.errorImageLabel->setVisible(false);
+	ui.warningImageLabel->setVisible(false);
+
+	setupSlots();
+	loadSettings();
+
+	// set first page
+	ui.stackedWidget->setCurrentIndex(SETTINGS_PAGE_INDEX);
+	ui.infoLabel->setText(tr("Welcome to DVD Menu Extraction Wizard!\nThe Wizard will guide You through the extraction process"));
+}
+
+DMXWizard::~DMXWizard()
+{
+	storeSettings();
+}
+
+void DMXWizard::pathEditTextChanged(const QString&)
+{
+	bool ready = true;
+
+	// set default styles
+	QPalette palette = ui.dvdPathEdit->palette();
+	palette.setColor(QPalette::Base, Qt::white);
+	ui.dvdPathEdit->setPalette(palette);
+	ui.toolsPathEdit->setPalette(palette);
+	ui.outputPathEdit->setPalette(palette);
+
+	// hide all message and image labels
+	ui.errorInfoLabel->clear();
+	ui.warningInfoLabel->clear();
+	ui.errorImageLabel->hide();
+	ui.warningImageLabel->hide();
+
+	// set background to "red" if incorrect paths are specified
+	// and show corresponding message
+	if (!QFile::exists(ui.dvdPathEdit->text()))
+	{	
+		palette.setColor(QPalette::Base, Qt::red);
+		ui.dvdPathEdit->setPalette(palette);
+		ready = false;
+	}
+
+	if (!QFile::exists(ui.toolsPathEdit->text()))
+	{	
+		palette.setColor(QPalette::Base, Qt::red);
+		ui.toolsPathEdit->setPalette(palette);
+		ready = false;
+	}
+
+	if (!ui.outputPathEdit->text().size())
+	{
+		palette.setColor(QPalette::Base, Qt::red);
+		ui.outputPathEdit->setPalette(palette);
+		ready = false;
+	}
+	else if (QFile::exists(ui.outputPathEdit->text())) // just a warning in case the output folder exists
+	{
+		palette.setColor(QPalette::Base, Qt::yellow);
+		ui.outputPathEdit->setPalette(palette);
+		
+		ui.warningImageLabel->show();
+		ui.warningInfoLabel->setText(tr("Specified path already exists. Contents will be overwritten"));
+	}
+
+	// show error info if needed
+	if (!ready)
+	{
+		ui.errorImageLabel->show();
+		ui.errorInfoLabel->setText(tr("Missing or incorrect path was specified"));
+	}
+
+	ui.nextButton->setEnabled(ready);
+}
+
+void DMXWizard::browseButtonClicked()
+{
+	QString directory = QFileDialog::getExistingDirectory(this, "Select directory...");
+
+	if (!directory.size())
+		return;
+
+	if (QPushButton *senderObject = dynamic_cast<QPushButton*>(sender()))
+	{
+		if (senderObject == ui.dvdBrowseButton)
+		{
+			if (!(directory.endsWith('/') || directory.endsWith('\\')))
+				directory.append('/');
+
+			ui.dvdPathEdit->setText(directory);
+		}
+		else if (senderObject == ui.outputBrowseButton)
+			ui.outputPathEdit->setText(directory);
+		else if (senderObject == ui.toolsBrowseButton)
+			ui.toolsPathEdit->setText(directory);
+	}
+}
+
+void DMXWizard::loadSettings()
+{
+	QSettings settings ("DMX", "MatroskaTeam");
+	ui.dvdPathEdit->setText(settings.value("Wizard/DVDPath").toString());
+	ui.outputPathEdit->setText(settings.value("Wizard/OutputPath").toString());
+	ui.toolsPathEdit->setText(settings.value("Wizard/ToolsPath").toString());
+}
+
+void DMXWizard::storeSettings()
+{
+	QSettings settings ("DMX", "MatroskaTeam");
+	settings.setValue("Wizard/DVDPath", ui.dvdPathEdit->text());
+	settings.setValue("Wizard/OutputPath", ui.outputPathEdit->text());
+	settings.setValue("Wizard/ToolsPath", ui.toolsPathEdit->text());
+}
+
+void DMXWizard::setupSlots()
+{
+	// setup slots for buttons
+	connect(ui.backButton, SIGNAL(clicked()), this, SLOT(backButtonClicked()));
+	connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextButtonClicked()));
+	connect(ui.stopButton, SIGNAL(clicked()), &dmx, SLOT(abort()));
+	connect(ui.dvdBrowseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
+	connect(ui.outputBrowseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
+	connect(ui.toolsBrowseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
+
+	// setup slots for edits
+	connect(ui.dvdPathEdit, SIGNAL(textChanged(const QString&)), this, SLOT(pathEditTextChanged(const QString&)));
+	connect(ui.outputPathEdit, SIGNAL(textChanged(const QString&)), this, SLOT(pathEditTextChanged(const QString&)));
+	connect(ui.toolsPathEdit, SIGNAL(textChanged(const QString&)), this, SLOT(pathEditTextChanged(const QString&)));
+
+	// setup log widget
+	connect(ui.logButton, SIGNAL(toggled(bool)), &logWidget_, SLOT(setVisible(bool)));
+	connect(&logWidget_, SIGNAL(closed()), ui.logButton, SLOT(toggle()));
+
+	// setup slots for extraction
+	connect(&dmx, SIGNAL(finished()), this, SLOT(extractionFinished()));
+	connect(&dmx, SIGNAL(progressChanged(int)), ui.progressBar, SLOT(setValue(int)));
+	connect(&dmx, SIGNAL(stepChanged(const QString&)), this, SLOT(extractionStepChanged(const QString&)));
+}
+
+void DMXWizard::nextButtonClicked()
+{
+	if (ui.stackedWidget->currentIndex() == SETTINGS_PAGE_INDEX)
+	{
+		// try to load DVD IFO
+		if (!ui.selectionTree->loadIFOFile(ui.dvdPathEdit->text()))
+			ui.nextButton->setEnabled(false);
+
+		// set button states
+		ui.backButton->setEnabled(true);
+
+		// turn to the "selection page"
+		ui.stackedWidget->setCurrentIndex(SELECTION_PAGE_INDEX);
+	}
+	else if (ui.stackedWidget->currentIndex() == SELECTION_PAGE_INDEX)
+	{
+		ui.nextButton->setEnabled(false);
+
+		// turn to the "extraction page"
+		ui.stackedWidget->setCurrentIndex(EXTRACTION_PAGE_INDEX);
+
+		// get selection
+		DMX::SelectionType selection = ui.selectionTree->getSelection();
+		if (selection.size())
+		{
+			// unhide
+			ui.stopButton->show();
+			ui.progressBar->show();
+
+			// set button states
+			ui.backButton->setEnabled(false);
+			ui.stopButton->setEnabled(true);
+
+			ui.progressInfoLabel->setText(tr("Please wait...\nYou can stop the process at any moment by clicking the \"Stop\" button."));
+
+			dmx.setExtractionParameters(ui.dvdPathEdit->text(), ui.outputPathEdit->text(),
+											ui.toolsPathEdit->text(), ui.selectionTree->getSelection());
+
+			dmx.start();
+		}
+		else // nothing was selected
+		{
+			ui.stopButton->hide();
+			ui.progressBar->hide();
+			ui.progressInfoLabel->clear();
+
+			ui.stepInfoLabel->setText(tr("Nothing was selected, nothing to do..."));
+			
+			ui.backButton->setEnabled(true);
+			ui.stopButton->setEnabled(false);
+		}
+	}
+}
+
+void DMXWizard::backButtonClicked()
+{
+	// if going back from the "selection page"
+	if (ui.stackedWidget->currentIndex() == SELECTION_PAGE_INDEX)
+	{
+		// set button states
+		ui.backButton->setEnabled(false);
+		ui.nextButton->setEnabled(true);
+
+		ui.stackedWidget->setCurrentIndex(SETTINGS_PAGE_INDEX);
+	}
+	else if (ui.stackedWidget->currentIndex() == EXTRACTION_PAGE_INDEX)
+	{
+		// set button states
+		ui.backButton->setEnabled(true);
+		ui.nextButton->setEnabled(true);
+
+		ui.stackedWidget->setCurrentIndex(SELECTION_PAGE_INDEX);
+	}
+}
+
+void DMXWizard::extractionFinished()
+{
+	// set button states
+	ui.backButton->setEnabled(true);
+	ui.stopButton->setEnabled(false);
+
+	// chage text
+	ui.stepInfoLabel->setText("Extraction finished!");
+}
+
+void DMXWizard::extractionStepChanged(const QString &text)
+{
+	ui.stepInfoLabel->setText(text);
+	
+	// send the message to the log
+	printf(qPrintable(text + '\n'));
+}
+
+void DMXWizard::closeEvent(QCloseEvent *evt)
+{
+	// stop extraction if in progress before quitting
+	if (dmx.isRunning())
+		dmx.abort();
+
+	evt->accept();
+}

Added: trunk/DvdMenuXtractor/dmxwizard/dmxwizard.h
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxwizard.h	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxwizard.h	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,40 @@
+#ifndef DMXWIZARD_H
+#define DMXWIZARD_H
+
+#include <QDialog>
+#include "ui_dmxwizard.h"
+#include "dmxlogwidget.h"
+
+class DMXWizard : public QDialog
+{
+    Q_OBJECT
+
+public:
+   DMXWizard(QWidget *parent = 0);
+   ~DMXWizard();
+
+protected:
+	void closeEvent(QCloseEvent* evt);
+
+private slots:
+	void backButtonClicked();
+	void nextButtonClicked();
+	void browseButtonClicked();
+	void extractionFinished();
+	void pathEditTextChanged(const QString& path);
+	void extractionStepChanged(const QString& text);
+
+private:
+  Ui::DMXWizardClass ui;
+	
+	DMX dmx;
+	DMXLogWidget logWidget_;
+
+	enum {SETTINGS_PAGE_INDEX = 0, SELECTION_PAGE_INDEX, EXTRACTION_PAGE_INDEX};
+
+	void setupSlots();
+	void loadSettings();
+	void storeSettings();
+};
+
+#endif // DMXWIZARD_H

Added: trunk/DvdMenuXtractor/dmxwizard/dmxwizard.proj
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxwizard.proj	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxwizard.proj	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,72 @@
+EXE dmxwizard
+{
+  USE dmx
+  
+  DEFINE __STDC_LIMIT_MACROS
+  DEFINE(QT_NO_DEBUG) QT_NO_DEBUG_STREAM
+
+  INCLUDE ../dmx
+  INCLUDE ../dmx/libdvdread
+  INCLUDE(COMPILER_MSVC) ../dmx/libdvdread/win32
+  
+  INCLUDE(COMPILER_MSVC) "$(QTDIR)/include"
+  INCLUDE(COMPILER_MSVC) "$(QTDIR)/include/QtXml"
+  INCLUDE(COMPILER_MSVC) "$(QTDIR)/include/QtGui"
+  INCLUDE(COMPILER_MSVC) "$(QTDIR)/include/QtCore"
+  
+  INCLUDE(COMPILER_GCC)  "$(QTDIR)/include/qt4/"
+  INCLUDE(COMPILER_GCC)  "$(QTDIR)/include/qt4/QtXml"
+  INCLUDE(COMPILER_GCC)  "$(QTDIR)/include/qt4/QtGui"
+  INCLUDE(COMPILER_GCC)  "$(QTDIR)/include/qt4/QtCore"
+  
+  LIBS_RELEASE(COMPILER_MSVC) qtmain.lib
+  LIBS_RELEASE(COMPILER_MSVC && CONFIG_STATIC) QtXml.lib
+  LIBS_RELEASE(COMPILER_MSVC && CONFIG_STATIC) QtGui.lib
+  LIBS_RELEASE(COMPILER_MSVC && CONFIG_STATIC) QtCore.lib
+  LIBS_RELEASE(COMPILER_MSVC && !CONFIG_STATIC) QtCore4.lib
+  LIBS_RELEASE(COMPILER_MSVC && !CONFIG_STATIC) QtXml4.lib
+  LIBS_RELEASE(COMPILER_MSVC && !CONFIG_STATIC) QtGui4.lib
+  LIBS_DEBUG(COMPILER_MSVC) qtmaind.lib
+  LIBS_DEBUG(COMPILER_MSVC && CONFIG_STATIC) QtXmld.lib
+  LIBS_DEBUG(COMPILER_MSVC && CONFIG_STATIC) QtGuid.lib
+  LIBS_DEBUG(COMPILER_MSVC && CONFIG_STATIC) QtCored.lib
+  LIBS_DEBUG(COMPILER_MSVC && !CONFIG_STATIC) QtXmld4.lib
+  LIBS_DEBUG(COMPILER_MSVC && !CONFIG_STATIC) QtGuid4.lib
+  LIBS_DEBUG(COMPILER_MSVC && !CONFIG_STATIC) QtCored4.lib
+  LIBS(COMPILER_GCC && CONFIG_STATIC) QtGui
+  LIBS(COMPILER_GCC && CONFIG_STATIC) QtXml
+  LIBS(COMPILER_GCC && CONFIG_STATIC) QtCore
+  LIBS(COMPILER_GCC && !CONFIG_STATIC) QtGui4
+  LIBS(COMPILER_GCC && !CONFIG_STATIC) QtXml4
+  LIBS(COMPILER_GCC && !CONFIG_STATIC) QtCore4
+  
+  LIBS(TARGET_WIN) imm32.lib
+  LIBS(TARGET_WIN) winmm.lib
+  LIBS(TARGET_WIN) ws2_32.lib
+
+  LIBINCLUDE "$(QTDIR)/lib"
+  
+  SOURCE main.cpp
+  SOURCE dmxwizard.cpp
+  SOURCE logtextedit.cpp
+  SOURCE dmxlogwidget.cpp
+  SOURCE outputreader.cpp
+  SOURCE dmxselectiontree.cpp
+  SOURCE selectiontreeitem.cpp
+  SOURCE selectiontreesubitem.cpp
+
+  SOURCE(TARGET_WIN) dmx.rc
+  
+  HEADER_QT4 dmxwizard.h
+  HEADER_QT4 logtextedit.h
+  HEADER_QT4 outputreader.h
+  HEADER_QT4 dmxlogwidget.h
+  HEADER selectiontreeitem.h
+  HEADER_QT4 dmxselectiontree.h
+  HEADER selectiontreesubitem.h
+  
+  UI_FORM_QT4 dmxlogwidget.ui
+  UI_FORM_QT4 dmxwizard.ui
+  
+  RESOURCE_QT4 dmxwizard.qrc
+}

Added: trunk/DvdMenuXtractor/dmxwizard/dmxwizard.qrc
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxwizard.qrc	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxwizard.qrc	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,11 @@
+<RCC>
+    <qresource prefix="/DMXWizard" >
+        <file>Resources/back.png</file>
+        <file>Resources/dmx.png</file>
+        <file>Resources/error.png</file>
+        <file>Resources/log.png</file>
+        <file>Resources/next.png</file>
+        <file>Resources/quit.png</file>
+        <file>Resources/warning.png</file>
+    </qresource>
+</RCC>

Added: trunk/DvdMenuXtractor/dmxwizard/dmxwizard.ui
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/dmxwizard.ui	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/dmxwizard.ui	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,514 @@
+<ui version="4.0" >
+ <class>DMXWizardClass</class>
+ <widget class="QDialog" name="DMXWizardClass" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>500</width>
+    <height>416</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>DMXWizard</string>
+  </property>
+  <layout class="QVBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <widget class="QFrame" name="frame" >
+     <property name="frameShape" >
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow" >
+      <enum>QFrame::Plain</enum>
+     </property>
+     <layout class="QHBoxLayout" >
+      <property name="margin" >
+       <number>9</number>
+      </property>
+      <property name="spacing" >
+       <number>6</number>
+      </property>
+      <item>
+       <widget class="QLabel" name="imageLabel" >
+        <property name="minimumSize" >
+         <size>
+          <width>64</width>
+          <height>64</height>
+         </size>
+        </property>
+        <property name="maximumSize" >
+         <size>
+          <width>64</width>
+          <height>64</height>
+         </size>
+        </property>
+        <property name="text" >
+         <string/>
+        </property>
+        <property name="pixmap" >
+         <pixmap resource="dmxwizard.qrc" >:/DMXWizard/Resources/dmx.png</pixmap>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QLabel" name="infoLabel" >
+        <property name="alignment" >
+         <set>Qt::AlignCenter</set>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QStackedWidget" name="stackedWidget" >
+     <property name="currentIndex" >
+      <number>1</number>
+     </property>
+     <widget class="QWidget" name="settingsPage" >
+      <layout class="QGridLayout" >
+       <property name="margin" >
+        <number>9</number>
+       </property>
+       <property name="spacing" >
+        <number>6</number>
+       </property>
+       <item row="3" column="0" >
+        <widget class="QLabel" name="label_2" >
+         <property name="text" >
+          <string>Output path</string>
+         </property>
+         <property name="buddy" >
+          <cstring>outputPathEdit</cstring>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="1" >
+        <widget class="QLineEdit" name="toolsPathEdit" />
+       </item>
+       <item row="3" column="1" >
+        <widget class="QLineEdit" name="outputPathEdit" />
+       </item>
+       <item row="3" column="2" >
+        <widget class="QPushButton" name="outputBrowseButton" >
+         <property name="text" >
+          <string>Browse...</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1" >
+        <widget class="QLineEdit" name="dvdPathEdit" />
+       </item>
+       <item row="1" column="1" >
+        <spacer>
+         <property name="orientation" >
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" >
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="4" column="2" >
+        <widget class="QPushButton" name="toolsBrowseButton" >
+         <property name="text" >
+          <string>Browse...</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0" >
+        <widget class="QLabel" name="label" >
+         <property name="text" >
+          <string>DVD path</string>
+         </property>
+         <property name="buddy" >
+          <cstring>dvdPathEdit</cstring>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="1" >
+        <layout class="QHBoxLayout" >
+         <property name="margin" >
+          <number>0</number>
+         </property>
+         <property name="spacing" >
+          <number>6</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="errorImageLabel" >
+           <property name="maximumSize" >
+            <size>
+             <width>24</width>
+             <height>24</height>
+            </size>
+           </property>
+           <property name="pixmap" >
+            <pixmap resource="dmxwizard.qrc" >:/DMXWizard/Resources/error.png</pixmap>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLabel" name="errorInfoLabel" >
+           <property name="sizePolicy" >
+            <sizepolicy>
+             <hsizetype>5</hsizetype>
+             <vsizetype>0</vsizetype>
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize" >
+            <size>
+             <width>0</width>
+             <height>24</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item row="6" column="1" >
+        <layout class="QHBoxLayout" >
+         <property name="margin" >
+          <number>0</number>
+         </property>
+         <property name="spacing" >
+          <number>6</number>
+         </property>
+         <item>
+          <widget class="QLabel" name="warningImageLabel" >
+           <property name="maximumSize" >
+            <size>
+             <width>24</width>
+             <height>24</height>
+            </size>
+           </property>
+           <property name="pixmap" >
+            <pixmap resource="dmxwizard.qrc" >:/DMXWizard/Resources/warning.png</pixmap>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLabel" name="warningInfoLabel" >
+           <property name="sizePolicy" >
+            <sizepolicy>
+             <hsizetype>5</hsizetype>
+             <vsizetype>0</vsizetype>
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize" >
+            <size>
+             <width>0</width>
+             <height>24</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item row="2" column="2" >
+        <widget class="QPushButton" name="dvdBrowseButton" >
+         <property name="text" >
+          <string>Browse...</string>
+         </property>
+        </widget>
+       </item>
+       <item row="7" column="1" >
+        <spacer>
+         <property name="orientation" >
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" >
+          <size>
+           <width>20</width>
+           <height>31</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="4" column="0" >
+        <widget class="QLabel" name="label_3" >
+         <property name="text" >
+          <string>Tools path</string>
+         </property>
+         <property name="buddy" >
+          <cstring>toolsPathEdit</cstring>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1" >
+        <widget class="QLabel" name="label_5" >
+         <property name="text" >
+          <string>Please specify the required paths and click "Next" button</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="selectionPage" >
+      <layout class="QVBoxLayout" >
+       <property name="margin" >
+        <number>9</number>
+       </property>
+       <property name="spacing" >
+        <number>6</number>
+       </property>
+       <item>
+        <widget class="QLabel" name="label_4" >
+         <property name="text" >
+          <string>Please select which tracks and subtracks you want to extract and press "Next" button</string>
+         </property>
+         <property name="buddy" >
+          <cstring>selectionTree</cstring>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="DMXSelectionTree" name="selectionTree" />
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="extractionPage" >
+      <layout class="QVBoxLayout" >
+       <property name="margin" >
+        <number>9</number>
+       </property>
+       <property name="spacing" >
+        <number>6</number>
+       </property>
+       <item>
+        <widget class="QLabel" name="progressInfoLabel" >
+         <property name="text" >
+          <string>Please wait...
+You can stop the process at any moment by clicking the "Stop" button.</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer>
+         <property name="orientation" >
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" >
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QLabel" name="stepInfoLabel" >
+         <property name="text" >
+          <string>Step</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QProgressBar" name="progressBar" >
+         <property name="value" >
+          <number>0</number>
+         </property>
+         <property name="orientation" >
+          <enum>Qt::Horizontal</enum>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" >
+         <property name="margin" >
+          <number>0</number>
+         </property>
+         <property name="spacing" >
+          <number>6</number>
+         </property>
+         <item>
+          <spacer>
+           <property name="orientation" >
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" >
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QPushButton" name="stopButton" >
+           <property name="enabled" >
+            <bool>false</bool>
+           </property>
+           <property name="text" >
+            <string>S&amp;top</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer>
+         <property name="orientation" >
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" >
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <widget class="QPushButton" name="logButton" >
+       <property name="text" >
+        <string>&amp;Show Log</string>
+       </property>
+       <property name="icon" >
+        <iconset resource="dmxwizard.qrc" >:/DMXWizard/Resources/log.png</iconset>
+       </property>
+       <property name="checkable" >
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType" >
+        <enum>QSizePolicy::Expanding</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="backButton" >
+       <property name="enabled" >
+        <bool>false</bool>
+       </property>
+       <property name="text" >
+        <string>&amp;Back</string>
+       </property>
+       <property name="icon" >
+        <iconset resource="dmxwizard.qrc" >:/DMXWizard/Resources/back.png</iconset>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="nextButton" >
+       <property name="enabled" >
+        <bool>false</bool>
+       </property>
+       <property name="text" >
+        <string>&amp;Next</string>
+       </property>
+       <property name="icon" >
+        <iconset resource="dmxwizard.qrc" >:/DMXWizard/Resources/next.png</iconset>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation" >
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeType" >
+        <enum>QSizePolicy::Fixed</enum>
+       </property>
+       <property name="sizeHint" >
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QPushButton" name="quitButton" >
+       <property name="text" >
+        <string>&amp;Quit</string>
+       </property>
+       <property name="icon" >
+        <iconset resource="dmxwizard.qrc" >:/DMXWizard/Resources/quit.png</iconset>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11" />
+ <customwidgets>
+  <customwidget>
+   <class>DMXSelectionTree</class>
+   <extends>QTreeWidget</extends>
+   <header>dmxselectiontree.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>dvdPathEdit</tabstop>
+  <tabstop>dvdBrowseButton</tabstop>
+  <tabstop>outputPathEdit</tabstop>
+  <tabstop>outputBrowseButton</tabstop>
+  <tabstop>toolsPathEdit</tabstop>
+  <tabstop>toolsBrowseButton</tabstop>
+  <tabstop>logButton</tabstop>
+  <tabstop>backButton</tabstop>
+  <tabstop>nextButton</tabstop>
+  <tabstop>quitButton</tabstop>
+  <tabstop>selectionTree</tabstop>
+  <tabstop>stopButton</tabstop>
+ </tabstops>
+ <resources>
+  <include location="dmxwizard.qrc" />
+ </resources>
+ <connections>
+  <connection>
+   <sender>quitButton</sender>
+   <signal>clicked()</signal>
+   <receiver>DMXWizardClass</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>489</x>
+     <y>380</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>479</x>
+     <y>260</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

Added: trunk/DvdMenuXtractor/dmxwizard/logtextedit.cpp
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/logtextedit.cpp	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/logtextedit.cpp	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,50 @@
+#include <QDate>
+#include <QFile>
+#include <QTextStream>
+#include "logtextedit.h"
+#include "outputreader.h"
+
+LogTextEdit::LogTextEdit(QWidget *parent)
+	: QTextEdit(parent), notifier_(OutputReader::instance())
+{
+	// set flags
+	setReadOnly(true);
+	setLineWrapMode(QTextEdit::NoWrap);
+
+	if (!notifier_.redirect())
+	{
+		setHtml("ERROR: Could not start output redirection");
+		notifier_.cancelRedirect();
+		return;
+	}
+
+	// setup slots
+	connect(&notifier_, SIGNAL(readyReadStandardError()), this, SLOT(standardErrorReady()));
+	connect(&notifier_, SIGNAL(readyReadStandardOutput()), this, SLOT(standardOutputReady()));
+}
+
+LogTextEdit::~LogTextEdit()
+{
+}
+
+void LogTextEdit::standardErrorReady()
+{
+	static const QString format("%1;%2 - WARNING: %3");
+	
+	int index = 0;
+	QString message = notifier_.readError();
+	QStringList messages = message.split('\n', QString::SkipEmptyParts);
+	for (index = 0; index < messages.size(); ++index)
+		append(format.arg(QDate::currentDate().toString(), QTime::currentTime().toString(), messages.at(index)));
+}
+
+void LogTextEdit::standardOutputReady()
+{
+	static const QString format("%1;%2: %3");
+
+	int index = 0;
+	QString message = notifier_.readOutput();
+	QStringList messages = message.split('\n', QString::SkipEmptyParts);
+	for (index = 0; index < messages.size(); ++index)
+		append(format.arg(QDate::currentDate().toString(), QTime::currentTime().toString(), messages.at(index)));
+}

Added: trunk/DvdMenuXtractor/dmxwizard/logtextedit.h
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/logtextedit.h	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/logtextedit.h	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,25 @@
+#ifndef LOGTEXTEDIT_H
+#define LOGTEXTEDIT_H
+
+#include <QTextEdit>
+
+// forward declaration
+class OutputReader;
+
+class LogTextEdit : public QTextEdit
+{
+	Q_OBJECT
+
+public:
+  LogTextEdit(QWidget *parent);
+  ~LogTextEdit();
+
+private slots:
+	void standardErrorReady();
+	void standardOutputReady();
+
+private:
+	OutputReader& notifier_;
+};
+
+#endif // LOGTEXTEDIT_H

Added: trunk/DvdMenuXtractor/dmxwizard/main.cpp
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/main.cpp	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/main.cpp	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,12 @@
+#include <QtGui/QApplication>
+#include "dmxwizard.h"
+
+int main(int argc, char *argv[])
+{	
+	QApplication app(argc, argv);
+	DMXWizard wizard;
+	wizard.show();
+	app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
+
+	return app.exec();
+}

Added: trunk/DvdMenuXtractor/dmxwizard/outputreader.cpp
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/outputreader.cpp	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/outputreader.cpp	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,177 @@
+#if defined(WIN32) || defined(WIN64)
+#include <io.h>
+#endif
+#include <QDir>
+#include <fcntl.h>
+#include <fstream>
+#include <QWidget>
+#include <QTimerEvent>
+#include "outputreader.h"
+
+OutputReader::OutputReader(QObject *parent /* = 0*/)
+  : QObject(parent)
+	,redirecting_(false)
+	,stdoutFileName("stdout.txt")
+	,stderrFileName("stderr.txt")
+	,stderrStream(0)
+	,stdoutStream(0)
+{
+}
+
+OutputReader::~OutputReader()
+{
+	if (redirecting_)
+		cancelRedirect();
+}
+
+void OutputReader::timerEvent(QTimerEvent *event)
+{
+	// if the event is intended for us
+	if ((event->timerId() == timer.timerId()) && redirecting_)
+	{
+		QFile stdoutFile (stdoutFileName);
+		QFile stderrFile (stderrFileName);
+	
+		static qint64 stderrFileSize = 0;
+		static qint64 stdoutFileSize = 0;
+
+		qint64 size = stderrFile.size();
+
+		if (size > stderrFileSize) // new data is available
+		{
+			stderrFileSize = size;
+			emit readyReadStandardError();
+		}
+
+		size = stdoutFile.size();
+
+		if (size > stdoutFileSize) // new data is available
+		{
+			stdoutFileSize = size;
+			emit readyReadStandardOutput();
+		}
+	}
+	else
+		QObject::timerEvent(event);
+}
+
+bool OutputReader::redirect() 
+{
+	if (redirecting_)
+		return true;
+
+	// save old descriptors
+#if defined(WIN32) || defined(WIN64)
+	stdout_desc = _dup(1);
+	stderr_desc = _dup(2);
+#else
+	stdout_desc = dup(1);
+	stderr_desc = dup(2);
+#endif
+
+	if ((stdout_desc == -1) || (stderr_desc == -1))
+  	return false;
+
+	// redirect stdout and stderr to corresponding files
+	stdoutStream = freopen(stdoutFileName.toAscii(), "wc", stdout);
+	stderrStream = freopen(stderrFileName.toAscii(), "wc", stderr);
+
+	if ((stderrStream == 0) || (stdoutStream == 0))
+		return false;
+
+	// disable buffering
+  setvbuf(stdout, 0, _IONBF, 0);
+  setvbuf(stderr, 0, _IONBF, 0);
+
+	redirecting_ = true;
+
+	// start monitoring
+	timer.start(TIMEOUT, this);
+	
+  return redirecting_;
+}
+
+bool OutputReader::cancelRedirect()
+{
+	// close streams
+	if (stderrStream != 0)
+		fclose(stderrStream);
+	
+	if (stdoutStream != 0)
+		fclose(stdoutStream);
+
+	// set back standard file descriptors
+#if defined(WIN32) || defined(WIN64)
+	if (( -1 == _dup2(stdout_desc, 1)) 
+	  ||( -1 == _dup2(stderr_desc, 2)))
+			return false;
+#else
+	if (( -1 == dup2(stdout_desc, 1)) 
+	  ||( -1 == dup2(stderr_desc, 2)))
+			return false;
+#endif
+
+	// stop monitoring
+	timer.stop();
+
+	stderrStream = 0;
+	stdoutStream = 0;
+
+	redirecting_ = false;
+
+	return true;
+}
+
+QString OutputReader::readOutput() const
+{
+	static std::ifstream::pos_type position = 0;
+	
+	QString output;
+	std::string data;
+	std::ifstream stream (qPrintable(stdoutFileName));
+	if (stream.is_open())
+	{
+		if (stream.seekg(position).good())
+			do
+			{
+				position = stream.tellg();
+				if(getline(stream, data))
+					output.append(data.data()).append('\n');
+				else
+					break;
+			}
+			while (true);
+	}
+
+	return output;
+}
+
+QString OutputReader::readError() const
+{
+	static std::ifstream::pos_type position = 0;
+	
+	QString error;
+	std::string data;
+	std::ifstream stream (qPrintable(stderrFileName));
+	if (stream.is_open())
+	{
+		if (stream.seekg(position).good())
+			do
+			{
+				position = stream.tellg();
+				if(getline(stream, data))
+					error.append(data.data()).append('\n');
+				else
+					break;
+			}
+			while (true);
+	}
+
+	return error;
+}
+
+OutputReader& OutputReader::instance()
+{
+	static OutputReader reader;
+	return reader;
+}

Added: trunk/DvdMenuXtractor/dmxwizard/outputreader.h
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/outputreader.h	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/outputreader.h	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,64 @@
+/**********************************************************/
+/* Description: Contains OutputReader class declaration	  */
+/**********************************************************/
+#ifndef OUTPUTREADER_H
+#define OUTPUTREADER_H
+
+#include <stdio.h>
+#include <QObject>
+#include <QBasicTimer>
+
+class OutputReader : public QObject
+{
+	Q_OBJECT
+
+public:
+
+	static OutputReader& instance();
+
+	/* Starts redirecting stdout and stderr to itself */
+	bool redirect();
+	
+	/* Cancels redirecting stdout and stderr to itself */
+	bool cancelRedirect();
+
+	/* Reads stderr content, when available */
+	QString readError() const;
+	
+	/* Reads stdout content, when available */
+	QString readOutput() const;
+
+signals:
+	/* These signals are emitted when stdout  */
+	/*  and/or stderr are ready to be read	  */
+	void readyReadStandardError();
+	void readyReadStandardOutput();
+
+protected:
+	void timerEvent(QTimerEvent *event);
+
+private:
+	static const int TIMEOUT = 1000;
+
+	bool redirecting_;
+
+	QString stdoutFileName; // file where stdout would be redirected
+	QString stderrFileName; // file where stderr would be redirected
+
+  int stdout_desc;	// stdout descriptor before redirecting
+	int stderr_desc;	// stderr descriptor before redirecting
+
+	FILE *stderrStream;	// file stream for standard error
+	FILE *stdoutStream; // file stream for standard output
+
+	QBasicTimer timer;	// Timer to watch for output change
+
+	// singleton pattern, no copying
+	OutputReader(const OutputReader&);
+	OutputReader& operator= (const OutputReader&);
+	OutputReader(QObject *parent = 0);
+	~OutputReader();
+};
+
+
+#endif // OUTPUTREADER_H

Added: trunk/DvdMenuXtractor/dmxwizard/selectiontreeitem.cpp
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/selectiontreeitem.cpp	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/selectiontreeitem.cpp	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,45 @@
+#include <QTreeWidgetItem>
+#include "selectiontreeitem.h"
+
+SelectionTreeItem::SelectionTreeItem(QTreeWidget *parent, int16_t title, bool isMenuItem)
+	: QTreeWidgetItem(parent)
+	,title_(title)
+	,isMenuItem_(isMenuItem)
+{
+	static const QString vmgTitleFormat(QObject::tr("VMG"));
+	static const QString vtsTitleFormat(QObject::tr("Title %1"));
+	static const QString vtsmTitleFormat(QObject::tr("Title %1 Menu"));
+	
+	if (isMenuItem && title)
+		setText(0, vtsmTitleFormat.arg(QString::number(title), 2, '0'));
+	else if (isMenuItem)
+		setText(0, vmgTitleFormat);
+	else
+		setText(0, vtsTitleFormat.arg(QString::number(title), 2, '0'));
+
+	setFlags(flags() | Qt::ItemIsTristate);
+	setCheckState(0, Qt::Checked);
+}
+
+SelectionTreeItem::SelectionTreeItem(const SelectionTreeItem &other)
+	: QTreeWidgetItem(other)
+	,title_(other.title_)
+	,isMenuItem_(other.isMenuItem_)
+{
+	setCheckState(0, other.checkState(0));
+}
+
+SelectionTreeItem::~SelectionTreeItem()
+{
+
+}
+
+bool SelectionTreeItem::isMenuItem() const
+{
+	return isMenuItem_;
+}
+
+int16_t SelectionTreeItem::title() const
+{
+	return title_;
+}

Added: trunk/DvdMenuXtractor/dmxwizard/selectiontreeitem.h
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/selectiontreeitem.h	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/selectiontreeitem.h	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,25 @@
+#ifndef SELECTIONTREEITEM_H
+#define SELECTIONTREEITEM_H
+
+#include <stdint.h>
+
+// forward declaration
+class QTreeWidgetItem;
+
+class SelectionTreeItem : public QTreeWidgetItem
+{
+public:
+
+  SelectionTreeItem(QTreeWidget *parent, int16_t title, bool isMenuItem);
+	SelectionTreeItem(const SelectionTreeItem &other);
+  ~SelectionTreeItem();
+
+	int16_t title()		const;
+	bool isMenuItem() const;
+
+private:
+	int16_t title_;
+	bool isMenuItem_;
+};
+
+#endif // SELECTIONTREEITEM_H

Added: trunk/DvdMenuXtractor/dmxwizard/selectiontreesubitem.cpp
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/selectiontreesubitem.cpp	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/selectiontreesubitem.cpp	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,48 @@
+#include <QTreeWidgetItem>
+#include "selectiontreesubitem.h"
+
+SelectionTreeSubItem::SelectionTreeSubItem(QTreeWidgetItem *parent, const SelectionTreeItem &titleItem, size_t index, SelectionTreeSubItem::SubItemType type)
+	: QTreeWidgetItem(parent)
+	,index_(index)
+	,type_(type)
+	,titleItem_(titleItem)
+{
+	static const QString audioTrackTitleFormat ("Audio Track %1");
+	static const QString subTrackTitleFormat ("Subtitle Track %1");
+	
+	if (type == AUDIO_TRACK)
+		setText(0, audioTrackTitleFormat.arg(index));
+	else
+		setText(0, subTrackTitleFormat.arg(index));
+
+	setFlags(flags() | Qt::ItemIsTristate);
+	setCheckState(0, Qt::Checked);
+}
+
+SelectionTreeSubItem::SelectionTreeSubItem(const SelectionTreeSubItem &other)
+	: QTreeWidgetItem(other)
+	,index_(other.index_)
+	,type_(other.type_)
+	,titleItem_(other.titleItem_)
+{
+	setCheckState(0, other.checkState(0));
+}
+
+SelectionTreeSubItem::~SelectionTreeSubItem()
+{
+}
+
+size_t SelectionTreeSubItem::index() const
+{
+	return index_;
+}
+
+SelectionTreeSubItem::SubItemType SelectionTreeSubItem::type() const
+{
+	return type_;
+}
+
+const SelectionTreeItem& SelectionTreeSubItem::titleItem() const
+{
+	return titleItem_;
+}

Added: trunk/DvdMenuXtractor/dmxwizard/selectiontreesubitem.h
===================================================================
--- trunk/DvdMenuXtractor/dmxwizard/selectiontreesubitem.h	2007-03-10 21:17:10 UTC (rev 1283)
+++ trunk/DvdMenuXtractor/dmxwizard/selectiontreesubitem.h	2007-03-10 21:18:10 UTC (rev 1284)
@@ -0,0 +1,26 @@
+#ifndef SELECTION_TREE_SUB_ITEM_H
+#define SELECTION_TREE_SUB_ITEM_H
+
+// forward declaration
+class QTreeWidgetItem;
+class SelectionTreeItem;
+
+class SelectionTreeSubItem : public QTreeWidgetItem
+{
+public:
+	enum SubItemType { AUDIO_TRACK, SUBTITLE_TRACK };
+	SelectionTreeSubItem(QTreeWidgetItem *parent, const SelectionTreeItem& titleItem, size_t index, SubItemType type);
+	SelectionTreeSubItem(const SelectionTreeSubItem& other);
+	~SelectionTreeSubItem();
+
+	size_t index() const;
+	SubItemType type() const;
+	const SelectionTreeItem& titleItem() const;
+
+private:
+	size_t index_;
+	SubItemType type_;
+	const SelectionTreeItem &titleItem_;
+};
+
+#endif // SELECTION_TREE_SUB_ITEM_H



More information about the Matroska-cvs mailing list