From 980af5458adb5bd06044af36c3edd69ff2541ba2 Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Wed, 27 Apr 2016 20:28:51 +0200 Subject: [PATCH] Released v1 --- ChangeLog | 4 + INSTALL | 182 +++++ Makefile.in | 51 ++ README | 91 +++ TODO | 23 + config.h.in | 165 +++++ configure.in | 110 +++ create_source_htmls | 33 + data/Makefile.in | 46 ++ data/botcommander.desktop.in.in | 11 + data/botcommander.schemas.in | 154 ++++ debian/README.Debian | 6 + debian/botcommander-default.ex | 10 + debian/botcommander.doc-base.EX | 22 + debian/changelog | 6 + debian/compat | 1 + debian/control | 14 + debian/copyright | 14 + debian/cron.d.ex | 4 + debian/dirs | 2 + debian/docs | 1 + debian/emacsen-install.ex | 45 ++ debian/emacsen-remove.ex | 15 + debian/emacsen-startup.ex | 25 + debian/init.d.ex | 74 ++ debian/manpage.1.ex | 59 ++ debian/manpage.sgml.ex | 156 ++++ debian/manpage.xml.ex | 148 ++++ debian/menu.ex | 2 + debian/postinst.ex | 42 ++ debian/postrm.ex | 38 + debian/preinst.ex | 38 + debian/prerm.ex | 38 + debian/rules | 107 +++ debian/watch.ex | 22 + doc/Makefile.in | 31 + doc/botcommander.texinfo | 349 +++++++++ doc/botcommander.xml | 542 ++++++++++++++ doc/version.texinfo | 2 + eggdrop/botcommander.tcl | 50 ++ gentoo/net-misc/botcommander/ChangeLog | 9 + gentoo/net-misc/botcommander/Manifest | 16 + .../botcommander/botcommander-1.0.ebuild | 34 + .../files/digest-botcommander-1.0 | 3 + gentoo/net-misc/botcommander/metadata.xml | 8 + include/defines.h | 76 ++ include/functions.h | 161 +++++ include/typedefs.h | 187 +++++ include/variables.h | 63 ++ pixmaps/Makefile.in | 16 + pixmaps/bc48.png | Bin 0 -> 3110 bytes pixmaps/bc48_trans.png | Bin 0 -> 3098 bytes po/BotCommander.pot | 307 ++++++++ po/Makefile.in.in | 221 ++++++ po/POTFILES.in | 13 + po/hu.po | 324 +++++++++ rules.in | 9 + src/Makefile.in | 33 + src/about.c | 91 +++ src/botlist.c | 532 ++++++++++++++ src/bots.c | 270 +++++++ src/callbacks.c | 518 ++++++++++++++ src/chanprops.c | 138 ++++ src/commands.c | 453 ++++++++++++ src/config.c | 611 ++++++++++++++++ src/debug.c | 69 ++ src/history.c | 123 ++++ src/main.c | 143 ++++ src/networking.c | 116 +++ src/setup.c | 366 ++++++++++ src/string.c | 244 +++++++ src/tabs.c | 677 ++++++++++++++++++ src/widgets.c | 412 +++++++++++ template | 26 + 74 files changed, 9002 insertions(+) create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.in create mode 100644 README create mode 100644 TODO create mode 100644 config.h.in create mode 100644 configure.in create mode 100755 create_source_htmls create mode 100644 data/Makefile.in create mode 100644 data/botcommander.desktop.in.in create mode 100644 data/botcommander.schemas.in create mode 100644 debian/README.Debian create mode 100644 debian/botcommander-default.ex create mode 100644 debian/botcommander.doc-base.EX create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/cron.d.ex create mode 100644 debian/dirs create mode 100644 debian/docs create mode 100644 debian/emacsen-install.ex create mode 100644 debian/emacsen-remove.ex create mode 100644 debian/emacsen-startup.ex create mode 100644 debian/init.d.ex create mode 100644 debian/manpage.1.ex create mode 100644 debian/manpage.sgml.ex create mode 100644 debian/manpage.xml.ex create mode 100644 debian/menu.ex create mode 100644 debian/postinst.ex create mode 100644 debian/postrm.ex create mode 100644 debian/preinst.ex create mode 100644 debian/prerm.ex create mode 100755 debian/rules create mode 100644 debian/watch.ex create mode 100644 doc/Makefile.in create mode 100644 doc/botcommander.texinfo create mode 100644 doc/botcommander.xml create mode 100644 doc/version.texinfo create mode 100644 eggdrop/botcommander.tcl create mode 100644 gentoo/net-misc/botcommander/ChangeLog create mode 100644 gentoo/net-misc/botcommander/Manifest create mode 100644 gentoo/net-misc/botcommander/botcommander-1.0.ebuild create mode 100644 gentoo/net-misc/botcommander/files/digest-botcommander-1.0 create mode 100644 gentoo/net-misc/botcommander/metadata.xml create mode 100644 include/defines.h create mode 100644 include/functions.h create mode 100644 include/typedefs.h create mode 100644 include/variables.h create mode 100644 pixmaps/Makefile.in create mode 100644 pixmaps/bc48.png create mode 100644 pixmaps/bc48_trans.png create mode 100644 po/BotCommander.pot create mode 100644 po/Makefile.in.in create mode 100644 po/POTFILES.in create mode 100644 po/hu.po create mode 100644 rules.in create mode 100644 src/Makefile.in create mode 100644 src/about.c create mode 100644 src/botlist.c create mode 100644 src/bots.c create mode 100644 src/callbacks.c create mode 100644 src/chanprops.c create mode 100644 src/commands.c create mode 100644 src/config.c create mode 100644 src/debug.c create mode 100644 src/history.c create mode 100644 src/main.c create mode 100644 src/networking.c create mode 100644 src/setup.c create mode 100644 src/string.c create mode 100644 src/tabs.c create mode 100644 src/widgets.c create mode 100644 template diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..0d2e46a --- /dev/null +++ b/ChangeLog @@ -0,0 +1,4 @@ +2007-04-09 19:41 Gergely Polonkai + + * Added this ChangeLog file. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..ef77c3a --- /dev/null +++ b/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.ac' is used to create `configure' by a program +called `autoconf'. You only need `configure.ac' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..edf73e6 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,51 @@ +include rules +subdirs = src doc pixmaps po data +SHELL = /bin/sh + +srcdir = @srcdir@ + +all: + @for dir in ${subdirs}; do \ + (cd $$dir && $(MAKE) all) \ + || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +install: + @for dir in ${subdirs}; do \ + (cd $$dir && $(MAKE) install) \ + || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +clean: + /bin/rm -f *~ + @for dir in ${subdirs}; do \ + (cd $$dir && $(MAKE) clean) \ + || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + +distclean: + @for dir in ${subdirs}; do \ + (cd $$dir && $(MAKE) distclean) \ + || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" + /bin/rm -f Makefile config.h config.status config.cache config.log intltool-extract intltool-merge intltool-update rules configure aclocal.m4 + /bin/rm -rf autom4te.cache/ + +# automatic re-running of configure if the configure.in file has changed +${srcdir}/configure: configure.in aclocal.m4 + cd ${srcdir} && autoconf + +# autoheader might not change config.h.in, so touch a stamp file +${srcdir}/config.h.in: stamp-h.in +${srcdir}/stamp-h.in: configure.in aclocal.m4 + cd ${srcdir} && autoheader + echo timestamp > ${srcdir}/stamp-h.in + +config.h: stamp-h +stamp-h: config.h.in config.status + ./config.status +Makefile: Makefile.in config.status + ./config.status +config.status: configure + ./config.status --recheck + diff --git a/README b/README new file mode 100644 index 0000000..274b494 --- /dev/null +++ b/README @@ -0,0 +1,91 @@ +This short document is originally based on eggdrop's README file. + +Contents + +0. Important notice +1. What is BotCommander +2. How do I get BotCommander? +3. Quick startup +4. Frequently Asked Questions +5. Legal stuff +6. Documentation +7. Obtaining help + + _________________________________________________________________ + + + (0) NOTICE + + Please read this document, and the original BotCommander documentation + before asking for help! These files contain almost everything possible, and + are always growing, as people ask me more and more questions. + + _________________________________________________________________ + + + (1) WHAT IS BOTCOMMANDER? + + BotCommander is a customisable telnet client, heavily specialized with the + usage with Eggdrop IRC bots. Currently it possesses only the planned basic + functionality, but I have many-many plans, such as module-writing, + scripting and such. + + BotCommander is continously updated: bugs are getting fixed, and new + features are being added, which sometimes can cause new bugs. Currently + there is a so called "stable" version out there, but there are still known + bugs. + + _________________________________________________________________ + + + (2) HOW DO I GET BOTCOMMANDER? + + Before you can install/compile BotCommander, you will need several other + software installed on your machine. + + As BotCommander currently depends heavily on GTK+ 2 and Gnome 2, you will + need these. If you are planning (or must) install BotCommander from + sources, you will also need the development libraries of them. These + software comes with most of the Linux/Unix distributions, so the only thing + you may have to do is to install them. + + The current stable version (as of writing) is 1.0; you can download it + (amongst many other files) from http://www.botcommander.hu/. + + Optionally, you can get the latest SVN version from + http://www.botcommander.hu/files/botcommander-svn.tar.bz2. BUT BEWARE! This + version may contain code snippets which will never compile on any machine! + This is because I'm a nasty developer, and sometimes upload this kind of + code, so I can continue coding on my other machine after an svn update. I'm + also planning to add anonymous SVN access, but currently I don't have + enough knowledge about SVN to do such thing. + + _________________________________________________________________ + + + (3) QUICK STARTUP + + About installation quick-start you should read the INSTALL file; about + usage, you should go and read the original BotCommander documentation. The + latter is written in DocBook XML, and is compiled into a PDF document upon + a successful installation. It can be found in the doc/ directory. + + _________________________________________________________________ + + + (4) FREQUENTLY ASKED QUESTIONS + + _________________________________________________________________ + + + (5) LEGAL STUFF + + _________________________________________________________________ + + + (6) DOCUMENTATION + + _________________________________________________________________ + + + (7) OBTAINING HELP diff --git a/TODO b/TODO new file mode 100644 index 0000000..0878181 --- /dev/null +++ b/TODO @@ -0,0 +1,23 @@ +* Preferences + - Save recalled command at the end of history? + - Save command to history which is already there somewhere? + +* Bot list + - Edit Save in conf backend + +* Command completion + +* If there is a command which can be abbreviated and one + which can not, get_command_from_abbrev() should return the former. + +* User should be able to set local vhost to use. + +* (Channel and Handle list) hideable. + +* Create a status icon. + +* BotCommander SWITCH command. This will act like the CONNECT command, but it will connect in a new tab. If the specified bot is already connected in one of the tabs, BotCommander will switch to that tab instead of opening a new one. + +* Contents of aclocal.m4 can be splitted somehow. But where to? + +* http://www.botcommander.hu/files/botcommander-latest.tar.bz2 <= http://www.botcommander.hu/latest diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..bbb4bef --- /dev/null +++ b/config.h.in @@ -0,0 +1,165 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * config.h.in + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * This file holds some default settings. + }}} */ + +/* This is the GConf path where BC stores it's settings. You should leave this + * as the default */ +#define GCONF2_ROOT "/apps/botcommander" + +/* {{{ Default settings */ +#define DEFAULT_SCROLL_ON_OUTPUT TRUE +#define DEFAULT_CHANGE_TO_MESSAGE TRUE +#define DEFAULT_DEBUG FALSE +#define DEFAULT_TRANSPARENT_BACKGROUND FALSE +#define DEFAULT_BACKGROUND_SATURATION 1.0 +#define DEFAULT_DEFAULT_MODE "B" +#define DEFAULT_VTE_FONT "Courier 10 Pitch 12" +#define DEFAULT_CHANGE_TO_NEW_TAB FALSE +#define DEFAULT_HISTORY_LENGTH 100 +/* }}} */ + +/* Eggdrop itself uses ISO-8859-1 when using the default english language. You + * only have to change this if you use a different language file (e.g hungarian + * is usually in ISO-8859-2), or you use a script or module which sends out + * characters in a different character set. */ +#define BOT_CHARSET "ISO-8859-1" + +#define MAX_READ_LINE_LEN 1024 + +/* config.h.in. Most of this file is generated from configure.in by + * autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* GETTEXT package name */ +#undef GETTEXT_PACKAGE + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the `setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to `int' if does not define. */ +#undef ssize_t + +/* Package pixmaps directory */ +#undef PACKAGE_PIXMAPS_DIR + +/* Package local directory */ +#undef PACKAGE_LOCALE_DIR + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..583c6c3 --- /dev/null +++ b/configure.in @@ -0,0 +1,110 @@ +AC_PREREQ(2.60) +AC_INIT(BotCommander, 1.0, polesz@botcommander.hu) +AM_INIT_AUTOMAKE + +PACKAGE=botcommander +BOTCOMMANDER_VERSION=1.0 +ALL_LINGUAS=hu +GETTEXT_PACKAGE=botcommander + +GLIB_REQUIRED=2.0.6 +GDK_PIXBUF_REQUIRED=2.0.0 +GTK_REQUIRED=2.2.0 +GNOME_REQUIRED=2.0.2 +GNOME_UI_REQUIRED=2.0.2 +VTE_REQUIRED=0.9.0 + +AC_GNU_SOURCE +AM_GNU_GETTEXT +AM_GLIB_GNU_GETTEXT + +AC_SUBST(GLIB_REQUIRED) +AC_SUBST(GDK_PIXBUF_REQUIRED) +AC_SUBST(GTK_REQUIRED) +AC_SUBST(GNOME_REQUIRED) +AC_SUBST(GNOME_UI_REQUIRED) +AC_SUBST(VTE_REQUIRED) +AC_SUBST(GETTEXT_PACKAGE) +AC_SUBST(PACKAGE) + +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name]) + +if test "x${prefix}" = "xNONE"; then + packageprefix=${ac_default_prefix} +else + packageprefix=${prefix} +fi + +if test "x${prefix}" = "xNONE"; then + AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${ac_default_prefix}/${DATADIRNAME}/locale", [Package local directory]) +else + AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${prefix}/${DATADIRNAME}/locale", [Package local directory]) +fi + +packagepixmapsdir=share/pixmaps/${PACKAGE} + +PACKAGE_PIXMAPS_DIR="${packageprefix}/${packagepixmapsdir}" +AC_SUBST(PACKAGE_PIXMAPS_DIR) + +AC_DEFINE_UNQUOTED(PACKAGE_PIXMAPS_DIR, "${packageprefix}/${packagepixmapsdir}", [Package pixmaps directory]) + +AC_CONFIG_HEADER([config.h]) + +AC_ARG_ENABLE(debug, [ --enable-debug Enable debug mode], CFLAGS="$CFLAGS -DDEBUG -g -Wall") + +dnl Check for required programs +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +IT_PROG_INTLTOOL +AC_CHECK_PROGS([TEXI2PDF], [texi2pdf]) + +dnl Check for extensions +AC_OBJEXT +AC_EXEEXT + +dnl Check for math library +AC_CHECK_LIB([m], [exp10]) +AC_ISC_POSIX + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([fcntl.h libintl.h locale.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SSIZE_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_TYPE_SIGNAL +AC_CHECK_FUNCS([gethostbyname memset setlocale socket strchr strerror strtol]) + +PKG_PROG_PKG_CONFIG([0.9.0]) + +if test x$PKG_CONFIG = xno; then + AC_MSG_ERROR(Please install the pkg-config package!); +fi + +PKG_CHECK_MODULES(BOTCOMMANDER, glib-2.0 >= $GLIB_REQUIRED gtk+-2.0 >= $GTK_REQUIRED libgnome-2.0 >= $GNOME_REQUIRED libgnomeui-2.0 >= $GNOME_REQUIRED vte >= $VTE_REQUIRED gconf-2.0) + +AC_SUBST(BOTCOMMANDER_CFLAGS) +AC_SUBST(BOTCOMMANDER_LIBS) + +AM_GCONF_SOURCE_2 + +AC_PATH_PROG([GCONFTOOL], [gconftool-2], [no]) +if test "x$GCONFTOOL" = "xno"; then + AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf]) +fi + +AC_CONFIG_FILES([rules + Makefile + data/Makefile + doc/Makefile + src/Makefile + pixmaps/Makefile + po/Makefile.in + data/botcommander.desktop.in + data/botcommander.schemas]) +AC_OUTPUT diff --git a/create_source_htmls b/create_source_htmls new file mode 100755 index 0000000..07260ba --- /dev/null +++ b/create_source_htmls @@ -0,0 +1,33 @@ +#! /bin/sh + +MAIN_DIR=source_html +C2HTML=`which c2html` + +if [ x$C2HTML = x ] +then + echo "c2html not found. Please install that first!" + exit 1 +fi + +rm -rf $MAIN_DIR +mkdir -p $MAIN_DIR + +echo " + + BotCommander sources in HTML + + +

BotCommander sources in HTML

