From 16626e1170ae849e82644474169c515facdb471a Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Tue, 28 Nov 2006 17:58:30 +0000 Subject: [PATCH] Added a Qt version of mkvinfo's GUI (is not enabled by default, add "--enable-qt" to configure). --- Makefile.in | 94 +++++-- configure.in | 259 ++++++++++++++--- src/info/console_ui.cpp | 71 +++++ src/info/mkvinfo.cpp | 81 +----- src/info/mkvinfo.h | 75 +---- src/info/qt_ui.cpp | 302 ++++++++++++++++++++ src/info/qt_ui.h | 62 +++++ src/info/rightclick_tree_widget.h | 34 +++ src/info/ui/mainwindow.ui | 122 ++++++++ src/info/wxwidgets_ui.cpp | 445 ++++++++++++++++++++++++++++++ src/info/wxwidgets_ui.h | 84 ++++++ 11 files changed, 1425 insertions(+), 204 deletions(-) create mode 100644 src/info/console_ui.cpp create mode 100644 src/info/qt_ui.cpp create mode 100644 src/info/qt_ui.h create mode 100644 src/info/rightclick_tree_widget.h create mode 100644 src/info/ui/mainwindow.ui create mode 100644 src/info/wxwidgets_ui.cpp create mode 100644 src/info/wxwidgets_ui.h diff --git a/Makefile.in b/Makefile.in index 076322cc2..7563a308a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,29 +34,32 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs localedir = $(datadir)/locale # Common programs -EXEEXT = @EXEEXT@ -OBJEXT = @OBJEXT@ -PATH_SEPARATOR = @PATH_SEPARATOR@ AR = @AR@ CC = @CC@ CPP = @CPP@ CXX = @CXX@ -LD = @LD@ -PROFILING_CFLAGS = @PROFILING_CFLAGS@ -PROFILING_LIBS = @PROFILING_LIBS@ -RANLIB = @RANLIB@ +EXEEXT = @EXEEXT@ +GCC_DEP_STYLE = @GCC_DEP_STYLE@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_HEADER = $(INSTALL_DATA) INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_HEADER = $(INSTALL_DATA) -GCC_DEP_STYLE = @GCC_DEP_STYLE@ +LD = @LD@ +MOC = @MOC@ +OBJEXT = @OBJEXT@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PROFILING_CFLAGS = @PROFILING_CFLAGS@ +PROFILING_LIBS = @PROFILING_LIBS@ +RANLIB = @RANLIB@ +UIC = @UIC@ # Variable stuff as set by configure BZ2_LIBS = @BZ2_LIBS@ +CPPFLAGS = @CPPFLAGS@ DEBUG_CFLAGS = @DEBUG_CFLAGS@ EBML_CFLAGS = @EBML_CFLAGS@ EBML_LIBS = @EBML_LIBS@ @@ -66,6 +69,7 @@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ EXTRA_LDFLAGS = @EXTRA_LDFLAGS@ FLAC_LIBS = @FLAC_LIBS@ ICONV_LIBS = @ICONV_LIBS@ +LIBINTL_LIBS = @LIBINTL_LIBS@ LZO_LIBS = @LZO_LIBS@ MAGIC_LIBS = @MAGIC_LIBS@ MATROSKA_CFLAGS = @MATROSKA_CFLAGS@ @@ -74,19 +78,29 @@ MINGW_GUIAPP = @MINGW_GUIAPP@ MINGW_LIBS = @MINGW_LIBS@ MINGW = @MINGW@ OGG_LIBS = @OGG_LIBS@ +OPTIMIZATION_CFLAGS = @OPTIMIZATION_CFLAGS@ +PCRE_CFLAGS = @PCRE_CFLAGS@ +PCRE_LIBS = @PCRE_LIBS@ +PROFILING_CFLAGS = @PROFILING_CFLAGS@ +PROFILING_LIBS = @PROFILING_LIBS@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +USER_CPPFLAGS = @USER_CPPFLAGS@ +USER_CXXFLAGS = @USER_CXXFLAGS@ +USER_CFLAGS = @USER_CFLAGS@ +USER_LDFLAGS = @USER_LDFLAGS@ VORBIS_LIBS = @VORBIS_LIBS@ WXWIDGETS_CFLAGS = @WXWIDGETS_CFLAGS@ WXWIDGETS_INCLUDES = @WXWIDGETS_INCLUDES@ WXWIDGETS_LIBS = @WXWIDGETS_LIBS@ ZLIB_LIBS = @ZLIB_LIBS@ -LIBINTL_LIBS = @LIBINTL_LIBS@ -PCRE_CFLAGS = @PCRE_CFLAGS@ -PCRE_LIBS = @PCRE_LIBS@ -CFLAGS = @USER_CPPFLAGS@ @EXTRA_CFLAGS@ @OPTIMIZATION_CFLAGS@ @USER_CFLAGS@ -Wall -Wno-sign-compare -Wno-comment -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 @EXTRA_CFLAGS@ @DEBUG_CFLAGS@ @PROFILING_CFLAGS@ @MATROSKA_CFLAGS@ @EBML_CFLAGS@ -CXXFLAGS = @USER_CPPFLAGS@ @EXTRA_CFLAGS@ @OPTIMIZATION_CFLAGS@ @USER_CXXFLAGS@ -Wall -Wno-sign-compare -Wno-comment -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 @EXTRA_CFLAGS@ @DEBUG_CFLAGS@ @PROFILING_CFLAGS@ @MATROSKA_CFLAGS@ @EBML_CFLAGS@ @WXWIDGETS_CFLAGS@ @PCRE_CFLAGS@ -CPPFLAGS = @USER_CPPFLAGS@ @CPPFLAGS@ -LDFLAGS = @USER_LDFLAGS@ @EXTRA_LDFLAGS@ @PROFILING_LIBS@ +WARNING_CFLAGS = -Wall -Wno-sign-compare -Wno-comment + +CFLAGS = $(USER_CPPFLAGS) $(EXTRA_CFLAGS) $(OPTIMIZATION_CFLAGS) $(USER_CFLAGS) $(WARNING_CFLAGS) -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(EXTRA_CFLAGS) $(DEBUG_CFLAGS) $(PROFILING_CFLAGS) $(MATROSKA_CFLAGS) $(EBML_CFLAGS) +CXXFLAGS = $(USER_CPPFLAGS) $(EXTRA_CFLAGS) $(OPTIMIZATION_CFLAGS) $(USER_CXXFLAGS) $(WARNING_CFLAGS) -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(EXTRA_CFLAGS) $(DEBUG_CFLAGS) $(PROFILING_CFLAGS) $(MATROSKA_CFLAGS) $(EBML_CFLAGS) $(WXWIDGETS_CFLAGS) $(PCRE_CFLAGS) $(QT_CFLAGS) +CPPFLAGS = $(USER_CPPFLAGS) $(CPPFLAGS) +LDFLAGS = $(USER_LDFLAGS) $(EXTRA_LDFLAGS) $(PROFILING_LIBS) CFLAGS += -DPACKAGE=\"$(PACKAGE)\" -DVERSION=\"$(VERSION)\" CXXFLAGS += -DPACKAGE=\"$(PACKAGE)\" -DVERSION=\"$(VERSION)\" @@ -95,6 +109,7 @@ CXXFLAGS += -DMTX_LOCALE_DIR=\"$(localedir)\" \ # Which additional stuff to compile USE_WXWIDGETS = @USE_WXWIDGETS@ +USE_QT = @USE_QT@ AVILIB_INCLUDES = -Iavilib-0.6.10 AVILIB_LIBDIRS = -Lavilib-0.6.10 @@ -202,7 +217,8 @@ ALL_SOURCES=$(wildcard avilib-0.6.10/*.c) $(wildcard avilib-0.6.10/*.cpp) \ $(wildcard src/output/*.cpp) $(wildcard src/common/*.cpp) \ $(wildcard src/mmg/*.cpp) $(wildcard src/extract/*.cpp) \ $(wildcard src/merge/*cpp) $(wildcard src/info/*.cpp) \ - $(wildcard src/mpegparser/*.cpp) + $(wildcard src/mpegparser/*.cpp) \ + $(patsubst %.ui,%.h,$(UIFILES)) ifeq ($(V),1) Q = @@ -244,9 +260,19 @@ endif @echo ' GREP ' $< $(Q)grep -v 'name="ID"' $< > $@ +# Qt files +%.h: %.ui + @echo ' UIC ' $< + $(Q)$(UIC) $< > $@ + +%.moc.cpp: %.h + @echo ' MOC ' $< + $(Q)$(MOC) $(QT_CFLAGS) $< > $@ + clean: rm -f *.o */*.o */*/*.o */lib*.a */*/lib*.a po/*.mo $(APPLICATIONS) \ - */*.exe */*/*.exe */*/*.dll */*/*.dll.a doc/*.hhk + */*.exe */*/*.exe */*/*.dll */*/*.dll.a doc/*.hhk \ + src/info/ui/*.h src/info/*.moc.cpp distclean dist-clean: clean rm -f config.h config.log config.cache Makefile */Makefile */*/Makefile @@ -394,12 +420,28 @@ mkvmerge_LDADD = -lmtxinput -lmtxoutput \ # src/info # -mkvinfo_SOURCES = $(wildcard src/info/*.cpp) +mkvinfo_SOURCES = src/info/mkvinfo.cpp src/info/console_ui.cpp +mkvinfo_LDADD = -lmtxcommon $(MAGIC_LIBS) -lmatroska -lebml + +ifeq (yes,$(USE_QT)) +mkvinfo_SOURCES += src/info/qt_ui.cpp src/info/qt_ui.moc.cpp \ + src/info/rightclick_tree_widget.moc.cpp +mkvinfo_UIFILES = $(patsubst %.ui,%.h,$(wildcard src/info/ui/*.ui)) +mkvinfo_LDADD += $(QT_LIBS) + +src/info/qt_ui.o: $(wildcard src/info/ui/*.ui) + +else +ifeq (yes,$(USE_WXWIDGETS)) +mkvinfo_SOURCES += src/info/wxwidgets_ui.cpp +mkvinfo_LDADD += $(WXWIDGETS_LIBS) +endif +endif + mkvinfo_OBJECTS := $(patsubst %.cpp,%.o,$(mkvinfo_SOURCES)) mkvinfo_DEPENDENCIES += $(DEP_COMMON) -mkvinfo_LDADD = -lmtxcommon $(MAGIC_LIBS) -lmatroska -lebml \ - $(WXWIDGETS_LIBS) \ - -lexpat $(ICONV_LIBS) $(LIBINTL_LIBS) $(LIBRPCRT) +mkvinfo_LDADD += -lexpat $(ICONV_LIBS) $(LIBINTL_LIBS) $(LIBRPCRT) + # # src/extract @@ -442,7 +484,7 @@ src/mkvmerge@EXEEXT@: $(mkvmerge_OBJECTS) $(mkvmerge_DEPENDENCIES) mkvinfo: src/mkvinfo@EXEEXT@ -src/mkvinfo@EXEEXT@: $(mkvinfo_OBJECTS) $(mkvinfo_DEPENDENCIES) +src/mkvinfo@EXEEXT@: $(mkvinfo_UIFILES) $(mkvinfo_OBJECTS) $(mkvinfo_DEPENDENCIES) @echo ' LINK ' $@ $(Q)$(LINK) -o $@ $(mkvinfo_OBJECTS) $(mkvinfo_LDADD) @@ -464,6 +506,8 @@ src/mmg/mmg@EXEEXT@: $(mmg_OBJECTS) $(mmg_DEPENDENCIES) @echo ' LINK ' $@ $(Q)$(LINK) -o $@ $(mmg_OBJECTS) $(mmg_LDADD) +.SECONDARY: + # # include dependency files if they exist # diff --git a/configure.in b/configure.in index 20733ad11..a96b9617c 100644 --- a/configure.in +++ b/configure.in @@ -31,6 +31,37 @@ dnl Optional features that are built and those that aren't opt_features_yes="" opt_features_no="" + +function check_version { + check_ver_req="$1" + check_ver_real="$2" + + set - `echo $check_ver_req 0 0 0 | sed 's/\./\ /g'` + check_ver_major=$1 + check_ver_minor=$2 + check_ver_micro=$3 + + set - `echo $check_ver_real 0 0 0 | sed 's/\./\ /g'` + check_ver_ok=0 + + if test "x$1" = "x" -o $1 -lt ${check_ver_major} ; then + check_ver_ok=0 + elif test $1 -gt ${check_ver_major} ; then + check_ver_ok=1 + elif test "x$2" = "x" -o $2 -lt ${check_ver_minor} ; then + check_ver_ok=0 + elif test $2 -gt ${check_ver_minor} ; then + check_ver_ok=1 + elif test "x$3" = "x" -o $3 -lt ${check_ver_micro} ; then + check_ver_ok=0 + else + check_ver_ok=1 + fi + + test $check_ver_ok = 1 +} + + dnl Stolen from VideoLAN Client, http://www.videolan.org/ dnl dnl Endianness check, AC_C_BIGENDIAN doesn't work if we are cross-compiling @@ -520,15 +551,15 @@ dnl [ flac_decoder_skip_found=no ], $FLAC_LIBS) if test x"$flac_decoder_skip_found" = xyes; then - opt_features_yes="$opt_features_yes; FLAC audio (1.1.1 or newer)" + opt_features_yes="$opt_features_yes\n * FLAC audio (1.1.1 or newer)" AC_DEFINE(HAVE_FLAC_DECODER_SKIP, [1], [Define if FLAC__stream_decoder_skip_single_frame exists]) else - opt_features_yes="$opt_features_yes; FLAC audio (1.1.0 or older)" + opt_features_yes="$opt_features_yes\n * FLAC audio (1.1.0 or older)" fi AC_DEFINE(HAVE_FLAC_FORMAT_H, [1], [Define if the FLAC headers are present]) else FLAC_LIBS="" - opt_features_no="$opt_features_no; FLAC audio" + opt_features_no="$opt_features_no\n * FLAC audio" fi AC_SUBST(FLAC_LIBS) @@ -864,10 +895,10 @@ dnl fi fi if test x"$lzo_found" = xyes ; then - opt_features_yes="$opt_features_yes; LZO compression" + opt_features_yes="$opt_features_yes\n * LZO compression" AC_DEFINE([HAVE_LZO], [1], [Define this if LZO compression is present]) else - opt_features_no="$opt_features_no; LZO compression" + opt_features_no="$opt_features_no\n * LZO compression" fi AC_SUBST(LZO_LIBS) @@ -889,9 +920,9 @@ dnl fi fi if test x"$bz2_found" = xyes ; then - opt_features_yes="$opt_features_yes; BZ2 compression" + opt_features_yes="$opt_features_yes\n * BZ2 compression" else - opt_features_no="$opt_features_no; BZ2 compression" + opt_features_no="$opt_features_no\n * BZ2 compression" fi AC_SUBST(BZ2_LIBS) @@ -904,10 +935,7 @@ dnl AC_ARG_ENABLE([gui], AC_HELP_STRING([--enable-gui],[compile mkvinfo's GUI and mmg (yes)])) - wxw_ver_req_major=2 - wxw_ver_req_minor=6 - wxw_ver_req_micro=0 - wxw_min_ver=$wxw_ver_req_major.$wxw_ver_req_minor.$wxw_ver_req_micro + wxw_min_ver=2.6.0 if test x"$enable_gui" = x"yes" -o x"$enable_gui" = "x"; then AC_ARG_WITH(wx_config, @@ -919,26 +947,7 @@ dnl AC_MSG_CHECKING(for wxWidgets $wxw_min_ver or newer) wxwversion=`$WX_CONFIG --version` - set - `echo $wxwversion | sed 's/\./\ /g'` - if test "x$1" = "x" -o $1 -lt ${wxw_ver_req_major} ; then - wxwver_ok=0 - elif test $1 -gt ${wxw_ver_req_major} ; then - wxwver_ok=1 - else - if test "x$2" = "x" -o $2 -lt ${wxw_ver_req_minor} ; then - wxwver_ok=0 - elif test $2 -gt ${wxw_ver_req_minor} ; then - wxwver_ok=1 - else - if test "x$3" = "x" -o $3 -lt ${wxw_ver_req_micro} ; then - wxwver_ok=0 - else - wxwver_ok=1 - fi - fi - fi - - if test "$wxwver_ok" = "1" ; then + if check_version $wxw_min_ver $wxwversion ; then WXWIDGETS_CFLAGS=`$WX_CONFIG --cxxflags` WXWIDGETS_LIBS=`$WX_CONFIG --libs | \ sed -e 's/-Wl,--subsystem,windows//' -e 's/-mwindows//'` @@ -973,11 +982,10 @@ wxTreeItemId id; done fi AC_DEFINE(HAVE_WXWIDGETS, 1, [Define if wxWindows is present]) - MMG_SUBDIRS=mmg AC_MSG_RESULT($wxwversion ok) have_wxwindows=yes USE_WXWIDGETS=yes - opt_features_yes="$opt_features_yes; GUIs" + opt_features_yes="$opt_features_yes\n * GUIs" else AC_MSG_RESULT(no: test program could not be compiled) fi @@ -992,15 +1000,179 @@ wxTreeItemId id; fi if test x"$have_wxwindows" != "xyes" ; then - opt_features_no="$opt_features_no; GUIs" + opt_features_no="$opt_features_no\n * GUIs" fi AC_SUBST(WXWIDGETS_CFLAGS) AC_SUBST(WXWIDGETS_INCLUDES) AC_SUBST(WXWIDGETS_LIBS) -AC_SUBST(MMG_SUBDIRS) AC_SUBST(USE_WXWIDGETS) + +dnl +dnl Check for Qt 4 or newer +dnl + +AC_ARG_ENABLE([qt], + AC_HELP_STRING([--enable-qt],[compile the Qt version of the GUIs])) + +qt_min_ver=4.0.0 + +if test x"$enable_qt" = "xyes" -a \ + '(' x"$enable_gui" = x"yes" -o x"$enable_gui" = "x" ')'; then + dnl Find moc. + AC_ARG_WITH(moc, + AC_HELP_STRING([--with-moc=prog],[use prog instead of looking for moc]), + [ MOC="$with_moc" ],) + if ! test -z "$MOC"; then + AC_MSG_CHECKING(for moc) + AC_MSG_RESULT(using supplied $MOC) + else + AC_PATH_PROG(MOC, moc-qt4,, $PATH) + if test -z "$MOC"; then + AC_PATH_PROG(MOC, moc,, $PATH) + fi + fi + if test -z "$MOC" -o ! -x "$MOC"; then + echo "*** The 'moc' binary was not found or is not executable." + exit 1 + fi + + dnl Check its version. + AC_MSG_CHECKING(for the Qt version $MOC uses) + moc_ver=`"$MOC" -v 2>&1 | sed -e 's:.*Qt ::' -e 's:[[^0-9\.]]::g'` + if test -z "moc_ver"; then + AC_MSG_RESULT(unknown; please contact the author) + elif ! check_version $qt_min_ver $moc_ver; then + AC_MSG_RESULT(too old: $moc_ver) + else + AC_MSG_RESULT($moc_ver) + moc_found=1 + fi + + AC_ARG_WITH(uic, + AC_HELP_STRING([--with-uic=prog],[use prog instead of looking for uic]), + [ UIC="$with_uic" ],) + + if test x"$moc_found" = "x1"; then + if ! test -z "$UIC"; then + AC_MSG_CHECKING(for uic) + AC_MSG_RESULT(using supplied $UIC) + else + AC_PATH_PROG(UIC, uic-qt4,, $PATH) + if test -z "$UIC"; then + AC_PATH_PROG(UIC, uic,, $PATH) + fi + fi + if test -z "$UIC" -o ! -x "$UIC"; then + echo "*** The 'uic' binary was not found or is not executable." + exit 1 + fi + + dnl Check its version. + AC_MSG_CHECKING(for the Qt version $UIC uses) + uic_ver=`"$UIC" -v 2>&1 | sed -e 's:.*Qt ::' -e 's:[[^0-9\.]]::g'` + if test -z "uic_ver"; then + AC_MSG_RESULT(unknown; please contact the author) + elif ! check_version $qt_min_ver $uic_ver; then + AC_MSG_RESULT(too old: $uic_ver) + else + AC_MSG_RESULT($uic_ver) + uic_found=1 + fi + fi + + AC_MSG_CHECKING(for Qt $qt_min_ver or newer) + if test x"$moc_found" != "x1"; then + AC_MSG_RESULT(no: moc not found) + elif test x"$uic_found" != "x1"; then + AC_MSG_RESULT(no: uic not found) + elif ! pkg-config QtGui --atleast-version=$qt_min_ver || \ + ! pkg-config QtCore --atleast-version=$qt_min_ver ; then + AC_MSG_RESULT(no: pkg-config says "too old") + else + dnl Try compiling and linking an application. + QT_CFLAGS="`pkg-config QtCore --cflags` `pkg-config QtGui --cflags`" + QT_LIBS="`pkg-config QtGui --libs`" + + AC_LANG_PUSH(C++) + AC_CACHE_VAL(am_cv_qt_compilation, [ + run_qt_test=1 + while true; do + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CXXFLAGS="$CXXFLAGS $QT_CFLAGS" + LIBS="$LDFLAGS $QT_LIBS" + unset ac_cv_qt_compilation + + AC_TRY_LINK([ +#include +class Config : public QCoreApplication { +public: +Config(int &argc, char **argv); +}; +Config::Config(int &argc, char **argv) +: QCoreApplication(argc,argv) {setApplicationName("config");} + ], [ +int ai = 0; +char **ac = 0; +Config app(ai,ac); +qWarning(qPrintable(app.applicationName())); +return 0; + ], [ am_cv_qt_compilation=1 ], [ am_cv_qt_compilation=0 ]) + + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + + if test x"$am_cv_qt_compilation" = x1; then + break + + elif test x"$run_qt_test" = "x1"; then + dnl On some systems (notably OpenSuSE 10.0) the pkg-config for the + dnl --cflags don't include the QtCore and QtGui subdirectories. + dnl Add them now. + set - $QT_CFLAGS + while test ! -z "$1" ; do + case "$1" in + -I*) + QT_CFLAGS="$QT_CFLAGS $1/QtCore $1/QtGui" + ;; + esac + shift + done + run_qt_test=2 + + elif test x"$run_qt_test" = "x2"; then + QT_CFLAGS="$QT_CFLAGS -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/local/include/QtCore -I/usr/local/include/QtGui" + run_qt_test=3 + + else + break + + fi + done + ]) + AC_LANG_POP() + + if test x"$am_cv_qt_compilation" = x1; then + AC_DEFINE(HAVE_QT, 1, [Define if Qt is present]) + have_qt=yes + USE_QT=yes + opt_features_yes="$opt_features_yes (Qt version)" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no: test program could not be compiled) + fi + fi +fi + +AC_SUBST(MOC) +AC_SUBST(UIC) +AC_SUBST(QT_CFLAGS) +AC_SUBST(QT_LIBS) +AC_SUBST(USE_QT) + + dnl dnl Which translations should be installed? dnl @@ -1027,9 +1199,9 @@ dnl TRANSLATIONS="`echo "$TRANSLATIONS_POS" | \ dnl sed -e 's/po\///g' -e 's/\.po//g'`" dnl AC_MSG_RESULT($TRANSLATIONS) dnl fi -dnl opt_features_yes="$opt_features_yes; translations (gettext)" +dnl opt_features_yes="$opt_features_yes\n * translations (gettext)" dnl else -dnl opt_features_no="$opt_features_yes; translations (gettext)" +dnl opt_features_no="$opt_features_yes\n * translations (gettext)" dnl fi AC_SUBST(LIBINTL_LIBS) @@ -1047,15 +1219,18 @@ AC_CHECK_LIB(magic, magic_open, if test "x$magic_found" = "xyes" ; then AC_CHECK_HEADERS([magic.h]) + if test "x$ac_cv_header_magic_h" = "xyes" ; then + opt_features_yes="$opt_features_yes\n * libMagic file type detection" + else + opt_features_no="$opt_features_no\n * libMagic file type detection" + fi fi AC_SUBST(MAGIC_LIBS) AC_OUTPUT(Makefile avilib-0.6.10/Makefile librmff/Makefile src/Makefile src/common/Makefile src/input/Makefile src/output/Makefile src/mpegparser/Makefile src/mmg/Makefile src/extract/Makefile src/merge/Makefile src/info/Makefile) -opt_features_yes="`echo "$opt_features_yes" | sed 's/^\;//'`" -opt_features_no="`echo "$opt_features_no" | sed 's/^\;//'`" echo '' -echo '*** The mkvtoolnix configuration is complete.' -echo '*** Optional features that are built: '"$opt_features_yes" -echo '*** Optional features that are NOT built: '"$opt_features_no" +echo 'The mkvtoolnix configuration is complete.' +echo -e 'Optional features that are built: '"$opt_features_yes" +echo -e 'Optional features that are NOT built: '"$opt_features_no" diff --git a/src/info/console_ui.cpp b/src/info/console_ui.cpp new file mode 100644 index 000000000..086692aa1 --- /dev/null +++ b/src/info/console_ui.cpp @@ -0,0 +1,71 @@ +/* + mkvinfo -- utility for gathering information about Matroska files + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + $Id: gui.cpp 3373 2006-11-19 17:41:46Z mosu $ + + A console UI for mkvinfo + + Written by Moritz Bunkus . +*/ + +#include "os.h" + +#include "common.h" +#include "mkvinfo.h" + +void +console_show_element(int level, + const char *text, + int64_t position) { + char *level_buffer; + + level_buffer = new char[level + 1]; + memset(&level_buffer[1], ' ', level); + level_buffer[0] = '|'; + level_buffer[level] = 0; + mxinfo("%s+ %s", level_buffer, text); + if ((1 < verbose) && (0 <= position)) + mxinfo(" at " LLU, position); + mxinfo("\n"); + delete []level_buffer; +} + +void +console_show_error(const char *text) { + mxinfo("(%s) %s\n", NAME, text); +} + +#if !defined(HAVE_QT) && !defined(HAVE_WXWIDGETS) +void +ui_show_element(int level, + const char *text, + int64_t position) { + console_show_element(level, text, position); +} + +void +ui_show_error(const char *text) { + console_show_error(text); +} + +void +ui_show_progress(int percentage, + const char *text) { +} + +int +ui_run(int argc, + char **argv) { + return 0; +} + +bool +ui_graphical_available() { + return false; +} + +#endif // !HAVE_QT && !HAVE_WXWIDGETS diff --git a/src/info/mkvinfo.cpp b/src/info/mkvinfo.cpp index 7ff279b07..b793cd736 100644 --- a/src/info/mkvinfo.cpp +++ b/src/info/mkvinfo.cpp @@ -132,7 +132,6 @@ find_track_by_uid(int tuid) { void set_usage() { -#ifdef HAVE_WXWIDGETS usage_text = Y( "Usage: mkvinfo [options] inname\n\n" " options:\n" @@ -148,22 +147,6 @@ set_usage() { " Redirect all messages to this file.\n" " -h, --help Show this help.\n" " -V, --version Show version information.\n"); -#else - usage_text = Y( - "Usage: mkvinfo [options] inname\n\n" - " options:\n" - " inname Use 'inname' as the source.\n" - " -v, --verbose Increase verbosity. See the man page for a detailed\n" - " description of what mkvinfo outputs.\n" - " -c, --checksum Calculate and display checksums of frame contents.\n" - " -s, --summary Only show summaries of the contents, not each element.\n" - " --output-charset \n" - " Output messages in this charset\n" - " -r, -o, --redirect-output file.ext\n" - " Redirect all messages to this file.\n" - " -h, --help Show this help.\n" - " -V, --version Show version information.\n"); -#endif version_info = "mkvinfo v" VERSION " ('" VERSIONNAME "')"; } @@ -185,12 +168,7 @@ show_error(const char *fmt, vsnprintf(args_buffer, ARGS_BUFFER_LEN - 1, new_fmt.c_str(), ap); va_end(ap); -#ifdef HAVE_WXWIDGETS - if (use_gui) - frame->show_error(wxU(args_buffer)); - else -#endif - mxinfo("(%s) %s\n", NAME, args_buffer); + ui_show_error(args_buffer); } #define show_warning(l, f, args...) _show_element(NULL, NULL, false, l, f, \ @@ -238,27 +216,10 @@ _show_element(EbmlElement *l, vsnprintf(args_buffer, ARGS_BUFFER_LEN - 1, new_fmt.c_str(), ap); va_end(ap); - if (!use_gui) { - char *level_buffer; - - level_buffer = new char[level + 1]; - memset(&level_buffer[1], ' ', level); - level_buffer[0] = '|'; - level_buffer[level] = 0; - mxinfo("%s+ %s", level_buffer, args_buffer); - if ((verbose > 1) && (l != NULL)) - mxinfo(" at " LLU, l->GetElementPosition()); - mxinfo("\n"); - delete []level_buffer; - } -#ifdef HAVE_WXWIDGETS - else { - if (l != NULL) - mxprints(&args_buffer[strlen(args_buffer)], " at " LLU, - l->GetElementPosition()); - frame->add_item(level, wxU(args_buffer)); - } -#endif // HAVE_WXWIDGETS + int64_t pos = -1; + if (NULL != l) + pos = l->GetElementPosition(); + ui_show_element(level, args_buffer, pos); if ((l != NULL) && skip) { // Dump unknown elements recursively. @@ -289,11 +250,9 @@ parse_args(vector args, // Now parse the rest of the arguments. for (i = 0; i < args.size(); i++) if ((args[i] == "-g") || (args[i] == "--gui")) { -#ifndef HAVE_WXWIDGETS - mxerror("mkvinfo was compiled without GUI support.\n"); -#else // HAVE_WXWIDGETS + if (!ui_graphical_available()) + mxerror("mkvinfo was compiled without GUI support.\n"); use_gui = true; -#endif // HAVE_WXWIDGETS } else if ((args[i] == "-c") || (args[i] == "--checksum")) calc_checksums = true; else if ((args[i] == "-C") || (args[i] == "--check-mode")) { @@ -1742,11 +1701,9 @@ def_handle2(cluster, cluster = (KaxCluster *)l1; -#ifdef HAVE_WXWIDGETS if (use_gui) - frame->show_progress(100 * cluster->GetElementPosition() / - file_size, wxT("Parsing file")); -#endif // HAVE_WXWIDGETS + ui_show_progress(100 * cluster->GetElementPosition() / file_size, + "Parsing file"); upper_lvl_el = 0; m1 = static_cast(l1); @@ -2127,17 +2084,6 @@ console_main(vector args) { return 1; } -#if !defined HAVE_WXWIDGETS -int -main(int argc, - char **argv) { - setup(); - - return console_main(command_line_utf8(argc, argv)); -} - -#elif defined(SYS_UNIX) || defined(SYS_APPLE) - int main(int argc, char **argv) { @@ -2149,11 +2095,8 @@ main(int argc, args = command_line_utf8(argc, argv); parse_args(args, initial_file); - if (use_gui) { - wxEntry(argc, argv); - return 0; - } else + if (use_gui) + return ui_run(argc, argv); + else return console_main(args); } - -#endif // HAVE_WXWIDGETS diff --git a/src/info/mkvinfo.h b/src/info/mkvinfo.h index 453e22dfc..a4948e564 100644 --- a/src/info/mkvinfo.h +++ b/src/info/mkvinfo.h @@ -22,14 +22,6 @@ #include #include -#include "config.h" - -#ifdef HAVE_WXWIDGETS -#include -#include -#include -#endif - #define NAME "MKVInfo" using namespace std; @@ -42,66 +34,13 @@ void cleanup(); extern bool use_gui; -#ifdef HAVE_WXWIDGETS +void ui_show_error(const char *text); +void ui_show_element(int level, const char *text, int64_t position); +void ui_show_progress(int percentage, const char *text); +int ui_run(int argc, char **argv); +bool ui_graphical_available(); -#include "wxcommon.h" - -class mi_app: public wxApp { -public: - virtual bool OnInit(); -}; - -class mi_dndfile: public wxFileDropTarget { -public: - virtual bool OnDropFiles(wxCoord x, wxCoord y, - const wxArrayString &filenames); -}; - -class mi_frame: public wxFrame { -private: - //For Drag-n-Drop - mi_dndfile *dnd_load; - wxMenu *menu_options, *menu_file; - bool show_all_elements, expand_important_elements; - bool file_open; - int last_percent; - int64_t num_elements, elements_saved; - wxString current_file, last_dir; - - wxTreeCtrl *tree; - wxTreeItemId item_ids[10]; - -public: - mi_frame(const wxString &title, const wxPoint &pos, const wxSize &size, - long style = wxDEFAULT_FRAME_STYLE); - - void open_file(wxString file_name); - void show_progress(int percent, wxString msg); - void show_error(wxString msg); - void add_item(int level, wxString text); - -protected: - void on_file_open(wxCommandEvent &event); - void on_file_savetext(wxCommandEvent &event); - void on_file_quit(wxCommandEvent &event); - void on_options_showall(wxCommandEvent &event); - void on_options_expandimportant(wxCommandEvent &event); - void on_help_about(wxCommandEvent &event); - void on_right_click(wxTreeEvent &event); - - void expand_elements(); - void expand_all_elements(wxTreeItemId &root, bool expand = true); - - void save_elements(wxTreeItemId &root, int level, FILE *f); - -private: - DECLARE_EVENT_TABLE() -}; - -extern mi_frame *frame; - -DECLARE_APP(mi_app); - -#endif // HAVE_WXWIDGETS +void console_show_error(const char *text); +void console_show_element(int level, const char *text, int64_t position); #endif // __MKVINFO_H diff --git a/src/info/qt_ui.cpp b/src/info/qt_ui.cpp new file mode 100644 index 000000000..037378be3 --- /dev/null +++ b/src/info/qt_ui.cpp @@ -0,0 +1,302 @@ +/* + mkvinfo -- utility for gathering information about Matroska files + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + $Id: gui.cpp 3373 2006-11-19 17:41:46Z mosu $ + + A Qt GUI for mkvinfo + + Written by Moritz Bunkus . +*/ + +#include "config.h" + +#include +#include + +#include "common.h" +#include "mkvinfo.h" + +#include "qt_ui.h" + +#include +#include +#include + +using namespace libebml; +using namespace libmatroska; + +main_window_c::main_window_c(): + last_percent(-1), num_elements(0), + root(NULL) { + + setupUi(this); + + connect(action_Open, SIGNAL(triggered()), this, SLOT(open())); + connect(action_Save_text_file, SIGNAL(triggered()), this, + SLOT(save_text_file())); + connect(action_Exit, SIGNAL(triggered()), this, SLOT(close())); + + connect(action_Show_all, SIGNAL(triggered()), this, SLOT(show_all())); + + connect(action_About, SIGNAL(triggered()), this, SLOT(about())); + + action_Save_text_file->setEnabled(false); + + action_Show_all->setCheckable(true); + action_Show_all->setChecked(0 < verbose); + + action_Expand_important->setCheckable(true); + action_Expand_important->setChecked(true); + + tree->setHeaderLabels(QStringList(tr("Elements"))); + tree->setRootIsDecorated(true); + + root = new QTreeWidgetItem(tree); + root->setText(0, tr("no file loaded")); +} + +void +main_window_c::open() { + QString file_name = + QFileDialog::getOpenFileName(this, tr("Open File"), "", + tr("Matroska files (*.mkv *.mka *.mks)" + ";;All files (*.*)")); + if (!file_name.isEmpty()) + parse_file(file_name); +} + +void +main_window_c::save_text_file() { + QString file_name = + QFileDialog::getSaveFileName(this, tr("Save information as"), "", + tr("Text files (*.txt);;All files (*.*)")); + if (file_name.isEmpty()) + return; + + QFile file(file_name); + if (!file.open(QIODevice::WriteOnly)) { + QMessageBox::critical(this, tr("Error saving the information"), + tr("The file could not be opened for writing.")); + return; + } + + write_tree(file, root, 0); + + file.close(); +} + +void +main_window_c::write_tree(QFile &file, + QTreeWidgetItem *item, + int level) { + int i; + + for (i = 0; item->childCount() > i; ++i) { + QTreeWidgetItem *child = item->child(i); + + char *level_buffer = new char[level + 1]; + level_buffer[0] = '|'; + memset(&level_buffer[1], ' ', level); + level_buffer[level] = 0; + + file.write(level_buffer, level); + file.write(QString("+ %1\n").arg(child->text(0)).toUtf8()); + write_tree(file, child, level + 1); + } +} + +void +main_window_c::show_all() { + verbose = action_Show_all->isChecked() ? 2 : 0; + if (!current_file.isEmpty()) + parse_file(current_file); +} + +void +main_window_c::about() { + QString msg = + QString(VERSIONINFO ".\n" + "Compiled with libebml %1 + libmatroska %2.\n\n" + "This program is licensed under the GPL v2 (see COPYING).\n" + "It was written by Moritz Bunkus .\n" + "Sources and the latest binaries are always available at\n" + "http://www.bunkus.org/videotools/mkvtoolnix/") + .arg(QString::fromUtf8(EbmlCodeVersion.c_str())) + .arg(QString::fromUtf8(KaxCodeVersion.c_str())); + QMessageBox::about(this, tr("About " NAME), msg); +} + +void +main_window_c::show_error(const QString &msg) { + QMessageBox::critical(this, tr("Error"), msg); +} + +void +main_window_c::parse_file(const QString &file_name) { + tree->setEnabled(false); + tree->clear(); + + root = new QTreeWidgetItem(tree); + root->setText(0, file_name); + + last_percent = -1; + num_elements = 0; + action_Save_text_file->setEnabled(false); + + parent_items.clear(); + parent_items.append(root); + + if (process_file(file_name.toUtf8().data())) { + action_Save_text_file->setEnabled(true); + current_file = file_name; + if (action_Expand_important->isChecked()) + expand_elements(); + } + + statusBar()->showMessage(tr("Ready"), 5000); + + tree->setEnabled(true); +} + +void +main_window_c::expand_all_elements(QTreeWidgetItem *item, + bool expand) { + int i; + + if (expand) + tree->expandItem(item); + else + tree->collapseItem(item); + for (i = 0; item->childCount() > i; ++i) + expand_all_elements(item->child(i), expand); +} + +void +main_window_c::expand_elements() { + int l0, l1, c0, c1; + QTreeWidgetItem *i0, *i1; + const QString s_segment(tr("Segment")); + const QString s_info(tr("Segment information")); + const QString s_tracks(tr("Segment tracks")); + + setUpdatesEnabled(false); + + expand_all_elements(root, false); + tree->expandItem(root); + + c0 = root->childCount(); + for (l0 = 0; l0 < c0; ++l0) { + i0 = root->child(l0); + tree->expandItem(i0); + if (i0->text(0).left(7) == s_segment) { + c1 = i0->childCount(); + for (l1 = 0; l1 < c1; ++l1) { + i1 = i0->child(l1); + if ((i1->text(0).left(19) == s_info) || + (i1->text(0).left(14) == s_tracks)) + expand_all_elements(i1, true); + } + } + } + + setUpdatesEnabled(true); +} + +void +main_window_c::add_item(int level, + const QString &text) { + ++level; + + while (parent_items.count() > level) + parent_items.erase(parent_items.end() - 1); + QTreeWidgetItem *item = new QTreeWidgetItem(parent_items.last()); + item->setText(0, text); + parent_items.append(item); +} + +void +main_window_c::show_progress(int percentage, + const QString &text) { + if ((percentage / 5) != (last_percent / 5)) { + statusBar()->showMessage(QString("%1: %2%").arg(text).arg(percentage)); + last_percent = percentage; + QCoreApplication::processEvents(); + } +} + +static main_window_c *gui; + +rightclick_tree_widget::rightclick_tree_widget(QWidget *parent): + QTreeWidget(parent) { +} + +void +rightclick_tree_widget::mousePressEvent(QMouseEvent *event) { + if (event->button() != Qt::RightButton) { + QTreeWidget::mousePressEvent(event); + return; + } + + QTreeWidgetItem *item = itemAt(event->pos()); + if (NULL != item) + gui->expand_all_elements(item, !item->isExpanded()); +} + +void +ui_show_error(const char *text) { + if (use_gui) + gui->show_error(QString::fromUtf8(text)); + else + console_show_error(text); +} + +void +ui_show_element(int level, + const char *text, + int64_t position) { + if (!use_gui) + console_show_element(level, text, position); + + else if (0 <= position) { + string buffer = mxsprintf("%s at " LLD, text, position); + gui->add_item(level, QString::fromUtf8(buffer.c_str())); + + } else + gui->add_item(level, QString::fromUtf8(text)); +} + +void +ui_show_progress(int percentage, + const char *text) { + gui->show_progress(percentage, QString::fromUtf8(text)); +} + +int +ui_run(int argc, + char **argv) { + vector args; + string initial_file; + + QApplication app(argc, argv); + main_window_c main_window; + gui = &main_window; + main_window.show(); + + args = command_line_utf8(argc, argv); + parse_args(args, initial_file); + + if (initial_file != "") + gui->parse_file(QString::fromUtf8(initial_file.c_str())); + + return app.exec(); +} + +bool +ui_graphical_available() { + return true; +} + diff --git a/src/info/qt_ui.h b/src/info/qt_ui.h new file mode 100644 index 000000000..ccf4f80ca --- /dev/null +++ b/src/info/qt_ui.h @@ -0,0 +1,62 @@ +/* + mkvinfo -- utility for gathering information about Matroska files + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + $Id: gui.cpp 3373 2006-11-19 17:41:46Z mosu $ + + A Qt GUI for mkvinfo + + Written by Moritz Bunkus . +*/ + +#ifndef __QT_UI_H +#define __QT_UI_H + +#include "os.h" + +#include +#include +#include +#include +#include + +#include "ui/mainwindow.h" + +class main_window_c: public QMainWindow, public Ui_main_window { + Q_OBJECT; + +private slots: + void open(); + void save_text_file(); + + void show_all(); + + void about(); + +private: + int last_percent, num_elements; + + QVector parent_items; + QString current_file; + QTreeWidgetItem *root; + + void expand_elements(); + void write_tree(QFile &file, QTreeWidgetItem *item, int level); + +public: + main_window_c(); + + void show_error(const QString &message); + void show_progress(int percentage, const QString &text); + + void add_item(int level, const QString &text); + + void expand_all_elements(QTreeWidgetItem *item, bool expand); + + void parse_file(const QString &file_name); +}; + +#endif // __QT_UI_H diff --git a/src/info/rightclick_tree_widget.h b/src/info/rightclick_tree_widget.h new file mode 100644 index 000000000..a8cdaf9b8 --- /dev/null +++ b/src/info/rightclick_tree_widget.h @@ -0,0 +1,34 @@ +/* + mkvinfo -- utility for gathering information about Matroska files + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + $Id: gui.cpp 3373 2006-11-19 17:41:46Z mosu $ + + A Qt GUI for mkvinfo + + Written by Moritz Bunkus . +*/ + +#ifndef __RIGHTCLICK_TREE_WIDGET_H +#define __RIGHTCLICK_TREE_WIDGET_H + +#include "config.h" + +#include + +class rightclick_tree_widget: public QTreeWidget { + Q_OBJECT; + +public slots: + +public: + rightclick_tree_widget(QWidget *parent = NULL); + +protected: + virtual void mousePressEvent(QMouseEvent *event); +}; + +#endif // __RIGHTCLICK_TREE_WIDGET_H diff --git a/src/info/ui/mainwindow.ui b/src/info/ui/mainwindow.ui new file mode 100644 index 000000000..6a533d191 --- /dev/null +++ b/src/info/ui/mainwindow.ui @@ -0,0 +1,122 @@ + + main_window + + + + 0 + 0 + 770 + 568 + + + + mkvInfo + + + + + 0 + + + 0 + + + + + + + + + + 0 + 0 + 770 + 29 + + + + + &Options + + + + + + + &Help + + + + + + &File + + + + + + + + + + + + + + &Open + + + Ctrl+O + + + + + &Save to text file + + + Ctrl+S + + + + + E&xit + + + Ctrl+Q + + + + + Show &all elements + + + Ctrl+A + + + + + &Expand important elements + + + Ctrl+E + + + + + &About mkvinfo + + + F1 + + + + + + rightclick_tree_widget + QTreeWidget +
rightclick_tree_widget.h
+
+
+ + +
diff --git a/src/info/wxwidgets_ui.cpp b/src/info/wxwidgets_ui.cpp new file mode 100644 index 000000000..19e3b1ce5 --- /dev/null +++ b/src/info/wxwidgets_ui.cpp @@ -0,0 +1,445 @@ +/* + mkvinfo -- utility for gathering information about Matroska files + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + $Id: gui.cpp 3373 2006-11-19 17:41:46Z mosu $ + + A wxWidgets GUI for mkvinfo + + Written by Moritz Bunkus . +*/ + +#include "config.h" + +#ifdef HAVE_WXWIDGETS + +#include +#include +#include + +#include +#include + +#include "common.h" +#include "mkvinfo.h" +#include "wxwidgets_ui.h" +#if !defined(SYS_WINDOWS) +#include "matroska.xpm" +#endif +#include "wxcommon.h" + +using namespace libebml; +using namespace libmatroska; + +#if ! wxCHECK_VERSION(2,4,2) +# define wxTreeItemIdValue long +#endif + +static mi_frame *frame; + +enum { + mi_file_quit = 1, + mi_file_open = 2, + mi_file_savetext = 3, + mi_options_showall = 101, + mi_options_expandimportant = 102, + mi_help_about = wxID_ABOUT +}; + +bool +mi_app::OnInit() { + string initial_file; + vector args; + + setup(); + +#if WXUNICODE + int i; + + for (i = 1; i < argc; i++) + args.push_back(string(wxMB(wxString(argv[i])))); +#else + args = command_line_utf8(argc, argv); +#endif + + parse_args(args, initial_file); + + if (!use_gui) { + console_main(args); + return false; + } + + frame = new mi_frame(wxT("mkvinfo"), wxPoint(50, 50), wxSize(600, 400)); + frame->Show(true); + frame->Refresh(true); + frame->Update(); + while (Pending()) + Dispatch(); + + if (initial_file != "") + frame->open_file(wxU(initial_file.c_str())); + + return true; +} + +mi_frame::mi_frame(const wxString &title, + const wxPoint &pos, + const wxSize &size, + long style) : + wxFrame(NULL, -1, title, pos, size, style) { + wxMenu *menu_help; + wxMenuBar *menu_bar; + + file_open = false; + tree = NULL; + + if (verbose == 0) + show_all_elements = false; + else + show_all_elements = true; + expand_important_elements = true; + + SetIcon(wxICON(matroska)); + + menu_file = new wxMenu(); + menu_options = new wxMenu(); + menu_help = new wxMenu(); + menu_bar = new wxMenuBar(); + + menu_file->Append(mi_file_open, wxT("&Open\tCtrl-O"), + wxT("Open a Matroska file")); + menu_file->Append(mi_file_savetext, wxT("&Save info as text\tCtrl-S"), + wxT("Saves the information from the current file to a " + "text file")); + menu_file->Enable(mi_file_savetext, false); + menu_file->AppendSeparator(); + menu_file->Append(mi_file_quit, wxT("E&xit\tCtrl-Q"), + wxT("Quits mkvinfo")); + menu_options->AppendCheckItem(mi_options_showall, + wxT("Show &all elements\tCtrl-A"), + wxT("Parse the file completely and show all " + "elements")); + menu_options->Check(mi_options_showall, show_all_elements); + menu_options->AppendCheckItem(mi_options_expandimportant, + wxT("&Expand important elements\tCtrl-E"), + wxT("After loading a file expand the most " + "important elements")); + menu_options->Check(mi_options_expandimportant, expand_important_elements); + menu_help->Append(mi_help_about, wxT("&About...\tF1"), + wxT("Show about dialog")); + + menu_bar->Append(menu_file, wxT("&File")); + menu_bar->Append(menu_options, wxT("&Options")); + menu_bar->Append(menu_help, wxT("&Help")); + + SetMenuBar(menu_bar); + + tree = new wxTreeCtrl(this, 4254); + dnd_load = new mi_dndfile(); + tree->SetDropTarget(dnd_load); + + CreateStatusBar(1); + SetStatusText(wxT("ready")); + + last_dir = wxGetWorkingDirectory(); +} + +void +mi_frame::open_file(wxString file_name) { + string cfile_name; + + cfile_name = wxMB(file_name); + tree->DeleteAllItems(); + item_ids[0] = tree->AddRoot(file_name); + last_percent = -1; + num_elements = 0; + menu_file->Enable(mi_file_open, false); + menu_file->Enable(mi_file_savetext, false); + menu_options->Enable(mi_options_showall, false); + + if (process_file(cfile_name)) { + file_open = true; + menu_file->Enable(mi_file_savetext, true); + current_file = file_name; + if (expand_important_elements) + expand_elements(); + } else { + tree->DeleteAllItems(); + menu_file->Enable(mi_file_savetext, false); + } + menu_file->Enable(mi_file_open, true); + menu_options->Enable(mi_options_showall, true); + SetStatusText(wxT("ready")); + tree->Refresh(); +} + +void +mi_frame::show_progress(int percent, + wxString msg) { + wxString s; + + if ((percent / 5) != (last_percent / 5)) { + s.Printf(wxT("%s: %d%%"), msg.c_str(), percent); + SetStatusText(s); + last_percent = percent; + } + wxYield(); +} + +void +mi_frame::expand_all_elements(wxTreeItemId &root, + bool expand) { + wxTreeItemId child; + wxTreeItemIdValue cookie; + + if (expand) + tree->Expand(root); + else + tree->Collapse(root); + child = tree->GetFirstChild(root, cookie); + while (child > 0) { + expand_all_elements(child, expand); + child = tree->GetNextChild(root, cookie); + } +} + +void +mi_frame::expand_elements() { + wxTreeItemId l0, l1; + wxTreeItemIdValue cl0, cl1; + + Freeze(); + + expand_all_elements(item_ids[0], false); + tree->Expand(item_ids[0]); + + l0 = tree->GetFirstChild(item_ids[0], cl0); + while (l0 > 0) { + tree->Expand(l0); + if (tree->GetItemText(l0).find(wxT("Segment")) == 0) { + l1 = tree->GetFirstChild(l0, cl1); + while (l1 > 0) { + if ((tree->GetItemText(l1).find(wxT("Segment information")) == 0) || + (tree->GetItemText(l1).find(wxT("Segment tracks")) == 0)) + expand_all_elements(l1); + l1 = tree->GetNextChild(l0, cl1); + } + } + + l0 = tree->GetNextChild(item_ids[0], cl0); + } + + Thaw(); +} + +void +mi_frame::add_item(int level, + wxString text) { + item_ids[level + 1] = tree->AppendItem(item_ids[level], text); + num_elements++; +} + +void +mi_frame::show_error(wxString msg) { + wxMessageBox(msg, wxT("Error"), wxOK | wxICON_ERROR | wxCENTER, this); +} + +void +mi_frame::save_elements(wxTreeItemId &root, + int level, + FILE *f) { + wxTreeItemId child; + wxTreeItemIdValue cookie; + char level_buffer[10]; + int pcnt_before, pcnt_now; + + if (level >= 0) { + memset(&level_buffer[1], ' ', 9); + level_buffer[0] = '|'; + level_buffer[level] = 0; + fprintf(f, "(%s) %s+ %s\n", NAME, level_buffer, + wxMB(tree->GetItemText(root))); + pcnt_before = elements_saved * 100 / num_elements; + pcnt_now = (elements_saved + 1) * 100 / num_elements; + if ((pcnt_before / 5) != (pcnt_now / 5)) + show_progress(pcnt_now, wxT("Writing info")); + elements_saved++; + } + child = tree->GetFirstChild(root, cookie); + while (child > 0) { + save_elements(child, level + 1, f); + child = tree->GetNextChild(root, cookie); + } +} + +void +mi_frame::on_file_open(wxCommandEvent &WXUNUSED(event)) { + wxFileDialog file_dialog(this, wxT("Select Matroska file"), wxT(""), wxT(""), + wxT("Matroska files (*.mkv;*.mka;*.mks)|" + "*.mkv;*.mka;*.mks|All files|*.*")); + file_dialog.SetDirectory(last_dir); + if (file_dialog.ShowModal() == wxID_OK) { + open_file(file_dialog.GetPath().c_str()); + last_dir = file_dialog.GetDirectory(); + } +} + +void +mi_frame::on_file_savetext(wxCommandEvent &WXUNUSED(event)) { + FILE *f; + + wxFileDialog file_dialog(this, wxT("Select output file"), wxT(""), wxT(""), + wxT("Text files (*.txt)|*.txt|All files|*.*"), + wxSAVE | wxOVERWRITE_PROMPT); + file_dialog.SetDirectory(last_dir); + if (file_dialog.ShowModal() == wxID_OK) { + last_dir = file_dialog.GetDirectory(); + f = fopen(wxMB(file_dialog.GetPath()), "w"); + if (f == NULL) { + wxString s; + s.Printf(wxT("Could not create the file '%s'."), + file_dialog.GetPath().c_str()); + show_error(s); + return; + } + + menu_file->Enable(mi_file_open, false); + menu_file->Enable(mi_file_savetext, false); + menu_options->Enable(mi_options_showall, false); + save_elements(item_ids[0], -1, f); + menu_file->Enable(mi_file_open, true); + menu_file->Enable(mi_file_savetext, true); + menu_options->Enable(mi_options_showall, true); + + fclose(f); + } +} + +void +mi_frame::on_file_quit(wxCommandEvent &WXUNUSED(event)) { + Close(true); +} + +void +mi_frame::on_options_showall(wxCommandEvent &WXUNUSED(event)) { + show_all_elements = !show_all_elements; + menu_options->Check(mi_options_showall, show_all_elements); + if (show_all_elements) + verbose = 2; + else + verbose = 0; + if (file_open) + open_file(current_file); +} + +void +mi_frame::on_options_expandimportant(wxCommandEvent &WXUNUSED(event)) { + expand_important_elements = !expand_important_elements; + menu_options->Check(mi_options_expandimportant, + expand_important_elements); +} + +void +mi_frame::on_help_about(wxCommandEvent &WXUNUSED(event)) { + wxString msg; + msg.Printf(wxT(VERSIONINFO ".\nCompiled with libebml %s + " + "libmatroska %s.\n\nThis program is licensed under the " + "GPL v2 (see COPYING).\nIt was written by Moritz Bunkus " + ".\nSources and the latest binaries are " + "always available at\nhttp://www.bunkus.org/videotools/" + "mkvtoolnix/"), + wxCS2WS(EbmlCodeVersion), wxCS2WS(KaxCodeVersion)); + wxMessageBox(msg, wxT("About mkvinfo"), wxOK | wxICON_INFORMATION, this); +} + +void +mi_frame::on_right_click(wxTreeEvent &event) { + wxTreeItemId item; + + item = event.GetItem(); + if (tree->GetChildrenCount(item) == 0) + return; + expand_all_elements(item, !tree->IsExpanded(item)); +} + +bool +mi_dndfile::OnDropFiles(wxCoord x, + wxCoord y, + const wxArrayString &filenames) { + wxString dnd_file; + unsigned int i; + + for (i = 0; i < filenames.GetCount(); i++) { + dnd_file = filenames[i]; + if ((dnd_file.Right(3).Lower() == wxT("mka")) || + (dnd_file.Right(3).Lower() == wxT("mkv")) || + (dnd_file.Right(3).Lower() == wxT("mks"))) { + frame->open_file(dnd_file); + } else { + wxString msg; + msg.Printf(wxT("The dragged file '%s'\nis not a Matroska file."), + dnd_file.c_str()); + frame->show_error(msg.c_str()); + break; + } + } + return true; +} + +BEGIN_EVENT_TABLE(mi_frame, wxFrame) + EVT_MENU(mi_file_open, mi_frame::on_file_open) + EVT_MENU(mi_file_savetext, mi_frame::on_file_savetext) + EVT_MENU(mi_file_quit, mi_frame::on_file_quit) + EVT_MENU(mi_options_showall, mi_frame::on_options_showall) + EVT_MENU(mi_options_expandimportant, mi_frame::on_options_expandimportant) + EVT_MENU(mi_help_about, mi_frame::on_help_about) + EVT_TREE_ITEM_RIGHT_CLICK(4254, mi_frame::on_right_click) +END_EVENT_TABLE() + +IMPLEMENT_APP_NO_MAIN(mi_app) + +void +ui_show_error(const char *text) { + if (use_gui) + frame->show_error(wxU(text)); + else + console_show_error(text); +} + +void +ui_show_element(int level, + const char *text, + int64_t position) { + if (!use_gui) + console_show_element(level, text, position); + + else if (0 <= position) { + string buffer = mxsprintf("%s at " LLD, text, position); + frame->add_item(level, wxU(buffer.c_str())); + + } else + frame->add_item(level, wxU(text)); +} + +void +ui_show_progress(int percentage, + const char *text) { + frame->show_progress(percentage, wxU(text)); +} + +int +ui_run(int argc, + char **argv) { + wxEntry(argc, argv); + return 0; +} + +bool +ui_graphical_available() { + return true; +} + +#endif // HAVE_WXWIDGETS diff --git a/src/info/wxwidgets_ui.h b/src/info/wxwidgets_ui.h new file mode 100644 index 000000000..c83cfce69 --- /dev/null +++ b/src/info/wxwidgets_ui.h @@ -0,0 +1,84 @@ +/* + mkvmerge -- utility for splicing together matroska files + from component media subtypes + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + $Id: mkvinfo.h 3373 2006-11-19 17:41:46Z mosu $ + + definition of global variables and functions + + Written by Moritz Bunkus . +*/ + + +#ifndef __WXWIDGETS_UI_H +#define __WXWIDGETS_UI_H + +#include "os.h" + +#ifdef HAVE_WXWIDGETS + +#include +#include +#include + +#include "wxcommon.h" + +class mi_app: public wxApp { +public: + virtual bool OnInit(); +}; + +class mi_dndfile: public wxFileDropTarget { +public: + virtual bool OnDropFiles(wxCoord x, wxCoord y, + const wxArrayString &filenames); +}; + +class mi_frame: public wxFrame { +private: + //For Drag-n-Drop + mi_dndfile *dnd_load; + wxMenu *menu_options, *menu_file; + bool show_all_elements, expand_important_elements; + bool file_open; + int last_percent; + int64_t num_elements, elements_saved; + wxString current_file, last_dir; + + wxTreeCtrl *tree; + wxTreeItemId item_ids[10]; + +public: + mi_frame(const wxString &title, const wxPoint &pos, const wxSize &size, + long style = wxDEFAULT_FRAME_STYLE); + + void open_file(wxString file_name); + void show_progress(int percent, wxString msg); + void show_error(wxString msg); + void add_item(int level, wxString text); + +protected: + void on_file_open(wxCommandEvent &event); + void on_file_savetext(wxCommandEvent &event); + void on_file_quit(wxCommandEvent &event); + void on_options_showall(wxCommandEvent &event); + void on_options_expandimportant(wxCommandEvent &event); + void on_help_about(wxCommandEvent &event); + void on_right_click(wxTreeEvent &event); + + void expand_elements(); + void expand_all_elements(wxTreeItemId &root, bool expand = true); + + void save_elements(wxTreeItemId &root, int level, FILE *f); + +private: + DECLARE_EVENT_TABLE() +}; + +#endif // HAVE_WXWIDGETS + +#endif // __WXWIDGETS_UI_H