# HG changeset patch # User Jacob Dawid # Date 1340027490 -7200 # Node ID 8e9f2cfa114d97b7f45df17c514f39a6d09b3f48 # Parent f43916137064a96de072f1bc80a5c876ff436f34# Parent 1230d5d58d2d1796be72d127f306449e4488b913 maint: periodic merge from default to gui diff --git a/.hgsub b/.hgsub --- a/.hgsub +++ b/.hgsub @@ -1,1 +1,2 @@ gnulib = [git]git://git.sv.gnu.org/gnulib +gui/qterminal = [git]https://code.google.com/p/qterminal/ diff --git a/.hgsubstate b/.hgsubstate --- a/.hgsubstate +++ b/.hgsubstate @@ -1,1 +1,2 @@ 33f823397dbb0edb57503f2f6dad2362456bc6a9 gnulib +9d13275430aae701805095845a857e3f528c7aad gui/qterminal diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Summary of important user-visible changes for version 4.0: +--------------------------------------------------------- + + ** A new GUI is now available with Octave. + Summary of important user-visible changes for version 3.8: --------------------------------------------------------- diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -741,6 +741,520 @@ FFT_DIR="fftpack" AC_SUBST(FFT_DIR) +dnl @synopsis BNV_HAVE_QT [--with-Qt-dir=DIR] [--with-Qt-lib-dir=DIR] [--with-Qt-lib=LIB] +dnl @synopsis BNV_HAVE_QT [--with-Qt-include-dir=DIR] [--with-Qt-bin-dir=DIR] [--with-Qt-lib-dir=DIR] [--with-Qt-lib=LIB] +dnl +dnl @summary Search for Trolltech's Qt GUI framework. +dnl +dnl Searches common directories for Qt include files, libraries and Qt +dnl binary utilities. The macro supports several different versions of +dnl the Qt framework being installed on the same machine. Without +dnl options, the macro is designed to look for the latest library, +dnl i.e., the highest definition of QT_VERSION in qglobal.h. By use of +dnl one or more options a different library may be selected. There are +dnl two different sets of options. Both sets contain the option +dnl --with-Qt-lib=LIB which can be used to force the use of a +dnl particular version of the library file when more than one are +dnl available. LIB must be in the form as it would appear behind the +dnl "-l" option to the compiler. Examples for LIB would be "qt-mt" for +dnl the multi-threaded version and "qt" for the regular version. In +dnl addition to this, the first set consists of an option +dnl --with-Qt-dir=DIR which can be used when the installation conforms +dnl to Trolltech's standard installation, which means that header files +dnl are in DIR/include, binary utilities are in DIR/bin and the library +dnl is in DIR/lib. The second set of options can be used to indicate +dnl individual locations for the header files, the binary utilities and +dnl the library file, in addition to the specific version of the +dnl library file. +dnl +dnl The following shell variable is set to either "yes" or "no": +dnl +dnl have_qt +dnl +dnl Additionally, the following variables are exported: +dnl +dnl QT_CXXFLAGS +dnl QT_LIBS +dnl QT_MOC +dnl QT_UIC +dnl QT_DIR +dnl +dnl which respectively contain an "-I" flag pointing to the Qt include +dnl directory (and "-DQT_THREAD_SUPPORT" when LIB is "qt-mt"), link +dnl flags necessary to link with Qt and X, the name of the meta object +dnl compiler and the user interface compiler both with full path, and +dnl finaly the variable QTDIR as Trolltech likes to see it defined (if +dnl possible). +dnl +dnl Example lines for Makefile.in: +dnl +dnl CXXFLAGS = @QT_CXXFLAGS@ +dnl MOC = @QT_MOC@ +dnl +dnl After the variables have been set, a trial compile and link is +dnl performed to check the correct functioning of the meta object +dnl compiler. This test may fail when the different detected elements +dnl stem from different releases of the Qt framework. In that case, an +dnl error message is emitted and configure stops. +dnl +dnl No common variables such as $LIBS or $CFLAGS are polluted. +dnl +dnl Options: +dnl +dnl --with-Qt-dir=DIR: DIR is equal to $QTDIR if you have followed the +dnl installation instructions of Trolltech. Header files are in +dnl DIR/include, binary utilities are in DIR/bin and the library is in +dnl DIR/lib. +dnl +dnl --with-Qt-include-dir=DIR: Qt header files are in DIR. +dnl +dnl --with-Qt-bin-dir=DIR: Qt utilities such as moc and uic are in DIR. +dnl +dnl --with-Qt-lib-dir=DIR: The Qt library is in DIR. +dnl +dnl --with-Qt-lib=LIB: Use -lLIB to link with the Qt library. +dnl +dnl If some option "=no" or, equivalently, a --without-Qt-* version is +dnl given in stead of a --with-Qt-*, "have_qt" is set to "no" and the +dnl other variables are set to the empty string. +dnl +dnl @category InstalledPackages +dnl @author Bastiaan Veelo +dnl @version 2006-03-12 +dnl @license AllPermissive + +dnl Copyright (C) 2001, 2002, 2003, 2005, 2006 Bastiaan Veelo + +dnl THANKS! This code includes bug fixes and contributions made by: +dnl Tim McClarren, +dnl Dennis R. Weilert, +dnl Qingning Huo, +dnl Brian Mingus, +dnl Jens Hannemann, +dnl Pavel Roskin, +dnl Scott J. Bertin. + +dnl ChangeLog +dnl 2006-03-12 * Hide output of ls and fix an m4 quoting problem (due to Scott J. Bertin). +dnl 2006-02-13 * Check compiler return value instead of parsing the error stream, +dnl which detected warnings as false negatives (due to Jens Hannemann). +dnl 2006-02-02 * Spelling of "Success". +dnl * Fixed unsave test for $bnv_qt_lib without quotes. +dnl * Put dnl in front of all comments. +dnl * Changed -l$bnv_qt_lib_dir into -L$bnv_qt_lib_dir (all due to Pavel Roskin). +dnl 2006-01-19 * Support for 64bit architectures. +dnl * Updated documentation. +dnl 2006-01-18: * Fix "cat: bnv_qt_test.c: No such file or directory" (due to Jens Hannemann). +dnl * Hide output of failing ls. +dnl 2006-01-11: * Check in /Developer on Mac OS X; Check in $QTDIR (due to Brian Mingus). + +dnl Calls BNV_PATH_QT_DIRECT (contained in this file) as a subroutine. +AC_DEFUN([BNV_HAVE_QT], +[ + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_PATH_X]) + AC_REQUIRE([AC_PATH_XTRA]) + + AC_MSG_CHECKING(for Qt) + + AC_ARG_WITH([Qt-dir], + [ --with-Qt-dir=DIR DIR is equal to $QTDIR if you have followed the + installation instructions of Trolltech. Header + files are in DIR/include, binary utilities are + in DIR/bin. The library is in DIR/lib, unless + --with-Qt-lib-dir is also set.]) + AC_ARG_WITH([Qt-include-dir], + [ --with-Qt-include-dir=DIR + Qt header files are in DIR]) + AC_ARG_WITH([Qt-bin-dir], + [ --with-Qt-bin-dir=DIR Qt utilities such as moc and uic are in DIR]) + AC_ARG_WITH([Qt-lib-dir], + [ --with-Qt-lib-dir=DIR The Qt library is in DIR]) + AC_ARG_WITH([Qt-lib], + [ --with-Qt-lib=LIB Use -lLIB to link with the Qt library]) + if test x"$with_Qt_dir" = x"no" || + test x"$with_Qt_include-dir" = x"no" || + test x"$with_Qt_bin_dir" = x"no" || + test x"$with_Qt_lib_dir" = x"no" || + test x"$with_Qt_lib" = x"no"; then + # user disabled Qt. Leave cache alone. + have_qt="User disabled Qt." + else + # "yes" is a bogus option + if test x"$with_Qt_dir" = xyes; then + with_Qt_dir= + fi + if test x"$with_Qt_include_dir" = xyes; then + with_Qt_include_dir= + fi + if test x"$with_Qt_bin_dir" = xyes; then + with_Qt_bin_dir= + fi + if test x"$with_Qt_lib_dir" = xyes; then + with_Qt_lib_dir= + fi + if test x"$with_Qt_lib" = xyes; then + with_Qt_lib= + fi + # No Qt unless we discover otherwise + have_qt=no + # Check whether we are requested to link with a specific version + if test x"$with_Qt_lib" != x; then + bnv_qt_lib="$with_Qt_lib" + fi + # Check whether we were supplied with an answer already + if test x"$with_Qt_dir" != x; then + have_qt=yes + bnv_qt_dir="$with_Qt_dir" + bnv_qt_include_dir="$with_Qt_dir/include" + bnv_qt_bin_dir="$with_Qt_dir/bin" + bnv_qt_lib_dir="$with_Qt_dir/lib" + # Only search for the lib if the user did not define one already + if test x"$bnv_qt_lib" = x; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # Use cached value or do search, starting with suggestions from + # the command line + AC_CACHE_VAL(bnv_cv_have_qt, + [ + # We are not given a solution and there is no cached value. + bnv_qt_dir=NO + bnv_qt_include_dir=NO + bnv_qt_lib_dir=NO + if test x"$bnv_qt_lib" = x; then + bnv_qt_lib=NO + fi + BNV_PATH_QT_DIRECT + if test "$bnv_qt_dir" = NO || + test "$bnv_qt_include_dir" = NO || + test "$bnv_qt_lib_dir" = NO || + test "$bnv_qt_lib" = NO; then + # Problem with finding complete Qt. Cache the known absence of Qt. + bnv_cv_have_qt="have_qt=no" + else + # Record where we found Qt for the cache. + bnv_cv_have_qt="have_qt=yes \ + bnv_qt_dir=$bnv_qt_dir \ + bnv_qt_include_dir=$bnv_qt_include_dir \ + bnv_qt_bin_dir=$bnv_qt_bin_dir \ + bnv_qt_LIBS=\"$bnv_qt_LIBS\"" + fi + ])dnl + eval "$bnv_cv_have_qt" + fi # all $bnv_qt_* are set + fi # $have_qt reflects the system status + if test x"$have_qt" = xyes; then + QT_CXXFLAGS="-I$bnv_qt_include_dir" + if test x"$bnv_qt_lib" = xqt-mt; then + QT_CXXFLAGS="$QT_CXXFLAGS -DQT_THREAD_SUPPORT" + fi + QT_DIR="$bnv_qt_dir" + QT_LIBS="$bnv_qt_LIBS" + # If bnv_qt_dir is defined, utilities are expected to be in the + # bin subdirectory + if test x"$bnv_qt_dir" != x; then + if test -x "$bnv_qt_dir/bin/uic"; then + QT_UIC="$bnv_qt_dir/bin/uic" + else + # Old versions of Qt don't have uic + QT_UIC= + fi + QT_MOC="$bnv_qt_dir/bin/moc" + else + # Or maybe we are told where to look for the utilities + if test x"$bnv_qt_bin_dir" != x; then + if test -x "$bnv_qt_bin_dir/uic"; then + QT_UIC="$bnv_qt_bin_dir/uic" + else + # Old versions of Qt don't have uic + QT_UIC= + fi + QT_MOC="$bnv_qt_bin_dir/moc" + else + # Last possibility is that they are in $PATH + QT_UIC="`which uic`" + QT_MOC="`which moc`" + fi + fi + # All variables are defined, report the result + AC_MSG_RESULT([$have_qt: + QT_CXXFLAGS=$QT_CXXFLAGS + QT_DIR=$QT_DIR + QT_LIBS=$QT_LIBS + QT_UIC=$QT_UIC + QT_MOC=$QT_MOC]) + else + # Qt was not found + QT_CXXFLAGS= + QT_DIR= + QT_LIBS= + QT_UIC= + QT_MOC= + AC_MSG_RESULT($have_qt) + fi + AC_SUBST(QT_CXXFLAGS) + AC_SUBST(QT_DIR) + AC_SUBST(QT_LIBS) + AC_SUBST(QT_UIC) + AC_SUBST(QT_MOC) + + #### Being paranoid: + if test x"$have_qt" = xyes; then + AC_MSG_CHECKING(correct functioning of Qt installation) + AC_CACHE_VAL(bnv_cv_qt_test_result, + [ + cat > bnv_qt_test.h << EOF +#include +class Test : public QObject +{ +Q_OBJECT +public: + Test() {} + ~Test() {} +public slots: + void receive() {} +signals: + void send(); +}; +EOF + + cat > bnv_qt_main.$ac_ext << EOF +#include "bnv_qt_test.h" +#include +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + Test t; + QObject::connect( &t, SIGNAL(send()), &t, SLOT(receive()) ); +} +EOF + + bnv_cv_qt_test_result="failure" + bnv_try_1="$QT_MOC bnv_qt_test.h -o moc_bnv_qt_test.$ac_ext >/dev/null 2>/dev/null" + AC_TRY_EVAL(bnv_try_1) + if test x"$ac_status" != x0; then + echo "$bnv_err_1" >&AC_FD_CC + echo "configure: could not run $QT_MOC on:" >&AC_FD_CC + cat bnv_qt_test.h >&AC_FD_CC + else + bnv_try_2="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o moc_bnv_qt_test.o moc_bnv_qt_test.$ac_ext >/dev/null 2>/dev/null" + AC_TRY_EVAL(bnv_try_2) + if test x"$ac_status" != x0; then + echo "$bnv_err_2" >&AC_FD_CC + echo "configure: could not compile:" >&AC_FD_CC + cat moc_bnv_qt_test.$ac_ext >&AC_FD_CC + else + bnv_try_3="$CXX $QT_CXXFLAGS -c $CXXFLAGS -o bnv_qt_main.o bnv_qt_main.$ac_ext >/dev/null 2>/dev/null" + AC_TRY_EVAL(bnv_try_3) + if test x"$ac_status" != x0; then + echo "$bnv_err_3" >&AC_FD_CC + echo "configure: could not compile:" >&AC_FD_CC + cat bnv_qt_main.$ac_ext >&AC_FD_CC + else + bnv_try_4="$CXX $QT_LIBS $LIBS -o bnv_qt_main bnv_qt_main.o moc_bnv_qt_test.o >/dev/null 2>/dev/null" + AC_TRY_EVAL(bnv_try_4) + if test x"$ac_status" != x0; then + echo "$bnv_err_4" >&AC_FD_CC + else + bnv_cv_qt_test_result="success" + fi + fi + fi + fi + ])dnl AC_CACHE_VAL bnv_cv_qt_test_result + AC_MSG_RESULT([$bnv_cv_qt_test_result]); + if test x"$bnv_cv_qt_test_result" = "xfailure"; then + AC_MSG_ERROR([Failed to find matching components of a complete + Qt installation. Try using more options, + see ./configure --help.]) + fi + + rm -f bnv_qt_test.h moc_bnv_qt_test.$ac_ext moc_bnv_qt_test.o \ + bnv_qt_main.$ac_ext bnv_qt_main.o bnv_qt_main + fi +]) + +dnl Internal subroutine of BNV_HAVE_QT +dnl Set bnv_qt_dir bnv_qt_include_dir bnv_qt_bin_dir bnv_qt_lib_dir bnv_qt_lib +AC_DEFUN([BNV_PATH_QT_DIRECT], +[ + ## Binary utilities ## + if test x"$with_Qt_bin_dir" != x; then + bnv_qt_bin_dir=$with_Qt_bin_dir + fi + ## Look for header files ## + if test x"$with_Qt_include_dir" != x; then + bnv_qt_include_dir="$with_Qt_include_dir" + else + # The following header file is expected to define QT_VERSION. + qt_direct_test_header=qglobal.h + # Look for the header file in a standard set of common directories. + bnv_include_path_list=" + /usr/include + `ls -dr ${QTDIR}/include 2>/dev/null` + `ls -dr /usr/include/qt* 2>/dev/null` + `ls -dr /usr/lib/qt*/include 2>/dev/null` + `ls -dr /usr/local/qt*/include 2>/dev/null` + `ls -dr /opt/qt*/include 2>/dev/null` + `ls -dr /Developer/qt*/include 2>/dev/null` + " + for bnv_dir in $bnv_include_path_list; do + if test -r "$bnv_dir/$qt_direct_test_header"; then + bnv_dirs="$bnv_dirs $bnv_dir" + fi + done + # Now look for the newest in this list + bnv_prev_ver=0 + for bnv_dir in $bnv_dirs; do + bnv_this_ver=`egrep -w '#define QT_VERSION' $bnv_dir/$qt_direct_test_header | sed s/'#define QT_VERSION'//` + if expr $bnv_this_ver '>' $bnv_prev_ver > /dev/null; then + bnv_qt_include_dir=$bnv_dir + bnv_prev_ver=$bnv_this_ver + fi + done + fi dnl Found header files. + + # Are these headers located in a traditional Trolltech installation? + # That would be $bnv_qt_include_dir stripped from its last element: + bnv_possible_qt_dir=`dirname $bnv_qt_include_dir` + if (test -x $bnv_possible_qt_dir/bin/moc) && + ((ls $bnv_possible_qt_dir/lib/libqt* > /dev/null 2>/dev/null) || + (ls $bnv_possible_qt_dir/lib64/libqt* > /dev/null 2>/dev/null)); then + # Then the rest is a piece of cake + bnv_qt_dir=$bnv_possible_qt_dir + bnv_qt_bin_dir="$bnv_qt_dir/bin" + if test x"$with_Qt_lib_dir" != x; then + bnv_qt_lib_dir="$with_Qt_lib_dir" + else + if (test -d $bnv_qt_dir/lib64); then + bnv_qt_lib_dir="$bnv_qt_dir/lib64" + else + bnv_qt_lib_dir="$bnv_qt_dir/lib" + fi + fi + # Only look for lib if the user did not supply it already + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # There is no valid definition for $QTDIR as Trolltech likes to see it + bnv_qt_dir= + ## Look for Qt library ## + if test x"$with_Qt_lib_dir" != x; then + bnv_qt_lib_dir="$with_Qt_lib_dir" + # Only look for lib if the user did not supply it already + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib="`ls $bnv_qt_lib_dir/libqt* | sed -n 1p | + sed s@$bnv_qt_lib_dir/lib@@ | [sed s@[.].*@@]`" + fi + bnv_qt_LIBS="-L$bnv_qt_lib_dir -l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + else + # Normally, when there is no traditional Trolltech installation, + # the library is installed in a place where the linker finds it + # automatically. + # If the user did not define the library name, try with qt + if test x"$bnv_qt_lib" = xNO; then + bnv_qt_lib=qt + fi + qt_direct_test_header=qapplication.h + qt_direct_test_main=" + int argc; + char ** argv; + QApplication app(argc,argv); + " + # See if we find the library without any special options. + # Don't add top $LIBS permanently yet + bnv_save_LIBS="$LIBS" + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + bnv_qt_LIBS="$LIBS" + bnv_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="-I$bnv_qt_include_dir" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Success. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Try the multi-threaded version + echo "Non-critical error, please neglect the above." >&AC_FD_CC + bnv_qt_lib=qt-mt + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Success. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Try the OpenGL version + echo "Non-critical error, please neglect the above." >&AC_FD_CC + bnv_qt_lib=qt-gl + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Success. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # That did not work. Maybe a library version I don't know about? + echo "Non-critical error, please neglect the above." >&AC_FD_CC + # Look for some Qt lib in a standard set of common directories. + bnv_dir_list=" + `echo $bnv_qt_includes | sed ss/includess` + /lib + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /opt/lib64 + /opt/lib + `ls -dr /usr/lib64/qt* 2>/dev/null` + `ls -dr /usr/lib64/qt*/lib64 2>/dev/null` + `ls -dr /usr/lib/qt* 2>/dev/null` + `ls -dr /usr/local/qt* 2>/dev/null` + `ls -dr /opt/qt* 2>/dev/null` + " + for bnv_dir in $bnv_dir_list; do + if ls $bnv_dir/libqt* >/dev/null 2>/dev/null; then + # Gamble that it's the first one... + bnv_qt_lib="`ls $bnv_dir/libqt* | sed -n 1p | + sed s@$bnv_dir/lib@@ | sed s/[[.]].*//`" + bnv_qt_lib_dir="$bnv_dir" + break + fi + done + # Try with that one + LIBS="-l$bnv_qt_lib $X_PRE_LIBS $X_LIBS -lX11 -lXext -lXmu -lXt -lXi $X_EXTRA_LIBS" + AC_TRY_LINK([#include <$qt_direct_test_header>], + $qt_direct_test_main, + [ + # Success. + # We can link with no special library directory. + bnv_qt_lib_dir= + ], [ + # Leave bnv_qt_lib_dir defined + ]) + ]) + ]) + ]) + if test x"$bnv_qt_lib_dir" != x; then + bnv_qt_LIBS="-L$bnv_qt_lib_dir $LIBS" + else + bnv_qt_LIBS="$LIBS" + fi + LIBS="$bnv_save_LIBS" + CXXFLAGS="$bnv_save_CXXFLAGS" + fi dnl $with_Qt_lib_dir was not given + fi dnl Done setting up for non-traditional Trolltech installation +]) + # Checks for FFTW header and library. OCTAVE_CHECK_LIBRARY(fftw3, FFTW3, diff --git a/doc/interpreter/contributors.in b/doc/interpreter/contributors.in --- a/doc/interpreter/contributors.in +++ b/doc/interpreter/contributors.in @@ -294,3 +294,6 @@ Michael Zeising Federico Zenith Alex Zvoleff +Valentin Ortega-Clavero +Jacob Dawid +Júlio Hoffimann diff --git a/gui/gui.pro b/gui/gui.pro new file mode 100644 --- /dev/null +++ b/gui/gui.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = qterminal src diff --git a/gui/kb-layouts/default.keytab b/gui/kb-layouts/default.keytab new file mode 100644 --- /dev/null +++ b/gui/kb-layouts/default.keytab @@ -0,0 +1,133 @@ +# [README.default.Keytab] Buildin Keyboard Table +# +# To customize your keyboard, copy this file to something +# ending with .keytab and change it to meet you needs. +# Please read the README.KeyTab and the README.keyboard +# in this case. +# +# -------------------------------------------------------------- + +keyboard "Default (XFree 4)" + +# -------------------------------------------------------------- +# +# Note that this particular table is a "risc" version made to +# ease customization without bothering with obsolete details. +# See VT100.keytab for the more hairy stuff. +# +# -------------------------------------------------------------- + +# common keys + +key Escape : "\E" + +key Tab -Shift : "\t" +key Tab +Shift+Ansi : "\E[Z" +key Tab +Shift-Ansi : "\t" +key Backtab +Ansi : "\E[Z" +key Backtab -Ansi : "\t" + +key Return-Shift-NewLine : "\r" +key Return-Shift+NewLine : "\r\n" + +key Return+Shift : "\EOM" + +# Backspace and Delete codes are preserving CTRL-H. + +key Backspace : "\x7f" + +# Arrow keys in VT52 mode +# shift up/down are reserved for scrolling. +# shift left/right are reserved for switching between tabs (this is hardcoded). + +key Up -Shift-Ansi : "\EA" +key Down -Shift-Ansi : "\EB" +key Right-Shift-Ansi : "\EC" +key Left -Shift-Ansi : "\ED" + +# Arrow keys in ANSI mode with Application - and Normal Cursor Mode) + +key Up -Shift-AnyMod+Ansi+AppCuKeys : "\EOA" +key Down -Shift-AnyMod+Ansi+AppCuKeys : "\EOB" +key Right -Shift-AnyMod+Ansi+AppCuKeys : "\EOC" +key Left -Shift-AnyMod+Ansi+AppCuKeys : "\EOD" + +key Up -Shift-AnyMod+Ansi-AppCuKeys : "\E[A" +key Down -Shift-AnyMod+Ansi-AppCuKeys : "\E[B" +key Right -Shift-AnyMod+Ansi-AppCuKeys : "\E[C" +key Left -Shift-AnyMod+Ansi-AppCuKeys : "\E[D" + +key Up -Shift+AnyMod+Ansi : "\E[1;*A" +key Down -Shift+AnyMod+Ansi : "\E[1;*B" +key Right -Shift+AnyMod+Ansi : "\E[1;*C" +key Left -Shift+AnyMod+Ansi : "\E[1;*D" + +# other grey PC keys + +key Enter+NewLine : "\r\n" +key Enter-NewLine : "\r" + +key Home -AnyMod -AppCuKeys : "\E[H" +key End -AnyMod -AppCuKeys : "\E[F" +key Home -AnyMod +AppCuKeys : "\EOH" +key End -AnyMod +AppCuKeys : "\EOF" +key Home +AnyMod : "\E[1;*H" +key End +AnyMod : "\E[1;*F" + +key Insert -AnyMod : "\E[2~" +key Delete -AnyMod : "\E[3~" +key Insert +AnyMod : "\E[2;*~" +key Delete +AnyMod : "\E[3;*~" + +key Prior -Shift-AnyMod : "\E[5~" +key Next -Shift-AnyMod : "\E[6~" +key Prior -Shift+AnyMod : "\E[5;*~" +key Next -Shift+AnyMod : "\E[6;*~" + +# Function keys +key F1 -AnyMod : "\EOP" +key F2 -AnyMod : "\EOQ" +key F3 -AnyMod : "\EOR" +key F4 -AnyMod : "\EOS" +key F5 -AnyMod : "\E[15~" +key F6 -AnyMod : "\E[17~" +key F7 -AnyMod : "\E[18~" +key F8 -AnyMod : "\E[19~" +key F9 -AnyMod : "\E[20~" +key F10 -AnyMod : "\E[21~" +key F11 -AnyMod : "\E[23~" +key F12 -AnyMod : "\E[24~" + +key F1 +AnyMod : "\EO*P" +key F2 +AnyMod : "\EO*Q" +key F3 +AnyMod : "\EO*R" +key F4 +AnyMod : "\EO*S" +key F5 +AnyMod : "\E[15;*~" +key F6 +AnyMod : "\E[17;*~" +key F7 +AnyMod : "\E[18;*~" +key F8 +AnyMod : "\E[19;*~" +key F9 +AnyMod : "\E[20;*~" +key F10 +AnyMod : "\E[21;*~" +key F11 +AnyMod : "\E[23;*~" +key F12 +AnyMod : "\E[24;*~" + +# Work around dead keys + +key Space +Control : "\x00" + +# Some keys are used by konsole to cause operations. +# The scroll* operations refer to the history buffer. + +key Up +Shift-AppScreen : scrollLineUp +key Prior +Shift-AppScreen : scrollPageUp +key Down +Shift-AppScreen : scrollLineDown +key Next +Shift-AppScreen : scrollPageDown + +#key Up +Shift : scrollLineUp +#key Prior +Shift : scrollPageUp +#key Down +Shift : scrollLineDown +#key Next +Shift : scrollPageDown + +key ScrollLock : scrollLock + +# keypad characters are not offered differently by Qt. diff --git a/gui/kb-layouts/linux.keytab b/gui/kb-layouts/linux.keytab new file mode 100644 --- /dev/null +++ b/gui/kb-layouts/linux.keytab @@ -0,0 +1,133 @@ +# [linux.keytab] Konsole Keyboard Table (Linux console keys) +# +# -------------------------------------------------------------- + +# NOT TESTED, MAY NEED SOME CLEANUPS +keyboard "Linux console" + +# -------------------------------------------------------------- +# +# This configuration table allows to customize the +# meaning of the keys. +# +# The syntax is that each entry has the form : +# +# "key" Keyname { ("+"|"-") Modename } ":" (String|Operation) +# +# Keynames are those defined in with the +# "Qt::Key_" removed. (We'd better insert the list here) +# +# Mode names are : +# +# - Shift +# - Alt +# - Control +# +# The VT100 emulation has two modes that can affect the +# sequences emitted by certain keys. These modes are +# under control of the client program. +# +# - Newline : effects Return and Enter key. +# - Application : effects Up and Down key. +# +# - Ansi : effects Up and Down key (This is for VT52, really). +# +# Operations are +# +# - scrollUpLine +# - scrollUpPage +# - scrollDownLine +# - scrollDownPage +# +# - emitSelection +# +# If the key is not found here, the text of the +# key event as provided by QT is emitted, possibly +# preceeded by ESC if the Alt key is pressed. +# +# -------------------------------------------------------------- + +key Escape : "\E" +key Tab : "\t" + +# VT100 can add an extra \n after return. +# The NewLine mode is set by an escape sequence. + +key Return-NewLine : "\r" +key Return+NewLine : "\r\n" + +# Some desperately try to save the ^H. + +key Backspace : "\x7f" +key Delete : "\E[3~" + +# These codes are for the VT52 mode of VT100 +# The Ansi mode (i.e. VT100 mode) is set by +# an escape sequence + +key Up -Shift-Ansi : "\EA" +key Down -Shift-Ansi : "\EB" +key Right-Shift-Ansi : "\EC" +key Left -Shift-Ansi : "\ED" + +# VT100 emits a mode bit together +# with the arrow keys.The AppCuKeys +# mode is set by an escape sequence. + +key Up -Shift+Ansi+AppCuKeys : "\EOA" +key Down -Shift+Ansi+AppCuKeys : "\EOB" +key Right-Shift+Ansi+AppCuKeys : "\EOC" +key Left -Shift+Ansi+AppCuKeys : "\EOD" + +key Up -Shift+Ansi-AppCuKeys : "\E[A" +key Down -Shift+Ansi-AppCuKeys : "\E[B" +key Right-Shift+Ansi-AppCuKeys : "\E[C" +key Left -Shift+Ansi-AppCuKeys : "\E[D" + +# linux functions keys F1-F5 differ from xterm + +key F1 : "\E[[A" +key F2 : "\E[[B" +key F3 : "\E[[C" +key F4 : "\E[[D" +key F5 : "\E[[E" + +key F6 : "\E[17~" +key F7 : "\E[18~" +key F8 : "\E[19~" +key F9 : "\E[20~" +key F10 : "\E[21~" +key F11 : "\E[23~" +key F12 : "\E[24~" + +key Home : "\E[1~" +key End : "\E[4~" + +key Prior -Shift : "\E[5~" +key Next -Shift : "\E[6~" +key Insert-Shift : "\E[2~" + +# Keypad-Enter. See comment on Return above. + +key Enter+NewLine : "\r\n" +key Enter-NewLine : "\r" + +key Space +Control : "\x00" + +# some of keys are used by konsole. + +key Up +Shift : scrollLineUp +key Prior +Shift : scrollPageUp +key Down +Shift : scrollLineDown +key Next +Shift : scrollPageDown + +key ScrollLock : scrollLock + +#---------------------------------------------------------- + +# keypad characters as offered by Qt +# cannot be recognized as such. + +#---------------------------------------------------------- + +# Following other strings as emitted by konsole. diff --git a/gui/kb-layouts/vt420pc.keytab b/gui/kb-layouts/vt420pc.keytab new file mode 100644 --- /dev/null +++ b/gui/kb-layouts/vt420pc.keytab @@ -0,0 +1,163 @@ +# [vt420pc.keytab] Konsole Keyboard Table (VT420pc keys) +# adapted by ferdinand gassauer f.gassauer@aon.at +# Nov 2000 +# +################################################################ +# +# The escape sequences emmited by the +# keys Shift+F1 to Shift+F12 might not fit your needs +# +################# IMPORTANT NOTICE ############################# +# the key bindings (Kcontrol -> look and feel -> keybindgs) +# overrule the settings in this file. The key bindings might be +# changed by the user WITHOUT notification of the maintainer of +# the keytab file. Konsole will not work as expected by +# the maintainer of the keytab file. +################################################################ +# +# -------------------------------------------------------------- + +keyboard "DEC VT420 Terminal" + +# -------------------------------------------------------------- +# +# This configuration table allows to customize the +# meaning of the keys. +# +# The syntax is that each entry has the form : +# +# "key" Keyname { ("+"|"-") Modename } ":" (String|Operation) +# +# Keynames are those defined in with the +# "Qt::Key_" removed. (We'd better insert the list here) +# +# Mode names are : +# +# - Shift +# - Alt +# - Control +# +# The VT100 emulation has two modes that can affect the +# sequences emitted by certain keys. These modes are +# under control of the client program. +# +# - Newline : effects Return and Enter key. +# - Application : effects Up and Down key. +# +# - Ansi : effects Up and Down key (This is for VT52, really). +# +# Operations are +# +# - scrollUpLine +# - scrollUpPage +# - scrollDownLine +# - scrollDownPage +# +# - emitSelection +# +# If the key is not found here, the text of the +# key event as provided by QT is emitted, possibly +# preceeded by ESC if the Alt key is pressed. +# +# -------------------------------------------------------------- + +key Escape : "\E" +key Tab : "\t" +key Backtab: "\E[Z" + +# VT100 can add an extra \n after return. +# The NewLine mode is set by an escape sequence. + +key Return-NewLine : "\r" +key Return+NewLine : "\r\n" + +# Some desperately try to save the ^H. +# may be not everyone wants this + +key Backspace : "\x08" # Control H +key Delete : "\x7f" + +# These codes are for the VT420pc +# The Ansi mode (i.e. VT100 mode) is set by +# an escape sequence + +key Up -Shift-Ansi : "\EA" +key Down -Shift-Ansi : "\EB" +key Right-Shift-Ansi : "\EC" +key Left -Shift-Ansi : "\ED" + +# VT100 emits a mode bit together +# with the arrow keys.The AppCuKeys +# mode is set by an escape sequence. + +key Up -Shift+Ansi+AppCuKeys : "\EOA" +key Down -Shift+Ansi+AppCuKeys : "\EOB" +key Right-Shift+Ansi+AppCuKeys : "\EOC" +key Left -Shift+Ansi+AppCuKeys : "\EOD" + +key Up -Shift+Ansi-AppCuKeys : "\E[A" +key Down -Shift+Ansi-AppCuKeys : "\E[B" +key Right-Shift+Ansi-AppCuKeys : "\E[C" +key Left -Shift+Ansi-AppCuKeys : "\E[D" + +# function keys + +key F1 -Shift : "\E[11~" +key F2 -Shift : "\E[12~" +key F3 -Shift : "\E[13~" +key F4 -Shift : "\E[14~" +key F5 -Shift : "\E[15~" +key F6 -Shift : "\E[17~" +key F7 -Shift : "\E[18~" +key F8 -Shift : "\E[19~" +key F9 -Shift : "\E[20~" +key F10-Shift : "\E[21~" +key F11-Shift : "\E[23~" +key F12-Shift : "\E[24~" +# +# Shift F1-F12 +# +key F1 +Shift : "\E[11;2~" +key F2 +Shift : "\E[12;2~" +key F3 +Shift : "\E[13;2~" +key F4 +Shift : "\E[14;2~" +key F5 +Shift : "\E[15;2~" +key F6 +Shift : "\E[17;2~" +key F7 +Shift : "\E[18;2~" +key F8 +Shift : "\E[19;2~" +key F9 +Shift : "\E[20;2~" +key F10+Shift : "\E[21;2~" +key F11+Shift : "\E[23;2~" +key F12+Shift : "\E[24;2~" + +key Home : "\E[H" +key End : "\E[F" + +key Prior -Shift : "\E[5~" +key Next -Shift : "\E[6~" +key Insert-Shift : "\E[2~" + +# Keypad-Enter. See comment on Return above. + +key Enter+NewLine : "\r\n" +key Enter-NewLine : "\r" + +key Space +Control : "\x00" + +# some of keys are used by konsole. + +key Up +Shift : scrollLineUp +key Prior +Shift : scrollPageUp +key Down +Shift : scrollLineDown +key Next +Shift : scrollPageDown + +key ScrollLock : scrollLock + +#---------------------------------------------------------- + +# keypad characters as offered by Qt +# cannot be recognized as such. + +#---------------------------------------------------------- + +# Following other strings as emitted by konsole. diff --git a/gui/languages/de-de.qm b/gui/languages/de-de.qm new file mode 100644 index 0000000000000000000000000000000000000000..a701c3df75595c1b14d890e84c3577aa8d342474 GIT binary patch literal 10151 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 R^zr)TNO51mA8KoA{tHnat`-0Q diff --git a/gui/languages/de-de.ts b/gui/languages/de-de.ts new file mode 100644 --- /dev/null +++ b/gui/languages/de-de.ts @@ -0,0 +1,642 @@ + + + + + FileEditorMdiSubWindow + + + + File Editor + Dateieditor + + + + Cannot read file %1: +%2. + Konnte Datei %1 nicht lesen: +%2. + + + + File loaded. + Datei geladen. + + + + Do you want to save the current file +%1 ? + Möchten Sie die Datei %1 sichern ? + + + + Cannot write file %1: +%2. + Konnte Datei %1 nicht schreiben: +%2. + + + + File %1 saved + Datei %1 gesichert + + + + &Close File + &Datei schließen + + + + &New File + &Neue Datei + + + + &Open File + &Öffne Datei + + + + &Save File + &Sichere Datei + + + + Save File &As + Sichere Datei &als + + + + &Undo + &Rückgängig + + + + &Redo + &Wiederholen + + + + &Copy + &Kopieren + + + + Cu&t + &Ausschneiden + + + + &Paste + &Einfügen + + + + &Next Bookmark + &Nächstes Bookmark + + + + Pre&vious Bookmark + &Voriges Bookmark + + + + Toggle &Bookmark + &Bookmark setzen + + + + &Run File + &Ausführen + + + + &File + &Datei + + + + &Edit + &Editieren + + + + &Run + &Ausführen + + + + FilesDockWidget + + Current Folder + Aktuelles Verzeichnis + + + + Current Directory + Aktuelles Verzeichnis + + + + Move up one directory. + Ein Verzeichnis höher wechseln. + + + + Enter the path or filename. + Geben Sie einen Pfad oder Dateinamen ein. + + + + Doubleclick a file to open it. + Führen Sie einen Doppelklick aus, um eine Datei zu öffnen. + + + + HistoryDockWidget + + + Doubleclick a command to transfer it to the terminal. + Führen Sie einen Doppelklick aus, um den Befehl in das Terminal zu übertragen. + + + + Enter text to filter the command history. + Geben Sie Text ein, um die Befehlshistorie zu filtern. + + + + Command History + Befehlshistorie + + + History updated. + Befehlshistorie aktualisiert. + + + + LexerOctaveGui + + + Default + Standard + + + + Comment + Kommentar + + + + Command + Befehl + + + + Number + Zahl + + + + Keyword + Schlüsselwort + + + + Single-quoted string + Zeichenkette in einfachen Hochkommata + + + + Operator + Operator + + + + Identifier + Bezeichner + + + + Double-quoted string + Zeichenkette in doppelten Hochkommata + + + + MainWindow + + + Opening file. + Öffne Datei. + + + + Save Workspace + Speichere Arbeitsumgebung + + + + Load Workspace + Lade Arbeitsumgebung + + + + + About Octave + Über Octave + + + + Saving data and shutting down. + Speichere Daten und schließe. + + + + View the variables in the active workspace. + Sehen Sie die Variablen ein, die sich in der aktiven Arbeitsumgebung befinden. + + + + Browse and search the command history. + Durchsuchen Sie die Befehlshistorie. + + + + Browse your files. + Durchsuchen Sie Ihre Dateien. + + + + Terminal + Terminal + + + + Enter your commands into the Octave terminal. + Geben Sie Ihre Befehle in das Octave Terminal ein. + + + + Browse the Octave documentation for help. + Durchsuchen Sie die Octave Dokumentation, um Hilfe zu erhalten. + + + + Chat + Chat + + + + Instantly chat with other Octave users for help. + Tauschen Sie sich direkt mit anderen Octave Benutzern aus, um Hilfe zu erhalten. + + + + Octave + Octave + + + + Settings + Einstellungen + + + + Exit + Beenden + + + + Interface + Oberfläche + + + + Align Windows + Fenster ausrichten + + + + + Workspace + Arbeitsumgebung + + + + History + Befehlshistorie + + + + File Browser + Dateibrowser + + + + Open New Editor Window + Neues Editorfenster öffnen + + + + Load + Laden + + + + Save + Sichern + + + + Clear + Löschen + + + + Community + Gemeinschaft + + + + Report Bug + Fehler melden + + + + Agora + Agora + + + + Octave Forge + Octave Forge + + + + About Qt + Über Qt + + + Octave Toolbar + Octave Werkzeugleiste + + + Command Window + Konsolenfenster + + + File Editor + Dateieditor + + + + Documentation + Dokumentation + + + Service + Service + + + Established link to Octave. + Verbindung zu Octave hergestellt. + + + + NumberBar + + Stop Here + Stoppe hier + + + Current Line + Aktuelle Zeile + + + Error Line + Fehlerzeile + + + + NumberedCodeEdit + + This file name is not valid. + Dieser Dateiname ist nicht gültig. + + + Octave doesn't understand this file name: + + Octave versteht diesen Dateityp nicht: + + + +Please, change it. + Do you want to save your changes? + Bitte ändern Sie dies. Möchten Sie Ihre Änderungen sichern? + + + + SettingsDialog + + + Settings + Einstellungen + + + + Chat + Char + + + + Connect to #octave on startup + Beim Start mit #octave verbinden + + + + Show message of the day + Nachricht des Tages anzeigen (MOTD) + + + + Show topic + Thema des Chatkanals anzeigen + + + + Automatically identify on NickServ + Automatisch bei NickServ identifizieren + + + + Warning: Your password will be stored in ~/.octavegui in human-readable format. Do not enter your password if you worry about security issues. + Warnung: Ihre Passwort wird unter ~/.octave-gui in einem menschenlesbaren Format gesichert. Hinterlegen Sie nicht Ihr Password, wenn Sie Bedenken über die Sicherheit haben. + + + + + Password: + Passwort: + + + + Editor + Editor + + + + Use custom file editor: + Benutzerdefinierten Editor verwenden: + + + + emacs + emacs + + + + File Browser + Dateibrowser + + + + Show filenames + Dateinamen anzeigen + + + + Show file size + Dateigröße anzeigen + + + + Show file type + Dateityp anzeigen + + + + Show date of last modification + Datum der letzten Änderung anzeigen + + + + Show hidden files + Versteckte Dateien anzeigen + + + + Alternating row colors + Alternierende Farben verwenden + + + + Network + + + + + Use proxy server + + + + + Proxy Type: + + + + + HttpProxy + + + + + Socks5Proxy + + + + + Hostname: + + + + + Port: + + + + + Username: + + + + + Reset to defaults + Standardeinstellungen wiederherstellen + + + + Export + Exportieren + + + + Import + Importieren + + + + VariablesDockWidget + + + Name + Bezeichner + + + + Type + Typ + + + + Value + Wert + + + + Workspace + Arbeitsumgebung + + + Save + Sichern + + + Load + Laden + + + Clear + Löschen + + + + Local + Lokal + + + + Global + Global + + + + Persistent + Persistent + + + + Hidden + Versteckt + + + diff --git a/gui/languages/es-es.qm b/gui/languages/es-es.qm new file mode 100644 index 0000000000000000000000000000000000000000..7fbf74ee61166c382a369dbfe80f7d2796451295 GIT binary patch literal 9411 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 + + + + FileEditorMdiSubWindow + + + + File Editor + Editor de archivos + + + + Cannot read file %1: +%2. + No se puede leer archivo %1: +%2. + + + + File loaded. + Archivo cargado. + + + + Do you want to save the current file +%1 ? + ¿Desea guardar archivo actual +%1 ? + + + + Cannot write file %1: +%2. + No se puede escribir archivo %1: +%2. + + + + File %1 saved + Archivo %1 guardado + + + + &Close File + &Cerrar archivo + + + + &New File + Archivo &nuevo + + + + &Open File + &Abrir archivo + + + + &Save File + &Guardar archivo + + + + Save File &As + Search for proper shortcut for this command + Guardar archivo &como + + + + &Undo + &Deshacer + + + + &Redo + &Rehacer + + + + &Copy + &Copiar + + + + Cu&t + Cor&tar + + + + &Paste + &Pegar + + + + &Next Bookmark + + + + + Pre&vious Bookmark + + + + + Toggle &Bookmark + + + + + &Run File + &Ejecutar archivo + + + + &File + &Archivo + + + + &Edit + &Editar + + + + &Run + &Ejecutar + + + + FilesDockWidget + + Current Folder + Carpeta actual + + + + Current Directory + + + + + Move up one directory. + Subir un directorio. + + + + Enter the path or filename. + Introduzca dirección o nombre de archivo. + + + + Doubleclick a file to open it. + Haga doble clic para abir archivo. + + + + HistoryDockWidget + + + Doubleclick a command to transfer it to the terminal. + Haga doble clic para transferir el comando a la terminal. + + + + Enter text to filter the command history. + Introduzca texto para filtrar el historial de comandos. + + + + Command History + Historial de comandos + + + + LexerOctaveGui + + + Default + Valores predeterminados + + + + Comment + Comentario + + + + Command + Comando + + + + Number + Número + + + + Keyword + Contraseña + + + + Single-quoted string + Cadena entre comillas simples + + + + Operator + Operador + + + + Identifier + Identificador + + + + Double-quoted string + Cadena entre comillas dobles + + + + MainWindow + + + Opening file. + Abriendo archivo. + + + + Save Workspace + Guardar espacio de trabajo + + + + Load Workspace + Cargar espacio de trabajo + + + + + About Octave + Acerca de Octave + + + + Saving data and shutting down. + Guardando datos y cerrando el sistema. + + + + View the variables in the active workspace. + Ver variables en el espacio de trabajo activo. + + + + Browse and search the command history. + Navegar y buscar en el historial de comandos. + + + + Browse your files. + Explorar sus archivos. + + + + Terminal + Terminal + + + + Enter your commands into the Octave terminal. + Introducir su comando a la terminal de Octave. + + + + Documentation + Documentación + + + + Browse the Octave documentation for help. + Consultar la documentación de Octave para obtener ayuda. + + + + Chat + Chat/conversación instantanea + + + + Instantly chat with other Octave users for help. + Coversación instantanea con otros usuarios de octave para obtener ayuda. + + + + Octave + Octave + + + + Settings + Configuración + + + + Exit + Salir + + + + Interface + Interfase + + + + Align Windows + Alinear ventanas + + + + + Workspace + Espacio de trabajo + + + + History + Historial + + + + File Browser + Explorador de archivos + + + + Open New Editor Window + Abrir nueva ventana de editor + + + + Load + Cargar + + + + Save + Guardar + + + + Clear + Limpiar + + + + Community + Comunidad + + + + Report Bug + Reportar error de software/Bug + + + + Agora + Ágora + + + + Octave Forge + Octave Forge + + + + About Qt + Acerca de Qt + + + + SettingsDialog + + + Settings + Configuración + + + + Chat + Chat/conversación instantanea + + + + Connect to #octave on startup + Conectar a #octave en el arranque + + + + Show message of the day + Mostrar mensaje del día + + + + Show topic + Mostrar tema + + + + Automatically identify on NickServ + Identificar automáticamente el NickServ + + + + Warning: Your password will be stored in ~/.octavegui in human-readable format. Do not enter your password if you worry about security issues. + Advertencia: La contraseña se guarda en ~ / octavegui en formato legible. No introduzca su contraseña en caso de que le preocupen los aspectos de seguridad. + + + + + + Password: + Contraseña: + + + + Editor + Editor + + + + Use custom file editor: + Usar editor de archivos personalizados: + + + + emacs + emacs + + + + File Browser + Explorador de archivos + + + + Show filenames + Mostrar nombres de archivos + + + + Show file size + Mostrar tamaño de archivo + + + + Show file type + Mostrar tipo de archivo + + + + Show date of last modification + Mostrar fecha de la última modificación + + + + Show hidden files + Mostrar archivos ocultos + + + + Alternating row colors + Colores alternos de filas + + + + Network + + + + + Use proxy server + + + + + Proxy Type: + + + + + HttpProxy + + + + + Socks5Proxy + + + + + Hostname: + + + + + Port: + + + + + Username: + + + + + Reset to defaults + Restaurar los valores predeterminados + + + + Export + Exportar + + + + Import + Importar + + + + VariablesDockWidget + + + Workspace + Espacio de trabajo + + + + Name + Nombre + + + + Type + Tipo + + + + Value + Valor + + + + Local + Local + + + + Global + Global + + + + Persistent + Persistente + + + + Hidden + Oculto + + + diff --git a/gui/languages/generic.qm b/gui/languages/generic.qm new file mode 100644 --- /dev/null +++ b/gui/languages/generic.qm @@ -0,0 +1,1 @@ + + + + + FileEditorMdiSubWindow + + + + File Editor + + + + + Cannot read file %1: +%2. + + + + + File loaded. + + + + + Do you want to save the current file +%1 ? + + + + + Cannot write file %1: +%2. + + + + + File %1 saved + + + + + &Close File + + + + + &New File + + + + + &Open File + + + + + &Save File + + + + + Save File &As + + + + + &Undo + + + + + &Redo + + + + + &Copy + + + + + Cu&t + + + + + &Paste + + + + + &Next Bookmark + + + + + Pre&vious Bookmark + + + + + Toggle &Bookmark + + + + + &Run File + + + + + &File + + + + + &Edit + + + + + &Run + + + + + FilesDockWidget + + + Current Directory + + + + + Move up one directory. + + + + + Enter the path or filename. + + + + + Doubleclick a file to open it. + + + + + HistoryDockWidget + + + Doubleclick a command to transfer it to the terminal. + + + + + Enter text to filter the command history. + + + + + Command History + + + + + LexerOctaveGui + + + Default + + + + + Comment + + + + + Command + + + + + Number + + + + + Keyword + + + + + Single-quoted string + + + + + Operator + + + + + Identifier + + + + + Double-quoted string + + + + + MainWindow + + + Opening file. + + + + + Save Workspace + + + + + Load Workspace + + + + + + About Octave + + + + + Saving data and shutting down. + + + + + View the variables in the active workspace. + + + + + Browse and search the command history. + + + + + Browse your files. + + + + + Terminal + + + + + Enter your commands into the Octave terminal. + + + + + Documentation + + + + + Browse the Octave documentation for help. + + + + + Chat + + + + + Instantly chat with other Octave users for help. + + + + + Octave + + + + + Settings + + + + + Exit + + + + + Interface + + + + + Align Windows + + + + + + Workspace + + + + + History + + + + + File Browser + + + + + Open New Editor Window + + + + + Load + + + + + Save + + + + + Clear + + + + + Community + + + + + Report Bug + + + + + Agora + + + + + Octave Forge + + + + + About Qt + + + + + SettingsDialog + + + Settings + + + + + Chat + + + + + Connect to #octave on startup + + + + + Show message of the day + + + + + Show topic + + + + + Automatically identify on NickServ + + + + + Warning: Your password will be stored in ~/.octavegui in human-readable format. Do not enter your password if you worry about security issues. + + + + + + Password: + + + + + Editor + + + + + Use custom file editor: + + + + + emacs + + + + + File Browser + + + + + Show filenames + + + + + Show file size + + + + + Show file type + + + + + Show date of last modification + + + + + Show hidden files + + + + + Alternating row colors + + + + + Network + + + + + Use proxy server + + + + + Proxy Type: + + + + + HttpProxy + + + + + Socks5Proxy + + + + + Hostname: + + + + + Port: + + + + + Username: + + + + + Reset to defaults + + + + + Export + + + + + Import + + + + + VariablesDockWidget + + + Workspace + + + + + Name + + + + + Type + + + + + Value + + + + + Local + + + + + Global + + + + + Persistent + + + + + Hidden + + + + diff --git a/gui/languages/pt-br.qm b/gui/languages/pt-br.qm new file mode 100644 index 0000000000000000000000000000000000000000..83d512baa96d8ad07afa2ef66532922ed0ddcb01 GIT binary patch literal 8860 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 diff --git a/gui/languages/pt-br.ts b/gui/languages/pt-br.ts new file mode 100644 --- /dev/null +++ b/gui/languages/pt-br.ts @@ -0,0 +1,571 @@ + + + + + FileEditorMdiSubWindow + + + + File Editor + Editor de Arquivos + + + + Cannot read file %1: +%2. + Não foi possível ler o arquivo %1: %2. + + + + File loaded. + Arquivo carregado. + + + + Do you want to save the current file +%1 ? + Você deseja salvar o arquivo atual %1 ? + + + + Cannot write file %1: +%2. + Não foi possível escrever no arquivo %1: %2. + + + + File %1 saved + Arquivo %1 salvo + + + + &Close File + &Fechar Arquivo + + + + &New File + &Novo Arquivo + + + + &Open File + &Abrir Arquivo + + + + &Save File + &Salvar Arquivo + + + + Save File &As + Salvar Arquivo &Como + + + + &Undo + &Desfazer + + + + &Redo + &Refazer + + + + &Copy + + + + + Cu&t + + + + + &Paste + + + + + &Next Bookmark + + + + + Pre&vious Bookmark + + + + + Toggle &Bookmark + + + + + &Run File + + + + + &File + + + + + &Edit + + + + + &Run + + + + + FilesDockWidget + + Current Folder + Diretório Atual + + + + Current Directory + + + + + Move up one directory. + Subir um diretório. + + + + Enter the path or filename. + Digite o caminho ou o nome do arquivo. + + + + Doubleclick a file to open it. + Clique duas vezes num arquivo para abrí-lo. + + + + HistoryDockWidget + + + Doubleclick a command to transfer it to the terminal. + Clique duas vezes num comando para transferí-lo ao terminal. + + + + Enter text to filter the command history. + Digite um texto para filtrar o hitórico de comandos. + + + + Command History + Histórico de Comandos + + + + LexerOctaveGui + + + Default + Padrão + + + + Comment + Comentário + + + + Command + Comando + + + + Number + Número + + + + Keyword + Palavra-Chave + + + + Single-quoted string + String com aspas simples + + + + Operator + Operador + + + + Identifier + Identificador + + + + Double-quoted string + String com aspas duplas + + + + MainWindow + + + Opening file. + Abrindo arquivo. + + + + Save Workspace + Salvar ambiente de trabalho + + + + Load Workspace + Carregar ambiente de trabalho + + + + + About Octave + Sobre o Octave + + + + Saving data and shutting down. + Salvando dados e encerrando a sessão. + + + + View the variables in the active workspace. + Visualizar variáveis no ambiente de trabalho. + + + + Browse and search the command history. + Pesquise no histórico de comandos. + + + + Browse your files. + Procure seus arquivos. + + + + Terminal + Terminal + + + + Enter your commands into the Octave terminal. + Digite seus comandos no terminal do Octave. + + + + Documentation + Documentação + + + + Browse the Octave documentation for help. + Procure na documentação do Octave. + + + + Chat + Chat + + + + Instantly chat with other Octave users for help. + Converse instantaneamente com outros usuários do Octave para pedir ajuda. + + + + Octave + Octave + + + + Settings + Configurações + + + + Exit + Sair + + + + Interface + Interface + + + + Align Windows + Alinhar Janelas + + + + + Workspace + Ambiente de trabalho + + + + History + Histórico + + + + File Browser + Navegador de Arquivos + + + + Open New Editor Window + Abrir nova janela de edição + + + + Load + Carregar + + + + Save + Salvar + + + + Clear + Limpar + + + + Community + Comunidade + + + + Report Bug + Reportar Bug + + + + Agora + Agora + + + + Octave Forge + Octave Forge + + + + About Qt + Sobre o Qt + + + + SettingsDialog + + + Settings + Configurações + + + + Chat + Chat + + + + Connect to #octave on startup + Conectar ao #octave ao iniciar + + + + Show message of the day + Mostrar mensagem do dia + + + + Show topic + Mostrar tópico + + + + Automatically identify on NickServ + Identificar-se automaticamente com o NickServ + + + + Warning: Your password will be stored in ~/.octavegui in human-readable format. Do not enter your password if you worry about security issues. + Aviso: Sua senha será salva em ~/.octavegui em um formato legível. Não digite sua senha se você tem problemas com segurança. + + + + + Password: + Senha: + + + + Editor + Editor + + + + Use custom file editor: + Usar editor de arquivos personalizado: + + + + emacs + emacs + + + + File Browser + Navegador de Arquivos + + + + Show filenames + Mostrar nomes de arquivo + + + + Show file size + Mostrar tamanho do arquivo + + + + Show file type + Mostrar tipo do arquivo + + + + Show date of last modification + Mostrar data de última modificação + + + + Show hidden files + Mostrar arquivos ocultos + + + + Alternating row colors + Alternar cores das linhas + + + + Network + + + + + Use proxy server + + + + + Proxy Type: + + + + + HttpProxy + + + + + Socks5Proxy + + + + + Hostname: + + + + + Port: + + + + + Username: + + + + + Reset to defaults + Resetar ao padrão + + + + Export + Exportar + + + + Import + Importar + + + + VariablesDockWidget + + + Workspace + Ambiente de trabalho + + + + Name + Nome + + + + Type + Tipo + + + + Value + Valor + + + + Local + Local + + + + Global + Global + + + + Persistent + Persistente + + + + Hidden + Oculto + + + diff --git a/gui/languages/ru-ru.qm b/gui/languages/ru-ru.qm new file mode 100644 index 0000000000000000000000000000000000000000..de3a769e3f6ba4f834ed1e7a6066bb9c0e6beeee GIT binary patch literal 9784 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 diff --git a/gui/languages/ru-ru.ts b/gui/languages/ru-ru.ts new file mode 100644 --- /dev/null +++ b/gui/languages/ru-ru.ts @@ -0,0 +1,574 @@ + + + + + FileEditorMdiSubWindow + + + + File Editor + Редактор файлов + + + + Cannot read file %1: +%2. + Не удалось прочитать файл %1: +%2. + + + + File loaded. + Файл загружен. + + + + Do you want to save the current file +%1 ? + Сохранить текущий файл +%1? + + + + Cannot write file %1: +%2. + Не удалось сохранить файл %1: +%2. + + + + File %1 saved + Файл %1 сохранён + + + + &Close File + &Закрыть + + + + &New File + Созд&ать + + + + &Open File + &Открыть + + + + &Save File + &Сохранить + + + + Save File &As + Сохранить &как + + + + &Undo + О&тменить + + + + &Redo + &Повторить + + + + &Copy + &Копировать + + + + Cu&t + Вы&резать + + + + &Paste + &Вставить + + + + &Next Bookmark + С&ледующая закладка + + + + Pre&vious Bookmark + Пр&едыдущая закладка + + + + Toggle &Bookmark + &Установить/снять закладку + + + + &Run File + &Запустить файл + + + + &File + &Файл + + + + &Edit + &Правка + + + + &Run + &Запуск + + + + FilesDockWidget + + Current Folder + Текущий каталог + + + + Current Directory + Текущий каталог + + + + Move up one directory. + Перейти на уровень выше. + + + + Enter the path or filename. + Введите путь или имя файла. + + + + Doubleclick a file to open it. + Двойной щелчок по файлу откроет его. + + + + HistoryDockWidget + + + Doubleclick a command to transfer it to the terminal. + Двойной щелчок по команде перенесёт её в командную строку. + + + + Enter text to filter the command history. + Введите текст для фильтрации выполненных команд. + + + + Command History + Журнал выполненных команд + + + + LexerOctaveGui + + + Default + По умолчанию + + + + Comment + Комментарий + + + + Command + Команда + + + + Number + Число + + + + Keyword + Зарезервированное слово + + + + Single-quoted string + Строка в одинарных кавычках + + + + Operator + Оператор + + + + Identifier + Идентификатор + + + + Double-quoted string + Строка в двойных кавычках + + + + MainWindow + + + Opening file. + Открывается файл. + + + + Save Workspace + Сохранить область переменных + + + + Load Workspace + Загрузить область переменных + + + + + About Octave + Об Octave + + + + Saving data and shutting down. + Сохранить и завершить работу. + + + + View the variables in the active workspace. + Просмотр содержимого текущей области переменных. + + + + Browse and search the command history. + Просмотр и поиск в журнале выполненных команд. + + + + Browse your files. + Просмотр файлов. + + + + Terminal + Командная строка + + + + Enter your commands into the Octave terminal. + Введите команды в командной строке Octave. + + + + Documentation + Документация + + + + Browse the Octave documentation for help. + Открыть документацию по Octave. + + + + Chat + Чат + + + + Instantly chat with other Octave users for help. + Чат с пользователями Octave. + + + + Octave + Octave + + + + Settings + Параметры + + + + Exit + Выход + + + + Interface + Интерфейс + + + + Align Windows + Выровнять окна + + + + + Workspace + Область переменных + + + + History + Журнал выполненных команд + + + + File Browser + Файловый менеджер + + + + Open New Editor Window + Открыть новое окно редактора + + + + Load + Загрузить + + + + Save + Сохранить + + + + Clear + Очистить + + + + Community + Сообщество + + + + Report Bug + Сообщить об ошибке + + + + Agora + Agora + + + + Octave Forge + Octave Forge + + + + About Qt + О Qt + + + + SettingsDialog + + + Settings + Параметры + + + + Chat + Чат + + + + Connect to #octave on startup + Подключиться к #octave при запуске + + + + Show message of the day + Показывать совет дня + + + + Show topic + Показывать тему обсуждения при подключении + + + + Automatically identify on NickServ + Автоматически идентифицироваться у NickServ + + + + Warning: Your password will be stored in ~/.octavegui in human-readable format. Do not enter your password if you worry about security issues. + Предупреждение: пароль будет сохранён в ~/.octavegui обычным текстом. Не вводите пароль, если переживаете о возможных уязвимостях в безопасности приложения. + + + + + Password: + Пароль: + + + + Editor + Редактор + + + + Use custom file editor: + Выбрать редактор: + + + + emacs + emacs + + + + File Browser + Файловый менеджер + + + + Show filenames + Показывать имена файлов + + + + Show file size + Показывать размер файлов + + + + Show file type + Показывать типы файлов + + + + Show date of last modification + Показывать дату последнего изменения + + + + Show hidden files + Показывать скрытые файлы + + + + Alternating row colors + Чередующиеся цвета строк + + + + Network + + + + + Use proxy server + + + + + Proxy Type: + + + + + HttpProxy + + + + + Socks5Proxy + + + + + Hostname: + + + + + Port: + + + + + Username: + + + + + Reset to defaults + Установить параметры по умолчанию + + + + Export + Экспортировать + + + + Import + Импортировать + + + + VariablesDockWidget + + + Workspace + Область переменных + + + + Name + Идентификатор + + + + Type + Тип + + + + Value + Значение + + + + Local + Локальная + + + + Global + Глобальная + + + + Persistent + Статическая + + + + Hidden + Скрытая + + + diff --git a/gui/languages/uk-ua.qm b/gui/languages/uk-ua.qm new file mode 100644 index 0000000000000000000000000000000000000000..106e473c4ee5a25399cf11bc5c2f5f0a50834565 GIT binary patch literal 9884 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 diff --git a/gui/languages/uk-ua.ts b/gui/languages/uk-ua.ts new file mode 100644 --- /dev/null +++ b/gui/languages/uk-ua.ts @@ -0,0 +1,574 @@ + + + + + FileEditorMdiSubWindow + + + + File Editor + Редактор файлів + + + + Cannot read file %1: +%2. + Не вдалося прочитати файл %1: +%2. + + + + File loaded. + Файл завантажено. + + + + Do you want to save the current file +%1 ? + Справді зберегти поточний файл +%1? + + + + Cannot write file %1: +%2. + Не вдалося зберегти файл %1: +%2. + + + + File %1 saved + Файл %1 збережено + + + + &Close File + За&крити + + + + &New File + &Створити + + + + &Open File + &Відкрити + + + + &Save File + &Зберегти + + + + Save File &As + Зберегти &як + + + + &Undo + В&ернути + + + + &Redo + П&овторити + + + + &Copy + &Копіювати + + + + Cu&t + Виріза&ти + + + + &Paste + &Вставити + + + + &Next Bookmark + До &наступної закладки + + + + Pre&vious Bookmark + До &попередньої закладки + + + + Toggle &Bookmark + В&становити/видалити закладку + + + + &Run File + &Виконати файл + + + + &File + &Файл + + + + &Edit + &Правка + + + + &Run + &Виконання + + + + FilesDockWidget + + Current Folder + Поточний каталог + + + + Current Directory + Поточний каталог + + + + Move up one directory. + Перейти вгору деревом каталогів. + + + + Enter the path or filename. + Введіть повний шлях до файлу або назву файлу. + + + + Doubleclick a file to open it. + Подвійне клацання відкриє файл. + + + + HistoryDockWidget + + + Doubleclick a command to transfer it to the terminal. + Подвійне клацання перенесе команду до командного рядку. + + + + Enter text to filter the command history. + Введіть текст для фільтрування історії виконаних команд. + + + + Command History + Історія виконаних команд + + + + LexerOctaveGui + + + Default + Стандартні налаштування + + + + Comment + Коментар + + + + Command + Команда + + + + Number + Число + + + + Keyword + Зарезервоване слово + + + + Single-quoted string + Рядок в одинарних лапках + + + + Operator + Оператор + + + + Identifier + Ідентифікатор + + + + Double-quoted string + Рядок у подвійних лапках + + + + MainWindow + + + Opening file. + Відкривається файл. + + + + Save Workspace + Зберегти область змінних + + + + Load Workspace + Завантажити область змінних + + + + + About Octave + Про Octave + + + + Saving data and shutting down. + Зберегти дані і завершити роботу. + + + + View the variables in the active workspace. + Перегляд змісту поточної області змінних. + + + + Browse and search the command history. + Перегляд і пошук серед історії виконаних команд. + + + + Browse your files. + Переглянути файли. + + + + Terminal + Командний рядок + + + + Enter your commands into the Octave terminal. + Введіть команди до командного рядка Octave. + + + + Documentation + Документація + + + + Browse the Octave documentation for help. + Переглянути документацію до Octave. + + + + Chat + Чат + + + + Instantly chat with other Octave users for help. + Чат з користувачами Octave. + + + + Octave + Octave + + + + Settings + Налаштування + + + + Exit + Вийти + + + + Interface + Інтерфейс + + + + Align Windows + Вирівняти вікна + + + + + Workspace + Область змінних + + + + History + Історія виконаних команд + + + + File Browser + Файловий менеджер + + + + Open New Editor Window + Відкрити нове вікно редактора + + + + Load + Завантажити + + + + Save + Зберегти + + + + Clear + Очистити + + + + Community + Спільнота + + + + Report Bug + Повідомити про помилку + + + + Agora + Agora + + + + Octave Forge + Octave Forge + + + + About Qt + Про Qt + + + + SettingsDialog + + + Settings + Налаштування + + + + Chat + Чат + + + + Connect to #octave on startup + З'єднатися з #octave при запуску + + + + Show message of the day + Показувати пораду дня + + + + Show topic + Показувати тему чату при з'єднанні + + + + Automatically identify on NickServ + Автоматично ідентифікуватися в NickServ + + + + Warning: Your password will be stored in ~/.octavegui in human-readable format. Do not enter your password if you worry about security issues. + Попередження: пароль буде збережено в ~/.octavegui звичайним текстом. Не вводьте пароль, якщо переймаєтесь потенційними проблемами із захистом даних в програмі. + + + + + Password: + Пароль: + + + + Editor + Редактор + + + + Use custom file editor: + Використовувати інший редактор: + + + + emacs + emacs + + + + File Browser + Файловий менеджер + + + + Show filenames + Показувати назви файлів + + + + Show file size + Показувати розмір файлів + + + + Show file type + Показувати типи файлів + + + + Show date of last modification + Показувати дату останньої зміни + + + + Show hidden files + Показувати приховані файли + + + + Alternating row colors + Чергувати колір рядків + + + + Network + + + + + Use proxy server + + + + + Proxy Type: + + + + + HttpProxy + + + + + Socks5Proxy + + + + + Hostname: + + + + + Port: + + + + + Username: + + + + + Reset to defaults + Встановити стандартні налаштування + + + + Export + Експортувати + + + + Import + Імпортувати + + + + VariablesDockWidget + + + Workspace + Область змінних + + + + Name + Ідентифікатор + + + + Type + Тип + + + + Value + Значення + + + + Local + Локальна + + + + Global + Глобальна + + + + Persistent + Статична + + + + Hidden + Прихована + + + diff --git a/gui/media/chat.png b/gui/media/chat.png new file mode 100644 index 0000000000000000000000000000000000000000..40b19cb63b244d6e71de31875904fb934d0498a2 GIT binary patch literal 15258 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 A4FCWD diff --git a/gui/media/help_index.png b/gui/media/help_index.png new file mode 100644 index 0000000000000000000000000000000000000000..cf0fd38174d6901460943a4c7e66039eb95afaae GIT binary patch literal 22733 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 Y1F4`rfN3>^-~a#s07*qoM6N<$f@plx0{{R3 diff --git a/gui/media/icons_license b/gui/media/icons_license new file mode 100644 --- /dev/null +++ b/gui/media/icons_license @@ -0,0 +1,323 @@ +Icons license for: chat.png help_index.png terminal.png +jabber_protocol.png + +by http://www.everaldo.com/ on 17.07.2011: + +The Crystal Project are released under LGPL. GNU General Public License. + +This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other +authorized party saying it may be distributed under the terms of this +Lesser General Public License (also called "this License"). Each +licensee is addressed as "you". + +A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which +has been distributed under these terms. A "work based on the Library" +means either the Library or any derivative work under copyright law: +that is to say, a work containing the Library or a portion of it, either +verbatim or with modifications and/or translated straightforwardly into +another language. (Hereinafter, translation is included without +limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making +modifications to it. For a library, complete source code means all the +source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and +installation of the library. + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of running +a program using the Library is not restricted, and output from such a +program is covered only if its contents constitute a work based on the +Library (independent of the use of the Library in a tool for writing +it). Whether that is true depends on what the Library does and what the +program that uses the Library does. + +You may copy and distribute verbatim copies of the Library's complete +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the notices +that refer to this License and to the absence of any warranty; and +distribute a copy of this License along with the Library. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such +modifications or work under the terms of Section 1 above, provided that +you also meet all of these conditions: + +The modified work must itself be a software library. You must cause the +files modified to carry prominent notices stating that you changed the +files and the date of any change. You must cause the whole of the work +to be licensed at no charge to all third parties under the terms of this +License. If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses the +facility, other than as an argument passed when the facility is invoked, +then you must make a good faith effort to ensure that, in the event an +application does not supply such function or table, the facility still +operates, and performs whatever part of its purpose remains meaningful. +(For example, a function in a library to compute square roots has a +purpose that is entirely well-defined independent of the application. +Therefore, Subsection 2d requires that any application-supplied function +or table used by this function must be optional: if the application does +not supply it, the square root function must still compute square +roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, and +can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based on +the Library, the distribution of the whole must be on the terms of this +License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of a +storage or distribution medium does not bring the other work under the +scope of this License. + +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so that +they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in these +notices. + +Once this change is made in a given copy, it is irreversible for that +copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the +Library into a program that is not a library. + +You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms +of Sections 1 and 2 above provided that you accompany it with the +complete corresponding machine-readable source code, which must be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a +designated place, then offering equivalent access to copy the source +code from the same place satisfies the requirement to distribute the +source code, even though third parties are not compelled to copy the +source along with the object code. + +A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with +it, is called a "work that uses the Library". Such a work, in isolation, +is not a derivative work of the Library, and therefore falls outside the +scope of this License. + +However, linking a "work that uses the Library" with the Library creates +an executable that is a derivative of the Library (because it contains +portions of the Library), rather than a "work that uses the library". +The executable is therefore covered by this License. Section 6 states +terms for distribution of such executables. When a "work that uses the +Library" uses material from a header file that is part of the Library, +the object code for the work may be a derivative work of the Library +even though the source code is not. Whether this is true is especially +significant if the work can be linked without the Library, or if the +work is itself a library. The threshold for this to be true is not +precisely defined by law. + +If such an object file uses only numerical parameters, data structure +layouts and accessors, and small macros and small inline functions (ten +lines or less in length), then the use of the object file is +unrestricted, regardless of whether it is legally a derivative work. +(Executables containing this object code plus portions of the Library +will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, whether +or not they are linked directly with the Library itself. + +As an exception to the Sections above, you may also combine or link a +"work that uses the Library" with the Library to produce a work +containing portions of the Library, and distribute that work under terms +of your choice, provided that the terms permit modification of the work +for the customer's own use and reverse engineering for debugging such +modifications. + +You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work during +execution displays copyright notices, you must include the copyright +notice for the Library among them, as well as a reference directing the +user to the copy of this License. Also, you must do one of these things: + +Accompany the work with the complete corresponding machine-readable +source code for the Library including whatever changes were used in the +work (which must be distributed under Sections 1 and 2 above); and, if +the work is an executable linked with the Library, with the complete +machine-readable "work that uses the Library", as object code and/or +source code, so that the user can modify the Library and then relink to +produce a modified executable containing the modified Library. (It is +understood that the user who changes the contents of definitions files +in the Library will not necessarily be able to recompile the application +to use the modified definitions.) . Use a suitable shared library +mechanism for linking with the Library. A suitable mechanism is one that +(1) uses at run time a copy of the library already present on the user's +computer system, rather than copying library functions into the +executable, and (2) will operate properly with a modified version of the +library, if the user installs one, as long as the modified version is +interface-compatible with the version that the work was made with. +Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, +for a charge no more than the cost of performing this distribution. If +distribution of the work is made by offering access to copy from a +designated place, offer equivalent access to copy the above specified +materials from the same place. Verify that the user has already received +a copy of these materials or that you have already sent this user a +copy. For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, the +materials to be distributed need not include anything that is normally +distributed (in either source or binary form) with the major components +(compiler, kernel, and so on) of the operating system on which the +executable runs, unless that component itself accompanies the +executable. + +It may happen that this requirement contradicts the license restrictions +of other proprietary libraries that do not normally accompany the +operating system. Such a contradiction means you cannot use both them +and the Library together in an executable that you distribute. + +You may place library facilities that are a work based on the Library +side-by-side in a single library together with other library facilities +not covered by this License, and distribute such a combined library, +provided that the separate distribution of the work based on the Library +and of the other library facilities is otherwise permitted, and provided +that you do these two things: + +Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be +distributed under the terms of the Sections above. + +Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the +accompanying uncombined form of the same work. + +You may not copy, modify, sublicense, link with, or distribute the +Library except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, link with, or distribute the +Library is void, and will automatically terminate your rights under this +License. However, parties who have received copies, or rights, from you +under this License will not have their licenses terminated so long as +such parties remain in full compliance. + +You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute +the Library or its derivative works. These actions are prohibited by law +if you do not accept this License. Therefore, by modifying or +distributing the Library (or any work based on the Library), you +indicate your acceptance of this License to do so, and all its terms and +conditions for copying, distributing or modifying the Library or works +based on it. + +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot distribute +so as to satisfy simultaneously your obligations under this License and +any other pertinent obligations, then as a consequence you may not +distribute the Library at all. For example, if a patent license would +not permit royalty-free redistribution of the Library by all those who +receive copies directly or indirectly through you, then the only way you +could satisfy both it and this License would be to refrain entirely from +distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is implemented +by public license practices. Many people have made generous +contributions to the wide range of software distributed through that +system in reliance on consistent application of that system; it is up to +the author/donor to decide if he or she is willing to distribute +software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be +a consequence of the rest of this License. + +If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Library under this License may add an +explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +The Free Software Foundation may publish revised and/or new versions of +the Lesser General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a license +version number, you may choose any version ever published by the Free +Software Foundation. + +If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally. + +No Warranty + +Because the library is licensed free of charge, there is no warranty for +the library, to the extent permitted by applicable law. Except when +otherwise stated in writing the copyright holders and/or other parties +provide the library "as is" without warranty of any kind, either +expressed or implied, including, but not limited to, the implied +warranties of merchantability and fitness for a particular purpose. The +entire risk as to the quality and performance of the library is with +you. Should the library prove defective, you assume the cost of all +necessary servicing, repair or correction. + +In no event unless required by applicable law or agreed to in writing +will any copyright holder, or any other party who may modify and/or +redistribute the library as permitted above, be liable to you for +damages, including any general, special, incidental or consequential +damages arising out of the use or inability to use the library +(including but not limited to loss of data or data being rendered +inaccurate or losses sustained by you or third parties or a failure of +the library to operate with any other software), even if such holder or +other party has been advised of the possibility of such damages. diff --git a/gui/media/jabber_protocol.png b/gui/media/jabber_protocol.png new file mode 100644 index 0000000000000000000000000000000000000000..e9fc4a5d7c42135d794836c183ac877465c485d7 GIT binary patch literal 11050 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 diff --git a/gui/media/terminal.png b/gui/media/terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..a7230e4fc22daeb0d5d71faedee86e1eafe65771 GIT binary patch literal 7757 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. + */ + +#include "resource-manager.h" +#include "files-dockwidget.h" + +#include +#include +#include +#include +#include +#include + +files_dock_widget::files_dock_widget (QWidget *parent) + : QDockWidget (parent) +{ + setObjectName ("FilesDockWidget"); + setWindowTitle (tr ("Current Directory")); + setWidget (new QWidget (this)); + + // Create a toolbar + _navigation_tool_bar = new QToolBar ("", widget ()); + _navigation_tool_bar->setAllowedAreas (Qt::TopToolBarArea); + _navigation_tool_bar->setMovable (false); + _navigation_tool_bar->setIconSize (QSize (20, 20)); + + // Add a button to the toolbar with the QT standard icon for up-directory + _directory_icon = QIcon(":/actions/icons/up.png"); + _directory_up_action = new QAction (_directory_icon, "", _navigation_tool_bar); + _directory_up_action->setStatusTip (tr ("Move up one directory.")); + + _current_directory = new QLineEdit (_navigation_tool_bar); + _current_directory->setStatusTip (tr ("Enter the path or filename.")); + + _navigation_tool_bar->addAction (_directory_up_action); + _navigation_tool_bar->addWidget (_current_directory); + connect (_directory_up_action, SIGNAL (triggered ()), this, + SLOT (do_up_directory ())); + + // TODO: Add other buttons for creating directories + + // Create the QFileSystemModel starting in the home directory + QString + homePath = QDir::homePath (); + // TODO: This should occur after Octave has been initialized and the startup directory of Octave is established + + _file_system_model = new QFileSystemModel (this); + _file_system_model->setFilter (QDir::NoDotAndDotDot | QDir::AllEntries); + QModelIndex + rootPathIndex = _file_system_model->setRootPath (homePath); + + // Attach the model to the QTreeView and set the root index + _file_tree_view = new QTreeView (widget ()); + _file_tree_view->setModel (_file_system_model); + _file_tree_view->setRootIndex (rootPathIndex); + _file_tree_view->setSortingEnabled (true); + _file_tree_view->setAlternatingRowColors (true); + _file_tree_view->setAnimated (true); + _file_tree_view->setColumnHidden (1, true); + _file_tree_view->setColumnHidden (2, true); + _file_tree_view->setColumnHidden (3, true); + _file_tree_view->setStatusTip (tr ("Doubleclick a file to open it.")); + + set_current_directory (_file_system_model->fileInfo (rootPathIndex). + absoluteFilePath ()); + + connect (_file_tree_view, SIGNAL (doubleClicked (const QModelIndex &)), this, + SLOT (item_double_clicked (const QModelIndex &))); + + // Layout the widgets vertically with the toolbar on top + QVBoxLayout * + layout = new QVBoxLayout (); + layout->setSpacing (0); + layout->addWidget (_navigation_tool_bar); + layout->addWidget (_file_tree_view); + layout->setMargin (1); + widget ()->setLayout (layout); + // TODO: Add right-click contextual menus for copying, pasting, deleting files (and others) + + connect (_current_directory, SIGNAL (returnPressed ()), this, + SLOT (current_directory_entered ())); + QCompleter * + completer = new QCompleter (_file_system_model, this); + _current_directory->setCompleter (completer); + + connect (this, SIGNAL (visibilityChanged(bool)), this, SLOT(handle_visibility_changed(bool))); +} + +void +files_dock_widget::item_double_clicked (const QModelIndex & index) +{ + // Retrieve the file info associated with the model index. + QFileInfo fileInfo = _file_system_model->fileInfo (index); + + // If it is a directory, cd into it. + if (fileInfo.isDir ()) + { + _file_system_model->setRootPath (fileInfo.absolutePath ()); + _file_tree_view->setRootIndex (index); + set_current_directory (_file_system_model->fileInfo (index). + absoluteFilePath ()); + } + // Otherwise attempt to open it. + else + { + // Check if the user wants to use a custom file editor. + QSettings *settings = resource_manager::instance ()->get_settings (); + if (settings->value ("useCustomFileEditor").toBool ()) + { + QString editor = settings->value ("customFileEditor").toString (); + QStringList arguments; + arguments << fileInfo.filePath (); + QProcess::startDetached (editor, arguments); + } + else + { + emit open_file (fileInfo.filePath ()); + } + } +} + +void +files_dock_widget::set_current_directory (QString currentDirectory) +{ + _current_directory->setText (currentDirectory); +} + +void +files_dock_widget::do_up_directory (void) +{ + QDir dir = + QDir (_file_system_model->filePath (_file_tree_view->rootIndex ())); + dir.cdUp (); + _file_system_model->setRootPath (dir.absolutePath ()); + _file_tree_view->setRootIndex (_file_system_model-> + index (dir.absolutePath ())); + set_current_directory (dir.absolutePath ()); +} + +void +files_dock_widget::current_directory_entered () +{ + QFileInfo fileInfo (_current_directory->text ()); + if (fileInfo.isDir ()) + { + _file_tree_view->setRootIndex (_file_system_model-> + index (fileInfo.absolutePath ())); + _file_system_model->setRootPath (fileInfo.absolutePath ()); + set_current_directory (fileInfo.absoluteFilePath ()); + } + else + { + if (QFile::exists (fileInfo.absoluteFilePath ())) + emit open_file (fileInfo.absoluteFilePath ()); + } +} + +void +files_dock_widget::notice_settings () +{ + QSettings *settings = resource_manager::instance ()->get_settings (); + _file_tree_view->setColumnHidden (0, !settings->value ("showFilenames").toBool ()); + _file_tree_view->setColumnHidden (1, !settings->value ("showFileSize").toBool ()); + _file_tree_view->setColumnHidden (2, !settings->value ("showFileType").toBool ()); + _file_tree_view->setColumnHidden (3, !settings->value ("showLastModified").toBool ()); + _file_tree_view->setAlternatingRowColors (settings->value ("useAlternatingRowColors").toBool ()); + //if (settings.value ("showHiddenFiles").toBool ()) + // TODO: React on option for hidden files. +} + +void +files_dock_widget::handle_visibility_changed (bool visible) +{ + if (visible) + emit active_changed (true); +} + +void +files_dock_widget::closeEvent (QCloseEvent *event) +{ + emit active_changed (false); + QDockWidget::closeEvent (event); +} diff --git a/gui/src/files-dockwidget.h b/gui/src/files-dockwidget.h new file mode 100644 --- /dev/null +++ b/gui/src/files-dockwidget.h @@ -0,0 +1,83 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FILESDOCKWIDGET_H +#define FILESDOCKWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +class files_dock_widget : public QDockWidget +{ + Q_OBJECT +public: + files_dock_widget (QWidget *parent = 0); + +public slots: + /** Slot for handling a change in directory via double click. */ + void item_double_clicked (const QModelIndex & index); + + /** Slot for handling the up-directory button in the toolbar. */ + void do_up_directory (); + void set_current_directory (QString currentDirectory); + void current_directory_entered (); + + /** Tells the widget to notice settings that are probably new. */ + void notice_settings (); + void handle_visibility_changed (bool visible); + +signals: + void open_file (QString fileName); + + /** Custom signal that tells if a user has clicke away that dock widget. */ + void active_changed (bool active); + +protected: + void closeEvent (QCloseEvent *event); + +private: + // TODO: Add toolbar with buttons for navigating the path, creating dirs, etc + + /** Toolbar for file and directory manipulation. */ + QToolBar * _navigation_tool_bar; + + /** Variables for the up-directory action. */ + QIcon _directory_icon; + QAction * _directory_up_action; + QToolButton * _up_directory_button; + + /** The file system model. */ + QFileSystemModel *_file_system_model; + + /** The file system view. */ + QTreeView * _file_tree_view; + QLineEdit * _current_directory; +}; + +#endif // FILESDOCKWIDGET_H diff --git a/gui/src/history-dockwidget.cc b/gui/src/history-dockwidget.cc new file mode 100644 --- /dev/null +++ b/gui/src/history-dockwidget.cc @@ -0,0 +1,136 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "history-dockwidget.h" +#include + +history_dock_widget::history_dock_widget (QWidget * parent) + : QDockWidget (parent), octave_event_observer () +{ + setObjectName ("HistoryDockWidget"); + construct (); +} + +void +history_dock_widget::event_accepted (octave_event *e) +{ + if (dynamic_cast (e)) + { + // Determine the client's (our) history length and the one of the server. + int clientHistoryLength = _history_model->rowCount (); + int serverHistoryLength = command_history::length (); + + // If were behind the server, iterate through all new entries and add + // them to our history. + if (clientHistoryLength < serverHistoryLength) + { + for (int i = clientHistoryLength; i < serverHistoryLength; i++) + { + _history_model->insertRow (0); + _history_model->setData (_history_model->index (0), + QString (command_history::get_entry (i).c_str ())); + } + } + } + + // Post a new update event in a given time. This prevents flooding the + // event queue. + _update_history_model_timer.start (); + delete e; +} + +void +history_dock_widget::event_reject (octave_event *e) +{ + delete e; +} + +void +history_dock_widget::construct () +{ + _history_model = new QStringListModel (); + _sort_filter_proxy_model.setSourceModel (_history_model); + _history_list_view = new QListView (this); + _history_list_view->setModel (&_sort_filter_proxy_model); + _history_list_view->setAlternatingRowColors (true); + _history_list_view->setEditTriggers (QAbstractItemView::NoEditTriggers); + _history_list_view->setStatusTip (tr ("Doubleclick a command to transfer it to the terminal.")); + _filter_line_edit = new QLineEdit (this); + _filter_line_edit->setStatusTip (tr ("Enter text to filter the command history.")); + QVBoxLayout *layout = new QVBoxLayout (); + + setWindowTitle (tr ("Command History")); + setWidget (new QWidget ()); + + layout->addWidget (_history_list_view); + layout->addWidget (_filter_line_edit); + layout->setMargin (2); + + widget ()->setLayout (layout); + + connect (_filter_line_edit, + SIGNAL (textEdited (QString)), + &_sort_filter_proxy_model, + SLOT (setFilterWildcard (QString))); + + connect (_history_list_view, + SIGNAL (doubleClicked (QModelIndex)), + this, + SLOT (handle_double_click (QModelIndex))); + + connect (this, + SIGNAL (visibilityChanged (bool)), + this, + SLOT (handle_visibility_changed (bool))); + + _update_history_model_timer.setInterval (200); + _update_history_model_timer.setSingleShot (true); + + connect (&_update_history_model_timer, + SIGNAL (timeout ()), + this, + SLOT (request_history_model_update ())); + + _update_history_model_timer.start (); +} + +void +history_dock_widget::handle_double_click (QModelIndex modelIndex) +{ + emit command_double_clicked (modelIndex.data().toString()); +} + +void +history_dock_widget::handle_visibility_changed (bool visible) +{ + if (visible) + emit active_changed (true); +} + +void +history_dock_widget::request_history_model_update () +{ + octave_link::instance () + ->post_event (new octave_update_history_event (*this)); +} + +void +history_dock_widget::closeEvent (QCloseEvent *event) +{ + emit active_changed (false); + QDockWidget::closeEvent (event); +} diff --git a/gui/src/history-dockwidget.h b/gui/src/history-dockwidget.h new file mode 100644 --- /dev/null +++ b/gui/src/history-dockwidget.h @@ -0,0 +1,66 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HISTORYDOCKWIDGET_H +#define HISTORYDOCKWIDGET_H + +#include +#include +#include +#include +#include +#include + +#include "octave-link.h" +#include "octave-event-observer.h" + +class history_dock_widget : public QDockWidget, public octave_event_observer +{ +Q_OBJECT +public: + history_dock_widget (QWidget *parent = 0); + + void event_accepted (octave_event *e); + void event_reject (octave_event *e); + +public slots: + void handle_visibility_changed (bool visible); + void request_history_model_update (); + +signals: + void information (QString message); + void command_double_clicked (QString command); + /** Custom signal that tells if a user has clicked away that dock widget. */ + void active_changed (bool active); +protected: + void closeEvent (QCloseEvent *event); +private slots: + void handle_double_click (QModelIndex modelIndex); + +private: + void construct (); + QListView *_history_list_view; + QLineEdit *_filter_line_edit; + QSortFilterProxyModel _sort_filter_proxy_model; + + /** Stores the current history_model. */ + QStringListModel *_history_model; + + QTimer _update_history_model_timer; +}; + +#endif // HISTORYDOCKWIDGET_H diff --git a/gui/src/icons/artsbuilderexecute.png b/gui/src/icons/artsbuilderexecute.png new file mode 100644 index 0000000000000000000000000000000000000000..814f916b5aab5d9474f3e857e982b123ac673b0c GIT binary patch literal 1382 zc$@)d1)2JZP)=;0)!9`NC-jFsu)2qWl;-MVw0%U zKJ}%PLd6q2@xmgW*g+@(9F{E2B_u?|S$v)AB{X*I+?hKwhlgv6I`}%SaX8W^of(bh z|2x04%!sv?v)g6&y!LEsa=gcv?C}qdWN)&sTwD0jLyOdOwwnk0iyONxy(;myd#=gX zC(QQx+dkOxvjUVu%d>9{aJV$dy_=SKbw*xF-SOe`nXMlse-;2^gh-&T7;xJyYq)W9 z9*3y)5y2B{`IQ#n@J?9kw0a2kG!HF`A zOv2#u7VP@~n8}`a zYnPE<;el{#3_BVh-t)@^7yyi5qnOyQ5c}ad%laXl2{?YLLV1ZtM@KXD3DX(I?C>7h z`-fTp&g=k!sDap4UmnME4dO>5I$4IvL>;R-niw1ycZSC*|7d#bKUa&&ouhy0J~;eXx`fi0GT*7)MdpU=c*8MlU}Y zn6{#-WaS+_M zBjl0>FJox+3@sU#J;jiHyY^wC;6QR^_jMyrtm&UMr=|g&ItR467-6RV>3Oen4UHMa zODQXwUBK|}p@5-p_S^KzuD=u8$44Gt?a!7mw}I&qtNvg>v^ot^osLYs!AmI@WDUz3 zU5aCtF9v)j`}dztuk6|~{OA1Za|O>0pj!PFs349`t%+*5V}xwd;H8z;hN|-2gArft z-iL<%*QwR(Hw{0s^7wqhYXeOG56mzi)VV@KTJchbe6vGr4exwgVdP-JW>$6mmDoN# z^ze#czTve20JOTt#R!6su2&jT%95<1z0u|9Da-B?70Tc4JC$C&ZtKuP%is8ag69TM zL5zY?jBCi&D_&apMb6Naa@kdiICQv(9Uc5SwdT^ROAodUE+o7rfJjxpI!ZR<;H8yS zO%9PYyni%g^gsc}G5@aX+|XOPe_6E9@R|S?Ax7wINpN#ll4GYrJ}bo(Mnn8>_MXgi ztiSz4Z|j>sC3sE%QBX%2A5b=4n4~avhA$2tMuv-p)Y{88o!GW?!OG_eAZQ@G{a#4_ zp$Ybu_gKe~=e~R9hTg>ro)f^v!kHt=Dq|ROjt{z>>+TroS@Qm3ht~vfa;@7d1I5+D ob;W-7qAPD4>1kdx diff --git a/gui/src/icons/configure.png b/gui/src/icons/configure.png new file mode 100644 index 0000000000000000000000000000000000000000..1753139eae90fd43069b2bd7da99b852b3fd2e93 GIT binary patch literal 2548 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 KMNUMnLSTaRrTcFH diff --git a/gui/src/icons/editcopy.png b/gui/src/icons/editcopy.png new file mode 100644 index 0000000000000000000000000000000000000000..8df8201ec9748822200f737fc52eb925382b0809 GIT binary patch literal 1075 zc$@(<1kC%1P)F4XY$#51Tv%gLs5t!G=w?gLnvd05%ymjJ$&pBL##A z$}rOxw=c2NZJ9WZ9ox98>aei8V>_M8ke;%R&d$fFREnok zb7_jbfuOa9QW{z-+~$*W&OOholu9K_+!`IgU@&;QP$>M6&1M&s(y?=hMi4}V+t!p$ z&*AaoZ@vTY#hm~EKuTpusSpIgjq?n{xRXDnR0;sD1=!u)Wov6|831{uR1N?et?uUK z-KC`Cc{ByU7~|P&Hn+b1-ulMI`x_4*e*S4bpR4%3-`LvP{+2Q0Ev3|*oWITx0PyJ1 zmtP$m{Px+>($c&6d_FfnpJw5N^Yae&_xEqD>%9P0S64Q-x3@kD0tuxQdc8h?Q9b+p z9;B3SCVB{Pc=*@f0B#gmSpU1$__Y9R+p?6>Fbw0`07(OcUIYMCtJPAw-5zE#nYlQj zg`JgX2F89E0QkON_kF*~Iggz;GJ@90Sm-kX2!i0$b=_mm`BbX)#P`uhCt?~D6@iUY zs~pF63g=Mgzw6mzoHI3#3x1=(mN1Ma(^TV8jAAj$;z0SG}^bibA0P#uyMa(8M5&_jx@! zoB&|V0An1B3ybi5uhnX`{t!Yi07$3P^Ut6E`e!V_ix)>n{eC|R&KO57mjmYv;oA~L zt2DqE0~Z{Eb1=q00D|EVoo*Lrt=7Q1xHx5w zvxDX3<(v#8h%}^9;Eay~2?5Rp0K)L!A=>RW{DyyCtJNB=>sD>sa*9sTtksU)X0v(R z?RJle$S0!MH{L55==FMyhVR!lKitd>g8%?QN{Mc#Lw?O`SE`j0$9Bq=ZMo(v(=1oY zcEk58gTcTD&?2H?T%ha56#yc-*xTFtT}rulczAeZS*GQ>rDC;ODSDn)?)7>efHn~& ta#*-h0ss&~yrZ>dM07?($)Cq2#(#k4+4%v4qPzeA002ovPDHLkV1jDD`{Doq diff --git a/gui/src/icons/editcut.png b/gui/src/icons/editcut.png new file mode 100644 index 0000000000000000000000000000000000000000..514bd97c273a2ab2f85222a0113d5aff45297b5b GIT binary patch literal 1379 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 AnE(I) diff --git a/gui/src/icons/filenew.png b/gui/src/icons/filenew.png new file mode 100644 index 0000000000000000000000000000000000000000..4828b63375b5067b8901ecf061bb65375cafe593 GIT binary patch literal 410 zc$@*60cHM)P)AUJ+VW{ zXXzyn5dk8aak{x8loKS3_bhz}LByAzrl|(tC5eFaI1Nz(s3eRaBuELs3vMOKEQe=9 z6{uEX2;eN}=yIe1^tY`ftU#phf{}!mRzL^365^5yWFX1_BWm~b5<#Ty0)5{1_tEy! zMnpA$OmgeQ^ZGnX9Yh*P_MeF}igyZNt*MtNBTmc0C6EcTCD-G6yIcWHuLDFoB&wFS za2G_PyIq7marQ`+V>|&{He3M!f4%>$0+uc;@68VZJRwC#wC9H|qfDYJAY2X1^ZeG< zzxks-D^}Yx7hql2A7*ZuOGo!x;}H>v=%WlRtJb^h3BCK`LD4@z3jhEB07*qoM6N<$ Ef=E%W8UO$Q diff --git a/gui/src/icons/fileopen.png b/gui/src/icons/fileopen.png new file mode 100644 index 0000000000000000000000000000000000000000..e3528f02c939db2a07723980076767c367605454 GIT binary patch literal 1365 zc$@)M1*-aqP)em6veIk|M#5#Kew(? zRjyae&d&N%Q&Y7#j%T(^PuE4<&WY;euH}_%_YFIDeXw)O#Ovn25SX2v^=q|SEso=v zTCG;M*6yg)YP*avH&?6Gok0-X7)9lJISi)-FYKgBY?X4!@Y#3gP98mU>m$K9fTvEK zx~X2TKNg1Jo=T;1^TC4$Z;Ya-9t6R35Coy```3JcN zRKS=%byO6q*MWeD5XUhh4r2^T4rB!kfB{uNu0sZlG5r$ci&dmZb*4E1Pm4JOoco^% zj2y3;*V`$^fB@DCz7bsR!tn^Wf_6`Q=4xTD2}7Q45pa?dP!*gL@IXYzCor6WK_Y{$ z7#wd!u&Q_p&bqurx=8}P3=D^=_Oqd?p!w=m6z2rzz=|LueKDqX6D8QV29%x%MIp0- zIEx{-qg7=kb(<$Joa(_6^j%;I5elT41r>||&p1O4?5l%P*ga{_6Wky)F! zTm!y=rLG`ub1slRKoRRX!C6OU9k#HcZ=jng%c~i>NgGZLzZ>3|^3^L@mge9#7hx6RPbI0zG)}w>*@BphYF>3N2=-Pzx4M;?AgW}Emw1FWJo@q7{ zU=c`w3NT5Y{)s{14U2HSOei2uQ70G`d=wAJ>>4&a(`=^u8;ykmd>TkqwY-t@!yvFR zh9C&=yk*yCMPFpwU*O` zg@yCYpS!LV1&iPO(w=X}(n`b_Bl2+&n0MAAuma2jk;zGvC!&Z_skEjD(=>H)9G{z; zn>+o{haaB)_Uo^{KL69t^W1*?>H2{!TNjtpwh2mQKUseF!pleB>wPzpz?o)KfM54F z8Y_Mf+;(Mg@z;|lPP~8k@ZsBc@7YsdU0r2)d6`zLb*|g(e%@}kKe5)Ho|&0x&dkiD z$BrN8t~>82n=q(9yd?c2HU-g~^MyB~k_&tHE0e(vK}z8p1ftle;& X7MP!rkhXXe00000NkvXXu0mjfYNeO3 diff --git a/gui/src/icons/filesave.png b/gui/src/icons/filesave.png new file mode 100644 index 0000000000000000000000000000000000000000..82db5055699c6c9e300a5bc6cc3e7dd936859a00 GIT binary patch literal 1440 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 diff --git a/gui/src/icons/redo.png b/gui/src/icons/redo.png new file mode 100644 index 0000000000000000000000000000000000000000..fea4842cb2278d7d6efbc0daa3919598f2e179a3 GIT binary patch literal 1895 zc$@)e2blPYP)zUcz>FJ*C=_(FAyV-HP>xc`l^`ugD z*ZcqLU-e#9i}#-Yr^(1K3wc8XvBJj17&!)oaiKn5q1Y%eePADr*8{RwiqP|j6IwUh zsL?%xdpu4(CutVSIT)uU%b+$@#eQE_6uBfw#CLD9NOrR<7@QvcGs zi@Qe{>;r2J#_BF^c<$Cydn=H6@7fbB$E%>n;iJn}`RKq^-W)qey-|7K48mTQdZ~ur zUYj8eP=sIeBmUO=fTb%pIRDqnunNbg=4sm&)~Ft7Y&Q1YdFj)ho5Vl$)h~1G_)&94 zPFDZ8@~2CmT)eWj8@M1KpjL6-;hi5&2@h}1{5@|MffEDYsQ~Z@!f685QM|*WqQ+nw zK66cA&6B6x)+}WUMe_RbpT#8(9X~LXngCy<$f2#K4(@C20;fX8T1G-5U^_u6uLibh|V+`JVmX}u0Ih~yyn>lu%J^%K#^3`V^ ztU%@t_>37~o{aglm(Hh2I-mG>Hi?tT)o+GF1ENk$6vjkhM06`cRY5^au12R7_8Z5h z?JFmK@I-h!ymEio9Rz&O&->JmkTQv5su!nINiUg-vtGI1OQ-K0kVbv_Q6IPN5Far7B==IK*XF+5Hd<6l;dt(?rz4#IEm>c>Davk`n^8= zj>{{sfY*F;dORp(v2(GHSmbiB z4v2dRUK|-2na^;UBg?XFk2>+q4k5R=MRz6U`km|STbMFOelv65qGo-F^8wHSMj+lu zX|J!-n5#4KtNKf|pI0BXBU(qqY~}q1z2SP}J>KD6&uwalBlX8Ucas+3dPuh!(OkPp zp;3|fpH63={_Kt!BH$vB1Zd?1k`YJR?s0u>i6>utZ1T*L!SjvD2Gv51F~%9srl?WF zk{?9Qcs6~Trn$pyZX@q>S($C|;mt)ltqvO-n{?U{-L;63sHEfHt7pyMZ*G&Ybb%7k z1nS_baC@cATk(17M{3mLI`#Dm)zLDQQiZyXP#!#j&?6xtq(exY#B@$}xx0Lqa3!SM zib*#5_|Q;pd7>LVW@~dg`>koW{Q4c;Cg7_cVqh7t&?ct65ku65I_M~96-*IK0SLeV z>J6qZXlgM%i%l&W1(?WUx&h_h7`1GgAT1D>0(QorRb}ebq#XUmA%FFa>tbC8@e}zD zrUg_%ra>&I1I@ssf=v~JVlqJ!MZG~YMfwJf1W6Rrw@7Tzo`J;RyWrL{`gan1CnF0i z1zSV{CELt*kZ(Bi?1!xe!RJB zF!iY)Vvp`1p}Uh<`(YO|u1I+YiGg|J+5gCXuARNc>J!U*{WuI1*r~ScAYu0)k;3ZB zUChKli5)QYV1!Rzy~66(ZtMvTpd;TevAqn#)bc&Cn+-^>z8E4EV228|jT(z@eZ24> zZ~%4do^2I&xkIWdFMRifVKsI%r65DM;nk;?Wc0_Se}6Foo1W2c?@(bUiJbxt0M#lQ h=+L|ETJb;Fe*x2YI^BO|KdS%$002ovPDHLkV1lFuqBj5l diff --git a/gui/src/icons/search.png b/gui/src/icons/search.png new file mode 100644 index 0000000000000000000000000000000000000000..88c6eb1d5eb0279b63fc845f25d3a2ba3d811e2e GIT binary patch literal 1567 zc$@(r2H^RLP)w)?Qq)4VYDY(B`s5{+h+5P&w%F43Ky(?*Ta;Puq(k(k3FiL}a~)JS-v$ zMI?E&&#W6BQGnl;mzTFLzGX>zq5!&)Tqw#M)u7zbaP-)NXS=mu<>pRV1~dbmz#!lS zPIN(_3#_NX`k{ukqH42o?k$f!^>XFQEro?&e=N}qi~uZJwCJI?>rd3I-s}!!XIMS} zngAc50YktkA1F4+uz)=Y?6xHAijGOEA77`BPMBG4w^?poeDinH69!Ne#d&>U;XG^F z?Ao=D6mN=wJq(Y>CyxT>{17%nmLAd!kY<83Go+aC5ADW>TrB35rB(z zAU|tzwmEHju>r`_!Bl}wKn-vW;MYMGpt~3{ecVhc7<4ejl^@V`wRYM(pUeiT69t%T zPt8=!Svjc;?{!TN-vR2va7MtU1KU{PQvgK)lbJxe(-qe1^~vLjK**$;REx!$0fc~X zeC)63p(O-^x>5hjXbBJ%P;>+{9I5tTFccaOK*xD+mmwoh_mwCF^~3EZAQFMh7}#~g zK*Zt}jZ=n0;J*MCm9RyPX7%;;pBfLqCkNi#+flOQ{``--7|PFNViY6>Y8X@<#3G|t z30HHM060*gXrT9 z7gs+7Xnyc|AsQl9Fqy1X&m4IFQ0@MY69M?FB*HZhJ@{i!NF?^ganb6|i2sC7w5Et? zZ6ey)xV4FB%~8?*?h~!XBU;5(?SIhgbnb*xFe()) zaDQoOX>&(Mw}^-gL`B+sBCP`=Js}xUSy`C|{08{>M~zMLyefOVd6%>RfCQsyaTRZPH9R9Yd8u#`0`!cUM0D#ZuTlJ%RR#aSD zkS|7~fj}U@KR#?MN=cbm^=Vg^eJtwBZoq`;)2DBHx2|6H?yr%?#*@(nA^>p+tIL)5qWj%CscSeQJw3hB+1(=pKHt9jh9eWMIKXERu5IqRI{B#aq=X_7 z8Swd}x7WMl$ot2VuQ)&)!jhexz4fg_?ue(gO``E4_H23iAFm2P9KxKQp1x)8{+gig zf+p)XY&ZsFUNwL?gwbZRJzYG1{!755i|v=S5dAkPieicHJpV}B)dUzz{{qwtDjYiM Ruzvsm002ovPDHLkV1mrp2BH7} diff --git a/gui/src/icons/undo.png b/gui/src/icons/undo.png new file mode 100644 index 0000000000000000000000000000000000000000..fcebab0bf03520ebbc1df2ff759fea1c720ca4dd GIT binary patch literal 2035 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. + */ + +#ifndef FILEEDITORINTERFACE_H +#define FILEEDITORINTERFACE_H + +#include + +class QTerminal; +class main_window; + +class file_editor_interface : public QDockWidget +{ + Q_OBJECT + + public: + file_editor_interface (QTerminal *terminal, main_window *mainWindow) + : QDockWidget ((QWidget*)mainWindow) // QDockWidget constructor is explicit, hence the cast. + { + setObjectName ("FileEditor"); + _terminal = terminal; + _main_window = mainWindow; + + connect (this, SIGNAL (visibilityChanged (bool)), this, SLOT (handle_visibility_changed (bool))); + } + + virtual ~file_editor_interface () { } + public slots: + virtual void request_new_file () = 0; + virtual void request_open_file () = 0; + virtual void request_open_file (QString fileName) = 0; + + virtual void handle_entered_debug_mode () = 0; + virtual void handle_quit_debug_mode () = 0; + + signals: + void active_changed (bool active); + + protected: + QTerminal* _terminal; + main_window* _main_window; + + void closeEvent (QCloseEvent *event) + { + emit active_changed (false); + QDockWidget::closeEvent (event); + } + + protected slots: + void handle_visibility_changed (bool visible) + { + if (visible) + emit active_changed (true); + } +}; + +#endif // FILEEDITORINTERFACE_H diff --git a/gui/src/m-editor/file-editor-tab.cc b/gui/src/m-editor/file-editor-tab.cc new file mode 100644 --- /dev/null +++ b/gui/src/m-editor/file-editor-tab.cc @@ -0,0 +1,514 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "file-editor-tab.h" +#include "file-editor.h" +#include +#include + +file_editor_tab::file_editor_tab(file_editor *fileEditor) + : QWidget ((QWidget*)fileEditor) +{ + QSettings *settings = resource_manager::instance ()->get_settings (); + _file_editor = fileEditor; + _file_name = ""; + _edit_area = new QsciScintilla (this); + _edit_area->setLexer (fileEditor->lexer ()); + + // markers + _edit_area->setMarginType (1, QsciScintilla::SymbolMargin); + _edit_area->setMarginSensitivity (1, true); + _edit_area->markerDefine (QsciScintilla::RightTriangle, MARKER_BOOKMARK); + connect (_edit_area, SIGNAL (marginClicked (int, int, Qt::KeyboardModifiers)), + this, SLOT (handle_margin_clicked (int, int, Qt::KeyboardModifiers))); + + // line numbers + _edit_area->setMarginsForegroundColor(QColor(96,96,96)); + _edit_area->setMarginsBackgroundColor(QColor(232,232,220)); + if (settings->value ("editor/showLineNumbers",true).toBool ()) + { + QFont marginFont( settings->value ("editor/fontName","Courier").toString () , + settings->value ("editor/fontSize",10).toInt () ); + _edit_area->setMarginsFont( marginFont ); + QFontMetrics metrics(marginFont); + _edit_area->setMarginType (2, QsciScintilla::TextMargin); + _edit_area->setMarginWidth(2, metrics.width("99999")); + _edit_area->setMarginLineNumbers(2, true); + } + + // code folding + _edit_area->setMarginType (3, QsciScintilla::SymbolMargin); + _edit_area->setFolding (QsciScintilla::BoxedTreeFoldStyle , 3); + + // other features + if (settings->value ("editor/highlightCurrentLine",true).toBool ()) + { + _edit_area->setCaretLineVisible(true); + _edit_area->setCaretLineBackgroundColor(QColor(245,245,245)); + } + _edit_area->setBraceMatching (QsciScintilla::StrictBraceMatch); + _edit_area->setAutoIndent (true); + _edit_area->setIndentationWidth (2); + _edit_area->setIndentationsUseTabs (false); + if (settings->value ("editor/codeCompletion",true).toBool ()) + { + _edit_area->autoCompleteFromAll (); + _edit_area->setAutoCompletionSource(QsciScintilla::AcsAll); + _edit_area->setAutoCompletionThreshold (1); + } + _edit_area->setUtf8 (true); + + QVBoxLayout *layout = new QVBoxLayout (); + layout->addWidget (_edit_area); + layout->setMargin (0); + setLayout (layout); + + // connect modified signal + connect (_edit_area, SIGNAL (modificationChanged (bool)), + this, SLOT (new_title (bool))); + connect (_edit_area, SIGNAL (copyAvailable (bool)), + this, SLOT (handle_copy_available (bool))); + connect (&_file_system_watcher, SIGNAL (fileChanged (QString)), + this, SLOT (file_has_changed (QString))); + + _file_name = ""; + new_title (false); +} + +bool +file_editor_tab::copy_available () +{ + return _copy_available; +} + +void +file_editor_tab::closeEvent (QCloseEvent *event) +{ + if (_file_editor->mainWindow ()->is_closing ()) + { + // close whole application: save file or not if modified + check_file_modified ("Closing Octave", 0); // no cancel possible + event->accept (); + } + else + { + // ignore close event if file is not saved and user cancels closing this window + if (check_file_modified ("Close File", QMessageBox::Cancel) == QMessageBox::Cancel) + { + event->ignore (); + } + else + { + event->accept(); + } + } +} + +void +file_editor_tab::set_file_name (QString fileName) +{ + _file_name = fileName; + update_tracked_file (); +} + +void +file_editor_tab::handle_margin_clicked(int margin, int line, Qt::KeyboardModifiers state) +{ + Q_UNUSED (state); + if (margin == 1) // marker margin + { + unsigned int mask = _edit_area->markersAtLine (line); + if (mask && (1 << MARKER_BOOKMARK)) + _edit_area->markerDelete(line,MARKER_BOOKMARK); + else + _edit_area->markerAdd(line,MARKER_BOOKMARK); + } +} + +void +file_editor_tab::comment_selected_text () +{ + do_comment_selected_text (true); +} + +void +file_editor_tab::uncomment_selected_text () +{ + do_comment_selected_text (false); +} + +void +file_editor_tab::do_comment_selected_text (bool comment) +{ + if ( _edit_area->hasSelectedText() ) + { + int lineFrom, lineTo, colFrom, colTo, i; + _edit_area->getSelection (&lineFrom,&colFrom,&lineTo,&colTo); + if ( colTo == 0 ) // the beginning of last line is not selected + lineTo--; // stop at line above + _edit_area->beginUndoAction (); + for ( i=lineFrom; i<=lineTo; i++ ) + { + if ( comment ) + _edit_area->insertAt("%",i,0); + else + { + QString line(_edit_area->text(i)); + if ( line.startsWith("%") ) + { + _edit_area->setSelection(i,0,i,1); + _edit_area->removeSelectedText(); + } + } + } + _edit_area->endUndoAction (); + } +} + +void +file_editor_tab::new_title(bool modified) +{ + QString title(_file_name); + if ( !_long_title ) + { + QFileInfo file(_file_name); + title = file.fileName(); + } + + if ( modified ) + { + emit file_name_changed (title.prepend("* ")); + } + else + emit file_name_changed (title); +} + +void +file_editor_tab::handle_copy_available(bool enableCopy) +{ + _copy_available = enableCopy; + emit editor_state_changed (); +} + +void +file_editor_tab::update_tracked_file () +{ + QStringList trackedFiles = _file_system_watcher.files (); + if (!trackedFiles.isEmpty ()) + _file_system_watcher.removePaths (trackedFiles); + + if (_file_name != UNNAMED_FILE) + _file_system_watcher.addPath (_file_name); +} + +int +file_editor_tab::check_file_modified (QString msg, int cancelButton) +{ + int decision = QMessageBox::Yes; + if (_edit_area->isModified ()) + { + // file is modified but not saved, aks user what to do + decision = QMessageBox::warning (this, + msg, + tr ("The file %1\n" + "has been modified. Do you want to save the changes?"). + arg (_file_name), + QMessageBox::Save, QMessageBox::Discard, cancelButton ); + if (decision == QMessageBox::Save) + { + save_file (); + if (_edit_area->isModified ()) + { + // If the user attempted to save the file, but it's still + // modified, then probably something went wrong, so return cancel + // for cancel this operation or try to save files as if cancel not + // possible + if ( cancelButton ) + return (QMessageBox::Cancel); + else + save_file_as (); + } + } + } + return (decision); +} + +void +file_editor_tab::remove_bookmark () +{ + _edit_area->markerDeleteAll(MARKER_BOOKMARK); +} + +void +file_editor_tab::toggle_bookmark () +{ + int line,cur; + _edit_area->getCursorPosition(&line,&cur); + if ( _edit_area->markersAtLine (line) && (1 << MARKER_BOOKMARK) ) + _edit_area->markerDelete(line,MARKER_BOOKMARK); + else + _edit_area->markerAdd(line,MARKER_BOOKMARK); +} + +void +file_editor_tab::next_bookmark () +{ + int line,cur,nextline; + _edit_area->getCursorPosition(&line,&cur); + if ( _edit_area->markersAtLine(line) && (1 << MARKER_BOOKMARK) ) + line++; // we have a bookmark here, so start search from next line + nextline = _edit_area->markerFindNext(line,(1 << MARKER_BOOKMARK)); + _edit_area->setCursorPosition(nextline,0); +} + +void +file_editor_tab::previous_bookmark () +{ + int line,cur,prevline; + _edit_area->getCursorPosition(&line,&cur); + if ( _edit_area->markersAtLine(line) && (1 << MARKER_BOOKMARK) ) + line--; // we have a bookmark here, so start search from prev line + prevline = _edit_area->markerFindPrevious(line,(1 << MARKER_BOOKMARK)); + _edit_area->setCursorPosition(prevline,0); +} + +void +file_editor_tab::cut () +{ + _edit_area->cut (); +} + +void +file_editor_tab::copy () +{ + _edit_area->copy (); +} + +void +file_editor_tab::paste () +{ + _edit_area->paste (); +} + +void +file_editor_tab::undo () +{ + _edit_area->undo (); +} + +void +file_editor_tab::redo () +{ + _edit_area->redo (); +} + +void +file_editor_tab::set_modified (bool modified) +{ + _edit_area->setModified (modified); +} + +bool +file_editor_tab::open_file () +{ + QString openFileName; + QFileDialog fileDialog(this); + fileDialog.setNameFilter(SAVE_FILE_FILTER); + fileDialog.setAcceptMode(QFileDialog::AcceptOpen); + fileDialog.setViewMode(QFileDialog::Detail); + if (fileDialog.exec () == QDialog::Accepted) + { + openFileName = fileDialog.selectedFiles().at(0); + if (openFileName.isEmpty ()) + return false; + + load_file(openFileName); + return true; + } + else + { + return false; + } +} + +void +file_editor_tab::load_file (QString fileName) +{ + if (!_file_editor->isVisible ()) + { + _file_editor->show (); + } + + QFile file (fileName); + if (!file.open (QFile::ReadOnly)) + { + QMessageBox::warning (this, tr ("Octave Editor"), + tr ("Could not open file %1 for read:\n%2.").arg (fileName). + arg (file.errorString ())); + return; + } + + QTextStream in (&file); + QApplication::setOverrideCursor (Qt::WaitCursor); + _edit_area->setText (in.readAll ()); + QApplication::restoreOverrideCursor (); + + set_file_name (fileName); + update_tracked_file (); + + + new_title (false); // window title (no modification) + _edit_area->setModified (false); // loaded file is not modified yet +} + +void +file_editor_tab::new_file () +{ + if (!_file_editor->isVisible ()) + { + _file_editor->show (); + } + + set_file_name (UNNAMED_FILE); + new_title (false); // window title (no modification) + _edit_area->setText (""); + _edit_area->setModified (false); // new file is not modified yet +} + +bool file_editor_tab::save_file() +{ + return save_file (_file_name); +} + +bool +file_editor_tab::save_file (QString saveFileName) +{ + // it is a new file with the name "" -> call saveFielAs + if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) + { + return save_file_as(); + } + + // open the file for writing + QFile file (saveFileName); + if (!file.open (QFile::WriteOnly)) + { + QMessageBox::warning (this, tr ("Octave Editor"), + tr ("Could not open file %1 for write:\n%2."). + arg (saveFileName).arg (file.errorString ())); + return false; + } + + // save the contents into the file + QTextStream out (&file); + QApplication::setOverrideCursor (Qt::WaitCursor); + out << _edit_area->text (); + QApplication::restoreOverrideCursor (); + set_file_name (saveFileName); // save file name for later use + new_title (false); // set the window title to actual file name (not modified) + _edit_area->setModified (false); // files is save -> not modified + return true; +} + +bool +file_editor_tab::save_file_as () +{ + QString saveFileName(_file_name); + QFileDialog fileDialog(this); + if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) + { + saveFileName = QDir::homePath (); + fileDialog.setDirectory (saveFileName); + } + else + { + fileDialog.selectFile (saveFileName); + } + fileDialog.setNameFilter (SAVE_FILE_FILTER); + fileDialog.setDefaultSuffix ("m"); + fileDialog.setAcceptMode (QFileDialog::AcceptSave); + fileDialog.setViewMode (QFileDialog::Detail); + + if (fileDialog.exec ()) + { + saveFileName = fileDialog.selectedFiles ().at (0); + if (saveFileName.isEmpty ()) + return false; + + return save_file (saveFileName); + } + + return false; +} + +void +file_editor_tab::run_file () +{ + if (_edit_area->isModified ()) + save_file(_file_name); + + _file_editor->terminal ()->sendText (QString ("run \'%1\'\n").arg (_file_name)); + _file_editor->terminal ()->setFocus (); +} + +void +file_editor_tab::file_has_changed (QString fileName) +{ + Q_UNUSED (fileName); + if (QFile::exists (_file_name)) + { + // Prevent popping up multiple message boxes when the file has been changed multiple times. + static bool alreadyAsking = false; + if (!alreadyAsking) + { + alreadyAsking = true; + + int decision = + QMessageBox::warning (this, tr ("Octave Editor"), + tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?"). + arg (_file_name), QMessageBox::Yes, QMessageBox::No); + + if (decision == QMessageBox::Yes) + { + load_file (_file_name); + } + + alreadyAsking = false; + } + } + else + { + int decision = + QMessageBox::warning (this, tr ("Octave Editor"), + tr ("It seems that \'%1\' has been deleted or renamed. Do you want to save it now?"). + arg (_file_name), QMessageBox::Save, QMessageBox::Close); + if (decision == QMessageBox::Save) + { + if (!save_file_as ()) + { + set_file_name (UNNAMED_FILE); + new_title (true); // window title (no modification) + set_modified (true); + update_tracked_file (); + } + } + else + { + emit close_request (); + } + } +} diff --git a/gui/src/m-editor/file-editor-tab.h b/gui/src/m-editor/file-editor-tab.h new file mode 100644 --- /dev/null +++ b/gui/src/m-editor/file-editor-tab.h @@ -0,0 +1,88 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FILEEDITORTAB_H +#define FILEEDITORTAB_H + +#include +#include +#include +#include + +class file_editor; +class file_editor_tab : public QWidget +{ + Q_OBJECT +public: + file_editor_tab (file_editor *fileEditor); + bool copy_available (); + +public slots: + void new_title(bool modified); + void handle_copy_available(bool enableCopy); + void handle_margin_clicked (int line, int margin, Qt::KeyboardModifiers state); + void comment_selected_text (); + void uncomment_selected_text (); + void remove_bookmark (); + void toggle_bookmark (); + void next_bookmark (); + void previous_bookmark (); + void cut (); + void copy (); + void paste (); + void undo (); + void redo (); + + void set_modified (bool modified = true); + + bool open_file (); + void load_file (QString fileName); + void new_file (); + bool save_file (); + bool save_file(QString saveFileName); + bool save_file_as(); + void run_file (); + + void file_has_changed (QString fileName); + +signals: + void file_name_changed (QString fileName); + void editor_state_changed (); + void close_request (); + +protected: + void closeEvent (QCloseEvent *event); + void set_file_name (QString fileName); + +private: + void update_tracked_file (); + int check_file_modified (QString msg, int cancelButton); + void do_comment_selected_text (bool comment); + + file_editor * _file_editor; + QsciScintilla * _edit_area; + + QString _file_name; + QString _file_name_short; + + bool _long_title; + bool _copy_available; + + QFileSystemWatcher _file_system_watcher; +}; + +#endif // FILEEDITORTAB_H diff --git a/gui/src/m-editor/file-editor.cc b/gui/src/m-editor/file-editor.cc new file mode 100644 --- /dev/null +++ b/gui/src/m-editor/file-editor.cc @@ -0,0 +1,506 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "file-editor.h" +#include +#include +#include +#include +#include +#include +#include +#include + +file_editor::file_editor (QTerminal *terminal, main_window *mainWindow) + : file_editor_interface(terminal, mainWindow) +{ + construct (); + + _terminal = terminal; + _main_window = mainWindow; + setVisible (false); +} + +file_editor::~file_editor () +{ +} + +lexer_octave_gui * +file_editor::lexer () +{ + return _lexer; +} + +QTerminal * +file_editor::terminal () +{ + return _terminal; +} + +main_window * +file_editor::mainWindow () +{ + return _main_window; +} + +void +file_editor::request_new_file () +{ + file_editor_tab *fileEditorTab = new file_editor_tab (this); + if (fileEditorTab) + { + add_file_editor_tab (fileEditorTab); + fileEditorTab->new_file (); + } +} + +void +file_editor::request_open_file () +{ + file_editor_tab *fileEditorTab = new file_editor_tab (this); + if (fileEditorTab) + { + add_file_editor_tab (fileEditorTab); + if (!fileEditorTab->open_file ()) + { + // If no file was loaded, remove the tab again. + _tab_widget->removeTab (_tab_widget->indexOf (fileEditorTab)); + } + } +} + +void +file_editor::request_open_file (QString fileName) +{ + if (!isVisible ()) + { + show (); + } + + file_editor_tab *fileEditorTab = new file_editor_tab (this); + if (fileEditorTab) + { + add_file_editor_tab (fileEditorTab); + fileEditorTab->load_file (fileName); + } +} + +void +file_editor::handle_entered_debug_mode () +{ + +} + +void +file_editor::handle_quit_debug_mode () +{ + +} + +void +file_editor::request_undo () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->undo (); +} + +void +file_editor::request_redo () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->redo (); +} + +void +file_editor::request_copy () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->copy (); +} + +void +file_editor::request_cut () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->cut (); +} + +void +file_editor::request_paste () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->paste (); +} + +void +file_editor::request_save_file () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->save_file (); +} + +void +file_editor::request_save_file_as () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->save_file_as (); +} + +void +file_editor::request_run_file () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->run_file (); +} + +void +file_editor::request_toggle_bookmark () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->toggle_bookmark (); +} + +void +file_editor::request_next_bookmark () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->next_bookmark (); +} + +void +file_editor::request_previous_bookmark () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->previous_bookmark (); +} + +void +file_editor::request_remove_bookmark () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->remove_bookmark (); +} + +void +file_editor::request_comment_selected_text () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->comment_selected_text (); +} + +void +file_editor::request_uncomment_selected_text () +{ + file_editor_tab *activeFileEditorTab = active_editor_tab (); + if (activeFileEditorTab) + activeFileEditorTab->uncomment_selected_text (); +} + +void +file_editor::handle_file_name_changed (QString fileName) +{ + QObject *senderObject = sender (); + file_editor_tab *fileEditorTab = dynamic_cast (senderObject); + if (fileEditorTab) + { + for(int i = 0; i < _tab_widget->count (); i++) + { + if (_tab_widget->widget (i) == fileEditorTab) + { + _tab_widget->setTabText (i, fileName); + } + } + } +} + +void +file_editor::handle_tab_close_request (int index) +{ + file_editor_tab *fileEditorTab = dynamic_cast (_tab_widget->widget (index)); + if (fileEditorTab) + if (fileEditorTab->close ()) + { + _tab_widget->removeTab (index); + delete fileEditorTab; + } +} + +void +file_editor::handle_tab_close_request () +{ + file_editor_tab *fileEditorTab = dynamic_cast (sender ()); + if (fileEditorTab) + if (fileEditorTab->close ()) + { + _tab_widget->removeTab (_tab_widget->indexOf (fileEditorTab)); + delete fileEditorTab; + } +} + +void +file_editor::active_tab_changed (int index) +{ + Q_UNUSED (index); + handle_editor_state_changed (); +} + +void +file_editor::handle_editor_state_changed () +{ + file_editor_tab *f = active_editor_tab (); + if (f) + { + bool copy_available = f->copy_available (); + _copy_action->setEnabled (copy_available); + _cut_action->setEnabled (copy_available); + } +} + +void +file_editor::construct () +{ + QWidget *widget = new QWidget (this); + QSettings *settings = resource_manager::instance ()->get_settings (); + QStyle *style = QApplication::style (); + + _menu_bar = new QMenuBar (widget); + _tool_bar = new QToolBar (widget); + _tab_widget = new QTabWidget (widget); + _tab_widget->setTabsClosable (true); + + // Theme icons with QStyle icons as fallback + QAction *new_action = new QAction (QIcon(":/actions/icons/filenew.png"), + tr("&New File"), _tool_bar); + + QAction *open_action = new QAction (QIcon(":/actions/icons/fileopen.png"), + tr("&Open File"), _tool_bar); + + QAction *save_action = new QAction (QIcon(":/actions/icons/filesave.png"), + tr("&Save File"), _tool_bar); + + QAction *save_as_action = new QAction (QIcon(":/actions/icons/filesaveas.png"), + tr("Save File &As"), _tool_bar); + + QAction *undo_action = new QAction (QIcon(":/actions/icons/undo.png"), + tr("&Undo"), _tool_bar); + + QAction *redo_action = new QAction (QIcon(":/actions/icons/redo.png"), + tr("&Redo"), _tool_bar); + + _copy_action = new QAction (QIcon::fromTheme ("edit-copy"), tr ("&Copy"), _tool_bar); + _cut_action = new QAction (QIcon::fromTheme ("edit-cut"), tr ("Cu&t"), _tool_bar); + + QAction *paste_action + = new QAction (QIcon (":/actions/icons/editpaste.png"), + tr("Paste"), _tool_bar); + QAction *next_bookmark_action = new QAction (tr ("&Next Bookmark"),_tool_bar); + QAction *previous_bookmark_action = new QAction (tr ("Pre&vious Bookmark"),_tool_bar); + QAction *toggle_bookmark_action = new QAction (tr ("Toggle &Bookmark"),_tool_bar); + QAction *remove_bookmark_action = new QAction (tr ("&Remove All Bookmarks"),_tool_bar); + QAction *comment_selection_action = new QAction (tr ("&Comment Selected Text"),_tool_bar); + QAction *uncomment_selection_action = new QAction (tr ("&Uncomment Selected Text"),_tool_bar); + + QAction *run_action = new QAction (QIcon(":/actions/icons/artsbuilderexecute.png"), + tr("&Run File"), _tool_bar); + + // some actions are disabled from the beginning + _copy_action->setEnabled(false); + _cut_action->setEnabled(false); + + // short cuts + new_action->setShortcut (QKeySequence::New); + new_action->setShortcutContext (Qt::WidgetShortcut); + open_action->setShortcut (QKeySequence::Open); + open_action->setShortcutContext (Qt::WidgetShortcut); + save_action->setShortcut (QKeySequence::Save); + save_action->setShortcutContext (Qt::WidgetShortcut); + save_as_action->setShortcut (QKeySequence::SaveAs); + save_as_action->setShortcutContext (Qt::WidgetShortcut); + undo_action->setShortcut (QKeySequence::Undo); + undo_action->setShortcutContext (Qt::WidgetShortcut); + redo_action->setShortcut (QKeySequence::Redo); + redo_action->setShortcutContext (Qt::WidgetShortcut); + _copy_action->setShortcut (QKeySequence::Copy); + _copy_action->setShortcutContext (Qt::WidgetShortcut); + _cut_action->setShortcut (QKeySequence::Cut); + _cut_action->setShortcutContext (Qt::WidgetShortcut); + paste_action->setShortcut (QKeySequence::Paste); + paste_action->setShortcutContext (Qt::WidgetShortcut); + run_action->setShortcut (Qt::Key_F5); + run_action->setShortcutContext (Qt::WidgetShortcut); + next_bookmark_action->setShortcut (Qt::Key_F2); + next_bookmark_action->setShortcutContext (Qt::WidgetShortcut); + previous_bookmark_action->setShortcut (Qt::SHIFT + Qt::Key_F2); + previous_bookmark_action->setShortcutContext (Qt::WidgetShortcut); + toggle_bookmark_action->setShortcut (Qt::Key_F7); + toggle_bookmark_action->setShortcutContext (Qt::WidgetShortcut); + comment_selection_action->setShortcut (Qt::CTRL + Qt::Key_R); + comment_selection_action->setShortcutContext (Qt::WidgetShortcut); + uncomment_selection_action->setShortcut (Qt::CTRL + Qt::Key_T); + uncomment_selection_action->setShortcutContext(Qt::WidgetShortcut); + + // toolbar + _tool_bar->addAction (new_action); + _tool_bar->addAction (open_action); + _tool_bar->addAction (save_action); + _tool_bar->addAction (save_as_action); + _tool_bar->addSeparator (); + _tool_bar->addAction (undo_action); + _tool_bar->addAction (redo_action); + _tool_bar->addAction (_copy_action); + _tool_bar->addAction (_cut_action); + _tool_bar->addAction (paste_action); + _tool_bar->addSeparator (); + _tool_bar->addAction (run_action); + + // menu bar + QMenu *fileMenu = new QMenu (tr ("&File"), _menu_bar); + fileMenu->addAction (new_action); + fileMenu->addAction (open_action); + fileMenu->addAction (save_action); + fileMenu->addAction (save_as_action); + fileMenu->addSeparator (); + _menu_bar->addMenu (fileMenu); + + QMenu *editMenu = new QMenu (tr ("&Edit"), _menu_bar); + editMenu->addAction (undo_action); + editMenu->addAction (redo_action); + editMenu->addSeparator (); + editMenu->addAction (_copy_action); + editMenu->addAction (_cut_action); + editMenu->addAction (paste_action); + editMenu->addSeparator (); + editMenu->addAction (comment_selection_action); + editMenu->addAction (uncomment_selection_action); + editMenu->addSeparator (); + editMenu->addAction (toggle_bookmark_action); + editMenu->addAction (next_bookmark_action); + editMenu->addAction (previous_bookmark_action); + editMenu->addAction (remove_bookmark_action); + _menu_bar->addMenu (editMenu); + + _debug_menu = new QMenu (tr ("&Debug"), _menu_bar); + QAction * debug_continue = _debug_menu->addAction (tr ("Continue")); + debug_continue->setShortcut (Qt::Key_F5); + QAction * debug_step_into = _debug_menu->addAction (tr ("Step into")); + debug_step_into->setShortcut (Qt::Key_F9); + QAction * debug_step_over = _debug_menu->addAction (tr ("Next")); + debug_step_over->setShortcut (Qt::Key_F10); + QAction * debug_step_out = _debug_menu->addAction (tr ("Step out")); + debug_step_out->setShortcut (Qt::Key_F11); + _debug_menu->addSeparator (); + QAction * debug_quit = _debug_menu->addAction (tr ("Quit")); + debug_quit->setShortcut (Qt::Key_Escape); + _menu_bar->addMenu (_debug_menu); + + QMenu *runMenu = new QMenu (tr ("&Run"), _menu_bar); + runMenu->addAction (run_action); + _menu_bar->addMenu (runMenu); + + QVBoxLayout *layout = new QVBoxLayout (); + layout->addWidget (_menu_bar); + layout->addWidget (_tool_bar); + layout->addWidget (_tab_widget); + layout->setMargin (0); + widget->setLayout (layout); + setWidget (widget); + + connect (new_action, SIGNAL (triggered ()), this, SLOT (request_new_file ())); + connect (open_action, SIGNAL (triggered ()), this, SLOT (request_open_file ())); + connect (undo_action, SIGNAL (triggered ()), this, SLOT (request_undo ())); + connect (redo_action, SIGNAL (triggered ()), this, SLOT (request_redo ())); + connect (_copy_action, SIGNAL (triggered ()), this, SLOT (request_copy ())); + connect (_cut_action, SIGNAL (triggered ()), this, SLOT (request_cut ())); + connect (paste_action, SIGNAL (triggered ()), this, SLOT (request_paste ())); + connect (save_action, SIGNAL (triggered ()), this, SLOT (request_save_file ())); + connect (save_as_action, SIGNAL (triggered ()), this, SLOT (request_save_file_as ())); + connect (run_action, SIGNAL (triggered ()), this, SLOT (request_run_file ())); + connect (toggle_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_toggle_bookmark ())); + connect (next_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_next_bookmark ())); + connect (previous_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_previous_bookmark ())); + connect (remove_bookmark_action, SIGNAL (triggered ()), this, SLOT (request_remove_bookmark ())); + connect (comment_selection_action, SIGNAL (triggered ()), this, SLOT (request_comment_selected_text ())); + connect (uncomment_selection_action, SIGNAL (triggered ()), this, SLOT (request_uncomment_selected_text ())); + connect (_tab_widget, SIGNAL (tabCloseRequested (int)), this, SLOT (handle_tab_close_request (int))); + connect (_tab_widget, SIGNAL (currentChanged(int)), this, SLOT (active_tab_changed (int))); + + // this has to be done only once, not for each editor + _lexer = new lexer_octave_gui (); + + // Editor font (default or from settings) + _lexer->setDefaultFont (QFont ( + settings->value ("editor/fontName","Courier").toString (), + settings->value ("editor/fontSize",10).toInt ())); + + // TODO: Autoindent not working as it should + _lexer->setAutoIndentStyle (QsciScintilla::AiMaintain || + QsciScintilla::AiOpening || + QsciScintilla::AiClosing); + + // The API info that is used for auto completion + // TODO: Where to store a file with API info (raw or prepared?)? + // TODO: Also provide infos on octave-forge functions? + // TODO: Also provide infos on function parameters? + // By now, use the keywords-list from syntax highlighting + _lexer_api = new QsciAPIs (_lexer); + + QString keyword; + QStringList keywordList; + keyword = _lexer->keywords (1); // get whole string with all keywords + keywordList = keyword.split (QRegExp ("\\s+")); // split into single strings + int i; + for (i = 0; i < keywordList.size (); i++) + { + _lexer_api->add (keywordList.at (i)); // add single strings to the API + } + _lexer_api->prepare (); // prepare API info ... this make take some time + resize (500, 400); + setWindowIcon (QIcon::fromTheme ("accessories-text-editor", style->standardIcon (QStyle::SP_FileIcon))); + setWindowTitle ("Octave Editor"); +} + +void +file_editor::add_file_editor_tab (file_editor_tab *f) +{ + _tab_widget->addTab (f, ""); + connect (f, SIGNAL (file_name_changed(QString)), + this, SLOT(handle_file_name_changed(QString))); + connect (f, SIGNAL (editor_state_changed ()), + this, SLOT (handle_editor_state_changed ())); + connect (f, SIGNAL (close_request ()), + this, SLOT (handle_tab_close_request ())); + _tab_widget->setCurrentWidget (f); +} + +file_editor_tab * +file_editor::active_editor_tab () +{ + return dynamic_cast (_tab_widget->currentWidget ()); +} diff --git a/gui/src/m-editor/file-editor.h b/gui/src/m-editor/file-editor.h new file mode 100644 --- /dev/null +++ b/gui/src/m-editor/file-editor.h @@ -0,0 +1,102 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FILEEDITORMDISUBWINDOW_H +#define FILEEDITORMDISUBWINDOW_H + +#include "main-window.h" +#include "file-editor-interface.h" +#include "file-editor-tab.h" + +#include +#include +#include +#include +#include +#include +#include +// Not available in the Debian repos yet! +// #include +#include "lexer-octave-gui.h" + +const char UNNAMED_FILE[] = ""; +const char SAVE_FILE_FILTER[] = "Octave Files (*.m);;All Files (*.*)"; +enum MARKER + { + MARKER_BOOKMARK, + MARKER_BREAKPOINT + }; + +class file_editor : public file_editor_interface +{ +Q_OBJECT + +public: + file_editor (QTerminal *terminal, main_window *mainWindow); + ~file_editor (); + void loadFile (QString fileName); + + lexer_octave_gui *lexer (); + QTerminal * terminal (); + main_window * mainWindow (); + +public slots: + void request_new_file (); + void request_open_file (); + void request_open_file (QString fileName); + + void handle_entered_debug_mode (); + void handle_quit_debug_mode (); + + void request_undo (); + void request_redo (); + void request_copy (); + void request_cut (); + void request_paste (); + void request_save_file (); + void request_save_file_as (); + void request_run_file (); + void request_toggle_bookmark (); + void request_next_bookmark (); + void request_previous_bookmark (); + void request_remove_bookmark (); + void request_comment_selected_text (); + void request_uncomment_selected_text (); + + void handle_file_name_changed (QString fileName); + void handle_tab_close_request (int index); + void handle_tab_close_request (); + void active_tab_changed (int index); + void handle_editor_state_changed (); + +private: + void construct (); + void add_file_editor_tab(file_editor_tab *f); + file_editor_tab *active_editor_tab(); + + QMenuBar * _menu_bar; + QToolBar * _tool_bar; + QMenu * _debug_menu; + QAction* _copy_action; + QAction* _cut_action; + QTabWidget * _tab_widget; + int _marker_bookmark; + lexer_octave_gui *_lexer; + QsciAPIs * _lexer_api; +}; + +#endif // FILEEDITORMDISUBWINDOW_H diff --git a/gui/src/m-editor/lexer-octave-gui.cc b/gui/src/m-editor/lexer-octave-gui.cc new file mode 100644 --- /dev/null +++ b/gui/src/m-editor/lexer-octave-gui.cc @@ -0,0 +1,141 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "lexer-octave-gui.h" +#include +#include + +// ----------------------------------------------------- +// Some basic functions +// ----------------------------------------------------- +lexer_octave_gui::lexer_octave_gui(QObject *parent) + : QsciLexer(parent) // inherit from base lexer +{ +} + +lexer_octave_gui::~lexer_octave_gui() +{ +} + +const char *lexer_octave_gui::language() const +{ + return "Octave"; // return the name of the language +} + +const char *lexer_octave_gui::lexer() const +{ + return "octave"; // return the name of the lexer +} + +// ----------------------------------------------------- +// The colors for syntax highlighting +// ----------------------------------------------------- +QColor lexer_octave_gui::defaultColor(int style) const +{ + switch (style) + { + case Default: // black + return QColor(0x00,0x00,0x00); + case Operator: // red + return QColor(0xef,0x00,0x00); + case Comment: // gray + return QColor(0x7f,0x7f,0x7f); + case Command: // blue-green + return QColor(0x00,0x7f,0x7f); + case Number: // orange + return QColor(0x7f,0x7f,0x00); + case Keyword: // blue + return QColor(0x00,0x00,0xbf); + case SingleQuotedString: // green + return QColor(0x00,0x7f,0x00); + case DoubleQuotedString: // green-yellow + return QColor(0x4f,0x7f,0x00); + } + return QsciLexer::defaultColor(style); +} + + +// ----------------------------------------------------- +// The font decorations for highlighting +// ----------------------------------------------------- +QFont lexer_octave_gui::defaultFont(int style) const +{ + QFont f; + + switch (style) + { + case Comment: // default but italic + f = QsciLexer::defaultFont(style); + f.setItalic(true); + break; + case Keyword: // default + f = QsciLexer::defaultFont(style); + break; + case Operator: // default + f = QsciLexer::defaultFont(style); + break; + default: // default + f = QsciLexer::defaultFont(style); + break; + } + return f; // return the selected font +} + + +// ----------------------------------------------------- +// Style names +// ----------------------------------------------------- +QString lexer_octave_gui::description(int style) const +{ + switch (style) + { + case Default: + return tr("Default"); + case Comment: + return tr("Comment"); + case Command: + return tr("Command"); + case Number: + return tr("Number"); + case Keyword: + return tr("Keyword"); + case SingleQuotedString: + return tr("Single-quoted string"); + case Operator: + return tr("Operator"); + case Identifier: + return tr("Identifier"); + case DoubleQuotedString: + return tr("Double-quoted string"); + } + return QString(); +} + + +// ----------------------------------------------------- +// The set of keywords for highlighting +// TODO: How to define a second set? +// ----------------------------------------------------- +const char *lexer_octave_gui::keywords(int set) const +{ + if (set == 1) + { + return resource_manager::instance ()->octave_keywords (); + } + return 0; +} + diff --git a/gui/src/m-editor/lexer-octave-gui.h b/gui/src/m-editor/lexer-octave-gui.h new file mode 100644 --- /dev/null +++ b/gui/src/m-editor/lexer-octave-gui.h @@ -0,0 +1,60 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef LEXEROCTAVE_H +#define LEXEROCTAVE_H + +#include "resource-manager.h" +#include +#include +#include + + +class lexer_octave_gui : public QsciLexer +{ + Q_OBJECT + +public: + // the used styles + enum + { + Default = 0, + Comment = 1, + Command = 2, + Number = 3, + Keyword = 4, + SingleQuotedString = 5, + Operator = 6, + Identifier = 7, + DoubleQuotedString = 8 + }; + + lexer_octave_gui (QObject *parent = 0); + virtual ~lexer_octave_gui (); + const char *language () const; + const char *lexer () const; + QColor defaultColor (int style) const; + QFont defaultFont (int style) const; + const char *keywords (int set) const; + QString description (int style) const; + +private: + lexer_octave_gui (const lexer_octave_gui &); + lexer_octave_gui &operator= (const lexer_octave_gui &); +}; + +#endif diff --git a/gui/src/main-window.cc b/gui/src/main-window.cc new file mode 100644 --- /dev/null +++ b/gui/src/main-window.cc @@ -0,0 +1,572 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main-window.h" +#include "file-editor.h" +#include "settings-dialog.h" + +main_window::main_window (QWidget * parent) + : QMainWindow (parent), octave_event_observer () +{ + // We have to set up all our windows, before we finally launch octave. + construct (); + octave_link::instance ()->launch_octave(); +} + +main_window::~main_window () +{ +} + +void +main_window::event_accepted (octave_event *e) +{ + delete e; +} + +void +main_window::event_reject (octave_event *e) +{ + delete e; +} + +void +main_window::new_file () +{ + _file_editor->request_new_file (); +} + +void +main_window::open_file () +{ + _file_editor->request_open_file (); +} + +void +main_window::report_status_message (QString statusMessage) +{ + _status_bar->showMessage (statusMessage, 1000); +} + +void +main_window::handle_save_workspace_request () +{ + QString selectedFile = + QFileDialog::getSaveFileName (this, tr ("Save Workspace"), + resource_manager::instance ()->get_home_path ()); + _terminal->sendText (QString ("save \'%1\'\n").arg (selectedFile)); + _terminal->setFocus (); +} + +void +main_window::handle_load_workspace_request () +{ + QString selectedFile = + QFileDialog::getOpenFileName (this, tr ("Load Workspace"), + resource_manager::instance ()->get_home_path ()); + if (!selectedFile.isEmpty ()) + { + _terminal->sendText (QString ("load \'%1\'\n").arg (selectedFile)); + _terminal->setFocus (); + } +} + +void +main_window::handle_clear_workspace_request () +{ + _terminal->sendText ("clear\n"); + _terminal->setFocus (); +} + +void +main_window::handle_command_double_clicked (QString command) +{ + _terminal->sendText(command); + _terminal->setFocus (); +} + +void +main_window::open_bug_tracker_page () +{ + QDesktopServices::openUrl (QUrl ("http://savannah.gnu.org/bugs/?group=octave")); +} + +void +main_window::open_agora_page () +{ + QDesktopServices::openUrl (QUrl ("http://agora.panocha.org.mx/")); +} + +void +main_window::open_octave_forge_page () +{ + QDesktopServices::openUrl (QUrl ("http://octave.sourceforge.net/")); +} + +void +main_window::process_settings_dialog_request () +{ + settings_dialog *settingsDialog = new settings_dialog (this); + settingsDialog->exec (); + delete settingsDialog; + emit settings_changed (); + resource_manager::instance ()->update_network_settings (); + notice_settings(); +} + +void +main_window::notice_settings () +{ + // Set terminal font: + QSettings *settings = resource_manager::instance ()->get_settings (); + QFont font = QFont(); + font.setFamily(settings->value("terminal/fontName").toString()); + font.setPointSize(settings->value("terminal/fontSize").toInt ()); + _terminal->setTerminalFont(font); +} + +void +main_window::prepare_for_quit () +{ + write_settings (); +} + +void +main_window::reset_windows () +{ + // TODO: Implement. +} + +void +main_window::update_current_working_directory (QString directory) +{ + if (_current_directory_combo_box->count () > 31) + { + _current_directory_combo_box->removeItem (0); + } + _current_directory_combo_box->addItem (directory); + int index = _current_directory_combo_box->findText (directory); + _current_directory_combo_box->setCurrentIndex (index); +} + +void +main_window::change_current_working_directory () +{ + QString selectedDirectory = + QFileDialog::getExistingDirectory(this, tr ("Set working direcotry")); + + if (!selectedDirectory.isEmpty ()) + { + octave_link::instance () + ->post_event (new octave_change_directory_event (*this, + selectedDirectory.toStdString ())); + } +} + +void +main_window::change_current_working_directory (QString directory) +{ + octave_link::instance () + ->post_event (new octave_change_directory_event (*this, + directory.toStdString ())); +} + +void +main_window::current_working_directory_up () +{ + _terminal->sendText ("cd ..\n"); + _terminal->setFocus (); +} + + +void +main_window::handle_entered_debug_mode () +{ + setWindowTitle ("Octave (Debugging)"); + _file_editor->handle_entered_debug_mode (); + _debug_menu->setEnabled (true); +} + +void +main_window::handle_quit_debug_mode () +{ + setWindowTitle ("Octave"); + _file_editor->handle_quit_debug_mode (); + _debug_menu->setEnabled (false); +} + +void +main_window::debug_continue () +{ + octave_link::instance () + ->post_event (new octave_debug_continue_event (*this)); +} + +void +main_window::debug_step_into () +{ + octave_link::instance () + ->post_event (new octave_debug_step_into_event (*this)); +} + +void +main_window::debug_step_over () +{ + octave_link::instance () + ->post_event (new octave_debug_step_over_event (*this)); +} + +void +main_window::debug_step_out () +{ + octave_link::instance () + ->post_event (new octave_debug_step_out_event (*this)); +} + +void +main_window::debug_quit () +{ + octave_link::instance () + ->post_event (new octave_debug_quit_event (*this)); +} + +void +main_window::update_performance_information () +{ + octave_link::performance_information p + = octave_link::instance ()->get_performance_information (); + + int generate_events_msec + = (p.generate_events_stop - p.generate_events_start) * 1000 / CLOCKS_PER_SEC; + + int process_events_msec + = (p.process_events_stop - p.process_events_start) * 1000 / CLOCKS_PER_SEC; + + _status_bar->showMessage + (QString ("CPU time of the GUI in octave thread - generating rx events: ~%1 ms - processing tx events: ~%2 ms (%3 events)") + .arg (generate_events_msec) + .arg (process_events_msec) + .arg (p.event_queue_size)); +} + +void +main_window::show_about_octave () +{ + QString message = + "GNU Octave\n" + "Copyright (C) 2009 John W. Eaton and others.\n" + "This is free software; see the source code for copying conditions." + "There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or" + "FITNESS FOR A PARTICULAR PURPOSE. For details, type `warranty'.\n" + "\n" + "Octave was configured for \"x86_64-pc-linux-gnu\".\n" + "\n" + "Additional information about Octave is available at http://www.octave.org.\n" + "\n" + "Please contribute if you find this software useful." + "For more information, visit http://www.octave.org/help-wanted.html\n" + "\n" + "Report bugs to (but first, please read" + "http://www.octave.org/bugs.html to learn how to write a helpful report).\n" + "\n" + "For information about changes from previous versions, type `news'.\n"; + + QMessageBox::about (this, tr ("About Octave"), message); +} + +void +main_window::closeEvent (QCloseEvent * closeEvent) +{ + closeEvent->ignore (); + octave_link::instance ()->post_event (new octave_exit_event (*this)); + } + +void +main_window::read_settings () +{ + QSettings *settings = resource_manager::instance ()->get_settings (); + restoreGeometry (settings->value ("MainWindow/geometry").toByteArray ()); + restoreState (settings->value ("MainWindow/windowState").toByteArray ()); + emit settings_changed (); +} + +void +main_window::write_settings () +{ + QSettings *settings = resource_manager::instance ()->get_settings (); + settings->setValue ("MainWindow/geometry", saveGeometry ()); + settings->setValue ("MainWindow/windowState", saveState ()); + settings->sync (); +} + +void +main_window::construct () +{ + _closing = false; // flag for editor files when closed + setWindowIcon (resource_manager::instance ()->get_icon (resource_manager::octave)); + + // Setup dockable widgets and the status bar. + _workspace_view = new workspace_view (this); + _workspace_view->setStatusTip (tr ("View the variables in the active workspace.")); + _history_dock_widget = new history_dock_widget (this); + _history_dock_widget->setStatusTip (tr ("Browse and search the command history.")); + _files_dock_widget = new files_dock_widget (this); + _files_dock_widget->setStatusTip (tr ("Browse your files.")); + _status_bar = new QStatusBar (this); + + _current_directory_combo_box = new QComboBox (this); + _current_directory_combo_box->setFixedWidth (300); + _current_directory_combo_box->setEditable (true); + _current_directory_combo_box->setInsertPolicy (QComboBox::InsertAtTop); + _current_directory_combo_box->setMaxVisibleItems (14); + + _current_directory_tool_button = new QToolButton (this); + _current_directory_tool_button->setIcon (QIcon(":/actions/icons/search.png")); + + _current_directory_up_tool_button = new QToolButton (this); + _current_directory_up_tool_button->setIcon (QIcon(":/actions/icons/up.png")); + + // Octave Terminal subwindow. + _terminal = new QTerminal (this); + _terminal->setObjectName ("OctaveTerminal"); + _terminal_dock_widget = new terminal_dock_widget (_terminal, this); + + QWidget *dummyWidget = new QWidget (); + dummyWidget->setObjectName ("CentralDummyWidget"); + dummyWidget->resize (10, 10); + dummyWidget->setSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum); + dummyWidget->hide (); + setCentralWidget (dummyWidget); + + _file_editor = new file_editor (_terminal, this); + + QMenu *file_menu = menuBar ()->addMenu (tr ("&File")); + QAction *new_file_action + = file_menu->addAction (QIcon(":/actions/icons/filenew.png"), tr ("New File")); + + QAction *open_file_action + = file_menu->addAction (QIcon(":/actions/icons/fileopen.png"), tr ("Open File")); + + QAction *settings_action + = file_menu->addAction (QIcon(":/actions/icons/configure.png"), tr ("Settings")); + file_menu->addSeparator (); + QAction *exit_action = file_menu->addAction (tr ("Exit")); + + QMenu *edit_menu = menuBar ()->addMenu (tr ("&Edit")); + QAction *cut_action + = edit_menu->addAction (QIcon(":/actions/icons/editcut.png"), tr ("Cut")); + cut_action->setShortcut (QKeySequence::Cut); + + QAction *copy_action + = edit_menu->addAction (QIcon(":/actions/icons/editcopy.png"), tr ("Copy")); + copy_action->setShortcut (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_C); + + QAction *paste_action + = edit_menu->addAction (QIcon(":/actions/icons/editpaste.png"), tr ("Paste")); + paste_action->setShortcut (Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_V); + + QAction *undo_action + = edit_menu->addAction (QIcon(":/actions/icons/undo.png"), tr ("Undo")); + undo_action->setShortcut (QKeySequence::Undo); + + QAction *redo_action + = edit_menu->addAction (QIcon(":/actions/icons/redo.png"), tr ("Redo")); + redo_action->setShortcut (QKeySequence::Redo); + + _debug_menu = menuBar ()->addMenu (tr ("De&bug")); + QAction * debug_continue = _debug_menu->addAction (tr ("Continue")); + debug_continue->setShortcut (Qt::Key_F5); + QAction * debug_step_into = _debug_menu->addAction (tr ("Step into")); + debug_step_into->setShortcut (Qt::Key_F9); + QAction * debug_step_over = _debug_menu->addAction (tr ("Next")); + debug_step_over->setShortcut (Qt::Key_F10); + QAction * debug_step_out = _debug_menu->addAction (tr ("Step out")); + debug_step_out->setShortcut (Qt::Key_F11); + _debug_menu->addSeparator (); + QAction * debug_quit = _debug_menu->addAction (tr ("Quit")); + debug_quit->setShortcut (Qt::Key_Escape); + _debug_menu->setEnabled (false); + + + //QMenu *parallelMenu = menuBar ()->addMenu (tr ("&Parallel")); + + QMenu * desktop_menu = menuBar ()->addMenu (tr ("&Desktop")); + QAction * load_workspace_action = desktop_menu->addAction (tr ("Load workspace")); + QAction * save_workspace_action = desktop_menu->addAction (tr ("Save workspace")); + QAction * clear_workspace_action = desktop_menu->addAction (tr ("Clear workspace")); + + // Window menu + QMenu * window_menu = menuBar ()->addMenu (tr ("&Window")); + QAction * show_command_window_action = window_menu->addAction (tr ("Command Window")); + show_command_window_action->setCheckable (true); + QAction * show_workspace_action = window_menu->addAction (tr ("Workspace")); + show_workspace_action->setCheckable (true); + QAction * show_history_action = window_menu->addAction (tr ("Command History")); + show_history_action->setCheckable (true); + QAction * show_file_browser_action = window_menu->addAction (tr ("Current Directory")); + show_file_browser_action->setCheckable (true); + QAction * show_editor_action = window_menu->addAction (tr ("Editor")); + show_editor_action->setCheckable (true); + window_menu->addSeparator (); + QAction * reset_windows_action = window_menu->addAction (tr ("Reset Windows")); + + // Help menu + QMenu * help_menu = menuBar ()->addMenu (tr ("&Help")); + QAction * report_bug_action = help_menu->addAction (tr ("Report Bug")); + QAction * agora_action = help_menu->addAction (tr ("Visit Agora")); + QAction * octave_forge_action = help_menu->addAction (tr ("Visit Octave Forge")); + help_menu->addSeparator (); + QAction * about_octave_action = help_menu->addAction (tr ("About Octave")); + + // Toolbars + QToolBar *main_tool_bar = addToolBar ("Main"); + main_tool_bar->addAction (new_file_action); + main_tool_bar->addAction (open_file_action); + main_tool_bar->addSeparator (); + main_tool_bar->addAction (cut_action); + main_tool_bar->addAction (copy_action); + main_tool_bar->addAction (paste_action); + main_tool_bar->addAction (undo_action); + main_tool_bar->addAction (redo_action); + main_tool_bar->addSeparator (); + main_tool_bar->addWidget (new QLabel (tr ("Current Directory:"))); + main_tool_bar->addWidget (_current_directory_combo_box); + main_tool_bar->addWidget (_current_directory_tool_button); + main_tool_bar->addWidget (_current_directory_up_tool_button); + + connect (qApp, SIGNAL (aboutToQuit ()), + this, SLOT (prepare_for_quit ())); + connect (settings_action, SIGNAL (triggered ()), + this, SLOT (process_settings_dialog_request ())); + connect (exit_action, SIGNAL (triggered ()), + this, SLOT (close ())); + connect (new_file_action, SIGNAL (triggered ()), + this, SLOT (new_file ())); + connect (open_file_action, SIGNAL (triggered ()), + this, SLOT (open_file ())); + connect (report_bug_action, SIGNAL (triggered ()), + this, SLOT (open_bug_tracker_page ())); + connect (agora_action, SIGNAL (triggered ()), + this, SLOT (open_agora_page ())); + connect (octave_forge_action, SIGNAL (triggered ()), + this, SLOT (open_octave_forge_page ())); + connect (about_octave_action, SIGNAL (triggered ()), + this, SLOT (show_about_octave ())); + connect (show_command_window_action, SIGNAL (toggled (bool)), + _terminal_dock_widget, SLOT (setVisible (bool))); + connect (_terminal_dock_widget, SIGNAL (active_changed (bool)), + show_command_window_action, SLOT (setChecked (bool))); + connect (show_workspace_action, SIGNAL (toggled (bool)), + _workspace_view, SLOT (setVisible (bool))); + connect (_workspace_view, SIGNAL (active_changed (bool)), + show_workspace_action, SLOT (setChecked (bool))); + connect (show_history_action, SIGNAL (toggled (bool)), + _history_dock_widget, SLOT (setVisible (bool))); + connect (_history_dock_widget, SIGNAL (active_changed (bool)), + show_history_action, SLOT (setChecked (bool))); + connect (show_file_browser_action, SIGNAL (toggled (bool)), + _files_dock_widget, SLOT (setVisible (bool))); + connect (_files_dock_widget, SIGNAL (active_changed (bool)), + show_file_browser_action, SLOT (setChecked (bool))); + connect (show_editor_action, SIGNAL (toggled (bool)), + _file_editor, SLOT (setVisible (bool))); + connect (_file_editor, SIGNAL (active_changed (bool)), + show_editor_action, SLOT (setChecked (bool))); + connect (reset_windows_action, SIGNAL (triggered ()), + this, SLOT (reset_windows ())); + connect (this, SIGNAL (settings_changed ()), + _files_dock_widget, SLOT (notice_settings ())); + connect (this, SIGNAL (settings_changed ()), + this, SLOT (notice_settings ())); + connect (_files_dock_widget, SIGNAL (open_file (QString)), + _file_editor, SLOT (request_open_file (QString))); + connect (_history_dock_widget, SIGNAL (information (QString)), + this, SLOT (report_status_message (QString))); + connect (_history_dock_widget, SIGNAL (command_double_clicked (QString)), + this, SLOT (handle_command_double_clicked (QString))); + connect (save_workspace_action, SIGNAL (triggered ()), + this, SLOT (handle_save_workspace_request ())); + connect (load_workspace_action, SIGNAL (triggered ()), + this, SLOT (handle_load_workspace_request ())); + connect (clear_workspace_action, SIGNAL (triggered ()), + this, SLOT (handle_clear_workspace_request ())); + connect (_current_directory_tool_button, SIGNAL (clicked ()), + this, SLOT (change_current_working_directory ())); + connect (_current_directory_up_tool_button, SIGNAL (clicked ()), + this, SLOT (current_working_directory_up())); + connect (copy_action, SIGNAL (triggered()), + _terminal, SLOT (copyClipboard ())); + connect (paste_action, SIGNAL (triggered()), + _terminal, SLOT (pasteClipboard ())); + connect (_current_directory_combo_box, SIGNAL (activated (QString)), + this, SLOT (change_current_working_directory (QString))); + connect (debug_continue, SIGNAL (triggered ()), + this, SLOT (debug_continue ())); + connect (debug_step_into, SIGNAL (triggered ()), + this, SLOT (debug_step_into ())); + connect (debug_step_over, SIGNAL (triggered ()), + this, SLOT (debug_step_over ())); + connect (debug_step_out, SIGNAL (triggered ()), + this, SLOT (debug_step_out ())); + connect (debug_quit, SIGNAL (triggered ()), + this, SLOT (debug_quit ())); + + setWindowTitle ("Octave"); + setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks); + addDockWidget (Qt::LeftDockWidgetArea, _workspace_view); + addDockWidget (Qt::LeftDockWidgetArea, _history_dock_widget); + addDockWidget (Qt::RightDockWidgetArea, _files_dock_widget); + addDockWidget (Qt::RightDockWidgetArea, _file_editor); + addDockWidget (Qt::BottomDockWidgetArea, _terminal_dock_widget); + setStatusBar (_status_bar); + read_settings (); + + _octave_qt_event_listener = new octave_qt_event_listener (); + octave_link::instance ()->register_event_listener (_octave_qt_event_listener); + + connect (_octave_qt_event_listener, + SIGNAL (current_directory_has_changed_signal (QString)), + this, + SLOT (update_current_working_directory (QString))); + + connect (_octave_qt_event_listener, + SIGNAL (entered_debug_mode_signal ()), + this, + SLOT(handle_entered_debug_mode ())); + + connect (_octave_qt_event_listener, + SIGNAL (quit_debug_mode_signal ()), + this, + SLOT (handle_quit_debug_mode ())); + + _update_performance_information_timer.setInterval (500); + _update_performance_information_timer.setSingleShot (false); + connect (&_update_performance_information_timer, SIGNAL (timeout ()), + this, SLOT (update_performance_information ())); + _update_performance_information_timer.start (); +} + diff --git a/gui/src/main-window.h b/gui/src/main-window.h new file mode 100644 --- /dev/null +++ b/gui/src/main-window.h @@ -0,0 +1,137 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Editor includes +#include "file-editor-interface.h" + +// QTerminal includes +#include "QTerminal.h" + +// Own includes +#include "resource-manager.h" +#include "octave-link.h" +#include "workspace-view.h" +#include "history-dockwidget.h" +#include "files-dockwidget.h" +#include "terminal-dockwidget.h" +#include "octave-qt-event-listener.h" +#include "octave-event-observer.h" + +/** + * \class MainWindow + * + * Represents the main window. + */ +class main_window + : public QMainWindow, public octave_event_observer +{ +Q_OBJECT public: + main_window (QWidget * parent = 0); + ~main_window (); + + void event_accepted (octave_event *e); + void event_reject (octave_event *e); + + QTerminal *get_terminal_view () { return _terminal; } + history_dock_widget *get_history_dock_widget () { return _history_dock_widget; } + files_dock_widget *get_files_dock_widget () { return _files_dock_widget; } + bool is_closing () { return _closing; } + +signals: + void settings_changed (); + +public slots: + void report_status_message (QString statusMessage); + void handle_save_workspace_request (); + void handle_load_workspace_request (); + void handle_clear_workspace_request (); + void handle_command_double_clicked (QString command); + void new_file (); + void open_file (); + void open_bug_tracker_page (); + void open_agora_page (); + void open_octave_forge_page (); + void process_settings_dialog_request (); + void show_about_octave (); + void notice_settings (); + void prepare_for_quit (); + void reset_windows (); + void update_current_working_directory (QString directory); + void change_current_working_directory (); + void change_current_working_directory (QString directory); + void current_working_directory_up (); + + void handle_entered_debug_mode (); + void handle_quit_debug_mode (); + void debug_continue (); + void debug_step_into (); + void debug_step_over (); + void debug_step_out (); + void debug_quit (); + + void update_performance_information (); + +protected: + void closeEvent (QCloseEvent * closeEvent); + void read_settings (); + void write_settings (); + +private: + void construct (); + void establish_octave_link (); + + QTerminal * _terminal; + file_editor_interface * _file_editor; + QMenu * _debug_menu; + QTimer _update_performance_information_timer; + + // Dock widgets. + workspace_view * _workspace_view; + history_dock_widget * _history_dock_widget; + files_dock_widget * _files_dock_widget; + terminal_dock_widget * _terminal_dock_widget; + + // Toolbars. + QStatusBar * _status_bar; + QComboBox * _current_directory_combo_box; + QToolButton * _current_directory_tool_button; + QToolButton * _current_directory_up_tool_button; + + octave_qt_event_listener *_octave_qt_event_listener; + + // Flag for closing whole application + bool _closing; +}; + +#endif // MAINWINDOW_H diff --git a/gui/src/msvc-debug.pri b/gui/src/msvc-debug.pri new file mode 100644 --- /dev/null +++ b/gui/src/msvc-debug.pri @@ -0,0 +1,24 @@ +# OctaveGUI - A graphical user interface for Octave +# Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +win32-msvc* { + CONFIG += release warn_off + QMAKE_CXXFLAGS += -MP + QMAKE_CXXFLAGS_RELEASE += -Zi + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_LFLAGS_RELEASE += -debug + QMAKE_CLEAN += $(DESTDIR)$(QMAKE_TARGET).pdb +} diff --git a/gui/src/msvc.pri b/gui/src/msvc.pri new file mode 100644 --- /dev/null +++ b/gui/src/msvc.pri @@ -0,0 +1,11 @@ +CONFIG += release + +QMAKE_CXXFLAGS += -MP +LIBDIR_SUFFIX = release + +msvc-debug { + QMAKE_CXXFLAGS_RELEASE += -Zi + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_LFLAGS_RELEASE += -debug + QMAKE_CLEAN += $(DESTDIR)$(QMAKE_TARGET).pdb +} diff --git a/gui/src/octave-adapter/octave-event-listener.h b/gui/src/octave-adapter/octave-event-listener.h new file mode 100644 --- /dev/null +++ b/gui/src/octave-adapter/octave-event-listener.h @@ -0,0 +1,36 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef OCTAVEEVENTLISTENER_H +#define OCTAVEEVENTLISTENER_H + +#include + +class octave_event_listener +{ + public: + octave_event_listener () { } + virtual ~octave_event_listener () { } + + virtual void current_directory_has_changed (std::string directory) = 0; + virtual void about_to_exit () = 0; + + virtual void entered_debug_mode () = 0; + virtual void quit_debug_mode () = 0; +}; + +#endif // OCTAVEEVENTLISTENER_H diff --git a/gui/src/octave-adapter/octave-event-observer.h b/gui/src/octave-adapter/octave-event-observer.h new file mode 100644 --- /dev/null +++ b/gui/src/octave-adapter/octave-event-observer.h @@ -0,0 +1,48 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef OCTAVEEVENTOBSERVER_H +#define OCTAVEEVENTOBSERVER_H + +class octave_event; + +/** + * \class octave_event_observer + * \brief Implements the observer part for the observer pattern. + */ +class octave_event_observer +{ + public: + octave_event_observer () { } + virtual ~octave_event_observer () { } + + /** + * This will be called when an event has been accepted. Operations + * in this routine will be processed in the octave thread. + */ + virtual void event_accepted (octave_event *e) = 0; + + /** + * This will be called when an event has been rejected. Operations + * in this routine will be processed in the octave thread. + */ + virtual void event_reject (octave_event *e) = 0; +}; + +#include "octave-event.h" + +#endif // OCTAVEEVENTOBSERVER_H diff --git a/gui/src/octave-adapter/octave-event.h b/gui/src/octave-adapter/octave-event.h new file mode 100644 --- /dev/null +++ b/gui/src/octave-adapter/octave-event.h @@ -0,0 +1,228 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef OCTAVEEVENT_H +#define OCTAVEEVENT_H + +#include +#include "octave-event-observer.h" +#include "oct-env.h" +#include "pt-eval.h" +#include "toplev.h" +#include "parse.h" +#include "debug.h" + +#include + +/** + * \class octave_event + * \brief Base class for an octave event. + * In order to make communication with octave threadsafe, comunication is + * implemented via events. An application may create events and post them, + * however there is no guarantee events will be processed in a given time. + * + * In order to create an event, there must be an event observer. The event + * observer will be given the opportunity to react on the event as soon as + * it has been processed in the octave thread. Accepting and ignoring takes + * places in the octave thread. + */ +class octave_event +{ + public: + octave_event (octave_event_observer& o) + : _octave_event_observer (o) + { } + + virtual ~octave_event () + { } + + /** Performs what is necessary to make this event happen. + * This code is thread-safe since it will be executed in the octave thread. + * However, you should take care to keep this code as short as possible. */ + virtual bool perform () = 0; + + /** + * Accepts this event. This allows the event observer to react properly + * onto the event. + */ + void accept () + { _octave_event_observer.event_accepted (this); } + + /** + * Rejects this event. This allows the event observer to react properly + * onto the event. + */ + void reject () + { _octave_event_observer.event_reject (this); } + + protected: + void call_octave_function (std::string name, + const octave_value_list& args = octave_value_list (), + int nargout = 0) + { + try + { + feval (name, args, nargout); + } catch (...) { } // Ignore exceptions. Crashes without that. + } + + void finish_readline_event () const + { + rl_line_buffer[0] = '\0'; + rl_point = rl_end = 0; + rl_done = 1; + //rl_forced_update_display (); + } + + private: + octave_event_observer& _octave_event_observer; +}; + +class octave_update_history_event : public octave_event +{ + public: + /** Creates a new octave_exit_event. */ + octave_update_history_event (octave_event_observer& o) + : octave_event (o) + { } + + bool perform () + { return true; /* Always grant. */ } +}; + +class octave_update_workspace_event : public octave_event +{ + public: + /** Creates a new octave_exit_event. */ + octave_update_workspace_event (octave_event_observer& o) + : octave_event (o) + { } + + bool perform () + { return true; /* Always grant. */ } +}; + +/** Implements an octave exit event. */ +class octave_exit_event : public octave_event +{ + public: + /** Creates a new octave_exit_event. */ + octave_exit_event (octave_event_observer& o) + : octave_event (o) + { } + + bool perform () + { clean_up_and_exit (0); return true; } +}; + +/** Implements a change directory events. */ +class octave_change_directory_event : public octave_event +{ + public: + /** Creates a new octave_change_directory_event. */ + octave_change_directory_event (octave_event_observer& o, + std::string directory) + : octave_event (o) + { _directory = directory; } + + bool perform () + { return octave_env::chdir (_directory); } + + private: + std::string _directory; +}; + +class octave_debug_step_into_event : public octave_event +{ + public: + /** Creates a new octave_debug_step_into_event. */ + octave_debug_step_into_event (octave_event_observer& o) + : octave_event (o) { } + + bool perform () + { + octave_value_list args; + args.append (octave_value ("in")); + call_octave_function ("dbstep", args); + finish_readline_event (); + return true; + } +}; + +class octave_debug_step_over_event : public octave_event +{ + public: + /** Creates a new octave_debug_step_over_event. */ + octave_debug_step_over_event (octave_event_observer& o) + : octave_event (o) { } + + bool perform () + { + call_octave_function ("dbnext"); + finish_readline_event (); + return true; + } +}; + +class octave_debug_step_out_event : public octave_event +{ + public: + /** Creates a new octave_debug_step_out_event. */ + octave_debug_step_out_event (octave_event_observer& o) + : octave_event (o) { } + + bool perform () + { + octave_value_list args; + args.append (octave_value ("out")); + call_octave_function ("dbstep", args); + finish_readline_event (); + return true; + } +}; + +class octave_debug_continue_event : public octave_event +{ + public: + /** Creates a new octave_debug_step_out_event. */ + octave_debug_continue_event (octave_event_observer& o) + : octave_event (o) { } + + bool perform () + { + call_octave_function ("dbcont"); + finish_readline_event (); + return true; + } +}; + +class octave_debug_quit_event : public octave_event +{ + public: + /** Creates a new octave_debug_step_out_event. */ + octave_debug_quit_event (octave_event_observer& o) + : octave_event (o) { } + + bool perform () + { + call_octave_function ("dbquit"); + finish_readline_event (); + return true; + } +}; + +#endif // OCTAVEEVENT_H diff --git a/gui/src/octave-adapter/octave-link.cc b/gui/src/octave-adapter/octave-link.cc new file mode 100644 --- /dev/null +++ b/gui/src/octave-adapter/octave-link.cc @@ -0,0 +1,164 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 John P. Swensen, Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "octave-link.h" +#include "load-path.h" + +int octave_readline_hook () +{ + octave_link::instance ()->entered_readline_hook (); + octave_link::instance ()->generate_events (); + octave_link::instance ()->process_events (); + octave_link::instance ()->finished_readline_hook (); + return 0; +} + +void octave_exit_hook (int status) +{ + (void) status; + octave_link::instance ()->about_to_exit (); +} + +octave_link octave_link::_singleton; + +octave_link::octave_link () +{ + _event_queue_mutex = new octave_mutex (); + _performance_information_mutex = new octave_mutex (); + _last_working_directory = ""; + _debugging_mode_active = false; +} + +octave_link::~octave_link () +{ +} + +void +octave_link::launch_octave () +{ + // Create both threads. + _octave_main_thread = new octave_main_thread (); + command_editor::add_event_hook (octave_readline_hook); + octave_exit = octave_exit_hook; + + // Start the first one. + _octave_main_thread->start (); +} + +void +octave_link::register_event_listener (octave_event_listener *oel) +{ _octave_event_listener = oel; } + +void +octave_link::generate_events () +{ + _next_performance_information.generate_events_start = clock (); + std::string current_working_directory = octave_env::get_current_directory (); + if (current_working_directory != _last_working_directory) + { + _last_working_directory = current_working_directory; + if (_octave_event_listener) + _octave_event_listener + ->current_directory_has_changed (_last_working_directory); + } + + if (_debugging_mode_active != Vdebugging) + { + _debugging_mode_active = Vdebugging; + if (_octave_event_listener) + { + if (_debugging_mode_active) + _octave_event_listener->entered_debug_mode (); + else + _octave_event_listener->quit_debug_mode (); + } + } + _next_performance_information.generate_events_stop = clock (); +} + +void +octave_link::process_events () +{ + _next_performance_information.process_events_start = clock (); + _event_queue_mutex->lock (); + _next_performance_information.event_queue_size = _event_queue.size (); + while (_event_queue.size () > 0) + { + octave_event * e = _event_queue.front (); + _event_queue.pop (); + if (e->perform ()) + e->accept (); + else + e->reject (); + } + _event_queue_mutex->unlock (); + _next_performance_information.process_events_stop = clock (); +} + +void +octave_link::post_event (octave_event *e) +{ + if (e) + { + _event_queue_mutex->lock (); + _event_queue.push (e); + _event_queue_mutex->unlock (); + } +} + +void +octave_link::event_accepted (octave_event *e) +{ delete e; } + +void +octave_link::event_reject (octave_event *e) +{ delete e; } + +void +octave_link::about_to_exit () +{ + _event_queue_mutex->lock (); + while (!_event_queue.empty ()) + _event_queue.pop (); + + _event_queue_mutex->unlock (); + + if (_octave_event_listener) + _octave_event_listener->about_to_exit (); +} + +void +octave_link::entered_readline_hook () +{ } + +void +octave_link::finished_readline_hook () +{ + _performance_information_mutex->lock (); + _performance_information = _next_performance_information; + _performance_information_mutex->unlock (); +} + +octave_link::performance_information +octave_link::get_performance_information () +{ + performance_information p; + _performance_information_mutex->lock (); + p = _performance_information; + _performance_information_mutex->unlock (); + return p; +} diff --git a/gui/src/octave-adapter/octave-link.h b/gui/src/octave-adapter/octave-link.h new file mode 100644 --- /dev/null +++ b/gui/src/octave-adapter/octave-link.h @@ -0,0 +1,140 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 John P. Swensen, Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef OCTAVELINK_H +#define OCTAVELINK_H + +// Octave includes +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef PACKAGE_URL +#include "octave/config.h" +#include "octave/cmd-edit.h" +#include "octave/error.h" +#include "octave/file-io.h" +#include "octave/input.h" +#include "octave/lex.h" +#include "octave/load-path.h" +#include "octave/octave.h" +#include "octave/oct-hist.h" +#include "octave/oct-map.h" +#include "octave/oct-obj.h" +#include "octave/ops.h" +#include "octave/ov.h" +#include "octave/ov-usr-fcn.h" +#include "octave/symtab.h" +#include "octave/pt.h" +#include "octave/pt-eval.h" +#include "octave/config.h" +#include "octave/Range.h" +#include "octave/toplev.h" +#include "octave/procstream.h" +#include "octave/sighandlers.h" +#include "octave/debug.h" +#include "octave/sysdep.h" +#include "octave/ov.h" +#include "octave/unwind-prot.h" +#include "octave/utils.h" +#include "octave/variables.h" +#include "oct-mutex.h" + +// Standard includes +#include +#include +#include +#include +#include +#include + +#include "octave-main-thread.h" +#include "octave-event.h" +#include "octave-event-observer.h" +#include "octave-event-listener.h" + +/** + * \class OctaveLink + * \brief Provides threadsafe access to octave. + * \author Jacob Dawid + * This class is a wrapper around octave and provides threadsafety by + * buffering access operations to octave and executing them in the readline + * event hook, which lives in the octave thread. + */ +class octave_link : public octave_event_observer +{ +public: + /** Provides a way to access the unique octave_link object. */ + static octave_link * instance () { return &_singleton; } + + typedef struct + { + clock_t generate_events_start; + clock_t generate_events_stop; + clock_t process_events_start; + clock_t process_events_stop; + int event_queue_size; + } performance_information; + + /** Starts octave. */ + void launch_octave (); + void register_event_listener (octave_event_listener *oel); + + void generate_events (); + void process_events (); + void post_event (octave_event *e); + void event_accepted (octave_event *e); + void event_reject (octave_event *e); + + void about_to_exit (); + + void entered_readline_hook (); + void finished_readline_hook (); + performance_information get_performance_information (); + +private: + /** Singleton. */ + octave_link (); + ~octave_link (); + + octave_event_listener *_octave_event_listener; + + /** Thread running octave_main. */ + octave_main_thread *_octave_main_thread; + + /** Semaphore to lock access to the event queue. */ + octave_mutex *_event_queue_mutex; + + /** Buffer for queueing events until they will be processed. */ + std::queue _event_queue; + + /** Stores the last known current working directory of octave. */ + std::string _last_working_directory; + bool _debugging_mode_active; + + /** Semaphore to lock access to the performance information. */ + octave_mutex *_performance_information_mutex; + + /** Stores performance data. */ + performance_information _next_performance_information; + performance_information _performance_information; + + /** Unique instance. Singelton! */ + static octave_link _singleton; +}; +#endif // OCTAVELINK_H diff --git a/gui/src/octave-adapter/octave-main-thread.cc b/gui/src/octave-adapter/octave-main-thread.cc new file mode 100644 --- /dev/null +++ b/gui/src/octave-adapter/octave-main-thread.cc @@ -0,0 +1,33 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "octave-main-thread.h" +#include "octave-link.h" + +octave_main_thread::octave_main_thread () : QThread () +{ +} + +void +octave_main_thread::run () +{ + setlocale(LC_ALL, "en_US.UTF-8"); + int argc = 1; + const char *argv[] = { "" }; + emit ready(); + octave_main (argc, (char **) argv, 0); +} diff --git a/gui/src/octave-adapter/octave-main-thread.h b/gui/src/octave-adapter/octave-main-thread.h new file mode 100644 --- /dev/null +++ b/gui/src/octave-adapter/octave-main-thread.h @@ -0,0 +1,44 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef OCTAVEMAINTHREAD_H +#define OCTAVEMAINTHREAD_H + +#include + +/** + * \class octave_main + * \brief This class represents a thread just running octave_main. + * \author Jacob Dawid + */ +class octave_main_thread : public QThread +{ + Q_OBJECT +public: + /** Creates a new thread running octave_main. */ + octave_main_thread (); + +signals: + /** This signal will be emitted when the thread is about to actually run octave_main. */ + void ready(); + +protected: + /** Runs octave_main. */ + void run (); +}; + +#endif // OCTAVEMAINTHREAD_H diff --git a/gui/src/octave-gui.cc b/gui/src/octave-gui.cc new file mode 100644 --- /dev/null +++ b/gui/src/octave-gui.cc @@ -0,0 +1,90 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include "welcome-wizard.h" +#include "resource-manager.h" +#include "main-window.h" + +int +main (int argc, char *argv[]) +{ + QApplication application (argc, argv); + while (true) + { + if (resource_manager::instance ()->is_first_run ()) + { + welcome_wizard welcomeWizard; + int returnCode = welcomeWizard.exec (); + + QSettings *settings = resource_manager::instance ()->get_settings (); + settings->setValue ("connectOnStartup", true); + settings->setValue ("showMessageOfTheDay", true); + settings->setValue ("showTopic", true); + settings->setValue ("autoIdentification", false); + settings->setValue ("nickServPassword", ""); + settings->setValue ("useCustomFileEditor", false); + settings->setValue ("customFileEditor", "emacs"); + settings->setValue ("editor/showLineNumbers", true); + settings->setValue ("editor/highlightCurrentLine", true); + settings->setValue ("editor/codeCompletion", true); + settings->setValue ("editor/fontName", "Monospace"); + settings->setValue ("editor/fontSize", 10); + settings->setValue ("editor/shortWindowTitle", true); + settings->setValue ("showFilenames", true); + settings->setValue ("showFileSize", false); + settings->setValue ("showFileType", false); + settings->setValue ("showLastModified", false); + settings->setValue ("showHiddenFiles", false); + settings->setValue ("useAlternatingRowColors", true); + settings->setValue ("useProxyServer", false); + settings->setValue ("proxyType", "Sock5Proxy"); + settings->setValue ("proxyHostName", "none"); + settings->setValue ("proxyPort", 8080); + settings->setValue ("proxyUserName", ""); + settings->setValue ("proxyPassword", ""); + settings->sync (); + resource_manager::instance ()->reload_settings (); + + application.quit (); + // We are in an infinite loop, so everything else than a return + // will cause the application to restart from the very beginning. + if (returnCode == QDialog::Rejected) + return 0; + } + else + { + QSettings *settings = resource_manager::instance ()->get_settings (); + QString language = settings->value ("language").toString (); + + QString translatorFile = resource_manager::instance ()->find_translator_file (language); + QTranslator translator; + translator.load (translatorFile); + application.installTranslator (&translator); + + resource_manager::instance ()->update_network_settings (); + resource_manager::instance ()->load_icons (); + + main_window w; + w.show (); + //w.activateWindow(); + return application.exec (); + } + } +} diff --git a/gui/src/octave-qt-event-listener.cc b/gui/src/octave-qt-event-listener.cc new file mode 100644 --- /dev/null +++ b/gui/src/octave-qt-event-listener.cc @@ -0,0 +1,46 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2012 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "octave-qt-event-listener.h" +#include + +octave_qt_event_listener::octave_qt_event_listener (QObject *parent) + : QObject (parent), octave_event_listener () +{ +} + +void +octave_qt_event_listener::current_directory_has_changed (std::string directory) +{ + emit current_directory_has_changed_signal + (QString::fromStdString (directory)); +} + +void +octave_qt_event_listener::about_to_exit () +{ + qApp->quit (); +} + +void +octave_qt_event_listener::entered_debug_mode () +{ emit entered_debug_mode_signal (); } + +void +octave_qt_event_listener::quit_debug_mode () +{ emit quit_debug_mode_signal (); } + diff --git a/gui/src/octave-qt-event-listener.h b/gui/src/octave-qt-event-listener.h new file mode 100644 --- /dev/null +++ b/gui/src/octave-qt-event-listener.h @@ -0,0 +1,44 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2012 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef OCTAVEQTEVENTLISTENER_H +#define OCTAVEQTEVENTLISTENER_H + +#include +#include +#include "octave-event-listener.h" + +class octave_qt_event_listener + : public QObject, public octave_event_listener +{ + Q_OBJECT + public: + octave_qt_event_listener (QObject *parent = 0); + + void current_directory_has_changed (std::string directory); + void about_to_exit (); + + void entered_debug_mode (); + void quit_debug_mode (); + + signals: + void current_directory_has_changed_signal (QString directory); + void entered_debug_mode_signal (); + void quit_debug_mode_signal (); +}; + +#endif // OCTAVEQTEVENTLISTENER_H diff --git a/gui/src/resource-manager.cc b/gui/src/resource-manager.cc new file mode 100644 --- /dev/null +++ b/gui/src/resource-manager.cc @@ -0,0 +1,1687 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "resource-manager.h" +#include +#include + +resource_manager resource_manager::_singleton; + +resource_manager::resource_manager () +{ + _settings = 0; + reload_settings (); +} + +resource_manager::~resource_manager () +{ + delete _settings; +} + +QSettings * +resource_manager::get_settings () +{ + return _settings; +} + +QString +resource_manager::get_home_path () +{ + return _home_path; +} + +void +resource_manager::reload_settings () +{ + QDesktopServices desktopServices; + _home_path = desktopServices.storageLocation (QDesktopServices::HomeLocation); + set_settings(_home_path + "/.config/octave-gui/settings"); +} + +void +resource_manager::set_settings (QString file) +{ + delete _settings; + + _first_run = false; + if (!QFile::exists (file)) + _first_run = true; + + // If the settings file does not exist, QSettings automatically creates it. + // Therefore we have to check if it exists before instantiating the settings object. + // That way we can detect if the user ran this application before. + _settings = new QSettings (file, QSettings::IniFormat); +} + +QString +resource_manager::find_translator_file (QString language) +{ + // TODO: Quick hack to be able to test language files. + return QString("../languages/%1.qm").arg(language); +} + +QIcon +resource_manager::get_icon (icon i) +{ + if (_icons.contains (i)) + { + return _icons [i]; + } + return QIcon (); +} + +bool +resource_manager::is_first_run () +{ + return _first_run; +} + +void +resource_manager::update_network_settings () +{ + QNetworkProxy::ProxyType proxyType = QNetworkProxy::NoProxy; + if (_settings->value ("useProxyServer").toBool ()) + { + QString proxyTypeString = _settings->value ("proxyType").toString (); + if (proxyTypeString == "Socks5Proxy") + { + proxyType = QNetworkProxy::Socks5Proxy; + } + else if (proxyTypeString == "HttpProxy") + { + proxyType = QNetworkProxy::HttpProxy; + } + } + + QNetworkProxy proxy; + proxy.setType (proxyType); + proxy.setHostName (_settings->value ("proxyHostName").toString ()); + proxy.setPort (_settings->value ("proxyPort").toInt ()); + proxy.setUser (_settings->value ("proxyUserName").toString ()); + proxy.setPassword (_settings->value ("proxyPassword").toString ()); + QNetworkProxy::setApplicationProxy (proxy); +} + +void +resource_manager::load_icons () +{ + _icons [resource_manager::octave] = QIcon ("../media/logo.png"); + _icons [resource_manager::terminal] = QIcon ("../media/terminal.png"); + _icons [resource_manager::documentation] = QIcon ("../media/help_index.png"); + _icons [resource_manager::chat] = QIcon ("../media/chat.png"); + _icons [resource_manager::chat_new_message] = QIcon ("../media/jabber_protocol.png"); +} + +const char* +resource_manager::octave_keywords () +{ + return + ".nargin. " + "EDITOR " + "EXEC_PATH " + "F_DUPFD " + "F_GETFD " + "F_GETFL " + "F_SETFD " + "F_SETFL " + "I " + "IMAGE_PATH " + "Inf " + "J " + "NA " + "NaN " + "OCTAVE_HOME " + "OCTAVE_VERSION " + "O_APPEND " + "O_ASYNC " + "O_CREAT " + "O_EXCL " + "O_NONBLOCK " + "O_RDONLY " + "O_RDWR " + "O_SYNC " + "O_TRUNC " + "O_WRONLY " + "PAGER " + "PAGER_FLAGS " + "PS1 " + "PS2 " + "PS4 " + "P_tmpdir " + "SEEK_CUR " + "SEEK_END " + "SEEK_SET " + "SIG " + "S_ISBLK " + "S_ISCHR " + "S_ISDIR " + "S_ISFIFO " + "S_ISLNK " + "S_ISREG " + "S_ISSOCK " + "WCONTINUE " + "WCOREDUMP " + "WEXITSTATUS " + "WIFCONTINUED " + "WIFEXITED " + "WIFSIGNALED " + "WIFSTOPPED " + "WNOHANG " + "WSTOPSIG " + "WTERMSIG " + "WUNTRACED " + "__accumarray_max__ " + "__accumarray_min__ " + "__accumarray_sum__ " + "__accumdim_sum__ " + "__all_opts__ " + "__builtins__ " + "__calc_dimensions__ " + "__contourc__ " + "__current_scope__ " + "__delaunayn__ " + "__dispatch__ " + "__display_tokens__ " + "__dsearchn__ " + "__dump_symtab_info__ " + "__end__ " + "__error_text__ " + "__finish__ " + "__fltk_ginput__ " + "__fltk_print__ " + "__fltk_uigetfile__ " + "__ftp__ " + "__ftp_ascii__ " + "__ftp_binary__ " + "__ftp_close__ " + "__ftp_cwd__ " + "__ftp_delete__ " + "__ftp_dir__ " + "__ftp_mget__ " + "__ftp_mkdir__ " + "__ftp_mode__ " + "__ftp_mput__ " + "__ftp_pwd__ " + "__ftp_rename__ " + "__ftp_rmdir__ " + "__get__ " + "__glpk__ " + "__gnuplot_drawnow__ " + "__gnuplot_get_var__ " + "__gnuplot_ginput__ " + "__gnuplot_has_feature__ " + "__gnuplot_open_stream__ " + "__gnuplot_print__ " + "__gnuplot_version__ " + "__go_axes__ " + "__go_axes_init__ " + "__go_close_all__ " + "__go_delete__ " + "__go_draw_axes__ " + "__go_draw_figure__ " + "__go_execute_callback__ " + "__go_figure__ " + "__go_figure_handles__ " + "__go_handles__ " + "__go_hggroup__ " + "__go_image__ " + "__go_line__ " + "__go_patch__ " + "__go_surface__ " + "__go_text__ " + "__go_uimenu__ " + "__gud_mode__ " + "__image_pixel_size__ " + "__init_fltk__ " + "__isa_parent__ " + "__keywords__ " + "__lexer_debug_flag__ " + "__lin_interpn__ " + "__list_functions__ " + "__magick_finfo__ " + "__magick_format_list__ " + "__magick_read__ " + "__magick_write__ " + "__makeinfo__ " + "__marching_cube__ " + "__next_line_color__ " + "__next_line_style__ " + "__operators__ " + "__parent_classes__ " + "__parser_debug_flag__ " + "__pathorig__ " + "__pchip_deriv__ " + "__plt_get_axis_arg__ " + "__print_parse_opts__ " + "__qp__ " + "__request_drawnow__ " + "__sort_rows_idx__ " + "__strip_html_tags__ " + "__token_count__ " + "__varval__ " + "__version_info__ " + "__voronoi__ " + "__which__ " + "abs " + "accumarray " + "accumdim " + "acos " + "acosd " + "acosh " + "acot " + "acotd " + "acoth " + "acsc " + "acscd " + "acsch " + "add_input_event_hook " + "addlistener " + "addpath " + "addproperty " + "addtodate " + "airy " + "all " + "allchild " + "allow_noninteger_range_as_index " + "amd " + "ancestor " + "and " + "angle " + "anova " + "ans " + "any " + "arch_fit " + "arch_rnd " + "arch_test " + "area " + "arg " + "argnames " + "argv " + "arma_rnd " + "arrayfun " + "asctime " + "asec " + "asecd " + "asech " + "asin " + "asind " + "asinh " + "assert " + "assignin " + "atan " + "atan2 " + "atand " + "atanh " + "atexit " + "autocor " + "autocov " + "autoload " + "autoreg_matrix " + "autumn " + "available_graphics_toolkits " + "axes " + "axis " + "balance " + "bar " + "barh " + "bartlett " + "bartlett_test " + "base2dec " + "beep " + "beep_on_error " + "bessel " + "besselh " + "besseli " + "besselj " + "besselk " + "bessely " + "beta " + "betacdf " + "betai " + "betainc " + "betainv " + "betaln " + "betapdf " + "betarnd " + "bicgstab " + "bicubic " + "bin2dec " + "bincoeff " + "binocdf " + "binoinv " + "binopdf " + "binornd " + "bitand " + "bitcmp " + "bitget " + "bitmax " + "bitor " + "bitpack " + "bitset " + "bitshift " + "bitunpack " + "bitxor " + "blackman " + "blanks " + "blkdiag " + "blkmm " + "bone " + "box " + "break " + "brighten " + "bsxfun " + "bug_report " + "builtin " + "bunzip2 " + "bzip2 " + "calendar " + "canonicalize_file_name " + "cart2pol " + "cart2sph " + "case " + "cast " + "cat " + "catch " + "cauchy_cdf " + "cauchy_inv " + "cauchy_pdf " + "cauchy_rnd " + "caxis " + "cbrt " + "ccolamd " + "cd " + "ceil " + "cell " + "cell2mat " + "cell2struct " + "celldisp " + "cellfun " + "cellidx " + "cellindexmat " + "cellslices " + "cellstr " + "center " + "cgs " + "char " + "chdir " + "chi2cdf " + "chi2inv " + "chi2pdf " + "chi2rnd " + "chisquare_test_homogeneity " + "chisquare_test_independence " + "chol " + "chol2inv " + "choldelete " + "cholinsert " + "cholinv " + "cholshift " + "cholupdate " + "chop " + "circshift " + "cla " + "clabel " + "class " + "clc " + "clear " + "clf " + "clg " + "clock " + "cloglog " + "close " + "closereq " + "colamd " + "colloc " + "colon " + "colorbar " + "colormap " + "colperm " + "colstyle " + "columns " + "comet " + "comet3 " + "comma " + "command_line_path " + "common_size " + "commutation_matrix " + "compan " + "compare_versions " + "compass " + "complement " + "completion_append_char " + "completion_matches " + "complex " + "computer " + "cond " + "condest " + "confirm_recursive_rmdir " + "conj " + "continue " + "contour " + "contour3 " + "contourc " + "contourf " + "contrast " + "conv " + "conv2 " + "convhull " + "convhulln " + "convn " + "cool " + "copper " + "copyfile " + "cor " + "cor_test " + "corrcoef " + "cos " + "cosd " + "cosh " + "cot " + "cotd " + "coth " + "cov " + "cplxpair " + "cputime " + "cquad " + "crash_dumps_octave_core " + "create_set " + "cross " + "csc " + "cscd " + "csch " + "cstrcat " + "csvread " + "csvwrite " + "csymamd " + "ctime " + "ctranspose " + "cummax " + "cummin " + "cumprod " + "cumsum " + "cumtrapz " + "curl " + "cut " + "cylinder " + "daspect " + "daspk " + "daspk_options " + "dasrt " + "dasrt_options " + "dassl " + "dassl_options " + "date " + "datenum " + "datestr " + "datetick " + "datevec " + "dbclear " + "dbcont " + "dbdown " + "dblquad " + "dbnext " + "dbquit " + "dbstack " + "dbstatus " + "dbstep " + "dbstop " + "dbtype " + "dbup " + "dbwhere " + "deal " + "deblank " + "debug " + "debug_on_error " + "debug_on_interrupt " + "debug_on_warning " + "dec2base " + "dec2bin " + "dec2hex " + "deconv " + "default_save_options " + "del2 " + "delaunay " + "delaunay3 " + "delaunayn " + "delete " + "dellistener " + "demo " + "det " + "detrend " + "diag " + "diary " + "diff " + "diffpara " + "diffuse " + "dir " + "discrete_cdf " + "discrete_inv " + "discrete_pdf " + "discrete_rnd " + "disp " + "dispatch " + "display " + "divergence " + "dlmread " + "dlmwrite " + "dmperm " + "dmult " + "do " + "do_braindead_shortcircuit_evaluation " + "do_string_escapes " + "doc " + "doc_cache_file " + "dos " + "dot " + "double " + "drawnow " + "dsearch " + "dsearchn " + "dump_prefs " + "dup2 " + "duplication_matrix " + "durbinlevinson " + "e " + "echo " + "echo_executing_commands " + "edit " + "edit_history " + "eig " + "eigs " + "ellipsoid " + "else " + "elseif " + "empirical_cdf " + "empirical_inv " + "empirical_pdf " + "empirical_rnd " + "end " + "end_try_catch " + "end_unwind_protect " + "endfor " + "endfunction " + "endgrent " + "endif " + "endpwent " + "endswitch " + "endwhile " + "eomday " + "eps " + "eq " + "erf " + "erfc " + "erfcx " + "erfinv " + "errno " + "errno_list " + "error " + "error_text " + "errorbar " + "etime " + "etree " + "etreeplot " + "eval " + "evalin " + "example " + "exec " + "exist " + "exit " + "exp " + "expcdf " + "expinv " + "expm " + "expm1 " + "exppdf " + "exprnd " + "eye " + "ezcontour " + "ezcontourf " + "ezmesh " + "ezmeshc " + "ezplot " + "ezplot3 " + "ezpolar " + "ezsurf " + "ezsurfc " + "f_test_regression " + "factor " + "factorial " + "fail " + "false " + "fcdf " + "fclear " + "fclose " + "fcntl " + "fdisp " + "feather " + "feof " + "ferror " + "feval " + "fflush " + "fft " + "fft2 " + "fftconv " + "fftfilt " + "fftn " + "fftshift " + "fftw " + "fgetl " + "fgets " + "fieldnames " + "figure " + "file_in_loadpath " + "file_in_path " + "fileattrib " + "filemarker " + "fileparts " + "fileread " + "filesep " + "fill " + "filter " + "filter2 " + "find " + "find_dir_in_path " + "findall " + "findobj " + "findstr " + "finite " + "finv " + "fix " + "fixed_point_format " + "flag " + "flipdim " + "fliplr " + "flipud " + "floor " + "fminbnd " + "fminunc " + "fmod " + "fnmatch " + "fopen " + "for " + "fork " + "format " + "formula " + "fpdf " + "fplot " + "fprintf " + "fputs " + "fractdiff " + "fread " + "freport " + "freqz " + "freqz_plot " + "frewind " + "frnd " + "fscanf " + "fseek " + "fskipl " + "fsolve " + "fstat " + "ftell " + "full " + "fullfile " + "func2str " + "function " + "functions " + "fwrite " + "fzero " + "gamcdf " + "gaminv " + "gamma " + "gammai " + "gammainc " + "gammaln " + "gampdf " + "gamrnd " + "gca " + "gcbf " + "gcbo " + "gcd " + "gcf " + "ge " + "gen_doc_cache " + "genpath " + "genvarname " + "geocdf " + "geoinv " + "geopdf " + "geornd " + "get " + "get_first_help_sentence " + "get_help_text " + "get_help_text_from_file " + "getappdata " + "getegid " + "getenv " + "geteuid " + "getfield " + "getgid " + "getgrent " + "getgrgid " + "getgrnam " + "gethostname " + "getpgrp " + "getpid " + "getppid " + "getpwent " + "getpwnam " + "getpwuid " + "getrusage " + "getuid " + "ginput " + "givens " + "glob " + "global " + "glpk " + "glpkmex " + "gls " + "gmap40 " + "gmres " + "gmtime " + "gnuplot_binary " + "gplot " + "gradient " + "graphics_toolkit " + "gray " + "gray2ind " + "grid " + "griddata " + "griddata3 " + "griddatan " + "gt " + "gtext " + "gunzip " + "gzip " + "hadamard " + "hamming " + "hankel " + "hanning " + "help " + "hess " + "hex2dec " + "hex2num " + "hggroup " + "hidden " + "hilb " + "hist " + "histc " + "history " + "history_control " + "history_file " + "history_size " + "history_timestamp_format_string " + "hold " + "home " + "horzcat " + "hot " + "hotelling_test " + "hotelling_test_2 " + "housh " + "hsv " + "hsv2rgb " + "hurst " + "hygecdf " + "hygeinv " + "hygepdf " + "hygernd " + "hypot " + "i " + "idivide " + "if " + "ifelse " + "ifft " + "ifft2 " + "ifftn " + "ifftshift " + "ignore_function_time_stamp " + "imag " + "image " + "imagesc " + "imfinfo " + "imread " + "imshow " + "imwrite " + "ind2gray " + "ind2rgb " + "ind2sub " + "index " + "inf " + "inferiorto " + "info " + "info_file " + "info_program " + "inline " + "inpolygon " + "input " + "inputname " + "int16 " + "int2str " + "int32 " + "int64 " + "int8 " + "interp1 " + "interp1q " + "interp2 " + "interp3 " + "interpft " + "interpn " + "intersect " + "intmax " + "intmin " + "intwarning " + "inv " + "inverse " + "invhilb " + "ipermute " + "iqr " + "is_absolute_filename " + "is_duplicate_entry " + "is_global " + "is_leap_year " + "is_rooted_relative_filename " + "is_valid_file_id " + "isa " + "isalnum " + "isalpha " + "isappdata " + "isargout " + "isascii " + "isbool " + "iscell " + "iscellstr " + "ischar " + "iscntrl " + "iscolumn " + "iscommand " + "iscomplex " + "isdebugmode " + "isdefinite " + "isdeployed " + "isdigit " + "isdir " + "isempty " + "isequal " + "isequalwithequalnans " + "isfield " + "isfigure " + "isfinite " + "isfloat " + "isglobal " + "isgraph " + "ishandle " + "ishermitian " + "ishghandle " + "ishold " + "isieee " + "isindex " + "isinf " + "isinteger " + "iskeyword " + "isletter " + "islogical " + "islower " + "ismac " + "ismatrix " + "ismember " + "ismethod " + "isna " + "isnan " + "isnull " + "isnumeric " + "isobject " + "isocolors " + "isonormals " + "isosurface " + "ispc " + "isprime " + "isprint " + "isprop " + "ispunct " + "israwcommand " + "isreal " + "isrow " + "isscalar " + "issorted " + "isspace " + "issparse " + "issquare " + "isstr " + "isstrprop " + "isstruct " + "issymmetric " + "isunix " + "isupper " + "isvarname " + "isvector " + "isxdigit " + "j " + "jet " + "kbhit " + "kendall " + "keyboard " + "kill " + "kolmogorov_smirnov_cdf " + "kolmogorov_smirnov_test " + "kolmogorov_smirnov_test_2 " + "kron " + "kruskal_wallis_test " + "krylov " + "krylovb " + "kurtosis " + "laplace_cdf " + "laplace_inv " + "laplace_pdf " + "laplace_rnd " + "lasterr " + "lasterror " + "lastwarn " + "lchol " + "lcm " + "ldivide " + "le " + "legend " + "legendre " + "length " + "lgamma " + "license " + "lin2mu " + "line " + "link " + "linkprop " + "linspace " + "list " + "list_in_columns " + "list_primes " + "load " + "loadaudio " + "loadimage " + "loadobj " + "localtime " + "log " + "log10 " + "log1p " + "log2 " + "logical " + "logistic_cdf " + "logistic_inv " + "logistic_pdf " + "logistic_regression " + "logistic_rnd " + "logit " + "loglog " + "loglogerr " + "logm " + "logncdf " + "logninv " + "lognpdf " + "lognrnd " + "logspace " + "lookfor " + "lookup " + "lower " + "ls " + "ls_command " + "lsode " + "lsode_options " + "lsqnonneg " + "lstat " + "lt " + "lu " + "luinc " + "luupdate " + "magic " + "mahalanobis " + "make_absolute_filename " + "makeinfo_program " + "manova " + "mark_as_command " + "mark_as_rawcommand " + "mat2cell " + "mat2str " + "matlabroot " + "matrix_type " + "max " + "max_recursion_depth " + "mcnemar_test " + "md5sum " + "mean " + "meansq " + "median " + "menu " + "merge " + "mesh " + "meshc " + "meshgrid " + "meshz " + "methods " + "mex " + "mexext " + "mfilename " + "mgorth " + "min " + "minus " + "mislocked " + "missing_function_hook " + "mist " + "mkdir " + "mkfifo " + "mkoctfile " + "mkpp " + "mkstemp " + "mktime " + "mldivide " + "mlock " + "mod " + "mode " + "moment " + "more " + "most " + "movefile " + "mpoles " + "mpower " + "mrdivide " + "mtimes " + "mu2lin " + "munlock " + "namelengthmax " + "nan " + "nargchk " + "nargin " + "nargout " + "nargoutchk " + "native_float_format " + "nbincdf " + "nbininv " + "nbinpdf " + "nbinrnd " + "nchoosek " + "ndgrid " + "ndims " + "ne " + "newplot " + "news " + "nextpow2 " + "nfields " + "nnz " + "nonzeros " + "norm " + "normcdf " + "normest " + "norminv " + "normpdf " + "normrnd " + "not " + "now " + "nproc " + "nth_element " + "nthroot " + "ntsc2rgb " + "null " + "num2cell " + "num2hex " + "num2str " + "numel " + "nzmax " + "ocean " + "octave_config_info " + "octave_core_file_limit " + "octave_core_file_name " + "octave_core_file_options " + "octave_tmp_file_name " + "ols " + "onCleanup " + "onenormest " + "ones " + "optimget " + "optimize_subsasgn_calls " + "optimset " + "or " + "orderfields " + "orient " + "orth " + "otherwise " + "output_max_field_width " + "output_precision " + "pack " + "page_output_immediately " + "page_screen_output " + "paren " + "pareto " + "parseparams " + "pascal " + "patch " + "path " + "pathdef " + "pathsep " + "pause " + "pbaspect " + "pcg " + "pchip " + "pclose " + "pcolor " + "pcr " + "peaks " + "periodogram " + "perl " + "perms " + "permute " + "perror " + "persistent " + "pi " + "pie " + "pie3 " + "pink " + "pinv " + "pipe " + "pkg " + "planerot " + "playaudio " + "plot " + "plot3 " + "plotmatrix " + "plotyy " + "plus " + "poisscdf " + "poissinv " + "poisspdf " + "poissrnd " + "pol2cart " + "polar " + "poly " + "polyaffine " + "polyarea " + "polyder " + "polyderiv " + "polyfit " + "polygcd " + "polyint " + "polyout " + "polyreduce " + "polyval " + "polyvalm " + "popen " + "popen2 " + "postpad " + "pow2 " + "power " + "powerset " + "ppder " + "ppint " + "ppjumps " + "ppplot " + "ppval " + "pqpnonneg " + "prctile " + "prepad " + "primes " + "print " + "print_empty_dimensions " + "print_struct_array_contents " + "print_usage " + "printf " + "prism " + "probit " + "prod " + "program_invocation_name " + "program_name " + "prop_test_2 " + "putenv " + "puts " + "pwd " + "qp " + "qqplot " + "qr " + "qrdelete " + "qrinsert " + "qrshift " + "qrupdate " + "quad " + "quad_options " + "quadcc " + "quadgk " + "quadl " + "quadv " + "quantile " + "quit " + "quiver " + "quiver3 " + "qz " + "qzhess " + "rainbow " + "rand " + "rande " + "randg " + "randi " + "randn " + "randp " + "randperm " + "range " + "rank " + "ranks " + "rat " + "rats " + "rcond " + "rdivide " + "re_read_readline_init_file " + "read_readline_init_file " + "readdir " + "readlink " + "real " + "reallog " + "realmax " + "realmin " + "realpow " + "realsqrt " + "record " + "rectangle " + "rectint " + "refresh " + "refreshdata " + "regexp " + "regexpi " + "regexprep " + "regexptranslate " + "rehash " + "rem " + "remove_input_event_hook " + "rename " + "repelems " + "replot " + "repmat " + "reset " + "reshape " + "residue " + "resize " + "restoredefaultpath " + "rethrow " + "return " + "rgb2hsv " + "rgb2ind " + "rgb2ntsc " + "ribbon " + "rindex " + "rmappdata " + "rmdir " + "rmfield " + "rmpath " + "roots " + "rose " + "rosser " + "rot90 " + "rotdim " + "round " + "roundb " + "rows " + "rref " + "rsf2csf " + "run " + "run_count " + "run_history " + "run_test " + "rundemos " + "runlength " + "runtests " + "save " + "save_header_format_string " + "save_precision " + "saveas " + "saveaudio " + "saveimage " + "saveobj " + "savepath " + "saving_history " + "scanf " + "scatter " + "scatter3 " + "schur " + "sec " + "secd " + "sech " + "semicolon " + "semilogx " + "semilogxerr " + "semilogy " + "semilogyerr " + "set " + "setappdata " + "setaudio " + "setdiff " + "setenv " + "setfield " + "setgrent " + "setpwent " + "setstr " + "setxor " + "shading " + "shell_cmd " + "shg " + "shift " + "shiftdim " + "sighup_dumps_octave_core " + "sign " + "sign_test " + "sigterm_dumps_octave_core " + "silent_functions " + "sin " + "sinc " + "sind " + "sinetone " + "sinewave " + "single " + "sinh " + "size " + "size_equal " + "sizemax " + "sizeof " + "skewness " + "sleep " + "slice " + "sombrero " + "sort " + "sortrows " + "source " + "spalloc " + "sparse " + "sparse_auto_mutate " + "spatan2 " + "spaugment " + "spchol " + "spchol2inv " + "spcholinv " + "spconvert " + "spcumprod " + "spcumsum " + "spdet " + "spdiag " + "spdiags " + "spearman " + "spectral_adf " + "spectral_xdf " + "specular " + "speed " + "spencer " + "speye " + "spfind " + "spfun " + "sph2cart " + "sphcat " + "sphere " + "spinmap " + "spinv " + "spkron " + "splchol " + "spline " + "split " + "split_long_rows " + "splu " + "spmax " + "spmin " + "spones " + "spparms " + "spprod " + "spqr " + "sprand " + "sprandn " + "sprandsym " + "sprank " + "spring " + "sprintf " + "spstats " + "spsum " + "spsumsq " + "spvcat " + "spy " + "sqp " + "sqrt " + "sqrtm " + "squeeze " + "sscanf " + "stairs " + "stat " + "static " + "statistics " + "std " + "stderr " + "stdin " + "stdnormal_cdf " + "stdnormal_inv " + "stdnormal_pdf " + "stdnormal_rnd " + "stdout " + "stem " + "stem3 " + "stft " + "str2double " + "str2func " + "str2mat " + "str2num " + "strcat " + "strchr " + "strcmp " + "strcmpi " + "strerror " + "strfind " + "strftime " + "string_fill_char " + "strjust " + "strmatch " + "strncmp " + "strncmpi " + "strptime " + "strread " + "strrep " + "strsplit " + "strtok " + "strtrim " + "strtrunc " + "struct " + "struct2cell " + "struct_levels_to_print " + "structfun " + "strvcat " + "studentize " + "sub2ind " + "subplot " + "subsasgn " + "subsindex " + "subspace " + "subsref " + "substr " + "substruct " + "sum " + "summer " + "sumsq " + "superiorto " + "suppress_verbose_help_message " + "surf " + "surface " + "surfc " + "surfl " + "surfnorm " + "svd " + "svd_driver " + "svds " + "swapbytes " + "switch " + "syl " + "sylvester_matrix " + "symamd " + "symbfact " + "symlink " + "symrcm " + "symvar " + "synthesis " + "system " + "t_test " + "t_test_2 " + "t_test_regression " + "table " + "tan " + "tand " + "tanh " + "tar " + "tcdf " + "tempdir " + "tempname " + "terminal_size " + "test " + "test2 " + "test3 " + "text " + "textread " + "textscan " + "tic " + "tilde_expand " + "time " + "times " + "tinv " + "title " + "tmpfile " + "tmpnam " + "toascii " + "toc " + "toeplitz " + "tolower " + "toupper " + "tpdf " + "trace " + "transpose " + "trapz " + "treelayout " + "treeplot " + "tril " + "trimesh " + "triplequad " + "triplot " + "trisurf " + "triu " + "trnd " + "true " + "try " + "tsearch " + "tsearchn " + "type " + "typecast " + "typeinfo " + "u_test " + "uigetdir " + "uigetfile " + "uimenu " + "uint16 " + "uint32 " + "uint64 " + "uint8 " + "uiputfile " + "umask " + "uminus " + "uname " + "undo_string_escapes " + "unidcdf " + "unidinv " + "unidpdf " + "unidrnd " + "unifcdf " + "unifinv " + "unifpdf " + "unifrnd " + "unimplemented " + "union " + "unique " + "unix " + "unlink " + "unmark_command " + "unmark_rawcommand " + "unmkpp " + "unpack " + "untabify " + "untar " + "until " + "unwind_protect " + "unwind_protect_cleanup " + "unwrap " + "unzip " + "uplus " + "upper " + "urlread " + "urlwrite " + "usage " + "usleep " + "validatestring " + "values " + "vander " + "var " + "var_test " + "varargin " + "varargout " + "vec " + "vech " + "vectorize " + "ver " + "version " + "vertcat " + "view " + "voronoi " + "voronoin " + "waitforbuttonpress " + "waitpid " + "warning " + "warning_ids " + "warranty " + "wavread " + "wavwrite " + "wblcdf " + "wblinv " + "wblpdf " + "wblrnd " + "weekday " + "weibcdf " + "weibinv " + "weibpdf " + "weibrnd " + "welch_test " + "what " + "which " + "while " + "white " + "whitebg " + "who " + "whos " + "whos_line_format " + "wienrnd " + "wilcoxon_test " + "wilkinson " + "winter " + "xlabel " + "xlim " + "xor " + "yes_or_no " + "ylabel " + "ylim " + "yulewalker " + "z_test " + "z_test_2 " + "zeros " + "zip " + "zlabel " + "zlim "; + /* "break case catch continue do else elseif end end_unwind_protect " + "endfor endfunction endif endswitch endwhile for function " + "global if otherwise persistent return switch try until " + "unwind_protect unwind_protect_cleanup while"; + */ +} diff --git a/gui/src/resource-manager.h b/gui/src/resource-manager.h new file mode 100644 --- /dev/null +++ b/gui/src/resource-manager.h @@ -0,0 +1,67 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RESOURCEMANAGER_H +#define RESOURCEMANAGER_H + +#include +#include +#include +#include + +class resource_manager +{ +public: + enum icon + { + octave, + terminal, + documentation, + chat, + chat_new_message + }; + + ~resource_manager (); + + static resource_manager * + instance () + { + return &_singleton; + } + + QSettings *get_settings (); + QString get_home_path (); + void reload_settings (); + void set_settings (QString file); + QString find_translator_file (QString language); + void update_network_settings (); + void load_icons (); + QIcon get_icon (icon i); + bool is_first_run (); + const char *octave_keywords (); + +private: + resource_manager (); + + QSettings *_settings; + QString _home_path; + QMap _icons; + static resource_manager _singleton; + bool _first_run; +}; + +#endif // RESOURCEMANAGER_H diff --git a/gui/src/resource.qrc b/gui/src/resource.qrc new file mode 100644 --- /dev/null +++ b/gui/src/resource.qrc @@ -0,0 +1,17 @@ + + + icons/artsbuilderexecute.png + icons/editcopy.png + icons/editcut.png + icons/editpaste.png + icons/filenew.png + icons/fileopen.png + icons/filesave.png + icons/redo.png + icons/search.png + icons/undo.png + icons/up.png + icons/configure.png + icons/filesaveas.png + + diff --git a/gui/src/settings-dialog.cc b/gui/src/settings-dialog.cc new file mode 100644 --- /dev/null +++ b/gui/src/settings-dialog.cc @@ -0,0 +1,87 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "resource-manager.h" +#include "settings-dialog.h" +#include "ui_settings-dialog.h" +#include + +settings_dialog::settings_dialog (QWidget * parent): +QDialog (parent), ui (new Ui::settings_dialog) +{ + ui->setupUi (this); + + QSettings *settings = resource_manager::instance ()->get_settings (); + ui->useCustomFileEditor->setChecked (settings->value ("useCustomFileEditor").toBool ()); + ui->customFileEditor->setText (settings->value ("customFileEditor").toString ()); + ui->editor_showLineNumbers->setChecked (settings->value ("editor/showLineNumbers",true).toBool () ); + ui->editor_highlightCurrentLine->setChecked (settings->value ("editor/highlightCurrentLine",true).toBool () ); + ui->editor_codeCompletion->setChecked (settings->value ("editor/codeCompletion",true).toBool () ); + ui->editor_fontName->setCurrentFont (QFont (settings->value ("editor/fontName","Courier").toString()) ); + ui->editor_fontSize->setValue (settings->value ("editor/fontSize",10).toInt ()); + ui->editor_longWindowTitle->setChecked (settings->value ("editor/longWindowTitle",true).toBool ()); + ui->terminal_fontName->setCurrentFont (QFont (settings->value ("terminal/fontName","Courier").toString()) ); + ui->terminal_fontSize->setValue (settings->value ("terminal/fontSize",10).toInt ()); + ui->showFilenames->setChecked (settings->value ("showFilenames").toBool()); + ui->showFileSize->setChecked (settings->value ("showFileSize").toBool()); + ui->showFileType->setChecked (settings->value ("showFileType").toBool()); + ui->showLastModified->setChecked (settings->value ("showLastModified").toBool()); + ui->showHiddenFiles->setChecked (settings->value ("showHiddenFiles").toBool()); + ui->useAlternatingRowColors->setChecked (settings->value ("useAlternatingRowColors").toBool()); + ui->useProxyServer->setChecked (settings->value ("useProxyServer").toBool ()); + ui->proxyHostName->setText (settings->value ("proxyHostName").toString ()); + + int currentIndex = 0; + QString proxyTypeString = settings->value ("proxyType").toString (); + while ( (currentIndex < ui->proxyType->count ()) && (ui->proxyType->currentText () != proxyTypeString)) + { + currentIndex++; + ui->proxyType->setCurrentIndex (currentIndex); + } + + ui->proxyPort->setText (settings->value ("proxyPort").toString ()); + ui->proxyUserName->setText (settings->value ("proxyUserName").toString ()); + ui->proxyPassword->setText (settings->value ("proxyPassword").toString ()); +} + +settings_dialog::~settings_dialog () +{ + QSettings *settings = resource_manager::instance ()->get_settings (); + settings->setValue ("useCustomFileEditor", ui->useCustomFileEditor->isChecked ()); + settings->setValue ("customFileEditor", ui->customFileEditor->text ()); + settings->setValue ("editor/showLineNumbers", ui->editor_showLineNumbers->isChecked ()); + settings->setValue ("editor/highlightCurrentLine", ui->editor_highlightCurrentLine->isChecked ()); + settings->setValue ("editor/codeCompletion", ui->editor_codeCompletion->isChecked ()); + settings->setValue ("editor/fontName", ui->editor_fontName->currentFont().family()); + settings->setValue ("editor/fontSize", ui->editor_fontSize->value()); + settings->setValue ("editor/longWindowTitle", ui->editor_longWindowTitle->isChecked()); + settings->setValue ("terminal/fontSize", ui->terminal_fontSize->value()); + settings->setValue ("terminal/fontName", ui->terminal_fontName->currentFont().family()); + settings->setValue ("showFilenames", ui->showFilenames->isChecked ()); + settings->setValue ("showFileSize", ui->showFileSize->isChecked ()); + settings->setValue ("showFileType", ui->showFileType->isChecked ()); + settings->setValue ("showLastModified", ui->showLastModified->isChecked ()); + settings->setValue ("showHiddenFiles", ui->showHiddenFiles->isChecked ()); + settings->setValue ("useAlternatingRowColors", ui->useAlternatingRowColors->isChecked ()); + settings->setValue ("useProxyServer", ui->useProxyServer->isChecked ()); + settings->setValue ("proxyType", ui->proxyType->currentText ()); + settings->setValue ("proxyHostName", ui->proxyHostName->text ()); + settings->setValue ("proxyPort", ui->proxyPort->text ()); + settings->setValue ("proxyUserName", ui->proxyUserName->text ()); + settings->setValue ("proxyPassword", ui->proxyPassword->text ()); + delete ui; +} diff --git a/gui/src/settings-dialog.h b/gui/src/settings-dialog.h new file mode 100644 --- /dev/null +++ b/gui/src/settings-dialog.h @@ -0,0 +1,39 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *md5 + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include + +namespace Ui +{ + class settings_dialog; +} + +class settings_dialog:public QDialog +{ +Q_OBJECT public: + explicit settings_dialog (QWidget * parent); + ~settings_dialog (); + +private: + Ui::settings_dialog * ui; +}; + +#endif // SETTINGSDIALOG_H diff --git a/gui/src/settings-dialog.ui b/gui/src/settings-dialog.ui new file mode 100644 --- /dev/null +++ b/gui/src/settings-dialog.ui @@ -0,0 +1,668 @@ + + + settings_dialog + + + Qt::ApplicationModal + + + + 0 + 0 + 600 + 400 + + + + + 600 + 400 + + + + + 600 + 400 + + + + Settings + + + + + + 0 + + + + Editor + + + + + + + + + + Font + + + + + + + false + + + QFontComboBox::MonospacedFonts + + + + + + + Font Size + + + + + + + 2 + + + 96 + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + true + + + Show line numbers + + + false + + + + + + + true + + + Highlight current line + + + false + + + + + + + true + + + Code completion + + + false + + + + + + + Show complete path in window title + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + true + + + Use custom file editor: + + + + + + + false + + + emacs + + + + + + + + + + Terminal + + + + + + + + Font + + + + + + + false + + + QFontComboBox::MonospacedFonts + + + + + + + Font Size + + + + + + + 2 + + + 96 + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 321 + + + + + + + + + File Browser + + + + + + Show filenames + + + + + + + Show file size + + + + + + + Show file type + + + + + + + Show date of last modification + + + + + + + Show hidden files + + + + + + + Alternating row colors + + + + + + + Qt::Vertical + + + + 20 + 360 + + + + + + + + + Network + + + + + + Use proxy server + + + + + + + + + false + + + Proxy Type: + + + + + + + false + + + + HttpProxy + + + + + Socks5Proxy + + + + + + + + false + + + Hostname: + + + + + + + false + + + + + + + false + + + Port: + + + + + + + false + + + + + + + false + + + Username: + + + + + + + false + + + + + + + false + + + Password: + + + + + + + false + + + QLineEdit::Password + + + + + + + + + + + + + + + useProxyServer + toggled(bool) + label_4 + setEnabled(bool) + + + 249 + 59 + + + 69 + 122 + + + + + useProxyServer + toggled(bool) + label_3 + setEnabled(bool) + + + 249 + 59 + + + 59 + 91 + + + + + useProxyServer + toggled(bool) + label_5 + setEnabled(bool) + + + 249 + 59 + + + 44 + 152 + + + + + useProxyServer + toggled(bool) + proxyType + setEnabled(bool) + + + 249 + 59 + + + 291 + 91 + + + + + useProxyServer + toggled(bool) + proxyHostName + setEnabled(bool) + + + 249 + 59 + + + 291 + 124 + + + + + useProxyServer + toggled(bool) + proxyPort + setEnabled(bool) + + + 249 + 59 + + + 364 + 154 + + + + + useCustomFileEditor + toggled(bool) + customFileEditor + setEnabled(bool) + + + 111 + 62 + + + 343 + 63 + + + + + useProxyServer + toggled(bool) + label_7 + setEnabled(bool) + + + 249 + 59 + + + 67 + 212 + + + + + editor_showLineNumbers + toggled(bool) + editor_showLineNumbers + setEnabled(bool) + + + 249 + 87 + + + 249 + 87 + + + + + editor_highlightCurrentLine + toggled(bool) + editor_highlightCurrentLine + setEnabled(bool) + + + 249 + 112 + + + 249 + 112 + + + + + useProxyServer + toggled(bool) + proxyUserName + setEnabled(bool) + + + 249 + 59 + + + 364 + 184 + + + + + useProxyServer + toggled(bool) + proxyPassword + setEnabled(bool) + + + 249 + 59 + + + 364 + 214 + + + + + useProxyServer + toggled(bool) + label_6 + setEnabled(bool) + + + 249 + 59 + + + 68 + 182 + + + + + editor_codeCompletion + toggled(bool) + editor_codeCompletion + setEnabled(bool) + + + 249 + 137 + + + 249 + 137 + + + + + diff --git a/gui/src/src.pro b/gui/src/src.pro new file mode 100644 --- /dev/null +++ b/gui/src/src.pro @@ -0,0 +1,121 @@ +# OctaveGUI - A graphical user interface for Octave +# Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Basic settings: +QT += core gui webkit network # Qt modules +TEMPLATE = app # Build as application +TARGET = octave-gui # Name of the target binary + +DESTDIR = ../bin # Destination of the output + +TRANSLATIONS += languages/generic.ts \ + languages/de-de.ts \ + languages/pt-br.ts \ + languages/es-es.ts \ + languages/ru-ru.ts \ + languages/uk-ua.ts # Available translations + +win32-msvc*: include(msvc.pri) + +LIBS += -lreadline -lqscintilla2 \ + -L../qterminal/libqterminal/$$LIBDIR_SUFFIX -lqterminal \ + $$system(mkoctfile -p LIBS) \ + $$system(mkoctfile -p OCTAVE_LIBS) + +mac { + CONFIG -= app_bundle +} + +# Includepaths and libraries to link against: +INCLUDEPATH += . octave-adapter m-editor ../qterminal/libqterminal /usr/include/qt4 \ + $$system(mkoctfile -p INCFLAGS) +INCFLAGS += $$system(mkoctfile -p INCFLAGS) +mac { + INCFLAGS += -I/opt/local/include +} + +QMAKE_LIBDIR += $$system(octave-config -p OCTLIBDIR) +unix { + QMAKE_RPATHDIR += $$system(octave-config -p OCTLIBDIR) +} + +mac { + LFLAGS += -L/opt/local/lib +} + +unix { + LIBS += -lutil +} + +win32-g++ { + QMAKE_LFLAGS += --enable-auto-import +} + +win32-msvc* { + DEFINES += QSCINTILLA_DLL + QMAKE_CXXFLAGS += -wd4244 +} + +QMAKE_LFLAGS += $$LFLAGS $$system(mkoctfile -p RLD_FLAG) +QMAKE_CXXFLAGS += $$INCFLAGS + +# Files associated with the project: +SOURCES +=\ + octave-adapter/octave-link.cc \ + octave-adapter/octave-main-thread.cc \ + m-editor/lexer-octave-gui.cc \ + m-editor/file-editor.cc \ + m-editor/file-editor-tab.cc \ + main-window.cc \ + workspace-view.cc \ + history-dockwidget.cc \ + files-dockwidget.cc \ + settings-dialog.cc \ + octave-gui.cc \ + resource-manager.cc \ + welcome-wizard.cc \ + workspace-model.cc \ + terminal-dockwidget.cc \ + octave-qt-event-listener.cc + +HEADERS += \ + octave-adapter/octave-link.h \ + octave-adapter/octave-main-thread.h \ + octave-adapter/octave-event.h \ + octave-adapter/octave-event-observer.h \ + octave-adapter/octave-event-listener.h \ + m-editor/lexer-octave-gui.h \ + m-editor/file-editor.h \ + m-editor/file-editor-interface.h \ + m-editor/file-editor-tab.h \ + symbol-information.h \ + main-window.h \ + workspace-view.h \ + history-dockwidget.h \ + files-dockwidget.h \ + settings-dialog.h \ + resource-manager.h \ + welcome-wizard.h \ + workspace-model.h \ + terminal-dockwidget.h \ + octave-qt-event-listener.h + +FORMS += \ + settings-dialog.ui \ + welcome-wizard.ui + +RESOURCES += \ + resource.qrc diff --git a/gui/src/symbol-information.h b/gui/src/symbol-information.h new file mode 100644 --- /dev/null +++ b/gui/src/symbol-information.h @@ -0,0 +1,148 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SYMBOLINFORMATION_H +#define SYMBOLINFORMATION_H + +#include +#include + +// Octave includes +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef PACKAGE_URL +#include "octave/config.h" +#include "octave/cmd-edit.h" +#include "octave/error.h" +#include "octave/file-io.h" +#include "octave/input.h" +#include "octave/lex.h" +#include "octave/load-path.h" +#include "octave/octave.h" +#include "octave/oct-hist.h" +#include "octave/oct-map.h" +#include "octave/oct-obj.h" +#include "octave/ops.h" +#include "octave/ov.h" +#include "octave/ov-usr-fcn.h" +#include "octave/symtab.h" +#include "octave/pt.h" +#include "octave/pt-eval.h" +#include "octave/config.h" +#include "octave/Range.h" +#include "octave/toplev.h" +#include "octave/procstream.h" +#include "octave/sighandlers.h" +#include "octave/debug.h" +#include "octave/sysdep.h" +#include "octave/ov.h" +#include "octave/unwind-prot.h" +#include "octave/utils.h" +#include "octave/variables.h" + +/** + * \struct symbol_information + * \brief Meta-information over a symbol-table entry. + * \author Jacob Dawid + * This struct is used to store meta information over a symbol entry. + * It reduces memory consumption, since it only stores relevant data + * about a symbol-table entry that will be used in the model for the + * graphical user interface. + */ +typedef struct symbol_information +{ + enum Scope + { + local = 0, + global = 1, + persistent = 2, + hidden = 3 + }; + + QString _symbol; + QString _type; + QString _value; + Scope _scope; + + /** Hashes the symbol information for quickly comparing it. */ + int + hash () const + { + return qHash (_symbol) + qHash (_type) + qHash (_value) + (int)_scope; + } + + /** Compares two symbol information objects. */ + bool + equals (const symbol_information& other) const + { + if (hash () == other.hash ()) + { + return _symbol == other._symbol + && _type == other._type + && _value == other._value + && _scope == other._scope; + } + } + + /** Extracts meta information from a given symbol record. */ + bool + from_symbol_record (const symbol_table::symbol_record& symbol_record) + { + if (symbol_record.is_local () && !symbol_record.is_global () && !symbol_record.is_hidden ()) + _scope = local; + else if (symbol_record.is_global ()) + _scope = global; + else if (symbol_record.is_persistent ()) + _scope = persistent; + else if (symbol_record.is_hidden ()) + _scope = hidden; + + _symbol = QString (symbol_record.name ().c_str ()); + _type = QString (symbol_record.varval ().type_name ().c_str ()); + octave_value ov = symbol_record.varval (); + + // For every type, convert to a human readable string. + if (ov.is_sq_string ()) + _value = QString ("\'%1\'").arg (ov.string_value ().c_str ()); + else if (ov.is_dq_string ()) + _value = QString ("\"%1\"").arg (ov.string_value ().c_str ()); + else if (ov.is_real_scalar ()) + _value = QString ("%1").arg (ov.scalar_value ()); + else if (ov.is_complex_scalar ()) + _value = QString ("%1 + %2i").arg (ov.scalar_value ()) + .arg (ov.complex_value ().imag ()); + else if (ov.is_range ()) + _value = QString ("%1 : %2 : %3").arg (ov.range_value ().base ()) + .arg (ov.range_value ().inc ()) + .arg (ov.range_value ().limit ()); + else if (ov.is_real_matrix ()) + _value = QString ("%1x%2").arg (ov.rows ()) + .arg (ov.columns ()); + else if (ov.is_complex_matrix ()) + _value = QString ("%1x%2").arg (ov.rows ()) + .arg (ov.columns ()); + else + _value = QString (""); + + return true; + } +} symbol_information; + +#endif // SYMBOLINFORMATION_H diff --git a/gui/src/terminal-dockwidget.cc b/gui/src/terminal-dockwidget.cc new file mode 100644 --- /dev/null +++ b/gui/src/terminal-dockwidget.cc @@ -0,0 +1,28 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "terminal-dockwidget.h" + +terminal_dock_widget::terminal_dock_widget (QTerminal *terminal, QWidget *parent) + : QDockWidget (parent) +{ + setObjectName ("TerminalDockWidget"); + setWindowTitle (tr ("Command Window")); + setWidget (terminal); + + connect (this, SIGNAL (visibilityChanged (bool)), this, SLOT (handle_visibility_changed (bool))); +} diff --git a/gui/src/terminal-dockwidget.h b/gui/src/terminal-dockwidget.h new file mode 100644 --- /dev/null +++ b/gui/src/terminal-dockwidget.h @@ -0,0 +1,41 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef TERMINALDOCKWIDGET_H +#define TERMINALDOCKWIDGET_H + +#include +#include "QTerminal.h" + +class terminal_dock_widget : public QDockWidget +{ + Q_OBJECT +public: + terminal_dock_widget (QTerminal *terminal, QWidget *parent = 0); + +signals: + void active_changed (bool active); + +public slots: + void handle_visibility_changed (bool visible) + { + if (visible) + emit active_changed (true); + } +}; + +#endif // TERMINALDOCKWIDGET_H diff --git a/gui/src/welcome-wizard.cc b/gui/src/welcome-wizard.cc new file mode 100644 --- /dev/null +++ b/gui/src/welcome-wizard.cc @@ -0,0 +1,53 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "welcome-wizard.h" +#include "ui_welcome-wizard.h" + +welcome_wizard::welcome_wizard (QWidget *parent) : + QDialog (parent), + _ui (new Ui::welcome_wizard) +{ + _ui->setupUi (this); + connect (_ui->nextButton1, SIGNAL (clicked ()), this, SLOT (next ())); + connect (_ui->nextButton2, SIGNAL (clicked ()), this, SLOT (next ())); + connect (_ui->nextButton3, SIGNAL (clicked ()), this, SLOT (next ())); + connect (_ui->nextButton4, SIGNAL (clicked ()), this, SLOT (next ())); + + connect (_ui->previousButton2, SIGNAL (clicked ()), this, SLOT (previous ())); + connect (_ui->previousButton3, SIGNAL (clicked ()), this, SLOT (previous ())); + connect (_ui->previousButton4, SIGNAL (clicked ()), this, SLOT (previous ())); + connect (_ui->previousButton5, SIGNAL (clicked ()), this, SLOT (previous ())); +} + +welcome_wizard::~welcome_wizard() +{ + delete _ui; +} + +void +welcome_wizard::next () +{ + _ui->stackedWidget->setCurrentIndex (_ui->stackedWidget->currentIndex () + 1); +} + +void +welcome_wizard::previous () +{ + _ui->stackedWidget->setCurrentIndex (_ui->stackedWidget->currentIndex () - 1); +} + diff --git a/gui/src/welcome-wizard.h b/gui/src/welcome-wizard.h new file mode 100644 --- /dev/null +++ b/gui/src/welcome-wizard.h @@ -0,0 +1,43 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WELCOMEWIZARD_H +#define WELCOMEWIZARD_H + +#include + +namespace Ui { + class welcome_wizard; +} + +class welcome_wizard : public QDialog +{ + Q_OBJECT + +public: + explicit welcome_wizard(QWidget *parent = 0); + ~welcome_wizard(); + +public slots: + void next (); + void previous (); + +private: + Ui::welcome_wizard *_ui; +}; + +#endif // WELCOMEWIZARD_H diff --git a/gui/src/welcome-wizard.ui b/gui/src/welcome-wizard.ui new file mode 100644 --- /dev/null +++ b/gui/src/welcome-wizard.ui @@ -0,0 +1,354 @@ + + + welcome_wizard + + + + 0 + 0 + 647 + 400 + + + + + 647 + 400 + + + + + 647 + 400 + + + + Welcome to GNU Octave + + + + + + 4 + + + + + + + It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at '~/.octave-gui'. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file. + + + Qt::AlignJustify|Qt::AlignVCenter + + + true + + + + + + + Qt::Vertical + + + + 20 + 218 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Next + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Previous + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Next + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Previous + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Next + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Previous + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Next + + + + + + + + + + + + + + + + + + 20 + + + + Welcome to Octave! + + + + + + + This is the development version of Octave with the first official GUI. + + + true + + + + + + + You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click 'Finish' to write a configuration file and launch Octave GUI. + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + false + + + Previous + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Finish + + + + + + + + + + + + + + + + + finishButton + clicked() + welcome_wizard + accept() + + + 577 + 372 + + + 323 + 199 + + + + + diff --git a/gui/src/workspace-model.cc b/gui/src/workspace-model.cc new file mode 100644 --- /dev/null +++ b/gui/src/workspace-model.cc @@ -0,0 +1,214 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "workspace-model.h" +#include +#include +#include "octave-link.h" + +workspace_model::workspace_model(QObject *parent) + : QAbstractItemModel(parent), octave_event_observer () +{ + QList rootData; + rootData << tr ("Name") << tr ("Type") << tr ("Value"); + _rootItem = new tree_item(rootData); + + insert_top_level_item(0, new tree_item ("Local")); + insert_top_level_item(1, new tree_item ("Global")); + insert_top_level_item(2, new tree_item ("Persistent")); + insert_top_level_item(3, new tree_item ("Hidden")); + + connect(&_update_workspace_model_timer, + SIGNAL (timeout ()), + this, + SLOT (request_update_workspace())); + + _update_workspace_model_timer.setInterval (500); + _update_workspace_model_timer.setSingleShot (true); + _update_workspace_model_timer.start (); +} + +workspace_model::~workspace_model() +{ + delete _rootItem; +} + +void +workspace_model::request_update_workspace () +{ + octave_link::instance () + ->post_event (new octave_update_workspace_event (*this)); +} + +void +workspace_model::event_accepted (octave_event *e) +{ + if (dynamic_cast (e)) + { + std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables (); + + _symbol_information.clear (); + for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin (); + iterator != symbolTable.end (); iterator++) + { + symbol_information symbolInformation; + symbolInformation.from_symbol_record (*iterator); + _symbol_information.push_back (symbolInformation); + } + + beginResetModel(); + top_level_item (0)->delete_child_items (); + top_level_item (1)->delete_child_items (); + top_level_item (2)->delete_child_items (); + top_level_item (3)->delete_child_items (); + + foreach (const symbol_information& s, _symbol_information) + { + tree_item *child = new tree_item (); + + child->set_data (0, s._symbol); + child->set_data (1, s._type); + child->set_data (2, s._value); + + switch (s._scope) + { + case symbol_information::local: top_level_item (0)->add_child (child); break; + case symbol_information::global: top_level_item (1)->add_child (child); break; + case symbol_information::persistent: top_level_item (2)->add_child (child); break; + case symbol_information::hidden: top_level_item (3)->add_child (child); break; + } + } + + endResetModel(); + emit model_changed(); + } + + // Post a new event in a given time. + // This prevents flooding the event queue when no events are being processed. + _update_workspace_model_timer.start (); + delete e; +} + +void +workspace_model::event_reject (octave_event *e) +{ + delete e; +} + +QModelIndex +workspace_model::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + tree_item *parentItem; + + if (!parent.isValid()) + parentItem = _rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + tree_item *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex +workspace_model::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + tree_item *childItem = static_cast(index.internalPointer()); + tree_item *parentItem = childItem->parent(); + + if (parentItem == _rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + +int +workspace_model::rowCount(const QModelIndex &parent) const +{ + tree_item *parentItem; + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + parentItem = _rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + return parentItem->child_count(); +} + +int +workspace_model::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return static_cast(parent.internalPointer())->column_count(); + else + return _rootItem->column_count(); +} + +void +workspace_model::insert_top_level_item(int at, tree_item *treeItem) +{ + _rootItem->insert_child_item(at, treeItem); +} + +tree_item * +workspace_model::top_level_item (int at) +{ + return _rootItem->child(at); +} + +Qt::ItemFlags +workspace_model::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant +workspace_model::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return _rootItem->data(section); + + return QVariant(); +} + +QVariant +workspace_model::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role != Qt::DisplayRole) + return QVariant(); + + tree_item *item = static_cast(index.internalPointer()); + + return item->data(index.column()); +} + diff --git a/gui/src/workspace-model.h b/gui/src/workspace-model.h new file mode 100644 --- /dev/null +++ b/gui/src/workspace-model.h @@ -0,0 +1,150 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WORKSPACEMODEL_H +#define WORKSPACEMODEL_H + +// Qt includes +#include +#include +#include +#include + +#include "symbol-information.h" +#include "octave-event-observer.h" + +class tree_item +{ +public: + tree_item(const QList &data, tree_item *parent = 0) { + _parent_item = parent; + _item_data = data; + } + + tree_item(QVariant data = QVariant(), tree_item *parent = 0) { + QList variantList; + variantList << data << QVariant() << QVariant(); + _parent_item = parent; + _item_data = variantList; + } + + ~tree_item() { + qDeleteAll(_child_items); + } + + void insert_child_item(int at, tree_item *item) { + item->_parent_item = this; + _child_items.insert(at, item); + } + + void add_child(tree_item *item) { + item->_parent_item = this; + _child_items.append(item); + } + + void delete_child_items() { + qDeleteAll(_child_items); + _child_items.clear(); + } + + void remove_child(tree_item *item) { + _child_items.removeAll(item); + } + + QVariant data(int column) const + { + return _item_data[column]; + } + + void set_data(int column, QVariant data) + { + _item_data[column] = data; + } + + tree_item *child(int row) { + return _child_items[row]; + } + + int child_count() const { + return _child_items.count(); + } + + int column_count() const + { + return _item_data.count(); + } + + int row() const { + if (_parent_item) + return _parent_item->_child_items.indexOf(const_cast(this)); + + return 0; + } + + tree_item *parent() + { + return _parent_item; + } + +private: + QList _child_items; + QList _item_data; + tree_item *_parent_item; +}; + +class workspace_model + : public QAbstractItemModel, public octave_event_observer +{ + Q_OBJECT + +public: + workspace_model (QObject *parent = 0); + ~workspace_model (); + + void event_accepted (octave_event *e); + void event_reject (octave_event *e); + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + void insert_top_level_item (int at, tree_item *treeItem); + tree_item *top_level_item (int at); + +public slots: + void request_update_workspace (); + +signals: + void model_changed(); + +private: + /** Timer for periodically updating the workspace model from the current + * symbol information. */ + QTimer _update_workspace_model_timer; + + /** Stores the current symbol information. */ + QList _symbol_information; + tree_item *_rootItem; +}; + +#endif // WORKSPACEMODEL_H diff --git a/gui/src/workspace-view.cc b/gui/src/workspace-view.cc new file mode 100644 --- /dev/null +++ b/gui/src/workspace-view.cc @@ -0,0 +1,177 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "workspace-view.h" +#include +#include +#include + +workspace_view::workspace_view (QWidget * parent) : QDockWidget + (parent) +{ + setObjectName ("WorkspaceView"); + setWindowTitle (tr ("Workspace")); + + _workspace_model = new workspace_model (); + + _workspace_tree_view = new QTreeView (this); + _workspace_tree_view->setHeaderHidden (false); + _workspace_tree_view->setAlternatingRowColors (true); + //_workspace_tree_view->setAnimated (true); + _workspace_tree_view->setModel (_workspace_model); + + setWidget (new QWidget (this)); + QVBoxLayout *layout = new QVBoxLayout (); + layout->addWidget (_workspace_tree_view); + layout->setMargin (2); + widget ()->setLayout (layout); + + connect (this, SIGNAL (visibilityChanged (bool)), + this, SLOT(handle_visibility_changed (bool))); + + connect (_workspace_model, SIGNAL (model_changed ()), + this, SLOT (model_changed ())); + + connect (_workspace_tree_view, SIGNAL (collapsed (QModelIndex)), + this, SLOT (collapse_requested (QModelIndex))); + connect (_workspace_tree_view, SIGNAL (expanded (QModelIndex)), + this, SLOT (expand_requested (QModelIndex))); + + _explicit_collapse.local = false; + _explicit_collapse.global = false; + _explicit_collapse.persistent = false; + _explicit_collapse.hidden = false; +} + +void +workspace_view::handle_visibility_changed (bool visible) +{ + if (visible) + emit active_changed (true); +} + +void +workspace_view::model_changed () +{ + // This code is very quirky and requires some explanation. + // Usually, we should not deal with collapsing or expanding ourselves, + // because the view itself determines (based on the model) whether it + // is appropriate to collapse or expand items. + // + // Now, the logic requires that we update our model item by item, which + // would make it work correctly, but this is extremely slow and scales + // very bad (O(n^2)). That's why we throw away our model and rebuild it + // completely from scratch (O(n)), which is why the view renders all + // displayed data as invalid. + // + // In order to make collapsing/expanding work again, we need to set + // flags ourselves here. + + QModelIndex local_model_index = _workspace_model->index (0, 0); + QModelIndex global_model_index = _workspace_model->index (1, 0); + QModelIndex persistent_model_index = _workspace_model->index (2, 0); + QModelIndex hidden_model_index = _workspace_model->index (3, 0); + + if (_explicit_collapse.local) { + _workspace_tree_view->collapse (local_model_index); + } else { + _workspace_tree_view->expand (local_model_index); + } + + if (_explicit_collapse.global) { + _workspace_tree_view->collapse (global_model_index); + } else { + _workspace_tree_view->expand (global_model_index); + } + + if (_explicit_collapse.persistent) { + _workspace_tree_view->collapse (persistent_model_index); + } else { + _workspace_tree_view->expand (persistent_model_index); + } + + if (_explicit_collapse.hidden) { + _workspace_tree_view->collapse (hidden_model_index); + } else { + _workspace_tree_view->expand (hidden_model_index); + } +} + +void +workspace_view::collapse_requested (QModelIndex index) +{ + // This code is very quirky and requires some explanation. + // Usually, we should not deal with collapsing or expanding ourselves, + // because the view itself determines (based on the model) whether it + // is appropriate to collapse or expand items. + // + // Now, the logic requires that we update our model item by item, which + // would make it work correctly, but this is extremely slow and scales + // very bad (O(n^2)). That's why we throw away our model and rebuild it + // completely from scratch (O(n)), which is why the view renders all + // displayed data as invalid. + // + // In order to make collapsing/expanding work again, we need to set + // flags ourselves here. + QMap item_data + = _workspace_model->itemData (index); + + if (item_data[0] == "Local") + _explicit_collapse.local = true; + if (item_data[0] == "Global") + _explicit_collapse.global = true; + if (item_data[0] == "Persistent") + _explicit_collapse.persistent = true; + if (item_data[0] == "Hidden") + _explicit_collapse.hidden = true; +} + +void +workspace_view::expand_requested (QModelIndex index) +{ + // This code is very quirky and requires some explanation. + // Usually, we should not deal with collapsing or expanding ourselves, + // because the view itself determines (based on the model) whether it + // is appropriate to collapse or expand items. + // + // Now, the logic requires that we update our model item by item, which + // would make it work correctly, but this is extremely slow and scales + // very bad (O(n^2)). That's why we throw away our model and rebuild it + // completely from scratch (O(n)), which is why the view renders all + // displayed data as invalid. + // + // In order to make collapsing/expanding work again, we need to do set + // flags ourselves here. + QMap item_data + = _workspace_model->itemData (index); + + if (item_data[0] == "Local") + _explicit_collapse.local = false; + if (item_data[0] == "Global") + _explicit_collapse.global = false; + if (item_data[0] == "Persistent") + _explicit_collapse.persistent = false; + if (item_data[0] == "Hidden") + _explicit_collapse.hidden = false; +} + +void +workspace_view::closeEvent (QCloseEvent *event) +{ + emit active_changed (false); + QDockWidget::closeEvent (event); +} diff --git a/gui/src/workspace-view.h b/gui/src/workspace-view.h new file mode 100644 --- /dev/null +++ b/gui/src/workspace-view.h @@ -0,0 +1,63 @@ +/* OctaveGUI - A graphical user interface for Octave + * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WORKSPACEVIEW_H +#define WORKSPACEVIEW_H + +#include +#include +#include +#include "octave-link.h" +#include "workspace-model.h" + +class workspace_view : public QDockWidget +{ + Q_OBJECT +public: + workspace_view (QWidget * parent = 0); + +public slots: + void handle_visibility_changed (bool visible); + void model_changed (); + +signals: + /** Custom signal that tells if a user has clicke away that dock widget. */ + void active_changed (bool active); + +protected: + void closeEvent (QCloseEvent *event); + +protected slots: + void collapse_requested (QModelIndex index); + void expand_requested (QModelIndex index); + +private: + QTreeView *_workspace_tree_view; + + /** Stores the current workspace model. */ + workspace_model *_workspace_model; + + struct + { + bool local; + bool global; + bool persistent; + bool hidden; + } _explicit_collapse; +}; + +#endif // WORKSPACEVIEW_H diff --git a/gui/translators b/gui/translators new file mode 100644 --- /dev/null +++ b/gui/translators @@ -0,0 +1,8 @@ +# Below Octave GUI translators are listed with their e-mails +# to be able inform them about generic translation file changes +en-en Jacob Dawid +es-es Valentin Ortega-Clavero +de-de Jacob Dawid +pt-br Júlio Hoffimann Mendes +ru-ru Andriy Shinkarchuck +uk-ua Andriy Shinkarchuck diff --git a/scripts/plot/__gnuplot_drawnow__.m b/scripts/plot/__gnuplot_drawnow__.m diff --git a/src/symtab.h b/src/symtab.h