diff options
author | Slávek Banko <slavek.banko@axis.cz> | 2013-07-02 18:32:11 +0200 |
---|---|---|
committer | Slávek Banko <slavek.banko@axis.cz> | 2013-07-02 18:32:11 +0200 |
commit | 5ec5bc2080bbc41e025fb98e6571a2c281b775cb (patch) | |
tree | a73cf2c57d306e6ce092996f70b29b8fbc0a006b /kbiff | |
download | kbiff-5ec5bc2080bbc41e025fb98e6571a2c281b775cb.tar.gz kbiff-5ec5bc2080bbc41e025fb98e6571a2c281b775cb.zip |
Initial import
Diffstat (limited to 'kbiff')
44 files changed, 9274 insertions, 0 deletions
diff --git a/kbiff/Makefile.am b/kbiff/Makefile.am new file mode 100644 index 0000000..b2f6603 --- /dev/null +++ b/kbiff/Makefile.am @@ -0,0 +1,38 @@ +# just set the variable +appsdir = $(kde_appsdir)/Internet +apps_DATA = kbiff.desktop + +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# claim, which subdirectories you want to install +SUBDIRS = pics + +####### This part is very kbiff specific +# you can add here more. This one gets installed +bin_PROGRAMS = +lib_LTLIBRARIES = +kdeinit_LTLIBRARIES = kbiff.la + +# Which sources should be compiled for kbiff. +kbiff_la_SOURCES = setupdlg.cpp kbiff.cpp main.cpp kbiffmonitor.cpp \ + notify.cpp kbiffurl.cpp status.cpp kbiffcodec.cpp \ + led.cpp kbiffcrypt.cpp version.cpp + +# the library search path +kbiff_la_LDFLAGS = $(all_libraries) -module -avoid-version + +# the libraries to link against. Be aware of the order. First the libraries, +# that depend on the following ones. +kbiff_la_LIBADD = $(LIB_KFILE) $(LIB_KIO) + +# this option you can leave out. Just, if you use "make dist", you need it +noinst_HEADERS = setupdlg.h kbiff.h kbiffmonitor.h notify.h kbiffurl.h \ + status.h kbiffcodec.h led.h version.h + +METASOURCES = AUTO + +messages: + $(XGETTEXT) *.cpp -o $(podir)/kbiff.pot + +KDE_ICON = kbiff diff --git a/kbiff/Makefile.in b/kbiff/Makefile.in new file mode 100644 index 0000000..6f9724f --- /dev/null +++ b/kbiff/Makefile.in @@ -0,0 +1,1132 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# KDE tags expanded automatically by am_edit - $Revision$ +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = +subdir = kbiff +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(kdeinitdir)" "$(DESTDIR)$(libdir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(appsdir)" +kdeinitLTLIBRARIES_INSTALL = $(INSTALL) +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(kdeinit_LTLIBRARIES) $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +#>- kbiff_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +#>+ 1 +kbiff_la_DEPENDENCIES = libkdeinit_kbiff.la +#>- am_kbiff_la_OBJECTS = setupdlg.lo kbiff.lo main.lo kbiffmonitor.lo \ +#>- notify.lo kbiffurl.lo status.lo kbiffcodec.lo led.lo \ +#>- kbiffcrypt.lo version.lo +#>+ 1 +am_kbiff_la_OBJECTS = kbiff_dummy.lo +#>- kbiff_la_OBJECTS = $(am_kbiff_la_OBJECTS) +#>+ 1 +kbiff_la_OBJECTS = kbiff_dummy.lo +#>- kbiff_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ +#>- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ +#>- $(CXXFLAGS) $(kbiff_la_LDFLAGS) $(LDFLAGS) -o $@ +#>+ 3 +kbiff_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(KDE_CXXFLAGS) $(kbiff_la_LDFLAGS) $(LDFLAGS) -o $@ +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +#>- PROGRAMS = $(bin_PROGRAMS) +#>+ 2 +bin_PROGRAMS += kbiff$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/admin/depcomp +am__depfiles_maybe = depfiles +#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 2 +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +#>- LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ +#>- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +#>+ 3 +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) +CXXLD = $(CXX) +#>- CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ +#>- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ +#>- $(LDFLAGS) -o $@ +#>+ 3 +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +#>- SOURCES = $(kbiff_la_SOURCES) +#>+ 1 +SOURCES = $(kbiff_la_SOURCES) $(kbiff_SOURCES) +#>- DIST_SOURCES = $(kbiff_la_SOURCES) +#>+ 1 +DIST_SOURCES = $(kbiff_la_SOURCES) $(kbiff_SOURCES) +#>- RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ +#>- html-recursive info-recursive install-data-recursive \ +#>- install-dvi-recursive install-exec-recursive \ +#>- install-html-recursive install-info-recursive \ +#>- install-pdf-recursive install-ps-recursive install-recursive \ +#>- installcheck-recursive installdirs-recursive pdf-recursive \ +#>- ps-recursive uninstall-recursive +#>+ 7 +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive nmcheck-recursive bcheck-recursive +appsDATA_INSTALL = $(INSTALL_DATA) +DATA = $(apps_DATA) +HEADERS = $(noinst_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 1 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AUTOCONF = @AUTOCONF@ +AUTODIRS = @AUTODIRS@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOPIDLNG = @DCOPIDLNG@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ +KCONFIG_COMPILER = @KCONFIG_COMPILER@ +KDECONFIG = @KDECONFIG@ +KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ +KDE_MT_LIBS = @KDE_MT_LIBS@ +KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_USE_FPIE = @KDE_USE_FPIE@ +KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@ +KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@ +KDE_USE_PIE = @KDE_USE_PIE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@ +LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBJPEG = @LIBJPEG@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBRESOLV = @LIBRESOLV@ +LIBS = @LIBS@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KABC = @LIB_KABC@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDED = @LIB_KDED@ +LIB_KDEPIM = @LIB_KDEPIM@ +LIB_KDEPRINT = @LIB_KDEPRINT@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KDNSSD = @LIB_KDNSSD@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIMPROXY = @LIB_KIMPROXY@ +LIB_KIO = @LIB_KIO@ +LIB_KJS = @LIB_KJS@ +LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_KUNITTEST = @LIB_KUNITTEST@ +LIB_KUTILS = @LIB_KUTILS@ +LIB_POLL = @LIB_POLL@ +LIB_QPE = @LIB_QPE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LIB_XEXT = @LIB_XEXT@ +LIB_XRENDER = @LIB_XRENDER@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CFLAGS = @NOOPT_CFLAGS@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +QTE_NORTTI = @QTE_NORTTI@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@ +XGETTEXT = @XGETTEXT@ +XMKMF = @XMKMF@ +XMLLINT = @XMLLINT@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +X_RPATH = @X_RPATH@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_kcfgdir = @kde_kcfgdir@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_styledir = @kde_styledir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +kde_widgetdir = @kde_widgetdir@ +kdeinitdir = @kdeinitdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ +xdg_appsdir = @xdg_appsdir@ +xdg_directorydir = @xdg_directorydir@ +xdg_menudir = @xdg_menudir@ + +# just set the variable +appsdir = $(kde_appsdir)/Internet +apps_DATA = kbiff.desktop + +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# claim, which subdirectories you want to install +SUBDIRS = pics +#>- lib_LTLIBRARIES = +#>+ 1 +lib_LTLIBRARIES = libkdeinit_kbiff.la +kdeinit_LTLIBRARIES = kbiff.la + +# Which sources should be compiled for kbiff. +kbiff_la_SOURCES = setupdlg.cpp kbiff.cpp main.cpp kbiffmonitor.cpp \ + notify.cpp kbiffurl.cpp status.cpp kbiffcodec.cpp \ + led.cpp kbiffcrypt.cpp version.cpp + + +# the library search path +kbiff_la_LDFLAGS = $(all_libraries) -module -avoid-version + +# the libraries to link against. Be aware of the order. First the libraries, +# that depend on the following ones. +#>- kbiff_la_LIBADD = $(LIB_KFILE) $(LIB_KIO) +#>+ 1 +kbiff_la_LIBADD = libkdeinit_kbiff.la + +# this option you can leave out. Just, if you use "make dist", you need it +noinst_HEADERS = setupdlg.h kbiff.h kbiffmonitor.h notify.h kbiffurl.h \ + status.h kbiffcodec.h led.h version.h + +#>- METASOURCES = AUTO +KDE_ICON = kbiff +#>- all: all-recursive +#>+ 1 +all: docs-am all-recursive + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +#>- @for dep in $?; do \ +#>- case '$(am__configure_deps)' in \ +#>- *$$dep*) \ +#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ +#>- && exit 0; \ +#>- exit 1;; \ +#>- esac; \ +#>- done; \ +#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kbiff/Makefile'; \ +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu kbiff/Makefile +#>+ 12 + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kbiff/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu kbiff/Makefile + cd $(top_srcdir) && perl admin/am_edit -padmin kbiff/Makefile.in +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-kdeinitLTLIBRARIES: $(kdeinit_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(kdeinitdir)" || $(MKDIR_P) "$(DESTDIR)$(kdeinitdir)" + @list='$(kdeinit_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(kdeinitLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(kdeinitdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(kdeinitLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(kdeinitdir)/$$f"; \ + else :; fi; \ + done + +uninstall-kdeinitLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(kdeinit_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(kdeinitdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(kdeinitdir)/$$p"; \ + done + +clean-kdeinitLTLIBRARIES: + -test -z "$(kdeinit_LTLIBRARIES)" || rm -f $(kdeinit_LTLIBRARIES) + @list='$(kdeinit_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +kbiff.la: $(kbiff_la_OBJECTS) $(kbiff_la_DEPENDENCIES) + $(kbiff_la_LINK) -rpath $(kdeinitdir) $(kbiff_la_OBJECTS) $(kbiff_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbiff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbiffcodec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbiffcrypt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbiffmonitor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbiffurl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/led.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notify.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setupdlg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-appsDATA: $(apps_DATA) + @$(NORMAL_INSTALL) + test -z "$(appsdir)" || $(MKDIR_P) "$(DESTDIR)$(appsdir)" + @list='$(apps_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(appsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(appsdir)/$$f'"; \ + $(appsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(appsdir)/$$f"; \ + done + +uninstall-appsDATA: + @$(NORMAL_UNINSTALL) + @list='$(apps_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(appsdir)/$$f'"; \ + rm -f "$(DESTDIR)$(appsdir)/$$f"; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(kdeinitdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(appsdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-recursive +#>+ 1 +clean: kde-rpo-clean clean-recursive + +#>- clean-am: clean-binPROGRAMS clean-generic clean-kdeinitLTLIBRARIES \ +#>- clean-libLTLIBRARIES clean-libtool mostlyclean-am +#>+ 2 +clean-am: clean-metasources clean-bcheck clean-final clean-binPROGRAMS clean-generic clean-kdeinitLTLIBRARIES \ + clean-libLTLIBRARIES clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +#>- install-data-am: install-appsDATA install-kdeinitLTLIBRARIES +#>+ 1 +install-data-am: install-kde-icons install-appsDATA install-kdeinitLTLIBRARIES + +install-dvi: install-dvi-recursive + +install-exec-am: install-binPROGRAMS install-libLTLIBRARIES + +install-html: install-html-recursive + +install-info: install-info-recursive + +install-man: + +install-pdf: install-pdf-recursive + +install-ps: install-ps-recursive + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +#>- uninstall-am: uninstall-appsDATA uninstall-binPROGRAMS \ +#>- uninstall-kdeinitLTLIBRARIES uninstall-libLTLIBRARIES +#>+ 2 +uninstall-am: uninstall-kde-icons uninstall-appsDATA uninstall-binPROGRAMS \ + uninstall-kdeinitLTLIBRARIES uninstall-libLTLIBRARIES + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-kdeinitLTLIBRARIES clean-libLTLIBRARIES \ + clean-libtool ctags ctags-recursive distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-appsDATA install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-kdeinitLTLIBRARIES \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am uninstall-appsDATA \ + uninstall-binPROGRAMS uninstall-kdeinitLTLIBRARIES \ + uninstall-libLTLIBRARIES + + +messages: + $(XGETTEXT) *.cpp -o $(podir)/kbiff.pot +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + + +#>+ 2 +libkdeinit_kbiff_la_LIBADD = $(LIB_KFILE) $(LIB_KIO) + +#>+ 2 +libkdeinit_kbiff_la_LDFLAGS = -no-undefined -avoid-version $(all_libraries) + +#>+ 2 +libkdeinit_kbiff_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + +#>+ 4 +am_libkdeinit_kbiff_la_OBJECTS = setupdlg.lo kbiff.lo main.lo kbiffmonitor.lo \ + notify.lo kbiffurl.lo status.lo kbiffcodec.lo led.lo \ + kbiffcrypt.lo version.lo + +#>+ 13 + +kbiff.la.cpp: + echo 'extern "C" int kdemain(int argc, char* argv[]);' > kbiff.la.cpp; \ + echo 'int main(int argc, char* argv[]) { return kdemain(argc,argv); }' >> kbiff.la.cpp + +kbiff_dummy.cpp: + echo '#include <kdemacros.h>' > kbiff_dummy.cpp; \ + echo 'extern "C" int kdemain(int argc, char* argv[]);' >> kbiff_dummy.cpp; \ + echo 'extern "C" KDE_EXPORT int kdeinitmain(int argc, char* argv[]) { return kdemain(argc,argv); }' >> kbiff_dummy.cpp +kbiff_LDFLAGS = $(KDE_RPATH) -no-undefined $(all_libraries) +kbiff_LDADD = libkdeinit_kbiff.la +kbiff_DEPENDENCIES = libkdeinit_kbiff.la + +#>+ 3 +setupdlg.moc: $(srcdir)/setupdlg.h + $(MOC) $(srcdir)/setupdlg.h -o setupdlg.moc + +#>+ 2 +mocs: setupdlg.moc + +#>+ 3 +kbiffmonitor.moc: $(srcdir)/kbiffmonitor.h + $(MOC) $(srcdir)/kbiffmonitor.h -o kbiffmonitor.moc + +#>+ 2 +mocs: kbiffmonitor.moc + +#>+ 3 +kbiff.moc: $(srcdir)/kbiff.h + $(MOC) $(srcdir)/kbiff.h -o kbiff.moc + +#>+ 2 +mocs: kbiff.moc + +#>+ 3 +status.moc: $(srcdir)/status.h + $(MOC) $(srcdir)/status.h -o status.moc + +#>+ 2 +mocs: status.moc + +#>+ 3 +notify.moc: $(srcdir)/notify.h + $(MOC) $(srcdir)/notify.h -o notify.moc + +#>+ 2 +mocs: notify.moc + +#>+ 3 +clean-metasources: + -rm -f setupdlg.moc kbiffmonitor.moc kbiff.moc status.moc notify.moc + +#>+ 2 +KDE_DIST=kbiff.desktop lo16-app-kbiff.png Makefile.in kbiffcrypt.h hi48-app-kbiff.png hi16-app-kbiff.png hi32-app-kbiff.png Makefile.am lo32-app-kbiff.png + +#>+ 2 +docs-am: + +#>+ 19 +install-kde-icons: + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/locolor/32x32/apps + $(INSTALL_DATA) $(srcdir)/lo32-app-kbiff.png $(DESTDIR)$(kde_icondir)/locolor/32x32/apps/kbiff.png + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps + $(INSTALL_DATA) $(srcdir)/hi16-app-kbiff.png $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps/kbiff.png + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/hicolor/48x48/apps + $(INSTALL_DATA) $(srcdir)/hi48-app-kbiff.png $(DESTDIR)$(kde_icondir)/hicolor/48x48/apps/kbiff.png + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/locolor/16x16/apps + $(INSTALL_DATA) $(srcdir)/lo16-app-kbiff.png $(DESTDIR)$(kde_icondir)/locolor/16x16/apps/kbiff.png + $(mkinstalldirs) $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps + $(INSTALL_DATA) $(srcdir)/hi32-app-kbiff.png $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps/kbiff.png + +uninstall-kde-icons: + -rm -f $(DESTDIR)$(kde_icondir)/locolor/32x32/apps/kbiff.png + -rm -f $(DESTDIR)$(kde_icondir)/hicolor/16x16/apps/kbiff.png + -rm -f $(DESTDIR)$(kde_icondir)/hicolor/48x48/apps/kbiff.png + -rm -f $(DESTDIR)$(kde_icondir)/locolor/16x16/apps/kbiff.png + -rm -f $(DESTDIR)$(kde_icondir)/hicolor/32x32/apps/kbiff.png + +#>+ 15 +force-reedit: + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kbiff/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu kbiff/Makefile + cd $(top_srcdir) && perl admin/am_edit -padmin kbiff/Makefile.in + + +#>+ 21 +clean-bcheck: + rm -f *.bchecktest.cc *.bchecktest.cc.class a.out + +bcheck: bcheck-recursive + +bcheck-am: + @for i in ; do \ + if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \ + echo "int main() {return 0;}" > $$i.bchecktest.cc ; \ + echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \ + echo "$$i"; \ + if ! $(CXXCOMPILE) --dump-class-hierarchy -c $$i.bchecktest.cc; then \ + rm -f $$i.bchecktest.cc; exit 1; \ + fi ; \ + echo "" >> $$i.bchecktest.cc.class; \ + perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \ + rm -f a.out; \ + fi ; \ + done + + +#>+ 11 +libkdeinit_kbiff_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/setupdlg.cpp $(srcdir)/kbiff.cpp $(srcdir)/main.cpp $(srcdir)/kbiffmonitor.cpp $(srcdir)/notify.cpp $(srcdir)/kbiffurl.cpp $(srcdir)/status.cpp $(srcdir)/kbiffcodec.cpp $(srcdir)/led.cpp $(srcdir)/kbiffcrypt.cpp $(srcdir)/version.cpp kbiffmonitor.moc setupdlg.moc kbiff.moc status.moc notify.moc + @echo 'creating libkdeinit_kbiff_la.all_cpp.cpp ...'; \ + rm -f libkdeinit_kbiff_la.all_cpp.files libkdeinit_kbiff_la.all_cpp.final; \ + echo "#define KDE_USE_FINAL 1" >> libkdeinit_kbiff_la.all_cpp.final; \ + for file in setupdlg.cpp kbiff.cpp main.cpp kbiffmonitor.cpp notify.cpp kbiffurl.cpp status.cpp kbiffcodec.cpp led.cpp kbiffcrypt.cpp version.cpp ; do \ + echo "#include \"$$file\"" >> libkdeinit_kbiff_la.all_cpp.files; \ + test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libkdeinit_kbiff_la.all_cpp.final; \ + done; \ + cat libkdeinit_kbiff_la.all_cpp.final libkdeinit_kbiff_la.all_cpp.files > libkdeinit_kbiff_la.all_cpp.cpp; \ + rm -f libkdeinit_kbiff_la.all_cpp.final libkdeinit_kbiff_la.all_cpp.files + +#>+ 11 +kbiff_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/setupdlg.cpp $(srcdir)/kbiff.cpp $(srcdir)/main.cpp $(srcdir)/kbiffmonitor.cpp $(srcdir)/notify.cpp $(srcdir)/kbiffurl.cpp $(srcdir)/status.cpp $(srcdir)/kbiffcodec.cpp $(srcdir)/led.cpp $(srcdir)/kbiffcrypt.cpp $(srcdir)/version.cpp kbiffmonitor.moc setupdlg.moc kbiff.moc status.moc notify.moc + @echo 'creating kbiff_la.all_cpp.cpp ...'; \ + rm -f kbiff_la.all_cpp.files kbiff_la.all_cpp.final; \ + echo "#define KDE_USE_FINAL 1" >> kbiff_la.all_cpp.final; \ + for file in setupdlg.cpp kbiff.cpp main.cpp kbiffmonitor.cpp notify.cpp kbiffurl.cpp status.cpp kbiffcodec.cpp led.cpp kbiffcrypt.cpp version.cpp ; do \ + echo "#include \"$$file\"" >> kbiff_la.all_cpp.files; \ + test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> kbiff_la.all_cpp.final; \ + done; \ + cat kbiff_la.all_cpp.final kbiff_la.all_cpp.files > kbiff_la.all_cpp.cpp; \ + rm -f kbiff_la.all_cpp.final kbiff_la.all_cpp.files + +#>+ 3 +clean-final: + -rm -f libkdeinit_kbiff_la.all_cpp.cpp kbiff_la.all_cpp.cpp + +#>+ 7 +libkdeinit_kbiff_la_final_OBJECTS = libkdeinit_kbiff_la.all_cpp.lo +libkdeinit_kbiff_la_nofinal_OBJECTS = setupdlg.lo kbiff.lo main.lo kbiffmonitor.lo \ + notify.lo kbiffurl.lo status.lo kbiffcodec.lo led.lo \ + kbiffcrypt.lo version.lo +@KDE_USE_FINAL_FALSE@libkdeinit_kbiff_la_OBJECTS = $(libkdeinit_kbiff_la_nofinal_OBJECTS) +@KDE_USE_FINAL_TRUE@libkdeinit_kbiff_la_OBJECTS = $(libkdeinit_kbiff_la_final_OBJECTS) + +#>+ 2 +kbiff_OBJECTS = kbiff.la.$(OBJEXT) + +#>+ 3 +final: + $(MAKE) libkdeinit_kbiff_la_OBJECTS="$(libkdeinit_kbiff_la_final_OBJECTS)" all-am + +#>+ 3 +final-install: + $(MAKE) libkdeinit_kbiff_la_OBJECTS="$(libkdeinit_kbiff_la_final_OBJECTS)" install-am + +#>+ 3 +no-final: + $(MAKE) libkdeinit_kbiff_la_OBJECTS="$(libkdeinit_kbiff_la_nofinal_OBJECTS)" all-am + +#>+ 3 +no-final-install: + $(MAKE) libkdeinit_kbiff_la_OBJECTS="$(libkdeinit_kbiff_la_nofinal_OBJECTS)" install-am + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo + +#>+ 20 +notify.o: notify.moc +libkdeinit_kbiff.la: $(libkdeinit_kbiff_la_OBJECTS) $(libkdeinit_kbiff_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libkdeinit_kbiff_la_LDFLAGS) $(libkdeinit_kbiff_la_OBJECTS) $(libkdeinit_kbiff_la_LIBADD) $(LIBS) + +kbiffmonitor.o: kbiffmonitor.moc +kbiff.lo: kbiff.moc +setupdlg.o: setupdlg.moc +nmcheck: +notify.lo: notify.moc +setupdlg.lo: setupdlg.moc +nmcheck-am: nmcheck +kbiffmonitor.lo: kbiffmonitor.moc +kbiff$(EXEEXT): $(kbiff_OBJECTS) $(kbiff_DEPENDENCIES) + @rm -f kbiff$(EXEEXT) + $(CXXLINK) $(kbiff_LDFLAGS) $(kbiff_OBJECTS) $(kbiff_LDADD) $(LIBS) + +kbiff.o: kbiff.moc +status.o: status.moc +status.lo: status.moc diff --git a/kbiff/hi16-app-kbiff.png b/kbiff/hi16-app-kbiff.png Binary files differnew file mode 100644 index 0000000..ad07177 --- /dev/null +++ b/kbiff/hi16-app-kbiff.png diff --git a/kbiff/hi32-app-kbiff.png b/kbiff/hi32-app-kbiff.png Binary files differnew file mode 100644 index 0000000..ee2fe26 --- /dev/null +++ b/kbiff/hi32-app-kbiff.png diff --git a/kbiff/hi48-app-kbiff.png b/kbiff/hi48-app-kbiff.png Binary files differnew file mode 100644 index 0000000..260a7c5 --- /dev/null +++ b/kbiff/hi48-app-kbiff.png diff --git a/kbiff/kbiff.cpp b/kbiff/kbiff.cpp new file mode 100644 index 0000000..95abaab --- /dev/null +++ b/kbiff/kbiff.cpp @@ -0,0 +1,995 @@ +/* + * kbiff.cpp + * Copyright (C) 1999-2008 Kurt Granroth <granroth@kde.org> + * + * This file contains the implementation of the main KBiff + * widget + */ +#include "kbiff.h" +#include "kbiff.moc" +#include <qmovie.h> +#include <qtooltip.h> + +#include <kaudioplayer.h> +#include <kconfig.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kpopupmenu.h> +#include <kprocess.h> +#include <krun.h> +#include <kwin.h> + +#include "setupdlg.h" +#include "notify.h" +#include "status.h" +#include "led.h" + +#include <unistd.h> + +#include <dcopclient.h> + +KBiff::KBiff(DCOPClient *client_, QWidget *parent_) + : DCOPObjectProxy(client_), + QLabel(parent_), + statusTimer(0), + status(0), + statusChanged(true), + mled( new Led("mled") ) +{ + setBackgroundMode(X11ParentRelative); + + setAutoResize(true); + setMargin(0); + setAlignment(AlignLeft | AlignTop); + + // enable the session management stuff + connect(kapp, SIGNAL(saveYourself()), this, SLOT(saveYourself())); + + // nuke the list stuff when removed + monitorList.setAutoDelete(true); + notifyList.setAutoDelete(true); + statusList.setAutoDelete(true); + + // register with DCOP + registerMe(client_); + + reset(); +} + +KBiff::~KBiff() +{ + monitorList.clear(); + notifyList.clear(); + statusList.clear(); + delete mled; + + // we no longer want to be registered + DCOPClient *client = kapp->dcopClient(); + QCString proxy = QCString("kbiff-") + QCString().setNum(getpid()); + if (client->isApplicationRegistered(proxy) == true) + { + QByteArray params; + QDataStream ds(params, IO_WriteOnly); + ds << proxy; + client->send("kbiff", "kbiff", "proxyDeregister(QString)", params); + } + client->detach(); +} + +void KBiff::processSetup(const KBiffSetup* setup_, bool run_) +{ + // General settings + isSecure = setup_->getSecure(); + profile = setup_->getProfile(); + mailClient = setup_->getMailClient(); + sessions = setup_->getSessionManagement(); + skipcheck = setup_->getCheckStartup(); + noMailIcon = setup_->getNoMailIcon(); + newMailIcon = setup_->getNewMailIcon(); + oldMailIcon = setup_->getOldMailIcon(); + noConnIcon = setup_->getNoConnIcon(); + stoppedIcon = setup_->getStoppedIcon(); + + // New mail + systemBeep = setup_->getSystemBeep(); + runCommand = setup_->getRunCommand(); + runCommandPath = setup_->getRunCommandPath(); + runResetCommand = setup_->getRunResetCommand(); + runResetCommandPath = setup_->getRunResetCommandPath(); + playSound = setup_->getPlaySound(); + playSoundPath = setup_->getPlaySoundPath(); + notify = setup_->getNotify(); + dostatus = setup_->getStatus(); + + // if we aren't going the status route, we should at least + // provide a tooltip! + if (dostatus == false) + QToolTip::add(this, profile); + else + QToolTip::remove(this); + + // set all the new mailboxes + setMailboxList(setup_->getMailboxList(), setup_->getPoll()); + + // change the dock state if necessary + if (docked != setup_->getDock()) + dock(); + + if (run_ && !skipcheck) + start(); + skipcheck = false; + + // handle session management disabling + if (sessions == false) + { + disconnect(this, SLOT(saveYourself())); + kapp->disableSessionManagement(); + } + + // if we are going to be doing status, we might as well create + // one now + if ( dostatus ) + { + statusList.clear(); + KBiffMonitor *monitor; + for (monitor = monitorList.first(); monitor; monitor = monitorList.next()) + { + statusList.append(new KBiffStatusItem(monitor->getMailboxKey(), + monitor->newMessages(), + monitor->curMessages())); + } + if (status) + { + status->hide(); + delete status; + status = 0; + } + status = new KBiffStatus(this, profile, statusList); + } + + delete setup_; +} + +void KBiff::setMailboxList(const QList<KBiffMailbox>& mailbox_list, unsigned int poll) +{ + QList<KBiffMailbox> tmp_list = mailbox_list; + + myMUTEX = true; + if (isRunning()) + stop(); + monitorList.clear(); + + KBiffMailbox *mbox; + for (mbox = tmp_list.first(); mbox != 0; mbox = tmp_list.next()) + { + KBiffURL *url = &(mbox->url); + KBiffMonitor *monitor = new KBiffMonitor(); + monitor->setMailbox(*url); + monitor->setPollInterval(poll); + monitor->setMailboxKey(mbox->key); + connect(monitor, SIGNAL(signal_newMail(const int, const QString&)), + this, SLOT(haveNewMail(const int, const QString&))); + connect(monitor, SIGNAL(signal_currentStatus(const int, const QString&, const KBiffMailState)), + this, SLOT(currentStatus(const int, const QString&, const KBiffMailState))); + connect(monitor, SIGNAL(signal_noMail()), this, SLOT(displayPixmap())); + connect(monitor, SIGNAL(signal_noMail()), + this, SLOT(haveNoNewMail())); + connect(monitor, SIGNAL(signal_oldMail()), this, SLOT(displayPixmap())); + connect(monitor, SIGNAL(signal_oldMail()), + this, SLOT(haveNoNewMail())); + connect(monitor, SIGNAL(signal_noConn()), this, SLOT(displayPixmap())); + connect(monitor, SIGNAL(signal_noConn()), + this, SLOT(haveNoNewMail())); + connect(monitor, SIGNAL(signal_invalidLogin(const QString&)), + this, SLOT(invalidLogin(const QString&))); + connect(monitor, SIGNAL(signal_fetchMail(const QString&)), + this, SLOT(slotLaunchFetchClient(const QString&))); + monitorList.append(monitor); + } + myMUTEX = false; +} + +bool KBiff::isDocked() const +{ + return docked; +} + +void KBiff::readSessionConfig() +{ + KConfig *config = kapp->sessionConfig(); + + config->setGroup("KBiff"); + + profile = config->readEntry("Profile", "Inbox"); + docked = config->readBoolEntry("IsDocked", false); + bool run = config->readBoolEntry("IsRunning", true); + + KBiffSetup *setup_dlg = new KBiffSetup(profile); + processSetup(setup_dlg, run); +} + +/////////////////////////////////////////////////////////////////////////// +// Protected Virtuals +/////////////////////////////////////////////////////////////////////////// +void KBiff::mousePressEvent(QMouseEvent *e) +{ + // regardless of which button, get rid of the status box + if (status) + status->hide(); + + // also, ditch the timer + if (statusTimer) + { + statusTimer->stop(); + delete statusTimer; + statusTimer = 0; + } + + // check if this is a right click + if(e->button() == RightButton) + { + // popup the context menu + popupMenu(); + } + else + { + // execute the command + slotLaunchMailClient(); + + readPop3MailNow(); + } +} + +void KBiff::enterEvent(QEvent *e) +{ + QLabel::enterEvent(e); + + // return now if the user doesn't want this feature. + // *sniff*.. the ingrate.. I worked so hard on this, too... *sob* + if (dostatus == false) + return; + + // don't do anything if we already have a timer + if (statusTimer) + return; + + // popup the status in one second + statusTimer = new QTimer(this); + connect(statusTimer, SIGNAL(timeout()), this, SLOT(popupStatus())); + + statusTimer->start(1000, true); +} + +void KBiff::leaveEvent(QEvent *e) +{ + QLabel::leaveEvent(e); + + // stop the timer if it is going + if (statusTimer) + { + statusTimer->stop(); + delete statusTimer; + statusTimer = 0; + } + + // get rid of the status box if it is activated + if (status) + status->hide(); +} + +void KBiff::popupStatus() +{ + // if we don't get rid of the timer, then the very next + // time we float over the icon, the status box will + // *not* be activated! + if (statusTimer) + { + statusTimer->stop(); + delete statusTimer; + statusTimer = 0; + } + + if (statusChanged) + { + statusList.clear(); + KBiffMonitor *monitor; + for(monitor = monitorList.first(); monitor; monitor = monitorList.next()) + { + statusList.append(new KBiffStatusItem(monitor->getMailboxKey(), monitor->newMessages(), monitor->curMessages())); + } + statusChanged = false; + } + + status->updateListView(statusList); + status->popup(QCursor::pos()); +} + +bool KBiff::isGIF8x(const QString& file_name) +{ + + /* The first test checks if we can open the file */ + QFile gif8x(file_name); + if (gif8x.open(IO_ReadOnly) == false) + return false; + + /** + * The GIF89 format specifies that the first five bytes of + * the file shall have the characters 'G' 'I' 'F' '8' '9'. + * The GIF87a format specifies that the first six bytes + * shall read 'G' 'I' 'F' '8' '7' 'a'. Knowing that, we + * shall read in the first six bytes and test away. + */ + char header[6]; + int bytes_read = gif8x.readBlock(header, 6); + + /* Close the file just to be nice */ + gif8x.close(); + + /* If we read less than 6 bytes, then its definitely not GIF8x */ + if (bytes_read < 6) + return false; + + /* Now test for the magical GIF8(9|7a) */ + if (header[0] == 'G' && + header[1] == 'I' && + header[2] == 'F' && + header[3] == '8' && + (header[4] == '9' || (header[4] == '7' && + header[5] == 'a'))) + { + /* Success! */ + return true; + } + + /* Apparently not GIF8(9|7a) */ + return false; +} + +/////////////////////////////////////////////////////////////////////////// +// Protected Slots +/////////////////////////////////////////////////////////////////////////// +void KBiff::saveYourself() +{ + if (sessions) + { + KConfig *config = kapp->sessionConfig(); + config->setGroup("KBiff"); + + config->writeEntry("Profile", profile); + config->writeEntry("IsDocked", docked); + config->writeEntry("IsRunning", isRunning()); + + config->sync(); + + } +} + +void KBiff::invokeHelp() +{ + kapp->invokeHelp(); +} + +void KBiff::displayPixmap() +{ + if (myMUTEX) + return; + + // we will try to deduce the pixmap (or gif) name now. it will + // vary depending on the dock and mail state + QString pixmap_name; + bool has_new = false, has_old = false, has_no = true, has_noconn = false; + KBiffMonitor *monitor; + for (monitor = monitorList.first(); + monitor != 0 && has_new == false; + monitor = monitorList.next()) + { + switch (monitor->getMailState()) + { + case NoMail: + has_no = true; + break; + case NewMail: + has_new = true; + break; + case OldMail: + has_old = true; + break; + case NoConn: + has_noconn = true; + break; + default: + has_no = true; + break; + } + } + + if ( !isRunning() ) + { + pixmap_name = stoppedIcon; + mled->Off(); + } + else if (has_new) + { + pixmap_name = newMailIcon; + // turn on led for new mail, otherwise turn off + mled->On(); + } + else if (has_old) + { + pixmap_name = oldMailIcon; + mled->Off(); + } + else if (has_noconn) + { + pixmap_name = noConnIcon; + mled->Off(); + } + else + { + pixmap_name = noMailIcon; + mled->Off(); + } + + if (docked) + { + // we need to check if this has path info encoded into it + QFileInfo info(pixmap_name); + + // if info.fileName() returns pixmap_name, then we no there + // isn't any paths attached and we can just prepend our 'mini' + if (info.fileName() == pixmap_name) + pixmap_name.prepend("mini-"); + else + { + // so we have some path junk on it. we get the filename + // by itself, prepend our 'mini' and tack it onto the end + // of the original dirpath. simple + QString filename(info.fileName()); + filename.prepend("mini-"); + + // we aren't guaranteed that the dirpath will end in a / + // so we add one (an extra one won't hurt, in any case + pixmap_name = info.dirPath() + "/" + filename; + } + } + QString filename = KGlobal::iconLoader()->iconPath( pixmap_name, KIcon::User ); + QFileInfo file(filename); + + // at this point, we have the file to display. so display it + if (isGIF8x(file.absFilePath())) + setMovie(QMovie(file.absFilePath())); + else + setPixmap(QPixmap(file.absFilePath())); + adjustSize(); +} + +void KBiff::currentStatus(const int num, const QString& the_mailbox, const KBiffMailState the_state) +{ + statusChanged = true; + // iterate through all saved notify dialogs to see if "our" one is + // currently being displayed + KBiffNotify *notifyptr; + for (notifyptr = notifyList.first(); + notifyptr != 0; + notifyptr = notifyList.next()) + { + // if this one is not visible, delete it from the list. the only + // way it will again become visible is if the haveNewMail slot + // gets triggered + if (notifyptr->isVisible() == false) + { + notifyList.remove(); + } + else + { + // if this box is visible (active), we see if it is the one + // we are looking for + if (notifyptr->getMailbox() == the_mailbox) + { + // yep. now, if there is new mail, we set the new number in + // the dialog. if it is any other state, we remove this + // dialog from the list + switch (the_state) + { + case NewMail: + notifyptr->setNew(num); + break; + case OldMail: + case NoMail: + case NoConn: + default: + notifyList.remove(); + break; + } + } + } + } +} + +void KBiff::haveNewMail(const int num, const QString& the_mailbox) +{ + displayPixmap(); + + // beep if we are allowed to + if (systemBeep) + { + kapp->beep(); + } + + // run a command if we have to + if (runCommand) + { + // make sure the command exists + if (!runCommandPath.isEmpty()) + { + executeCommand(replaceCommandArgs(runCommandPath)); + } + } + + // play a sound if we have to + if (playSound) + slotPlaySound(playSoundPath); + + // notify if we must + if (notify) + { + KBiffNotify *notify_dlg = new KBiffNotify(this, num, the_mailbox); + connect(notify_dlg, SIGNAL(signalLaunchMailClient()), + this, SLOT(slotLaunchMailClient())); + notifyList.append(notify_dlg); + notify_dlg->show(); + + // half-hearted attempt to center this + int x_pos = (KApplication::desktop()->width() - notify_dlg->width()) / 2; + int y_pos = (KApplication::desktop()->height() - notify_dlg->height()) / 2; + notify_dlg->move(x_pos, y_pos); + } +} + +void KBiff::haveNoNewMail() +{ + displayPixmap(); + + // run a command if we have to + if (runResetCommand) + { + // make sure the command exists + if (!runResetCommandPath.isEmpty()) + { + executeCommand(runResetCommandPath); + } + } +} + +QString KBiff::getURLWithNewMail() +{ + KBiffMonitor *monitor; + for (monitor = monitorList.first(); + monitor != 0; + monitor = monitorList.next()) + { + if(monitor->getMailState() == NewMail) + return monitor->getMailbox(); + } + + return monitorList.first()->getMailbox(); +} + +QString KBiff::getMailBoxWithNewMail() +{ + QString url(getURLWithNewMail()); + + int slashPos = url.find('/'); + if(slashPos == -1) + return url.mid(slashPos + 1); + else + return url.mid(url.find(':') + 1); +} + +QString KBiff::replaceCommandArgs(QString cmdStr) +{ + bool expand = false; + for(unsigned int i = 0; i < cmdStr.length(); i++) + { + if(expand) + { + expand = false; + if(cmdStr[i] == 'm') + cmdStr.replace(i - 1, 2, getMailBoxWithNewMail()); + else if(cmdStr[i] == 'u') + cmdStr.replace(i - 1, 2, getURLWithNewMail()); + else if(cmdStr[i] == '%') + cmdStr.replace(i - 1, 2, "%"); + + continue; + } + + if(cmdStr[i] == '%') + expand = true; + } + + return cmdStr; +} + +void KBiff::dock() +{ + // destroy the old window + if (this->isVisible()) + { + this->hide(); + this->destroy(true, true); + this->create(0, true, false); + kapp->setMainWidget(this); + + // we don't want a "real" top widget if we are _going_ to + // be docked. + if (docked) + kapp->setTopWidget(this); + else + kapp->setTopWidget(new QWidget); + } + + if (docked == false) + { + docked = true; + + // enable docking + KWin::setSystemTrayWindowFor(this->winId(), 0); + } + else + docked = false; + + // (un)dock it! + this->show(); + QTimer::singleShot(1000, this, SLOT(displayPixmap())); +} + +void KBiff::setup() +{ + KBiffSetup* setup_dlg = new KBiffSetup(profile); + + if (setup_dlg->exec()) + processSetup(setup_dlg, true); + else + delete setup_dlg; +} + +void KBiff::checkMailNow() +{ + KBiffMonitor *monitor; + for (monitor = monitorList.first(); + monitor != 0; + monitor = monitorList.next()) + { + monitor->checkMailNow(); + } +} + +void KBiff::readMailNow() +{ + KBiffMonitor *monitor; + for (monitor = monitorList.first(); + monitor != 0; + monitor = monitorList.next()) + { + monitor->setMailboxIsRead(); + } +} + +void KBiff::readPop3MailNow() +{ + KBiffMonitor *monitor; + for (monitor = monitorList.first(); + monitor != 0; + monitor = monitorList.next()) + { + if (monitor->getProtocol() == "pop3") + monitor->setMailboxIsRead(); + } +} + +void KBiff::stop() +{ + KBiffMonitor *monitor; + for (monitor = monitorList.first(); + monitor != 0; + monitor = monitorList.next()) + { + monitor->stop(); + } + displayPixmap(); +} + +void KBiff::start() +{ + myMUTEX = true; + KBiffMonitor *monitor; + for (unsigned int i = 0; i < monitorList.count(); i++) + { + monitor = monitorList.at(i); + monitor->start(); + } + myMUTEX = false; + displayPixmap(); +} + +/////////////////////////////////////////////////////////////////////////// +// Protected Functions +/////////////////////////////////////////////////////////////////////////// +void KBiff::popupMenu() +{ + KPopupMenu *popup = new KPopupMenu(0, "popup"); + popup->insertTitle(kapp->miniIcon(), profile); + + // if secure, disable everything but exit + if (isSecure == false) + { + if (docked) + popup->insertItem(i18n("&UnDock"), this, SLOT(dock())); + else + popup->insertItem(i18n("&Dock"), this, SLOT(dock())); + popup->insertItem(i18n("&Setup..."), this, SLOT(setup())); + popup->insertSeparator(); + popup->insertItem(i18n("&Help..."), this, SLOT(invokeHelp())); + popup->insertSeparator(); + + int check_id; + check_id = popup->insertItem(i18n("&Check Mail Now"), this, SLOT(checkMailNow())); + int read_id; + read_id = popup->insertItem(i18n("&Read Mail Now"), this, SLOT(readMailNow())); + + if (isRunning()) + { + popup->setItemEnabled(check_id, true); + popup->setItemEnabled(read_id, true); + popup->insertItem(i18n("&Stop"), this, SLOT(stop())); + } + else + { + popup->setItemEnabled(check_id, false); + popup->setItemEnabled(read_id, false); + popup->insertItem(i18n("&Start"), this, SLOT(start())); + } + popup->insertSeparator(); + } + + popup->insertItem(i18n("E&xit"), kapp, SLOT(quit())); + + popup->popup(QCursor::pos()); +} + +void KBiff::reset() +{ + // reset all the member variables + systemBeep = true; + runCommand = false; + runCommandPath = ""; + playSound = false; + playSoundPath = ""; + notify = true; + dostatus = true; + + noMailIcon = "nomail"; + newMailIcon = "newmail"; + oldMailIcon = "oldmail"; + noConnIcon = "noconn"; + stoppedIcon = "stopped"; + + docked = false; + isSecure = false; + + mailClient = "xmutt -f +%m"; + + myMUTEX = false; +} + +bool KBiff::isRunning() +{ + bool is_running = false; + KBiffMonitor *monitor; + for (monitor = monitorList.first(); + monitor != 0; + monitor = monitorList.next()) + { + if (monitor->isRunning()) + { + is_running = true; + break; + } + } + return is_running; +} + +void KBiff::executeCommand(const QString& command) +{ + KRun::runCommand(command); +} + +void KBiff::slotLaunchFetchClient(const QString& fetchClient) +{ + if (!fetchClient.isEmpty()) + executeCommand(fetchClient); +} + +void KBiff::slotLaunchMailClient() +{ + if (!mailClient.isEmpty()) + executeCommand(replaceCommandArgs(mailClient)); +} + +void KBiff::slotPlaySound(const QString& play_sound) +{ + // make sure something is specified + if (!play_sound.isNull()) + KAudioPlayer::play(play_sound); +} + +bool KBiff::process(const QCString&, const QCString& function, + const QByteArray& data, QCString& replyType, + QByteArray &replyData) +{ + QDataStream args(data, IO_ReadOnly); + QDataStream reply(replyData, IO_WriteOnly); + QString proxy; + if (function == "proxyRegister(QString)") + { + args >> proxy; + proxyList.append(proxy); + replyType = "void"; + return true; + } + + else if (function == "proxyDeregister(QString)") + { + args >> proxy; + proxyList.remove(proxy); + replyType = "void"; + return true; + } + + else if (function == "hasMailbox(QString)") + { + QString mailbox; + args >> mailbox; + + reply << (bool) findMailbox(mailbox, proxy); + replyType = "bool"; + return true; + } + + else if (function == "mailCount(QString)") + { + reply << -1; + replyType = "int"; + return true; + } + + else if (function == "newMailCount(QString)") + { + QString mailbox; + args >> mailbox; + + reply << newMailCount(mailbox); + replyType = "int"; + return true; + } + + + return false; +} + +int KBiff::newMailCount(const QString& url) +{ + int newmail = -1; + + QString proxy; + if (findMailbox(url, proxy) == true) + { + if (proxy != QString::null) + { + QByteArray data; + QDataStream ds(data, IO_WriteOnly); + ds << url; + + QByteArray reply_data; + QCString reply_type; + QDataStream reply(reply_data, IO_ReadOnly); + + DCOPClient *dcc = kapp->dcopClient(); + if (dcc->call(proxy.ascii(), "kbiff", + "newMailCount(QString)", data, reply_type, + reply_data) == true) + { + reply >> newmail; + } + } + else + { + KBiffMonitor *monitor; + for(monitor = monitorList.first(); monitor; + monitor = monitorList.next()) + { + if (monitor->getMailbox() == url) + { + newmail = monitor->newMessages(); + break; + } + } + } + } + + return newmail; +} + +bool KBiff::findMailbox(const QString& url, QString& proxy) +{ + bool has_mailbox = false; + KBiffMonitor *monitor; + for(monitor = monitorList.first(); monitor; monitor = monitorList.next()) + { + if (monitor->getMailbox() == url) + { + has_mailbox = true; + break; + } + } + if (has_mailbox == false) + { + QByteArray data, replyData; + QCString replyType; + QDataStream ds(data, IO_WriteOnly); + ds << url; + // okay, now try to iterate through our proxies + QStringList::Iterator it = proxyList.begin(); + for ( ; it != proxyList.end(); it++) + { + DCOPClient *dcc = kapp->dcopClient(); + if (dcc->call(QCString((*it).ascii()), "kbiff", + "hasMailbox(QString)", data, replyType, + replyData) == true) + { + has_mailbox = true; + proxy = *it; + break; + } + } + } + + return has_mailbox; +} + +void KBiff::registerMe(DCOPClient *client) +{ + // we need to attach our client before doing anything + client->attach(); + + // if we aren't registered yet, then we will do so.. and be + // responsible for all *other* kbiff requests, too! + if (client->isApplicationRegistered("kbiff") == false) + client->registerAs("kbiff"); + else + { + // okay, there is a running kbiff already. we will let it + // know that we are active and let it feed us requests + QCString proxy = QCString("kbiff-") + QCString().setNum(getpid()); + QByteArray params, reply; + QCString reply_type; + QDataStream ds(params, IO_WriteOnly); + ds << proxy; + client->send("kbiff", "kbiff", "proxyRegister(QString)", params); + client->registerAs(QCString(proxy)); + } +} + +void KBiff::invalidLogin(const QString& mailbox) +{ + QString title(i18n("Invalid Login to %1").arg(mailbox)); + KMessageBox::sorry(0, + i18n("I was not able to login to the remote server.\n" + "This means that either the server is down or you have " + "entered an incorrect username or password.\n" + "Please make sure that you have entered the correct settings."), + title); +} diff --git a/kbiff/kbiff.desktop b/kbiff/kbiff.desktop new file mode 100644 index 0000000..62a35db --- /dev/null +++ b/kbiff/kbiff.desktop @@ -0,0 +1,75 @@ +[Desktop Entry] +Name=Email Monitor (KBiff) +Name[ca]=Notificador de correu +Name[cs]=Kontrola příchodu nové pošty +Name[da]=E-post alarm (biff) +Name[de]=E-Mail-Benachrichtigung (biff) +Name[el]=Ειδοποίηση email (biff) +Name[eo]=Retpoŝtanoncilo (biff) +Name[es]=Notificador de correo electrónico (biff) +Name[et]=Uutest meilidest teataja (biff) +Name[fi]=Sähköpostimuistuttaja (biff) +Name[fr]=Avis d'arrivée de courrier électronique +Name[gl]=Notificador de correo (biff) +Name[he]=(biff) שדח ראוד גצ +Name[hu]=E-mail figyelmeztető (biff) +Name[is]=Tilkynning tölvupósts (biff) +Name[it]=Notificatore di posta (biff) +Name[ja]=Email受信を検出(biff) +Name[mk]=Известувач за нова е-пошта +Name[nl]=E-mail-notificatie (biff) +Name[no]=Epost-varsler (biff) +Name[no_NY]=E-postpåminning (biff) +Name[pl]=Powiadamianie o nadejściu E-maila (biff) +Name[pt]=Aviso de Correio Electrónico +Name[pt_BR]=Notificador de novos e-mails +Name[ro]=Notificare e-mail +Name[ru]=Сообщение о Email (biff) +Name[sk]=Kontrola došlej pošty (biff) +Name[sl]=Indikator e-pošte (biff) +Name[sr]=Email obaveštavač (biff) +Name[sv]=E-postsignalerare (biff) +Name[ta]=Á¢ý«ïºø «È¢Å¢ôÀ¡Ç÷ (biff) +Name[tr]=E-Posta Bildiricisi (biff) +Name[uk]=Сповіщувач електронної пошти (biff) +Name[zh_CN.GB2312]=Email 通知(biff) +Exec=kbiff %i %m +Icon=kbiff +Type=Application +DocPath=kbiff/index.html +Comment=Mail notification utility +Comment[ca]=Utilitat de notificació de correu +Comment[cs]=Pomůcka upozorňující na novou poštu +Comment[da]=Giver besked om ny e-post +Comment[de]=Benachrichtigung bei neuen Mails +Comment[el]=Ειδοποιεί όταν έχετε νέο μύνημα +Comment[eo]=Informas pri nova retpoŝto +Comment[es]=Utilidad de notificación de correo +Comment[et]=Rakendus, mis teatab uutest saabunud meilidest +Comment[fi]=Postin saapumisesta ilmoittava ohjelma +Comment[fr]=Utilitaire d'avis d'arrivée de courrier électronique (biff) +Comment[gl]=Utilidade de notificación de correo +Comment[he]=שדח ראוד לע העדוהל רזע +Comment[hr]=Obavijest o novim porukama +Comment[hu]=Üzenet érkezésére figyelmeztető program +Comment[is]=kbiff: Fygjast með hvenær nýr póstur berst +Comment[it]=Notifica l'arrivo della posta elettronica +Comment[ja]=メールモニター +Comment[mk]=Известувач за нова е-пошта +Comment[nl]=Notificatie bij nieuwe berichten +Comment[no]=Gir beskjed når nye eposter ankommer +Comment[no_NY]=Gir beskjed når du får ny e-post +Comment[pl]=Powiadomienie o nowej poczcie +Comment[pt]=Utilitário de aviso de novo correio +Comment[pt_BR]=Utilitário de notificação de correio +Comment[ro]=Vă anunţă cînd vine un e-mail nou +Comment[ru]=Утилита оповещения о почте +Comment[sk]=Pomôcka, ktorá informuje o novej pošte +Comment[sl]=Obvestila o prispeli pošti +Comment[sr]=Program za obaveštavanje o pristigloj e-pošti +Comment[sv]=Verktyg som uppmärksammar dig när du fått ny post +Comment[ta]=«ïºø «È¢Å¢ôÒ ÀÂýÀ¡Î +Comment[tr]=Posta bildirim yardımcısı +Comment[uk]=Утіліта сповіщування про надходження пошти +Comment[zh_CN.GB2312]=邮件通知工具 +Terminal=0 diff --git a/kbiff/kbiff.h b/kbiff/kbiff.h new file mode 100644 index 0000000..b76fad6 --- /dev/null +++ b/kbiff/kbiff.h @@ -0,0 +1,140 @@ +/* + * kbiff.h + * Copyright (C) 1999-2004 Kurt Granroth <granroth@kde.org> + * + * This file contains the declaration of the main KBiff + * widget. + * + * $Id$ + */ +#ifndef KBIFF_H +#define KBIFF_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qlist.h> + +#include <kbiffmonitor.h> +#include <setupdlg.h> + +#include <kbiffurl.h> +#include <kapp.h> + +#include <qlabel.h> +#include <qtimer.h> + +#include <notify.h> +#include <status.h> + +#include <dcopclient.h> +#include <dcopobject.h> + +class Led; + +class KBiff : public QLabel, virtual public DCOPObjectProxy +{ + Q_OBJECT +public: + KBiff(DCOPClient *client_, QWidget *parent_ = 0); + virtual ~KBiff(); + + bool isDocked() const; + + void processSetup(const KBiffSetup* setup, bool start); + void readSessionConfig(); + + void setMailboxList(const QList<KBiffMailbox>& mailbox_list, unsigned int poll = 60); + + virtual bool process(const QCString& obj, const QCString& function, + const QByteArray& data, QCString& replyType, + QByteArray &replyData ); + +public slots: + void slotPlaySound(const QString&); + void slotLaunchFetchClient(const QString&); + void slotLaunchMailClient(); + +protected: + void mousePressEvent(QMouseEvent *); + void enterEvent(QEvent *); + void leaveEvent(QEvent *); + +protected: + void popupMenu(); + void reset(); + bool isRunning(); + bool isGIF8x(const QString & file); + void executeCommand(const QString& command); + void registerMe(DCOPClient *client); + +protected slots: + void saveYourself(); + void invokeHelp(); + void displayPixmap(); + void haveNewMail(const int, const QString &); + void haveNoNewMail(); + void currentStatus(const int, const QString &, const KBiffMailState); + void dock(); + void setup(); + void checkMailNow(); + void readMailNow(); + void readPop3MailNow(); + void stop(); + void start(); + void popupStatus(); + void invalidLogin(const QString& mailbox); + +private: + bool findMailbox(const QString& url, QString& proxy); + int newMailCount(const QString& url); + + QString getURLWithNewMail(); + QString getMailBoxWithNewMail(); + QString replaceCommandArgs(QString cmdStr); + +protected: + bool myMUTEX; + QList<KBiffMonitor> monitorList; + QList<KBiffNotify> notifyList; + KBiffStatusList statusList; + QStringList proxyList; + + // Capability + QTimer *statusTimer; + + // General settings + QString profile; + QString mailClient; + + // New mail + bool systemBeep; + bool runCommand; + QString runCommandPath; + bool runResetCommand; + QString runResetCommandPath; + bool playSound; + QString playSoundPath; + bool notify; + bool dostatus; + + bool docked; + bool sessions; + bool skipcheck; + + bool isSecure; + + QString noMailIcon; + QString newMailIcon; + QString oldMailIcon; + QString noConnIcon; + QString stoppedIcon; + + KBiffStatus *status; + bool statusChanged; + + Led *mled; +}; + +#endif // KBIFF_H diff --git a/kbiff/kbiffcodec.cpp b/kbiff/kbiffcodec.cpp new file mode 100644 index 0000000..c69525d --- /dev/null +++ b/kbiff/kbiffcodec.cpp @@ -0,0 +1,243 @@ +/* + This is taken from kdmcodec.h from kdelibs/kdecore in KDE 2.2 + ------------------------------------------------------------- + + Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org> + Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org> + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License (LGPL) as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This KMD5 class is based upon a C++ implementation of "RSA + Data Security, Inc. MD5 Message-Digest Algorithm" by Mordechai + T. Abzug, Copyright (c) 1995. This implementation passes the + test-suite supplied with RFC 1321. + + RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992, + RSA Data Security, Inc. Created 1991. All rights reserved. + + The encoding and decoding utilities in KBiffCodecs with the exception of + quoted-printable were ported from the HTTPClient java package by Ronald + Tschalär Copyright (C) 1996-1999. The quoted-printable codec as described + in RFC 2045, section 6.7. is by Rik Hemsley (C) 2001. +*/ + +#include <string.h> + +#include "kbiffcodec.h" + +class CodecPrivate +{ +public: + static char Base64EncMap[64]; + static char Base64DecMap[128]; + +static void base64Encode( const QByteArray& in, QByteArray& out) +{ + bool insertLFs(false); + + // clear out the output buffer + out.resize( 0 ); + if ( in.isEmpty() ) + return; + + unsigned int sidx = 0, didx = 0; + const char* buf = in.data(); + const unsigned int len = in.size(); + + unsigned int out_len = ((len+2)/3)*4; + + // Deal with the 76 characters or less per + // line limit specified in RFC 2045 on a + // pre request basis. + insertLFs = (insertLFs && out_len > 76); + if ( insertLFs ) + out_len += (out_len/76); + + int count = 0; + out.resize( out_len ); + + // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion + if ( len > 1 ) + { + while (sidx < len-2) + { + if ( insertLFs ) + { + if ( count && (count%76) == 0 ) + out[didx++] = '\n'; + count += 4; + } + out[didx++] = Base64EncMap[(buf[sidx] >> 2) & 077]; + out[didx++] = Base64EncMap[((buf[sidx+1] >> 4) & 017) | ((buf[sidx] << 4) & 077)]; + out[didx++] = Base64EncMap[((buf[sidx+2] >> 6) & 003) | ((buf[sidx+1] << 2) & 077)]; + out[didx++] = Base64EncMap[buf[sidx+2] & 077]; + sidx += 3; + } + } + + if (sidx < len) + { + out[didx++] = Base64EncMap[(buf[sidx] >> 2) & 077]; + if (sidx < len-1) + { + out[didx++] = Base64EncMap[((buf[sidx+1] >> 4) & 017) | ((buf[sidx] << 4) & 077)]; + out[didx++] = Base64EncMap[(buf[sidx+1] << 2) & 077]; + } + else + { + out[didx++] = Base64EncMap[(buf[sidx] << 4) & 077]; + } + } + + // Add padding + while (didx < out.size()) + { + out[didx] = '='; + didx++; + } +} + +static void base64Decode( const QByteArray& in, QByteArray& out ) +{ + out.resize(0); + if ( in.isEmpty() ) + return; + + unsigned int count = 0; + unsigned int len = in.size(), tail = len; + const char* in_buf = in.data(); + + // Deal with possible *nix "BEGIN" marker!! + while ( count < len && (in_buf[count] == '\n' || in_buf[count] == '\r' || + in_buf[count] == '\t' || in_buf[count] == ' ') ) + count++; + + if ( strncasecmp(in_buf, "begin", 5) == 0 ) + { + count += 5; + while ( count < len && in_buf[count] != '\n' && in_buf[count] != '\r' ) + count++; + in_buf += (++count); + tail = (len -= count); + } + + // Find the tail end of the actual encoded data even if + // there is/are trailing CR and/or LF. + while ( in_buf[tail-1] == '=' || in_buf[tail-1] == '\n' || + in_buf[tail-1] == '\r' ) + if ( in_buf[--tail] != '=' ) len = tail; + + unsigned int outIdx = 0; + out.resize( (count=len) ); + for (unsigned int idx = 0; idx < count; idx++) + { + // Adhere to RFC 2045 and ignore characters + // that are not part of the encoding table. + char ch = in_buf[idx]; + if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) || + (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=') + { + out[outIdx++] = Base64DecMap[(int)ch]; + } + else + { + len--; + tail--; + } + } + + // 4-byte to 3-byte conversion + len = (tail>(len/4)) ? tail-(len/4) : 0; + unsigned int sidx = 0, didx = 0; + if ( len > 1 ) + { + while (didx < len-2) + { + out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003)); + out[didx+1] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017)); + out[didx+2] = (((out[sidx+2] << 6) & 255) | (out[sidx+3] & 077)); + sidx += 4; + didx += 3; + } + } + + if (didx < len) + out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003)); + + if (++didx < len ) + out[didx] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017)); + + // Resize the output buffer + if ( len == 0 || len < out.size() ) + out.resize(len); +} +}; + +// static constants for base64 +char CodecPrivate::Base64EncMap[64] = { + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, + 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, + 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F + }; + +char CodecPrivate::Base64DecMap[128] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + +/***************************************************************************/ +QString KBiffCodecs::base64Encode( const QString& str ) +{ + if ( str.isEmpty() ) + return QString::fromLatin1(""); + QByteArray in, out; + const unsigned int len = str.length(); + in.resize( len ); + memcpy( in.data(), str.latin1(), len ); + CodecPrivate::base64Encode( in, out ); + return QString( out ); +} + +QString KBiffCodecs::base64Decode( const QString& str ) +{ + if ( str.isEmpty() ) + return QString::fromLatin1(""); + + QByteArray in, out; + const unsigned int len = str.length(); + in.resize( str.length() ); + memcpy( in.data(), str.latin1(), len ); + CodecPrivate::base64Decode( in, out ); + return QString( out ); +} diff --git a/kbiff/kbiffcodec.h b/kbiff/kbiffcodec.h new file mode 100644 index 0000000..3643618 --- /dev/null +++ b/kbiff/kbiffcodec.h @@ -0,0 +1,66 @@ +/* + This is taken from kdmcodec.h from kdelibs/kdecore in KDE 2.2 + ------------------------------------------------------------- + + Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org> + Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This KMD5 class is based on a C++ implementation of + "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by + Mordechai T. Abzug, Copyright (c) 1995. This implementation + passes the test-suite as defined by RFC 1321. + + RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992. + RSA Data Security, Inc. Created 1991. All rights reserved. + + The encoding and decoding utilities in KCodecs with the exception of + quoted-printable were ported from the HTTPClient java package by Ronald + Tschalr Copyright (C) 1996-1999. The quoted-printable codec as described + in RFC 2045, section 6.7. is by Rik Hemsley (C) 2001. +*/ + +#ifndef _KBIFFCODEC_H +#define _KBIFFCODEC_H + +#include <qstring.h> + +class KBiffCodecs +{ +public: + + /** + * Encodes the given string using the base64 algorithm. + * + * @param str the string to be encoded. + * @return the decoded string. + */ + static QString base64Encode( const QString& str ); + + /** + * Decodes the given data that was encoded using the + * base64 algorithm. + * + * @param in the base64-encoded data to be decoded. + * @return the decoded data. + */ + static QString base64Decode( const QString& in ); + +private: + KBiffCodecs(); +}; + +#endif diff --git a/kbiff/kbiffcrypt.cpp b/kbiff/kbiffcrypt.cpp new file mode 100644 index 0000000..66ce0b0 --- /dev/null +++ b/kbiff/kbiffcrypt.cpp @@ -0,0 +1,72 @@ +/* + * kbiffcrypt.cpp + * Copyright (C) 2005 Michael Hendricks <michael@palmcluster.org> + * + * This file contains the implementation of the functions in + * the KBiffCrypt namespace. + * + * $Id$ + */ +#include "kbiffcrypt.h" + +#include <kmdcodec.h> +#include <qcstring.h> + +QString KBiffCrypt::hmac_md5(const QString& text, const QString& k) +{ + // If the original key is too long, the new key will be a hash of + // the original key. Then the new key might have NULL bytes in it, + // so we can't use QCString + QByteArray key = (QByteArray)k.utf8(); + + KMD5 context; // for calculating MD5 sums + KMD5::Digest digest; // intermediate storage for MD5 sums + + // inner and outer padding (key XORd with ipad and opad, respectively) + QByteArray k_ipad(64); + QByteArray k_opad(64); + + + // if key is longer than 64 bytes reset it to key=MD5(key) + if (key.size() > 64) { + // cast to a QCString because we don't want to hash the + // trailing NULL byte + KMD5 tctx((QCString)key); + + key.duplicate((char*)tctx.rawDigest(), 16); + } + + /* the HMAC-MD5 transform looks like this: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * text is the data being protected + */ + + // XOR key with ipad and opad values, copying + // the pad values after the key's end + for (unsigned int i=0; i<64; i++) { + if( i < key.size() ) { + k_ipad[i] = key[i] ^ 0x36; + k_opad[i] = key[i] ^ 0x5c; + } else { + k_ipad[i] = 0x36; + k_opad[i] = 0x5c; + } + } + + // perform inner MD5 + context.reset(); // init context for 1st pass + context.update(k_ipad); // start with inner pad + context.update(text.utf8()); // then text of datagram + context.rawDigest(digest); // finish up 1st pass + + // perform outer MD5 + context.reset(); // init context for 2nd pass + context.update(k_opad); // start with outer pad + context.update(digest, 16); // then results of 1st hash + return context.hexDigest(); // finish up 2nd pass and return +} diff --git a/kbiff/kbiffcrypt.h b/kbiff/kbiffcrypt.h new file mode 100644 index 0000000..137817e --- /dev/null +++ b/kbiff/kbiffcrypt.h @@ -0,0 +1,49 @@ +/* + * kbiffcrypt.h + * Copyright (C) 2005 Michael Hendricks <michael@palmcluster.org> + * + * $Id$ + * + */ +#ifndef KBIFFCRYPT_H +#define KBIFFCRYPT_H + +#include <qstring.h> + +/** + * @brief Useful cryptographic functions for secure authentication + * + * Until QCA + * (<a href='http://delta.affinix.com/qca/'>Qt Cryptographic Architecture</a>) + * becomes more widely available, + * this will be the place for our custom-written, cryptography functions. + * These are mostly needed to implement various forms of secure authentication + * against POP3 or IMAP mail servers. + */ +namespace KBiffCrypt +{ + /** + * @brief Calculate HMAC-MD5 of the given text + * + * Calculates the HMAC-MD5 as specified in RFC 2104. The code + * is originally based on the example code provided in the RFC, + * but it has been modified to remove the dependency on the + * OpenSSL libraries. It, instead, depends on KMD5 provided by + * KDE. + * + * The emphasis in writing this function was readability not speed. + * Since the client will authenticate itself against the server + * every couple minutes (at the most), the speed of the function + * is essentially unimportant. The maintainability of the code + * seemed more important. That's not to say that the function is + * slow, it simply hasn't been optimized for speed. If you want + * to call this function several times per second, look elsewhere. + * + * @param text calculate the HMAC-MD5 of this text + * @param key the key used when calculating the HMAC + * @return the HMAC-MD5 value as a string of lower-case, hexadecimal digits + */ + QString hmac_md5(const QString& text, const QString& key); +} + +#endif // KBIFFCRYPT_H diff --git a/kbiff/kbiffmonitor.cpp b/kbiff/kbiffmonitor.cpp new file mode 100644 index 0000000..37b51e9 --- /dev/null +++ b/kbiff/kbiffmonitor.cpp @@ -0,0 +1,2225 @@ +/* + * kbiffmonitor.cpp + * Copyright (C) 1999-2008 Kurt Granroth <granroth@kde.org> + * + * This file contains the implementation of KBiffMonitor and + * associated classes. + */ +#include "kbiffmonitor.h" +#include "kbiffmonitor.moc" + +#include <kmessagebox.h> + +#include <sys/types.h> +#ifndef __STRICT_ANSI__ +#define __STRICT_ANSI__ +#include <sys/socket.h> +#undef __STRICT_ANSI__ +#else +#include <sys/socket.h> +#endif +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <utime.h> + +#include <fcntl.h> +#include <errno.h> + +#include <kbiffurl.h> +#include <kdebug.h> + +#include <qapplication.h> +#include <qstring.h> +#include <qregexp.h> +#include <qdir.h> +#include <qdatetime.h> +#include <ksimpleconfig.h> + +// Needed for CRAM-MD5 and APOP +#include <kmdcodec.h> +#include "kbiffcrypt.h" + +#define MAXSTR (1024) + +#define MAIL_STATE_FILE "kbiffstate" + +#if defined (_HPUX_SOURCE) +extern int h_errno; +#endif + +static bool real_from(const QString& buffer); +static const char* compare_header(const char* header, const char* field); + +KBiffMonitor::KBiffMonitor() + : QObject(), + poll(60), + oldTimer(0), + started(false), + newCount(0), + curCount(-1), + oldCount(-1), + firstRun(false), + key(""), + simpleURL(""), + protocol(""), + mailbox(""), + server(""), + user(""), + password(""), + port(0), + preauth(false), + keepalive(false), + mailState(UnknownState), + lastSize(0), + imap(0), + pop(0), + nntp(0) +{ + lastRead.setTime_t(0); + lastModified.setTime_t(0); + b_new_lastSize = false; + b_new_lastRead = false; + b_new_lastModified = false; + b_new_uidlList = false; +} + +KBiffMonitor::~KBiffMonitor() +{ + if (imap) + { + delete imap; + imap = 0; + } + if (pop) + { + delete pop; + pop = 0; + } + if (nntp) + { + delete nntp; + nntp = 0; + } +} + +void KBiffMonitor::readConfig() +{ + KSimpleConfig *config = new KSimpleConfig(MAIL_STATE_FILE); + config->setDollarExpansion(false); + + QString group; + group = mailbox + "(" + key + ")"; + config->setGroup(group); + + QStrList list; + + mailState = (KBiffMailState)config->readNumEntry("mailState", UnknownState); + lastSize = config->readNumEntry("lastSize"); + config->readListEntry("lastRead", list); + if (list.count()==6) + { + lastRead.setDate(QDate(atoi(list.at(0)),atoi(list.at(1)),atoi(list.at(2)))); + lastRead.setTime(QTime(atoi(list.at(3)),atoi(list.at(4)),atoi(list.at(5)))); + } + config->readListEntry("lastModified", list); + if (list.count()==6) + { + lastModified.setDate(QDate(atoi(list.at(0)),atoi(list.at(1)),atoi(list.at(2)))); + lastModified.setTime(QTime(atoi(list.at(3)),atoi(list.at(4)),atoi(list.at(5)))); + } + config->readListEntry("uidlList", list); + + char *UIDL; + uidlList.clear(); + for (UIDL = list.first(); UIDL != 0; UIDL = list.next()) + { + uidlList.append( new QString(UIDL) ); + } + + newCount = config->readNumEntry("newCount", 0); + oldCount = config->readNumEntry("oldCount", -1); + + delete config; +} + +void KBiffMonitor::saveConfig() +{ + // open the config file + KSimpleConfig *config = new KSimpleConfig(MAIL_STATE_FILE); + config->setDollarExpansion(false); + + QString group; + group = mailbox + "(" + key + ")"; + config->setGroup(group); + + QStringList uidlist; + QString *UIDL; + for (UIDL = uidlList.first(); UIDL != 0; UIDL = uidlList.next()) + { + uidlist.append(*UIDL); + } + + config->writeEntry("mailState", (int)mailState); + config->writeEntry("lastSize", lastSize); + config->writeEntry("lastRead",lastRead); + config->writeEntry("lastModified",lastModified); + config->writeEntry("uidlList",uidlist); + config->writeEntry("newCount", newCount); + config->writeEntry("oldCount", oldCount); + + delete config; +} + +void KBiffMonitor::onStateChanged() +{ + saveConfig(); +} + +void KBiffMonitor::start() +{ + readConfig(); + started = true; + firstRun = true; + oldTimer = startTimer(poll * 1000); + emit(signal_checkMail()); +} + +void KBiffMonitor::stop() +{ + if (oldTimer > 0) + killTimer(oldTimer); + + lastSize = 0; + oldTimer = 0; + mailState = UnknownState; + started = false; + lastRead.setTime_t(0); + lastModified.setTime_t(0); + uidlList.clear(); +} + +void KBiffMonitor::setPollInterval(const int interval) +{ + poll = interval; + + // Kill any old timers that may be running + if (oldTimer > 0) + { + killTimer(oldTimer); + + // Start a new timer will the specified time + if (started) + { + oldTimer = startTimer(interval * 1000); + + emit(signal_checkMail()); + } + } +} + +void KBiffMonitor::setMailbox(const QString& url) +{ + KBiffURL kurl(url); + setMailbox(kurl); +} + +void KBiffMonitor::setMailbox(KBiffURL& url) +{ + if (imap) + { + delete imap; + imap = 0; + } + if (pop) + { + delete pop; + pop = 0; + } + if (nntp) + { + delete nntp; + nntp = 0; + } + + protocol = url.protocol(); + + if (protocol == "imap4") + { + disconnect(this); + + imap = new KBiffImap; + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkImap())); + server = url.host(); + user = url.user(); + password = url.pass(); + + mailbox = url.path().right(url.path().length() - 1); + port = (url.port() > 0) ? url.port() : 143; + + preauth = url.searchPar("preauth") == "yes"; + keepalive = url.searchPar("keepalive") == "yes"; + bool async = url.searchPar("async") == "yes"; + imap->setAsync(async); +#ifdef USE_SSL + imap->setSSL(false); +#endif // USE_SSL + simpleURL = "imap4://" + server + "/" + mailbox; + } + +#ifdef USE_SSL + if (protocol == "imap4s") + { + disconnect(this); + + imap = new KBiffImap; + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkImap())); + server = url.host(); + user = url.user(); + password = url.pass(); + + mailbox = url.path().right(url.path().length() - 1); + port = (url.port() > 0) ? url.port() : 993; + + preauth = url.searchPar("preauth") == "yes"; + keepalive = url.searchPar("keepalive") == "yes"; + bool async = url.searchPar("async") == "yes"; + imap->setAsync(async); + imap->setSSL(true); + simpleURL = "imap4s://" + server + "/" + mailbox; + } +#endif // USE_SSL + + if (protocol == "pop3") + { + disconnect(this); + + pop = new KBiffPop; + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkPop())); + server = url.host(); + user = url.user(); + password = url.pass(); + mailbox = url.user(); + port = (url.port() > 0) ? url.port() : 110; + + keepalive = url.searchPar("keepalive") == "yes"; + bool async = url.searchPar("async") == "yes"; + pop->setAsync(async); + // preserve existing behaviour, prior to adding disable apop, + // by setting Apop on, even if no apop parameter is found in the mailbox url + bool useApop = !( url.searchPar("apop") == "no" ); + pop->setApop( useApop ); +#ifdef USE_SSL + pop->setSSL(false); +#endif // USE_SSL + + simpleURL = "pop3://" + server + "/" + mailbox; + } + +#ifdef USE_SSL + if (protocol == "pop3s") + { + disconnect(this); + + pop = new KBiffPop; + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkPop())); + server = url.host(); + user = url.user(); + password = url.pass(); + mailbox = url.user(); + port = (url.port() > 0) ? url.port() : 995; + + keepalive = url.searchPar("keepalive") == "yes"; + bool async = url.searchPar("async") == "yes"; + pop->setAsync(async); + // preserve existing behaviour, prior to adding disable apop, + // by setting Apop on, even if no apop parameter is found in the mailbox url + bool useApop = !( url.searchPar("apop") == "no" ); + pop->setApop( useApop ); + pop->setSSL(true); + + simpleURL = "pop3s://" + server + "/" + mailbox; + } +#endif // USE_SSL + + if (protocol == "mbox") + { + disconnect(this); + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkMbox())); + mailbox = url.path(); + + simpleURL = "mbox:" + mailbox; + } + + if (protocol == "file") + { + disconnect(this); + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkLocal())); + mailbox = url.path(); + + simpleURL = "file:" + mailbox; + } + + if (protocol == "maildir") + { + disconnect(this); + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkMaildir())); + mailbox = url.path(); + + simpleURL = "maildir:" + mailbox; + } + + if (protocol == "mh") + { + disconnect(this); + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkMHdir())); + mailbox = url.path(); + + simpleURL = "mh:" + mailbox; + } + + if (protocol == "nntp") + { + disconnect(this); + + nntp = new KBiffNntp; + + connect(this, SIGNAL(signal_checkMail()), SLOT(checkNntp())); + server = url.host(); + user = url.user(); + password = url.pass(); + + mailbox = url.path().right(url.path().length() - 1); + port = (url.port() > 0) ? url.port() : 119; + + keepalive = url.searchPar("keepalive") == "yes"; + bool async = url.searchPar("async") == "yes"; + nntp->setAsync(async); +#ifdef USE_SSL + nntp->setSSL(false); +#endif // USE_SSL + simpleURL = "nntp://" + server + "/" + mailbox; + } + + fetchCommand = url.searchPar("fetch"); +} + +void KBiffMonitor::setMailboxIsRead() +{ + lastRead = QDateTime::currentDateTime(); + if (mailState == NewMail) + { + if (b_new_lastSize) lastSize = new_lastSize; + if (b_new_lastRead) lastRead = new_lastRead; + if (b_new_lastModified) lastModified = new_lastModified; + if (b_new_uidlList) uidlList = new_uidlList; + + if (curCount!=-1) curCount+=newCount; + newCount = 0; + b_new_lastSize = false; + b_new_lastRead = false; + b_new_lastModified = false; + b_new_uidlList = false; + + determineState(OldMail); + } +} + +void KBiffMonitor::checkMailNow() +{ + emit(signal_checkMail()); +} + +void KBiffMonitor::setPassword(const QString& pass) +{ + password = pass; +} + +void KBiffMonitor::setMailboxKey(const QString& k) +{ + key = k; +} + +void KBiffMonitor::timerEvent(QTimerEvent *) +{ + emit(signal_checkMail()); +} + +void KBiffMonitor::checkLocal() +{ + // get the information about this local mailbox + QFileInfo mbox(mailbox); + + // run external fetch client + if (!fetchCommand.isEmpty()) + emit(signal_fetchMail(fetchCommand)); + + // check if we have new mail + determineState(mbox.size(), mbox.lastRead(), mbox.lastModified()); + + firstRun = false; +} + +void KBiffMonitor::checkMbox() +{ + // get the information about this local mailbox + QFileInfo mbox(mailbox); + + // run external fetch client + if (!fetchCommand.isEmpty()) + emit(signal_fetchMail(fetchCommand)); + + // see if the state has changed + if ((mbox.lastModified() != lastModified) || (mbox.size() != lastSize) || + (mailState == UnknownState) || (oldCount == -1)) + { + lastModified = mbox.lastModified(); + lastSize = mbox.size(); + + // ok, the state *has* changed. see if the number of + // new messages has, too. + newCount = mboxMessages(); + + // Set access time of the file to what it was. If we don't do + // this some (all?) MUAs think that the mail has already been + // read. + { + utimbuf buf; + buf.actime = mbox.lastRead().toTime_t(); + buf.modtime = mbox.lastModified().toTime_t(); + utime(QFile::encodeName(mailbox), &buf); + } + + // if there are any new messages, consider the state New + if (newCount > 0) + determineState(NewMail); + else + { + if (oldCount == 0) + determineState(NoMail); + else + determineState(OldMail); + } + } + else if (firstRun) + { + KBiffMailState state(mailState); + mailState = UnknownState; + determineState(state); + } + + firstRun = false; + + // handle the NoMail case + if ((mbox.size() == 0) || (oldCount == 0)) + { + newCount = 0; + determineState(NoMail); + return; + } +} + +void KBiffMonitor::checkPop() +{ + firstRun = false; + + QString command; + + // connect to the server unless it is active already + if (pop->active() == false) + { + if(pop->connectSocket(server, port) == false) + { + determineState(NoConn); + return; + } + + // find out if APOP is supported + pop->parseBanner(); + + // find other possibly useful capabilities + // we don't care if this fails + pop->command("CAPA\r\n"); + + if (pop->authenticate(user, password) == false ) + { + pop->close(); + invalidLogin(); + return; + } + } + + command = "UIDL\r\n"; + if (pop->command(command) == false) + { + command = "STAT\r\n"; + if (pop->command(command) == false) + { + command = "LIST\r\n"; + if (pop->command(command) == false) + { + // if this still doesn't work, then we + // close this port + pop->close(); + return; + } + } + } + + if (command == "UIDL\r\n") + { + determineState(pop->getUidlList()); + curCount = uidlList.count(); + } + else + { + determineState(pop->numberOfMessages()); + } + + if (keepalive == false) + pop->close(); +} + +void KBiffMonitor::checkImap() +{ + firstRun = false; + + QString command; + int seq = 1000; + bool do_login = false; + + // run external client (probably to setup SSL) + if (!fetchCommand.isEmpty()) { + emit(signal_fetchMail(fetchCommand)); + + // sleep a bit to allow the connection to take place + sleep(1); + } + + // connect to the server + if (imap->active() == false) + { + if (imap->connectSocket(server, port) == false) + { + invalidLogin(); + return; + } + + do_login = true; + + // check the server's capabilities (see RFC 3050, 6.1.1) + command = QString().setNum(seq) + " CAPABILITY\r\n"; + if (imap->command(command, seq) == false) + { + invalidLogin(); + return; + } + seq++; + } + + // if we are preauthorized OR we want to keep the session alive, then + // we don't login. Otherwise, we do. + if ((preauth == false) && (do_login == true)) + { + if (imap->authenticate(&seq, user, password) == false) + { + invalidLogin(); + return; + } + } + + // reset the numbers from the last check + imap->resetNumbers(); + + // The STATUS COMMAND is documented in RFC2060, 6.3.10 + command = QString().setNum(seq) + " STATUS " + mailbox + " (UNSEEN MESSAGES)\r\n"; + if ( ! imap->command(command, seq)) { + return; + } + seq++; + + // lets not logout if we want to keep the session alive + if (keepalive == false) + { + command = QString().setNum(seq) + " LOGOUT\r\n"; + if (imap->command(command, seq) == false) + return; + imap->close(); + } + + // what state are we in? + if (imap->numberOfMessages() == 0) + { + newCount = 0; + determineState(NoMail); + } + else + { + newCount = imap->numberOfNewMessages(); + curCount = imap->numberOfMessages() - newCount; + if (newCount > 0) + determineState(NewMail); + else + determineState(OldMail); + } +} + +void KBiffMonitor::checkMaildir() +{ + firstRun = false; + + // get the information about this local mailbox + QDir mbox(mailbox); + + // run external fetch client + if (!fetchCommand.isEmpty()) + emit(signal_fetchMail(fetchCommand)); + + // make sure the mailbox exists + if (mbox.exists()) + { + // maildir stores its mail in MAILDIR/new and MAILDIR/cur + QDir new_mailbox(mailbox + "/new"); + QDir cur_mailbox(mailbox + "/cur"); + + // make sure both exist + if (new_mailbox.exists() && cur_mailbox.exists()) + { + // check only files + new_mailbox.setFilter(QDir::Files); + cur_mailbox.setFilter(QDir::Files); + + // determining "new" (or "unread") mail in maildir folders + // is a *little* tricky. all mail in the 'new' folder are + // new, of course... but so is all mail in the 'cur' + // folder that doesn't have a ':2,[F|R|S|T]' after it. + newCount = new_mailbox.count(); + curCount = cur_mailbox.count(); + + const QFileInfoList *cur_list = cur_mailbox.entryInfoList(); + QFileInfoListIterator it(*cur_list); + QFileInfo *info; + + static QRegExp suffix(":2,?F?R?S?T?$"); + while ((info = it.current())) + { + if (info->fileName().findRev(suffix) == -1) + { + newCount++; + curCount--; + } + ++it; + } + + // all messages in 'new' are new + if (newCount > 0) + { + determineState(NewMail); + } + // failing that, we look for any old ones + else if (curCount > 0) + { + determineState(OldMail); + } + // failing that, we have no mail + else + determineState(NoMail); + } + } +} + +void KBiffMonitor::checkNntp() +{ + firstRun = false; + + QString command; + bool do_login = false; + + // connect to the server + if (nntp->active() == false) + { + if (nntp->connectSocket(server, port) == false) + { + determineState(NoConn); + return; + } + + do_login = true; + } + + // if we are preauthorized OR we want to keep the session alive, then + // we don't login. Otherwise, we do. + if ((preauth == false) && (do_login == true)) + { + if (user.isEmpty() == false) + { + command = "authinfo user " + user + "\r\n"; + if (nntp->command(command) == false) + return; + } + if (password.isEmpty() == false) + { + command = "authinfo pass " + password + "\r\n"; + if (nntp->command(command) == false) + return; + } + } + + command = "group " + mailbox + "\r\n"; + if (nntp->command(command) == false) + return; + + // lets not logout if we want to keep the session alive + if (keepalive == false) + { + command = "QUIT\r\n"; + nntp->command(command); + nntp->close(); + } + + // now, we process the .newsrc file + QString home(getenv("HOME")); + QString newsrc_path(home + "/.newsrc"); + QFile newsrc(newsrc_path); + if (newsrc.open(IO_ReadOnly) == false) + { + return; + } + + char c_buffer[MAXSTR]; + while(newsrc.readLine(c_buffer, MAXSTR) > 0) + { + // search for our mailbox name + QString str_buffer(c_buffer); + if (str_buffer.left(mailbox.length()) != mailbox) + continue; + + // we now have our mailbox. this parsing routine is so + // ugly, however, that I could almost cry. it assumes way + // too much. the "actual" range MUST be 1-something + // continuously and our read sequence MUST be sequentially in + // order + bool range = false; + int last = 1; + newCount = 0; + char *buffer = c_buffer; + + // skip over the mailbox name + for(; buffer && *buffer != ' '; buffer++) {} + + // iterate over the sequence until we hit a newline or end of string + while (buffer && *buffer != '\n' && *buffer != '\0') + { + // make sure that this is a digit + if (!isdigit(*buffer)) + { + buffer++; + continue; + } + + // okay, what digit are we looking at? atoi() will convert + // only those digits it recognizes to an it. this will handily + // skip spaces, dashes, commas, etc + char *digit = buffer; + int current = atoi(digit); + + // if our current digit is greater than is possible, then we + // should just quit while we're (somewhat) ahead + if (current > nntp->last()) + break; + + // we treat our sequences different ways if we are in a range + // or not. specifically, if we are in the top half of a range, + // we don't do anything + if (range == false) + { + if (current > last) + newCount += current - last - 1; + } + else + range = false; + + // set our 'last' one for the next go-round + last = current; + + // skip over all of these digits + for(;buffer && isdigit(*buffer); buffer++) {} + + // is this a range? + if (*buffer == '-') + range = true; + } + + // get the last few new ones + if (last < nntp->last()) + newCount += nntp->last() - last; + + break; + } + // with newsgroups, it is either new or non-existant. it + // doesn't make sense to count the number of read mails + if (newCount > 0) + determineState(NewMail); + else + determineState(OldMail); +} + +/* + * MH support provided by David Woodhouse <David.Woodhouse@mvhi.com> + */ +void KBiffMonitor::checkMHdir() +{ + firstRun = false; + + // get the information about this local mailbox + QDir mbox(mailbox); + char the_buffer[MAXSTR]; + char *buffer = the_buffer; + + // run external fetch client + if (!fetchCommand.isEmpty()) + emit(signal_fetchMail(fetchCommand)); + + + // make sure the mailbox exists + if (mbox.exists()) + { + QFile mhseq(mailbox+"/.mh_sequences"); + if (mhseq.open(IO_ReadOnly) == true) + { + // Check the .mh_sequences file for 'unseen:' + + buffer[MAXSTR-1]=0; + + while(mhseq.readLine(buffer, MAXSTR-2) > 0) + { + if (!strchr(buffer, '\n') && !mhseq.atEnd()) + { + // read till the end of the line + + int c; + while((c=mhseq.getch()) >=0 && c !='\n') {} + } + if (!strncmp(buffer, "unseen:", 7)) + { + // There are unseen messages + // we will now attempt to count exactly how + // many new messages there are + + // an unseen sequence looks something like so: + // unseen: 1, 5-9, 27, 35-41 + bool range = false; + int last = 0; + + // initialize the number of new messages + newCount = 0; + + // jump to the correct position and iterate through the + // rest of the buffer + buffer+=7; + while(*buffer != '\n' && buffer) + { + // is this a digit? if so, it is the first of possibly + // several digits + if (isdigit(*buffer)) + { + // whether or not this is a range, we are guaranteed + // of at least *one* new message + newCount++; + + // get a handle to this digit. atoi() will convert + // only those digits it recognizes to an int. so + // atoi("123garbage") would become 123 + char *digit = buffer; + + // if we are in the second half of a range, we need + // to compute the number of new messages. + if (range) + { + // remember that we have already counted the + // two extremes.. hence we need to subtract one. + newCount += atoi(digit) - last - 1; + range = false; + } + + // skip over all digits + for(;buffer && isdigit(*buffer); buffer++) {} + + // check if we are in a range + if (*buffer == '-') + { + // save the current digit for later computing + last = atoi(digit); + range = true; + } + } + else + buffer++; + } + mhseq.close(); + determineState(NewMail); + return; + } + } + mhseq.close(); + } + + // OK. No new messages listed in .mh_sequences. Check if + // there are any old ones. + //mbox.setFilter(QDir::Files); + QStringList mails = mbox.entryList(QDir::Files); + QStringList::Iterator str; + + for (str = mails.begin(); str != mails.end(); str++) + { + uint index; + // Check each file in the directory. + // If it's a numeric filename, then it's a mail. + + for (index = 0; index < (*str).length(); index++) + { + if (!(*str).at(index).isDigit()) + break; + } + if (index >= (*str).length()) + { + // We found a filename which was entirely + // made up of digits - it's a real mail, so + // respond accordingly. + + determineState(OldMail); + return; + } + } + + // We haven't found any valid filenames. No Mail. + determineState(NoMail); + } +} + +void KBiffMonitor::determineState(unsigned int size) +{ + // check for no mail + if (size == 0) + { + if (mailState != NoMail) + { + mailState = NoMail; + lastSize = 0; + newCount = 0; + emit(signal_noMail()); + emit(signal_noMail(simpleURL)); + onStateChanged(); + } + + emit(signal_currentStatus(newCount, key, mailState)); + return; + } + + // check for new mail + if (size > lastSize) + { + if (!b_new_lastSize || size > new_lastSize) + { + mailState = NewMail; + emit(signal_newMail()); + emit(signal_newMail(newCount, key)); + onStateChanged(); + } + new_lastSize = size; + b_new_lastSize = true; + newCount = size - lastSize; + emit(signal_currentStatus(newCount, key, mailState)); + return; + } + + // if we have *some* mail, but the state is unknown, + // then we'll consider it old + if (mailState == UnknownState) + { + mailState = OldMail; + lastSize = size; + emit(signal_oldMail()); + emit(signal_oldMail(simpleURL)); + + emit(signal_currentStatus(newCount, key, mailState)); + onStateChanged(); + return; + } + + // check for old mail + if (size < lastSize) + { + if (mailState != OldMail) + { + mailState = OldMail; + lastSize = size; + emit(signal_oldMail()); + emit(signal_oldMail(simpleURL)); + onStateChanged(); + } + } + + emit(signal_currentStatus(newCount, key, mailState)); +} + +void KBiffMonitor::determineState(KBiffUidlList uidl_list) +{ + QString *UIDL; + unsigned int messages = 0; + + // if the uidl_list is empty then the number of messages = 0 + if (uidl_list.isEmpty()) + { + if (mailState != NoMail) + { + lastSize = newCount = 0; + mailState = NoMail; + emit(signal_noMail()); + emit(signal_noMail(simpleURL)); + onStateChanged(); + } + } + else + { + // if a member of uidl_list is not in the old uidlList then we have + // new mail + for (UIDL = uidl_list.first(); UIDL != 0; UIDL = uidl_list.next()) + { + // If we already have new mail use new_uidlList to se if we have + // more new messages + if (b_new_uidlList) + { + if (new_uidlList.find(UIDL) == -1) + messages++; + } + else + { + if (uidlList.find(UIDL) == -1) + messages++; + } + } + // if there are any new messages, then notify.. + if (messages > 0) + { + mailState = NewMail; + emit(signal_newMail()); + emit(signal_newMail(newCount, key)); + onStateChanged(); + // now update newCount + if (b_new_uidlList) + { + // if we have used new_uidlList for a check + newCount += messages; + } + else + { + // if we have used uidlList for a check + newCount = messages; + } + new_uidlList = uidl_list; + b_new_uidlList = true; + } + // this is horrible. it will reset kbiff to OldMail the very next + // time a pop3 mailbox is checked. i don't know of a way around + // this, though :-( + // MZ: what's wrong with that? + else if ( (!b_new_uidlList) && mailState != OldMail) + { + newCount = 0; + mailState = OldMail; + emit(signal_oldMail()); + emit(signal_oldMail(simpleURL)); + onStateChanged(); + } + } + emit(signal_currentStatus(newCount, key, mailState)); +} + +void KBiffMonitor::determineState(KBiffMailState state) +{ + if ((state == NewMail) && (mailState != NewMail)) + { + mailState = NewMail; + emit(signal_newMail()); + emit(signal_newMail(newCount, key)); + onStateChanged(); + } + else + if ((state == NoMail) && (mailState != NoMail)) + { + mailState = NoMail; + emit(signal_noMail()); + emit(signal_noMail(simpleURL)); + onStateChanged(); + } + else + if ((state == OldMail) && (mailState != OldMail)) + { + mailState = OldMail; + emit(signal_oldMail()); + emit(signal_oldMail(simpleURL)); + onStateChanged(); + } + else + if ((state == NoConn) && (mailState != NoConn)) + { + mailState = NoConn; + emit(signal_noConn()); + emit(signal_noConn(simpleURL)); + onStateChanged(); + } + emit(signal_currentStatus(newCount, key, mailState)); +} + +void KBiffMonitor::determineState(unsigned int size, const QDateTime& last_read, const QDateTime& last_modified) +{ + // Check for NoMail + if (size == 0) + { + // Is this a new state? + if (mailState != NoMail) + { + // Yes, the user has just nuked the entire mailbox + mailState = NoMail; + lastRead = last_read; + lastSize = 0; + + // Let the world know of the new state + emit(signal_noMail()); + emit(signal_noMail(simpleURL)); + onStateChanged(); + } + } + else + // There is some mail. See if it is new or not. To be new, the + // mailbox must have been modified after it was last read AND the + // current size must be greater then it was before. + if (last_modified>=last_read && size>lastSize) + { + if (!b_new_lastSize || size>new_lastSize) + { + mailState = NewMail; + // Let the world know of the new state + emit(signal_newMail()); + emit(signal_newMail(1, key)); + onStateChanged(); + } + new_lastSize = size; + b_new_lastSize = true; + new_lastRead = last_read; + b_new_lastRead = true; + newCount = 1; + } + else + // Finally, check if the state needs to change to OldMail + if ((mailState != OldMail) && (last_read > lastRead)) + { + mailState = OldMail; + lastRead = last_read; + lastSize = size; + + // Let the world know of the new state + emit(signal_oldMail()); + emit(signal_oldMail(simpleURL)); + onStateChanged(); + } + + // If we get to this point, then the state now is exactly the + // same as the state when last we checked. Do nothing at this + // point. + emit(signal_currentStatus(newCount, key, mailState)); +} + +/** + * The following function is lifted from unixdrop.cpp in the korn + * distribution. It is (C) Sirtaj Singh Kang <taj@kde.org> and is + * used under the GPL license (and the author's permission). It has + * been slightly modified for formatting reasons. + */ +int KBiffMonitor::mboxMessages() +{ + QFile mbox(mailbox); + char buffer[MAXSTR]; + int count = 0; + int msg_count = 0; + bool in_header = false; + bool has_content_len = false; + bool msg_read = false; + long content_length = 0; + + oldCount = 0; + curCount = 0; + + if (mbox.open(IO_ReadOnly) == false) + return 0; + + buffer[MAXSTR-1] = 0; + + while (mbox.readLine(buffer, MAXSTR-2) > 0) + { + // read a line from the mailbox + + if (!strchr(buffer, '\n') && !mbox.atEnd()) + { + // read till the end of the line if we + // haven't already read all of it. + + int c; + + while((c=mbox.getch()) >=0 && c !='\n') {} + } + + if (!in_header && real_from(buffer)) + { + // check if this is the start of a message + has_content_len = false; + in_header = true; + msg_read = false; + } + else if (in_header) + { + // check header fields if we're already in one + + if (compare_header(buffer, "Content-Length")) + { + has_content_len = true; + content_length = atol(buffer + 15); + } + // This should handle those folders that double as IMAP or POP + // folders. Possibly PINE uses these always + if (strcmp(buffer, "Subject: DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA\n") == 0) + { + oldCount--; + curCount--; + } + else + { + if (compare_header(buffer, "Status")) + { + const char *field = buffer; + field += 7; + while (field && (*field== ' ' || *field == '\t')) + field++; + + if (*field == 'N' || *field == 'U' || *field == 0x0a) + msg_read = false; + else + msg_read = true; + } + // Netscape *sometimes* uses X-Mozilla-Status to determine + // unread vs read mail. The only pattern I could see for + // sure, though, was that Read mails started with an '8'. + // I make no guarantees on this... + else if (compare_header(buffer, "X-Mozilla-Status")) + { + const char *field = buffer; + field += 17; + while (field && (*field== ' ' || *field == '\t')) + field++; + + if (*field == '8') + msg_read = true; + else + msg_read = false; + } + else if (buffer[0] == '\n' ) + { + if (has_content_len) + mbox.at(mbox.at() + content_length); + + in_header = false; + + oldCount++; + + if (!msg_read) { + count++; + } else { + curCount++; + } + } + } + }//in header + + if(++msg_count >= 100 ) + { + qApp->processEvents(); + msg_count = 0; + } + }//while + + mbox.close(); + return count; +} + +void KBiffMonitor::invalidLogin() +{ + // first, we stop this monitor to be on the safe side + stop(); + determineState(NoConn); + newCount = -1; + + emit(signal_invalidLogin(key)); +} + +/////////////////////////////////////////////////////////////////////////// +// KBiffSocket +/////////////////////////////////////////////////////////////////////////// +KBiffSocket::KBiffSocket() : async(false), socketFD(-1), messages(0), newMessages(-1) +#ifdef USE_SSL + , ssltunnel(0) +#endif // USE_SSL +{ + FD_ZERO(&socketFDS); + + /* + * Set the socketTO once and DO NOT use it in any select call as this + * may alter its value! + */ + socketTO.tv_sec = SOCKET_TIMEOUT; + socketTO.tv_usec = 0; +} + +KBiffSocket::~KBiffSocket() +{ + close(); +#ifdef USE_SSL + if (ssltunnel) + { + delete ssltunnel; + ssltunnel = 0; + } +#endif // USE_SSL +} + +int KBiffSocket::numberOfMessages() +{ + return messages; +} + +int KBiffSocket::numberOfNewMessages() +{ + return (newMessages > -1) ? newMessages : 0; +} + +void KBiffSocket::close() +{ + +#ifdef USE_SSL + if (isSSL() && (socketFD != -1) && (ssltunnel != 0)) + { + ssltunnel->close(); + } +#endif // USE_SSL + + if (socketFD != -1) + ::close(socketFD); + + socketFD = -1; + FD_ZERO(&socketFDS); +} + +bool KBiffSocket::connectSocket(const QString& host, unsigned short int port) +{ + sockaddr_in sin; + hostent *hent; + int addr, n; + + // if we still have a socket, close it + if (socketFD != -1) + close(); + + // get the socket + socketFD = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + + // start setting up the socket info + memset((char *)&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + + // get the address + if ((addr = inet_addr(host.ascii())) == -1) + { + // get the address by host name + if ((hent = gethostbyname(host.ascii())) == 0) + { + switch (h_errno) + { + case HOST_NOT_FOUND: + break; + + case NO_ADDRESS: + break; + + case NO_RECOVERY: + break; + + case TRY_AGAIN: + break; + + default: + break; + } + + close(); + return false; + } + + memcpy((void *)&sin.sin_addr, *(hent->h_addr_list), hent->h_length); + } + else + // get the address by IP + memcpy((void *)&sin.sin_addr, (void *)&addr, sizeof(addr)); + + // Set up non-blocking io if requested + if (async) + { + int flags = fcntl(socketFD, F_GETFL); + if (flags < 0 || fcntl(socketFD, F_SETFL, flags | O_NONBLOCK) < 0) + { + async = false; + } + } + + + // the socket is correctly setup. now connect + if ((n = ::connect(socketFD, (sockaddr *)&sin, sizeof(sockaddr_in))) == -1 && + errno != EINPROGRESS) + { + close(); + return false; + } + + // Empty the file descriptor set + FD_ZERO(&socketFDS); + FD_SET(socketFD, &socketFDS); + + // For non-blocking io, the connection may need time to finish (n = -1) + if (n == -1 && async == true) + { + struct timeval tv = socketTO; + + // Wait for the connection to come up + if (select(socketFD+1, NULL, &socketFDS, NULL, &tv) != 1) + { + errno = ETIMEDOUT; + close(); + return false; + } + + // The connection has finished. Catch any error in a call to readLine() + } + +#ifdef USE_SSL + // Initialize SSL tunnel, if needed + if (isSSL()) + { + if (ssltunnel == 0) + ssltunnel = new KSSL(true); + else + ssltunnel->reInitialize(); + if (ssltunnel == 0) + { + close(); + return false; + } + if (ssltunnel->connect(socketFD) != 1) + { + close(); + return false; + } + } +#endif // USE_SSL + + // we're connected! see if the connection is good + QString line(readLine()); + if (line.isNull() || ((line.find("200") == -1 ) && (line.find("OK") == -1) && (line.find("PREAUTH") == -1))) + { + if (line.isNull()) + + close(); + return false; + } + + // everything is swell + banner = line; // save the banner for use by subclasses + return true; +} + +bool KBiffSocket::active() +{ + return socketFD != -1; +} + +bool KBiffSocket::isAsync() +{ + return async; +} + +void KBiffSocket::setAsync(bool on) +{ + int flags = 0; + + async = on; + + if (active()) + { + flags = fcntl(socketFD, F_GETFL); + + switch (async) + { + case false: + if (flags >= 0) + fcntl(socketFD, F_SETFL, flags & ~O_NONBLOCK); + break; + + case true: + if (flags < 0 || fcntl(socketFD, F_SETFL, flags | O_NONBLOCK) < 0) + async = false; + break; + } + } +} + +#ifdef USE_SSL +bool KBiffSocket::isSSL() +{ + return usessl; +} + +void KBiffSocket::setSSL(bool on) +{ + if (usessl == on) return; + if (!KSSL::doesSSLWork()) + { + usessl = false; + return; + } + usessl = on; + if (active()) + { + switch (usessl) + { + case false: + ssltunnel->close(); + delete ssltunnel; + ssltunnel = 0; + break; + case true: + if (ssltunnel == 0) + ssltunnel = new KSSL(true); + else + ssltunnel->reInitialize(); + if (ssltunnel == 0) + { + usessl = false; + break; + } + if (ssltunnel->connect(socketFD) != 1) + usessl = false; + break; + } + } +} +#endif // USE_SSL + +int KBiffSocket::writeLine(const QString& line) +{ + int bytes = 0; + + // Do not try to write to a non active socket. Return error. + if (!active()) + return -1; + +#ifdef USE_SSL + if (isSSL()) + { + if ((bytes = ssltunnel->write(line.ascii(), line.length())) <= 0) + close(); + } + else +#endif // USE_SSL + if ((bytes = ::write(socketFD, line.ascii(), line.length())) <= 0) + close(); + + return bytes; +} + +QString KBiffSocket::readLine() +{ + QString fault, response; + char buffer; + ssize_t bytes = -1; + +#ifdef USE_SSL + if (isSSL()) + { + while (((bytes = ssltunnel->read(&buffer, 1)) > 0) && (buffer != '\n')) + response += buffer; + } + else +#endif // USE_SSL + if (!async) + while (((bytes = ::read(socketFD, &buffer, 1)) > 0) && (buffer != '\n')) + response += buffer; + else + { + while ( (((bytes = ::read(socketFD, &buffer, 1)) > 0) && (buffer != '\n')) || + ((bytes < 0) && (errno == EWOULDBLOCK)) ) + { + if (bytes > 0) + response += buffer; + else + { + struct timeval tv = socketTO; + if (select(socketFD+1, &socketFDS, NULL, NULL, &tv) != 1) + { + errno = ETIMEDOUT; + break; + } + } + } + } + + if (bytes == -1) + { + // Close the socket and hope for better luck with a new one + close(); + return fault; + } + + return response; +} + +/////////////////////////////////////////////////////////////////////////// +// KBiffImap +/////////////////////////////////////////////////////////////////////////// +KBiffImap::KBiffImap() +{ + /* Assume that the IMAP server does no fancy authentication */ + auth_cram_md5 = false; +} + +KBiffImap::~KBiffImap() +{ + close(); +} + +bool KBiffImap::command(const QString& line, unsigned int seq) +{ + QString messagesListString; + QStringList messagesList; + bool tried_cram_md5; // are we trying CRAM-MD5 ? + + if (writeLine(line) <= 0) + { + close(); + return false; + } + + QString ok, bad, no, response; + ok.sprintf("%d OK", seq); + bad.sprintf("%d BAD", seq); + no.sprintf("%d NO", seq); + + // must be case insensitive + QRegExp status("\\* STATUS", FALSE); + QRegExp capability("\\* CAPABILITY", FALSE); + QRegExp cram_md5("AUTHENTICATE CRAM-MD5", FALSE); + + // are we trying CRAM-MD5 ? + tried_cram_md5 = cram_md5.search(line)>=0; + cram_md5 = QRegExp("\\+ ([A-Za-z0-9+/=]+)"); + + while (!(response = readLine()).isNull()) + { + // if an error has occurred, we get a null string in return + if (response.isNull()) + break; + + // if the response is either good or bad, then return + if (response.find(ok) > -1) + return true; + if ((response.find(bad) > -1) || (response.find(no) > -1)) + break; + + /* The STATUS response is documented in RFC2060, 6.3.10/7.2.4 + * Briefly: the response depends on command and looks like + * * STATUS "some-imap-folder" ( requested-info ) + * for example: + * C: . STATUS "INBOX" (UNSEEN MESSAGES) + * S: * STATUS "INBOX" (UNSEEN 2 MESSAGES 3) + * S: . OK STATUS Completed + */ + if (status.search(response) >= 0) { + QRegExp unseen("UNSEEN ([0-9]*)", FALSE); + if (unseen.search(response) >= 0) { + QString num = unseen.cap(1); + newMessages = num.toInt(); + } + + QRegExp number("MESSAGES ([0-9]*)", FALSE); + if (number.search(response) >= 0) { + QString num = number.cap(1); + messages = num.toInt(); + } + } + + /* The CAPABILITY response is documented in RFC 3050, + * sections 6.1.1 and 7.2.1 + * An example: + * C: . CAPABILITY + * S: * CAPABILITY IMAP4rev1 IDLE AUTH=PLAIN AUTH=CRAM-MD5 + * S: . OK CAPABILITY completed. + */ + if (capability.search(response) >= 0) { + QRegExp cram_md5_cap("AUTH=CRAM-MD5", FALSE); + if (cram_md5_cap.search(response) >= 0) { + auth_cram_md5 = true; + } + } + + /* AUTHENTICATE CRAM-MD5 response is documented in + * RFC 3050 6.2.2 and RFC 2195 + */ + if (tried_cram_md5 && cram_md5.search(response)>=0) { + chall_cram_md5 = KCodecs::base64Decode(cram_md5.cap(1).local8Bit()); + if (chall_cram_md5.isNull()) + break; + + return true; + } + } + + close(); + return false; +} + +QString KBiffImap::mungeUserPass(const QString& old_user) +{ + QString new_user(old_user); + + if (new_user.left(1) != "\"") + new_user.prepend("\""); + if (new_user.right(1) != "\"") + new_user.append("\""); + + return new_user; +} + +void KBiffImap::resetNumbers() +{ + messages = 0; + newMessages = 0; +} + +bool KBiffImap::authenticate(int *pseq, const QString& user, const QString& pass) +{ + QString cmd, username, password; + + // If CRAM-MD5 is available, use it. It's the best we know. + // RFC 2195 defines the CRAM-MD5 authentication method + // also see RFC 3501 section 6.2.2 for the AUTHENTICATE command + if( auth_cram_md5 ) + { + cmd = QString("%1 AUTHENTICATE CRAM-MD5\r\n").arg(*pseq); + if (command(cmd, *pseq) == false) + { + return false; + } + + // calculate the real response to the challenge + QString response = user + " " + KBiffCrypt::hmac_md5(chall_cram_md5, pass); + response = KCodecs::base64Encode(response.latin1()); + + // send the response + if (command(response+"\r\n", *pseq) == false) + { + return false; + } + + return true; + } + else // well, we tried, LOGIN is the best we can do + { + // imap allows spaces in usernames... we need to take care of that + username = mungeUserPass(user); + + // also asterisks (*) in passwords. maybe it's a good idea + // to _always_ munge the user and the password. + password = mungeUserPass(pass); + + cmd = QString().setNum(*pseq) + " LOGIN " + + username + " " + + password + "\r\n"; + if (command(cmd, *pseq) == false) + { + return false; + } + (*pseq)++; + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////// +// KBiffPop +/////////////////////////////////////////////////////////////////////////// +KBiffPop::KBiffPop() : use_apop( true ) +{ +} + +KBiffPop::~KBiffPop() +{ + close(); +} + +void KBiffPop::close() +{ + command("QUIT\r\n"); + KBiffSocket::close(); +} + +void KBiffPop::setApop( bool enabled ) +{ + use_apop = enabled; +} + +bool KBiffPop::command(const QString& line) +{ + if (writeLine(line) <= 0) + return false; + + QString response; + response = readLine(); + + // check if the response was bad. if so, return now + if (response.isNull() || response.left(4) == "-ERR") + { + // we used to close the socket here.. but this MAY be + // because the server didn't understand UIDL. the server + // may react better with LIST or STAT so just fail quitely + // thanks to David Barth (dbarth@videotron.ca) + return false; + } + + // if the command was UIDL then build up the newUidlList + if (line == "UIDL\r\n") + { + uidlList.clear(); + for (response = readLine(); + !response.isNull() && response.left(1) != "."; + response = readLine()) + { + uidlList.append(new QString(response.right(response.length() - + response.find(" ") - 1))); + } + } + else + // get all response lines from the LIST command + // LIST and UIDL are return multilines so we have to loop around + if (line == "LIST\r\n") + { + for (messages = 0, response = readLine(); + !response.isNull() && response.left(1) != "."; + messages++, response = readLine()) {} + } + else + if (line == "STAT\r\n") + { + if (!response.isNull()) + sscanf(response.ascii(), "+OK %d", &messages); + } + else + // find out what the server is capable of + if (line == "CAPA\r\n") + { + QRegExp rx("\\bCRAM-MD5\\b"); + + auth_cram_md5 = false; // assume no support + + for (response = readLine(); + !response.isNull() && response.left(1) != "."; + response = readLine()) + { + if (response.left(4) == "SASL") + auth_cram_md5 = response.find(rx) != -1; + } + } + else + // look for the CRAM-MD5 challenge + if (line == "AUTH CRAM-MD5\r\n") + { + QRegExp challenge("\\+ ([A-Za-z0-9+/=]+)"); + if (challenge.search(response) == -1 ) + { + return false; + } + + chall_cram_md5 = KCodecs::base64Decode(challenge.cap(1).local8Bit()); + } + + return !response.isNull(); +} + +KBiffUidlList KBiffPop::getUidlList() const +{ + return uidlList; +} + +/*! + This method parses the initial response from the POP3 server. + The response is defined in RFC 1939 sections 4 and 7. + + \fn KBiffPop::parse_banner(void) + */ +bool KBiffPop::parseBanner(void) +{ + // RFC 1939 section 3 says server MUST use uppercase + if( banner.left(3) != "+OK" ) { + auth_apop = false; + return false; + } + + // Look for the banner part that indicates APOP support + QRegExp rx("(<[a-zA-Z0-9_+.-]+@[a-zA-Z0-9_+.-]+>)"); + if( rx.search(banner) == -1 || !use_apop ) { + auth_apop = false; + } else { + chall_apop = rx.cap(1).latin1(); + auth_apop = true; + } + + return true; +} + +/*! + This method authenticates using the most secure + technique available. + \fn KBiffPop::authenticate(const QString& user, const QString& pass) + */ +bool KBiffPop::authenticate(const QString& user, const QString& pass) +{ + QString popcommand; + + // CRAM-MD5 authentication is the most secure we can handle + // the use of the AUTH command is documented in RFC 1734 + if( auth_cram_md5 ) + { + if (this->command("AUTH CRAM-MD5\r\n") == false) + { + return false; + } + + // calculate the real response to the challenge + QString response = user + " " + KBiffCrypt::hmac_md5(chall_cram_md5, pass); + response = KCodecs::base64Encode(response.latin1()); + + // send the response + if (this->command(response+"\r\n") == false) + { + return false; + } + + return true; + } + + // APOP is not as secure as CRAM-MD5 but it's still better + // than sending the password in the clear + if( auth_apop ) + { + QCString digest; + + KMD5 md5(chall_apop); + md5.update(pass); + + digest = md5.hexDigest(); + + popcommand = QString("APOP %1 %2\r\n").arg(user, digest.data()); + if (this->command(popcommand) == false) + { + return false; + } + + return true; + } + + // lastly we'll try regular, plain-text authentication + + popcommand = "USER " + user + "\r\n"; + if (this->command(popcommand) == false) + { + return false; + } + + popcommand = "PASS " + pass + "\r\n"; + if (this->command(popcommand) == false) + { + return false; + } + + return true; +} +/////////////////////////////////////////////////////////////////////////// +// KBiffNntp +/////////////////////////////////////////////////////////////////////////// +KBiffNntp::~KBiffNntp() +{ + close(); +} + +bool KBiffNntp::command(const QString& line) +{ + int bogus; + + if (writeLine(line) <= 0) + return false; + + QString response; + while (!(response = readLine()).isNull()) + { + // return if the response is bad + if (response.find("500") > -1) + { + close(); + return false; + } + + // find return codes for tcp, user, pass + QString code(response.left(3)); + if ((code == "200") || (code == "281") || (code == "381")) + return true; + + // look for the response to the GROUP command + // 211 <num> <first> <last> <group> + if (code == "211") + { + sscanf(response.ascii(), "%d %d %d %d", + &bogus, &messages, &firstMsg, &lastMsg); + return true; + } + } + + close(); + return false; +} + +int KBiffNntp::first() const +{ + return firstMsg; +} + +int KBiffNntp::last() const +{ + return lastMsg; +} + +///////////////////////////////////////////////////////////////////////// +/* The following is a (C) Sirtaj Singh Kang <taj@kde.org> */ + +#define whitespace(c) (c == ' ' || c == '\t') + +#define skip_white(c) while(c && (*c) && whitespace(*c) ) c++ +#define skip_nonwhite(c) while(c && (*c) && !whitespace(*c) ) c++ + +#define skip_token(buf) skip_nonwhite(buf); if(!*buf) return false; \ + skip_white(buf); if(!*buf) return false; + +static const char *month_name[13] = { + "jan", "feb", "mar", "apr", "may", "jun", + "jul", "aug", "sep", "oct", "nov", "dec", NULL +}; + +static const char *day_name[8] = { + "sun", "mon", "tue", "wed", "thu", "fri", "sat", 0 +}; + +static bool real_from(const QString& orig_buffer) +{ + /* + A valid from line will be in the following format: + + From <user> <weekday> <month> <day> <hr:min:sec> [TZ1 [TZ2]] <year> + */ + + int day; + int i; + int found; + + const char *buffer = (const char*)orig_buffer.ascii(); + + /* From */ + + if(!buffer || !*buffer) + return false; + + if (strncmp(buffer, "From ", 5)) + return false; + + buffer += 5; + + skip_white(buffer); + + /* <user> */ + if(*buffer == 0) return false; + skip_token(buffer); + + /* <weekday> */ + found = 0; + for (i = 0; day_name[i] != NULL; i++) + found = found || (qstrnicmp(day_name[i], buffer, 3) == 0); + + if (!found) + return false; + + skip_token(buffer); + + /* <month> */ + found = 0; + for (i = 0; month_name[i] != NULL; i++) + found = found || (qstrnicmp(month_name[i], buffer, 3) == 0); + if (!found) + return false; + + skip_token(buffer); + + /* <day> */ + if ( (day = atoi(buffer)) < 0 || day < 1 || day > 31) + return false; + + return true; +} + +static const char* compare_header(const char* header, const char* field) +{ + int len = strlen(field); + + if (qstrnicmp(header, field, len)) + return NULL; + + header += len; + + if( *header != ':' ) + return NULL; + + header++; + + while( *header && ( *header == ' ' || *header == '\t') ) + header++; + + return header; +} diff --git a/kbiff/kbiffmonitor.h b/kbiff/kbiffmonitor.h new file mode 100644 index 0000000..cf7ed11 --- /dev/null +++ b/kbiff/kbiffmonitor.h @@ -0,0 +1,535 @@ +/* + * kbiffmonitor.h + * Copyright (C) 1999-2001 Kurt Granroth <granroth@kde.org> + * + * $Id$ + * + */ +#ifndef KBIFFMONITOR_H +#define KBIFFMONITOR_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> // Needed on some systems. +#endif + +#include <sys/time.h> + +#include <qobject.h> +#include <qlist.h> +#include <qfileinfo.h> + +#ifdef USE_SSL +#include <kssl.h> +#endif + +class KBiffURL; +class QString; + +/** + * @internal + * Internal class to store UIDL list + */ +class KBiffUidlList : public QList<QString> +{ +protected: + int compareItems(Item s1, Item s2) + { + QString *str1, *str2; + str1 = (QString *)s1; + str2 = (QString *)s2; + if((*str1) == (*str2)) + return 0; + else + return -1; + } +}; + +/** + * @internal + */ + +#define SOCKET_TIMEOUT 5 + +class KBiffSocket +{ +public: + KBiffSocket(); + virtual ~KBiffSocket(); + + bool connectSocket(const QString& host, unsigned short int port); + bool active(); + + bool isAsync(); + void setAsync(bool on); + +#ifdef USE_SSL + bool isSSL(); + void setSSL(bool on); +#endif // USE_SSL + + int numberOfMessages(); + int numberOfNewMessages(); + + void close(); + +protected: + QString readLine(); + int writeLine(const QString& line); + + bool async; + + struct timeval socketTO; + + int socketFD; + fd_set socketFDS; + int messages; + int newMessages; + QString banner; // the first line read from a new connection + +#ifdef USE_SSL + bool usessl; + KSSL *ssltunnel; +#endif // USE_SSL +}; + +/** + * @internal + */ +class KBiffImap : public KBiffSocket +{ +public: + KBiffImap(); + virtual ~KBiffImap(); + + bool command(const QString& line, unsigned int seq); + QString mungeUserPass(const QString& old_user); + void resetNumbers(); + /** + * @internal + * + * @brief Encapsulates all authentication to the IMAP server + * + * All authentication, including the determination of which authentication + * mechanism to use, is performed in this method. To add an + * authentication method, one will need to modify this method, + * KBiffMonitor::checkImap and KBiffImap::command + * + * @param pseq a pointer to the number of the next IMAP command. + * This value will be incremented depending on the number of + * commands necessary for authentication. + * @param user the user name required for authentication + * @param pass the password required for authentication + */ + bool authenticate(int *pseq, const QString& user, const QString& pass); + +protected: + /** + * @internal + * + * @brief does the IMAP server support AUTH=CRAM-MD5 ? + */ + bool auth_cram_md5; + + /** + * @internal + * + * @brief the CRAM-MD5 challenge (base64 decoded) as issued by the server + */ + QString chall_cram_md5; +}; + +/** + * @internal + */ +class KBiffPop : public KBiffSocket +{ +public: + KBiffPop(); + virtual ~KBiffPop(); + + bool command(const QString& line); + KBiffUidlList getUidlList() const; + + void close(); + + // Parses the banner message in the initial server response + bool parseBanner(void); + // Unset to disable APOP authentication + void setApop( bool enabled ); + /** + * @internal + * + * @brief Encapsulates all authentication to the POP3 server + * + * All authentication, including the determination of which authentication + * mechanism to use, is performed in this method. To add an + * authentication method, one will need to modify this method, + * KBiffMonitor::checkPop and KBiffPop::command + * + * @param user the user name required for authentication + * @param pass the password required for authentication + */ + bool authenticate(const QString& user, const QString& pass); + +protected: + KBiffUidlList uidlList; + /** + * @internal + * @brief does the server support APOP authentication ? + */ + bool auth_apop; + /** + * @internal + * @brief the APOP challenge from the server + */ + QCString chall_apop; + /** + * @internal + * @brief does the server support CRAM-MD5 authentication ? + */ + bool auth_cram_md5; + /** + * @internal + * @brief the CRAM-MD5 challenge (base64 decoded) + */ + QString chall_cram_md5; // the CRAM-MD5 challenge (base64 decoded) + /** + * @internal + * @brief does the user want APOP authentication + */ + bool use_apop; +}; + +/** + * @internal + */ +class KBiffNntp : public KBiffSocket +{ +public: + virtual ~KBiffNntp(); + + bool command(const QString& line); + int first() const; + int last() const; +protected: + int firstMsg; + int lastMsg; +}; + +typedef enum +{ + NewMail = 0, + NoMail, + OldMail, + NoConn, + UnknownState +} KBiffMailState; + +/** + * A "biff"-like class that can monitor local and remote mailboxes for new + * mail. KBiffMonitor currently supports eight protocols. + * + * <UL> + * <LI>mbox</LI> Unix style mailbox files + * <LI>pop3</LI> POP3 + * <LI>imap4</LI> imap4 + * <LI>maildir</LI> Mailboxes in maildir format + * <LI>mh</LI> Mailboxes in MH format + * <LI>file</LI> Simple files (no parsing) + * <LI>nntp</LI> USENET newsgroups + * <LI>imap4s</LI> imap4 over SSL + * <LI>pop3s</LI> POP3 over SSL + * </UL> + * + * A typical usage would look like so: + * + * <PRE> + * KBiffMonitor mon; + * mon.setMailbox("imap4://user:password@some.host.net/mailbox"); + * mon.setPollInterval(15); + * mon.start(); + * + * connect(&mon, SIGNAL(signal_newMail()), this, SLOT(processNewMail())); + * connect(&mon, SIGNAL(signal_oldMail()), this, SLOT(processOldMail())); + * connect(&mon, SIGNAL(signal_noMail()), this, SLOT(processNoMail())); + * connect(&mon, SIGNAL(signal_noConn()), this, SLOT(processNoConn())); + * </PRE> + * + * @short A "biff" class that monitors local and remote mailboxes + * @author Kurt Granroth <granroth@kde.org> + * @version $Id$ + */ +class KBiffMonitor : public QObject +{ + + Q_OBJECT +public: + + /** + * Constructor. Does not take any arguments + */ + KBiffMonitor(); + + /** + * Destructor. + */ + virtual ~KBiffMonitor(); + + /** + * Returns the current state of the mailbox (NewMail, OldMail, NoMail, or + * UnknownState) + */ + KBiffMailState getMailState() const { return mailState; } + + /** + * Returns the simpleURL of current mailbox being monitored + */ + const QString getMailbox() const { return simpleURL; } + + /** + * Sets or Returns the key of current mailbox being monitored + */ + const QString getMailboxKey() const { return key; } + + /** + * Returns the type of mailbox being monitored + */ + const QString getProtocol() const { return protocol; } + /** + * Returns <CODE>true</CODE> is KBiffMonitor is currently monitoring + * a mailbox. + */ + bool isRunning() { return started; } + + /** + * Returns the number of new messages for the current mailbox + */ + int newMessages() { return newCount; } + + /** + * Returns the number of messages for the current mailbox + */ + int curMessages() { return curCount; } + + + void saveConfig(); + void readConfig(); + +public slots: + /** + * Sets the mailbox to monitor. It uses a KBiffURL to specify the + * protocol, host, username, password, port and path (depending on + * protocol type). KBiffMonitor recognizes eight protocols: + * + * <UL> + * <LI>mbox</LI> Unix style mailbox files + * <LI>pop3</LI> POP3 + * <LI>imap4</LI> IMAP4 + * <LI>maildir</LI> Mailboxes in maildir format + * <LI>mh</LI> Mailboxes in MH format + * <LI>nttp</LI> USENET newsgroups + * <LI>imap4s</LI> imap4 over SSL + * <LI>pop3s</LI> POP3 over SSL + * </UL> + * + * Some examples: + * <PRE> + * mbox:/var/spool/mail/granroth + * </PRE> + * + * This would monitor a local file called '/var/spool/mail/granroth' + * + * <PRE> + * pop3://granroth:password@host.net:1234 + * </PRE> + * + * This would monitor POP3 mailbox 'granroth' on server 'host.net' + * using 1234 as the port and 'password' as the password. + * + * <PRE> + * imap4://granroth:password@host.net/Mail/mailbox + * </PRE> + * + * This would monitor IMAP4 mailbox 'Mail/mailbox' on server 'host.net' + * with 'granroth' as the user and 'password' as the password. + */ + void setMailbox(KBiffURL& url); + + /** + * Overloaded for convenience + */ + void setMailbox(const QString& url); + void setMailboxKey(const QString& k); + + /** + * Sets the password for the POP3 and IMAP4 protocols. + */ + void setPassword(const QString& password); + + /** + * Set the interval between mailbox reads. This is in seconds. + */ + void setPollInterval(const int interval); + + /** + * Start monitoring the mailbox + */ + void start(); + + /** + * Stop monitoring the mailbox + */ + void stop(); + + /** + * Fakes KBiffMonitor into thinking that the mailbox was just read + */ + void setMailboxIsRead(); + + /** + * Forces a mailbox check + */ + void checkMailNow(); + +signals: + /** + * This will get <CODE>emit</CODE>ed when new mail arrives + */ + void signal_newMail(); + + /** + * This will get <CODE>emit</CODE>ed when new mail arrives + */ + void signal_newMail(const int num_new, const QString& mailbox); + + /** + * This will get <CODE>emit</CODE>ed when no mail exists + */ + void signal_noMail(); + + /** + * This will get <CODE>emit</CODE>ed when no mail exists + */ + void signal_noMail(const QString& mailbox); + + /** + * This will get <CODE>emit</CODE>ed when the mailbox is read + */ + void signal_oldMail(); + + /** + * This will get <CODE>emit</CODE>ed when the mailbox is read + */ + void signal_oldMail(const QString& mailbox); + + /** + * This will get <CODE>emit</CODE>ed when no connection can be + * established + */ + void signal_noConn(); + + /** + * This will get <CODE>emit</CODE>ed when no connection can + * be established + */ + void signal_noConn(const QString& mailbox); + + /** + * This will get <CODE>emit</CODE>ed everytime mail will be + * fetched externally + */ + void signal_fetchMail(const QString& fetchClient); + + /** + * This will get <CODE>emit</CODE>ed everytime the mailbox + * should be checked (determined by @ref #setPollInterval) + */ + void signal_checkMail(); + + /** + * This will get <CODE>emit</CODE>ed everytime the mailbox is + * checked. It contains the current mailbox name, state, and number + * of new messages + */ + void signal_currentStatus(const int, const QString& , const KBiffMailState); + + /** + * This will get <CODE>emit</CODE>ed everytime there was an + * invalid login or incomplete connection to a remote server. + */ + void signal_invalidLogin(const QString& mailbox); + +protected: + void timerEvent(QTimerEvent *); + +protected slots: + void checkLocal(); + void checkMbox(); + void checkPop(); + void checkMaildir(); + void checkImap(); + void checkMHdir(); + void checkNntp(); + +protected: + // protected (non-slot) functions + void determineState(unsigned int size, const QDateTime& last_read, + const QDateTime& last_modified); + void determineState(unsigned int size); + + void determineState(KBiffUidlList uidl_list); + void determineState(KBiffMailState state); + void onStateChanged(); + int mboxMessages(); + + void invalidLogin(); + +private: + // General stuff + int poll; + int oldTimer; + bool started; + int newCount; + int curCount; + int oldCount; + bool firstRun; + + // Mailbox stuff + QString key; + QString simpleURL; + QString protocol; + QString mailbox; + QString server; + QString user; + QString password; + QString fetchCommand; + unsigned short int port; + bool preauth; + bool keepalive; + + // New state cache + unsigned int new_lastSize; + QDateTime new_lastRead; + QDateTime new_lastModified; + KBiffUidlList new_uidlList; + bool b_new_lastSize; + bool b_new_lastRead; + bool b_new_lastModified; + bool b_new_uidlList; + // State variables + KBiffMailState mailState; + unsigned int lastSize; + QDateTime lastRead; + QDateTime lastModified; + KBiffUidlList uidlList; + + // Socket protocols + KBiffImap *imap; + KBiffPop *pop; + KBiffNntp *nntp; +}; + +#endif // KBIFFMONITOR_H diff --git a/kbiff/kbiffurl.cpp b/kbiff/kbiffurl.cpp new file mode 100644 index 0000000..e6c633b --- /dev/null +++ b/kbiff/kbiffurl.cpp @@ -0,0 +1,175 @@ +/* + * kbiffurl.cpp + * Copyright (C) 1999-2002 Kurt Granroth <granroth@kde.org> + * Copyright (C) 1999 Bjorn Hansson <Bjorn.Hansson@signal.uu.se> + * + * This file contains the implementation of KBiffURL and + * + * $Id$ + */ +#include "kbiffurl.h" + +KBiffURL::KBiffURL() + : KURL() +{ +} + +KBiffURL::KBiffURL(const QString& _url) + : KURL(_url) +{ + /** + * There exists no search part in the nntp spec; let's go around that + */ + if (protocol() == "nntp") + { + QString urlStr(_url); + urlStr.replace(0,4, "imap4"); + *this = KBiffURL(urlStr); + setProtocol("nntp"); + } +} + +/** + * BNF description of the syntax (see RFC1738, HTTP syntax) + * ; HTTP + * + * httpurl = "http://" hostport [ "/" hpath [ "?" search ]] + * hpath = hsegment *[ "/" hsegment ] + * hsegment = *[ uchar | ";" | ":" | "@" | "&" | "=" ] + * search = *[ uchar | ";" | ":" | "@" | "&" | "=" ] + */ +QString KBiffURL::searchPar( const QString & _parName ) const +{ + const char *_searchPart, *_searchPos, *_parVal; + int n; + + // Set some initial values + n = 0; + _parVal = NULL; + + // Get the search part of the URL, i.e. the stuff after "?" + QString query_str(query()); + if (!query_str.isNull()) + query_str = query_str.remove(0,1); + _searchPart = query_str.ascii(); + + // Try to find the given parameter in the search part string + if ((n = findPos( _searchPart, _parName )) < 0) + return QString::null; + + /* + * Now, we know that the parameter name is found + */ + + // If no value is assigned, an empty string is returned + if (_searchPart[n] != '=') + return QString::null; + + // Set the beginning of the parameter value string + _parVal = &(_searchPart[n+1]); + + // Find the end of the assigned parameter value + _searchPos = strpbrk( _parVal, ";:@&=" ); + + // Return the assigned parameter value + if (_searchPos == NULL) + return QString( _parVal ); + else + return QString( _parVal ).left(_searchPos - _parVal); +} + +void KBiffURL::setSearchPar( const QString & _parName, const QString & _newParVal ) +{ + QString _newSearchPart; + const char *_searchPart, *_searchPos, *_parVal; + int index, len; + + // Get the search part of the URL, i.e. the stuff after "?" + QString query_str(query()); + + if (!query_str.isNull()) + query_str = query_str.remove(0,1); + _searchPart = query_str.ascii(); + + // Try to find the given parameter in the search part string + index = findPos( _searchPart, _parName ); + + // If the parameter name is not found it is simply appended + if (index < 0) + { + if (query_str.length() > 0) + { + _newSearchPart = query_str; + _newSearchPart += "&"; + } + _newSearchPart += _parName; + _newSearchPart += "="; + _newSearchPart += _newParVal; + } + else + { + _newSearchPart = _searchPart; + + // If no value is assigned, the new value is inserted + if (_searchPart[index] != '=') + { + _newSearchPart.insert( index, _newParVal ); + _newSearchPart.insert( index, '=' ); + } + + // Otherwise, the old value is replaced with the new one + else + { + // Point to the first character of the assigned value + index++; + + // Set the beginning of the parameter value string + _parVal = &(_searchPart[index]); + + // Get the length of the old parameter value + _searchPos = strpbrk( _parVal, ";:@&=" ); + + if (_searchPos == NULL) + len = strlen( _parVal ); + else + len = _searchPos - _parVal; + + _newSearchPart.replace( index, len, _newParVal ); + } + } + + setQuery( _newSearchPart ); +} + +int KBiffURL::findPos( const QString & _searchPart, const QString & _parName ) const +{ + const char *_searchPos; + int n = -1; + + _searchPos = _searchPart.ascii(); + while (_searchPos != NULL) + { + _searchPos = strstr( _searchPos, _parName.ascii() ); + + // If not found, a NULL string is returned + if (_searchPos == NULL) + return -1; + + // Find the index of the next character + n = _searchPos - _searchPart.ascii() + strlen(_parName.ascii()); + + // Stop searching if this is not a substring + if ((_searchPos == _searchPart || _searchPos[-1] == '&') && + (_searchPart[n] == '0' || strchr(";:@&=", _searchPart[n]) != NULL)) + return n; + + _searchPos = &(_searchPart.ascii()[n+1]); + } + + return -1; +} + +QString KBiffURL::pass() const +{ + return KURL::decode_string(KURL::pass()); +} diff --git a/kbiff/kbiffurl.h b/kbiff/kbiffurl.h new file mode 100644 index 0000000..82bc9b6 --- /dev/null +++ b/kbiff/kbiffurl.h @@ -0,0 +1,48 @@ +/* + * kbiffurl.h + * Copyright (C) 1999 Kurt Granroth <granroth@kde.org> + * Copyright (C) 1999 Bjorn Hansson <Bjorn.Hansson@signal.uu.se> + * + * $Id$ + * + */ +#ifndef KBIFFURL_H +#define KBIFFURL_H + +#include <kurl.h> + +/** + * This is a simple extension to the KURL class. + */ +class KBiffURL : public KURL +{ +public: + /** + * Default constructor + */ + KBiffURL(); + + /** + * Construct a KBiffURL object from _url + */ + KBiffURL(const QString& _url); + + /** + * Returns the parameter value found in the search part of the URL + */ + QString searchPar( const QString & _parName ) const; + + /** + * Sets a parameter value in the search part of the URL + */ + void setSearchPar( const QString & _parName, const QString & _newParVal ); + + QString pass() const; + +private: + /** + * Returns the position of a parameter within the search part + */ + int findPos( const QString & _searchPart, const QString & _parName ) const; +}; +#endif // KBIFFURL_H diff --git a/kbiff/led.cpp b/kbiff/led.cpp new file mode 100644 index 0000000..cc27d71 --- /dev/null +++ b/kbiff/led.cpp @@ -0,0 +1,81 @@ +/*************************************************************************** + led.cpp - description + ------------------- + begin : do okt 9 2003 + copyright : (C) 2003 by Roeland Merks + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "led.h" + +#ifdef HAVE_MLED +#include <fstream> +#include <string> +#include <fstream> +#include <iostream> +using namespace std; + +const char *ASUS_ACPI="/proc/acpi/asus/"; + +Led::Led() +{ + Led("wled"); +} + +Led::Led(const char *ledname) +{ + string fname(string(ASUS_ACPI)+string(ledname)); + + led=new ofstream(fname.c_str()); + + // If there is no LED, just give a one time warning on cerr + if (!(*led)) { + static bool error_given=false; + if (!error_given) { + cerr << "Warning: trying to use Asus LED, but no ACPI-entry found.\n"; + error_given=true; + } + } +} + +Led::~Led() +{ + Off(); + delete led; +} + + +void Led::On() +{ + if (*led) { + *led << 1; + led->flush(); + } +} + +void Led::Off() +{ + if (*led) { + *led << 0; + led->flush(); + } +} +#else +Led::Led() {} +Led::Led(const char *) {} +Led::~Led() {} +void Led::On() {} +void Led::Off() {} +#endif diff --git a/kbiff/led.h b/kbiff/led.h new file mode 100644 index 0000000..169b7ea --- /dev/null +++ b/kbiff/led.h @@ -0,0 +1,40 @@ +/*************************************************************************** + led.h - description + ------------------- + begin : wo okt 8 2003 + copyright : (C) 2003 by Roeland Merks +*/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef LED_H +#define LED_H + +#include <fstream> + +/** + *@author Roeland Merks + */ + +class Led +{ +public: + Led(); + Led(const char *ledname); + ~Led(); + void On(); + void Off(); + +private: + std::ofstream *led; +}; + +#endif + diff --git a/kbiff/lo16-app-kbiff.png b/kbiff/lo16-app-kbiff.png Binary files differnew file mode 100644 index 0000000..ad07177 --- /dev/null +++ b/kbiff/lo16-app-kbiff.png diff --git a/kbiff/lo32-app-kbiff.png b/kbiff/lo32-app-kbiff.png Binary files differnew file mode 100644 index 0000000..dc47f09 --- /dev/null +++ b/kbiff/lo32-app-kbiff.png diff --git a/kbiff/main.cpp b/kbiff/main.cpp new file mode 100644 index 0000000..5257c5f --- /dev/null +++ b/kbiff/main.cpp @@ -0,0 +1,87 @@ +#include "kbiff.h" +#include "version.h" +#include <kwin.h> +#include <kapp.h> +#include <klocale.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> + +#include "setupdlg.h" + +static const char *description = + I18N_NOOP("Full featured mail notification utility."); + +static KCmdLineOptions option[] = +{ + { "secure", I18N_NOOP("Run in secure mode"), 0 }, + { "profile <profile>", I18N_NOOP("Use 'profile'"), 0 }, + { 0, 0, 0 } +}; + +extern "C" KDE_EXPORT int kdemain(int argc, char *argv[]) +{ + KAboutData aboutData( "kbiff", I18N_NOOP("KBiff"), + kbiff_version, description, KAboutData::License_GPL, + "(c) 1998-2008, Kurt Granroth"); + aboutData.addAuthor("Kurt Granroth",0, "granroth@kde.org"); + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions(option); + + KApplication app; + KBiff kbiff(app.dcopClient()); + KBiffSetup* setup = 0; + bool is_secure = false; + bool have_profile = false; + QString profile; + + app.setMainWidget(&kbiff); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + is_secure = args->isSet("secure"); + + if (args->isSet("profile")) + { + profile = args->getOption("profile"); + have_profile = true; + } + + args->clear(); + + // restore this app if it is + if (kapp->isRestored()) + kbiff.readSessionConfig(); + else + { + // do we have the profile option? + if (have_profile) + { + setup = new KBiffSetup(profile, is_secure); + } + else + { + setup = new KBiffSetup(); + + if (!setup->exec()) + { + delete setup; + return 0; + } + } + kbiff.processSetup(setup, true); + + } + + // check if we are docked (only if restored) + if (kbiff.isDocked()) + { + kapp->setTopWidget(new QWidget); + KWin::setSystemTrayWindowFor(kbiff.winId(), 0); + } + else + kapp->setTopWidget(&kbiff); + + kbiff.show(); + + return app.exec(); +} diff --git a/kbiff/notify.cpp b/kbiff/notify.cpp new file mode 100644 index 0000000..2289372 --- /dev/null +++ b/kbiff/notify.cpp @@ -0,0 +1,95 @@ +/* + * notify.cpp + * Copyright (C) 1999-2008 Kurt Granroth <granroth@kde.org> + * + * This file contains the implementation of the KBiffNotify + * widget + */ +#include "notify.h" +#include "notify.moc" + +#include <qlayout.h> +#include <qlabel.h> +#include <qpixmap.h> +#include <qpushbutton.h> + +#include <kapp.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kprocess.h> +#include <kwin.h> + +KBiffNotify::KBiffNotify(QWidget *parent_, const int num_new, + const QString& mailbx) + : QDialog(parent_, 0, false, 0) +{ + KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon()); + setCaption(i18n("You have new mail!")); + + QLabel *pixmap = new QLabel(this); + pixmap->setPixmap(kapp->icon()); + pixmap->setFixedSize(pixmap->sizeHint()); + + QLabel *congrats = new QLabel(i18n("You have new mail!"), this); + QFont the_font(congrats->font()); + the_font.setBold(true); + congrats->setFont(the_font); + + QString msg; + msg = i18n("New Messages: %1").arg(num_new); + msgLabel = new QLabel(msg, this); + + msg = i18n("Mailbox: %1").arg(mailbx); + QLabel *which_one = new QLabel(msg, this); + + QPushButton *ok = new QPushButton(i18n("OK"), this); + ok->setDefault(true); + + QPushButton *launch = new QPushButton(i18n("Mailer"), this); + + // connect the signals to slots + connect(ok, SIGNAL(clicked()), SLOT(accept())); + connect(launch, SIGNAL(clicked()), SLOT(slotLaunchMailClient())); + connect(launch, SIGNAL(clicked()), this, SLOT(accept())); + + // Now do the layout + QVBoxLayout *info_layout = new QVBoxLayout(12); + info_layout->addWidget(congrats); + info_layout->addWidget(msgLabel); + info_layout->addWidget(which_one); + + QHBoxLayout *upper_layout = new QHBoxLayout; + upper_layout->addWidget(pixmap); + upper_layout->addLayout(info_layout, 1); + + QHBoxLayout *button_layout = new QHBoxLayout; + button_layout->addStretch(1); + button_layout->addWidget(launch); + button_layout->addWidget(ok); + button_layout->addStretch(1); + + QVBoxLayout *top_layout = new QVBoxLayout(this, 12); + top_layout->addLayout(upper_layout); + top_layout->addLayout(button_layout); + + mailbox = mailbx; + messages = num_new; +} + +KBiffNotify::~KBiffNotify() +{ +} + +void KBiffNotify::setNew(const int num_new) +{ + QString msg; + msg = i18n("New Messages: %1").arg(num_new); + msgLabel->setText(msg); + messages = num_new; +} + +void KBiffNotify::slotLaunchMailClient() +{ + emit(signalLaunchMailClient()); +} diff --git a/kbiff/notify.h b/kbiff/notify.h new file mode 100644 index 0000000..d31949b --- /dev/null +++ b/kbiff/notify.h @@ -0,0 +1,46 @@ +/* + * notify.h + * Copyright (C) 1999 Kurt Granroth <granroth@kde.org> + * + * This file contains the declaration of the KBiffNotify + * widget. + * + * $Id$ + */ +#ifndef KBIFFNOTIFY_H +#define KBIFFNOTIFY_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qdialog.h> +#include <qstring.h> + +class QLabel; + +class KBiffNotify : public QDialog +{ + Q_OBJECT +public: + KBiffNotify(QWidget *parent, const int num_new, const QString& mailbx); + virtual ~KBiffNotify(); + + const QString getMailbox() { return mailbox; } + int newMessages() { return messages; } + + void setNew(const int num_new); + +signals: + void signalLaunchMailClient(); + +protected slots: + void slotLaunchMailClient(); + +protected: + QString mailbox; + QLabel* msgLabel; + int messages; +}; + +#endif // KBIFFNOTIFY_H diff --git a/kbiff/pics/Makefile.am b/kbiff/pics/Makefile.am new file mode 100644 index 0000000..2d6751b --- /dev/null +++ b/kbiff/pics/Makefile.am @@ -0,0 +1,8 @@ +# Files to install +pics_DATA = mini-newmail.png mini-nomail.png mini-oldmail.png \ + newmail.png nomail.png oldmail.png mailbox.png delete.png \ + playsound.png mini-noconn.png noconn.png mini-stopped.png \ + stopped.png + +# This is where it will all be installed +picsdir = $(kde_datadir)/kbiff/pics diff --git a/kbiff/pics/Makefile.in b/kbiff/pics/Makefile.in new file mode 100644 index 0000000..70d5972 --- /dev/null +++ b/kbiff/pics/Makefile.in @@ -0,0 +1,591 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# KDE tags expanded automatically by am_edit - $Revision$ +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = kbiff/pics +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(picsdir)" +picsDATA_INSTALL = $(INSTALL_DATA) +DATA = $(pics_DATA) +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 1 +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AUTOCONF = @AUTOCONF@ +AUTODIRS = @AUTODIRS@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOPIDLNG = @DCOPIDLNG@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_PERMISSIVE_FLAG = @ENABLE_PERMISSIVE_FLAG@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FRAMEWORK_COREAUDIO = @FRAMEWORK_COREAUDIO@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +HAVE_GCC_VISIBILITY = @HAVE_GCC_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KCFG_DEPENDENCIES = @KCFG_DEPENDENCIES@ +KCONFIG_COMPILER = @KCONFIG_COMPILER@ +KDECONFIG = @KDECONFIG@ +KDE_CHECK_PLUGIN = @KDE_CHECK_PLUGIN@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_MT_LDFLAGS = @KDE_MT_LDFLAGS@ +KDE_MT_LIBS = @KDE_MT_LIBS@ +KDE_NO_UNDEFINED = @KDE_NO_UNDEFINED@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_USE_FPIE = @KDE_USE_FPIE@ +KDE_USE_NMCHECK_FALSE = @KDE_USE_NMCHECK_FALSE@ +KDE_USE_NMCHECK_TRUE = @KDE_USE_NMCHECK_TRUE@ +KDE_USE_PIE = @KDE_USE_PIE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_AS_NEEDED = @LDFLAGS_AS_NEEDED@ +LDFLAGS_NEW_DTAGS = @LDFLAGS_NEW_DTAGS@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBJPEG = @LIBJPEG@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBRESOLV = @LIBRESOLV@ +LIBS = @LIBS@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KABC = @LIB_KABC@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDED = @LIB_KDED@ +LIB_KDEPIM = @LIB_KDEPIM@ +LIB_KDEPRINT = @LIB_KDEPRINT@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KDNSSD = @LIB_KDNSSD@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIMPROXY = @LIB_KIMPROXY@ +LIB_KIO = @LIB_KIO@ +LIB_KJS = @LIB_KJS@ +LIB_KNEWSTUFF = @LIB_KNEWSTUFF@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_KUNITTEST = @LIB_KUNITTEST@ +LIB_KUTILS = @LIB_KUTILS@ +LIB_POLL = @LIB_POLL@ +LIB_QPE = @LIB_QPE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LIB_XEXT = @LIB_XEXT@ +LIB_XRENDER = @LIB_XRENDER@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MAKEKDEWIDGETS = @MAKEKDEWIDGETS@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MKDIR_P = @MKDIR_P@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CFLAGS = @NOOPT_CFLAGS@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +QTE_NORTTI = @QTE_NORTTI@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@ +XGETTEXT = @XGETTEXT@ +XMKMF = @XMKMF@ +XMLLINT = @XMLLINT@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +X_RPATH = @X_RPATH@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_kcfgdir = @kde_kcfgdir@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_styledir = @kde_styledir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +kde_widgetdir = @kde_widgetdir@ +kdeinitdir = @kdeinitdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ +xdg_appsdir = @xdg_appsdir@ +xdg_directorydir = @xdg_directorydir@ +xdg_menudir = @xdg_menudir@ + +# Files to install +pics_DATA = mini-newmail.png mini-nomail.png mini-oldmail.png \ + newmail.png nomail.png oldmail.png mailbox.png delete.png \ + playsound.png mini-noconn.png noconn.png mini-stopped.png \ + stopped.png + + +# This is where it will all be installed +picsdir = $(kde_datadir)/kbiff/pics +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +#>- @for dep in $?; do \ +#>- case '$(am__configure_deps)' in \ +#>- *$$dep*) \ +#>- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ +#>- && exit 0; \ +#>- exit 1;; \ +#>- esac; \ +#>- done; \ +#>- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kbiff/pics/Makefile'; \ +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu kbiff/pics/Makefile +#>+ 12 + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kbiff/pics/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu kbiff/pics/Makefile + cd $(top_srcdir) && perl admin/am_edit -padmin kbiff/pics/Makefile.in +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-picsDATA: $(pics_DATA) + @$(NORMAL_INSTALL) + test -z "$(picsdir)" || $(MKDIR_P) "$(DESTDIR)$(picsdir)" + @list='$(pics_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(picsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(picsdir)/$$f'"; \ + $(picsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(picsdir)/$$f"; \ + done + +uninstall-picsDATA: + @$(NORMAL_UNINSTALL) + @list='$(pics_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(picsdir)/$$f'"; \ + rm -f "$(DESTDIR)$(picsdir)/$$f"; \ + done +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(picsdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +#>- clean-am: clean-generic clean-libtool mostlyclean-am +#>+ 1 +clean-am: clean-bcheck clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-picsDATA + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-picsDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-picsDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am uninstall-picsDATA + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + + +#>+ 2 +KDE_DIST=newmail.png mini-newmail.png mini-oldmail.png Makefile.in mailbox.png playsound.png mini-nomail.png noconn.png oldmail.png delete.png nomail.png mini-noconn.png stopped.png mini-stopped.png Makefile.am + +#>+ 2 +docs-am: + +#>+ 15 +force-reedit: + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu kbiff/pics/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu kbiff/pics/Makefile + cd $(top_srcdir) && perl admin/am_edit -padmin kbiff/pics/Makefile.in + + +#>+ 21 +clean-bcheck: + rm -f *.bchecktest.cc *.bchecktest.cc.class a.out + +bcheck: bcheck-am + +bcheck-am: + @for i in ; do \ + if test $(srcdir)/$$i -nt $$i.bchecktest.cc; then \ + echo "int main() {return 0;}" > $$i.bchecktest.cc ; \ + echo "#include \"$$i\"" >> $$i.bchecktest.cc ; \ + echo "$$i"; \ + if ! $(CXX) $(DEFS) -I. -I$(srcdir) -I$(top_builddir) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) --dump-class-hierarchy -c $$i.bchecktest.cc; then \ + rm -f $$i.bchecktest.cc; exit 1; \ + fi ; \ + echo "" >> $$i.bchecktest.cc.class; \ + perl $(top_srcdir)/admin/bcheck.pl $$i.bchecktest.cc.class || { rm -f $$i.bchecktest.cc; exit 1; }; \ + rm -f a.out; \ + fi ; \ + done + + +#>+ 3 +final: + $(MAKE) all-am + +#>+ 3 +final-install: + $(MAKE) install-am + +#>+ 3 +no-final: + $(MAKE) all-am + +#>+ 3 +no-final-install: + $(MAKE) install-am + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo + +#>+ 3 +nmcheck: +nmcheck-am: nmcheck diff --git a/kbiff/pics/delete.png b/kbiff/pics/delete.png Binary files differnew file mode 100644 index 0000000..b148c55 --- /dev/null +++ b/kbiff/pics/delete.png diff --git a/kbiff/pics/mailbox.png b/kbiff/pics/mailbox.png Binary files differnew file mode 100644 index 0000000..339202b --- /dev/null +++ b/kbiff/pics/mailbox.png diff --git a/kbiff/pics/mini-newmail.png b/kbiff/pics/mini-newmail.png Binary files differnew file mode 100644 index 0000000..30999c4 --- /dev/null +++ b/kbiff/pics/mini-newmail.png diff --git a/kbiff/pics/mini-noconn.png b/kbiff/pics/mini-noconn.png Binary files differnew file mode 100644 index 0000000..7253c1f --- /dev/null +++ b/kbiff/pics/mini-noconn.png diff --git a/kbiff/pics/mini-nomail.png b/kbiff/pics/mini-nomail.png Binary files differnew file mode 100644 index 0000000..50b491a --- /dev/null +++ b/kbiff/pics/mini-nomail.png diff --git a/kbiff/pics/mini-oldmail.png b/kbiff/pics/mini-oldmail.png Binary files differnew file mode 100644 index 0000000..5c87bf1 --- /dev/null +++ b/kbiff/pics/mini-oldmail.png diff --git a/kbiff/pics/mini-stopped.png b/kbiff/pics/mini-stopped.png Binary files differnew file mode 100644 index 0000000..2679bf2 --- /dev/null +++ b/kbiff/pics/mini-stopped.png diff --git a/kbiff/pics/newmail.png b/kbiff/pics/newmail.png Binary files differnew file mode 100644 index 0000000..f634622 --- /dev/null +++ b/kbiff/pics/newmail.png diff --git a/kbiff/pics/noconn.png b/kbiff/pics/noconn.png Binary files differnew file mode 100644 index 0000000..7b828ff --- /dev/null +++ b/kbiff/pics/noconn.png diff --git a/kbiff/pics/nomail.png b/kbiff/pics/nomail.png Binary files differnew file mode 100644 index 0000000..05fc59a --- /dev/null +++ b/kbiff/pics/nomail.png diff --git a/kbiff/pics/oldmail.png b/kbiff/pics/oldmail.png Binary files differnew file mode 100644 index 0000000..b4e8c76 --- /dev/null +++ b/kbiff/pics/oldmail.png diff --git a/kbiff/pics/playsound.png b/kbiff/pics/playsound.png Binary files differnew file mode 100644 index 0000000..d28d012 --- /dev/null +++ b/kbiff/pics/playsound.png diff --git a/kbiff/pics/stopped.png b/kbiff/pics/stopped.png Binary files differnew file mode 100644 index 0000000..ddc4750 --- /dev/null +++ b/kbiff/pics/stopped.png diff --git a/kbiff/setupdlg.cpp b/kbiff/setupdlg.cpp new file mode 100644 index 0000000..ba2c1a3 --- /dev/null +++ b/kbiff/setupdlg.cpp @@ -0,0 +1,2015 @@ +/* + * setupdlg.cpp + * Copyright (C) 1999-2008 Kurt Granroth <granroth@kde.org> + * + * This file contains the implementation of the setup dialog + * class for KBiff. + */ +#include "setupdlg.h" +#include "setupdlg.moc" + +#include <qgroupbox.h> +#include <qfileinfo.h> +#include <qlineedit.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <qheader.h> +#include <qtabwidget.h> + +#include <qpixmap.h> +#include <qfont.h> +#include <qlabel.h> +#include <qstrlist.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qdict.h> +#include <qlist.h> +#include <qwhatsthis.h> +#include <qstylesheet.h> + +#include <kaudioplayer.h> +#include <kmessagebox.h> +#include <kfiledialog.h> +#include <kapp.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kstddirs.h> +#include <ksimpleconfig.h> +#include <kbiffurl.h> +#include <kprocess.h> +#include <krun.h> +#include <kurllabel.h> +#include <kwin.h> + +#include <kbiffcodec.h> +#include "version.h" + +#include <stdlib.h> +#include <unistd.h> +#include <pwd.h> +#include <sys/types.h> + +#define CONFIG_FILE "kbiffrc" + +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif + +#ifndef _PATH_MAILDIR +#define _PATH_MAILDIR "/var/spool/mail" +#endif + +/////////////////////////////////////////////////////////////////////////// +// KBiffSetup +/////////////////////////////////////////////////////////////////////////// +KBiffSetup::KBiffSetup(const QString& profile_, bool secure_) + : KDialog(0, 0, true) +{ + // set the icon just to be cute + KWin::setIcons(winId(), kapp->icon(), kapp->miniIcon()); + + // make sure the profile is *something* + QString the_profile; + if (profile_.isEmpty() || profile_.isNull()) + the_profile = getSomeProfile(); + else + the_profile = profile_; + + setCaption(i18n("KBiff Setup")); + + // The profile combo box and buttons all go in this groupbox + QGroupBox* profile_groupbox = new QGroupBox(i18n("Profile"), this); + + // combo box to hold the profile names + comboProfile = new QComboBox(false, profile_groupbox); + comboProfile->setSizeLimit(10); + + QString whatsthis = i18n( + "This is a list of all of the KBiff <b>profiles</b><p>" + "A profile is a logical grouping of settings for either one " + "mailbox or several mailboxes. Each profile gets one icon " + "and one new mail sound and one... well, everything"); + QWhatsThis::add(comboProfile, whatsthis); + + // Add New Profile button + QPushButton *new_profile_button = new QPushButton(i18n("&New..."), + profile_groupbox); + whatsthis = i18n("Create a new profile"); + QWhatsThis::add(new_profile_button, whatsthis); + connect(new_profile_button, SIGNAL(clicked()), SLOT(slotAddNewProfile())); + + // Rename Profile button + QPushButton *rename_profile_button = new QPushButton(i18n("&Rename..."), + profile_groupbox); + whatsthis = i18n("Rename the current profile"); + QWhatsThis::add(rename_profile_button, whatsthis); + connect(rename_profile_button, SIGNAL(clicked()), SLOT(slotRenameProfile())); + + // Delete Profile button + QPushButton *delete_profile_button = new QPushButton(i18n("&Delete"), + profile_groupbox); + whatsthis = i18n("Delete the current profile"); + QWhatsThis::add(delete_profile_button, whatsthis); + connect(delete_profile_button, SIGNAL(clicked()), SLOT(slotDeleteProfile())); + + // setup the tabs + QTabWidget *tabctl = new QTabWidget(this); + generalTab = new KBiffGeneralTab(the_profile, tabctl); + newmailTab = new KBiffNewMailTab(the_profile, tabctl); + mailboxTab = new KBiffMailboxTab(the_profile, tabctl); + aboutTab = new KBiffAboutTab(tabctl); + + connect(comboProfile, SIGNAL(highlighted(const QString&)), + generalTab, SLOT(readConfig(const QString&))); + connect(comboProfile, SIGNAL(highlighted(const QString&)), + newmailTab, SLOT(readConfig(const QString&))); + connect(comboProfile, SIGNAL(highlighted(const QString&)), + mailboxTab, SLOT(readConfig(const QString&))); + + // add the tabs + tabctl->addTab(generalTab, i18n("General")); + tabctl->addTab(newmailTab, i18n("New Mail")); + tabctl->addTab(mailboxTab, i18n("Mailbox")); + tabctl->addTab(aboutTab, i18n("About")); + + // help button + QPushButton *help_button = new QPushButton(i18n("&Help"), this); + connect(help_button, SIGNAL(clicked()), SLOT(invokeHelp())); + + // ok button + QPushButton *ok_button = new QPushButton(i18n("&OK"), this); + ok_button->setDefault(true); + connect(ok_button, SIGNAL(clicked()), SLOT(slotDone())); + + // cancel button + QPushButton *cancel_button = new QPushButton(i18n("&Cancel"), this); + connect(cancel_button, SIGNAL(clicked()), SLOT(reject())); + + // are we secure? + isSecure = secure_; + + // NOW, SETUP ALL THE LAYOUTS! + // This layout handles the buttons for the profile combobox + QBoxLayout *pro_button_layout = new QBoxLayout(QBoxLayout::LeftToRight, 12); + pro_button_layout->addWidget(new_profile_button); + pro_button_layout->addWidget(rename_profile_button); + pro_button_layout->addWidget(delete_profile_button); + + // This layout handles the upper profile groupbox + QBoxLayout *profile_layout = new QBoxLayout(profile_groupbox, + QBoxLayout::Down, 12); + profile_layout->addSpacing(8); + profile_layout->addWidget(comboProfile); + profile_layout->addLayout(pro_button_layout); + + // This layout handles the dialog buttons + QBoxLayout *dialog_button_layout = new QBoxLayout(QBoxLayout::LeftToRight, + 12); + dialog_button_layout->addWidget(help_button); + dialog_button_layout->addStretch(1); + dialog_button_layout->addWidget(ok_button); + dialog_button_layout->addWidget(cancel_button); + + // This is the outermost layout + QBoxLayout *top_layout = new QBoxLayout(this, QBoxLayout::Down, 12); + top_layout->addWidget(profile_groupbox); + top_layout->addWidget(tabctl, 1); + top_layout->addLayout(dialog_button_layout); + + // Read in the config for this profile + readConfig(the_profile); +} + +KBiffSetup::~KBiffSetup() +{ +} + +bool KBiffSetup::getSecure() const +{ + return isSecure; +} + +const QString KBiffSetup::getProfile() const +{ + return comboProfile->currentText(); +} + +const KBiffURL KBiffSetup::getCurrentMailbox() const +{ + return mailboxTab->getMailbox(); +} + +const QList<KBiffMailbox> KBiffSetup::getMailboxList() const +{ + return mailboxTab->getMailboxList(); +} + +const QString KBiffSetup::getMailClient() const +{ + return generalTab->getMailClient(); +} + +const QString KBiffSetup::getNoMailIcon() const +{ + return generalTab->getButtonNoMail(); +} + +const QString KBiffSetup::getNewMailIcon() const +{ + return generalTab->getButtonNewMail(); +} + +const QString KBiffSetup::getOldMailIcon() const +{ + return generalTab->getButtonOldMail(); +} + +const QString KBiffSetup::getNoConnIcon() const +{ + return generalTab->getButtonNoConn(); +} + +const QString KBiffSetup::getStoppedIcon() const +{ + return generalTab->getButtonStopped(); +} + +bool KBiffSetup::getSessionManagement() const +{ + return generalTab->getSessionManagement(); +} + +bool KBiffSetup::getCheckStartup() const +{ + return generalTab->getCheckStartup(); +} + +bool KBiffSetup::getDock() const +{ + return generalTab->getDock(); +} + +unsigned int KBiffSetup::getPoll() const +{ + return generalTab->getPoll(); +} + +const QString KBiffSetup::getRunCommandPath() const +{ + return newmailTab->getRunCommandPath(); +} + +const QString KBiffSetup::getRunResetCommandPath() const +{ + return newmailTab->getRunResetCommandPath(); +} + +const QString KBiffSetup::getPlaySoundPath() const +{ + return newmailTab->getPlaySoundPath(); +} + +bool KBiffSetup::getRunCommand() const +{ + return newmailTab->getRunCommand(); +} + +bool KBiffSetup::getRunResetCommand() const +{ + return newmailTab->getRunResetCommand(); +} + +bool KBiffSetup::getPlaySound() const +{ + return newmailTab->getPlaySound(); +} + +bool KBiffSetup::getSystemBeep() const +{ + return newmailTab->getSystemBeep(); +} + +bool KBiffSetup::getNotify() const +{ + return newmailTab->getNotify(); +} + +bool KBiffSetup::getStatus() const +{ + return newmailTab->getStatus(); +} + +void KBiffSetup::invokeHelp() +{ + kapp->invokeHelp(); +} + +void KBiffSetup::readConfig(const QString& profile_) +{ + QStringList profile_list; + + // open the config file + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true); + config->setDollarExpansion(false); + + config->setGroup("General"); + + // read in the mailboxes + profile_list = config->readListEntry("Profiles", ','); + int number_of_mailboxes = profile_list.count(); + delete config; + + // check if we have any mailboxes to read in + if (number_of_mailboxes > 0) + { + comboProfile->clear(); + + // load up the combo box + comboProfile->insertStringList(profile_list); + + // read in the data from the first mailbox if we don't have a name + for (int i = 0; i < comboProfile->count(); i++) + { + if (QString(profile_) == comboProfile->text(i)) + { + comboProfile->setCurrentItem(i); + break; + } + } + } + else + comboProfile->insertItem(profile_); +} + +QString KBiffSetup::getSomeProfile() const +{ + QStringList profile_list; + + // open the config file + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true); + config->setGroup("General"); + + // read in the mailboxes + profile_list = config->readListEntry("Profiles", ','); + int number_of_mailboxes = profile_list.count(); + delete config; + + // get the first mailbox if it exists + if (number_of_mailboxes > 0) + return profile_list.last(); + else + return QString("Inbox"); +} + +void KBiffSetup::saveConfig() +{ + // open the config file for writing + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE); + + config->setGroup("General"); + + // get the list of profiles + QStringList profile_list; + for (int i = 0; i < comboProfile->count(); i++) + profile_list.append(comboProfile->text(i)); + + // write the mailboxes + config->writeEntry("Profiles", profile_list, ','); + + delete config; +} + +/////////////////////////////////////////////////////////////////////// +// Protected slots +/////////////////////////////////////////////////////////////////////// +void KBiffSetup::slotDone() +{ + QString profile = comboProfile->currentText(); + saveConfig(); + generalTab->saveConfig(profile); + newmailTab->saveConfig(profile); + mailboxTab->saveConfig(profile); + accept(); +} + +void KBiffSetup::slotAddNewProfile() +{ + KBiffNewDlg dlg; + + // popup the name chooser + dlg.setCaption(i18n("New Profile")); + if (dlg.exec()) + { + QString profile_name = dlg.getName(); + + // bail out if we already have this name + for (int i = 0; i < comboProfile->count(); i++) + { + if (profile_name == comboProfile->text(i)) + return; + } + + // continue only if we received a decent name + if (profile_name.isEmpty() == false) + { + comboProfile->insertItem(profile_name, 0); + + saveConfig(); + readConfig(profile_name); + generalTab->readConfig(profile_name); + newmailTab->readConfig(profile_name); + mailboxTab->readConfig(profile_name); + } + } +} + +void KBiffSetup::slotRenameProfile() +{ + KBiffNewDlg dlg; + QString title; + QString old_profile = comboProfile->currentText(); + + title = i18n("Rename Profile: %1").arg(old_profile); + dlg.setCaption(title); + // popup the name chooser + if (dlg.exec()) + { + QString profile_name = dlg.getName(); + + // bail out if we already have this name + for (int i = 0; i < comboProfile->count(); i++) + { + if (profile_name == comboProfile->text(i)) + return; + } + + // continue only if we received a decent name + if (profile_name.isNull() == false) + { + comboProfile->removeItem(comboProfile->currentItem()); + comboProfile->insertItem(profile_name, 0); + + // remove the reference from the config file + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE); + // nuke the group + config->deleteGroup(old_profile, true); + delete config; + + // now save the profile settings + saveConfig(); + generalTab->saveConfig(profile_name); + newmailTab->saveConfig(profile_name); + mailboxTab->saveConfig(profile_name); + } + } +} + +void KBiffSetup::slotDeleteProfile() +{ + QString title, msg; + QString profile = comboProfile->currentText(); + + title = i18n("Delete Profile: %1").arg(profile); + msg = i18n("Are you sure you wish to delete this profile?\n"); + + switch (KMessageBox::warningYesNo(this, msg, title)) + { + case KMessageBox::Yes: + { + comboProfile->removeItem(comboProfile->currentItem()); + + saveConfig(); + + // remove the reference from the config file + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE); + // nuke the group + config->deleteGroup(profile, true); + delete config; + + if (comboProfile->count() == 0) + { + readConfig("Inbox"); + generalTab->readConfig("Inbox"); + newmailTab->readConfig("Inbox"); + mailboxTab->readConfig("Inbox"); + } + else + { + readConfig(comboProfile->currentText()); + generalTab->readConfig(comboProfile->currentText()); + newmailTab->readConfig(comboProfile->currentText()); + mailboxTab->readConfig(comboProfile->currentText()); + } + + break; + } + case KMessageBox::No: + default: + break; + } +} + +/////////////////////////////////////////////////////////////////////// +// KBiffGeneralTab +/////////////////////////////////////////////////////////////////////// +KBiffGeneralTab::KBiffGeneralTab(const QString& profile_, QWidget *parent_) + : QWidget(parent_) +{ + // the poll time (in seconds) + QLabel* poll_label = new QLabel(i18n("P&oll (sec):"), this); + editPoll = new QLineEdit(this); + poll_label->setBuddy(editPoll); + QString whatsthis = i18n( + "This is the interval (in seconds) that KBiff will check " + "for new mail. Typically, this can be quite small (under " + "60 seconds) for local mailboxes but should be around 5 " + "minutes (300 seconds) for remote mailboxes"); + QWhatsThis::add(editPoll, whatsthis); + + // the command to run when clicked + QLabel *mail_label = new QLabel(i18n("&Mail client:"), this); + editCommand = new QLineEdit(this); + mail_label->setBuddy(editCommand); + whatsthis = i18n( + "This is the mail client that KBiff was use when you click " + "on the icon or the Mailer button. If it's not in your path, " + "then you must specify the location using an absolute path. " + "This recognizes the <b>%m</b> and <b>%u</b> arguments. The " + "first is replaced with the first mailbox containing new mail " + "and the latter is replaced with the mailbox's URL."); + QWhatsThis::add(editCommand, whatsthis); + + // do we dock automatically? + checkDock = new QCheckBox(i18n("Doc&k in panel"), this); + + // should we support session management? + checkNoSession = new QCheckBox(i18n("Use &session management"), this); + + // should we check at startup? + checkNoStartup = new QCheckBox(i18n("Don't &check at startup"), this); + whatsthis = i18n( + "This option is for those people using KBiff to check their " + "IMAP4 or POP3 account over a dial-up connection. If KBiff " + "tries to connect at startup and you are not connected, the " + "DNS lookup will hang for a long time. If this is checked, " + "then KBiff will not check for new mail on startup. You will " + "need to manually start it every time you connect"); + QWhatsThis::add(checkNoStartup, whatsthis); + + // group box to hold the icons together + QGroupBox* icons_groupbox = new QGroupBox(i18n("Icons:"), this); + + // "stopped" pixmap button + QLabel* stopped_label = new QLabel(i18n("&Stopped:"), icons_groupbox); + buttonStopped = new KIconButton(icons_groupbox); + buttonStopped->setFixedSize(50, 50); + buttonStopped->setIconType(KIcon::User, KIcon::Any, true); + stopped_label->setBuddy(buttonStopped); + + // "no mailbox" pixmap button + QLabel* noconn_label = new QLabel(i18n("No Mail&box:"), icons_groupbox); + buttonNoConn = new KIconButton(icons_groupbox); + buttonNoConn->setFixedSize(50, 50); + buttonNoConn->setIconType(KIcon::User, KIcon::Any, true); + noconn_label->setBuddy(buttonNoConn); + + // "no mail" pixmap button + QLabel* nomail_label = new QLabel(i18n("No M&ail:"), icons_groupbox); + buttonNoMail = new KIconButton(icons_groupbox); + buttonNoMail->setIconType(KIcon::User, KIcon::Any, true); + buttonNoMail->setFixedSize(50, 50); + nomail_label->setBuddy(buttonNoMail); + + // "old mail" pixmap button + QLabel* oldmail_label = new QLabel(i18n("O&ld Mail:"), icons_groupbox); + buttonOldMail = new KIconButton(icons_groupbox); + buttonOldMail->setIconType(KIcon::User, KIcon::Any, true); + buttonOldMail->setFixedSize(50, 50); + oldmail_label->setBuddy(buttonOldMail); + + // "new mail" pixmap button + QLabel* newmail_label = new QLabel(i18n("N&ew Mail:"), icons_groupbox); + buttonNewMail = new KIconButton(icons_groupbox); + buttonNewMail->setIconType(KIcon::User, KIcon::Any, true); + buttonNewMail->setFixedSize(50, 50); + newmail_label->setBuddy(buttonNewMail); + + // poll time layout + QGridLayout *info_layout = new QGridLayout(5, 3, 8); + info_layout->addWidget(poll_label, 0, 0); + info_layout->addWidget(editPoll, 0, 1); + info_layout->setColStretch(2, 1); + + info_layout->addWidget(mail_label, 1, 0); + info_layout->addMultiCellWidget(editCommand, 1, 1, 1, 2); + info_layout->addMultiCellWidget(checkDock, 2, 2, 1, 2); + info_layout->addMultiCellWidget(checkNoSession, 3, 3, 1, 2); + info_layout->addMultiCellWidget(checkNoStartup, 4, 4, 1, 2); + + // icons layout + QVBoxLayout *stopped_layout = new QVBoxLayout; + stopped_layout->addWidget(stopped_label); + stopped_layout->addWidget(buttonStopped); + + QVBoxLayout *no_conn_layout = new QVBoxLayout; + no_conn_layout->addWidget(noconn_label); + no_conn_layout->addWidget(buttonNoConn); + + QVBoxLayout *no_mail_layout = new QVBoxLayout; + no_mail_layout->addWidget(nomail_label); + no_mail_layout->addWidget(buttonNoMail); + + QVBoxLayout *old_mail_layout = new QVBoxLayout; + old_mail_layout->addWidget(oldmail_label); + old_mail_layout->addWidget(buttonOldMail); + + QVBoxLayout *new_mail_layout = new QVBoxLayout; + new_mail_layout->addWidget(newmail_label); + new_mail_layout->addWidget(buttonNewMail); + + QHBoxLayout *inner_icon_layout = new QHBoxLayout; + inner_icon_layout->addStretch(1); + inner_icon_layout->addLayout(stopped_layout); + inner_icon_layout->addStretch(1); + inner_icon_layout->addLayout(no_conn_layout); + inner_icon_layout->addStretch(1); + inner_icon_layout->addLayout(no_mail_layout); + inner_icon_layout->addStretch(1); + inner_icon_layout->addLayout(old_mail_layout); + inner_icon_layout->addStretch(1); + inner_icon_layout->addLayout(new_mail_layout); + inner_icon_layout->addStretch(1); + + QBoxLayout *outer_icon_layout = new QBoxLayout(icons_groupbox, + QBoxLayout::Down, 5); + outer_icon_layout->addSpacing(8); + outer_icon_layout->addLayout(inner_icon_layout); + outer_icon_layout->addStretch(1); + + // main "outer" layout for this tab + QVBoxLayout *top_layout = new QVBoxLayout(this, 12); + top_layout->addLayout(info_layout); + top_layout->addWidget(icons_groupbox); + top_layout->addStretch(1); + + // now read in the config data for this profile + readConfig(profile_); +} + +KBiffGeneralTab::~KBiffGeneralTab() +{ +} + +bool KBiffGeneralTab::getSessionManagement() const +{ + return checkNoSession->isChecked(); +} + +bool KBiffGeneralTab::getCheckStartup() const +{ + return checkNoStartup->isChecked(); +} + +bool KBiffGeneralTab::getDock() const +{ + return checkDock->isChecked(); +} + +const QString KBiffGeneralTab::getButtonOldMail() const +{ + return buttonOldMail->icon(); +} + +const QString KBiffGeneralTab::getButtonNewMail() const +{ + return buttonNewMail->icon(); +} + +const QString KBiffGeneralTab::getButtonNoMail() const +{ + return buttonNoMail->icon(); +} + +const QString KBiffGeneralTab::getButtonNoConn() const +{ + return buttonNoConn->icon(); +} + +const QString KBiffGeneralTab::getButtonStopped() const +{ + return buttonStopped->icon(); +} + +const QString KBiffGeneralTab::getMailClient() const +{ + return editCommand->text(); +} + +int KBiffGeneralTab::getPoll() const +{ + return QString(editPoll->text()).toInt(); +} + +void KBiffGeneralTab::readConfig(const QString& profile_) +{ + // open the config file + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true); + + config->setGroup(profile_); + + // someday, we need to read in the system email prefs + editPoll->setText(config->readEntry("Poll", "60")); + editCommand->setText(config->readEntry("MailClient", "kmail -check")); + checkDock->setChecked(config->readBoolEntry("Docked", true)); + checkNoSession->setChecked(config->readBoolEntry("Sessions", true)); + checkNoStartup->setChecked(config->readBoolEntry("DontCheck", false)); + + QString stopped, no_mail, old_mail, new_mail, no_conn; + stopped = config->readEntry("StoppedPixmap", "stopped"); + no_mail = config->readEntry("NoMailPixmap", "nomail"); + old_mail = config->readEntry("OldMailPixmap", "oldmail"); + new_mail = config->readEntry("NewMailPixmap", "newmail"); + no_conn = config->readEntry("NoConnPixmap", "noconn"); + + buttonOldMail->setIcon(old_mail); + buttonNewMail->setIcon(new_mail); + buttonNoMail->setIcon(no_mail); + buttonNoConn->setIcon(no_conn); + buttonStopped->setIcon(stopped); + + delete config; +} + +static QString justIconName(const QString& icon_name) +{ + // the following code is a bit of a hack, but there is a rationale + // to it. if possible, we want to just save the name of the icons + // (without extension), and not the whole path due to name munging + // later on. + QFileInfo info( icon_name ); + + // we first test if the basename (filename without extensions) is + // the same as the filename. if it is, then we are perfect. no + // need to do anything further + if ( info.baseName() == info.fileName() ) + return icon_name; + + // now we see if we can load based just on the basename + QPixmap icon = KGlobal::iconLoader()->loadIcon( info.baseName(), KIcon::User ); + + // if it's null, then it's in a non-standard path so we must use an + // absolute path. no need to go further + if ( icon.isNull() ) + return icon_name; + + // now we know that the icon loader can find it.. but is it the same + // one as the one the user picked? + if ( KGlobal::iconLoader()->iconPath( info.baseName(), KIcon::User ) != + KGlobal::iconLoader()->iconPath( icon_name, KIcon::User ) ) + return icon_name; + + // FINALLY done! if we got this far, then we know that the icon + // loader can handle just the name and that the icon returned is the + // same one that the user wanted. whew! + return info.baseName(); +} + +void KBiffGeneralTab::saveConfig(const QString& profile_) +{ + // open the config file for writing + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE); + + config->setGroup(profile_); + + config->writeEntry("Poll", editPoll->text()); + config->writeEntry("MailClient", editCommand->text()); + config->writeEntry("Docked", checkDock->isChecked()); + config->writeEntry("Sessions", checkNoSession->isChecked()); + config->writeEntry("DontCheck", checkNoStartup->isChecked()); + config->writeEntry("NoMailPixmap", justIconName(buttonNoMail->icon())); + config->writeEntry("NewMailPixmap", justIconName(buttonNewMail->icon())); + config->writeEntry("OldMailPixmap", justIconName(buttonOldMail->icon())); + config->writeEntry("NoConnPixmap", justIconName(buttonNoConn->icon())); + config->writeEntry("StoppedPixmap", justIconName(buttonStopped->icon())); + delete config; +} + +/////////////////////////////////////////////////////////////////////// +// KBiffNewMailTab +/////////////////////////////////////////////////////////////////////// +KBiffNewMailTab::KBiffNewMailTab(const QString& profile_, QWidget *parent_) + : QWidget(parent_) +{ + // setup the Run Command stuff + checkRunCommand = new QCheckBox(i18n("R&un Command"), this); + editRunCommand = new QLineEdit(this); + buttonBrowseRunCommand = new QPushButton(i18n("Browse"), this); + + // setup the Run Reset Command stuff + checkRunResetCommand = new QCheckBox(i18n("R&un Reset-Command"), this); + editRunResetCommand = new QLineEdit(this); + buttonBrowseRunResetCommand = new QPushButton(i18n("Browse"), this); + + // setup the Play Sound stuff + checkPlaySound = new QCheckBox(i18n("&Play Sound"), this); + editPlaySound = new QLineEdit(this); + buttonBrowsePlaySound = new QPushButton(i18n("Browse"), this); + + buttonTestPlaySound = new QPushButton(this); + buttonTestPlaySound->setPixmap(UserIcon("playsound")); + + // setup the System stuff + checkBeep = new QCheckBox(i18n("System &Beep"), this); + checkNotify = new QCheckBox(i18n("N&otify"), this); + checkStatus = new QCheckBox(i18n("&Floating Status"), this); + + // connect some slots and signals + connect(buttonBrowsePlaySound, SIGNAL(clicked()), SLOT(browsePlaySound())); + connect(buttonBrowseRunCommand, SIGNAL(clicked()), SLOT(browseRunCommand())); + connect(buttonBrowseRunResetCommand, SIGNAL(clicked()), SLOT(browseRunResetCommand())); + connect(checkPlaySound, SIGNAL(toggled(bool)), SLOT(enablePlaySound(bool))); + connect(buttonTestPlaySound, SIGNAL(clicked()), SLOT(testPlaySound())); + connect(checkRunCommand, SIGNAL(toggled(bool)), SLOT(enableRunCommand(bool))); + connect(checkRunResetCommand, SIGNAL(toggled(bool)), SLOT(enableRunResetCommand(bool))); + + // NOW DO THE LAYOUT + QHBoxLayout *run_command_layout = new QHBoxLayout(5); + run_command_layout->addWidget(editRunCommand); + run_command_layout->addWidget(buttonBrowseRunCommand); + + QHBoxLayout *run_reset_command_layout = new QHBoxLayout(5); + run_reset_command_layout->addWidget(editRunResetCommand); + run_reset_command_layout->addWidget(buttonBrowseRunResetCommand); + + QHBoxLayout *play_sound_layout = new QHBoxLayout(5); + play_sound_layout->addWidget(buttonTestPlaySound, 0); + play_sound_layout->addWidget(editPlaySound, 1); + play_sound_layout->addWidget(buttonBrowsePlaySound); + + QVBoxLayout *top_layout = new QVBoxLayout(this, 5); + top_layout->addWidget(checkRunCommand); + top_layout->addLayout(run_command_layout); + + top_layout->addWidget(checkRunResetCommand); + top_layout->addLayout(run_reset_command_layout); + + top_layout->addWidget(checkPlaySound); + top_layout->addLayout(play_sound_layout); + + top_layout->addWidget(checkBeep); + top_layout->addWidget(checkNotify); + top_layout->addWidget(checkStatus); + top_layout->addStretch(1); + + readConfig(profile_); +} + +KBiffNewMailTab::~KBiffNewMailTab() +{ +} + +void KBiffNewMailTab::testPlaySound() +{ + KAudioPlayer::play(getPlaySoundPath()); +} + +void KBiffNewMailTab::readConfig(const QString& profile_) +{ + // open the config file + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true); + + config->setGroup(profile_); + + checkRunCommand->setChecked(config->readBoolEntry("RunCommand", false)); + checkRunResetCommand->setChecked(config->readBoolEntry("RunResetCommand", false)); + checkPlaySound->setChecked(config->readBoolEntry("PlaySound", false)); + checkBeep->setChecked(config->readBoolEntry("SystemBeep", true)); + checkNotify->setChecked(config->readBoolEntry("Notify", true)); + checkStatus->setChecked(config->readBoolEntry("Status", true)); + editRunCommand->setText(config->readEntry("RunCommandPath")); + editRunResetCommand->setText(config->readEntry("RunResetCommandPath")); + editPlaySound->setText(config->readEntry("PlaySoundPath")); + + enableRunCommand(checkRunCommand->isChecked()); + enableRunResetCommand(checkRunResetCommand->isChecked()); + enablePlaySound(checkPlaySound->isChecked()); + + delete config; +} + +void KBiffNewMailTab::saveConfig(const QString& profile_) +{ + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE); + + config->setGroup(profile_); + + config->writeEntry("RunCommand", checkRunCommand->isChecked()); + config->writeEntry("RunResetCommand", checkRunResetCommand->isChecked()); + config->writeEntry("PlaySound", checkPlaySound->isChecked()); + config->writeEntry("SystemBeep", checkBeep->isChecked()); + config->writeEntry("Notify", checkNotify->isChecked()); + config->writeEntry("Status", checkStatus->isChecked()); + config->writeEntry("RunCommandPath", editRunCommand->text()); + config->writeEntry("RunResetCommandPath", editRunResetCommand->text()); + config->writeEntry("PlaySoundPath", editPlaySound->text()); + + delete config; +} + +bool KBiffNewMailTab::getRunCommand() const +{ + return checkRunCommand->isChecked(); +} + +const QString KBiffNewMailTab::getRunCommandPath() const +{ + return editRunCommand->text(); +} + +bool KBiffNewMailTab::getRunResetCommand() const +{ + return checkRunResetCommand->isChecked(); +} + +const QString KBiffNewMailTab::getRunResetCommandPath() const +{ + return editRunResetCommand->text(); +} + +bool KBiffNewMailTab::getPlaySound() const +{ + return checkPlaySound->isChecked(); +} + +const QString KBiffNewMailTab::getPlaySoundPath() const +{ + return editPlaySound->text(); +} + +bool KBiffNewMailTab::getSystemBeep() const +{ + return checkBeep->isChecked(); +} + +bool KBiffNewMailTab::getNotify() const +{ + return checkNotify->isChecked(); +} + +bool KBiffNewMailTab::getStatus() const +{ + return checkStatus->isChecked(); +} + +void KBiffNewMailTab::enableRunCommand(bool enable) +{ + editRunCommand->setEnabled(enable); + buttonBrowseRunCommand->setEnabled(enable); +} + +void KBiffNewMailTab::enableRunResetCommand(bool enable) +{ + editRunResetCommand->setEnabled(enable); + buttonBrowseRunResetCommand->setEnabled(enable); +} + +void KBiffNewMailTab::enablePlaySound(bool enable) +{ + editPlaySound->setEnabled(enable); + buttonBrowsePlaySound->setEnabled(enable); + buttonTestPlaySound->setEnabled(enable); +} + +void KBiffNewMailTab::browseRunCommand() +{ + + KURL url = KFileDialog::getOpenURL(); + + if( url.isEmpty() ) + return; + + if( !url.isLocalFile() ) + { + KMessageBox::sorry( 0L, i18n( "Only local files can be executed." ) ); + return; + } + + editRunCommand->setText( url.path() ); +} + +void KBiffNewMailTab::browseRunResetCommand() +{ + + KURL url = KFileDialog::getOpenURL(); + + if( url.isEmpty() ) + return; + + if( !url.isLocalFile() ) + { + return; + } + + editRunResetCommand->setText( url.path() ); +} + +void KBiffNewMailTab::browsePlaySound() +{ + + KURL url = KFileDialog::getOpenURL(); + + if( url.isEmpty() ) + return; + + if( !url.isLocalFile() ) + { + KMessageBox::sorry( 0L, i18n( "Only local files are supported yet." ) ); + return; + } + + editPlaySound->setText( url.path() ); +} + + +////////////////////////////////////////////////////////////////////// +// KBiffMailboxTab +////////////////////////////////////////////////////////////////////// +KBiffMailboxAdvanced::KBiffMailboxAdvanced() + : KDialog(0, 0, true, 0) +{ + setCaption(i18n("Advanced Options")); + + QLabel *mailbox_label = new QLabel(i18n("Mailbox &URL:"), this); + mailbox_label->setAlignment(AlignVCenter | AlignRight); + mailbox = new QLineEdit(this); + mailbox_label->setBuddy(mailbox); + QString whatsthis = i18n( + "KBiff uses URLs to specify a mailbox and the parameters " + "to the mailbox. This allows you to modify the URL directly. " + "Do so <i>only</i> if you really really know what you're doing!"); + QWhatsThis::add(mailbox, whatsthis); + + QLabel *port_label = new QLabel(i18n("P&ort:"), this); + port_label->setAlignment(AlignVCenter | AlignRight); + port = new QLineEdit(this); + port_label->setBuddy(port); + whatsthis = i18n( + "This allows you to specify the port of your socket protocol. " + "It usually is correct, so the only time you would change it is " + "if you are accessing a non-standard server or going through " + "a proxy (or something similar"); + QWhatsThis::add(port, whatsthis); + + whatsthis = i18n( + "IMAP4, POP3, and NNTP sockets each have their own timeout " + "before they give up. If you have a slow connection, you might " + "want to set this to some random high value"); + QLabel *timeout_label = new QLabel(i18n("&Timeout:"), this); + timeout_label->setAlignment(AlignVCenter | AlignRight); + timeout = new QLineEdit(this); + QWhatsThis::add(timeout, whatsthis); + timeout_label->setBuddy(timeout); + + preauth = new QCheckBox(i18n("&PREAUTH"), this); + preauth->setEnabled(false); + whatsthis = i18n( + "Check this if you login to your IMAP4 or POP3 server before " + "kbiff accesses it."); + QWhatsThis::add(preauth, whatsthis); + + keepalive = new QCheckBox(i18n("&Keep Alive"), this); + keepalive->setEnabled(false); + whatsthis = i18n( + "If this is checked, then the IMAP4, POP3, or NNTP client " + "will not log off each time"); + QWhatsThis::add(keepalive, whatsthis); + + async = new QCheckBox(i18n("&Asynchronous"), this); + async->setEnabled(false); + whatsthis = i18n( + "If this is checked, then the socket protocols will access " + "the server asynchronously"); + QWhatsThis::add(async, whatsthis); + + apop = new QCheckBox(i18n("&Disable APOP"), this); + apop->setEnabled(false); + whatsthis = i18n( + "If this is checked, then POP mailboxes will not use Authenticated POP where available, " + "and send passwords in plaintext over the network, which is a security risk"); + QWhatsThis::add(apop, whatsthis); + + QPushButton *ok = new QPushButton(i18n("&OK"), this); + ok->setDefault(true); + + QPushButton *cancel = new QPushButton(i18n("&Cancel"), this); + + // connect all the slots to signals + connect(preauth, SIGNAL(toggled(bool)), SLOT(preauthModified(bool))); + connect(keepalive, SIGNAL(toggled(bool)), SLOT(keepaliveModified(bool))); + connect(async, SIGNAL(toggled(bool)), SLOT(asyncModified(bool))); + connect(apop, SIGNAL(toggled(bool)), SLOT(apopModified(bool))); + connect(port, SIGNAL(textChanged(const QString&)), + SLOT(portModified(const QString&))); + connect(ok, SIGNAL(clicked()), SLOT(accept())); + connect(cancel, SIGNAL(clicked()), SLOT(reject())); + connect(timeout, SIGNAL(textChanged(const QString&)), + SLOT(timeoutModified(const QString&))); + + // NOW DO THE LAYOUT + QGridLayout *top_layout = new QGridLayout(this, 7, 4, 12); + top_layout->addWidget(mailbox_label, 0, 0); + top_layout->addMultiCellWidget(mailbox, 0, 0, 1, 3); + top_layout->addWidget(port_label, 1, 0); + top_layout->addWidget(port, 1, 1); + top_layout->addWidget(timeout_label, 1, 2); + top_layout->addWidget(timeout, 1, 3); + top_layout->addWidget(preauth, 2, 1); + top_layout->addWidget(keepalive, 3, 1); + top_layout->addWidget(async, 4, 1); + top_layout->addWidget(apop, 4, 1); + top_layout->addWidget(ok, 6, 2); + top_layout->addWidget(cancel, 6, 3); +} + +KBiffMailboxAdvanced::~KBiffMailboxAdvanced() +{ +} + +const KBiffURL KBiffMailboxAdvanced::getMailbox() const +{ + KBiffURL url(mailbox->text()); + url.setPass(password); + return url; +} + +unsigned int KBiffMailboxAdvanced::getPort() const +{ + return QString(port->text()).toInt(); +} + +void KBiffMailboxAdvanced::setMailbox(const KBiffURL& url) +{ + password = url.pass(); + KBiffURL new_url(url); + new_url.setPass(""); + mailbox->setText(new_url.url()); +} + +void KBiffMailboxAdvanced::setPort(unsigned int the_port, bool enable) +{ + port->setEnabled(enable); + port->setText(QString().setNum(the_port)); +} + +void KBiffMailboxAdvanced::portModified(const QString& text) +{ + KBiffURL url = getMailbox(); + url.setPort(QString(text).toInt()); + setMailbox(url); +} + +void KBiffMailboxAdvanced::setTimeout(unsigned int the_to, bool enable) +{ + timeout->setEnabled(enable); + timeout->setText(QString().setNum(the_to)); +} + +void KBiffMailboxAdvanced::timeoutModified(const QString& text) +{ + KBiffURL url = getMailbox(); + url.setSearchPar("timeout", text.local8Bit()); + setMailbox(url); +} + +void KBiffMailboxAdvanced::preauthModified(bool is_preauth) +{ + KBiffURL url = getMailbox(); + if (is_preauth) + url.setSearchPar("preauth", "yes"); + else + url.setSearchPar("preauth", "no"); + setMailbox(url); +} + +void KBiffMailboxAdvanced::keepaliveModified(bool is_keepalive) +{ + KBiffURL url = getMailbox(); + if (is_keepalive) + url.setSearchPar("keepalive", "yes"); + else + url.setSearchPar("keepalive", "no"); + setMailbox(url); +} + +void KBiffMailboxAdvanced::asyncModified(bool is_async) +{ + KBiffURL url = getMailbox(); + if (is_async) + url.setSearchPar("async", "yes"); + else + url.setSearchPar("async", "no"); + setMailbox(url); +} + +void KBiffMailboxAdvanced::apopModified(bool disable_apop) +{ + KBiffURL url = getMailbox(); + if ( url.protocol() == "pop3" || url.protocol() == "pop3s" ) + { + if ( disable_apop ) + url.setSearchPar("apop", "no"); + else + url.setSearchPar("apop", "yes"); + setMailbox(url); + } +} + +void KBiffMailboxAdvanced::setPreauth(bool on) +{ + preauth->setEnabled(true); + preauth->setChecked(on); +} + +void KBiffMailboxAdvanced::setKeepalive(bool on) +{ + keepalive->setEnabled(true); + keepalive->setChecked(on); +} + +void KBiffMailboxAdvanced::setAsync(bool on) +{ + async->setEnabled(true); + async->setChecked(on); +} + +void KBiffMailboxAdvanced::setDisableApop(bool on) +{ + apop->setEnabled(true); + apop->setChecked(on); +} + +bool KBiffMailboxAdvanced::getPreauth() const +{ + return preauth->isChecked(); +} + +KBiffMailboxTab::KBiffMailboxTab(const QString& profile_, QWidget *parent_) + : QWidget(parent_), mailboxHash(new QDict<KBiffMailbox>) +{ + if (mailboxHash) + mailboxHash->setAutoDelete(true); + + mailboxes = new QListView(this); + mailboxes->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); + mailboxes->addColumn(i18n("Mailbox:")); + mailboxes->header()->hide(); + + QPushButton *new_mailbox = new QPushButton(this); + new_mailbox->setPixmap(UserIcon("mailbox")); + QToolTip::add(new_mailbox, i18n("New Mailbox")); + + QPushButton *delete_mailbox = new QPushButton(this); + delete_mailbox->setPixmap(UserIcon("delete")); + QToolTip::add(delete_mailbox, i18n("Delete Mailbox")); + + QLabel *protocol_label = new QLabel(i18n("Pro&tocol:"), this); + comboProtocol = new QComboBox(this); + comboProtocol->insertItem(""); + comboProtocol->insertItem("mbox"); + comboProtocol->insertItem("maildir"); + comboProtocol->insertItem("imap4"); + comboProtocol->insertItem("pop3"); + comboProtocol->insertItem("mh"); + comboProtocol->insertItem("file"); + comboProtocol->insertItem("nntp"); +#ifdef USE_SSL + comboProtocol->insertItem("imap4s"); + comboProtocol->insertItem("pop3s"); +#endif // USE_SSL + protocol_label->setBuddy(comboProtocol); + + QLabel *mailbox_label = new QLabel(i18n("&Mailbox:"), this); + editMailbox = new QLineEdit(this); + mailbox_label->setBuddy(editMailbox); + buttonBrowse = new QPushButton("...", this); + + QLabel *server_label = new QLabel(i18n("&Server:"), this); + editServer = new QLineEdit(this); + server_label->setBuddy(editServer); + + QLabel *user_label = new QLabel(i18n("&User:"), this); + editUser = new QLineEdit(this); + user_label->setBuddy(editUser); + + QLabel *password_label = new QLabel(i18n("P&assword:"), this); + editPassword = new QLineEdit(this); + editPassword->setEchoMode(QLineEdit::Password); + password_label->setBuddy(editPassword); + + checkStorePassword = new QCheckBox(i18n("S&tore password"), this); + QPushButton *advanced_button = new QPushButton(i18n("&Advanced"), this); + + // the command to run before polling + QGroupBox *fetch_box = new QGroupBox(this); + fetch_box->setTitle(i18n("Pre-&Polling Command")); + fetch_box->setColumnLayout(0, Qt::Vertical ); + fetch_box->layout()->setSpacing(0); + fetch_box->layout()->setMargin(0); + + checkFetchCommand = new QCheckBox(i18n("&Enable"), fetch_box); + editFetchCommand = new QLineEdit(fetch_box); + buttonBrowseFetchCommand = new QPushButton(i18n("Browse"), fetch_box); + QString whatsthis = i18n( + "This command shall be run <em>before</em> KBiff polls for new " + "mail. It is useful for those people that want to download their " + "POP3 mail regularly using (for instance) 'fetchmail'"); + QWhatsThis::add(checkFetchCommand, whatsthis); + QWhatsThis::add(editFetchCommand, whatsthis); + QWhatsThis::add(buttonBrowseFetchCommand, whatsthis); + enableFetchCommand(false); + + // connect all the signals + connect(mailboxes, SIGNAL(selectionChanged(QListViewItem *)), + SLOT(slotMailboxSelected(QListViewItem *))); + connect(new_mailbox, SIGNAL(clicked()), SLOT(slotNewMailbox())); + connect(delete_mailbox, SIGNAL(clicked()), SLOT(slotDeleteMailbox())); + connect(comboProtocol, SIGNAL(highlighted(int)), + SLOT(protocolSelected(int))); + connect(buttonBrowse, SIGNAL(clicked()), SLOT(browse())); + connect(advanced_button, SIGNAL(clicked()), SLOT(advanced())); + connect(buttonBrowseFetchCommand, SIGNAL(clicked()), SLOT(browseFetchCommand())); + connect(checkFetchCommand, SIGNAL(toggled(bool)), SLOT(enableFetchCommand(bool))); + + // NOW DO THE LAYOUT + QHBoxLayout *fetch_command_layout = new QHBoxLayout(5); + fetch_command_layout->addWidget(editFetchCommand, 1); + fetch_command_layout->addWidget(buttonBrowseFetchCommand); + + QVBoxLayout *group_layout = new QVBoxLayout(fetch_box->layout()); + group_layout->setAlignment(Qt::AlignTop); + group_layout->setSpacing(6); + group_layout->setMargin(11); + group_layout->addWidget(checkFetchCommand); + group_layout->addLayout(fetch_command_layout); + + QHBoxLayout *advanced_layout = new QHBoxLayout; + advanced_layout->addStretch(1); + advanced_layout->addWidget(advanced_button); + + QGridLayout *param_layout = new QGridLayout(6, 3, 12); + param_layout->addWidget(protocol_label, 0, 0); + param_layout->addWidget(comboProtocol, 0, 1, 1); + param_layout->addWidget(buttonBrowse, 0, 2); + param_layout->addWidget(mailbox_label, 1, 0); + param_layout->addMultiCellWidget(editMailbox, 1, 1, 1, 2); + param_layout->addWidget(server_label, 2, 0); + param_layout->addMultiCellWidget(editServer, 2, 2, 1, 2); + param_layout->addWidget(user_label, 3, 0); + param_layout->addMultiCellWidget(editUser, 3, 3, 1, 2); + param_layout->addWidget(password_label, 4, 0); + param_layout->addMultiCellWidget(editPassword, 4, 4, 1, 2); + param_layout->addMultiCellWidget(checkStorePassword, 5, 5, 1, 2); + param_layout->setColStretch(1, 1); + + QVBoxLayout *right_side_layout = new QVBoxLayout; + right_side_layout->addLayout(param_layout); + right_side_layout->addWidget(fetch_box); + right_side_layout->addLayout(advanced_layout); + right_side_layout->addStretch(1); + + QGridLayout *mailbox_layout = new QGridLayout(2, 2, 1); + mailbox_layout->addMultiCellWidget(mailboxes, 0, 0, 0, 1); + mailbox_layout->addWidget(new_mailbox, 1, 0); + mailbox_layout->addWidget(delete_mailbox, 1, 1); + + QHBoxLayout *top_layout = new QHBoxLayout(this, 12); + top_layout->addLayout(mailbox_layout); + top_layout->addLayout(right_side_layout); + + readConfig(profile_); +} + +KBiffMailboxTab::~KBiffMailboxTab() +{ + delete mailboxHash; +} + +void KBiffMailboxTab::readConfig(const QString& profile_) +{ + // initialize some variables that need initing + oldItem = 0; + + // open the config file + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE, true); + config->setDollarExpansion(false); + + mailboxHash->clear(); + mailboxes->clear(); + + config->setGroup(profile_); + + QStringList mailbox_list; + + mailbox_list = config->readListEntry("Mailboxes", ','); + int number_of_mailboxes = mailbox_list.count(); + + if (number_of_mailboxes > 0) + { + for (unsigned int i = 0; i < mailbox_list.count(); i+=3) + { + KBiffMailbox *mailbox = new KBiffMailbox(); + mailbox->key = *mailbox_list.at(i); + mailbox->url = KBiffURL(*mailbox_list.at(i+1)); + QString password(KBiffCodecs::base64Decode(*mailbox_list.at(i+2))); + + if (password.isEmpty()) + mailbox->store = false; + else + { + mailbox->store = true; + mailbox->url.setPass(password); + } + + QListViewItem *item = new QListViewItem(mailboxes, mailbox->key); + item->setPixmap(0, QPixmap(UserIcon("mailbox"))); + + mailboxHash->insert(mailbox->key, mailbox); + } + } + else + { + KBiffMailbox *mailbox = new KBiffMailbox(); + mailbox->key = i18n("Default"); + mailbox->store = false; + mailbox->url = defaultMailbox(); + mailboxHash->insert(mailbox->key, mailbox); + + QListViewItem *item = new QListViewItem(mailboxes, mailbox->key); + item->setPixmap(0, QPixmap(UserIcon("mailbox"))); + } + + mailboxes->setSelected(mailboxes->firstChild(), true); + delete config; +} + +void KBiffMailboxTab::saveConfig(const QString& profile_) +{ + // open the config file + KSimpleConfig *config = new KSimpleConfig(CONFIG_FILE); + config->setDollarExpansion(false); + + config->setGroup(profile_); + + QStringList mailbox_list; + + for (QListViewItem *item = mailboxes->firstChild(); + item; + item = item->nextSibling()) + { + KBiffMailbox *mailbox = new KBiffMailbox(); + QString item_text(item->text(0)); + + // if this mailbox is the current one, then use the current + // settings instead of the hash + if (item == mailboxes->currentItem()) + { + mailbox->store = checkStorePassword->isChecked(); + mailbox->url = getMailbox(); + + mailboxHash->replace(item_text, mailbox); + } + + mailbox = mailboxHash->find(item_text); + + QString password(KBiffCodecs::base64Encode(mailbox->url.pass().local8Bit())); + KBiffURL url = mailbox->url; + url.setPass(""); + + if (mailbox->store == false) + password = ""; + + mailbox_list.append(item_text); + mailbox_list.append(url.url()); + mailbox_list.append(password); + } + + config->writeEntry("Mailboxes", mailbox_list, ','); + delete config; +} + +void KBiffMailboxTab::enableFetchCommand(bool enable) +{ + editFetchCommand->setEnabled(enable); + buttonBrowseFetchCommand->setEnabled(enable); +} + +void KBiffMailboxTab::browseFetchCommand() +{ + KURL url = KFileDialog::getOpenURL(); + + if( url.isEmpty() ) + return; + + if( !url.isLocalFile() ) + { + KMessageBox::sorry( 0L, i18n( "Only local files can be executed." ) ); + return; + } + + editFetchCommand->setText( url.path() ); +} + +void KBiffMailboxTab::setMailbox(const KBiffURL& url) +{ + QString prot(url.protocol()); + + if (prot == "mbox") + protocolSelected(1); + else if (prot == "maildir") + protocolSelected(2); + else if (prot == "imap4") + protocolSelected(3); + else if (prot == "pop3") + protocolSelected(4); + else if (prot == "mh") + protocolSelected(5); + else if (prot == "file") + protocolSelected(6); + else if (prot == "nntp") + protocolSelected(7); +#ifdef USE_SSL + else if (prot == "imap4s") + protocolSelected(8); + else if (prot == "pop3s") + protocolSelected(9); +#endif // USE_SSL + else + return; + + if (editMailbox->isEnabled()) + { + QString path(url.path()); + if (((prot == "imap4") || (prot == "nntp") || (prot == "imap4s")) && !path.isEmpty() && path[0] == '/') + path.remove(0, 1); + + editMailbox->setText(path); + } + + port = url.port(); + + if (editServer->isEnabled()) + editServer->setText(url.host()); + if (editUser->isEnabled()) + { + QString user(url.user()); + editUser->setText(user); + } + if (editPassword->isEnabled()) + { + QString passwd(url.pass()); + editPassword->setText(passwd); + } + + timeout = url.searchPar("timeout").toInt(); + preauth = url.searchPar("preauth") == "yes" ? true : false; + keepalive = url.searchPar("keepalive") == "yes" ? true : false; + async = url.searchPar("async") == "yes" ? true : false; + useApop = url.searchPar("apop") == "no" ? false : true; + + QString fetch = url.searchPar("fetch"); + checkFetchCommand->setChecked(!fetch.isEmpty()); + editFetchCommand->setText(fetch); +} + +const KBiffURL KBiffMailboxTab::getMailbox() const +{ + KBiffURL url; + + url.setProtocol(comboProtocol->currentText()); + QString prot(url.protocol()); + + if (editUser->isEnabled()) + { + QString user(editUser->text()); + url.setUser(user); + } + + if (editPassword->isEnabled()) + { + QString passwd(editPassword->text()); + url.setPass(passwd); + } + + if (editServer->isEnabled()) + url.setHost(editServer->text()); + + url.setPort(port); + + if (editMailbox->isEnabled()) + { + QString path(editMailbox->text()); + if (!path.isEmpty() && path[0] != '/') + path.prepend("/"); + url.setPath(path); + } + + if ((prot == "imap4") || (prot == "pop3") || (prot == "nntp") || (prot == "imap4s") || (prot == "pop3s")) + { + if (keepalive) + url.setSearchPar("keepalive", "yes"); + else + url.setSearchPar("keepalive", "no"); + + if (async) + url.setSearchPar("async", "yes"); + else + url.setSearchPar("async", "no"); + + if ((prot == "pop3s") || (prot == "pop3") ) + { + if (useApop) + url.setSearchPar("apop", "yes"); + else + url.setSearchPar("apop", "no"); + } + url.setSearchPar("timeout", QString().setNum(timeout)); + } + + if (checkFetchCommand->isChecked() && !editFetchCommand->text().isEmpty()) + url.setSearchPar("fetch", editFetchCommand->text()); + + return url; +} + +const QList<KBiffMailbox> KBiffMailboxTab::getMailboxList() const +{ + QList<KBiffMailbox> mbox_list; + + for (QListViewItem *item = mailboxes->firstChild(); + item; + item = item->nextSibling()) + { + KBiffMailbox *mailbox = mailboxHash->find(item->text(0)); + // without the next line the key of the first mailbox is lost. + // it's a mystery for me + mailbox->key = item->text(0); + mbox_list.append(mailbox); + } + return mbox_list; +} + +void KBiffMailboxTab::slotDeleteMailbox() +{ + /* only delete the non default mailboxes */ + if (mailboxes->childCount() == 1) + return; + + /* need some "Are you sure?" code here */ + QListViewItem *item = mailboxes->currentItem(); + + mailboxHash->remove(item->text(0)); + mailboxes->takeItem(item); + item = 0; + + mailboxes->setSelected(mailboxes->firstChild(), true); +} + +void KBiffMailboxTab::slotNewMailbox() +{ + KBiffNewDlg dlg; + + // popup the name chooser + dlg.setCaption(i18n("New Mailbox")); + if (dlg.exec()) + { + QString mailbox_name = dlg.getName(); + + // continue only if we received a decent name + if (mailbox_name.isEmpty() == false) + { + QListViewItem *item = new QListViewItem(mailboxes, mailbox_name); + item->setPixmap(0, QPixmap(UserIcon("mailbox"))); + + KBiffMailbox *mailbox = new KBiffMailbox(); + mailbox->store = false; + mailbox->url = defaultMailbox(); + + mailboxHash->insert(mailbox_name, mailbox); + mailboxes->setSelected(item, true); + } + } +} + +void KBiffMailboxTab::slotMailboxSelected(QListViewItem *item) +{ + KBiffMailbox *mailbox; + + // if an "old" item exists, save the current info as it + if (oldItem && !oldItem->text(0).isNull()) + { + mailbox = mailboxHash->find(oldItem->text(0)); + + if (mailbox) + { + // change the hash only if the item is different + KBiffURL url(getMailbox()); + bool checked = checkStorePassword->isChecked(); + if (mailbox->url.url() != url.url() || mailbox->store != checked) + { + mailbox->url = getMailbox(); + mailbox->store = checkStorePassword->isChecked(); + } + } + } + + mailbox = mailboxHash->find(item->text(0)); + + if (mailbox) + { + setMailbox(mailbox->url); + checkStorePassword->setChecked(mailbox->store); + + // save this as the "old" item + oldItem = item; + } +} + +void KBiffMailboxTab::protocolSelected(int protocol) +{ + comboProtocol->setCurrentItem(protocol); + + switch (protocol) + { + case 1: // mbox + case 2: // maildir + case 5: // mh + case 6: // file + port = 0; + buttonBrowse->setEnabled(true); + editMailbox->setEnabled(true); + editServer->setEnabled(false); + editUser->setEnabled(false); + editPassword->setEnabled(false); + checkStorePassword->setEnabled(false); + break; + case 3: // IMAP4 + port = 143; + timeout = 10; + editMailbox->setEnabled(true); + buttonBrowse->setEnabled(true); + editServer->setEnabled(true); + editUser->setEnabled(true); + editPassword->setEnabled(true); + checkStorePassword->setEnabled(true); + break; +#ifdef USE_SSL + case 8: // IMAP4S + port = 993; + timeout = 10; + editMailbox->setEnabled(true); + buttonBrowse->setEnabled(true); + editServer->setEnabled(true); + editUser->setEnabled(true); + editPassword->setEnabled(true); + checkStorePassword->setEnabled(true); + break; +#endif // USE_SSL + case 7: // NNTP + port = 119; + timeout = 10; + editMailbox->setEnabled(true); + buttonBrowse->setEnabled(false); + editServer->setEnabled(true); + editUser->setEnabled(true); + editPassword->setEnabled(true); + checkStorePassword->setEnabled(true); + break; + case 4: // POP3 + port = 110; + timeout = 10; + editMailbox->setEnabled(false); + buttonBrowse->setEnabled(false); + editServer->setEnabled(true); + editUser->setEnabled(true); + editPassword->setEnabled(true); + checkStorePassword->setEnabled(true); + break; +#ifdef USE_SSL + case 9: // POP3S + port = 995; + timeout = 10; + editMailbox->setEnabled(false); + buttonBrowse->setEnabled(false); + editServer->setEnabled(true); + editUser->setEnabled(true); + editPassword->setEnabled(true); + checkStorePassword->setEnabled(true); + break; +#endif // USE_SSL + default: // blank + port = 0; + timeout = 0; + editMailbox->setEnabled(false); + buttonBrowse->setEnabled(false); + editServer->setEnabled(false); + editUser->setEnabled(false); + editPassword->setEnabled(false); + checkStorePassword->setEnabled(false); + break; + } +} + +void KBiffMailboxTab::browse() +{ + QString proto(getMailbox().protocol()); + + if (proto == "imap4" || proto == "imap4s") + { + KURL start; + start.setProtocol((proto == "imap4s") ? "imaps" : "imap"); + start.setUser(getMailbox().user()); + start.setHost(getMailbox().host()); + start.setPath("/"); + KURL url = KFileDialog::getOpenURL(start.url()); + if (url.url().isEmpty()) + return; + + QString path(url.path()); + if (path.isEmpty()) + return; + + if (path[0] == '/') + path = path.right(path.length() - 1); + if (path.right(1) == "/") + path = path.left(path.length() - 1); + + editMailbox->setText( path ); + return; + } + else + { + QString file; + if (proto == "maildir") + file = KFileDialog::getExistingDirectory(); + else + file = KFileDialog::getOpenFileName(); + + if( file.isEmpty() ) + return; + + editMailbox->setText( file ); + } +} + +void KBiffMailboxTab::advanced() +{ + KBiffMailboxAdvanced advanced_dlg; + QString prot(getMailbox().protocol()); + + if (prot == "mbox" || prot == "maildir" || prot == "file" || prot == "mh") + { + advanced_dlg.setPort(port, false); + advanced_dlg.setTimeout(timeout, false); + } + else + { + advanced_dlg.setPort(port); + advanced_dlg.setTimeout(timeout); + } + + if ((prot == "imap4") || (prot == "imap4s")) + { + advanced_dlg.setPreauth(preauth); + advanced_dlg.setKeepalive(keepalive); + advanced_dlg.setAsync(async); + } + + if ((prot == "pop3") || (prot == "nntp") || (prot == "pop3s")) + { + advanced_dlg.setKeepalive(keepalive); + advanced_dlg.setAsync(async); + advanced_dlg.setDisableApop(!useApop); + } + + advanced_dlg.setMailbox(getMailbox()); + if (advanced_dlg.exec()) + { + port = advanced_dlg.getPort(); + setMailbox(advanced_dlg.getMailbox()); + } +} + +const KBiffURL KBiffMailboxTab::defaultMailbox() const +{ + QFileInfo mailbox_info(getenv("MAIL")); + if (mailbox_info.exists() == false) + { + QString s(_PATH_MAILDIR); + s += "/"; + s += getpwuid(getuid())->pw_name; + mailbox_info.setFile(s); + } + + QString default_path = mailbox_info.isDir() ? QString("maildir:") : + QString("mbox:"); + default_path.append(mailbox_info.absFilePath()); + + return KBiffURL(default_path); +} + +////////////////////////////////////////////////////////////////////// +// KBiffAboutTab +////////////////////////////////////////////////////////////////////// +KBiffAboutTab::KBiffAboutTab(QWidget *parent_) + : QWidget(parent_) +{ + // load in the kbiff pixmap + QPixmap logo_pixmap(kapp->icon()); + + QLabel *pixmap_label = new QLabel(this); + pixmap_label->setPixmap(logo_pixmap); + + // we want a bigger logo + QFont logo_font = QFont::defaultFont(); + logo_font.setPointSize(logo_font.pointSize() * 1.5); + logo_font.setBold(true); + + KURLLabel *logo_label = new KURLLabel(this); + logo_label->setURL("http://kbiff.granroth.org"); + logo_label->setFont(logo_font); + logo_label->setText("KBiff"); + logo_label->setUnderline(false); + logo_label->setGlow(false); + logo_label->setFloat(true); + connect(logo_label, SIGNAL(leftClickedURL(const QString&)), + SLOT(homepage(const QString&))); + + QLabel *version_label = new QLabel(this); + version_label->setText(QString("Version %1\n\nCopyright (C) 1998-2008\nKurt Granroth").arg(kbiff_version)); + + KURLLabel *email_label = new KURLLabel(this); + email_label->setText("granroth@kde.org"); + email_label->setURL("mailto:granroth@kde.org"); + email_label->setUnderline(false); + email_label->setGlow(false); + email_label->setFloat(true); + connect(email_label, SIGNAL(leftClickedURL(const QString&)), + SLOT(mailTo(const QString&))); + + // about tab text layout + QVBoxLayout *text_layout = new QVBoxLayout(0); + text_layout->addWidget(version_label); + text_layout->addWidget(email_label); + + // main about tab layout + QGridLayout *about_layout = new QGridLayout(this, 3, 2, 12, 0); + about_layout->addWidget(pixmap_label, 0, 0); + about_layout->addWidget(logo_label, 0, 1); + about_layout->addLayout(text_layout, 1, 1); + about_layout->setRowStretch(2, 1); +} + +KBiffAboutTab::~KBiffAboutTab() +{ +} + +void KBiffAboutTab::mailTo(const QString& url) +{ + (void) new KRun ( url ); +} + +void KBiffAboutTab::homepage(const QString& url) +{ + (void) new KRun ( url ); +} + +KBiffNewDlg::KBiffNewDlg(QWidget* parent_, const char * name_) + : KDialog(parent_, name_, true) +{ + // set my name + setCaption(i18n("New Name")); + + QLabel* label = new QLabel(i18n("&New Name:"), this); + editName = new QLineEdit(this); + editName->setFocus(); + label->setBuddy(editName); + + // ok button + QPushButton* button_ok = new QPushButton(i18n("&OK"), this); + button_ok->setDefault(true); + + // cancel button + QPushButton* button_cancel = new QPushButton(i18n("&Cancel"), this); + + connect(button_ok, SIGNAL(clicked()), SLOT(accept())); + connect(button_cancel, SIGNAL(clicked()), SLOT(reject())); + + // NOW DO THE LAYOUT + QGridLayout *top_layout = new QGridLayout(this, 2, 3, 12); + top_layout->addWidget(label, 0, 0); + top_layout->addMultiCellWidget(editName, 0, 0, 1, 2); + top_layout->addWidget(button_ok, 1, 1); + top_layout->addWidget(button_cancel, 1, 2); +} diff --git a/kbiff/setupdlg.h b/kbiff/setupdlg.h new file mode 100644 index 0000000..bf423d9 --- /dev/null +++ b/kbiff/setupdlg.h @@ -0,0 +1,308 @@ +/* + * setupdlg.h + * Copyright (C) 1999-2001 Kurt Granroth <granroth@kde.org> + * + * This file contains the setup dialog and related widgets + * for KBiff. All user configuration is done here. + * + * $Id$ + */ +#ifndef SETUPDLG_H +#define SETUPDLG_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif //HAVE_CONFIG_H + +#include <kbiffurl.h> + +#include <qlistview.h> + +#include <qwidget.h> +#include <kdialog.h> +#include <qdict.h> +#include <qlineedit.h> + +class QLineEdit; +class QCheckBox; +class QPushButton; +class QComboBox; + +#include <kicondialog.h> + +struct KBiffMailbox +{ + KBiffURL url; + bool store; + QString key; +}; + +class KBiffGeneralTab; +class KBiffNewMailTab; +class KBiffMailboxTab; +class KBiffAboutTab; +class KBiffNewDlg; + +class KBiffSetup : public KDialog +{ + Q_OBJECT +public: + KBiffSetup(const QString& name = QString::null, bool secure = false); + virtual ~KBiffSetup(); + + const QString getProfile() const; + const KBiffURL getCurrentMailbox() const; + const QList<KBiffMailbox> getMailboxList() const; + + const QString getMailClient() const; + const QString getRunCommandPath() const; + const QString getRunResetCommandPath() const; + const QString getPlaySoundPath() const; + const QString getNoMailIcon() const; + const QString getNewMailIcon() const; + const QString getOldMailIcon() const; + const QString getNoConnIcon() const; + const QString getStoppedIcon() const; + bool getSystemBeep() const; + bool getRunCommand() const; + bool getRunResetCommand() const; + bool getPlaySound() const; + bool getNotify() const; + bool getStatus() const; + bool getDock() const; + bool getSessionManagement() const; + bool getCheckStartup() const; + bool getSecure() const; + unsigned int getPoll() const; + +public slots: + void invokeHelp(); + + void readConfig(const QString& profile); + void saveConfig(); + +protected: + QString getSomeProfile() const; + +protected slots: + void slotDone(); + void slotAddNewProfile(); + void slotRenameProfile(); + void slotDeleteProfile(); + +private: + bool isSecure; + + // "outer" dialog + QComboBox *comboProfile; + + // tabs + KBiffGeneralTab *generalTab; + KBiffNewMailTab *newmailTab; + KBiffMailboxTab *mailboxTab; + KBiffAboutTab *aboutTab; +}; + +class KBiffGeneralTab : public QWidget +{ + Q_OBJECT +public: + KBiffGeneralTab(const QString& profile = QString::null, QWidget *parent=0); + virtual ~KBiffGeneralTab(); + + const QString getButtonNewMail() const; + const QString getButtonOldMail() const; + const QString getButtonNoMail() const; + const QString getButtonNoConn() const; + const QString getButtonStopped() const; + const QString getMailClient() const; + int getPoll() const; + bool getDock() const; + bool getSessionManagement() const; + bool getCheckStartup() const; + +public slots: + void readConfig(const QString& profile); + void saveConfig(const QString& profile); + +private: + QLineEdit* editPoll; + QLineEdit* editCommand; + QCheckBox* checkDock; + QCheckBox* checkNoSession; + QCheckBox* checkNoStartup; + + KIconButton *buttonNoMail; + KIconButton *buttonOldMail; + KIconButton *buttonNewMail; + KIconButton *buttonNoConn; + KIconButton *buttonStopped; +}; + +class KBiffNewMailTab : public QWidget +{ + Q_OBJECT +public: + KBiffNewMailTab(const QString& profile = QString::null, QWidget *parent=0); + virtual ~KBiffNewMailTab(); + + bool getRunCommand() const; + const QString getRunCommandPath() const; + bool getRunResetCommand() const; + const QString getRunResetCommandPath() const; + bool getPlaySound() const; + const QString getPlaySoundPath() const; + bool getSystemBeep() const; + bool getNotify() const; + bool getStatus() const; + +public slots: + void readConfig(const QString& profile); + void saveConfig(const QString& profile); + +protected slots: + void enableRunCommand(bool); + void enableRunResetCommand(bool); + void enablePlaySound(bool); + void browseRunCommand(); + void browseRunResetCommand(); + void browsePlaySound(); + void testPlaySound(); + +private: + QLineEdit *editRunCommand; + QLineEdit *editRunResetCommand; + QLineEdit *editPlaySound; + + QCheckBox *checkRunCommand; + QCheckBox *checkRunResetCommand; + QCheckBox *checkPlaySound; + QCheckBox *checkBeep; + QCheckBox *checkNotify; + QCheckBox *checkStatus; + + QPushButton *buttonBrowsePlaySound; + QPushButton *buttonTestPlaySound; + QPushButton *buttonBrowseRunCommand; + QPushButton *buttonBrowseRunResetCommand; +}; + +class KBiffMailboxAdvanced : public KDialog +{ + Q_OBJECT +public: + KBiffMailboxAdvanced(); + virtual ~KBiffMailboxAdvanced(); + + const KBiffURL getMailbox() const; + unsigned int getPort() const; + bool getPreauth() const; + + void setPort(unsigned int the_port, bool enable = true); + void setTimeout(unsigned int the_to, bool enable = true); + void setMailbox(const KBiffURL& url); + void setPreauth(bool on); + void setKeepalive(bool on); + void setAsync(bool on); + void setDisableApop(bool on); + +protected slots: + void portModified(const QString& text); + void timeoutModified(const QString& text); + void preauthModified(bool toggled); + void keepaliveModified(bool toggled); + void asyncModified(bool toggled); + void apopModified(bool toggled); + +private: + QString password; + QLineEdit *mailbox; + QLineEdit *port; + QLineEdit *timeout; + QCheckBox *preauth; + QCheckBox *keepalive; + QCheckBox *async; + QCheckBox *apop; +}; + +class KBiffMailboxTab : public QWidget +{ + Q_OBJECT +public: + KBiffMailboxTab(const QString& profile = QString::null, QWidget *parent=0); + virtual ~KBiffMailboxTab(); + + void setMailbox(const KBiffURL& url); + + const KBiffURL getMailbox() const; + const QList<KBiffMailbox> getMailboxList() const; + +public slots: + void readConfig(const QString& profile); + void saveConfig(const QString& profile); + +protected slots: + void slotDeleteMailbox(); + void slotNewMailbox(); + void slotMailboxSelected(QListViewItem *item); + + void protocolSelected(int protocol); + void browse(); + void advanced(); + + void enableFetchCommand(bool); + void browseFetchCommand(); + +protected: + const KBiffURL defaultMailbox() const; + +private: + QDict<KBiffMailbox> *mailboxHash; + QListViewItem *oldItem; + + unsigned int port; + unsigned int timeout; + bool preauth; + bool keepalive; + bool async; + bool useApop; + QComboBox *comboProtocol; + QLineEdit *editMailbox; + QLineEdit *editServer; + QLineEdit *editUser; + QLineEdit *editPassword; + QLineEdit *editFetchCommand; + QCheckBox *checkFetchCommand; + QCheckBox *checkStorePassword; + QPushButton *buttonBrowse; + QListView *mailboxes; + + QPushButton *buttonBrowseFetchCommand; +}; + +class KBiffAboutTab : public QWidget +{ + Q_OBJECT +public: + KBiffAboutTab(QWidget *parent=0); + virtual ~KBiffAboutTab(); + +protected slots: + void mailTo(const QString&); + void homepage(const QString&); +}; + +class KBiffNewDlg : public KDialog +{ + Q_OBJECT +public: + KBiffNewDlg(QWidget* parent = 0, const char * name = 0); + + const QString getName() const + { return editName->text(); } + +private: + QLineEdit *editName; +}; + +#endif // SETUPDLG_H diff --git a/kbiff/status.cpp b/kbiff/status.cpp new file mode 100644 index 0000000..3919185 --- /dev/null +++ b/kbiff/status.cpp @@ -0,0 +1,136 @@ +/* + * status.cpp + * Copyright (C) 1999-2008 Kurt Granroth <granroth@kde.org> + * + * This file contains the implementation of the KBiffStatus + * widget + */ +#include "status.h" +#include "status.moc" + +#include <kapp.h> +#include <klocale.h> + +#include <qdesktopwidget.h> +#include <qpoint.h> +#include <qrect.h> + +#include <qheader.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlistview.h> +#include <qpoint.h> + +KBiffStatus::KBiffStatus(QWidget *parent_, const QString& profile, const KBiffStatusList& list) + : QFrame(parent_, 0, WType_Popup), + _listView(new QListView(this)) +{ + setFrameStyle(WinPanel|Raised); + QLabel *profile_label = new QLabel(profile, this); + profile_label->setFrameStyle(QFrame::Box | QFrame::Raised); + profile_label->setAlignment(AlignCenter); + + _listView->addColumn(i18n("Mailbox")); + _listView->addColumn(i18n("New")); + _listView->addColumn(i18n("Old")); + _listView->setColumnAlignment(1, AlignRight); + _listView->setColumnAlignment(2, AlignRight); + _listView->setSorting(1, FALSE); + _listView->setFrameStyle(QFrame::WinPanel | QFrame::Raised); + _listView->setVScrollBarMode(QScrollView::AlwaysOff); + _listView->setHScrollBarMode(QScrollView::AlwaysOff); + _listView->header()->hide(); + + updateListView(list); + + int list_height = (_listView->firstChild()->height() * list.count()) + 10; + _listView->setFixedSize(_listView->sizeHint().width() + 5, list_height); + resize(_listView->size()); + + QVBoxLayout *blayout = new QVBoxLayout(this, 0, 0); + blayout->addWidget(profile_label); + blayout->addWidget(_listView); +} + +KBiffStatus::~KBiffStatus() +{ +} + +void KBiffStatus::updateListView(const KBiffStatusList& list) +{ + _listView->clear(); + KBiffStatusListIterator it(list); + for(it.toFirst(); it.current(); ++it) + { + if (it.current()->newMessages() == "-1") + { + new QListViewItem(_listView, it.current()->mailbox(), + i18n("Disabled")); + } + else + { + new QListViewItem(_listView, it.current()->mailbox(), + it.current()->newMessages(),it.current()->curMessages()); + } + } +} + +void KBiffStatus::popup(const QPoint& pos_) +{ + QDesktopWidget *desktop = KApplication::desktop(); + int cx = pos_.x(), cy = pos_.y(); + + // for some reason, the width and height are incorrect until + // we do the show. so we show first (after hiding) and move later + move(-100, -100); + show(); + + // verify that the width is within the desktop + if (desktop->isVirtualDesktop()) + { + QRect scn = desktop->screenGeometry(QPoint(cx, cy)); + + if ((pos_.x() + width()) > (scn.x() + scn.width())) + { + cx = (scn.x() + scn.width()) - width(); + cx = (cx < 0) ? 0 : cx; + } + } + else + { + if ((pos_.x() + width()) > desktop->width()) + { + cx = pos_.x() - width(); + cx = (cx < 0) ? 0 : cx; + } + } + + // verify that that height is within tolerances + if ((pos_.y() + height()) > desktop->height()) + { + cy = pos_.y() - height() - 2; + cy = (cy < 0) ? 0 : cy; + } + + // now that we have *real* co-ordinates, we move to them + move(cx, cy+1); +} + +KBiffStatusItem::KBiffStatusItem(const QString& mailbox_, const int num_new,const int num_cur) + : QObject(), + _mailbox(mailbox_), + _newMessages(QString().setNum(num_new)), + _curMessages((num_cur==-1)?QString("?"):QString().setNum(num_cur)) +{ +} +KBiffStatusItem::KBiffStatusItem(const QString& mailbox_, const int num_new) + : QObject(), + _mailbox(mailbox_), + _newMessages(QString().setNum(num_new)), + _curMessages(QString("?")) +{ +} + +KBiffStatusItem::~KBiffStatusItem() +{ +} diff --git a/kbiff/status.h b/kbiff/status.h new file mode 100644 index 0000000..8c05ad3 --- /dev/null +++ b/kbiff/status.h @@ -0,0 +1,59 @@ +/* + * status.h + * Copyright (C) 1999 Kurt Granroth <granroth@kde.org> + * + * This file contains the declaration of the KBiffStatus + * widget. + * + * $Id$ + */ +#ifndef KBIFFSTATUS_H +#define KBIFFSTATUS_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qframe.h> +#include <qlist.h> +#include <qstring.h> + +class QListView; +class QPoint; + +class KBiffStatusItem : QObject +{ + Q_OBJECT +public: + KBiffStatusItem(const QString& mailbox, const int num_new); + KBiffStatusItem(const QString& mailbox, const int num_new,const int num_cur); + virtual ~KBiffStatusItem(); + + QString mailbox() const { return _mailbox; } + QString newMessages() const { return _newMessages; } + QString curMessages() const { return _curMessages; } + +protected: + QString _mailbox; + QString _newMessages; + QString _curMessages; +}; + +typedef QList<KBiffStatusItem> KBiffStatusList; +typedef QListIterator<KBiffStatusItem> KBiffStatusListIterator; + +class KBiffStatus : public QFrame +{ + Q_OBJECT +public: + KBiffStatus(QWidget *parent, const QString& profile, const KBiffStatusList& list); + virtual ~KBiffStatus(); + + void updateListView(const KBiffStatusList& list); + void popup(const QPoint& pos); + +protected: + QListView *_listView; +}; + +#endif // KBIFFSTATUS_H diff --git a/kbiff/version.cpp b/kbiff/version.cpp new file mode 100644 index 0000000..be74333 --- /dev/null +++ b/kbiff/version.cpp @@ -0,0 +1,3 @@ +#include "version.h" + +const char *kbiff_version = "3.9"; diff --git a/kbiff/version.h b/kbiff/version.h new file mode 100644 index 0000000..cc37c2f --- /dev/null +++ b/kbiff/version.h @@ -0,0 +1,12 @@ +/* + * version.h + * Copyright (C) 2008 Kurt Granroth <granroth@kde.org> + * + * This file contains the current version number. + */ +#ifndef VERSION_H +#define VERSION_H + +extern const char *kbiff_version; + +#endif // VERSION_H |