" >> $MAIN_DIR/index.html + +for FILE in `find -name \*.[ch]` +do + DIR=`dirname $FILE` + mkdir -p $MAIN_DIR/$DIR + cat $FILE | c2html > $MAIN_DIR/$FILE.html + echo " $FILE
" >> $MAIN_DIR/index.html +done + +echo " +" >> $MAIN_DIR/index.html + +exit 0 diff --git a/data/Makefile.in b/data/Makefile.in new file mode 100644 index 0000000..2526766 --- /dev/null +++ b/data/Makefile.in @@ -0,0 +1,46 @@ +include ../rules + +GCONFTOOL = @GCONFTOOL@ + +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +sysconfdir = @sysconfdir@ +datarootdir = @datarootdir@ +datadir = @datadir@ + +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@ +INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@ +GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ +GCONF_SCHEMAS_INSTALL_TRUE = @GCONF_SCHEMAS_INSTALL_TRUE@ +GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ + +gnomemenudir = $(datadir)/applications +gnomemenu_premerge_file = botcommander.desktop.in +gnomemenu_DATA = $(gnomemenu_premerge_file:.desktop.in=.desktop) + +schema_in_files = botcommander.schemas.in +schemadir = $(GCONF_SCHEMA_FILE_DIR) +schema_DATA = $(schema_in_files:.schemas.in=.schemas) + +all: $(gnomemenu_DATA) +clean: + +install: $(gnomemenu_DATA) +@GCONF_SCHEMAS_INSTALL_TRUE@ if test -z "$(DESTDIR)" ; then \ +@GCONF_SCHEMAS_INSTALL_TRUE@ for p in $(schema_DATA) ; do \ +@GCONF_SCHEMAS_INSTALL_TRUE@ GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(top_builddir)/data/$$p >&1 > /dev/null; \ +@GCONF_SCHEMAS_INSTALL_TRUE@ done \ +@GCONF_SCHEMAS_INSTALL_TRUE@ fi + $(top_srcdir)/mkinstalldirs $(gnomemenudir) + $(top_srcdir)/mkinstalldirs $(schemadir) + $(INSTALL) -m 0644 $(gnomemenu_DATA) $(gnomemenudir) + $(INSTALL) -m 0644 $(schema_DATA) $(schemadir) + +distclean: + rm -f botcommander.desktop botcommander.desktop.in botcommander.schemas Makefile + +@INTLTOOL_DESKTOP_RULE@ + +@INTLTOOL_SCHEMAS_RULE@ + diff --git a/data/botcommander.desktop.in.in b/data/botcommander.desktop.in.in new file mode 100644 index 0000000..d48c9f2 --- /dev/null +++ b/data/botcommander.desktop.in.in @@ -0,0 +1,11 @@ +[Desktop Entry] +_Name=BotCommander +_Comment=BotCommander eggdrop client +Exec=botcommander +Icon=@PACKAGE_PIXMAPS_DIR@/bc48_trans.png +Terminal=false +X-MultipleArgs=false +Type=Application +Categories=Application;Network; +Encoding=UTF-8 +StartupNotify=true diff --git a/data/botcommander.schemas.in b/data/botcommander.schemas.in new file mode 100644 index 0000000..4af305e --- /dev/null +++ b/data/botcommander.schemas.in @@ -0,0 +1,154 @@ + + + + /schemas/apps/botcommander/background_saturation + /apps/botcommander/background_saturation + botcommander + float + 0.0 + + Background is not opaque by default + background_saturation only has effect when transparent_background is true. If so, this value gives the opacity of the VTE + + + A háttér alapértelmezés szerint nem áttetsző + A background_saturation értékét csak akkor veszi figyelembe a program, ha a transparent_background értéke true. Ha így van, ez az érték adja meg a VTE áttetszőségének mértékét. + + + + /schemas/apps/botcommander/change_to_message + /apps/botcommander/change_to_message + botcommander + bool + true + + By default, BotCommander will change to Message mode after connecting to a bot + When this option is true, BotCommander will set Message mode after connecting to a bot + + + Alapértelmezés szerint a BotCommander átvált Üzenet módba miután csatlakozott egy bothoz + Ha ez az opció true, a BotCommander átvált Üzenet módba, miután csatlakozott egy bothoz + + + + /schemas/apps/botcommander/change_to_new_tab + /apps/botcommander/change_to_new_tab + botcommander + bool + true + + BotCommander changes to the newly created tab by default + When this value is true, BotCommander will change to the newly opened tab. Otherwise, the new tab won't be activated + + + A BotCommander alapértelmezés szerint átvált az újonnan létrehozott fülre + Ha ez az érték true, a BotCommander automatikusan átvált az újonnan megnyitott fülre. Ha nem, a fül nem lesz aktiválva + + + + /schemas/apps/botcommander/debug + /apps/botcommander/debug + botcommander + bool + false + + By default, BotCommander won't print out debug messages + If this option is true, and the code is compiled with the DEBUG flag, BotCommander will print debug messages + + + Alapértelmezés szerint a BotCommander nem fogja kiírni a hibakereső üzeneteket + Ha ez az opció be van kapcsolva, és a kód a DEBUG opcióval lett fordítva, a BotCommander folyamatosan kiírja a hibakereső üzeneteket + + + + /schemas/apps/botcommander/default_mode + /apps/botcommander/default_mode + botcommander + string + B + + By default, BotCommander will use BotCommander command mode + When you open a new tab, BotCommander will use this mod as the initial mode of the tab + + + Alapértelmezés szerint a BotCommander Botcommander Parancs-módot használ + Mikor megnyitsz egy új fület, a BotCommander ezt a módot állítja be rajta + + + + /schemas/apps/botcommander/history_length + /apps/botcommander/history_length + botcommander + int + 300 + + The default scrollback-size for the VTEs is 300 lines + The VTEs scrollback is set to this value + + + A VTE-k memóritára alapértelmezésben 300 sor + A VTE-k memóriatárának mérete ennyi sorra van állítva + + + + /schemas/apps/botcommander/sanity + /apps/botcommander/sanity + botcommander + string + Needed for gconf sanity check, please don't remove! + + NEVER CHANGE THIS VALUE! + NEVER CHANGE THIS VALUE! This is for sanity check. Maybe I'll remove it soon. NEVER CHANGE THIS VALUE! + + + SOHA NE VÁLTOZTASD MEG EZT AZ ÉRTÉKET! + SOHA NE VÁLTOZTASD MEG EZT AZ ÉRTÉKET! Ez a gconf ellenőrzésére szolgál. Valószínűleg hamarosan törlöm. SOHA NE VÁLTOZTAST MEG EZT AZ ÉRTÉKET! + + + + /schemas/apps/botcommander/scroll_on_output + /apps/botcommander/scroll_on_output + botcommander + bool + true + + By default, BotCommander will scroll the contents of the VTE when new data arrives from the bot + When this option is true, BotCommander will automatically scroll to the bottom of the window when a new line arrives from the bot + + + Alapértelmezés szerint a BotCommander a VTE aljára görget, ha új adat érkezik a bottól + Ha ez az opció true, a BotCommander automatikusan a VTE aljára görget, ha új adat érkezik a bottól + + + + /schemas/apps/botcommander/transparent_background + /apps/botcommander/transparent_background + botcommander + bool + false + + By default, the VTEs' background is not transparent + If you set this option to true, and background_saturation to a number greater then 0, the VTEs' background will be opaque + + + Alapértelmezés szerint a VTE-k háttere nem áttetsző + Ha ezt az értéket true-ra állítod, a background_saturation értékét pedig 0-nál nagyobbra, a VTE-k háttere áttetsző lesz + + + + /schemas/apps/botcommander/vte_font + /apps/botcommander/vte_font + botcommander + string + Courier 10 Pitch 12 + + By default, the VTEs use the Courier 10 Pitch font with a 12pt size + The VTEs' font will set to this value + + + Alapértelmezés szerint a VTE-k a Courier 10 Pitch font 12pt méretű változatát használják + Ez az érték lesz megadva, mint a VTE-k betűkészlete + + + + diff --git a/debian/README.Debian b/debian/README.Debian new file mode 100644 index 0000000..fa8abec --- /dev/null +++ b/debian/README.Debian @@ -0,0 +1,6 @@ +botcommander for Debian +----------------------- + + + + -- Gergely POLONKAI , Mon, 11 Sep 2006 07:31:20 +0200 diff --git a/debian/botcommander-default.ex b/debian/botcommander-default.ex new file mode 100644 index 0000000..4813ccd --- /dev/null +++ b/debian/botcommander-default.ex @@ -0,0 +1,10 @@ +# Defaults for botcommander initscript +# sourced by /etc/init.d/botcommander +# installed at /etc/default/botcommander by the maintainer scripts + +# +# This is a POSIX shell fragment +# + +# Additional options that are passed to the Daemon. +DAEMON_OPTS="" diff --git a/debian/botcommander.doc-base.EX b/debian/botcommander.doc-base.EX new file mode 100644 index 0000000..0be1ab0 --- /dev/null +++ b/debian/botcommander.doc-base.EX @@ -0,0 +1,22 @@ +Document: botcommander +Title: Debian botcommander Manual +Author: Gergely POLONKAI (polesz@botcommander.hu) +Abstract: This manual describes what botcommander is + and how it can be used to + manage online manuals on Debian systems. +Section: utils + +Format: debiandoc-sgml +Files: /usr/share/doc/botcommander/botcommander.sgml.gz + +Format: postscript +Files: /usr/share/doc/botcommander/botcommander.ps.gz + +Format: text +Files: /usr/share/doc/botcommander/botcommander.text.gz + +Format: HTML +Index: /usr/share/doc/botcommander/html/index.html +Files: /usr/share/doc/botcommander/html/*.html + + diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..1237317 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +botcommander (1.0-1) unstable; urgency=low + + * Initial release (Closes: #nnnn) + + -- POLONKAI Gergely Mon, 11 Sep 2006 07:41:46 +0200 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..dba8943 --- /dev/null +++ b/debian/control @@ -0,0 +1,14 @@ +Source: botcommander +Section: utils +Priority: optional +Maintainer: Gergely POLONKAI +Build-Depends: debhelper (>= 5), autotools-dev, libgnomeui-0, libvte4, libgtk2.0-0, libgconf2-4 +Standards-Version: 3.7.2 + +Package: botcommander +Architecture: i386 +Depends: ${shlibs:Depends} +Description: BotCommander is a graphical eggdrop client for UN*X sytems + BotCommander is a graphical eggdrop client written for UN*X systems. This is + still a work-in-progress, as it already functional. There are still many plans + which are not implemented yet. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..a7928bf --- /dev/null +++ b/debian/copyright @@ -0,0 +1,14 @@ +This package was debianized by Gergely POLONKAI on +Mon, 11 Sep 2006 07:31:20 +0200. + +It was downloaded from http://www.botcommander.hu/ + +Upstream Author: Gergely POLONKAI + +Copyright: Gergely POLONKAI, 2006 + +License: GNU GPL, version 2 or later + +The Debian packaging is (C) 2006, Gergely POLONKAI and +is licensed under the GPL, see `/usr/share/common-licenses/GPL'. + diff --git a/debian/cron.d.ex b/debian/cron.d.ex new file mode 100644 index 0000000..af409a3 --- /dev/null +++ b/debian/cron.d.ex @@ -0,0 +1,4 @@ +# +# Regular cron jobs for the botcommander package +# +0 4 * * * root botcommander_maintenance diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..b99fd7c --- /dev/null +++ b/debian/dirs @@ -0,0 +1,2 @@ +usr/bin +usr/share/pixmaps/botcommander diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..1333ed7 --- /dev/null +++ b/debian/docs @@ -0,0 +1 @@ +TODO diff --git a/debian/emacsen-install.ex b/debian/emacsen-install.ex new file mode 100644 index 0000000..036afa3 --- /dev/null +++ b/debian/emacsen-install.ex @@ -0,0 +1,45 @@ +#! /bin/sh -e +# /usr/lib/emacsen-common/packages/install/botcommander + +# Written by Jim Van Zandt , borrowing heavily +# from the install scripts for gettext by Santiago Vila +# and octave by Dirk Eddelbuettel . + +FLAVOR=$1 +PACKAGE=botcommander + +if [ ${FLAVOR} = emacs ]; then exit 0; fi + +echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR} + +#FLAVORTEST=`echo $FLAVOR | cut -c-6` +#if [ ${FLAVORTEST} = xemacs ] ; then +# SITEFLAG="-no-site-file" +#else +# SITEFLAG="--no-site-file" +#fi +FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile" + +ELDIR=/usr/share/emacs/site-lisp/${PACKAGE} +ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE} + +# Install-info-altdir does not actually exist. +# Maybe somebody will write it. +if test -x /usr/sbin/install-info-altdir; then + echo install/${PACKAGE}: install Info links for ${FLAVOR} + install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/info/${PACKAGE}.info.gz +fi + +install -m 755 -d ${ELCDIR} +cd ${ELDIR} +FILES=`echo *.el` +cp ${FILES} ${ELCDIR} +cd ${ELCDIR} + +cat << EOF > path.el +(setq load-path (cons "." load-path) byte-compile-warnings nil) +EOF +${FLAVOR} ${FLAGS} ${FILES} +rm -f *.el path.el + +exit 0 diff --git a/debian/emacsen-remove.ex b/debian/emacsen-remove.ex new file mode 100644 index 0000000..7dc9741 --- /dev/null +++ b/debian/emacsen-remove.ex @@ -0,0 +1,15 @@ +#!/bin/sh -e +# /usr/lib/emacsen-common/packages/remove/botcommander + +FLAVOR=$1 +PACKAGE=botcommander + +if [ ${FLAVOR} != emacs ]; then + if test -x /usr/sbin/install-info-altdir; then + echo remove/${PACKAGE}: removing Info links for ${FLAVOR} + install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/info/botcommander.info.gz + fi + + echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR} + rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE} +fi diff --git a/debian/emacsen-startup.ex b/debian/emacsen-startup.ex new file mode 100644 index 0000000..70f1a36 --- /dev/null +++ b/debian/emacsen-startup.ex @@ -0,0 +1,25 @@ +;; -*-emacs-lisp-*- +;; +;; Emacs startup file, e.g. /etc/emacs/site-start.d/50botcommander.el +;; for the Debian botcommander package +;; +;; Originally contributed by Nils Naumann +;; Modified by Dirk Eddelbuettel +;; Adapted for dh-make by Jim Van Zandt + +;; The botcommander package follows the Debian/GNU Linux 'emacsen' policy and +;; byte-compiles its elisp files for each 'emacs flavor' (emacs19, +;; xemacs19, emacs20, xemacs20...). The compiled code is then +;; installed in a subdirectory of the respective site-lisp directory. +;; We have to add this to the load-path: +(let ((package-dir (concat "/usr/share/" + (symbol-name flavor) + "/site-lisp/botcommander"))) +;; If package-dir does not exist, the botcommander package must have +;; removed but not purged, and we should skip the setup. + (when (file-directory-p package-dir) + (setq load-path (cons package-dir load-path)) + (autoload 'botcommander-mode "botcommander-mode" + "Major mode for editing botcommander files." t) + (add-to-list 'auto-mode-alist '("\\.botcommander$" . botcommander-mode)))) + diff --git a/debian/init.d.ex b/debian/init.d.ex new file mode 100644 index 0000000..f975873 --- /dev/null +++ b/debian/init.d.ex @@ -0,0 +1,74 @@ +#! /bin/sh +# +# skeleton example file to build /etc/init.d/ scripts. +# This file should be used to construct scripts for /etc/init.d. +# +# Written by Miquel van Smoorenburg . +# Modified for Debian +# by Ian Murdock . +# +# Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl +# + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/botcommander +NAME=botcommander +DESC=botcommander + +test -x $DAEMON || exit 0 + +# Include botcommander defaults if available +if [ -f /etc/default/botcommander ] ; then + . /etc/default/botcommander +fi + +set -e + +case "$1" in + start) + echo -n "Starting $DESC: " + start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ + --exec $DAEMON -- $DAEMON_OPTS + echo "$NAME." + ;; + stop) + echo -n "Stopping $DESC: " + start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ + --exec $DAEMON + echo "$NAME." + ;; + #reload) + # + # If the daemon can reload its config files on the fly + # for example by sending it SIGHUP, do it here. + # + # If the daemon responds to changes in its config file + # directly anyway, make this a do-nothing entry. + # + # echo "Reloading $DESC configuration files." + # start-stop-daemon --stop --signal 1 --quiet --pidfile \ + # /var/run/$NAME.pid --exec $DAEMON + #;; + restart|force-reload) + # + # If the "reload" option is implemented, move the "force-reload" + # option to the "reload" entry above. If not, "force-reload" is + # just the same as "restart". + # + echo -n "Restarting $DESC: " + start-stop-daemon --stop --quiet --pidfile \ + /var/run/$NAME.pid --exec $DAEMON + sleep 1 + start-stop-daemon --start --quiet --pidfile \ + /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS + echo "$NAME." + ;; + *) + N=/etc/init.d/$NAME + # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $N {start|stop|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/debian/manpage.1.ex b/debian/manpage.1.ex new file mode 100644 index 0000000..bd395cc --- /dev/null +++ b/debian/manpage.1.ex @@ -0,0 +1,59 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH BOTCOMMANDER SECTION "szeptember 11, 2006" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +botcommander \- program to do something +.SH SYNOPSIS +.B botcommander +.RI [ options ] " files" ... +.br +.B bar +.RI [ options ] " files" ... +.SH DESCRIPTION +This manual page documents briefly the +.B botcommander +and +.B bar +commands. +.PP +.\" TeX users may be more comfortable with the \fB\fP and +.\" \fI\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBbotcommander\fP is a program that... +.SH OPTIONS +These programs follow the usual GNU command line syntax, with long +options starting with two dashes (`-'). +A summary of options is included below. +For a complete description, see the Info files. +.TP +.B \-h, \-\-help +Show summary of options. +.TP +.B \-v, \-\-version +Show version of program. +.SH SEE ALSO +.BR bar (1), +.BR baz (1). +.br +The programs are documented fully by +.IR "The Rise and Fall of a Fooish Bar" , +available via the Info system. +.SH AUTHOR +botcommander was written by . +.PP +This manual page was written by Gergely POLONKAI , +for the Debian project (but may be used by others). diff --git a/debian/manpage.sgml.ex b/debian/manpage.sgml.ex new file mode 100644 index 0000000..c58d072 --- /dev/null +++ b/debian/manpage.sgml.ex @@ -0,0 +1,156 @@ + manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + + + The docbook-to-man binary is found in the docbook-to-man package. + Please remember that if you create the nroff version in one of the + debian/rules file targets (such as build), you will need to include + docbook-to-man in your Build-Depends control field. + + --> + + + FIRSTNAME"> + SURNAME"> + + szeptember 11, 2006"> + + SECTION"> + polesz@botcommander.hu"> + + BOTCOMMANDER"> + + + Debian"> + GNU"> + GPL"> +]> + + + +
+ &dhemail; +
+ + &dhfirstname; + &dhsurname; + + + 2003 + &dhusername; + + &dhdate; +
+ + &dhucpackage; + + &dhsection; + + + &dhpackage; + + program to do something + + + + &dhpackage; + + + + + + + + DESCRIPTION + + This manual page documents briefly the + &dhpackage; and bar + commands. + + This manual page was written for the &debian; distribution + because the original program does not have a manual page. + Instead, it has documentation in the &gnu; + Info format; see below. + + &dhpackage; is a program that... + + + + OPTIONS + + These programs follow the usual &gnu; command line syntax, + with long options starting with two dashes (`-'). A summary of + options is included below. For a complete description, see the + Info files. + + + + + + + + Show summary of options. + + + + + + + + Show version of program. + + + + + + SEE ALSO + + bar (1), baz (1). + + The programs are documented fully by The Rise and + Fall of a Fooish Bar available via the + Info system. + + + AUTHOR + + This manual page was written by &dhusername; &dhemail; for + the &debian; system (but may be used by others). Permission is + granted to copy, distribute and/or modify this document under + the terms of the &gnu; General Public License, Version 2 any + later version published by the Free Software Foundation. + + + On Debian systems, the complete text of the GNU General Public + License can be found in /usr/share/common-licenses/GPL. + + + +
+ + + + diff --git a/debian/manpage.xml.ex b/debian/manpage.xml.ex new file mode 100644 index 0000000..bafd0d6 --- /dev/null +++ b/debian/manpage.xml.ex @@ -0,0 +1,148 @@ + +.
will be generated. You may view the +manual page with: nroff -man .
| less'. A +typical entry in a Makefile or Makefile.am is: + +DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\ +manpages/docbook.xsl +XP=xsltproc -''-nonet + +manpage.1: manpage.dbk + $(XP) $(DB2MAN) $< + +The xsltproc binary is found in the xsltproc package. The +XSL files are in docbook-xsl. Please remember that if you +create the nroff version in one of the debian/rules file +targets (such as build), you will need to include xsltproc +and docbook-xsl in your Build-Depends control field. + +--> + + + FIRSTNAME"> + SURNAME"> + + szeptember 11, 2006"> + + SECTION"> + polesz@botcommander.hu"> + + BOTCOMMANDER"> + + + Debian"> + GNU"> + GPL"> +]> + + + +
+ &dhemail; +
+ + &dhfirstname; + &dhsurname; + + + 2003 + &dhusername; + + &dhdate; +
+ + &dhucpackage; + + &dhsection; + + + &dhpackage; + + program to do something + + + + &dhpackage; + + + + + + + + DESCRIPTION + + This manual page documents briefly the + &dhpackage; and bar + commands. + + This manual page was written for the &debian; distribution + because the original program does not have a manual page. + Instead, it has documentation in the &gnu; + Info format; see below. + + &dhpackage; is a program that... + + + + OPTIONS + + These programs follow the usual &gnu; command line syntax, + with long options starting with two dashes (`-'). A summary of + options is included below. For a complete description, see the + Info files. + + + + + + + + Show summary of options. + + + + + + + + Show version of program. + + + + + + SEE ALSO + + bar (1), baz (1). + + The programs are documented fully by The Rise and + Fall of a Fooish Bar available via the + Info system. + + + AUTHOR + + This manual page was written by &dhusername; &dhemail; for + the &debian; system (but may be used by others). Permission is + granted to copy, distribute and/or modify this document under + the terms of the &gnu; General Public License, Version 2 any + later version published by the Free Software Foundation. + + + On Debian systems, the complete text of the GNU General Public + License can be found in /usr/share/common-licenses/GPL. + + + +
+ diff --git a/debian/menu.ex b/debian/menu.ex new file mode 100644 index 0000000..dc29b4b --- /dev/null +++ b/debian/menu.ex @@ -0,0 +1,2 @@ +?package(botcommander):needs="X11|text|vc|wm" section="Apps/see-menu-manual"\ + title="botcommander" command="/usr/bin/botcommander" diff --git a/debian/postinst.ex b/debian/postinst.ex new file mode 100644 index 0000000..1cd89cd --- /dev/null +++ b/debian/postinst.ex @@ -0,0 +1,42 @@ +#!/bin/sh +# postinst script for botcommander +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package +# + +case "$1" in + configure) + + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/debian/postrm.ex b/debian/postrm.ex new file mode 100644 index 0000000..cf20add --- /dev/null +++ b/debian/postrm.ex @@ -0,0 +1,38 @@ +#!/bin/sh +# postrm script for botcommander +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `purge' +# * `upgrade' +# * `failed-upgrade' +# * `abort-install' +# * `abort-install' +# * `abort-upgrade' +# * `disappear' overwrit>r> +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + + + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/debian/preinst.ex b/debian/preinst.ex new file mode 100644 index 0000000..cc8f816 --- /dev/null +++ b/debian/preinst.ex @@ -0,0 +1,38 @@ +#!/bin/sh +# preinst script for botcommander +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + install|upgrade) + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/debian/prerm.ex b/debian/prerm.ex new file mode 100644 index 0000000..bb00807 --- /dev/null +++ b/debian/prerm.ex @@ -0,0 +1,38 @@ +#!/bin/sh +# prerm script for botcommander +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `upgrade' +# * `failed-upgrade' +# * `remove' `in-favour' +# * `deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + remove|upgrade|deconfigure) + ;; + failed-upgrade) + ;; + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..2f33fdc --- /dev/null +++ b/debian/rules @@ -0,0 +1,107 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +config.status: configure + dh_testdir + # Add here commands to configure the package. + ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs" --with-gconf-schema-file-dir=\$${prefix}/share/gconf/schemas + + +build: build-stamp + +build-stamp: config.status + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #docbook-to-man debian/botcommander.sgml > botcommander.1 + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) distclean +ifneq "$(wildcard /usr/share/misc/config.sub)" "" + cp -f /usr/share/misc/config.sub config.sub +endif +ifneq "$(wildcard /usr/share/misc/config.guess)" "" + cp -f /usr/share/misc/config.guess config.guess +endif + + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/botcommander. + $(MAKE) install prefix=$(CURDIR)/debian/botcommander/usr + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/debian/watch.ex b/debian/watch.ex new file mode 100644 index 0000000..27a0f34 --- /dev/null +++ b/debian/watch.ex @@ -0,0 +1,22 @@ +# Example watch control file for uscan +# Rename this file to "watch" and then you can run the "uscan" command +# to check for upstream updates and more. +# See uscan(1) for format + +# Compulsory line, this is a version 3 file +version=3 + +# Uncomment to examine a Webpage +# +#http://www.example.com/downloads.php botcommander-(.*)\.tar\.gz + +# Uncomment to examine a Webserver directory +#http://www.example.com/pub/botcommander-(.*)\.tar\.gz + +# Uncommment to examine a FTP server +#ftp://ftp.example.com/pub/botcommander-(.*)\.tar\.gz debian uupdate + +# Uncomment to find new files on sourceforge, for debscripts >= 2.9 +# http://sf.net/botcommander/botcommander-(.*)\.tar\.gz + + diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..3c8b1d9 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,31 @@ +include ../rules + +TEXI2PDF = @TEXI2PDF@ + +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +prefix = @prefix@ +datarootdir = @datarootdir@ +docdir = @docdir@ +PDFTARGETDIR = @pdfdir@ +top_srcdir = @top_srcdir@ + +all: $(DOC_OBJECTS) + +botcommander.pdf: botcommander.texinfo + $(TEXI2PDF) botcommander.texinfo + +clean: + $(RM) $(DOC_OBJECTS) + $(RM) botcommander.aux botcommander.cp botcommander.cps botcommander.fn \ + botcommander.ky botcommander.log botcommander.pg botcommander.toc \ + botcommander.tp botcommander.vr + +distclean: clean + $(RM) Makefile config.status config.cache config.log + +install: all + $(top_srcdir)/mkinstalldirs $(PDFTARGETDIR) + $(INSTALL) -m 0644 botcommander.pdf $(PDFTARGETDIR) + +.PHONY: all clean distclean install + diff --git a/doc/botcommander.texinfo b/doc/botcommander.texinfo new file mode 100644 index 0000000..4ed4611 --- /dev/null +++ b/doc/botcommander.texinfo @@ -0,0 +1,349 @@ +\input texinfo +@c vim:textwidth=80 +@c Header +@setfilename botcommander.info +@include version.texinfo +@settitle BotCommander @value{VERSION} +@documentdescription +BotCommander manual for version @value{VERSION} +@end documentdescription +@setchapternewpage odd +@firstparagraphindent insert + +@c Summary and Copyright +@copying +This manual is for BotCommander +(version @value{VERSION}, @value{UPDATED}), +which is a specialized telnet client. + +Copyright @copyright{} 2005, Gergely POLONKAI + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' +and with the Back-Cover Texts as in (a) below. A copy of the +license is included in the section entitled ``GNU Free Documentation +License.'' + +(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify +this GNU Manual, like GNU software. Copies published by the Free +Software Foundation raise funds for GNU development.'' +@end quotation +@end copying + +@dircategory Network Applications +@direntry +* BotCommander: (botcommander). +@end direntry + +@c Title and Copyright +@titlepage +@title BotCommander +@subtitle for version @value{VERSION}, @value{UPDATED} +@author Gergely POLONKAI (@email{polesz@@botcommander.hu}) +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@c Top node and master menu +@ifnottex +@node Top, About, , (dir) +@top BotCommander + +@insertcopying +@end ifnottex + +@menu +* About:: About the application +* Overview:: Features of BotCommander +* Installation:: How to install BotCommander +* Invoking:: Command line arguments +* Commands:: Internal commands +* Configuration:: The setup window +* Plans:: Plans in future versions +* Index:: Index +@end menu + +@c Body + +@node About, Overview, Top, Top +@chapter About BotCommander + +@cindex about + +@cindex homepage + +You can reach the project's homepage at @url{http://www.botcommander.hu/}. + +@cindex description + +BotCommander is a small tool, originally written for the Gnome2 interface, to +remotely manage your @url{http://www.eggheads.org/, eggdrop} IRC bots.@* +Actually, it's acting as a small, configurable telnet client, but it will know a +bit more. For example, it has command-line history. While you cannot recall your +previous command in a simple telnet client, you will be able to do it with this +program. As it uses a text box for the command line, you can easily edit that +command. + +The program uses @url{http://www.gnome.org/projects/gconf/, GConf2} +to store its configuration data. You can configure it to use a samba-like config +file instead, so you won't depend that heavily on @url{http://www.gnome.org/, +Gnome 2}, @xref{Installation}. In the near future I also plan +@url{http://www.w3.org/XML/, XML} config backend support. + +On 28 August, 2006 I decided to drop this plan, and also the samba-like config +backend for a longer period. I think the application should first function, and +only after that I can create such addons. + +@cindex status + +The code is in alpha status. You can see how will it look like, also can use +for one connection, and decide if you will like it or not. + +@cindex icon + +BotCommander icon is from @url{http://www.eggheads.org/, Eggdrop}'s official +homepage. I will draw a new one, but until then, this is perfect. + +@node Overview, Installation, About, Top +@chapter Features + +BotCommander is a telnet client and much more. It can connect to one or more +@url{http://www.eggheads.org/, eggdrop} IRC bots, and give commands to them. In +the near future it will also possible to give the same command to each connected +bots. + +Unlike the normal telnet client, this program has command line editing and +recalling possibilities. E.g if you have a long command line such + +@code{ +.process very much ugly paramters username +} +@*what you have to run multiple times, and in which you only change the username, +it is possible to recall the previous command, change the username, and send the +changed command. Thus, you don't have to enter the whole line again and again. + +It uses @url{http://www.gtk.org/, GTK2} and some @url{http://www.gnome.org/, +GnomeUI} components, and stores its configuration data in +@url{http://www.gnome.org/projects/gconf/, GConf2}. + +As it uses tabs, you can connect to many bots in one application, and at last +you won't have one icon for every bot in your task bar. + +If you want (and you are at least have global +o in the bot), you can have a +sidebar on your tabs, in which you can see a list of the channels and the users +you have. For this, you will need to install the @file{botcommander.tcl} script +(can be found in the @file{eggdrop/} directory) in your bot (@code{.source +botcommander.tcl}). When the script loads, or when someone connects to the bot +via DCC + +@node Installation, Invoking, Overview, Top +@chapter How to install? + +@cindex installation + +As BotCommander is currently in alpha phase, you cannot compile it with the +usual + +@example +./configure +make +make install +@end example + +sequence. First, you should edit the config.h file, and change the location of +the pixmaps dir. Then You should run @code{make check} to check if all the +required packages are installed on your system. At the moment these are + +@itemize +@item +pkg-config + +@item +gtk + +@item +vte + +@item +gconf2 + +@item +gnomeui2 +@end itemize + +If all is OK, simply run @code{make}. If nothing goes wrong, the binary will be +src/botcommander. + +If you want to install BotCommander, copy the binary to /usr/local/bin. You +should change the @code{PIXMAPSDIR} variable in @file{config.h} to something +like @code{/usr/local/share/botcommander}, and recompile the whole thing. + +@node Invoking, Commands, Installation, Top +@chapter Command line arguments + +@cindex command line args + +No command line arguments are defined yet. This means that BotCommander +currently accepts the @url{http://www.gnome.org/, Gnome} and +@url{http://www.gtk.org, GTK} standard command line parameters. + +Yet I don't even have any plans for such parameters. + +@node Commands, QUIT, Invoking, Top +@chapter Internal commands + +@cindex command + +BotCommander is a bit like an IRC client. As is, there are many commands built +in. + +Most of the commands can be abbreviated. This means you can shorten a command +while it is still obvious. + +For example, you can write @code{CON botname} instead of +@code{CONNECT botname}, as no other commands begin with ``CON''. + +However, there are some ``dangerous'' commands which cannot be abbreviated. One +such command is QUIT. + +@cindex internal command list + +@menu +* QUIT:: Exits BotCommander +* CLOSE:: Closes the active tab +* CONNECT:: Connects to a bot or a host +* ASSIGN:: Assigns a bot to the active tab +* MODE:: Changes the mode in the current tab +* HISTLIST:: Lists the previously issued commands and sent messages +* BOTLIST:: Opens the bot list window +* PREFERENCES:: Opens the setup dialog +* DISCONNECT:: Disconnects the current tab +@end menu + +@node QUIT, CLOSE, Commands, Commands +@section The QUIT command + +@cindex command, QUIT + +This command simply exists BotCommander. + +If at least one tab is open with an opened connection, BotCommander will pop up +a dialog if the user really wants to exit. + +These commands cannot be abbreviated. + +@node CLOSE, CONNECT, QUIT, Commands +@section The CLOSE command + +@cindex command, CLOSE + +This will close the active tab. If a connection is opened in the tab, +BotCommander will pop up a dialog if the user really wants to do that. + +@node CONNECT, ASSIGN, CLOSE, Commands +@section The CONNECT command + +@cindex command, CONNECT + +This will open a connection. You can use it in several ways. + +If you have already assigned a bot to the tab with the ASSIGN (@xref{ASSIGN}.) command, +you can use it without parameters, so it will connect to the assigned bot. + +If you have a bot in your bot list, you can connect to it with @code{CONNECT +botname}. It will also assign that bot to the tab. + +You can use it in the form @code{CONNECT host port}. + +@node ASSIGN, MODE, CONNECT, Commands +@section The ASSIGN command + +@cindex command, ASSIGN + +Assigns a bot to the active tab. You can use it in the form @code{ASSING +botname} or @code{ASSIGN host port}. After assigning a bot, you can use the +@code{CONNECT} command without parameters to connect to the bot. + +@node MODE, HISTLIST, ASSIGN, Commands +@section The MODE command + +@cindex command, MODE + +Sets the mode in the current tab. It has only one parameter, the new mode +character. It can be B for BotCommander command mode, E for Eggdrop command mode +or M for Message mode. + +You can see the current mode in the right side of the status bar. + +@node HISTLIST, BOTLIST, MODE, Commands +@section The HISTLIST command + +@cindex command, HISTLIST + +It's a very useless command. Prints out all the commands and messages you +entered in the current tab. + +@node BOTLIST, PREFERENCES, HISTLIST, Commands +@section The BOTLIST command + +@cindex command, BOTLIST + +This command simply opens the bot list dialog window. + +@node PREFERENCES, DISCONNECT, BOTLIST, Commands +@section The PREFERENCES command + +@cindex command, PREFERENCES + +This command simply opens the setup dialog. + +@node DISCONNECT, Configuration, PREFERENCES, Commands +@section The DISCONNECT command + +@cindex command, DISCONNECT + +This command forces the disconnection of the current tab. This is useful if you +try to connect a bot which doesn't respond, and you don't want to wait for the +"connection timeout" message before connecting to somewhere else. + +@node Configuration, Plans, DISCONNECT, Top +@chapter The preferences window + +@node Plans, Index, Configuration, Top +@chapter Future plans + +@cindex plans + +@itemize +@item +ADDBOT botname host port [nick] will add a new bot to the bot list + +@item +DELBOT botname will remove a bot from the bot list + +@item +Scripting. BotCommander will be able to run small scripts, perhaps in TCL + +@item +Macros and command aliases, so you have to type only one command to achieve the +same as you type in many + +@item +Windows port. This will be done after the whole application is functioning. So +this will be in the very far future, though I already got requests for it +@end itemize + +@node Index, , Plans, Top +@unnumbered Index + +@printindex cp + +@c End +@bye + diff --git a/doc/botcommander.xml b/doc/botcommander.xml new file mode 100644 index 0000000..a32bb00 --- /dev/null +++ b/doc/botcommander.xml @@ -0,0 +1,542 @@ + + + + BotCommander + + + + + Gergely + + POLONKAI + + + polesz@botcommander.hu + + + + 2005-2007 + + Gergely POLONKAI + + + + + + + I dedicate this book to my girlfriend, as she was so patient while I + wrote it. + + + + + + Table of Contents + + + Part I: About BotCommander and this book + + + Chapter 1: Who should read this book? + + + + Chapter 2: About BotCommander + + + + + + + + Preface + + This document tries to explain the history and usage of the software + BotCommander briefly. + + + + About BotCommander and this book + + + Who should read this book? + + + + Everyone, who handles at least one eggdrop IRC bot + + + + Everyone, who wants to write addons (modules) for + BotCommander + + + + Everyone, who wants to learn the script-writing methods for + BotCommander + + + + + + About BotCommander + + BotCommander is a specialized telnet client, and a bit more. It is + specialized in eggdrop IRC bot handling, enhanced with scripting + possibility, and may also be enhanced with self-written modules (just + like eggdrop itself). + + The project has its own homepage at + http://www.botcommander.hu/ + + + + BotCommander features + + + + Command line history + + + BotCommander has command line history. This means you can + recall your previous commands with the Up/Down keys, edit them, + and/or issue them again. + + + + + Tabbed interface + + + BotCommander has a tabbed interface, which means you can + have several connections in only one window - just like an IRC, or + IM client. + + + + + Channel and user list + + + If you have the correct permissions, you can have a list of + the bot's users and channels; also you will be able to manage + these: change user and channel flags and more. However, this + feature requires a small TCL script to be loaded in the bot (that + script is provided with BotCommander). + + + + + + + Some technical background + + BotCommander uses GConf2 to store its configuration, and all + bot-related data. The graphical part (the widgets) are from GTK+ + (currently using 2.6 features), and some are from libgnomeui. + + + + + Installation + + + About this part + + In this chapter you will learn about the installation methods of + BotCommander. You will be able to install BotCommander under several + Linux distributions, such as Debian and Gentoo, and also will know how + to install it from the sources. + + + + Install on Debian machines + + For a few years, I was a hardcore Debian-user. Thus, it was almost + my first task to create a Debian package out of BotCommander. + + I also created a Debian repository, so it is an easy task to + install BotCommander under a Debian system. Just add the following lines + to your sources list file. + + + The <filename>sources.list</filename> snippet required to + install BotCommander .deb packages with apt. + + deb http://www.botcommander.hu/debian testing main + + deb-src http://www.botcommander.hu/debian testing main + + + This snippet is only for debian etch (as of writing, at the end of + 2006). + + + + Install on Gentoo machines + + After my Debian years, my next Linux-breed was Gentoo. It's + absolutely does what the user wants (sure, if the user is smart enough). + After a few days of coding, a Gentoo ebuild was born. It is the part of + the BotCommander package, can be downloaded from + http://www.botcommander.hu/, and I'm also trying to add it to + the official Gentoo portage. + + + + Install from sources + + If you are not the user of the above systems, then currently no + package exists for your needs. I'm really sorry for that, but I always + welcome if someone sends me a package for any OS-es. + + So, you arrived here, you want to install BotCommander from + sources. This is good, but has some prerequisites: you will need bunch + of software you may not currently have installed. I'm trying to make + this list as correct as possible, but it may happen that I forgot about + something. I'm really sorry if so. + + + + autoconf v2.60 + + + This is required only if you want to compile the SVN tree, + as it doesn't contain a configure script. + + + + + gcc + + + gcc is the GNU C Compiler. This is a necessary tool. + + + + + gdk-pixbuf + + + This is the GDK-pixbuf library, required by BotCommander to + render some icons. + + + + + glib + + + This is the GLib library. BotCommander uses its + memory-handling routines. + + + + + GTK+ v2.6.2 or greater + + + This is the GTK library. BotCommander uses its widgets + heavily. + + + + + libgnome2 + + + This is the Gnome library. BotCommander uses some widgets in + it. + + + + + libgnomeui2 + + + This is the Gnome-UI library. BotCommander uses the file + open dialog from it. + + + + + VTE + + + This is the VTE (Virtual Terminal Emulation) library. + BotCommander displays all the bot-messages in such a + widget. + + + + + GNU Gettext package + + + This package is required for BotCommander to speak many + languages. I'm trying to make this one optional, so one will be + able to compile BotCommander without multilingual support (may be + good for english-speaking people, and for minimalist + systems) + + + + + + + + Basic eggdrop usage + + + Terms and assumptions + + Throughout this part we assume that you install your bot yourself, + and thus you have an owner flag in it. Many functions are not + accessible, if you don't possess that +n flag. + + + + Compiling and installing eggdrop + + + This chapter assumes that you have TCL installed system-wide. If + not, please consult the eggdrop manual on how to install it for one + single user, and how to make eggdrop use that library. I also assume + that you know how to use the basic Unix/Linux commands, such as tar, + thus you can unpack the eggdrop archive. + + + First things first, you much fetch eggdrop from somewhere. The + best place for this is eggheads' homepage at + http://www.eggheads.org/. Download the latest version (as of + writing, it is 1.6.18), and unpack it. Then enter the unpacked + distibution's directory, and issue the following commands: + + + Commands to configure and compile eggdrop + + ./configure + + make iconfig + + make + + + After issuing make iconfig, that script will + ask you several questions if you want to install this-or-that module. + Read the module descriptions, and choose whichever you need. + + + I'm currently planning to write my + botcommander.tcl script as an eggdrop module. If + I'm ready with that, I will instruct you how to compile new modules + for eggdrop. + + + After make finishes without errors, you can + issue the last, make install command. This will + install eggdrop to the given directory (if none was given, the default + is $HOME/eggdrop. + + + + Configuring your bot + + Configuring eggdrop is a long, yet not hard process, which + requires almost no understanding of eggdrop, if you know english. + + + The following is only a suggestion; contains my way on + configuring an eggdrop bot.You may do it several other ways; it's up + to you. However, if you read through this chapter, and follow my + words, I will assume that the name you have chosen your bot is + BCbot. + + + First of all, enter the directory which contains your eggdrop + installation. As said in the previous chapter, by default it is + $HOME/eggdrop. After that, make a copy of + eggdrop.conf with a filename as you will call your bot; then make it + executable for at least yourself. + + + Copy eggdrop.conf to your own file, and make it + executable. + + cp eggdrop.conf BCbot + + chmow 755 BCbot + + + Now begin to edit your newly created configuration. The most + important thing (of course, if you follow my way) it the very first row, + which now looks like this: + + #! /path/to/executable/eggdrop + + This tells the Unix/Linux shell to use + /path/to/executable/eggdrop to interpret this file. + Thus, the shell, instead of trying on interpreting the command in that + file, will run the given command with this file as a parameter. Unless + your eggdrop is at that location, you must change that line to something + like this: + + #! /home/yourusername/eggdrop/eggdrop + + + + + Usage + + + Command line parameters + + BotCommander doesn't have any defined command line parameters. + This means that it accepts only the standard Gnome and GTK+ parameters + only. I don't even have any plans on defining such things (yet). + + + + Built-in commands + + BotCommander has several built-in commands. These can be called + from BotCommander or external scripts, thus extending BotCommander's + functionality. + + Most of these commands can be abbreviated. This means that you can + cut off the end of the commands, until it is obvious to the application. + For example, as of the time of writing, the CONNECT command can be + abbreviated as CON. + + There are some "dangerous" commands, such as QUIT, which cannot be + abbreviated, so - in this case - you won't exit BotCommander if you + accidently type in the Q command. + +
+ QUIT + + The QUIT command does what it should according to its name: + exits BotCommander. + + If at least one connected tab is open, a small dialog will pop + up, asking if you are serious about quitting. + + This command cannot be abbreviated. +
+ +
+ CLOSE + + This command closes the currently active tab. If there is an + active connection in that tab, a dialog will pop up asking if you + really want to do that. + + This command cannot be abbreviated. +
+ +
+ CONNECT + + This will open a connection in the current tab. It has many + different invokations, depending on the parameters given. + + + + CONNECT without parameters will work if you previously + assigned a bot to the active tab with the ASSIGN command. If so, + the connection will be open to the given bot. + + + + CONNECT botname will connect to the named bot in the bot + list. + + + + CONNECT host port will connect to the specified host, on the + specified port. This can be useful, if you want to connect to a + bot only once, e.g to check some settings or such. + + + + CONNECT host port username does exactly as the above + command, but it will automatically send the given username also. + This will be useful as the initial connection to a bot, as I'm + planning to implement a SAVEBOT command, which will do just what + it name suggests: save the current bot to the bot list. + + +
+ +
+ ASSIGN + + The ASSIGN command does the same as CONNECT, with only one + difference: it won't connect. It will assign all the connection + parameters to the current tab, so when you are ready, you can use the + CONNECT command without any parameters to do the actual + connection. +
+ +
+ MODE + + The MODE command changes the current tab's mode. You can read + more about modes in +
+
+ + + Modes + + BotCommander uses modes to distinguish between commands addressed + to itself, and addressed to the connected bot. + + There are three modes, identified by their english names' first + character. + + + + B, or BotCommander command mode (/) + + + In this mode, entered text is validated against the commands + built in to BotCommander, or commands provided by scripts and + modules. + + + + + E, or Eggdrop command mode (.) + + + In this mode, text is sent to the connected bot (if any), so + eggdrop itself will validate it. + + + + + M, or Message mode (@) + + + In this mode, entered text is sent to the connected bot. As + you see, it is just the same as E mode, but there is a small + difference. If the entered text begins with a dot (.), eggdrop + would identify and parse it as a command. So in this case, the + entered text is prefixed with a space. + + + + + You can change between these modes in the Mode menu, or with + hotkeys (Ctrl-B, Ctrl-E and Ctrl-M respectively). However, if you want + to use one specific mode for a long time, and issue one line in a + different mode, you can prefix your text with the character in + parentheses in the above list. E.g if you use Message mode for hours, + and want to issue one BotCommander command, you can do it by entering + /COMMAND. As this happens, BotCommander will parse and execute the given + row as a BotCommander command, and return to message mode. + +
+
\ No newline at end of file diff --git a/doc/version.texinfo b/doc/version.texinfo new file mode 100644 index 0000000..dd64404 --- /dev/null +++ b/doc/version.texinfo @@ -0,0 +1,2 @@ +@set VERSION 1.0 +@set UPDATED 15 November 2005 diff --git a/eggdrop/botcommander.tcl b/eggdrop/botcommander.tcl new file mode 100644 index 0000000..5f5e5d5 --- /dev/null +++ b/eggdrop/botcommander.tcl @@ -0,0 +1,50 @@ +bind chon - * botcommander:chon +bind dcc - botcomm_chanlist botcommander:chanlist +bind dcc - botcomm_userlist botcommander:userlist +bind dcc - botcomm_chanprop botcommander:chanprop + +proc botcommander:chon {handle connid} { + putdcc $connid "BC+ ABILITY\r\n" +} + +proc botcommander:chanlist {handle connid params} { + if {[matchattr $handle o]} { + putdcc $connid "BC+ CHANLIST_START\r\n" + foreach chan [channels] { + set active [channel get $chan inactive] + if {$active != 0} { set active 0 } else { set active 1 } + putdcc $connid "BC+ CHAN $active $chan\r\n" + } + putdcc $connid "BC+ CHANLIST_END\r\n" + } else { + putcc $connid "BC- NOPRIV\r\n" + } +} + +proc botcommander:userlist {handle connid params} { + if {[matchattr $handle o]} { + putdcc $connid "BC+ USERLIST_START\r\n" + foreach user [userlist] { + putdcc $connid "BC+ USER $user\r\n" + } + putdcc $connid "BC+ USERLIST_END\r\n" + } else { + putdcc $connid "BC- NOPRIV\r\n" + } +} + +proc botcommander:chanprop {handle connid params} { + if {[matchattr $handle o]} { + set chan [lindex $params 0] + putdcc $connid "BC+ CHANPROPS_START $chan\r\n" + foreach prop [channel info $chan] { + putdcc $connid "BC+ CHANPROP $chan $prop\r\n" + } + putdcc $connid "BC+ CHANPROPS_END $chan\r\n" + } else { + putdcc $connid "BC- NOPRIV" + } +} + +putlog "BC+ ABILITY" + diff --git a/gentoo/net-misc/botcommander/ChangeLog b/gentoo/net-misc/botcommander/ChangeLog new file mode 100644 index 0000000..6f63b8f --- /dev/null +++ b/gentoo/net-misc/botcommander/ChangeLog @@ -0,0 +1,9 @@ +# ChangeLog for net-misc/botcommander +# Copyright 1999-2007 Gentoo Foundation; Distributed under the GPL v2 +# $Header: $ + +*botcommander-1.0 (07 May 2007) + + 07 May 2007; Gergely POLONKAI ChangeLog, + metadata.xml, botcommander-1.0.ebuild : + Initial import. Ebuild submitted by Gergely POLONKAI . diff --git a/gentoo/net-misc/botcommander/Manifest b/gentoo/net-misc/botcommander/Manifest new file mode 100644 index 0000000..c2ffc9f --- /dev/null +++ b/gentoo/net-misc/botcommander/Manifest @@ -0,0 +1,16 @@ +DIST botcommander-1.0.tar.gz 199432 RMD160 2b215e140f4be8d606e50851f62a768415dc20bd SHA1 4791e1ef953447769e185dd09378959111a472bb SHA256 60c9b2304ffd52710896a3fc23cbe7d2a1a311e930588e1c0ff0770832d7d34c +EBUILD botcommander-1.0.ebuild 824 RMD160 ba7a4d6d66187ff84a5b0f34099b0cae33c1d67d SHA1 5c236fa215ad00120ecc0d688e039e60a10537b2 SHA256 07b5b914e2a59f5a45b48fafa52ff391703a478a91a7a7722570af59b310145b +MD5 02966d62ff21c59a56c6e49205d7ea73 botcommander-1.0.ebuild 824 +RMD160 ba7a4d6d66187ff84a5b0f34099b0cae33c1d67d botcommander-1.0.ebuild 824 +SHA256 07b5b914e2a59f5a45b48fafa52ff391703a478a91a7a7722570af59b310145b botcommander-1.0.ebuild 824 +MISC ChangeLog 347 RMD160 f388beb33308560a58336982968c1a42a10010e8 SHA1 f93cc861296127765a24db8027842f31ac7d7e58 SHA256 6bbc25b9c2de498ab7912fc269d55b4c56273f413215f8f89a4731ad6999c0ef +MD5 8da252e524f30f329737a630a99822a5 ChangeLog 347 +RMD160 f388beb33308560a58336982968c1a42a10010e8 ChangeLog 347 +SHA256 6bbc25b9c2de498ab7912fc269d55b4c56273f413215f8f89a4731ad6999c0ef ChangeLog 347 +MISC metadata.xml 228 RMD160 63206419b7b7c6a2c350d341159550195e4a6c39 SHA1 5459d1b0d5252954b1e03749daf24fae8328241c SHA256 77715d077c12ef5f4fb0210a6ab0afbd1ce72893197b00172e113bc1feefd7b8 +MD5 12db369dccd15f41022110f874eec256 metadata.xml 228 +RMD160 63206419b7b7c6a2c350d341159550195e4a6c39 metadata.xml 228 +SHA256 77715d077c12ef5f4fb0210a6ab0afbd1ce72893197b00172e113bc1feefd7b8 metadata.xml 228 +MD5 3b1381c413a444be4c2ccf88873fb996 files/digest-botcommander-1.0 250 +RMD160 06d1d7d46814dd557e6d8e280747fc1efa37315b files/digest-botcommander-1.0 250 +SHA256 69bea651c8d76ef75dad3c4ad15772813f75e1673b7c8d54bc448ac60f89de3c files/digest-botcommander-1.0 250 diff --git a/gentoo/net-misc/botcommander/botcommander-1.0.ebuild b/gentoo/net-misc/botcommander/botcommander-1.0.ebuild new file mode 100644 index 0000000..5de5506 --- /dev/null +++ b/gentoo/net-misc/botcommander/botcommander-1.0.ebuild @@ -0,0 +1,34 @@ +# Copyright 1999-2007 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +inherit eutils versionator gnome2 + +DESCRIPTION="Eggdrop IRC bot maintanence program" +HOMEPAGE="http://www.botcommander.hu/" +SRC_URI="http://www.botcommander.hu/dl/${P}.tar.gz" +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="x86 amd64" +IUSE="-debug" +DEPEND="" +RDEPEND=">=dev-libs/glib-2.6.0 + >=x11-libs/gtk+-2.10.0" + +src_compile() { + econf \ + --prefix="${D}"/usr \ + --mandir="${D}"/usr/share/man \ + --infodir="${D}"/usr/share/info \ + --libdir="${D}"/usr/$(get_libdir) || die "econf failed" + emake || die "emake failed" +} + +src_install() { + emake \ + prefix="${D}"/usr \ + mandir="${D}"/usr/share/man \ + infodir="${D}"/usr/share/info \ + libdir="${D}"/usr/$(get_libdir) \ + install || die "emake install failed" +} diff --git a/gentoo/net-misc/botcommander/files/digest-botcommander-1.0 b/gentoo/net-misc/botcommander/files/digest-botcommander-1.0 new file mode 100644 index 0000000..6ea2dbc --- /dev/null +++ b/gentoo/net-misc/botcommander/files/digest-botcommander-1.0 @@ -0,0 +1,3 @@ +MD5 1d44a59bc7466b2f36dbc812bb793793 botcommander-1.0.tar.gz 199432 +RMD160 2b215e140f4be8d606e50851f62a768415dc20bd botcommander-1.0.tar.gz 199432 +SHA256 60c9b2304ffd52710896a3fc23cbe7d2a1a311e930588e1c0ff0770832d7d34c botcommander-1.0.tar.gz 199432 diff --git a/gentoo/net-misc/botcommander/metadata.xml b/gentoo/net-misc/botcommander/metadata.xml new file mode 100644 index 0000000..14ca7d6 --- /dev/null +++ b/gentoo/net-misc/botcommander/metadata.xml @@ -0,0 +1,8 @@ + + + +net-misc + + polesz@botcommander.hu + + diff --git a/include/defines.h b/include/defines.h new file mode 100644 index 0000000..e35aef2 --- /dev/null +++ b/include/defines.h @@ -0,0 +1,76 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * defines.h + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Macro definitions used in many places + }}} */ + +/* {{{ _BC_DEFINES_H */ +#ifndef _BC_DEFINES_H +# define _BC_DEFINES_H + +/* {{{ Locale-related definition. It's much easier this way */ +#define _(String) gettext(String) +/* }}} */ + +/* {{{ BC_COMMAND prototype definition */ +#define BC_COMMAND(x) gboolean x (t_tab_data *tab, int paramnum, gchar **param) +/* In typedefs.h there is a struct which is for the command list. + * To make life easier, you only have to change the functions' type here (and + * in the previous line). + */ +#define BC_COMMAND_DEF(x) gboolean (* x )(t_tab_data *, int, gchar **) +/* }}} */ + +/* {{{ Command types */ +#define CT_INTERNAL 0 +#define CT_MODULE 1 +#define CT_SCRIPT 2 +/* }}} */ + +/* {{{ BotCommander error constants */ +#define BCE_SUCCESS 0 +#define BCE_BOT_EXISTS 1 +#define BCE_NOMEM 2 +#define BCE_NOBOT 3 +#define BCE_NOPROTO 4 +#define BCE_CANTRESOLV 5 +#define BCE_CANTCONNECT 6 +/* }}} */ + +/* {{{ The eggdrops character for eggdrop commands. You should never change this! */ +#define EGG_CMD_CHAR "." +/* }}} */ + +/* {{{ The telnet codes we use, from RFC 854) */ +#define TELNET_IAC "\xff" /* Interpret As Command */ +#define TELNET_WILL "\xfb" /* Will */ +#define TELNET_WONT "\xfc" /* Won't */ +#define TELNET_ECHO "\x01" /* Echo */ + +#define TELNET_WILL_ECHO TELNET_IAC TELNET_WILL TELNET_ECHO +#define TELNET_WONT_ECHO TELNET_IAC TELNET_WONT TELNET_ECHO +/* }}} */ + +#endif +/* }}} */ + diff --git a/include/functions.h b/include/functions.h new file mode 100644 index 0000000..cdc51ce --- /dev/null +++ b/include/functions.h @@ -0,0 +1,161 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * functions.h + * + * Wed Nov 09 22:16:59 2005 + * Copyright 2004 Gergely POLONKAI + * polesz@techinfo.hu + * + * Function prototypes + }}} */ + +/* {{{ _BC_FUNCTIONS_H */ +#ifndef _BC_FUNCTIONS_H +# define _BC_FUNCTIONS_H + +/* {{{ Includes */ +# include +# include +# include "typedefs.h" +/* }}} */ + +/* {{{ widgets.c */ +void set_title(t_tab_data *, char *, ...); +int create_main_window(void); +void feed_message_to_terminal(t_tab_data *, gboolean, gchar *, ...); +void feed_error_to_terminal(t_tab_data *, gboolean, gchar *, ...); +void feed_info_to_terminal(t_tab_data *, gboolean, gchar *, ...); +/* }}} */ + +/* {{{ callbacks.c */ +void destroy_event(GtkWidget *, gpointer); +gboolean delete_event(GtkWidget *, GdkEvent *, gpointer); +void toolbar_quit(GtkButton *, gpointer); +void toolbar_add_tab(GtkButton *, gpointer); +void toolbar_close_active(GtkButton *, gpointer); +void toolbar_open_prefs(GtkButton *, gpointer); +void book_change_tab(GtkNotebook *, GtkNotebookPage *newpage, guint, gpointer); +void close_tab_cb(GtkWidget *, gpointer); +gboolean entry_activate(GtkWidget *, gpointer); +void menu_exit(GtkWidget *, gpointer); +void menu_mode_changed(GtkWidget *, gpointer); +void menu_botlist_open(GtkWidget *, gpointer); +void menu_prefs_open(GtkWidget *, gpointer); +void menu_new_tab(GtkWidget *, gpointer); +void menu_close_tab(GtkWidget *, gpointer); +void menu_about(GtkWidget *, gpointer); +int vte_clicked(GtkWidget *, gpointer); +int entry_keypress(GtkEntry *, GdkEventKey *, gpointer); +void socket_event(gpointer, gint, GdkInputCondition); +void menu_showhide_sidebar(GtkWidget *, gpointer); +/* }}} */ + +/* {{{ main.c */ +void exit_cleanly(gboolean); +void change_mode(char, gboolean); +/* }}} */ + +/* {{{ tabs.c */ +int add_tab(t_tab_data **); +t_tab_data *get_active_tab(void); +gboolean close_tab(t_tab_data *); +gboolean assign_bot_to_tab_by_name(t_tab_data *, gchar *); +void assign_bot_to_tab(t_tab_data *, t_bot_data *); +gint connect_tab(t_tab_data *); +void update_channel_list(t_tab_data *); +void update_user_list(t_tab_data *); +gint find_tab_by_pagenum(gconstpointer, gconstpointer); +void disconnect_tab(t_tab_data *); +void change_active_tab(gint); +/* }}} */ + +/* {{{ string.c */ +gboolean streq(gchar *, gchar *, gboolean); +int wordwrap(gchar *, gchar *, gchar ***, gint *); +void wl_free(gchar ***, gint); +gboolean is_numeric(gchar *, gint *); +gchar *trim(gchar *); +/* }}} */ + +/* {{{ bots.c */ +#ifdef DEBUG +void list_bots(void); +#endif +gint add_bot(gchar *, gchar *, guint, gchar *); +t_bot_data *get_bot_by_botname(gchar *); +gint create_bot_record(gchar *, gint, t_bot_data **); +gint update_bot(t_bot_data *, gchar *, gchar *, guint, gchar *); +void save_bot(t_bot_data *, t_bot_data *); +void free_bot_data(gpointer, gpointer); +t_bot_data *get_bot_by_conf_num(guint); +/* }}} */ + +/* {{{ commands.c */ +gboolean process_commandline(gchar *, t_tab_data *); +void process_botcommander_script_commands(t_tab_data *, char *); +/* }}} */ + +/* {{{ config.c */ +gboolean init_config(void); +void read_config_data(void); +gboolean set_int_conf_value(gchar *, gint); +gboolean set_string_conf_value(gchar *, gchar *); +void read_bot_list_from_config(void); +void save_bot_list_to_config(void); +/* }}} */ + +/* {{{ about.c */ +void display_about_box(void); +/* }}} */ + +/* {{{ setup.c */ +void display_setup_window(void); +/* }}} */ + +/* {{{ networking.c */ +gint connect_to_host(gchar *, guint, int *, gint *, t_tab_data *); +void process_incoming_data(t_tab_data *, char *); +/* }}} */ + +/* {{{ history.c */ +void history_add(t_tab_data *, gchar, gchar *); +gint get_history_len(t_tab_data *); +/* }}} */ + +/* {{{ botlist.c */ +void display_botlist_window(void); +void create_bot_editor(t_bot_data *); +/* }}} */ + +/* {{{ chanprops.c */ +void update_channel_property(t_tab_data *, gchar *, gchar *); +/* }}} */ + +/* {{{ debug.c */ +/* This one is only compiled if DEBUG is defined */ +# ifdef DEBUG +void debug_init(void); +void set_context(char *file, int line); +# define Context set_context(__FILE__, __LINE__) +# else /* DEBUG */ +# define Context +# endif /* DEBUG */ +/* }}} */ + +#endif /* _BC_FUNCTIONS_H */ +/* }}} */ diff --git a/include/typedefs.h b/include/typedefs.h new file mode 100644 index 0000000..b9a3b16 --- /dev/null +++ b/include/typedefs.h @@ -0,0 +1,187 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * typedefs.h + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Type definitions + }}} */ + +/* {{{ _BC_TYPEDEFS_H */ +#ifndef _BC_TYPEDEFS_H +# define _BC_TYPEDEFS_H + +/* {{{ Includes */ +# include + +# include "defines.h" +/* }}} */ + +/* {{{ Bot data */ +typedef struct _t_bot_data { + /* The bot's name. NULL if now known */ + gchar *botname; + /* The hostname of the bot */ + gchar *host; + /* The port number of the bot */ + guint port; + /* The handle in the bot (may be NULL) */ + gchar *handle; + /* The config key value for this bot (used only when loading bot data from config */ + guint id; +} t_bot_data; +/* }}} */ + +/* {{{ History data */ +typedef struct _t_history_data { + gchar *line; + struct _t_history_data *next; +} t_history_data; +/* }}} */ + +/* {{{ Tab data */ +typedef struct _t_tab_data { + /* General data */ + + /* The number of the tab */ + gint num; + /* The current mode in the tab (b|e|m)*/ + char mode; + /* The bot assigned to this tab */ + t_bot_data *bot; + /* The history data */ + t_history_data *history; + /* The current position in the history list */ + gint history_position; + + /* BC script related data */ + + /* Currently we are in the middle of the channel list */ + gboolean chanlist_process; + /* Currently we are in the middle of the user list */ + gboolean userlist_process; + /* Currently we are processing the properties of this channel */ + gchar *chanprops_process; + /* This is number x in the property list */ + gint chanprops_list_num; + /* The channel list */ + GList *actual_channel_list; + /* The user list */ + GList *actual_user_list; + + /* Networking data */ + + /* TRUE if the tab is connected, FALSE otherwise */ + gboolean connected; + /* The socket descriptor */ + int sock; + /* The GDK socket tag */ + gint socktag; + /* Set to TRUE when the first byte arrives from the other side */ + gboolean data_arrived; + + /* Widgets */ + + /* The virtual terminal */ + GtkWidget *vt; + /* Command line */ + GtkWidget *editbox; + /* The hbox containing the tab label and the close button */ + GtkWidget *labelbox; + /* The tab label */ + GtkWidget *label; + /* The close button */ + GtkWidget *closebutton; + /* List of channels */ + GtkWidget *channel_list; + /* List of users (handles) */ + GtkWidget *user_list; + /* Channel store */ + GtkListStore *channel_store; + /* User store */ + GtkListStore *user_store; +} t_tab_data; +/* }}} */ + +/* {{{ Configuration data */ +typedef struct _t_config_data { + /* GUI options */ + gboolean change_to_new_tab; + /* VTE options */ + gboolean scroll_on_output; + gboolean transparent_background; + gfloat background_saturation; + gchar *vte_font; + /* General options */ + gboolean change_to_message; +#ifdef DEBUG + gboolean debug; +#endif /* DEBUG */ + gchar default_mode; + gboolean save_prefs; + gint history_len; +} t_config_data; +/* }}} */ + +/* {{{ Command Data */ +typedef struct _t_command { + /* The command verb */ + gchar *command_verb; + /* Type of the command: 0 - Internal; 1 - From a module; 2 - From a script */ + guint type; + /* How many parameters do we require? */ + gint min_paramnum; + /* Can this command be abbreviated? */ + gboolean can_abbrev; + /* The commands function */ + BC_COMMAND_DEF(func); +} t_command; +/* }}} */ + +/* {{{ Channel data */ +typedef struct _t_channel { + /* The channel name */ + char *name; + /* TRUE if then channel is active */ + gboolean active; + /* The property list */ + GList *properties; +} t_channel; +/* }}} */ + +/* {{{ User data */ +typedef struct _t_user { + /* The use name */ + char *name; +} t_user; +/* }}} */ + +/* {{{ Channel properties */ +typedef struct _t_chan_prop { + char *name; + gboolean bool_prop; + gboolean bool_value; + gchar *string_value; +} t_chan_prop; +/* }}} */ + +#endif +/* }}} */ + diff --git a/include/variables.h b/include/variables.h new file mode 100644 index 0000000..e5d157b --- /dev/null +++ b/include/variables.h @@ -0,0 +1,63 @@ +/* vim: set foldmethod=marker : */ +/* {{{ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ + * variables.h + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Variable definitions + }}} */ + +/* {{{ _BC_VARIABLES_H */ +#ifndef _BC_VARIABLES_H +# define _BC_VARIABLES_H + +/* {{{ Includes */ +# include +# include + +#include "typedefs.h" +/* }}} */ + +/* {{{ widgets.c */ +extern GtkWidget *main_window; +extern GtkWidget *main_book; +extern GtkWidget *main_statuslabel_mode; +extern GtkWidget *main_menu_mode_b; +extern GtkWidget *main_menu_mode_e; +extern GtkWidget *main_menu_mode_m; +extern GtkWidget *main_menu_show_sidebar; +/* }}} */ + +/* {{{ tabs.c */ +extern GList *tab_list; +/* }}} */ + +/* {{{ bots.c */ +extern GList *internal_bot_list; +/* }}} */ + +/* {{{ config.c */ +extern t_config_data config_data; +extern GConfClient *gconf_client; +/* }}} */ + +#endif +/* }}} */ + diff --git a/pixmaps/Makefile.in b/pixmaps/Makefile.in new file mode 100644 index 0000000..6453107 --- /dev/null +++ b/pixmaps/Makefile.in @@ -0,0 +1,16 @@ +include ../rules + +top_srcdir = @top_srcdir@ + +PACKAGE_PIXMAPS_DIR = @datarootdir@/pixmaps/@PACKAGE_TARNAME@ + +all: +clean: + +install: + $(top_srcdir)/mkinstalldirs $(PACKAGE_PIXMAPS_DIR) + $(INSTALL) -m 0644 $(PIXMAPS_OBJECTS) $(PACKAGE_PIXMAPS_DIR) + +distclean: + /bin/rm -f Makefile + diff --git a/pixmaps/bc48.png b/pixmaps/bc48.png new file mode 100644 index 0000000000000000000000000000000000000000..199c4d245bc165f1ecc34c85b16875c4520bf685 GIT binary patch literal 3110 zcmV+>4B7LEP)~F(-~@_a^`V03vin zSad^gZEa<4bO3j0bZ8({Xk{QrX>D*IVtF7}Z*OFCbZ=v88a$iN000YxNklfgpR@B|MwCii zBwK>nkEhn&d;NQ_^{>l5k`O|$3}bL`kfTSBvSY^%TrL+qJw23^l;CtamvkT9aws2* z#n`uRA1y5{^!4?zXU`sv963UJdpnw@E$Lp;a@;^`Yb&xWGchrNUazO6r3G1*m*cE3 zEahV9behr8QR4A9i9~{;q9UrQs?h88EZ10)8&Fl1&p-d1OeTZN<;LkO!fLfLJw46X z*cc-tBM2d=tEh{xkxym*nCnp!Mo3rG?L1^M&jQmGV|E?vUqa#2-P^``+K zl}d5u%o#Rr+(=?3NmfyfByi2!60t88&y?FCR5n$d5d0SWMl+Y zRXKkAICsJ$w-pCQMnlq1QYpH-yLslBXKpLaShNpln#RS87pbnUL6UTgkB@Tr@L`IJi>a@# zCoeCLcsx!|PY;1WfbHA2Q(s??BuS{M%KPuXPgPYFt5>f^2!Wy~U(#?5Znt~+0nE(I z;P?A+7P%>K9E`FI2;ZN3ky+Im5PcAj7B5rbegWNF527M zId|?Hp->1#QAnjyl$Ms_^?GS(X<_HiotR9f3=VMi>{+_IyGf-| z7z_pq3k!+I<8*a(keML=1_STB^A0<9>{ysWVv%EDU_e~G`h{q0XcVQTrNU;ji5FgYLG<_c3sqHx5JG60 zCI$xw#eo9{gxziz4u?a0^2sM6H#b+j^2#eBlg`XrS5XwPfB$~*(n~LibUM9YeHIL$ zqoYH-{`%|U*s)_G9KI=hzFx6;^Ja1U`0;O@clPXAQBY7IUVQOIQB+hUB9X{9%AP-e zUToR2Wl;yZAQqaKm|*+%?X#S{abq*PcKtauH8nIhH-GEg#>PhW?%hiu5Wwkl&dE%L z5NMh<`_1F=5C{Z_Mx*5C=Pz9x=?V*8 z-ztCV)G1L`Rwl;A#>C9bjA&?R6tBMes?aoTj$AUC6kE4$6?^yo?eYQ$g(Jf69}tt1 zQE}wR5m8%PD=u8P@U^m6uU-{v)~pe4yz$1IZ|l~r6VE>Ttmy6S6;o4FqPMqKJn_U6 z!r>?sJwD&^0!XFO!sqK1k?@ERLWmDP{7|f4zh3Oyw@-Zh@yDX4r$?MQb4I-U^2?&W zzFr(UbVy{g*?H#p{PWL?d+)th)YjGtkH;fwSKlq#K03Zwb;P10u@Hiu9v=lO9Jq^} z=yWOcr@qB*;joqF{ zI2^&C*ON-7?ij#uaQL=cj<*HCYPBHCHUt`xo1=GBQDrh2g5l8xr_W2)8?CLa;_4UI zkgb+GGNntGJ6U_*J>P$G*Jw0ST~$SYV1TLE6pE5v^cvAUY8_rI*a(T%|F3tG?6vQ{Nj;D zstaXoW+Q(%-9d#zV*lG8@z`HH&aTQ8==DqUwz8xT9I<$UO|KoJKWoFPCb4Nrb{GfP zS)Ad;z7^bDQOT5MASDbOY_#z=TYo%D!HS}wswz624wK2WV86Jn8_+b3p`jsy!62HZ zVX<0qI-Qs;7K%oDIQa92_|e^socH^sjhe?L7oTVgBpnW$tk{F*Gzp ze}6x+EF*+Kuh)}ICNUa~G&D3U2*jdqU^+g--yLq{ZaKr>KlO7A1_P;7ikmlY5({=pSdNEZwydLmb>*Br`uh4X zo6VG#mM%Sje}3l#{_zC=`HP>hqa{P-3|M8bi^OT>Op61^= zV+RFyWtjf2|+Ziehn!|%fmvMOa_x) zhu2*=zhgZXWk|Jx9uOL1)tg!C9O5o9fp^s^h9e`S#|#MFm&$WXE|!_U&tQ0jg_^~p zxXf%eW75)G8w#VU>YOBQBsN1@GJVCXlOa~*=TlKp!Nm9&+gg6YS~ZB2Nz6?rGTNNz z{NAS**!KD{obKYKxdByG86O`<2*LI1*V*7Su=96U@H(#JvYBz2!EG}T9-BbuTwemv z;R|8Ge*&ZL1NBC)(1Dnl8B9Xvq{q}da z?_{B_t}Z$|JDHrEWPE&_^73-L<>e^o@kL@>pOF|&N{poinM{T%U5ssIR_r-4`F1-^ zO-Uo;*n+k-%UuAj>ii zhXaqtLuF;7Gkj&I-L$llF&4bL^6rVXr!*Lj+vR6SzpV^$ssQ<54+ut z%jLr5a^dlKC@wC>YPBw1E+m8?l}ZtbM6g&asH#dfn?+F+ve_)Es-kHcU-qAnBnh2P zhfb$Muh(NR7%-Vk7>!0uCKG0}8H>fTs1*DE0lOzGpApA2kpKVy07*qoM6N<$f@^Q( A>i_@% literal 0 HcmV?d00001 diff --git a/pixmaps/bc48_trans.png b/pixmaps/bc48_trans.png new file mode 100644 index 0000000000000000000000000000000000000000..36dd87cea5acd37458d6246a88946a053bd3e0df GIT binary patch literal 3098 zcmV+#4CV8QP)D*IVtF7}Z*OFCbZ=v88a$iN000YlNkl*69G3no${RZInvR0g%tB(3>!;v{j}I@UI$P15#9GU=C@ zOr|yMn0D$o)0&y48LdSpX%vh=RMMb`2viot1zBYGuDc8D!ouF&yZ4^{urZ}3smMa} z-hc1h_r2$N&pGdN&T~PSo5$^T)0=O;8FIVbBnSdsxNw2|m;IFN?-tvwh2xx0-gUMtGOsx z%j9yosI9FnX}8g=7N0tGio&5AhDRnQNtR{0oiRK-Os%c0Nda-kA=K~cCzVPCtu`I0 zniK#4r{!*Y{ne{i5sSr8Tv9x%aJpk22m}Ji%*=vDlY+P?&d7KGu-okjhr_c@fja^) z!Bdk$T^c=3t6yu4;X5K0UN!;$SzY~N;Z7?^nh zaPI6mDk^e-VH6k{3E;qi18-X_mT#4nm2nvv8Hhw8=S47lnm|C@Coc5kVA1oIiga4u=C~i+O$kbai%-(O^clJ`=62t;o#G#OUZK+-^4% z3I%jJ9rSuVa&mGYNfPq&^Py6y5R1jo)zyWjrlu2T&z@cD^?D(SA_PHz&1Qq$Zbx-> zH6DBXF=oyH@Lrw-A%=ne0l0?-(bCd_OP4M|5CkZdO626^AQFk7tE&r%L;_~B8Jjk3 zYJUFt=PS2w-;Rcc1~?oJtX{o3Xti1|a2!`A2trSNeSPJbGiRVwDskx0q1&&YW_s@q z4h~Xp?`0}qSxz>ajkH=Vz4X#ce;ybZAW4#L64ubr5bfT*`_DR^j`VsxH8wU z!QpU-RaI50FIrn(UXC3*b{ufK-CK=DBUqOG)cZt`W%=fu)oO*??S`~S0_$dz#{;e3 zZY8hRi#OhQ18=?c7M3kr_O{pSeLE6~sQ%L+p6Bt*Gtc0ok3RY|$ruKem6cnyS}lr; zixCQiZW_OP_wM~$wrqhYiU0tOMuVxTDfHF#QBsL4FE0;Ps}+Y2A4Wkz0oJTpvt{MV zm0SAy`lg+z$K%0!@4bghmoDAH+E%OeKz4REnwy(%0;{R1*|vG}W+;`P27<+6LCKPm z+rLh4H`aKbr@p>E>ged8D_309-Q7(NhvR1Aev-Uyx0^&!yg4UH5^dhRnGPO2NbkJ! z4&8U(eH4vGKQ{*|Dk^ABtI_`cesT|9BcAt>&1R$e`uZuAT0@5kp9fS31CfBztjjfJSTww8*Ei*J<1pD}uSdui#? zrL=$l{%Lc|moKO1o_j9P)6+xar1n~IBz z$!fJyamf;@KXH=gr60KT&u+@j(!*>qLZMI~5D1{QwifmE^%xr)1IKZws;WBrojc)A;xVC1XgEL@h06Y2Jh_ z`=UjN#bXGC#*@;Q2ZJM6xX?O(4UO4iWO&{OCCfsH3bWUeJi}OMTgc2C007`PEeJAv z*8?EB^QI~ukHfjp;-vkuizHK{3~=CEyJIf`;PXj4=;+T4zOJ+pP!!4r7&i6^nCAnVKfgJapx z57R(Gi&QBJtsKQes==X$E%Dr!U0JxERe*6>34xT@Q?A8#*ME)qzj?qt=q8WH16h`# zNlk^(Xhe!e1H&)6vFGu%_{x%UoOAZ$d+)|`aqa|u@W|7+ciCO=czL{i`XcT!R^Zyu zH5wQg0LO74BCsrrXfz6yN`>-O<;A3pOqlu9K8LBRFv*WvYg(SGrw z$S{oR-c_q`s@;hL&JaxED1Q9Vz3_TGu-olOPfy2RPn4 zB_##6TpN>g0KYicK>Z_A_~W*3Olt)JVBh=Ac;Rdq*?cFST__%SZ(wrkFTe9Bnz{!? z!=&e|&1|eZ*5gC{cm^U1N+B!N_*vdKe)`z`(+f-@w70jT?5qDf(Pzv9ColW(qngrN zj31wvz;8Okm`XEYxM&^rd9+(|wZOU7^UbB&m?|q>Tlw3bI1Z;(VBEGGvVsMO5Q<5+ zo+`u4T@I*O1?=XWTjo8%5Uxq701JR*1dG;SneiGH(`coA(IO1{{D=jWAcYe6q;?`1 z;rM5$-@N~}<6_1hP|Gp&UE?81(zGJZAD%>vQGarTz?c_VnVHDX&&TLU5bLWSz%t1L zCO$R2oQTWQ*!jq*R;=H93`Vmhc^(K{4v?&qaplSttnOCg;lFgiuD=44HU*{>z^qk* z4~~Kqrhfxaz~pU55m$lK)O485X83$QJi0s&r;cBM*IotC4a5HtknrPo8WEEjG`T0> zgb|PBXwZM954l({djOpsoupN0p%PROMG+Qd9A8OSp&^`tSWE{f6gN&B833CA7zJ!G z9=lc=r}AwUE|ExJU|;|)mkWBm9vdhUTjC@cKd|`mja)sn zT5WQOtgEw&Iy*ZtHa5nOjEo$~%gg(|JueR;SU7!QT$yAr9AyxU5#sSU3Ke0j&rO9c zjYFnRhl+{{T)lb~k;o*vx;o+a`@0H?ib{LEBXCAo1QKd643Mi9vD&J|LPHi#pFaKj zsi~;~rBWH-I8LS4>z}Y%ttcocxaFVP{{(RC{bSVB)YKJ?MoWnZ9LIH)mzS3=Sg-&F zg8>s06HuvCAR>f9A*7|Jk&&U=xN+l#{{DV&90!d?gMItN6g+lR(?l~0> zhdG5p0fu29%QB{-QK(fa+;h)8&6AUp7e+=#wi1ylEiJ7%BO@cE)9E&vOeW4`GQn!K zVsZXrW=?9Ms{>a_qtQT;BqS0Eh@yx@A^}N~Aj>j{2t)*iVW3bbpin5lvMiKJCDdv) oR4NrR{*duA?Ju=IpXs;%1(rwe7uqiqW&i*H07*qoM6N<$f>&$XAOHXW literal 0 HcmV?d00001 diff --git a/po/BotCommander.pot b/po/BotCommander.pot new file mode 100644 index 0000000..5756ec6 --- /dev/null +++ b/po/BotCommander.pot @@ -0,0 +1,307 @@ +# BotCommander gettext messages. +# Original file created by Gergely POLONKAI for BotCommander v1.0 + +#: src/widgets.c:223 +msgid "_About" +msgstr "" + +#: src/tabs.c:103 +msgid "Activate" +msgstr "" + +#: src/botlist.c:180 +msgid "Add bot" +msgstr "" + +#: src/widgets.c:114 +msgid "_BotCommander command mode" +msgstr "" + +#: src/botlist.c:351 +msgid "Bot list" +msgstr "" + +#: src/widgets.c:147 +msgid "_Bot list" +msgstr "" + +#: src/botlist.c:384 +#: src/botlist.c:482 +msgid "Bot name" +msgstr "" + +#: src/widgets.c:106 +msgid "_Bot" +msgstr "" + +#: src/tabs.c:510 +msgid "Can not connect to bot" +msgstr "" + +#: src/tabs.c:504 +msgid "Can not get IP protocol" +msgstr "" + +#: src/tabs.c:507 +msgid "Can not resolv hostname %s" +msgstr "" + +#: src/setup.c:247 +msgid "Change to message mode after connect" +msgstr "" + +#: src/setup.c:253 +msgid "Change to newly created tab" +msgstr "" + +#: src/tabs.c:309 +msgid "Channels" +msgstr "" + +#: src/widgets.c:269 +msgid "Close active tab" +msgstr "" + +#: src/widgets.c:200 +msgid "_Close tab" +msgstr "" + +#: src/setup.c:265 +msgid "Command line history length" +msgstr "" + +#: src/callbacks.c:357 +msgid "Connected" +msgstr "" + +#: src/commands.c:131 +#: src/networking.c:53 +msgid "Connecting to %s:%d" +msgstr "" + +#: src/commands.c:93 +#: src/commands.c:108 +msgid "Connecting to %s" +msgstr "" + +#: src/tabs.c:593 +msgid "Connection closed" +msgstr "" + +#: src/botlist.c:357 +msgid "_Connect" +msgstr "" + +#: src/setup.c:240 +msgid "Debug mode" +msgstr "" + +#: src/botlist.c:88 +msgid "Edit bot" +msgstr "" + +#: src/widgets.c:123 +msgid "_Eggdrop command mode" +msgstr "" + +#: src/widgets.c:267 +msgid "Exit BotCommander" +msgstr "" + +#: src/widgets.c:91 +msgid "E_xit" +msgstr "" + +#: src/setup.c:306 +msgid "Font" +msgstr "" + +#: src/botlist.c:494 +msgid "Handle" +msgstr "" + +#: src/tabs.c:323 +msgid "Handles" +msgstr "" + +#: src/widgets.c:237 +msgid "_Help" +msgstr "" + +#: src/botlist.c:486 +msgid "Host" +msgstr "" + +#: src/about.c:52 +msgid "licence" +msgstr "" + +#: src/widgets.c:131 +msgid "_Message mode" +msgstr "" + +#: src/commands.c:170 +msgid "Mode char can be one of B, E or M!" +msgstr "" + +#: src/callbacks.c:93 +#: src/callbacks.c:94 +#: src/main.c:45 +#: src/main.c:46 +#: src/tabs.c:362 +#: src/tabs.c:363 +#: src/tabs.c:460 +#: src/tabs.c:461 +#: src/widgets.c:291 +#: src/widgets.c:292 +#: src/widgets.c:139 +#: src/widgets.c:185 +msgid "Mode: %c" +msgstr "" + +#: src/widgets.c:268 +msgid "New tab" +msgstr "" + +#: src/commands.c:102 +#: src/commands.c:143 +msgid "No bot exists by that name" +msgstr "" + +#: src/commands.c:86 +msgid "No bot is assigned to this tab. Use ASSIGN to do that." +msgstr "" + +#: src/tabs.c:335 +#: src/tabs.c:360 +msgid "Not connected" +msgstr "" + +#: src/commands.c:124 +#: src/commands.c:261 +msgid "Not enough memory!" +msgstr "" + +#: src/commands.c:154 +#: src/commands.c:275 +msgid "Not enough parameters!" +msgstr "" + +#: src/commands.c:159 +msgid "Only one parameter required!" +msgstr "" + +#: src/botlist.c:490 +msgid "Port" +msgstr "" + +#: src/widgets.c:162 +msgid "_Preferences" +msgstr "" + +#: src/widgets.c:270 +msgid "Preferences" +msgstr "" + +#: src/tabs.c:107 +#: src/tabs.c:124 +#: src/tabs.c:141 +msgid "Properties" +msgstr "" + +#: src/setup.c:295 +msgid "Saturation" +msgstr "" + +#: src/setup.c:259 +msgid "Save preferences on exit" +msgstr "" + +#: src/setup.c:285 +msgid "Scroll on output" +msgstr "" + +#: src/commands.c:119 +msgid "Second parameter must be a port number!" +msgstr "" + +#: src/setup.c:228 +msgid "Setup" +msgstr "" + +#: src/widgets.c:177 +msgid "_Setup" +msgstr "" + +#: src/tabs.c:583 +msgid "Tab is not connected" +msgstr "" + +#: src/widgets.c:215 +msgid "_Tab" +msgstr "" + +#: src/setup.c:280 +msgid "Terminal" +msgstr "" + +#: src/commands.c:164 +msgid "The parameter must be one character!" +msgstr "" + +#: src/main.c:84 +msgid "There are connected tabs. Are you sure, you want to exit?" +msgstr "" + +#: src/bots.c:75 +msgid "There is already a bot named %s in the list.\n" +msgstr "" + +#: src/config.c:109 +msgid "There was an error accessing GConf2: %s" +msgstr "" + +#: src/commands.c:271 +msgid "This command cannot be abbreviated!" +msgstr "" + +#: src/commands.c:81 +msgid "This tab is already connected. Exit the bot with .quit, or use /DISCONNECT!" +msgstr "" + +#: src/tabs.c:431 +msgid "This tab is connected. Are you sure you want to close it?" +msgstr "" + +#: src/about.c:51 +msgid "translator_credits" +msgstr "" + +#: src/setup.c:290 +msgid "Transparent background" +msgstr "" + +#: src/commands.c:281 +msgid "Unknown command \"%s\"" +msgstr "" + +#: src/tabs.c:516 +msgid "Unknown error!" +msgstr "" + +#: src/callbacks.c:141 +msgid "Won't send an eggdrop command to a not connected tab" +msgstr "" + +#: src/callbacks.c:162 +msgid "Won't send message to a not connected tab" +msgstr "" + +#: data/botcommander.desktop.in.in +msgid "BotCommander" +msgstr "" + +#: data/botcommander.desktop.in.in +msgstr "BotCommander eggdrop client" +msgid "" + diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 0000000..ab3aea6 --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,221 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. +# +# - Modified by Owen Taylor to use GETTEXT_PACKAGE +# instead of PACKAGE and to look for po2tbl in ./ not in intl/ +# +# - Modified by jacob berkman to install +# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize +# +# - Modified by Rodney Dawes for use with intltool +# +# We have the following line for use by intltoolize: +# INTLTOOL_MAKEFILE + +include ../rules + +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_builddir = .. +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +libdir = @libdir@ +DATADIRNAME = @DATADIRNAME@ +itlocaledir = $(prefix)/$(DATADIRNAME)/locale +subdir = po +install_sh = @INSTALL@ +# Automake >= 1.8 provides @mkdir_p@. +# Until it can be supposed, use the safe fallback: +mkdir_p = $(install_sh) -d + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = @XGETTEXT@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist +GENPOT = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot + +ALL_LINGUAS = @ALL_LINGUAS@ + +PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; fi) + +POFILES=$(shell if test -n "$(PO_LINGUAS)"; then LINGUAS="$(PO_LINGUAS)"; else LINGUAS="$(ALL_LINGUAS)"; fi; for lang in $$LINGUAS; do printf "$$lang.po "; done) + +DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(POFILES) +EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS + +POTFILES = \ +#This Gets Replace for some reason + +CATALOGS=$(shell if test -n "$(PO_LINGUAS)"; then LINGUAS="$(PO_LINGUAS)"; else LINGUAS="$(ALL_LINGUAS)"; fi; for lang in $$LINGUAS; do printf "$$lang.gmo "; done) + +.SUFFIXES: +.SUFFIXES: .po .pox .gmo .mo .msg .cat + +.po.pox: + $(MAKE) $(GETTEXT_PACKAGE).pot + $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && gencat $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: $(CATALOGS) +all-no: + +$(GETTEXT_PACKAGE).pot: $(POTFILES) + $(GENPOT) + +install: install-data +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + $(mkdir_p) $(DESTDIR)$(itlocaledir) + if test -n "$(PO_LINGUAS)"; then \ + linguas="$(PO_LINGUAS)"; \ + else \ + linguas="$(ALL_LINGUAS)"; \ + fi; \ + for lang in $$linguas; do \ + dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $$dir; \ + if test -r $$lang.gmo; then \ + $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ + echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ + echo "installing $(srcdir)/$$lang.gmo as" \ + "$$dir/$(GETTEXT_PACKAGE).mo"; \ + fi; \ + if test -r $$lang.gmo.m; then \ + $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \ + echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \ + else \ + if test -r $(srcdir)/$$lang.gmo.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \ + $$dir/$(GETTEXT_PACKAGE).mo.m; \ + echo "installing $(srcdir)/$$lang.gmo.m as" \ + "$$dir/$(GETTEXT_PACKAGE).mo.m"; \ + else \ + true; \ + fi; \ + fi; \ + done + +# Empty stubs to satisfy archaic automake needs +dvi info tags TAGS ID: + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + if test -n "$(PO_LINGUAS)"; then \ + linguas="$(PO_LINGUAS)"; \ + else \ + linguas="$(ALL_LINGUAS)"; \ + fi; \ + for lang in $$linguas; do \ + rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \ + rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \ + done + +check: all $(GETTEXT_PACKAGE).pot + +mostlyclean: + rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp + rm -f .intltool-merge-cache + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES stamp-it + rm -f *.mo *.msg *.cat *.cat.m *.gmo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f Makefile.in.in + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: $(DISTFILES) + dists="$(DISTFILES)"; \ + extra_dists="$(EXTRA_DISTFILES)"; \ + for file in $$extra_dists; do \ + test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \ + done; \ + for file in $$dists; do \ + test -f $$file || file="$(srcdir)/$$file"; \ + ln $$file $(distdir) 2> /dev/null \ + || cp -p $$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(GETTEXT_PACKAGE).pot + tmpdir=`pwd`; \ + if test -n "$(PO_LINGUAS)"; then \ + linguas="$(PO_LINGUAS)"; \ + else \ + linguas="$(ALL_LINGUAS)"; \ + fi; \ + for lang in $$linguas; do \ + echo "$$lang:"; \ + result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \ + if $$result; then \ + if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.gmo failed!"; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi; \ + done + +Makefile POTFILES: stamp-it + @if test ! -f $@; then \ + rm -f stamp-it; \ + $(MAKE) stamp-it; \ + fi + +stamp-it: Makefile.in.in ../config.status POTFILES.in + cd .. \ + && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..c0d8637 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,13 @@ +# List of source files containing translatable strings. +# Please keep this list in alphabetical order. +../src/about.c +../src/botlist.c +../src/bots.c +../src/callbacks.c +../src/commands.c +../src/config.c +../src/main.c +../src/networking.c +../src/setup.c +../src/tabs.c +../src/widgets.c diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 0000000..d01f3bf --- /dev/null +++ b/po/hu.po @@ -0,0 +1,324 @@ +# Magyar translation of BotCommander. +# Copyright (C) 2006 Free Software Foundation, Inc. +# Gergely POLONKAI , 2006. +# +# +msgid "" +msgstr "" +"Project-Id-Version: BotCommander 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-09-08 11:43+0200\n" +"PO-Revision-Date: 2006-09-08 12:02+0200\n" +"Last-Translator: Gergely POLONKAI \n" +"Language-Team: Hungarian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: " + +# BotCommander gettext messages. +# Original file created by Gergely POLONKAI for BotCommander v1.0 +#: src/widgets.c:223 +msgid "_About" +msgstr "_Névjegy" + +#: src/tabs.c:103 +msgid "Activate" +msgstr "Aktiválás" + +#: src/botlist.c:180 +msgid "Add bot" +msgstr "Új bot" + +#: src/widgets.c:114 +msgid "_BotCommander command mode" +msgstr "_BotCommander parancs mód" + +#: src/botlist.c:351 +msgid "Bot list" +msgstr "Bot lista" + +#: src/widgets.c:147 +msgid "_Bot list" +msgstr "Bot _lista" + +#: src/botlist.c:384 +#: src/botlist.c:482 +msgid "Bot name" +msgstr "Bot neve" + +#: src/widgets.c:106 +msgid "_Bot" +msgstr "_Bot" + +#: src/tabs.c:510 +msgid "Can not connect to bot" +msgstr "Nem tudok csatlakozni a bothoz" + +#: src/tabs.c:504 +msgid "Can not get IP protocol" +msgstr "Nem találom az IP protokol adatait" + +#: src/tabs.c:507 +msgid "Can not resolv hostname %s" +msgstr "Nem lehet feloldani a nevet (%s)" + +#: src/setup.c:247 +msgid "Change to message mode after connect" +msgstr "Váltás üzenet-módba csatlakozás után" + +#: src/setup.c:253 +msgid "Change to newly created tab" +msgstr "Új fül nyitásakor váltás az új fülre" + +#: src/tabs.c:309 +msgid "Channels" +msgstr "Csatornák" + +#: src/widgets.c:269 +msgid "Close active tab" +msgstr "Aktív fül bezárása" + +#: src/widgets.c:200 +msgid "_Close tab" +msgstr "Fül be_zárása" + +#: src/setup.c:265 +msgid "Command line history length" +msgstr "Parancssor-megőrzés hossza" + +#: src/callbacks.c:357 +msgid "Connected" +msgstr "Csatlakozva" + +#: src/commands.c:131 +#: src/networking.c:53 +msgid "Connecting to %s:%d" +msgstr "Csatlakozás ide: %s:%d" + +#: src/commands.c:93 +#: src/commands.c:108 +msgid "Connecting to %s" +msgstr "Csatlakozás ehhez: %s" + +#: src/tabs.c:593 +msgid "Connection closed" +msgstr "Kapcsolat lezárva" + +#: src/botlist.c:357 +msgid "_Connect" +msgstr "_Csatlakozás" + +#: src/setup.c:240 +msgid "Debug mode" +msgstr "Debug mód" + +#: src/botlist.c:88 +msgid "Edit bot" +msgstr "Bot szerkesztése" + +#: src/widgets.c:123 +msgid "_Eggdrop command mode" +msgstr "_Eggdrop parancs mód" + +#: src/widgets.c:267 +msgid "Exit BotCommander" +msgstr "Kilépés a BotCommanderből" + +#: src/widgets.c:91 +msgid "E_xit" +msgstr "K_ilépés" + +#: src/setup.c:306 +msgid "Font" +msgstr "Betűtípus" + +#: src/botlist.c:494 +msgid "Handle" +msgstr "Felhasználónév" + +#: src/tabs.c:323 +msgid "Handles" +msgstr "Felhasználók" + +#: src/widgets.c:237 +msgid "_Help" +msgstr "_Súgó" + +#: src/botlist.c:486 +msgid "Host" +msgstr "Cím" + +#: src/about.c:52 +msgid "licence" +msgstr "A BotCommander a GNU General Public Licence alatt készült. Ennek egy másolata megtalálható a program forrás-fájljai között." + +#: src/widgets.c:131 +msgid "_Message mode" +msgstr "Üzenet _mód" + +#: src/commands.c:170 +msgid "Mode char can be one of B, E or M!" +msgstr "A mód karakter csak B, E vagy M lehet!" + +#: src/callbacks.c:93 +#: src/callbacks.c:94 +#: src/main.c:45 +#: src/main.c:46 +#: src/tabs.c:362 +#: src/tabs.c:363 +#: src/tabs.c:460 +#: src/tabs.c:461 +#: src/widgets.c:291 +#: src/widgets.c:292 +#: src/widgets.c:139 +#: src/widgets.c:185 +msgid "Mode: %c" +msgstr "Mód: %c" + +#: src/widgets.c:268 +msgid "New tab" +msgstr "Új fül" + +#: src/commands.c:102 +#: src/commands.c:143 +msgid "No bot exists by that name" +msgstr "Nem létezik ilyen nevű bot" + +#: src/commands.c:86 +msgid "No bot is assigned to this tab. Use ASSIGN to do that." +msgstr "Nincs bot rendelve ehhez a fülhöz. A hozzárendeléshez használd az ASSIGN parancsot." + +#: src/tabs.c:335 +#: src/tabs.c:360 +msgid "Not connected" +msgstr "Nincs csatlakoztatva" + +#: src/commands.c:124 +#: src/commands.c:261 +msgid "Not enough memory!" +msgstr "Nincs elég memória!" + +#: src/commands.c:154 +#: src/commands.c:275 +msgid "Not enough parameters!" +msgstr "Túl kevés paraméter!" + +#: src/commands.c:159 +msgid "Only one parameter required!" +msgstr "Csak egy paramétert kell megadni!" + +#: src/botlist.c:490 +msgid "Port" +msgstr "Port" + +#: src/widgets.c:162 +msgid "_Preferences" +msgstr "_Beállítás" + +#: src/widgets.c:270 +msgid "Preferences" +msgstr "Beállítások" + +#: src/tabs.c:107 +#: src/tabs.c:124 +#: src/tabs.c:141 +msgid "Properties" +msgstr "Tulajdonságok" + +#: src/setup.c:295 +msgid "Saturation" +msgstr "Áttetszőség" + +#: src/setup.c:259 +msgid "Save preferences on exit" +msgstr "Beállítások mentése kilépéskor" + +#: src/setup.c:285 +msgid "Scroll on output" +msgstr "Automatikus görgetés" + +#: src/commands.c:119 +msgid "Second parameter must be a port number!" +msgstr "A második paraméternek portszámnak kell lennie!" + +#: src/setup.c:228 +msgid "Setup" +msgstr "Beállítás" + +#: src/widgets.c:177 +msgid "_Setup" +msgstr "B_eállítás" + +#: src/tabs.c:583 +msgid "Tab is not connected" +msgstr "A fül nincs csatlakozva" + +#: src/widgets.c:215 +msgid "_Tab" +msgstr "_Fül" + +#: src/setup.c:280 +msgid "Terminal" +msgstr "Terminál" + +#: src/commands.c:164 +msgid "The parameter must be one character!" +msgstr "A paraméternek egy karakter hosszúnak kell lennie!" + +#: src/main.c:84 +msgid "There are connected tabs. Are you sure, you want to exit?" +msgstr "Még vannak csatlakozott fülek. Biztosan ki akarsz lépni?" + +#: src/bots.c:75 +msgid "There is already a bot named %s in the list.\n" +msgstr "Már van %s nevű bot a listában\n" + +#: src/config.c:109 +msgid "There was an error accessing GConf2: %s" +msgstr "Hiba történt a GConf2 elérése közben: %s" + +#: src/commands.c:271 +msgid "This command cannot be abbreviated!" +msgstr "Ezt a parancsot nem lehet rövidíteni!" + +#: src/commands.c:81 +msgid "This tab is already connected. Exit the bot with .quit, or use /DISCONNECT!" +msgstr "A fül csatlakoztatva van. Lépj ki a botból a .quit paranccsal, vagy használd a /DISCONNECT-et!" + +#: src/tabs.c:431 +msgid "This tab is connected. Are you sure you want to close it?" +msgstr "A fül csatlakoztatva van. Biztosan bezárod?" + +#: src/about.c:51 +msgid "translator_credits" +msgstr "Fordította: POLONKAI Gergely " + +#: src/setup.c:290 +msgid "Transparent background" +msgstr "Áttetsző háttér" + +#: src/commands.c:281 +msgid "Unknown command \"%s\"" +msgstr "Ismeretlen parancs: %s" + +#: src/tabs.c:516 +msgid "Unknown error!" +msgstr "Ismeretlen hiba!" + +#: src/callbacks.c:141 +msgid "Won't send an eggdrop command to a not connected tab" +msgstr "Nem küldhetek eggdrop parancsot egy nem csatlakoztatott fülön" + +#: src/callbacks.c:162 +msgid "Won't send message to a not connected tab" +msgstr "Nem küldhetek üzenetet egy nem csatlakoztatott fülön" + +#: data/botcommander.desktop.in.in +msgid "BotCommander" +msgstr "BotCommander" + +#: data/botcommander.desktop.in.in +msgid "BotCommander eggdrop client" +msgstr "BotCommander eggdrop kliens" + diff --git a/rules.in b/rules.in new file mode 100644 index 0000000..ccf39c0 --- /dev/null +++ b/rules.in @@ -0,0 +1,9 @@ +C_OBJECTS = main.@OBJEXT@ widgets.@OBJEXT@ callbacks.@OBJEXT@ tabs.@OBJEXT@ string.@OBJEXT@ bots.@OBJEXT@ commands.@OBJEXT@ config.@OBJEXT@ setup.@OBJEXT@ about.@OBJEXT@ networking.@OBJEXT@ history.@OBJEXT@ botlist.@OBJEXT@ debug.@OBJEXT@ chanprops.@OBJEXT@ +DOC_OBJECTS = botcommander.pdf +RM = rm -f +PIXMAPS_OBJECTS = bc48.png bc48_trans.png +INSTALL = @INSTALL@ +EXE = botcommander@EXEEXT@ +prefix = ${DESTDIR}@prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..49ac135 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,33 @@ +include ../rules + +top_srcdir = @top_srcdir@ + +CC = @CC@ +CPPFLAGS = @CPPFLAGS@ +CFLAGS = -I../include -I.. @BOTCOMMANDER_CFLAGS@ $(CPPFLAGS) @CFLAGS@ +LIBS = @BOTCOMMANDER_LIBS@ @LDFLAGS@ @LIBS@ + +all: $(C_OBJECTS) + $(CC) -o $(EXE) $(LIBS) $(C_OBJECTS) + +about.@OBJEXT@ botlist.@OBJEXT@ bots.@OBJEXT@ callbacks.@OBJEXT@ config.@OBJEXT@ networking.@OBJEXT@: ../config.h +about.@OBJEXT@ config.@OBJEXT@ main.@OBJEXT@ networking.@OBJEXT@ string.@OBJEXT@ tabs.@OBJEXT@ widgets.@OBJEXT@: ../include/defines.h +about.@OBJEXT@ botlist.@OBJEXT@ bots.@OBJEXT@ callbacks.@OBJEXT@ commands.@OBJEXT@ config.@OBJEXT@ main.@OBJEXT@ networking.@OBJEXT@ setup.@OBJEXT@ tabs.@OBJEXT@ widgets.@OBJEXT@ chanprops.@OBJEXT@: ../include/functions.h +$(C_OBJECTS): ../include/typedefs.h +botlist.@OBJEXT@ bots.@OBJEXT@ callbacks.@OBJEXT@ commands.@OBJEXT@ config.@OBJEXT@ history.@OBJEXT@ main.@OBJEXT@ networking.@OBJEXT@ setup.@OBJEXT@ tabs.@OBJEXT@ widgets.@OBJEXT@: ../include/variables.h + +.c.@OBJEXT@: + $(CC) $(CFLAGS) -o $@ -c $< + +clean: + $(RM) $(EXE) $(C_OBJECTS) + +install: all + $(top_srcdir)/mkinstalldirs $(bindir) + $(INSTALL) -m 0755 botcommander $(bindir) + +distclean: clean + $(RM) Makefile config.status config.cache config.log + +.PHONY: all clean + diff --git a/src/about.c b/src/about.c new file mode 100644 index 0000000..6abb4df --- /dev/null +++ b/src/about.c @@ -0,0 +1,91 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * about.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * The About dialog + }}} */ + +/* {{{ Includes */ +#include +#include + +#include "config.h" +#include "defines.h" +#include "functions.h" +/* }}} */ + +/* {{{ authors[] */ +const gchar *authors[] = { + "Gergely POLONKAI ", + "KrzychuG from #eggdrop@IRCNET as Beta Tester", + "Peter \"FaZy\" Erdosi as Beta Tester", + NULL, +}; +/* }}} */ + +/* {{{ documenters[] */ +const gchar *documenters[] = { + "Gergely POLONKAI ", + NULL, +}; +/* }}} */ + +/* {{{ display_about_box() */ +void +display_about_box(void) +{ + static GtkWidget *about_box = NULL; + GdkPixbuf *logo; + gchar *translator_credits = _("translator_credits"); + gchar *licence = _("licence"); + + if (!GTK_IS_WINDOW(about_box)) + { + char *buf = NULL; + + buf = g_locale_to_utf8(licence, -1, NULL, NULL, NULL); + logo = gdk_pixbuf_new_from_file(PACKAGE_PIXMAPS_DIR "/bc48_trans.png", NULL); + + about_box = gtk_about_dialog_new(); + gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about_box), "BotCommander"); + gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about_box), "1.0"); + gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about_box), "\xc2\xa9 2005, Gergely POLONKAI"); + gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about_box), "Developer's Version"); + gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about_box), buf); + g_free(buf); + gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about_box), "http://botcommander.hu/"); + gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about_box), authors); + gtk_about_dialog_set_documenters(GTK_ABOUT_DIALOG(about_box), documenters); + gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(about_box), translator_credits); + gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about_box), logo); + + if (logo) + g_object_unref(logo); + + g_signal_connect(G_OBJECT(about_box), "destroy", G_CALLBACK(gtk_widget_destroyed), &about_box); + gtk_widget_show(about_box); + } + else + gtk_window_present(GTK_WINDOW(about_box)); +} +/* }}} */ + diff --git a/src/botlist.c b/src/botlist.c new file mode 100644 index 0000000..81bd8f4 --- /dev/null +++ b/src/botlist.c @@ -0,0 +1,532 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * botlist.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * The Bot list dialog + }}} */ + +/* {{{ Includes */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include "variables.h" +#include "functions.h" +/* }}} */ + +/* {{{ Variables */ +static GtkDialog *editor_window = NULL; +static GtkDialog *botlist_win = NULL; +GtkWidget *botlist_edit_button, + *botlist_connect_button, + *botlist_remove_button, + *botlist_editor_botname, + *botlist_editor_host, + *botlist_editor_port, + *botlist_editor_handle; +static GtkWidget *bot_list = NULL; +/* }}} */ + +/* {{{ add_this_data() */ +static void +add_this_data(gpointer data, gpointer user_data) +{ + GtkTreeIter iter; + GtkListStore *store = (GtkListStore *)user_data; + t_bot_data *bot = (t_bot_data *)data; + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, bot->botname, -1); +} +/* }}} */ + +/* {{{ refresh_botlist() */ +static void +refresh_botlist(void) +{ + GtkTreeModel *model; + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(bot_list)); + g_object_ref(model); + gtk_tree_view_set_model(GTK_TREE_VIEW(bot_list), NULL); + gtk_list_store_clear(GTK_LIST_STORE(model)); + + g_list_foreach(internal_bot_list, add_this_data, (gpointer)model); + + gtk_tree_view_set_model(GTK_TREE_VIEW(bot_list), model); + g_object_unref(model); +} +/* }}} */ + +/* {{{ edit_bot_dialog() */ +static void +edit_bot_dialog(GtkWidget *widget, gpointer data) +{ + /* Here we can be sure that we have a selected item */ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + gint response; + gboolean can_close = FALSE; + + if (!editor_window) + create_bot_editor(NULL); + gtk_window_set_title(GTK_WINDOW(editor_window), _("Edit bot")); + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(bot_list)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + { + gchar *name; + t_bot_data *bot; + + gtk_tree_model_get(model, &iter, 0, &name, -1); + + if ((bot = get_bot_by_botname(name)) != NULL) + { + char *portnum; + + asprintf(&portnum, "%d", bot->port); + gtk_entry_set_text(GTK_ENTRY(botlist_editor_botname), bot->botname); + gtk_entry_set_text(GTK_ENTRY(botlist_editor_host), bot->host); + gtk_entry_set_text(GTK_ENTRY(botlist_editor_port), portnum); + gtk_entry_set_text(GTK_ENTRY(botlist_editor_handle), bot->handle); + + while (!can_close) + { + can_close = TRUE; + response = gtk_dialog_run(editor_window); + + if (response == GTK_RESPONSE_OK) + { + gint port_num; + char *endptr; + + gchar *botname = trim((char *)gtk_entry_get_text(GTK_ENTRY(botlist_editor_botname))); + gchar *host = trim((char *)gtk_entry_get_text(GTK_ENTRY(botlist_editor_host))); + gchar *port = trim((char *)gtk_entry_get_text(GTK_ENTRY(botlist_editor_port))); + gchar *handle = trim((char *)gtk_entry_get_text(GTK_ENTRY(botlist_editor_handle))); + if ((strcmp(botname, "") == 0) || (strcmp(host, "") == 0) || (strcmp(port, "") == 0)) + { + can_close = FALSE; +#ifdef DEBUG + if (config_data.debug) + fprintf(stderr, "All fields are mandatory except Handle\n"); +#endif /* DEBUG */ + // TODO: Here we have to notify the user + g_free(botname); + g_free(host); + g_free(port); + g_free(handle); + continue; + } + port_num = strtol(port, &endptr, 10); + if (*endptr) + { + can_close = FALSE; +#ifdef DEBUG + if (config_data.debug) + fprintf(stderr, "Port must be a number! (%s)\n", endptr); +#endif /* DEBUG */ + // TODO: Here we have to notify the user + g_free(botname); + g_free(host); + g_free(port); + g_free(handle); + continue; + } + (void)update_bot(bot, botname, host, port_num, handle); + refresh_botlist(); + + g_free(port); + g_free(botname); + g_free(host); + g_free(handle); + } + } + + gtk_widget_hide(GTK_WIDGET(editor_window)); + } + } +#ifdef DEBUG + else + if (config_data.debug) + printf("No bot selected, but signal caught??\n"); +#endif /* DEBUG */ +} +/* }}} */ + +/* {{{ add_bot_dialog() */ +/* This callback is called when the "Add" button is pressed in the Botlist dialog */ +static void +add_bot_dialog(GtkWidget *widget, gpointer data) +{ + gint response; + gboolean can_close = FALSE; + + if (!editor_window) + create_bot_editor(NULL); + gtk_window_set_title(GTK_WINDOW(editor_window), _("Add bot")); + + gtk_entry_set_text(GTK_ENTRY(botlist_editor_botname), ""); + gtk_entry_set_text(GTK_ENTRY(botlist_editor_host), ""); + gtk_entry_set_text(GTK_ENTRY(botlist_editor_port), ""); + gtk_entry_set_text(GTK_ENTRY(botlist_editor_handle), ""); + + while (!can_close) + { + can_close = TRUE; + response = gtk_dialog_run(editor_window); + + if (response == GTK_RESPONSE_OK) + { + gint port_num; + char *endptr; + + gchar *botname = trim((char *)gtk_entry_get_text(GTK_ENTRY(botlist_editor_botname))); + gchar *host = trim((char *)gtk_entry_get_text(GTK_ENTRY(botlist_editor_host))); + gchar *port = trim((char *)gtk_entry_get_text(GTK_ENTRY(botlist_editor_port))); + gchar *handle = trim((char *)gtk_entry_get_text(GTK_ENTRY(botlist_editor_handle))); + if ((strcmp(botname, "") == 0) || (strcmp(host, "") == 0) || (strcmp(port, "") == 0)) + { + can_close = FALSE; +#ifdef DEBUG + if (config_data.debug) + fprintf(stderr, "All fields are mandatory except Handle\n"); +#endif /* DEBUG */ + // TODO: Here we have to notify the user + g_free(botname); + g_free(host); + g_free(port); + g_free(handle); + continue; + } + port_num = strtol(port, &endptr, 10); + if (*endptr) + { + can_close = FALSE; +#ifdef DEBUG + if (config_data.debug) + fprintf(stderr, "Port must be a number! (%s)\n", endptr); +#endif /* DEBUG */ + // TODO: Here we have to notify the user + g_free(botname); + g_free(host); + g_free(port); + g_free(handle); + continue; + } + if (add_bot(botname, host, port_num, handle) != BCE_SUCCESS) + { +#ifdef DEBUG + if (config_data.debug) + fprintf(stderr, "Port must be a number! (%s)\n", endptr); +#endif /* DEBUG */ + // TODO: Here we have to notify the user + } + else + refresh_botlist(); + g_free(port); + g_free(botname); + g_free(host); + g_free(handle); + } + } + + gtk_widget_hide(GTK_WIDGET(editor_window)); +} +/* }}} */ + +/* {{{ cchange() */ +/* This callback is called, when I select a list item */ +void +static cchange(GtkWidget *widget, gpointer data) +{ + /* Here we can be sure that we have a selected item */ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + { + gtk_widget_set_sensitive(botlist_connect_button, TRUE); + gtk_widget_set_sensitive(botlist_edit_button, TRUE); + gtk_widget_set_sensitive(botlist_remove_button, TRUE); + } +#ifdef DEBUG + else + if (config_data.debug) + printf("No bot selected, but signal caught??\n"); +#endif /* DEBUG */ +} +/* }}} */ + +/* {{{ cactivate() */ +/* This callback is called when I double-click a list item, or when I navigate to an item and press Enter */ +static void +cactivate(GtkWidget *widget, GtkTreePath *path, GtkTreeViewColumn *column, gpointer data) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + gtk_button_clicked(GTK_BUTTON(botlist_connect_button)); +#ifdef DEBUG + else + if (config_data.debug) + fprintf(stderr, "No bot selected, but signal caught??\n"); +#endif /* DEBUG */ +} +/* }}} */ + +/* {{{ toggle_cursor_row() */ +/* This callback is called when I select or deselect a list item (but not when I change selection!) */ +static gboolean +toggle_cursor_row(GtkTreeView *widget, gpointer data) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + { + gtk_widget_set_sensitive(botlist_connect_button, FALSE); + gtk_widget_set_sensitive(botlist_edit_button, FALSE); + gtk_widget_set_sensitive(botlist_remove_button, FALSE); + } + else + { + gtk_widget_set_sensitive(botlist_connect_button, TRUE); + gtk_widget_set_sensitive(botlist_edit_button, TRUE); + gtk_widget_set_sensitive(botlist_remove_button, TRUE); + } + + return TRUE; +} +/* }}} */ + +/* {{{ create_and_fill_model() */ +/* This function creates the tree model and fills it with data */ +static GtkTreeModel * +create_and_fill_model(void) +{ + GtkListStore *store; + + store = gtk_list_store_new(1, G_TYPE_STRING); + + g_list_foreach(internal_bot_list, add_this_data, (gpointer)store); + + return GTK_TREE_MODEL(store); +} +/* }}} */ + +/* {{{ display_botlist_window() */ +/* This one creates the bot list window if it doesn't exist, and displays it */ +void +display_botlist_window(void) +{ + gint response; + gboolean created_model = FALSE; + GtkTreeModel *model; + + if (!GTK_IS_WINDOW(botlist_win)) + { + GtkCellRenderer *renderer; + GtkWidget *hbox, + *vbox, + *button, + *scrollwin, + *image, + *bbox, + *blabel; + + created_model = TRUE; + + botlist_win = (GtkDialog *)gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(botlist_win), _("Bot list")); + gtk_window_set_transient_for(GTK_WINDOW(botlist_win), GTK_WINDOW(main_window)); + gtk_window_set_destroy_with_parent(GTK_WINDOW(botlist_win), TRUE); + gtk_window_set_modal(GTK_WINDOW(botlist_win), TRUE); + + image = gtk_image_new_from_stock(GTK_STOCK_CONNECT, GTK_ICON_SIZE_BUTTON); + blabel = gtk_label_new_with_mnemonic(_("_Connect")); + bbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(bbox), blabel, TRUE, TRUE, 0); + + botlist_connect_button = gtk_button_new(); + gtk_widget_set_sensitive(botlist_connect_button, FALSE); + gtk_container_add(GTK_CONTAINER(botlist_connect_button), bbox); + gtk_widget_show_all(botlist_connect_button); + gtk_dialog_add_action_widget(botlist_win, botlist_connect_button, GTK_RESPONSE_APPLY); + + button = gtk_button_new_from_stock(GTK_STOCK_SAVE); + gtk_widget_show(button); + gtk_dialog_add_action_widget(botlist_win, button, GTK_RESPONSE_OK); + + button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); + gtk_widget_show(button); + gtk_dialog_add_action_widget(botlist_win, button, GTK_RESPONSE_CANCEL); + + scrollwin = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_set_size_request(scrollwin, 150, 200); + + renderer = gtk_cell_renderer_text_new(); + bot_list = gtk_tree_view_new(); + gtk_signal_connect(GTK_OBJECT(bot_list), "cursor-changed", GTK_SIGNAL_FUNC(cchange), NULL); + gtk_signal_connect(GTK_OBJECT(bot_list), "row-activated", GTK_SIGNAL_FUNC(cactivate), NULL); + gtk_signal_connect(GTK_OBJECT(bot_list), "toggle-cursor-row", GTK_SIGNAL_FUNC(toggle_cursor_row), NULL); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(bot_list), -1, _("Bot name"), renderer, "text", 0, NULL); + model = create_and_fill_model(); + gtk_tree_view_set_model(GTK_TREE_VIEW(bot_list), model); + g_object_unref(model); + + gtk_container_add(GTK_CONTAINER(scrollwin), bot_list); + + hbox = gtk_hbox_new(FALSE, 2); + + gtk_box_pack_start(GTK_BOX(hbox), scrollwin, TRUE, TRUE, 0); + + vbox = gtk_vbox_new(FALSE, 2); + + button = gtk_button_new_from_stock(GTK_STOCK_ADD); + gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(add_bot_dialog), NULL); + gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); + + botlist_edit_button = gtk_button_new_from_stock(GTK_STOCK_EDIT); + gtk_signal_connect(GTK_OBJECT(botlist_edit_button), "clicked", GTK_SIGNAL_FUNC(edit_bot_dialog), NULL); + gtk_widget_set_sensitive(botlist_edit_button, FALSE); + gtk_box_pack_start(GTK_BOX(vbox), botlist_edit_button, FALSE, FALSE, 0); + + botlist_remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); + gtk_widget_set_sensitive(botlist_remove_button, FALSE); + gtk_box_pack_start(GTK_BOX(vbox), botlist_remove_button, FALSE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); + + gtk_widget_show_all(hbox); + + gtk_container_add(GTK_CONTAINER(botlist_win->vbox), hbox); + } + + if (!created_model) + refresh_botlist(); + + response = gtk_dialog_run(botlist_win); + + switch (response) + { + case GTK_RESPONSE_APPLY: + { + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + t_tab_data *tab = get_active_tab(); + + if (tab) + gtk_widget_grab_focus(tab->editbox); + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(bot_list)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + { + gchar *name; + + if (!tab) + add_tab(&tab); + + if (tab->connected) + add_tab(&tab); + + gtk_tree_model_get(model, &iter, 0, &name, -1); + + assign_bot_to_tab_by_name(tab, name); + g_free(name); + connect_tab(tab); + } +#ifdef DEBUG + else + if (config_data.debug) + printf("No bot selected, but signal caught??\n"); +#endif /* DEBUG */ + } + break; + case GTK_RESPONSE_OK: + save_bot_list_to_config(); + break; + } + + gtk_widget_hide(GTK_WIDGET(botlist_win)); +} +/* }}} */ + +/* {{{ create_bot_editor */ +void +create_bot_editor(t_bot_data *bot) +{ + if (!editor_window) + { + GtkWidget *button, + *label; + GtkTable *table; + + editor_window = (GtkDialog *)gtk_dialog_new(); + gtk_window_set_transient_for(GTK_WINDOW(editor_window), GTK_WINDOW(botlist_win)); + gtk_window_set_destroy_with_parent(GTK_WINDOW(editor_window), TRUE); + gtk_window_set_modal(GTK_WINDOW(editor_window), TRUE); + + table = (GtkTable *)gtk_table_new(4, 2, FALSE); + + gtk_table_attach(table, (label = gtk_label_new(_("Bot name"))), 0, 1, 0, 1, GTK_FILL, 0, 2, 2); + gtk_table_attach(table, (botlist_editor_botname = gtk_entry_new()), 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 2, 2); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + + gtk_table_attach(table, (label = gtk_label_new(_("Host"))), 0, 1, 1, 2, GTK_FILL, 0, 2, 2); + gtk_table_attach(table, (botlist_editor_host = gtk_entry_new()), 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 2, 2); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + + gtk_table_attach(table, (label = gtk_label_new(_("Port"))), 0, 1, 2, 3, GTK_FILL, 0, 2, 2); + gtk_table_attach(table, (botlist_editor_port = gtk_entry_new()), 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 2, 2); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + + gtk_table_attach(table, (label = gtk_label_new(_("Handle"))), 0, 1, 3, 4, GTK_FILL, 0, 2, 2); + gtk_table_attach(table, (botlist_editor_handle = gtk_entry_new()), 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, 0, 2, 2); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + + gtk_container_add(GTK_CONTAINER(editor_window->vbox), GTK_WIDGET(table)); + + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_dialog_add_action_widget(editor_window, button, GTK_RESPONSE_CANCEL); + + button = gtk_button_new_from_stock(GTK_STOCK_SAVE); + gtk_dialog_add_action_widget(editor_window, button, GTK_RESPONSE_OK); + } + gtk_widget_show_all(GTK_WIDGET(editor_window)); +} +/* }}} */ + diff --git a/src/bots.c b/src/bots.c new file mode 100644 index 0000000..11286e4 --- /dev/null +++ b/src/bots.c @@ -0,0 +1,270 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * bots.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Bot list handling + }}} */ + +/* TODO: Put this into a Makefile */ +#define _GNU_SOURCE +/* {{{ Includes */ +#include +#include +#include +#include + +#include "config.h" + +#include "typedefs.h" +#include "functions.h" +#include "variables.h" +/* }}} */ + +/* {{{ Variables */ +GList *internal_bot_list; +/* }}} */ + +#ifdef DEBUG +/* {{{ print_this_bot() */ +void print_this_bot(gpointer data, gpointer user_data) +{ + t_bot_data *temp = (t_bot_data *)data; + + printf("%s:%s:%d:%s\n", temp->botname, temp->host, temp->port, temp->handle); +} +/* }}} */ + +/* {{{ list_bots() */ +void +list_bots(void) +{ + g_list_foreach(internal_bot_list, print_this_bot, NULL); +} +/* }}} */ +#endif + +/* {{{ search_function() */ +static gint +search_function(gconstpointer a, gconstpointer b) +{ + t_bot_data *bot = (t_bot_data *)a; + char *botname = (char *)b; + + return strcmp(bot->botname, botname); +} +/* }}} */ + +/* {{{ add_bot() */ +gint +add_bot(gchar *botname, gchar *host, guint port, gchar *handle) +{ + t_bot_data *temp; + + if (g_list_find_custom(internal_bot_list, botname, search_function)) + { + // TODO: Here we should notify the user that this bot already exists. +#ifdef DEBUG + if (config_data.debug) + fprintf(stderr, _("There is already a bot named %s in the list.\n"), botname); +#endif /* DEBUG */ + return BCE_BOT_EXISTS; + } + +#ifdef DEBUG + printf("Adding bot %s at %s:%d with user %s\n", botname, host, port, handle); +#endif + + temp = g_malloc(sizeof(t_bot_data)); + + temp->botname = g_strdup(botname); + temp->host = g_strdup(host); + temp->port = port; + temp->handle = g_strdup(handle); + + internal_bot_list = g_list_append(internal_bot_list, temp); + + return BCE_SUCCESS; +} +/* }}} */ + +/* {{{ del_bot() */ +gint +del_bot(gchar *botname) +{ + return BCE_SUCCESS; +} +/* }}} */ + +/* {{{ get_bot_by_botname() */ +t_bot_data * +get_bot_by_botname(gchar *name) +{ + GList *temp = g_list_find_custom(internal_bot_list, name, search_function); + + if (temp) + return (t_bot_data *)(temp->data); + + return NULL; +} +/* }}} */ + +/* {{{ create_bot_record() */ +gint +create_bot_record(gchar *host, gint port, t_bot_data **rec) +{ + t_bot_data *temp; + + if (rec == NULL) + return BCE_NOMEM; + + temp = g_malloc(sizeof(t_bot_data)); + + if (temp) + { + temp->botname = NULL; + temp->host = g_strdup(host); + temp->port = port; + temp->handle = NULL; + + *rec = temp; + return BCE_SUCCESS; + } + + return BCE_NOMEM; +} +/* }}} */ + +/* {{{ update_bot() */ +gint +update_bot(t_bot_data *bot, gchar *botname, gchar *host, guint port, gchar *handle) +{ + if (bot) + { + t_bot_data *temp = g_malloc(sizeof(t_bot_data)); + memset(temp, 0, sizeof(t_bot_data)); + + if (bot->botname) + { + temp->botname = g_strdup(bot->botname); + g_free(bot->botname); + } + if (bot->host) + { + temp->host = g_strdup(bot->host); + g_free(bot->host); + } + temp->port = bot->port; + if (bot->handle) + { + temp->handle = g_strdup(bot->handle); + g_free(bot->handle); + } + + bot->botname = g_strdup(botname); + bot->host = g_strdup(host); + bot->port = port; + bot->handle = g_strdup(handle); + + if (temp->botname) + g_free(temp->botname); + if (temp->host) + g_free(temp->host); + if (temp->handle) + g_free(temp->handle); + } + + return BCE_SUCCESS; +} +/* }}} */ + +/* {{{ get_bot_by_name() */ +gint +get_bot_by_name(gconstpointer a, gconstpointer b) +{ + GConfEntry *entry = (GConfEntry *)a; + gchar *name = (gchar *)b; + gchar *i; + GConfValue *value; + gchar *this_name; + gchar *key; + gint len = strlen(GCONF2_ROOT "/bots/"); + + /* TODO: Would be easier with regex? */ + key = (gchar *)gconf_entry_get_key(entry); + if (strncmp(key + len, "bot", 3) != 0) + return 1; + for (i = key + len + 3; *i && isdigit(*i); i++); + if (*i != '_') + return 1; + if (strcmp(++i, "name") != 0) + return 1; + value = gconf_entry_get_value(entry); + if (value->type != GCONF_VALUE_STRING) + return 1; + this_name = (char *)gconf_value_get_string(value); + return strcmp(this_name, name); +} +/* }}} */ + +/* {{{ free_bot_data() */ +void +free_bot_data(gpointer data, gpointer user_data) +{ + t_bot_data *bot = (t_bot_data *)data; + + if (bot) + { + if (bot->botname) + g_free(bot->botname); + if (bot->host) + g_free(bot->host); + if (bot->handle) + g_free(bot->handle); + g_free(bot); + } +} +/* }}} */ + +/* {{{ is_this_num_bot() */ +gint +is_this_num_bot(gconstpointer a, gconstpointer b) +{ + if (((t_bot_data *)a)->id == *((guint *)b)) + return 0; + + return 1; +} +/* }}} */ + +/* {{{ get_bot_by_conf_num() */ +t_bot_data * +get_bot_by_conf_num(guint num) +{ + GList *entry; + + entry = g_list_find_custom(internal_bot_list, &num, is_this_num_bot); + if (entry) + return entry->data; + return NULL; +} +/* }}} */ + diff --git a/src/callbacks.c b/src/callbacks.c new file mode 100644 index 0000000..0ee6aa0 --- /dev/null +++ b/src/callbacks.c @@ -0,0 +1,518 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * callbacks.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Various widget callbacks + }}} */ + +/* {{{ Includes */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#include "variables.h" +#include "functions.h" +/* }}} */ + +/* {{{ destroy_event() */ +void +destroy_event(GtkWidget *widget, gpointer data) +{ + if (widget == main_window) + gtk_main_quit(); +} +/* }}} */ + +/* {{{ delete_event() */ +gboolean +delete_event(GtkWidget * widget, GdkEvent *event, gpointer data) +{ + exit_cleanly(FALSE); + return FALSE; +} +/* }}} */ + +/* {{{ toolbar_quit() */ +void +toolbar_quit(GtkButton *button, gpointer data) +{ + exit_cleanly(FALSE); +} +/* }}} */ + +/* {{{ toolbar_add_tab() */ +void +toolbar_add_tab(GtkButton *button, gpointer data) +{ + add_tab(NULL); +} +/* }}} */ + +/* {{{ toolbar_close_active() */ +void toolbar_close_active(GtkButton *button, gpointer data) +{ + close_tab(get_active_tab()); +} +/* }}} */ + +/* {{{ toolbar_open_prefs() */ +void +toolbar_open_prefs(GtkButton *button, gpointer data) +{ + display_setup_window(); +} +/* }}} */ + +/* {{{ book_change_tab() */ +void +book_change_tab(GtkNotebook *book, GtkNotebookPage *newpage, guint pagenum, gpointer data) +{ + GList *list; + + list = g_list_find_custom(tab_list, &pagenum, find_tab_by_pagenum); + if (list) + { + t_tab_data *temp; + gchar *buf; + gboolean sidebar_visible; + gboolean menuitem_state; + GtkWidget *box = gtk_paned_get_child2(GTK_PANED(gtk_notebook_get_nth_page(GTK_NOTEBOOK(main_book), pagenum))); + + temp = list->data; + Context; + set_title(NULL, "BotCommander - %s", gtk_label_get_text(GTK_LABEL(temp->label))); + Context; + buf = g_malloc(strlen(_("Mode: %c")) + 1); + sprintf(buf, _("Mode: %c"), toupper(temp->mode)); + gtk_label_set_text(GTK_LABEL(main_statuslabel_mode), buf); + g_free(buf); + + menuitem_state = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(main_menu_show_sidebar)); + sidebar_visible = GTK_WIDGET_VISIBLE(box); + + if (menuitem_state != sidebar_visible) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(main_menu_show_sidebar), sidebar_visible); + } +} +/* }}} */ + +/* {{{ close_tab_cb() */ +void +close_tab_cb(GtkWidget *button, gpointer data) +{ + GList *to_remove = g_list_find(tab_list, data); + + if (to_remove) + close_tab((t_tab_data *)data); +} +/* }}} */ + +/* {{{ entry_activate() */ +gboolean +entry_activate(GtkWidget *widget, gpointer data) +{ + char this_mode; + t_tab_data *active_tab = (t_tab_data *)data; + gchar *text; + gboolean add_to_history = TRUE; + gboolean shift = FALSE; + gboolean want_change = TRUE; + + this_mode = active_tab->mode; + text = (gchar *)gtk_entry_get_text(GTK_ENTRY(widget)); + + if (*text == '/') + this_mode = 'b'; + else if (*text == '.') + this_mode = 'e'; + else if (*text == '@') + this_mode = 'm'; + + switch (tolower(this_mode)) + { + case 'b': + Context; + want_change = process_commandline((*text == '/') ? text + 1 : text, active_tab); + Context; + shift = (*text == '/'); + Context; + break; + case 'e': + if (!active_tab->connected) + { + feed_error_to_terminal(active_tab, TRUE, _("Won't send an eggdrop command to a not connected tab")); + add_to_history = FALSE; + break; + } + else + { + char *buf = NULL; + + buf = g_convert(text, -1, BOT_CHARSET, "UTF-8", NULL, NULL, NULL); + if (buf) + { + dprintf(active_tab->sock, "%s%s\n", (*buf != *EGG_CMD_CHAR) ? EGG_CMD_CHAR : "", buf); + g_free(buf); + } + } + shift = (*text == '.'); + break; + case 'm': + default: + if (!active_tab->connected) + { + feed_error_to_terminal(active_tab, TRUE, _("Won't send message to a not connected tab")); + add_to_history = FALSE; + break; + } + else + { + char *buf = NULL; + + buf = g_convert(text, -1, BOT_CHARSET, "UTF-8", NULL, NULL, NULL); + if (buf) + { + dprintf(active_tab->sock, "%s%s\n", (*buf == *EGG_CMD_CHAR) ? " " : "", buf); + g_free(buf); + } + } + shift = (*text == '@'); + } + + Context; + + if ((add_to_history) && (gtk_entry_get_visibility(GTK_ENTRY(widget)))) + history_add(active_tab, tolower(this_mode), (shift) ? text + 1 : text); + active_tab->history_position = -1; + Context; + + if (want_change) + gtk_entry_set_text(GTK_ENTRY(((t_tab_data *)data)->editbox), ""); + + Context; + + return TRUE; +} +/* }}} */ + +/* {{{ menu_exit() */ +void +menu_exit(GtkWidget *widget, gpointer data) +{ + exit_cleanly(FALSE); +} +/* }}} */ + +/* {{{ menu_mode_changed() */ +void +menu_mode_changed(GtkWidget *widget, gpointer data) +{ + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) + { + char m = 0; + + if (widget == main_menu_mode_b) + m = 'b'; + else + { + if (widget == main_menu_mode_e) + m = 'e'; + else + { + if (widget == main_menu_mode_m) + m = 'm'; + } + } + if (m) + change_mode(m, TRUE); + } +} +/* }}} */ + +/* {{{ menu_botlist_open() */ +void +menu_botlist_open(GtkWidget *widget, gpointer data) +{ + display_botlist_window(); +} +/* }}} */ + +/* {{{ menu_prefs_open() */ +void +menu_prefs_open(GtkWidget *widget, gpointer data) +{ + display_setup_window(); +} +/* }}} */ + +/* {{{ menu_new_tab() */ +void +menu_new_tab(GtkWidget *widget, gpointer data) +{ + add_tab(NULL); +} +/* }}} */ + +/* {{{ menu_close_tab() */ +void +menu_close_tab(GtkWidget *widget, gpointer data) +{ + close_tab(get_active_tab()); +} +/* }}} */ + +/* {{{ menu_about() */ +void +menu_about(GtkWidget *widget, gpointer data) +{ + display_about_box(); +} +/* }}} */ + +/* {{{ entry_keypress() */ +int +entry_keypress(GtkEntry *entry, GdkEventKey *event, gpointer data) +{ + if (data) + { + t_tab_data *tab = (t_tab_data *)data; + if (entry == (GtkEntry *)tab->editbox) + { + if (event->keyval == GDK_Up) + { + gint count = get_history_len(tab); + gint steps; + t_history_data *temp = tab->history; + + if (count == 0) + { + tab->history_position = -1; + return TRUE; + } + + if ((count > 0) && (count > tab->history_position + 1)) + tab->history_position++; + + steps = count - tab->history_position - 1; + while (steps) + { + if (!temp) + return TRUE; + temp = temp->next; + steps--; + } + gtk_entry_set_text(GTK_ENTRY(tab->editbox), temp->line); + gtk_entry_set_position(GTK_ENTRY(tab->editbox), -1); + return TRUE; + } + else if (event->keyval == GDK_Down) + { + gint count = get_history_len(tab); + + if (count == 0) + { + tab->history_position = -1; + return TRUE; + } + + if (tab->history_position > -1) + tab->history_position--; + + if (tab->history_position == -1) + gtk_entry_set_text(GTK_ENTRY(tab->editbox), ""); + else + { + t_history_data *temp = tab->history; + gint steps = count - tab->history_position - 1; + + while (steps) + { + if (!temp) + return TRUE; + temp = temp->next; + steps--; + } + gtk_entry_set_text(GTK_ENTRY(tab->editbox), temp->line); + gtk_entry_set_position(GTK_ENTRY(tab->editbox), -1); + } + return TRUE; + } + } + } + switch (event->keyval) + { + case GDK_0: + case GDK_1: + case GDK_2: + case GDK_3: + case GDK_4: + case GDK_5: + case GDK_6: + case GDK_7: + case GDK_8: + case GDK_9: + if (event->state & GDK_MOD1_MASK) + { + gint num = event->keyval - GDK_0; + if (num == 0) + num = 9; + else + num--; + + change_active_tab(num); + return TRUE; + } + break; + case GDK_Tab: + return TRUE; + break; + } + if (event->keyval == GDK_Tab) + return TRUE; + + return FALSE; +} +/* }}} */ + +/* {{{ socket_event() */ +void +socket_event(gpointer data, gint fd, GdkInputCondition cond) +{ + t_tab_data *tab = data; + ssize_t len; + char buf[MAX_READ_LINE_LEN]; + static char *current_line = NULL; + static int current_line_pointer = 0; + static char current_telnet_code[4]; + static int current_telnet_code_pointer = 0; + + memset(&buf, 0, MAX_READ_LINE_LEN); + memset(¤t_telnet_code, 0, 4); + + len = recv(tab->sock, &buf, MAX_READ_LINE_LEN - 1, 0); + + if (len == 0) + disconnect_tab(tab); + else if (len > 0) + { + char *obuf = NULL, *a; + + if (tab->data_arrived == FALSE) + { + if (config_data.change_to_message) + change_mode('M', FALSE); + tab->data_arrived = TRUE; + feed_info_to_terminal(tab, TRUE, _("Connected")); + } + + if (current_line == NULL) + { + current_line = g_malloc(MAX_READ_LINE_LEN + 1); + memset(current_line, 0, MAX_READ_LINE_LEN + 1); + } + + for (a = (char *)&buf; *a; a++) + { + if (*a == '\r') + continue; + if (*a == '\n') + { + process_incoming_data(tab, current_line); + memset(current_line, 0, MAX_READ_LINE_LEN + 1); + current_line_pointer = 0; + continue; + } + if ((*a == *TELNET_IAC) || (*a == *TELNET_WILL) || (*a == *TELNET_WONT) || (*a == *TELNET_ECHO)) + { + current_telnet_code[current_telnet_code_pointer++] = *a; + if (strlen((char *)¤t_telnet_code) == 3) + { + if (strcmp((char *)¤t_telnet_code, TELNET_WILL_ECHO) == 0) + gtk_entry_set_visibility(GTK_ENTRY(tab->editbox), FALSE); + else if (strcmp((char *)¤t_telnet_code, TELNET_WONT_ECHO) == 0) + gtk_entry_set_visibility(GTK_ENTRY(tab->editbox), TRUE); + memset(¤t_telnet_code, 0, 4); + current_telnet_code_pointer = 0; + } + continue; + } + current_line[current_line_pointer++] = *a; + } + + obuf = g_convert(buf, -1, "UTF-8", BOT_CHARSET, NULL, NULL, NULL); + g_free(obuf); + } +#ifdef DEBUG + else if (config_data.debug) + { + char *buf = NULL; + char *orig = strerror(errno); + + buf = g_locale_to_utf8(orig, -1, NULL, NULL, NULL); + feed_error_to_terminal(tab, TRUE, "%s", buf); + g_free(buf); + + disconnect_tab(tab); + } +#endif /* DEBUG */ +} +/* }}} */ + +/* {{{ menu_showhide_sidebar() */ +void +menu_showhide_sidebar(GtkWidget *menuitem, gpointer data) +{ + gint current_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_book)); + + if (current_page >= 0) + { + gboolean new_state, + current_state; + GtkWidget *box = gtk_paned_get_child2(GTK_PANED(gtk_notebook_get_nth_page(GTK_NOTEBOOK(main_book), current_page))); + + new_state = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); + current_state = GTK_WIDGET_VISIBLE(box); + + feed_info_to_terminal(get_active_tab(), TRUE, "Current state: %s; new state: %s\n", (current_state) ? "active" : "not active", (new_state) ? "active" : "not active"); + + if (current_state != new_state) + { + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)) == TRUE) + gtk_widget_show_all(box); + else + gtk_widget_hide_all(box); + } + + } +} +/* }}} */ + diff --git a/src/chanprops.c b/src/chanprops.c new file mode 100644 index 0000000..2060486 --- /dev/null +++ b/src/chanprops.c @@ -0,0 +1,138 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * chanprops.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * This holds functions which belong to the Channel properties dialog + }}} */ + +/* {{{ Includes */ +#include +#include +#include + +#include "functions.h" +#include "typedefs.h" +/* }}} */ + +/* {{{ find_chan_in_list() */ +gint +find_chan_in_list(gconstpointer a, gconstpointer b) +{ + t_channel *chanrec = (t_channel *)a; + gchar *channame = (gchar *)b; + + if (streq(chanrec->name, channame, FALSE)) + return 0; + + return 1; +} +/* }}} */ + +/* {{{ find_chan_property() */ +gint +find_chan_property(gconstpointer a, gconstpointer b) +{ + t_chan_prop *prop = (t_chan_prop *)a; + gchar *propname = (gchar *)b; + + return strcmp(prop->name, propname); +} +/* }}} */ + +/* {{{ update_channel_property() */ +void +update_channel_property(t_tab_data *tab, gchar *chan, gchar *property) +{ + GList *this_chan; + + if ((this_chan = g_list_find_custom(tab->actual_channel_list, chan, find_chan_in_list))) + { + t_chan_prop *prop; + GList *this_prop; + t_channel *chanrec = this_chan->data; + + switch (tab->chanprops_list_num) + { + case 1: + /* Channel modes */ + break; + case 2: + /* idle-kick */ + break; + case 3: + /* stopnethack-mode */ + break; + case 4: + /* revenge-mode */ + break; + } + + prop = g_malloc0(sizeof(t_chan_prop)); + + prop->bool_prop = ((*property == '+') || (*property == '-')); + + Context; + + if (prop->bool_prop) + { + prop->name = g_strdup(property + 1); + prop->bool_value = (*property == '+') ? TRUE : FALSE; + prop->string_value = NULL; + } + else + { + gchar *a; + + Context; + + for (a = property; *a; a++) + if (isspace(*a)) + break; + + if (*a && (a - property > 0)) + { + prop->name = g_strndup(property, a - property); + for (; *a; a++) + if (!isspace(*a)) + break; + prop->string_value = g_strdup(a); + } + + Context; + } + + if (prop->name) + { + this_prop = g_list_find_custom(chanrec->properties, prop->name, find_chan_property); + if (this_prop) + { + printf("Updating %s property \"%s\" with value %s\n", (prop->bool_prop) ? "boolean" : "string", prop->name, (prop->bool_prop) ? ((prop->bool_value) ? "TRUE" : "FALSE") : prop->string_value); + } + else + { + printf("Adding %s property \"%s\" with value %s\n", (prop->bool_prop) ? "boolean" : "string", prop->name, (prop->bool_prop) ? ((prop->bool_value) ? "TRUE" : "FALSE") : prop->string_value); + } + } + } +} +/* }}} */ + diff --git a/src/commands.c b/src/commands.c new file mode 100644 index 0000000..b95761f --- /dev/null +++ b/src/commands.c @@ -0,0 +1,453 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * commands.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * BotCommander internal command definitions + }}} */ + +/* TODO: Put this into a Makefile */ +#define _GNU_SOURCE +/* {{{ Includes */ +#include +#include +#include +#include + +#include "typedefs.h" +#include "functions.h" +#include "variables.h" +/* }}} */ + +/* {{{ Prototypes */ +BC_COMMAND(command_exit); +BC_COMMAND(command_close); +BC_COMMAND(command_connect); +BC_COMMAND(command_assign); +BC_COMMAND(command_mode); +BC_COMMAND(command_histlist); +BC_COMMAND(command_botlist); +BC_COMMAND(command_preferences); +BC_COMMAND(command_disconnect); +/* }}} */ + +/* {{{ internal_command[] */ +t_command internal_command[] = { +/* verb, CT_INTERNAL, paramnum, can_abbrev, function */ + {"QUIT", CT_INTERNAL, 0, FALSE, command_exit}, + {"CLOSE", CT_INTERNAL, 0, TRUE, command_close}, + {"CONNECT", CT_INTERNAL, 0, TRUE, command_connect}, + {"ASSIGN", CT_INTERNAL, 1, TRUE, command_assign}, + {"MODE", CT_INTERNAL, 1, TRUE, command_mode}, + {"HISTLIST", CT_INTERNAL, 0, TRUE, command_histlist}, + {"BOTLIST", CT_INTERNAL, 0, TRUE, command_botlist}, + {"PREFERENCES", CT_INTERNAL, 0, TRUE, command_preferences}, + {"DISCONNECT", CT_INTERNAL, 0, TRUE, command_disconnect}, + {NULL, CT_INTERNAL, 0, FALSE, NULL}, +}; +/* }}} */ + +#define num_commands (sizeof(command) / sizeof(t_command)) + +/* {{{ command_exit */ +BC_COMMAND(command_exit) +{ + exit_cleanly(FALSE); + return FALSE; +} +/* }}} */ + +/* {{{ command_close */ +BC_COMMAND(command_close) +{ + Context; + close_tab(tab); + Context; + return FALSE; +} +/* }}} */ + +/* {{{ command_connect */ +BC_COMMAND(command_connect) +{ + if (tab->connected) + { + feed_error_to_terminal(tab, TRUE, _("This tab is already connected. Exit the bot with .quit, or use /DISCONNECT!")); + return TRUE; + } + if ((paramnum == 0) && (tab->bot == NULL)) + { + feed_error_to_terminal(tab, TRUE, _("No bot is assigned to this tab. Use ASSIGN to do that.")); + return TRUE; + } + if (paramnum == 0) + { +#ifdef DEBUG /* {{{ */ + if (config_data.debug) + feed_message_to_terminal(tab, TRUE, _("Connecting to %s"), tab->bot->botname); +#endif /* DEBUG }}} */ + } + if (paramnum == 1) + { + t_bot_data *bot; + + if ((bot = get_bot_by_botname(param[1])) == NULL) + { + feed_error_to_terminal(tab, TRUE, _("No bot exists by that name")); + return TRUE; + } + assign_bot_to_tab(tab, bot); +#ifdef DEBUG /* {{{ */ + if (config_data.debug) + feed_message_to_terminal(tab, TRUE, _("Connecting to %s"), bot->botname); +#endif /* DEBUG }}} */ + } + if (paramnum > 1) + { + gchar *host = param[1]; + gint port; + t_bot_data *bot; + + if (!is_numeric(param[2], &port)) + { + feed_error_to_terminal(tab, TRUE, _("Second parameter must be a port number!")); + return TRUE; + } + if (create_bot_record(host, port, &bot) != BCE_SUCCESS) + { + feed_error_to_terminal(tab, TRUE, _("Not enough memory!")); + return TRUE; + } + tab->bot = bot; + set_title(tab, "%s:%d", host, port); +#ifdef DEBUG /* {{{ */ + if (config_data.debug) + feed_message_to_terminal(tab, TRUE, _("Connecting to %s:%d"), host, port); +#endif /* DEBUG }}} */ + } + + connect_tab(tab); + return TRUE; +} +/* }}} */ + +/* {{{ command_assign */ +BC_COMMAND(command_assign) +{ + if (!assign_bot_to_tab_by_name(tab, param[1])) + { + feed_error_to_terminal(tab, TRUE, _("No bot exists by this name")); + return TRUE; + } + return TRUE; +} +/* }}} */ + +/* {{{ command_mode */ +BC_COMMAND(command_mode) +{ + char newmode; + if (paramnum < 1) + { + feed_error_to_terminal(tab, TRUE, _("Not enough parameters!")); + return TRUE; + } + if (paramnum > 1) + { + feed_error_to_terminal(tab, TRUE, _("Only one parameter required!")); + return TRUE; + } + if (strlen(param[1]) > 1) + { + feed_error_to_terminal(tab, TRUE, _("The parameter must be one character!")); + return TRUE; + } + newmode = *param[1]; + if (!strchr("bem", tolower(newmode))) + { + feed_error_to_terminal(tab, TRUE, _("Mode char can be one of B, E or M!")); + return TRUE; + } + + change_mode(newmode, FALSE); + return TRUE; +} +/* }}} */ + +/* {{{ command_histlist */ +BC_COMMAND(command_histlist) +{ + t_history_data *temp = tab->history; + + while (temp) + { + feed_info_to_terminal(tab, TRUE, temp->line); + temp = temp->next; + } + + return TRUE; +} +/* }}} */ + +/* {{{ command_botlist */ +BC_COMMAND(command_botlist) +{ +#ifdef DEBUG + list_bots(); +#endif + + display_botlist_window(); + + return TRUE; +} +/* }}} */ + +/* {{{ command_preferences */ +BC_COMMAND(command_preferences) +{ + display_setup_window(); + + return TRUE; +} +/* }}} */ + +/* {{{ command_disconnect */ +BC_COMMAND(command_disconnect) +{ + disconnect_tab(tab); + + return TRUE; +} +/* }}} */ + +/* {{{ get_command_from_abbrev() */ +/* Returning rules: + * If the given abbreviation is a whole command, that command will be returned + * If there are more commands matching the pattern, and only one of them can be abbreviated, that command will be returned + * If there are multiple commands matching the pattern, and more of them can be abbreviated, nothing is returned + */ +t_command * +get_command_from_abbrev(gchar *abbrev) +{ + t_command *temp, *found_command = NULL; + gchar *a; + + for (temp = internal_command; temp->command_verb; temp++) + { + gboolean found = TRUE; + + if (streq(temp->command_verb, abbrev, FALSE)) + return temp; + if (strlen(abbrev) > strlen(temp->command_verb)) + continue; + for (a = abbrev; *a; a++) + { + if (tolower(*a) != tolower(*(temp->command_verb + (a - abbrev)))) + { + found = FALSE; + break; + } + } + if ((found) && (temp->can_abbrev == TRUE)) + { + if (found_command) + return NULL; + found_command = temp; + } + } + + return found_command; +} +/* }}} */ + +/* {{{ process_commandline() */ +gboolean +process_commandline(gchar *cmdline, t_tab_data *tab) +{ + gchar **wl; + gint wnum; + t_command *this_command; + gboolean want_change = TRUE; + + Context; + + if (wordwrap(cmdline, " \t", &wl, &wnum) != BCE_SUCCESS) + { + feed_error_to_terminal(tab, TRUE, _("Not enough memory!")); + } + + Context; + + if (!wnum) + return TRUE; + + this_command = get_command_from_abbrev(wl[0]); + if (this_command) + { + if (!this_command->can_abbrev && (strlen(wl[0]) != strlen(this_command->command_verb))) + feed_error_to_terminal(tab, TRUE, _("This command cannot be abbreviated!")); + else + { + if (this_command->min_paramnum > wnum - 1) + feed_error_to_terminal(tab, TRUE, _("Not enough parameters!")); + else + want_change = this_command->func(tab, wnum - 1, wl); + } + } + else + feed_error_to_terminal(tab, TRUE, _("Unknown command \"%s\""), wl[0]); + + Context; + + wl_free(&wl, wnum); + + Context; + + return want_change; +} +/* }}} */ + +/* {{{ process_botcommander_script_commands() */ +/* This function processes the messages sent by the botcommander.tcl script. */ +void +process_botcommander_script_commands(t_tab_data *tab, char *string) +{ + /* Here the script command is already in UTF-8 */ + + Context; + + switch (*(string + 2)) + { + case '+': + if (strlen(string) > 4) + { + char *command = (string + 4); + + Context; + if (strcmp(command, "ABILITY") == 0) + { + dprintf(tab->sock, ".botcomm_chanlist\n"); + dprintf(tab->sock, ".botcomm_userlist\n"); + } + else if (strcmp(command, "CHANLIST_START") == 0) + { + tab->chanlist_process = TRUE; + if (tab->actual_channel_list != NULL) + g_list_free(tab->actual_channel_list); + tab->actual_channel_list = NULL; + } + else if (strcmp(command, "CHANLIST_END") == 0) + { + tab->actual_channel_list = g_list_reverse(tab->actual_channel_list); + tab->chanlist_process = FALSE; + update_channel_list(tab); + } + else if ((strncmp(command, "CHAN ", 5) == 0) && (tab->chanlist_process)) + { + t_channel *chan = g_malloc(sizeof(t_channel)); + + chan->active = (*(command + 5) == '1') ? TRUE : FALSE; + chan->name = g_strdup((command + 7)); + chan->properties = NULL; + tab->actual_channel_list = g_list_prepend(tab->actual_channel_list, chan); + } + else if (strcmp(command, "USERLIST_START") == 0) + { + tab->userlist_process = TRUE; + if (tab->actual_user_list != NULL) + g_list_free(tab->actual_user_list); + tab->actual_user_list = NULL; + } + else if (strcmp(command, "USERLIST_END") == 0) + { + tab->actual_user_list = g_list_reverse(tab->actual_user_list); + tab->userlist_process = FALSE; + update_user_list(tab); + } + else if ((strncmp(command, "USER ", 5) == 0) && (tab->userlist_process)) + { + t_user *user = g_malloc(sizeof(t_user)); + + user->name = g_strdup((command + 5)); + tab->actual_user_list = g_list_prepend(tab->actual_user_list, user); + } + else if (strncmp(command, "CHANPROPS_START ", 16) == 0) + { + tab->chanprops_process = g_strdup(command + 16); + tab->chanprops_list_num = 0; + } + else if (strncmp(command, "CHANPROPS_END ", 14) == 0) + { + if (tab->chanprops_process != NULL) + { + g_free(tab->chanprops_process); + tab->chanprops_process = NULL; + } + tab->chanprops_list_num = 0; + } + else if (strncmp(command, "CHANPROP ", 9) == 0) + { + gchar *chan = command + 9; + gchar *property; + + for (property = chan; *property; property++) + if (isspace(*property)) + break; + if (*property) + { + *property = 0; + if (streq(chan, tab->chanprops_process, FALSE)) + { + property++; + for (; *property; property++) + if (!isspace(*property)) + break; + tab->chanprops_list_num++; + update_channel_property(tab, chan, property); + } + } + } +#ifdef DEBUG + else if (config_data.debug) + printf("Unknown script command: %s\n", command); +#endif /* DEBUG */ + Context; + } + break; + case '-': + feed_error_to_terminal(tab, FALSE, "%s", string); + break; + default: + return; + } + + Context; + +#ifdef DEBUG + if (config_data.debug) + { + feed_message_to_terminal(tab, TRUE, string); + printf("%s\n", string); + } +#endif /* DEBUG */ +} +/* }}} */ + diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..19608c8 --- /dev/null +++ b/src/config.c @@ -0,0 +1,611 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * config.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Configuration backend handlers + }}} */ + +/* {{{ Includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "defines.h" +#include "typedefs.h" +#include "variables.h" +#include "functions.h" +/* }}} */ + +/* {{{ Defines */ +#define TA_NAME 1 +#define TA_HOST 2 +#define TA_PORT 3 +#define TA_HANDLE 4 +/* }}} */ + +/* {{{ Variables */ +GConfClient *gconf_client; +t_config_data config_data; + +static gboolean gconf_inited = FALSE; +static int internal_value; +/* }}} */ + +/* {{{ set_gconf_values() */ +gboolean +set_gconf_values(GConfClient *client) +{ + int err = 0; + GError *error = NULL; + + error = NULL; + gconf_client_set_float(client, GCONF2_ROOT "/background_saturation", DEFAULT_BACKGROUND_SATURATION, &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_bool(client, GCONF2_ROOT "/change_to_message", DEFAULT_CHANGE_TO_MESSAGE, &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_bool(client, GCONF2_ROOT "/debug", DEFAULT_DEBUG, &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_string(client, GCONF2_ROOT "/default_mode", DEFAULT_DEFAULT_MODE, &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_string(client, GCONF2_ROOT "/sanity", "Needed for gconf sanity check, please don't remove!", &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_bool(client, GCONF2_ROOT "/scroll_on_output", DEFAULT_SCROLL_ON_OUTPUT, &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_bool(client, GCONF2_ROOT "/transparent_background", DEFAULT_TRANSPARENT_BACKGROUND, &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_string(client, GCONF2_ROOT "/vte_font", DEFAULT_VTE_FONT, &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_bool(client, GCONF2_ROOT "/change_to_new_tab", DEFAULT_CHANGE_TO_NEW_TAB, &error); + if (error) err = 1; + + error = NULL; + gconf_client_set_int(client, GCONF2_ROOT "/history_length", DEFAULT_HISTORY_LENGTH, &error); + if (error) err = 1; + + if (err) + { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("There was an error accessing GConf2: %s"), error->message); + gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); + gtk_dialog_run(GTK_DIALOG(dialog)); + + return FALSE; + } + + return TRUE; +} +/* }}} */ + +/* {{{ gconf_sanity_check_string() */ +gboolean +gconf_sanity_check_string(GConfClient *client, const gchar *key) +{ + gchar *string; + GError *error = NULL; + + string = gconf_client_get_string(client, key, &error); + + if (error) + { + gboolean temp = set_gconf_values(client); + if (temp == FALSE) + return FALSE; + } + + if (!string) + { + gboolean temp = set_gconf_values(client); + if (temp == FALSE) + return FALSE; + } else + g_free(string); + + return TRUE; +} +/* }}} */ + +/* {{{ init_config() */ +gboolean +init_config(void) +{ + GError *error = NULL; + + gconf_client = gconf_client_get_default(); + if (!gconf_sanity_check_string(gconf_client, GCONF2_ROOT "/sanity")) + return FALSE; + gconf_client_add_dir(gconf_client, GCONF2_ROOT, GCONF_CLIENT_PRELOAD_RECURSIVE, &error); + + return TRUE; +} +/* }}} */ + +/* {{{ get_boolean_conf_value() */ +gboolean +get_boolean_conf_value(gchar *key, gboolean *retval) +{ + GError *error = NULL;; + GConfValue *value = NULL; + gchar *full_key; + + if ((full_key = g_malloc(strlen(GCONF2_ROOT) + strlen(key) + 2)) == NULL) + return FALSE; + + memset(full_key, 0, strlen(GCONF2_ROOT) + strlen(key) + 2); + + strcpy(full_key, GCONF2_ROOT); + strcat(full_key, "/"); + strcat(full_key, key); + + value = gconf_client_get(gconf_client, full_key, &error); + if (error && !value) + { + g_free(full_key); + return FALSE; + } + if (value) + { + if (value->type == GCONF_VALUE_BOOL) + { + if (retval) + *retval = gconf_client_get_bool(gconf_client, full_key, &error); + g_free(full_key); + return TRUE; + } + } + return FALSE; +} +/* }}} */ + +/* {{{ get_float_conf_value() */ +gboolean +get_float_conf_value(gchar *key, gfloat *retval) +{ + GError *error = NULL; + GConfValue *value = NULL; + gchar *full_key; + + if ((full_key = g_malloc(strlen(GCONF2_ROOT) + strlen(key) + 2)) == NULL) + return FALSE; + + memset(full_key, 0, strlen(GCONF2_ROOT) + strlen(key) + 2); + + strcpy(full_key, GCONF2_ROOT); + strcat(full_key, "/"); + strcat(full_key, key); + + value = gconf_client_get(gconf_client, full_key, &error); + + if ((error != NULL) || (value == NULL)) { + g_free(full_key); + return FALSE; + } + + if (value) { + if (value->type == GCONF_VALUE_FLOAT) { + if (retval) + *retval = gconf_client_get_float(gconf_client, full_key, &error); + g_free(full_key); + return TRUE; + } + } + g_free(full_key); + return FALSE; +} +/* }}} */ + +/* {{{ get_int_conf_value() */ +gboolean +get_int_conf_value(gchar *key, gint *retval) +{ + GError *error = NULL; + GConfValue *value = NULL; + gchar *full_key; + + if ((full_key = g_malloc(strlen(GCONF2_ROOT) + strlen(key) + 2)) == NULL) + return FALSE; + + memset(full_key, 0, strlen(GCONF2_ROOT) + strlen(key) + 2); + + strcpy(full_key, GCONF2_ROOT); + strcat(full_key, "/"); + strcat(full_key, key); + + value = gconf_client_get(gconf_client, full_key, &error); + + if ((error != NULL) || (value == NULL)) { + g_free(full_key); + return FALSE; + } + + if (value) { + if (value->type == GCONF_VALUE_INT) { + if (retval) + *retval = gconf_client_get_int(gconf_client, full_key, &error); + g_free(full_key); + return TRUE; + } + } + g_free(full_key); + return FALSE; +} +/* }}} */ + +/* {{{ get_string_conf_value() */ +gboolean +get_string_conf_value(gchar *key, gchar **retval) +{ + GError *error = NULL; + GConfValue *value = NULL; + gchar *full_key; + + if ((full_key = g_malloc(strlen(GCONF2_ROOT) + strlen(key) + 2)) == NULL) + return FALSE; + + memset(full_key, 0, strlen(GCONF2_ROOT) + strlen(key) + 2); + + strcpy(full_key, GCONF2_ROOT); + strcat(full_key, "/"); + strcat(full_key, key); + + value = gconf_client_get(gconf_client, full_key, &error); + + if (error || !value) { + g_free(full_key); + return FALSE; + } + + if (value) { + if (value->type == GCONF_VALUE_STRING) { + if (retval) + *retval = g_strdup(gconf_client_get_string(gconf_client, full_key, &error)); + g_free(full_key); + return TRUE; + } + } + g_free(full_key); + return FALSE; +} +/* }}} */ + +/* {{{ set_boolean_conf_value() */ +gboolean +set_boolean_conf_value(gchar *key, gboolean value) +{ + GError *error = NULL; + gchar *full_key; + + if ((full_key = g_malloc(strlen(GCONF2_ROOT) + strlen(key) + 2)) == NULL) + return FALSE; + + memset(full_key, 0, strlen(GCONF2_ROOT) + strlen(key) + 2); + + strcpy(full_key, GCONF2_ROOT); + strcat(full_key, "/"); + strcat(full_key, key); + + gconf_client_set_bool(gconf_client, full_key, value, &error); + if (error) + { + g_free(full_key); + return FALSE; + } + + return TRUE; +} +/* }}} */ + +/* {{{ set_float_conf_value() */ +gboolean +set_float_conf_value(gchar *key, gdouble value) +{ + GError *error = NULL; + gchar *full_key; + + if ((full_key = g_malloc(strlen(GCONF2_ROOT) + strlen(key) + 2)) == NULL) + return FALSE; + + memset(full_key, 0, strlen(GCONF2_ROOT) + strlen(key) + 2); + + strcpy(full_key, GCONF2_ROOT); + strcat(full_key, "/"); + strcat(full_key, key); + + gconf_client_set_float(gconf_client, full_key, value, &error); + if (error) + { + g_free(full_key); + return FALSE; + } + + return TRUE; +} +/* }}} */ + +/* {{{ set_int_conf_value() */ +gboolean +set_int_conf_value(gchar *key, gint value) +{ + GError *error = NULL; + gchar *full_key; + + if ((full_key = g_malloc(strlen(GCONF2_ROOT) + strlen(key) + 2)) == NULL) + return FALSE; + + memset(full_key, 0, strlen(GCONF2_ROOT) + strlen(key) + 2); + + strcpy(full_key, GCONF2_ROOT); + strcat(full_key, "/"); + strcat(full_key, key); + + gconf_client_set_int(gconf_client, full_key, value, &error); + if (error) + { + g_free(full_key); + return FALSE; + } + + return TRUE; +} +/* }}} */ + +/* {{{ set_string_conf_value() */ +gboolean +set_string_conf_value(gchar *key, gchar *value) +{ + GError *error = NULL; + gchar *full_key; + + if ((full_key = g_malloc(strlen(GCONF2_ROOT) + strlen(key) + 2)) == NULL) + return FALSE; + + memset(full_key, 0, strlen(GCONF2_ROOT) + strlen(key) + 2); + + strcpy(full_key, GCONF2_ROOT); + strcat(full_key, "/"); + strcat(full_key, key); + + gconf_client_set_string(gconf_client, full_key, value, &error); + if (error) + { + printf("%s\n", error->message); + g_free(full_key); + return FALSE; + } + + return TRUE; +} +/* }}} */ + +/* {{{ read_config_data() */ +void +read_config_data(void) +{ + gboolean setting_b; + gfloat setting_f; + gchar *setting_s; + gint setting_i; + + if (get_boolean_conf_value("scroll_on_output", &setting_b)) + config_data.scroll_on_output = setting_b; + else + config_data.scroll_on_output = DEFAULT_SCROLL_ON_OUTPUT; + + if (get_boolean_conf_value("change_to_message", &setting_b)) + config_data.change_to_message = setting_b; + else + config_data.change_to_message = DEFAULT_CHANGE_TO_MESSAGE; + +#ifdef DEBUG + if (get_boolean_conf_value("debug", &setting_b)) + config_data.debug = setting_b; + else + config_data.debug = DEFAULT_DEBUG; +#endif /* DEBUG */ + + if (get_boolean_conf_value("transparent_background", &setting_b)) + config_data.transparent_background = setting_b; + else + config_data.transparent_background = DEFAULT_TRANSPARENT_BACKGROUND; + + if (get_float_conf_value("background_saturation", &setting_f)) + config_data.background_saturation = setting_f; + else + config_data.background_saturation = DEFAULT_BACKGROUND_SATURATION; + + if (get_string_conf_value("default_mode", &setting_s)) + config_data.default_mode = *setting_s; + else + config_data.default_mode = *DEFAULT_DEFAULT_MODE; + + if (get_string_conf_value("vte_font", &setting_s)) + config_data.vte_font = setting_s; + else + config_data.vte_font = DEFAULT_VTE_FONT; + + if (get_boolean_conf_value("change_to_new_tab", &setting_b)) + config_data.change_to_new_tab = setting_b; + else + config_data.change_to_new_tab = DEFAULT_CHANGE_TO_NEW_TAB; + + if (get_int_conf_value("history_length", &setting_i)) + config_data.history_len = setting_i; + else + config_data.history_len = DEFAULT_HISTORY_LENGTH; +} +/* }}} */ + +/* {{{ set_bot_data_from_conf() */ +void +set_bot_data_from_conf(gpointer data, gpointer discard) +{ + GConfEntry *entry = (GConfEntry *)data; + gint len = strlen(GCONF2_ROOT "/bots/"); + gchar *key = (char *)gconf_entry_get_key(entry); + gchar *num = NULL; + gchar *i; + gint bot_id; + t_bot_data *bot; + int to_add = 0; + GConfValue *value; + gchar *string_value = NULL; + gint int_value = 0; + + if (strncmp(key + len, "bot", 3)) + return; + num = key + len + 3; + for (i = num; *i && isdigit(*i); i++); + if (*i != '_') + return; + *i = 0; + i++; + bot_id = atoi((const char *)num); + if (bot_id == 0) + return; + if (strcmp(i, "name") == 0) + to_add = TA_NAME; + else if (strcmp(i, "host") == 0) + to_add = TA_HOST; + else if (strcmp(i, "port") == 0) + to_add = TA_PORT; + else if (strcmp(i, "handle") == 0) + to_add = TA_HANDLE; + + if (to_add == 0) + return; + + value = gconf_entry_get_value(entry); + if (to_add == TA_PORT) + int_value = gconf_value_get_int((const GConfValue *)value); + else + string_value = (gchar *)gconf_value_get_string((const GConfValue *)value); + + if ((bot = get_bot_by_conf_num(bot_id)) == NULL) + { + create_bot_record(NULL, 0, &bot); + bot->id = bot_id; + internal_bot_list = g_list_append(internal_bot_list, bot); + } + + switch (to_add) + { + case TA_NAME: + bot->botname = g_strdup(string_value); + break; + case TA_HOST: + bot->host = g_strdup(string_value); + break; + case TA_PORT: + bot->port = int_value; + break; + case TA_HANDLE: + bot->handle = g_strdup(string_value); + break; + } +} +/* }}} */ + +/* {{{ read_bot_list_from_config() */ +void +read_bot_list_from_config(void) +{ + GSList *entries; + + if (internal_bot_list) + { + g_list_foreach(internal_bot_list, free_bot_data, NULL); + g_list_free(internal_bot_list); + internal_bot_list = NULL; + } + entries = gconf_client_all_entries(gconf_client, GCONF2_ROOT "/bots", NULL); + if (entries) + { + g_slist_foreach(entries, set_bot_data_from_conf, NULL); + } +} +/* }}} */ + +/* {{{ save_this_bot() */ +void +save_this_bot(gpointer data, gpointer user_data) +{ + /* NEVER CHANGE THIS, or change the code below, either! */ + static char *config_keynames[] = { "name", "host", "port", "handle", NULL }; + gchar *key; + gint len; + char **a; + + internal_value++; + + for (a = config_keynames; *a; a++) + { + len = (int)log10((double)internal_value) + 11 + strlen(*a); + key = g_malloc(len); + + sprintf(key, "bots/bot%d_%s", internal_value, *a); + + if (strcmp(*a, "name") == 0) + set_string_conf_value(key, ((t_bot_data *)data)->botname); + else if (strcmp(*a, "host") == 0) + set_string_conf_value(key, ((t_bot_data *)data)->host); + else if (strcmp(*a, "port") == 0) + set_int_conf_value(key, ((t_bot_data *)data)->port); + else if (strcmp(*a, "handle") == 0) + set_string_conf_value(key, ((t_bot_data *)data)->handle); + g_free(key); + } +} +/* }}} */ + +/* {{{ save_bot_list_to_config() */ +void +save_bot_list_to_config(void) +{ + gconf_client_recursive_unset(gconf_client, GCONF2_ROOT "/bots", GCONF_UNSET_INCLUDING_SCHEMA_NAMES, NULL); + + internal_value = 0; + g_list_foreach(internal_bot_list, save_this_bot, NULL); +} +/* }}} */ + diff --git a/src/debug.c b/src/debug.c new file mode 100644 index 0000000..5132f4b --- /dev/null +++ b/src/debug.c @@ -0,0 +1,69 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * debug.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Debugging functions + }}} */ + +#ifdef DEBUG + +/* {{{ Includes */ +# include +# include +# include +/* }}} */ + +/* {{{ Variables */ +char *last_file = NULL; +int last_line = 0; +/* }}} */ + +/* {{{ fatal_signal() */ +void fatal_signal_handler(int sig) +{ + if (last_file) + fprintf(stderr, "Fatal signal cought (%d). Last context was at %s:%d\n", sig, last_file, last_line); + exit(1); +} +/* }}} */ + +/* {{{ debug_init() */ +void +debug_init() +{ + signal(SIGSEGV, fatal_signal_handler); +} +/* }}} */ + +/* {{{ set_context() */ +void +set_context(char *file, int line) +{ + if (last_file) + g_free(last_file); + last_file = g_strdup(file); + last_line = line; +} +/* }}} */ + +#endif + diff --git a/src/history.c b/src/history.c new file mode 100644 index 0000000..a8fb366 --- /dev/null +++ b/src/history.c @@ -0,0 +1,123 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * history.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Handles tabs' command line history + }}} */ + +/* {{{ Includes */ +#include +#include +#include + +#include "typedefs.h" +#include "variables.h" +/* }}} */ + +/* {{{ history_add() */ +void +history_add(t_tab_data *tab, gchar mode, gchar *line) +{ + t_history_data *temp; + + if (config_data.history_len == 0) + return; + + if (tab) + { + gint count = 0; + char modechar = 0; + + switch (tolower(mode)) + { + case 'b': + modechar = '/'; + break; + case 'e': + modechar = '.'; + break; + case 'm': + modechar = '@'; + break; + } + + if (modechar == 0) + return; + + temp = tab->history; + while (temp) + { + count++; + temp = temp->next; + } + + if (count == config_data.history_len) + { + temp = tab->history; + tab->history = temp->next; + g_free(temp->line); + g_free(temp); + } + + temp = g_malloc(sizeof(t_history_data)); + temp->line = g_malloc(strlen(line) + 2); + sprintf(temp->line, "%c%s", modechar, line); + temp->next = NULL; + + if (tab->history == NULL) + tab->history = temp; + else + { + t_history_data *t = tab->history; + while (t->next) + t = t->next; + t->next = temp; + } + } +} +/* }}} */ + +/* {{{ get_history_len() */ +gint +get_history_len(t_tab_data *tab) +{ + + if (tab) + { + t_history_data *temp = tab->history; + gint count = 0; + + if (tab->history == NULL) + return 0; + while (temp) + { + count++; + temp = temp->next; + } + + return count; + } + + return 0; +} +/* }}} */ + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..424cd1d --- /dev/null +++ b/src/main.c @@ -0,0 +1,143 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * main.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Very common functions + }}} */ + +/* {{{ Includes */ +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#include "functions.h" +#include "variables.h" +#include "defines.h" +/* }}} */ + +/* {{{ change_mode() */ +void +change_mode(char newmode, gboolean from_menu) +{ + char *buf; + + t_tab_data *active_tab = get_active_tab(); + + buf = g_malloc(strlen(_("Mode: %c")) + 1); + sprintf(buf, _("Mode: %c"), toupper(newmode)); + + active_tab->mode = toupper(newmode); + gtk_label_set_text(GTK_LABEL(main_statuslabel_mode), buf); + g_free(buf); + + if (!from_menu) + { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(main_menu_mode_b), (toupper(newmode) == 'B') ? TRUE : FALSE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(main_menu_mode_e), (toupper(newmode) == 'E') ? TRUE : FALSE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(main_menu_mode_m), (toupper(newmode) == 'M') ? TRUE : FALSE); + } +} +/* }}} */ + +/* {{{ find_connected_tab() */ +gint +find_connected_tab(gconstpointer a, gconstpointer b) +{ + if (((t_tab_data *)a)->connected) + return 0; + + return 1; +} +/* }}} */ + +/* {{{ exit_cleanly() */ +void +exit_cleanly(gboolean force) +{ + gboolean ask = FALSE; + + save_bot_list_to_config(); + + if (g_list_find_custom(tab_list, NULL, find_connected_tab)) + ask = TRUE; + + if (ask) + { + GtkWidget *dialog; + gint result; + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("There are connected tabs. Are you sure, you want to exit?")); + result = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + if (result == GTK_RESPONSE_NO) + return; + } + +#ifdef DEBUG + printf("exit_cleanly(%d)\n", force); +#endif /* DEBUG */ + gtk_main_quit(); +} +/* }}} */ + +/* {{{ main() */ +int +main(int argc, char **argv) +{ +#ifdef DEBUG + debug_init(); +#endif /* DEBUG */ + + Context; + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + textdomain(GETTEXT_PACKAGE); + + Context; + + gtk_init(&argc, &argv); + + if (!init_config()) + return 1; + + read_config_data(); + read_bot_list_from_config(); + + tab_list = NULL; + + g_set_prgname("BotCommander"); + g_set_application_name("BotCommander"); + + create_main_window(); + + add_tab(NULL); + + gtk_main(); + return 0; +} +/* }}} */ + diff --git a/src/networking.c b/src/networking.c new file mode 100644 index 0000000..4acb31b --- /dev/null +++ b/src/networking.c @@ -0,0 +1,116 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * networking.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Network-handling functions + }}} */ + +/* {{{ Includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#include "defines.h" +#include "typedefs.h" +#include "functions.h" +#include "variables.h" +/* }}} */ + +/* {{{ connect_to_host() */ +gint +connect_to_host(gchar *host, guint port, int *fd, gint *tag, t_tab_data *tab) +{ + int desc; + static struct protoent *p = NULL; + struct hostent *h = NULL; + struct sockaddr_in dest; + + if (tab) + feed_info_to_terminal(tab, TRUE, _("Connecting to %s:%d"), host, port); + + if (!p) + { + if ((p = getprotobyname("IP")) == NULL) + return BCE_NOPROTO; + } + desc = socket(PF_INET, SOCK_STREAM, p->p_proto); + fcntl(desc, F_SETFL, O_NONBLOCK); + + if ((h = gethostbyname(host)) == NULL) + return BCE_CANTRESOLV; + + memset(&dest, 0, sizeof(struct sockaddr_in)); + dest.sin_family = AF_INET; + dest.sin_addr = *((struct in_addr *)h->h_addr); + dest.sin_port = htons(port); + + if (connect(desc, (struct sockaddr *)&dest, sizeof(struct sockaddr)) < 0) + { + if (errno != EINPROGRESS) + { + if (tab) + { + char *buf = NULL; + char *orig = strerror(errno); + + buf = g_locale_to_utf8(orig, -1, NULL, NULL, NULL); + feed_error_to_terminal(tab, TRUE, "%s", buf); + g_free(buf); + } +#ifdef DEBUG + perror("BotCommander: connect"); +#endif /* DEBUG */ + return BCE_CANTCONNECT; + } + } + + if (fd) + *fd = desc; + if (tag) + *tag = gdk_input_add(desc, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, socket_event, tab); + + return BCE_SUCCESS; +} +/* }}} */ + +/* {{{ process_incoming_data() */ +void +process_incoming_data(t_tab_data *tab, char *string) +{ + char *obuf; + + obuf = g_convert(string, -1, "UTF-8", BOT_CHARSET, NULL, NULL, NULL); + if (strncmp(obuf, "BC", 2) == 0) + process_botcommander_script_commands(tab, obuf); + else + feed_message_to_terminal(tab, TRUE, obuf); +} +/* }}} */ + diff --git a/src/setup.c b/src/setup.c new file mode 100644 index 0000000..bda28d8 --- /dev/null +++ b/src/setup.c @@ -0,0 +1,366 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * setup.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Preferences dialog + }}} */ + +/* {{{ Defines */ +#define CB_ALL 0 +#define CB_SCROLL 1 +#define CB_TRANSBG 2 +#define CB_BGSAT 3 +#define CB_FONT 4 +#define CB_RESET 5 +/* }}} */ + +/* {{{ Includes */ +#include +#include +#include +#include + +#include "variables.h" +#include "functions.h" +/* }}} */ + +/* {{{ Typedefs */ +typedef struct _t_which { + gint which; + gboolean bool_value; + gfloat float_value; + gchar *string_value; +} t_which; +/* }}} */ + +/* {{{ Variables */ +#ifdef DEBUG +GtkWidget *debug_cb; +#endif /* DEBUG */ +GtkWidget *cmode_cb; +GtkWidget *prefsave_cb; +GtkWidget *scroll_cb; +GtkWidget *transbg_cb; +GtkWidget *font_button; +GtkWidget *historylen_spin; +GtkWidget *satur_scale; +GtkWidget *changetab_cb; +t_config_data backup_data; +/* }}} */ + +/* {{{ debug_cb_toggled() */ +#ifdef DEBUG +static void +debug_cb_toggled(GtkWidget *widget, gpointer data) +{ + backup_data.debug = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); +} +#endif /* DEBUG */ +/* }}} */ + +/* {{{ cmode_cb_toggled() */ +static void +cmode_cb_toggled(GtkWidget *widget, gpointer data) +{ + backup_data.change_to_message = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); +} +/* }}} */ + +/* {{{ prefsave_cb_toggled() */ +static void +prefsave_cb_toggled(GtkWidget *widget, gpointer data) +{ + backup_data.save_prefs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); +} +/* }}} */ + +/* {{{ changetab_cb_toggled() */ +static void +changetab_cb_toggled(GtkWidget *widget, gpointer data) +{ + backup_data.change_to_new_tab = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); +} +/* }}} */ + +/* {{{ set_tab_vt_prefs() */ +static void +set_tab_vt_prefs(gpointer data, gpointer user_data) +{ + t_tab_data *tab = (t_tab_data *)data; + t_which *which = (t_which *)user_data; + + if ((which->which == CB_SCROLL) || (which->which == CB_ALL)) + vte_terminal_set_scroll_on_output(VTE_TERMINAL(tab->vt), which->bool_value); + if ((which->which == CB_TRANSBG) || (which->which == CB_ALL)) + vte_terminal_set_background_transparent(VTE_TERMINAL(tab->vt), which->bool_value); + if ((which->which == CB_BGSAT) || (which->which == CB_ALL)) + vte_terminal_set_background_saturation(VTE_TERMINAL(tab->vt), which->float_value / 100.0); + if ((which->which == CB_FONT) || (which->which == CB_ALL)) + vte_terminal_set_font_from_string(VTE_TERMINAL(tab->vt), which->string_value); + if (which->which == CB_RESET) + { + vte_terminal_set_scroll_on_output(VTE_TERMINAL(tab->vt), config_data.scroll_on_output); + vte_terminal_set_background_transparent(VTE_TERMINAL(tab->vt), config_data.transparent_background); + vte_terminal_set_background_saturation(VTE_TERMINAL(tab->vt), config_data.background_saturation); + vte_terminal_set_font_from_string(VTE_TERMINAL(tab->vt), config_data.vte_font); + } +} +/* }}} */ + +/* {{{ scroll_cb_toggled() */ +static void +scroll_cb_toggled(GtkWidget *widget, gpointer data) +{ + t_which which; + + backup_data.scroll_on_output = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + + which.which = CB_SCROLL; + which.bool_value = backup_data.scroll_on_output; + + g_list_foreach(tab_list, set_tab_vt_prefs, &which); +} +/* }}} */ + +/* {{{ transbg_cb_toggled() */ +static void +transbg_cb_toggled(GtkWidget *widget, gpointer data) +{ + t_which which; + + backup_data.transparent_background = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + + which.which = CB_TRANSBG; + which.bool_value = backup_data.transparent_background; + + g_list_foreach(tab_list, set_tab_vt_prefs, &which); +} +/* }}} */ + +/* {{{ satur_bar_changed() */ +static void +satur_bar_changed(GtkWidget *widget, gpointer data) +{ + t_which which; + + backup_data.background_saturation = gtk_range_get_value(GTK_RANGE(widget)); + + which.which = CB_BGSAT; + which.float_value = backup_data.background_saturation; + + g_list_foreach(tab_list, set_tab_vt_prefs, &which); +} +/* }}} */ + +/* {{{ historylen_spin_changed() */ +static void +historylen_spin_changed(GtkWidget *widget, gpointer data) +{ + backup_data.history_len = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); +} +/* }}} */ + +/* {{{ font_changed() */ +static void +font_changed(GtkWidget *widget, gpointer data) +{ + t_which which; + + if (backup_data.vte_font) + g_free(backup_data.vte_font); + backup_data.vte_font = g_strdup(gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget))); + + which.which = CB_FONT; + which.string_value = backup_data.vte_font; + + g_list_foreach(tab_list, set_tab_vt_prefs, &which); +} +/* }}} */ + +/* {{{ setup_response() */ +static void +setup_response(GtkDialog *dialog, int id, gpointer data) +{ + switch (id) + { + case GTK_RESPONSE_OK: + g_free(config_data.vte_font); + memcpy(&config_data, &backup_data, sizeof(t_config_data)); + config_data.vte_font = g_strdup(backup_data.vte_font); + /* TODO: Change the command line history buffer's size!! */ + gtk_widget_hide(GTK_WIDGET(dialog)); + break; + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_DELETE_EVENT: + { + t_which which; + + which.which = CB_RESET; + g_list_foreach(tab_list, set_tab_vt_prefs, &which); + gtk_widget_hide(GTK_WIDGET(dialog)); + } + break; + case GTK_RESPONSE_YES: + /* Itt minden pref beallitast el kell menteni az aktualis backendbe */ + break; + default: +#ifdef DEBUG + if (config_data.debug) + fprintf(stderr, "Unknown response!\n"); +#endif /* DEBUG */ + break; + } +} +/* }}} */ + +/* {{{ display_setup_window() */ +void +display_setup_window(void) +{ + static GtkWidget *setup_window = NULL; + + memcpy(&backup_data, &config_data, sizeof(t_config_data)); + backup_data.vte_font = g_strdup(config_data.vte_font); + + if (!GTK_IS_WINDOW(setup_window)) + { + GtkWidget *frame; + GtkWidget *content; + GtkWidget *satur_label; + GtkWidget *font_label; + GtkWidget *historylen_label; + gint row; +#ifdef DEBUG +# define CONTENT_ROW_NUMBER 5 +#else +# define CONTENT_ROW_NUMBER 4 +#endif + + setup_window = gtk_dialog_new_with_buttons((const gchar *)_("Setup"), GTK_WINDOW(main_window), GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_SAVE, GTK_RESPONSE_YES, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); + gtk_dialog_set_response_sensitive(GTK_DIALOG(setup_window), GTK_RESPONSE_OK, TRUE); + + gtk_signal_connect(GTK_OBJECT(setup_window), "response", GTK_SIGNAL_FUNC(setup_response), NULL); + + frame = gtk_frame_new("BotCommander"); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); + + content = gtk_table_new(CONTENT_ROW_NUMBER, 2, TRUE); + + row = 0; +#ifdef DEBUG + debug_cb = gtk_check_button_new_with_label(_("Debug mode")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(debug_cb), config_data.debug); + gtk_table_attach_defaults(GTK_TABLE(content), debug_cb, 0, 2, row, row + 1); + gtk_signal_connect(GTK_OBJECT(debug_cb), "toggled", GTK_SIGNAL_FUNC(debug_cb_toggled), NULL); + row++; +#endif + + cmode_cb = gtk_check_button_new_with_label(_("Change to message mode after connect")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cmode_cb), config_data.change_to_message); + gtk_table_attach_defaults(GTK_TABLE(content), cmode_cb, 0, 2, row, row + 1); + gtk_signal_connect(GTK_OBJECT(cmode_cb), "toggled", GTK_SIGNAL_FUNC(cmode_cb_toggled), NULL); + row++; + + changetab_cb = gtk_check_button_new_with_label(_("Change to newly created tab")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(changetab_cb), config_data.change_to_new_tab); + gtk_table_attach_defaults(GTK_TABLE(content), changetab_cb, 0, 2, row, row + 1); + gtk_signal_connect(GTK_OBJECT(changetab_cb), "toggled", GTK_SIGNAL_FUNC(changetab_cb_toggled), NULL); + row++; + + prefsave_cb = gtk_check_button_new_with_label(_("Save preferences on exit")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefsave_cb), config_data.save_prefs); + gtk_table_attach_defaults(GTK_TABLE(content), prefsave_cb, 0, 2, row, row + 1); + gtk_signal_connect(GTK_OBJECT(prefsave_cb), "toggled", GTK_SIGNAL_FUNC(prefsave_cb_toggled), NULL); + row++; + + historylen_label = gtk_label_new(_("Command line history length")); + gtk_table_attach(GTK_TABLE(content), historylen_label, 0, 1, row, row + 1, GTK_FILL, 0, 4, 0); + + historylen_spin = gtk_spin_button_new_with_range(0, 5000, 1); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(historylen_spin), config_data.history_len); + gtk_table_attach_defaults(GTK_TABLE(content), historylen_spin, 1, 2, row, row + 1); + gtk_signal_connect(GTK_OBJECT(historylen_spin), "value-changed", GTK_SIGNAL_FUNC(historylen_spin_changed), NULL); + row++; + + gtk_container_add(GTK_CONTAINER(frame), content); + + gtk_widget_show_all(frame); + + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(setup_window)->vbox), frame, TRUE, TRUE, 0); + + frame = gtk_frame_new(_("Terminal")); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); + + content = gtk_table_new(5, 3, TRUE); + + scroll_cb = gtk_check_button_new_with_label(_("Scroll on output")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scroll_cb), config_data.scroll_on_output); + gtk_table_attach_defaults(GTK_TABLE(content), scroll_cb, 0, 3, 0, 1); + gtk_signal_connect(GTK_OBJECT(scroll_cb), "toggled", GTK_SIGNAL_FUNC(scroll_cb_toggled), NULL); + + transbg_cb = gtk_check_button_new_with_label(_("Transparent background")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(transbg_cb), config_data.transparent_background); + gtk_table_attach_defaults(GTK_TABLE(content), transbg_cb, 0, 3, 1, 2); + gtk_signal_connect(GTK_OBJECT(transbg_cb), "toggled", GTK_SIGNAL_FUNC(transbg_cb_toggled), NULL); + + satur_label = gtk_label_new(_("Saturation")); + gtk_table_attach(GTK_TABLE(content), satur_label, 0, 1, 2, 3, GTK_FILL, 0, 0, 0); + + satur_scale = gtk_hscale_new_with_range(0, 100, 1); + gtk_scale_set_digits(GTK_SCALE(satur_scale), 0); + gtk_scale_set_draw_value(GTK_SCALE(satur_scale), TRUE); + gtk_scale_set_value_pos(GTK_SCALE(satur_scale), GTK_POS_RIGHT); + gtk_range_set_value(GTK_RANGE(satur_scale), config_data.background_saturation * 100); + gtk_signal_connect(GTK_OBJECT(satur_scale), "value-changed", GTK_SIGNAL_FUNC(satur_bar_changed), NULL); + gtk_table_attach_defaults(GTK_TABLE(content), satur_scale, 0, 3, 3, 4); + + font_label = gtk_label_new(_("Font")); + gtk_table_attach(GTK_TABLE(content), font_label, 0, 1, 4, 5, GTK_FILL, 0, 0, 0); + + font_button = gtk_font_button_new_with_font(config_data.vte_font); + gtk_table_attach_defaults(GTK_TABLE(content), font_button, 1, 3, 4, 5); + gtk_signal_connect(GTK_OBJECT(font_button), "font-set", GTK_SIGNAL_FUNC(font_changed), NULL); + + gtk_container_add(GTK_CONTAINER(frame), content); + + gtk_widget_show_all(frame); + + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(setup_window)->vbox), frame, TRUE, TRUE, 0); + } + else + { +#ifdef DEBUG + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(debug_cb), config_data.debug); +#endif /* DEBUG */ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cmode_cb), config_data.change_to_message); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefsave_cb), config_data.save_prefs); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scroll_cb), config_data.scroll_on_output); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(transbg_cb), config_data.transparent_background); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(font_button), config_data.vte_font); + gtk_range_set_value(GTK_RANGE(satur_scale), config_data.background_saturation * 100); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(historylen_spin), config_data.history_len); + } + + gtk_dialog_run(GTK_DIALOG(setup_window)); +} +/* }}} */ + diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..b97aaad --- /dev/null +++ b/src/string.c @@ -0,0 +1,244 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ Author and file info + * string.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * String manipulation functions + }}} */ + +/* TODO: Insert this into one of the makefiles, perhaps in rules? */ +#define _GNU_SOURCE +/* {{{ Includes */ +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" +/* }}} */ + +/* {{{ streq() */ +gboolean +streq(gchar *s1, gchar *s2, gboolean cs) +{ + gchar *a; + + if (!s1 && !s2) + return TRUE; + if (!s1 || !s2) + return FALSE; + if (strlen(s1) != strlen(s2)) + return FALSE; + if (cs) + return strcmp(s1, s2) == 0 ? TRUE : FALSE; + for (a = s1; *a; a++) + if (tolower(*a) != tolower(*(s2 + (a - s1)))) + return FALSE; + + return TRUE; +} +/* }}} */ + +/* {{{ wordwrap() */ +int +wordwrap(gchar *sentence, gchar *delim, gchar ***retval, gint *wnum) +{ + gboolean prev_delim = TRUE; + gchar *a; + gint words = 0; + gchar **starts; + gchar **newstarts; + gint *lens; + signed int cword = -1; + int i; + + for (a = sentence; *a; a++) + { + gboolean is_delim = (strchr(delim, *a)) ? TRUE : FALSE; + + if (!is_delim && prev_delim) + words++; + prev_delim = is_delim; + } + + if (wnum) + *wnum = words; + + if (words == 0) + { + if (retval) + *retval = NULL; + return BCE_SUCCESS; + } + + if (!retval) + return BCE_SUCCESS; + + if ((starts = (gchar **)g_malloc(sizeof(gchar *))) == NULL) + return BCE_NOMEM; + if ((lens = (gint *)g_malloc(sizeof(gint))) == NULL) + { + g_free(starts); + return BCE_NOMEM; + } + if ((newstarts = (gchar **)g_malloc(sizeof(gchar *))) == NULL) + { + g_free(starts); + g_free(lens); + return BCE_NOMEM; + } + + prev_delim = TRUE; + + for (a = sentence; *a; a++) + { + gboolean is_delim = (strchr(delim, *a)) ? TRUE : FALSE; + + if (!is_delim) + { + if (prev_delim) + { + cword++; + starts[cword] = a; + lens[cword] = 0; + } + else + lens[cword]++; + } + prev_delim = is_delim; + } + + for (i = 0; i < words; i++) + { + if ((newstarts[i] = g_malloc((sizeof(gchar) * (lens[i] + 2)))) == NULL) + { + int j; + + for (j = 0; j < i; j++) + g_free(newstarts[i]); + g_free(starts); + g_free(lens); + g_free(newstarts); + return BCE_NOMEM; + } + memset(newstarts[i], 0, (sizeof(gchar) * (lens[i] + 2))); + strncpy(newstarts[i], starts[i], lens[i] + 1); + } + g_free(lens); + g_free(starts); + + *retval = newstarts; + + return BCE_SUCCESS; +} +/* }}} */ + +/* {{{ wl_free() */ +void +wl_free(gchar ***owl, gint wnum) +{ + gint i; + + if (*owl) + { + for (i = 0; i < wnum; i++) + g_free((*owl)[i]); + g_free(*owl); + } +} +/* }}} */ + +/* {{{ is_numeric() */ +gboolean +is_numeric(gchar *s, gint *retval) +{ + gchar *a; + + if (!s) + return FALSE; + for (a = s; *a; a++) + if (!isdigit(*a)) + return FALSE; + + if (retval) + *retval = atoi(s); + + return TRUE; +} +/* }}} */ + +/* {{{ trim() */ +gchar * +trim(gchar *s) +{ + gchar *start; + gchar *end; + gchar *ret; + + if (s == NULL) + return NULL; + if (*s == 0) + return ""; + + for (start = s; *start; start++) + if (!isspace(*start)) + break; + + if (!*start) + return ""; + + for (end = s + strlen(s) - 1; end >= s; end--) + if (!isspace(*end)) + break; + + ret = g_malloc((end - start) + 2); + memset(ret, 0, (end - start) + 2); + strncpy(ret, start, (end - start) + 1); + + return ret; +} +/* }}} */ + +// Under FreeBSD, dprintf doesn't exist :( +#ifndef dprintf +/* {{{ dprintf() */ +int +dprintf(int fd, const char *format, ...) +{ + va_list ap; + char *buf; + int len; + + va_start(ap, format); + vasprintf(&buf, format, ap); + len = strlen(buf); + write(fd, buf, len); + g_free(buf); + va_end(ap); + + return len; +} +/* }}} */ +#endif + diff --git a/src/tabs.c b/src/tabs.c new file mode 100644 index 0000000..c0a8b95 --- /dev/null +++ b/src/tabs.c @@ -0,0 +1,677 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ + * tabs.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Tab handling functions + }}} */ + +/* TODO: Put this into a Makefile */ +#define _GNU_SOURCE + +/* {{{ Includes */ +#include +#include +#include +#include +#include +#include +#include + +#include "typedefs.h" +#include "variables.h" +#include "functions.h" +#include "defines.h" +/* }}} */ + +/* {{{ Variables */ +GList *tab_list; +/* }}} */ + +/* {{{ find_tab_by_pagenum() */ +gint +find_tab_by_pagenum(gconstpointer a, gconstpointer b) +{ + if (((t_tab_data *)a)->num == (gint)*((gint *)b)) + return 0; + + return 1; +} +/* }}} */ + +/* {{{ open_channel_properties() */ +void +open_channel_properties(GtkWidget *menuitem, gpointer data) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + t_tab_data *tab = (t_tab_data *)data; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tab->channel_list)); + model = gtk_tree_view_get_model(GTK_TREE_VIEW(tab->channel_list)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + { + char *name; + + gtk_tree_model_get(model, &iter, 0, &name, -1); + dprintf(tab->sock, ".botcomm_chanprop %s\r\n", name); + } +} +/* }}} */ + +/* {{{ open_user_properties() */ +void +open_user_properties(GtkWidget *menuitem, gpointer data) +{ +} +/* }}} */ + +/* {{{ change_channel_status() */ +void +change_channel_status(GtkWidget *menuitem, gpointer data) +{ +} +/* }}} */ + +/* {{{ view_channel_popup() */ +void +view_channel_popup(GtkWidget *treeview, GdkEventButton *event, gpointer tab) +{ + GtkWidget *menu = NULL; + GtkWidget *menuitem; + + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(((t_tab_data *)tab)->channel_list)); + model = gtk_tree_view_get_model(GTK_TREE_VIEW(((t_tab_data *)tab)->channel_list)); + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + { + menu = gtk_menu_new(); + + // TODO: If the channel is active, the label should say Deactivate + menuitem = gtk_menu_item_new_with_label(_("Activate")); + g_signal_connect(menuitem, "activate", G_CALLBACK(change_channel_status), tab); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + menuitem = gtk_menu_item_new_with_label(_("Properties")); + g_signal_connect(menuitem, "activate", G_CALLBACK(open_channel_properties), tab); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + gtk_widget_show_all(menu); + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, (event != NULL) ? event->button : 0, gdk_event_get_time((GdkEvent *)event)); + } +} +/* }}} */ + +/* {{{ view_user_popup() */ +void +view_user_popup(GtkWidget *treeview, GdkEventButton *event, gpointer tab) +{ + GtkWidget *menu; + GtkWidget *menuitem; + + menu = gtk_menu_new(); + + menuitem = gtk_menu_item_new_with_label(_("Properties")); + g_signal_connect(menuitem, "activate", G_CALLBACK(open_user_properties), tab); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + gtk_widget_show_all(menu); + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, (event != NULL) ? event->button : 0, gdk_event_get_time((GdkEvent *)event)); +} +/* }}} */ + +/* {{{ view_terminal_popup() */ +void +view_terminal_popup(GtkWidget *terminal, GdkEventButton *event, gpointer tab) +{ + GtkWidget *menu; + GtkWidget *menuitem; + + menu = gtk_menu_new(); + + menuitem = gtk_menu_item_new_with_label(_("Properties")); + g_signal_connect(menuitem, "activate", G_CALLBACK(open_user_properties), tab); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + gtk_widget_show_all(menu); + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, (event != NULL) ? event->button : 0, gdk_event_get_time((GdkEvent *)event)); +} +/* }}} */ + +/* {{{ channel_popupmenu_button() */ +gboolean +channel_popupmenu_button(GtkWidget *treeview, GdkEventButton *event, gpointer userdata) +{ + if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) + { + GtkTreeSelection *selection; + GtkTreePath *path; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL)) + { + gtk_tree_selection_unselect_all(selection); + gtk_tree_selection_select_path(selection, path); + gtk_tree_path_free(path); + } + else + return FALSE; + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + if (gtk_tree_selection_count_selected_rows(selection) > 0) + view_channel_popup(treeview, event, userdata); + + return TRUE; + } + + return FALSE; +} +/* }}} */ + +/* {{{ user_popupmenu_button() */ +gboolean +user_popupmenu_button(GtkWidget *treeview, GdkEventButton *event, gpointer userdata) +{ + if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) + { + GtkTreeSelection *selection; + GtkTreePath *path; + + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL)) + { + gtk_tree_selection_unselect_all(selection); + gtk_tree_selection_select_path(selection, path); + gtk_tree_path_free(path); + } + else + return FALSE; + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + if (gtk_tree_selection_count_selected_rows(selection) > 0) + view_user_popup(treeview, event, userdata); + + return TRUE; + } + + return FALSE; +} +/* }}} */ + +/* {{{ terminal_popupmenu_button() */ +gboolean +terminal_popupmenu_button(GtkWidget *terminal, GdkEventButton *event, gpointer userdata) +{ + if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) + { + view_terminal_popup(terminal, event, userdata); + + return TRUE; + } + + return FALSE; +} +/* }}} */ + +/* {{{ channel_popupmenu_popup() */ +gboolean +channel_popupmenu_popup(GtkWidget *treeview, gpointer userdata) +{ + view_channel_popup(treeview, NULL, userdata); + + return TRUE; +} +/* }}} */ + +/* {{{ user_popupmenu_popup() */ +gboolean +user_popupmenu_popup(GtkWidget *treeview, gpointer userdata) +{ + view_user_popup(treeview, NULL, userdata); + + return TRUE; +} +/* }}} */ + +/* {{{ terminal_popupmenu_popup() */ +gboolean +terminal_popupmenu_popup(GtkWidget *terminal, gpointer userdata) +{ + view_terminal_popup(terminal, NULL, userdata); + + return TRUE; +} +/* }}} */ + +/* {{{ add_tab() */ +int +add_tab(t_tab_data **newtab) +{ + t_tab_data *temp; + GtkWidget *img; + gint w, h; + gboolean change_title = config_data.change_to_new_tab, + first_tab = FALSE; + char *buf; + GtkWidget *paned; + GtkWidget *scroll; + GtkWidget *box; + t_tab_data *active; + GtkWidget *hbox; + + GtkCellRenderer *renderer; + + if (newtab) + *newtab = NULL; + + if (tab_list == NULL) + { + change_title = TRUE; + first_tab = TRUE; + } + + temp = (t_tab_data *)malloc(sizeof(t_tab_data)); + + temp->mode = config_data.default_mode; + temp->connected = FALSE; + temp->history = NULL; + temp->history_position = -1; + temp->chanlist_process = FALSE; + temp->userlist_process = FALSE; + temp->chanprops_process = NULL; + temp->actual_channel_list = NULL; + temp->actual_user_list = NULL; + temp->data_arrived = FALSE; + + paned = gtk_hpaned_new(); + + hbox = gtk_hbox_new(FALSE, 0); + temp->vt = vte_terminal_new(); + vte_terminal_set_encoding(VTE_TERMINAL(temp->vt), "UTF-8"); + vte_terminal_set_allow_bold(VTE_TERMINAL(temp->vt), TRUE); + vte_terminal_set_audible_bell(VTE_TERMINAL(temp->vt), TRUE); + vte_terminal_set_visible_bell(VTE_TERMINAL(temp->vt), FALSE); + vte_terminal_set_scroll_on_output(VTE_TERMINAL(temp->vt), config_data.scroll_on_output); + vte_terminal_set_background_transparent(VTE_TERMINAL(temp->vt), config_data.transparent_background); + vte_terminal_set_background_saturation(VTE_TERMINAL(temp->vt), (double)config_data.background_saturation); + vte_terminal_set_font_from_string(VTE_TERMINAL(temp->vt), (const char *)config_data.vte_font); + GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(temp->vt), GTK_CAN_FOCUS); + g_signal_connect(temp->vt, "button-press-event", G_CALLBACK(terminal_popupmenu_button), temp); + g_signal_connect(temp->vt, "popup-menu", G_CALLBACK(terminal_popupmenu_popup), temp); + gtk_box_pack_start(GTK_BOX(hbox), temp->vt, TRUE, TRUE, 0); + + scroll = gtk_vscrollbar_new(vte_terminal_get_adjustment(VTE_TERMINAL(temp->vt))); + gtk_box_pack_start(GTK_BOX(hbox), scroll, FALSE, TRUE, 0); + + box = gtk_vbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(box), hbox, TRUE, TRUE, 0); + + temp->editbox = gtk_entry_new(); + gtk_signal_connect(GTK_OBJECT(temp->editbox), "activate", GTK_SIGNAL_FUNC(entry_activate), temp); + gtk_signal_connect(GTK_OBJECT(temp->editbox), "key_press_event", GTK_SIGNAL_FUNC(entry_keypress), temp); + gtk_box_pack_start(GTK_BOX(box), temp->editbox, FALSE, TRUE, 0); + + gtk_paned_add1(GTK_PANED(paned), box); + + box = gtk_vbox_new(TRUE, 2); + + Context; + scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_set_size_request(scroll, 150, -1); + gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0); + + temp->channel_store = gtk_list_store_new(1, G_TYPE_STRING); + renderer = gtk_cell_renderer_text_new(); + temp->channel_list = gtk_tree_view_new(); + g_signal_connect(temp->channel_list, "button-press-event", G_CALLBACK(channel_popupmenu_button), temp); + g_signal_connect(temp->channel_list, "popup-menu", G_CALLBACK(channel_popupmenu_popup), temp); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(temp->channel_list), -1, _("Channels"), renderer, "text", 0, NULL); + gtk_tree_view_set_model(GTK_TREE_VIEW(temp->channel_list), GTK_TREE_MODEL(temp->channel_store)); + gtk_container_add(GTK_CONTAINER(scroll), temp->channel_list); + + Context; + scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_set_size_request(scroll, 150, -1); + gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0); + + renderer = gtk_cell_renderer_text_new(); + temp->user_store = gtk_list_store_new(1, G_TYPE_STRING); + temp->user_list = gtk_tree_view_new(); + g_signal_connect(temp->user_list, "button-press-event", G_CALLBACK(user_popupmenu_button), temp); + g_signal_connect(temp->user_list, "popup-menu", G_CALLBACK(user_popupmenu_popup), temp); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(temp->user_list), -1, _("Handles"), renderer, "text", 0, NULL); + gtk_tree_view_set_model(GTK_TREE_VIEW(temp->user_list), GTK_TREE_MODEL(temp->user_store)); + gtk_container_add(GTK_CONTAINER(scroll), temp->user_list); + Context; + + gtk_paned_add2(GTK_PANED(paned), box); + + img = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &w, &h); + + temp->labelbox = gtk_hbox_new(FALSE, 0); + + temp->label = gtk_label_new(_("Not connected")); + temp->closebutton = gtk_button_new(); + gtk_signal_connect(GTK_OBJECT(temp->closebutton), "clicked", GTK_SIGNAL_FUNC(close_tab_cb), temp); + gtk_container_add(GTK_CONTAINER(temp->closebutton), img); + gtk_button_set_relief(GTK_BUTTON(temp->closebutton), GTK_RELIEF_NONE); + gtk_widget_set_size_request(temp->closebutton, w, h); + Context; + + gtk_box_pack_start(GTK_BOX(temp->labelbox), temp->label, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(temp->labelbox), temp->closebutton, FALSE, TRUE, 0); + gtk_widget_show_all(temp->labelbox); + + Context; + + gtk_widget_show_all(paned); + Context; + + temp->num = gtk_notebook_append_page(GTK_NOTEBOOK(main_book), paned, temp->labelbox); + + gtk_widget_set_sensitive(main_menu_show_sidebar, TRUE); + +#ifdef DEBUG + feed_info_to_terminal(temp, TRUE, "Opened as %d\n", temp->num); +#endif + + if (change_title) + { + set_title(NULL, "BotCommander - %s", _("Not connected")); + gtk_notebook_set_current_page(GTK_NOTEBOOK(main_book), temp->num); + buf = g_malloc(strlen(_("Mode: %c")) + 1); + sprintf(buf, _("Mode: %c"), toupper(temp->mode)); + gtk_label_set_text(GTK_LABEL(main_statuslabel_mode), buf); + g_free(buf); + } + + tab_list = g_list_append(tab_list, temp); + + Context; + + active = get_active_tab(); + if (active) + gtk_widget_grab_focus((get_active_tab())->editbox); + + Context; + + temp->sock = 0; + temp->socktag = 0; + temp->bot = NULL; + + if (newtab) + *newtab = temp; + + Context; + + return temp->num; +} +/* }}} */ + +/* {{{ get_active_tab() */ +t_tab_data * +get_active_tab(void) +{ + GList *temp; + gint current = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_book)); + + Context; + + temp = g_list_find_custom(tab_list, ¤t, find_tab_by_pagenum); + + if (temp) + return (t_tab_data *)(temp->data); + + Context; + + return NULL; +} +/* }}} */ + +/* {{{ set_tab_numbers() */ +void +set_tab_numbers(gpointer data, gpointer user_data) +{ + t_tab_data *tab = (t_tab_data *)data; + gint num = *((gint *)user_data); + + if (tab->num > num) + tab->num--; +} +/* }}} */ + +/* {{{ close_tab() */ +gboolean +close_tab(t_tab_data *to_close) +{ + Context; + + if (!to_close) + return TRUE; + + if (to_close->connected) + { + GtkWidget *dialog; + gint result; + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("This tab is connected. Are you sure you want to close it?")); + result = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + switch (result) + { + case GTK_RESPONSE_YES: + gdk_input_remove(to_close->socktag); + close(to_close->sock); + break; + default: + return TRUE; + } + } + + Context; + + g_list_foreach(tab_list, set_tab_numbers, &(to_close->num)); + + Context; + + gtk_notebook_remove_page(GTK_NOTEBOOK(main_book), to_close->num); + tab_list = g_list_remove(tab_list, to_close); + + Context; + + if (!tab_list) + { + char *buf; + + buf = g_malloc(strlen(_("Mode: %c")) + 1); + sprintf(buf, _("Mode: %c"), 0); + gtk_label_set_text(GTK_LABEL(main_statuslabel_mode), buf); + g_free(buf); + + gtk_widget_set_sensitive(main_menu_show_sidebar, FALSE); + } + + Context; + + return TRUE; +} +/* }}} */ + +/* {{{ assign_bot_to_tab_by_name() */ +gboolean +assign_bot_to_tab_by_name(t_tab_data *tab, gchar *name) +{ + t_bot_data *temp = get_bot_by_botname(name); + + if (temp) + { + tab->bot = get_bot_by_botname(name); + set_title(tab, name); + return TRUE; + } + + return FALSE; +} +/* }}} */ + +/* {{{ assign_bot_to_tab() */ +void +assign_bot_to_tab(t_tab_data *tab, t_bot_data *bot) +{ + tab->bot = bot; + set_title(tab, bot->botname); +} +/* }}} */ + +/* {{{ connect_tab() */ +gint +connect_tab(t_tab_data *tab) +{ + gint t = BCE_NOBOT; + + if (tab->bot) + { + t = connect_to_host(tab->bot->host, tab->bot->port, &(tab->sock), &(tab->socktag), tab); + switch (t) + { + case BCE_NOPROTO: + feed_error_to_terminal(tab, TRUE, _("Can not get IP protocol")); + break; + case BCE_CANTRESOLV: + feed_error_to_terminal(tab, TRUE, _("Can not resolv hostname %s"), tab->bot->host); + break; + case BCE_CANTCONNECT: + feed_error_to_terminal(tab, TRUE, _("Can not connect to bot")); + break; + case BCE_SUCCESS: + tab->connected = TRUE; + break; + default: + feed_error_to_terminal(tab, TRUE, _("Unknown error!")); + break; + } + } + + return t; +} +/* }}} */ + +/* {{{ channel_store_updater() */ +void +channel_store_updater(gpointer item, gpointer store) +{ + GtkListStore *model = (GtkListStore *)store; + GtkTreeIter iter; + + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, 0, ((t_channel *)item)->name, -1); +} +/* }}} */ + +/* {{{ update_channel_list() */ +void +update_channel_list(t_tab_data *tab) +{ + GtkTreeModel *model; + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(tab->channel_list)); + g_object_ref(model); + gtk_tree_view_set_model(GTK_TREE_VIEW(tab->channel_list), NULL); + + gtk_list_store_clear(GTK_LIST_STORE(model)); + + g_list_foreach(tab->actual_channel_list, channel_store_updater, model); + + gtk_tree_view_set_model(GTK_TREE_VIEW(tab->channel_list), model); + g_object_unref(model); +} +/* }}} */ + +/* {{{ user_store_updater() */ +void +user_store_updater(gpointer item, gpointer store) +{ + GtkListStore *model = (GtkListStore *)store; + GtkTreeIter iter; + + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, 0, ((t_user *)item)->name, -1); +} +/* }}} */ + +/* {{{ update_user_list() */ +void +update_user_list(t_tab_data *tab) +{ + GtkTreeModel *model; + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(tab->user_list)); + g_object_ref(model); + gtk_tree_view_set_model(GTK_TREE_VIEW(tab->user_list), NULL); + + gtk_list_store_clear(GTK_LIST_STORE(model)); + + g_list_foreach(tab->actual_user_list, user_store_updater, model); + + gtk_tree_view_set_model(GTK_TREE_VIEW(tab->user_list), model); + g_object_unref(model); +} +/* }}} */ + +/* {{{ disconnect_tab() */ +void +disconnect_tab(t_tab_data *tab) +{ + if (tab->connected == FALSE) + { + feed_error_to_terminal(tab, TRUE, _("Tab is not connected")); + return; + } + shutdown(tab->sock, SHUT_RDWR); + close(tab->sock); + gdk_input_remove(tab->socktag); + tab->connected = FALSE; + tab->socktag = 0; + tab->sock = 0; + if (tab->data_arrived) + feed_info_to_terminal(tab, TRUE, _("Connection closed")); + set_title(tab, "Not connected"); + change_mode('B', FALSE); + tab->data_arrived = FALSE; + /* If the connection is closed while we enter the password (e.g + * you mistype the password), the entry would be masked + * forever, so I unmask it now */ + gtk_entry_set_visibility(GTK_ENTRY(tab->editbox), TRUE); +} +/* }}} */ + +/* {{{ change_active_tab() */ +void +change_active_tab(gint num) +{ + gtk_notebook_set_current_page(GTK_NOTEBOOK(main_book), num); +} +/* }}} */ diff --git a/src/widgets.c b/src/widgets.c new file mode 100644 index 0000000..adcb3f3 --- /dev/null +++ b/src/widgets.c @@ -0,0 +1,412 @@ +/* vim: set foldmethod=marker : */ +/* {{{ Legal info + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + }}} */ +/* {{{ + * widgets.c + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + * + * Widget creation + }}} */ + +// TODO: Insert this in one of the Makefiles +#define _GNU_SOURCE +/* {{{ Includes */ +#include +#include +#include +#include +#include +#include +#include + +#include "functions.h" +#include "typedefs.h" +#include "defines.h" +#include "config.h" + +/* }}} */ + +/* {{{ Variables */ +GtkWidget *main_window; +GtkWidget *main_vbox; +GtkWidget *main_menu; +GtkWidget *main_toolbar; +GtkWidget *main_book; +GtkWidget *main_statusbox; +GtkWidget *main_statuslabel_message; +GtkWidget *main_statuslabel_mode; +GtkWidget *main_menu_mode_b; +GtkWidget *main_menu_mode_e; +GtkWidget *main_menu_mode_m; +GtkAccelGroup *accel_group; +GtkWidget *main_menu_show_sidebar; +/* }}} */ + +/* {{{ set_title() */ +void +set_title(t_tab_data *what, char *format, ...) +{ + gchar *ptbuf; + va_list args; + + Context; + va_start(args, format); + vasprintf(&ptbuf, format, args); + va_end(args); + Context; + + if (!what) + gtk_window_set_title(GTK_WINDOW(main_window), (const gchar *)ptbuf); + else + { + gtk_label_set_text(GTK_LABEL(what->label), ptbuf); + if (get_active_tab() == what) + set_title(NULL, "BotCommander - %s", ptbuf); + } +} +/* }}} */ + +/* {{{ create_menu() */ +GtkWidget * +create_menu(void) +{ + GtkWidget *menubar; + GtkWidget *submenu; + GtkWidget *menuitem; + GtkWidget *image; + GtkWidget *hbox; + GtkWidget *child; + GSList *group = NULL; + + menubar = gtk_menu_bar_new(); + + /* Bot submenu */ + submenu = gtk_menu_new(); + + /* Exit menu item */ + menuitem = gtk_menu_item_new_with_mnemonic(_("E_xit")); + hbox = gtk_hbox_new(FALSE, 0); + image = gtk_image_new_from_stock(GTK_STOCK_QUIT, GTK_ICON_SIZE_MENU); + child = gtk_bin_get_child(GTK_BIN(menuitem)); + g_object_ref(child); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + gtk_container_remove(GTK_CONTAINER(menuitem), child); + gtk_box_pack_start(GTK_BOX(hbox), child, TRUE, TRUE, 2); + g_object_unref(child); + gtk_container_add(GTK_CONTAINER(menuitem), hbox); + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(menu_exit), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + /* Append the submenu to the menu bar */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_Bot")); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menuitem); + + /* Mode submenu */ + submenu = gtk_menu_new(); + + /* BotCommander Command Mode menu item */ + menuitem = gtk_radio_menu_item_new_with_mnemonic(group, _("_BotCommander command mode")); + gtk_signal_connect(GTK_OBJECT(menuitem), "toggled", GTK_SIGNAL_FUNC(menu_mode_changed), NULL); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem)); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + main_menu_mode_b = menuitem; + gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_b, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + /* Eggdrop Command Mode menu item */ + menuitem = gtk_radio_menu_item_new_with_mnemonic(group, _("_Eggdrop command mode")); + gtk_signal_connect(GTK_OBJECT(menuitem), "toggled", GTK_SIGNAL_FUNC(menu_mode_changed), NULL); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem)); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + main_menu_mode_e = menuitem; + gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_e, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + /* Message Mode menu item */ + menuitem = gtk_radio_menu_item_new_with_mnemonic(group, _("_Message mode")); + gtk_signal_connect(GTK_OBJECT(menuitem), "toggled", GTK_SIGNAL_FUNC(menu_mode_changed), NULL); + group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem)); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + main_menu_mode_m = menuitem; + gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_m, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + /* Append the submenu to the menu bar */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_Mode")); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menuitem); + + /* Setup submenu */ + submenu = gtk_menu_new(); + + /* Bot List menu item */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_Bot list")); + hbox = gtk_hbox_new(FALSE, 0); + image = gtk_image_new_from_stock(GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_MENU); + child = gtk_bin_get_child(GTK_BIN(menuitem)); + g_object_ref(child); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + gtk_container_remove(GTK_CONTAINER(menuitem), child); + gtk_box_pack_start(GTK_BOX(hbox), child, TRUE, TRUE, 2); + g_object_unref(child); + gtk_container_add(GTK_CONTAINER(menuitem), hbox); + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(menu_botlist_open), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_l, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + /* Preferences menu item */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_Preferences")); + hbox = gtk_hbox_new(FALSE, 0); + image = gtk_image_new_from_stock(GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU); + child = gtk_bin_get_child(GTK_BIN(menuitem)); + g_object_ref(child); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + gtk_container_remove(GTK_CONTAINER(menuitem), child); + gtk_box_pack_start(GTK_BOX(hbox), child, TRUE, TRUE, 2); + g_object_unref(child); + gtk_container_add(GTK_CONTAINER(menuitem), hbox); + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(menu_prefs_open), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_p, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + /* Append the submenu to the menu bar */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_Setup")); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menuitem); + + /* Tab submenu */ + submenu = gtk_menu_new(); + + /* New Tab menu item */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_New tab")); + hbox = gtk_hbox_new(FALSE, 0); + image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU); + child = gtk_bin_get_child(GTK_BIN(menuitem)); + g_object_ref(child); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + gtk_container_remove(GTK_CONTAINER(menuitem), child); + gtk_box_pack_start(GTK_BOX(hbox), child, TRUE, TRUE, 2); + g_object_unref(child); + gtk_container_add(GTK_CONTAINER(menuitem), hbox); + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(menu_new_tab), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_t, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + /* Close Tab menu item */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_Close tab")); + hbox = gtk_hbox_new(FALSE, 0); + image = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); + child = gtk_bin_get_child(GTK_BIN(menuitem)); + g_object_ref(child); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + gtk_container_remove(GTK_CONTAINER(menuitem), child); + gtk_box_pack_start(GTK_BOX(hbox), child, TRUE, TRUE, 2); + g_object_unref(child); + gtk_container_add(GTK_CONTAINER(menuitem), hbox); + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(menu_close_tab), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + gtk_widget_add_accelerator(menuitem, "activate", accel_group, GDK_w, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + + /* Show/hide the channel and handle list */ + main_menu_show_sidebar = gtk_check_menu_item_new_with_mnemonic(_("Show sidebar")); + hbox = gtk_hbox_new(FALSE, 0); + image = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); + child = gtk_bin_get_child(GTK_BIN(main_menu_show_sidebar)); + g_object_ref(child); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + gtk_container_remove(GTK_CONTAINER(main_menu_show_sidebar), child); + gtk_box_pack_start(GTK_BOX(hbox), child, TRUE, TRUE, 2); + g_object_unref(child); + gtk_container_add(GTK_CONTAINER(main_menu_show_sidebar), hbox); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(main_menu_show_sidebar), TRUE); + gtk_signal_connect(GTK_OBJECT(main_menu_show_sidebar), "toggled", GTK_SIGNAL_FUNC(menu_showhide_sidebar), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), main_menu_show_sidebar); + gtk_widget_add_accelerator(main_menu_show_sidebar, "activate", accel_group, GDK_h, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); + gtk_widget_set_sensitive(main_menu_show_sidebar, FALSE); + + /* Append the submenu to the menu bar */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_Tab")); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menuitem); + + /* Help submenu */ + submenu = gtk_menu_new(); + + /* About menu item */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_About")); + hbox = gtk_hbox_new(FALSE, 0); + image = gtk_image_new_from_stock(GTK_STOCK_ABOUT, GTK_ICON_SIZE_MENU); + child = gtk_bin_get_child(GTK_BIN(menuitem)); + g_object_ref(child); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + gtk_container_remove(GTK_CONTAINER(menuitem), child); + gtk_box_pack_start(GTK_BOX(hbox), child, TRUE, TRUE, 2); + g_object_unref(child); + gtk_container_add(GTK_CONTAINER(menuitem), hbox); + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", GTK_SIGNAL_FUNC(menu_about), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); + + /* Append the submenu to the menu bar */ + menuitem = gtk_menu_item_new_with_mnemonic(_("_Help")); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menuitem); + gtk_menu_item_set_right_justified(GTK_MENU_ITEM(menuitem), TRUE); + + return menubar; +} +/* }}} */ + +/* {{{ create_main_window() */ +int +create_main_window(void) +{ + GtkWidget *frame; + gchar *buf; + + main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(destroy_event), NULL); + g_signal_connect(G_OBJECT(main_window), "delete_event", G_CALLBACK(delete_event), NULL); + set_title(NULL, "BotCommander"); + gtk_window_set_default_icon_from_file(PACKAGE_PIXMAPS_DIR "/bc48_trans.png", NULL); + + accel_group = gtk_accel_group_new(); + gtk_window_add_accel_group(GTK_WINDOW(main_window), accel_group); + + main_vbox = gtk_vbox_new(FALSE, 0); + + main_menu = create_menu(); + gtk_signal_connect(GTK_OBJECT(main_window), "key_press_event", GTK_SIGNAL_FUNC(entry_keypress), NULL); + gtk_box_pack_start(GTK_BOX(main_vbox), main_menu, FALSE, TRUE, 0); + + main_toolbar = gtk_toolbar_new(); + gtk_toolbar_insert_stock(GTK_TOOLBAR(main_toolbar), GTK_STOCK_QUIT, _("Exit BotCommander"), NULL, G_CALLBACK(toolbar_quit), NULL, -1); + gtk_toolbar_insert_stock(GTK_TOOLBAR(main_toolbar), GTK_STOCK_ADD, _("New tab"), NULL, G_CALLBACK(toolbar_add_tab), NULL, -1); + gtk_toolbar_insert_stock(GTK_TOOLBAR(main_toolbar), GTK_STOCK_CLOSE, _("Close active tab"), NULL, G_CALLBACK(toolbar_close_active), NULL, -1); + gtk_toolbar_insert_stock(GTK_TOOLBAR(main_toolbar), GTK_STOCK_PREFERENCES, _("Preferences"), NULL, G_CALLBACK(toolbar_open_prefs), NULL, -1); + gtk_toolbar_set_style(GTK_TOOLBAR(main_toolbar), GTK_TOOLBAR_ICONS); + gtk_box_pack_start(GTK_BOX(main_vbox), main_toolbar, FALSE, TRUE, 0); + + main_book = gtk_notebook_new(); + gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_book), GTK_POS_TOP); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_book), TRUE); + gtk_notebook_set_show_border(GTK_NOTEBOOK(main_book), TRUE); + gtk_notebook_set_scrollable(GTK_NOTEBOOK(main_book), TRUE); + gtk_signal_connect(GTK_OBJECT(main_book), "switch-page", GTK_SIGNAL_FUNC(book_change_tab), NULL); + gtk_box_pack_start(GTK_BOX(main_vbox), main_book, TRUE, TRUE, 0); + + main_statusbox = gtk_hbox_new(FALSE, 0); + + frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); + main_statuslabel_message = gtk_label_new("BotCommander"); + gtk_label_set_justify(GTK_LABEL(main_statuslabel_message), GTK_JUSTIFY_RIGHT); + gtk_container_add(GTK_CONTAINER(frame), main_statuslabel_message); + gtk_box_pack_start(GTK_BOX(main_statusbox), frame, TRUE, TRUE, 0); + + buf = g_malloc(strlen(_("Mode: %c")) + 1); + sprintf(buf, _("Mode: %c"), 0); + frame = gtk_frame_new(NULL); + main_statuslabel_mode = gtk_label_new(buf); + g_free(buf); + gtk_label_set_justify(GTK_LABEL(main_statuslabel_mode), GTK_JUSTIFY_LEFT); + gtk_container_add(GTK_CONTAINER(frame), main_statuslabel_mode); + gtk_box_pack_end(GTK_BOX(main_statusbox), frame, FALSE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(main_vbox), main_statusbox, FALSE, FALSE, 0); + + gtk_container_add(GTK_CONTAINER(main_window), main_vbox); + + gtk_widget_show_all(main_window); + + return TRUE; +} +/* }}} */ + +/* {{{ feed_line_to_terminal() */ +/* Feeds some text to the terminal widget. */ +static void +feed_line_to_terminal(t_tab_data *tab, gboolean need_crlf, gchar *line, va_list list) +{ + gchar *string; + gint len; + + len = vasprintf(&string, line, list); + + vte_terminal_feed((VteTerminal *)tab->vt, string, strlen(string)); + if (need_crlf) + vte_terminal_feed((VteTerminal *)tab->vt, "\r\n", 2); +} +/* }}} */ + +/* {{{ feed_crlf_to_terminal() */ +/* Feeds a CD LF pair to the terminal, if needed. */ +static void +feed_crlf_to_terminal(t_tab_data *tab, gboolean need_it) +{ + if (need_it) + vte_terminal_feed((VteTerminal *)tab->vt, "\r\n", 2); +} +/* }}} */ + +/* {{{ feed_message_to_terminal() */ +/* Feeds some informational (un-coloured) text to the terminal, always appending a line-feed. */ +void +feed_message_to_terminal(t_tab_data *tab, gboolean need_crlf, gchar *line, ...) +{ + va_list pl; + + va_start(pl, line); + feed_line_to_terminal(tab, FALSE, line, pl); + va_end(pl); + feed_crlf_to_terminal(tab, need_crlf); +} +/* }}} */ + +/* {{{ feed_error_to_terminal() */ +/* Feeds some error (red) text to the terminal, always appending a line-feed */ +void +feed_error_to_terminal(t_tab_data *tab, gboolean need_crlf, gchar *line, ...) +{ + va_list pl; + + va_start(pl, line); + feed_message_to_terminal(tab, FALSE, "\033[1;31m"); + feed_line_to_terminal(tab, FALSE, line, pl); + va_end(pl); + feed_message_to_terminal(tab, need_crlf, "\033[0m"); +} +/* }}} */ + +/* {{{ feed_info_to_terminal() */ +/* Feeds some informational (green) text to the terminal, always appending a line-feed. */ +void +feed_info_to_terminal(t_tab_data *tab, gboolean need_crlf, gchar *line, ...) +{ + va_list pl; + + feed_message_to_terminal(tab, FALSE, "\033[1;32m"); + + va_start(pl, line); + feed_line_to_terminal(tab, FALSE, line, pl); + va_end(pl); + + feed_message_to_terminal(tab, need_crlf, "\033[0m"); +} +/* }}} */ + diff --git a/template b/template new file mode 100644 index 0000000..ded3ee0 --- /dev/null +++ b/template @@ -0,0 +1,26 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +/*************************************************************************** + * #FILE# + * + * Wed Nov 09 22:16:59 2005 + * Copyright (C) 2005 Gergely POLONKAI + * polesz@techinfo.hu + ***************************************************************************/ +/*************************************************************************** + * #DESCRIPTION# + ***************************************************************************/ +