diff options
Diffstat (limited to 'kmousetool/kmousetool')
18 files changed, 2121 insertions, 0 deletions
diff --git a/kmousetool/kmousetool/Makefile.am b/kmousetool/kmousetool/Makefile.am new file mode 100644 index 0000000..72c6a08 --- /dev/null +++ b/kmousetool/kmousetool/Makefile.am @@ -0,0 +1,29 @@ +bin_PROGRAMS = kmousetool + +kmousetool_SOURCES = kmousetoolui.ui mtstroke.cpp kmousetool.cpp main.cpp +kmousetool_LDADD = -lXtst $(LIB_KDEUI) $(LIB_KDECORE) $(LIB_QT) -lXext -lX11 $(LIBSOCKET) + +SUBDIRS = pics + +EXTRA_DIST = main.cpp version.h kmousetool.cpp kmousetool.h kmousetool.desktop mtstroke.cpp mtstroke.h mousetool_tap.wav + +kmousetooldir = $(kde_appsdir)/Applications +kmousetool_DATA = kmousetool.desktop + +sounddatadir = $(kde_datadir)/kmousetool/sounds +sounddata_DATA = mousetool_tap.wav + +# set the include path for X, qt and KDE +INCLUDES= $(all_includes) + +METASOURCES = AUTO + +# the library search path. +kmousetool_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +messages: rc.cpp + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/kmousetool.pot; \ + fi + diff --git a/kmousetool/kmousetool/Xmd_kmousetool.h b/kmousetool/kmousetool/Xmd_kmousetool.h new file mode 100644 index 0000000..2a35eb8 --- /dev/null +++ b/kmousetool/kmousetool/Xmd_kmousetool.h @@ -0,0 +1,201 @@ +/* $XFree86: xc/include/Xmd.h,v 3.9 2001/01/17 17:53:11 dawes Exp $ */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +#ifndef XMD_H +#define XMD_H 1 +/* $Xorg: Xmd.h,v 1.3 2000/08/18 04:05:44 coskrey Exp $ */ +/* + * Xmd.h: MACHINE DEPENDENT DECLARATIONS. + */ + +/* + * Special per-machine configuration flags. + */ +#ifdef CRAY +#define WORD64 /* 64-bit architecture */ +#endif +#if defined(__alpha) || defined(__alpha__) || \ + defined(__ia64__) || defined(ia64) +#define LONG64 /* 32/64-bit architecture */ +#endif +#ifdef __sgi +#if (_MIPS_SZLONG == 64) +#define LONG64 +#endif +#endif + +/* + * Stuff to handle large architecture machines; the constants were generated + * on a 32-bit machine and must coorespond to the protocol. + */ +#ifdef WORD64 +#define MUSTCOPY +#endif /* WORD64 */ + + +/* + * Definition of macro used to set constants for size of network structures; + * machines with preprocessors that can't handle all of the sz_ symbols + * can define this macro to be sizeof(x) if and only if their compiler doesn't + * pad out structures (esp. the xTextElt structure which contains only two + * one-byte fields). Network structures should always define sz_symbols. + * + * The sz_ prefix is used instead of something more descriptive so that the + * symbols are no more than 32 characters long (which causes problems for some + * compilers and preprocessors). + * + * The extra indirection in the __STDC__ case is to get macro arguments to + * expand correctly before the concatenation, rather than afterward. + */ +#if ((defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)) && !defined(UNIXCPP)) || defined(ANSICPP) +#define _SIZEOF(x) sz_##x +#define SIZEOF(x) _SIZEOF(x) +#else +#define SIZEOF(x) sz_/**/x +#endif /* if ANSI C compiler else not */ + +/* + * Bitfield suffixes for the protocol structure elements, if you + * need them. Note that bitfields are not guarranteed to be signed + * (or even unsigned) according to ANSI C. + */ +#ifdef WORD64 +typedef long INT64; +typedef unsigned long CARD64; +#define B32 :32 +#define B16 :16 +#ifdef UNSIGNEDBITFIELDS +typedef unsigned int INT32; +typedef unsigned int INT16; +#else +#ifdef __STDC__ +typedef signed int INT32; +typedef signed int INT16; +#else +typedef int INT32; +typedef int INT16; +#endif +#endif +#else +#define B32 +#define B16 +#ifdef LONG64 +//typedef long INT64; +typedef int INT32; +#else +//typedef long INT32; +#endif +typedef short INT16; +#endif + +#if defined(__STDC__) || defined(sgi) || defined(AIXV3) +typedef signed char INT8; +#else +typedef char INT8; +#endif + +#ifdef LONG64 +typedef unsigned long CARD64; +typedef unsigned int CARD32; +#else +typedef unsigned long CARD32; +#endif +typedef unsigned short CARD16; +typedef unsigned char CARD8; + +typedef CARD32 BITS32; +typedef CARD16 BITS16; + +#ifndef __EMX__ +typedef CARD8 BYTE; +typedef CARD8 BOOL; +#else /* __EMX__ */ +/* + * This is bad style, but the central include file <os2.h> declares them + * as well + */ +#define BYTE CARD8 +#define BOOL CARD8 +#endif /* __EMX__ */ + +/* + * definitions for sign-extending bitfields on 64-bit architectures + */ +#if defined(WORD64) && defined(UNSIGNEDBITFIELDS) +#define cvtINT8toInt(val) (((val) & 0x00000080) ? ((val) | 0xffffffffffffff00) : (val)) +#define cvtINT16toInt(val) (((val) & 0x00008000) ? ((val) | 0xffffffffffff0000) : (val)) +#define cvtINT32toInt(val) (((val) & 0x80000000) ? ((val) | 0xffffffff00000000) : (val)) +#define cvtINT8toShort(val) cvtINT8toInt(val) +#define cvtINT16toShort(val) cvtINT16toInt(val) +#define cvtINT32toShort(val) cvtINT32toInt(val) +#define cvtINT8toLong(val) cvtINT8toInt(val) +#define cvtINT16toLong(val) cvtINT16toInt(val) +#define cvtINT32toLong(val) cvtINT32toInt(val) +#else +#define cvtINT8toInt(val) (val) +#define cvtINT16toInt(val) (val) +#define cvtINT32toInt(val) (val) +#define cvtINT8toShort(val) (val) +#define cvtINT16toShort(val) (val) +#define cvtINT32toShort(val) (val) +#define cvtINT8toLong(val) (val) +#define cvtINT16toLong(val) (val) +#define cvtINT32toLong(val) (val) +#endif /* WORD64 and UNSIGNEDBITFIELDS */ + + + +#ifdef MUSTCOPY +/* + * This macro must not cast or else pointers will get aligned and be wrong + */ +#define NEXTPTR(p,t) (((char *) p) + SIZEOF(t)) +#else /* else not MUSTCOPY, this is used for 32-bit machines */ +/* + * this version should leave result of type (t *), but that should only be + * used when not in MUSTCOPY + */ +#define NEXTPTR(p,t) (((t *)(p)) + 1) +#endif /* MUSTCOPY - used machines whose C structs don't line up with proto */ + +#endif /* XMD_H */ diff --git a/kmousetool/kmousetool/kmousetool.cpp b/kmousetool/kmousetool/kmousetool.cpp new file mode 100644 index 0000000..ee27ba4 --- /dev/null +++ b/kmousetool/kmousetool/kmousetool.cpp @@ -0,0 +1,641 @@ +/*************************************************************************** + kmousetool.cpp - description + ------------------- + begin : Sun Jan 20 23:27:58 PST 2002 + copyright : (C) 2002-2003 by Jeff Roush + email : jeff@mousetool.com + copyright : (C) 2003 by Olaf Schmidt + email : ojschmidt@kde.org + copyright : (C) 2003 by Gunnar Schmi Dt + email : gunnar@schmi-dt.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + + +#include "Xmd_kmousetool.h" +#include "kmousetool.h" +#include "kmousetool.moc" +#include <kconfig.h> +#include <X11/Intrinsic.h> /* Intrinsics Definitions*/ +#include <X11/StringDefs.h> /* Standard Name-String definitions*/ +#include <X11/extensions/xtestext1.h> /* Standard Name-String definitions*/ +#include <X11/extensions/XTest.h> /* Standard Name-String definitions*/ +#include <kdialog.h> +#include <klocale.h> +#include <qpushbutton.h> +#include <qpoint.h> +#include <qnamespace.h> +#include <kmessagebox.h> +#include <kaudioplayer.h> +#include <kstandarddirs.h> +#include <qsound.h> +#include <kglobalsettings.h> +#include <kdebug.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qcheckbox.h> +#include <ksystemtray.h> +#include <kiconloader.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> +#include <knuminput.h> +#include <kpopupmenu.h> +#include <kaboutapplication.h> + +//#include <arts/soundserver.h> +#include <netwm.h> + +#include <iostream> + +#include "mtstroke.h" + +//using namespace Arts; + +int currentXPosition; +int currentYPosition; + +//using namespace std; + +#undef long + +/** +* Gnarly X functions +*/ +void queryPointer(Window *pidRoot, int *pnRx, int *pnRy, int *pnX, int *pnY, unsigned int *puMask); +int CursorHasMoved(int minMovement); +void LeftClick(); +void RightClick(); +void DoubleClick(); +void LeftDn(); +void LeftUp(); + +// Declarations +Display *display; + +//SimpleSoundServer sound_server(Reference("global:Arts_SimpleSoundServer")); + + +void KMouseTool::init_vars() +{ + continue_timer = 1; + tick_count = 0; + max_ticks = dwell_time+1; + mouse_is_down = FALSE; + + loadOptions(); + + // If the ~/.mousetool directory doesn't exist, create it +// mSoundFileName = QDir::homeDirPath(); + mSoundFileName = locate("appdata", "sounds/mousetool_tap.wav"); + mplayer = new KAudioPlayer(mSoundFileName); + + + // find application file + appfilename = locate("exe", "kmousetool"); + + // find the user's autostart directory + autostartdirname = KGlobalSettings::autostartPath(); + + // SimpleSoundServer server(Reference("global:Arts_SimpleSoundServer")); +// sound_server(Reference("global:Arts_SimpleSoundServer")); + + QDesktopWidget *d = QApplication::desktop(); + int w = d->width(); + int h = d->height(); + MTStroke::setUpperLeft(0,0); + MTStroke::setUpperRight(w-1,0); + MTStroke::setLowerLeft(0,h-1); + MTStroke::setLowerRight(w-1,h-1); +} + +void KMouseTool::resetSettings() +{ + cbDrag ->setChecked(smart_drag_on); + cbStart->setChecked(isAutostart()); + cbClick->setChecked(playSound); + cbStroke->setChecked(strokesEnabled); + movementEdit->setValue(min_movement); + dwellTimeEdit->setValue(dwell_time); + dragTimeEdit->setValue(drag_time); + settingsChanged(); +} + +void KMouseTool::setDefaultSettings() +{ + cbDrag ->setChecked(false); + cbStart->setChecked(false); + cbClick->setChecked(false); + cbStroke->setChecked(false); + movementEdit->setValue(5); + dwellTimeEdit->setValue(5); + dragTimeEdit->setValue(3); + settingsChanged(); +} + + +void KMouseTool::timerEvent( QTimerEvent * ) +{ + if (!mousetool_is_running) + return; + + if (!continue_timer) { + killTimers(); + return; + } + + max_ticks = dwell_time + drag_time; + stroke.addPt(currentXPosition, currentYPosition); + + moving = moving?CursorHasMoved(1):CursorHasMoved(min_movement); + if (moving) { + if (mousetool_just_started) { + mousetool_just_started = false; + tick_count = max_ticks; + } + else + tick_count = 0; + return; + } + + if (tick_count<max_ticks) + tick_count++; + + + // If the mouse has paused ... + if (tick_count==dwell_time) { + int strokeType = stroke.getStrokeType(); + + // if we're dragging the mouse, ignore stroke type + if (mouse_is_down) { + normalClick(); + return; + } + + if (!strokesEnabled) { + normalClick(); + return; + } + if (strokeType == MTStroke::DontClick) + return; + if (strokeType==MTStroke::bumped_mouse) + return; + + if (strokeType==MTStroke::RightClick || strokeType==MTStroke::UpperRightStroke) + RightClick(); + else if (strokeType==MTStroke::DoubleClick || strokeType==MTStroke::LowerLeftStroke) + DoubleClick(); + else + normalClick(); + } +} + +void KMouseTool::normalClick() +{ + if (smart_drag_on) { + if (!mouse_is_down) { + LeftDn(); + mouse_is_down = TRUE; + tick_count = 0; + playTickSound(); + } + else if (mouse_is_down) { + LeftUp(); + mouse_is_down = FALSE; + tick_count = max_ticks; + } + } + else { + // not smart_drag_on + LeftClick(); + playTickSound(); + } +} + +// This function isn't happy yet. +void KMouseTool::playTickSound() +{ + if (!playSound) + return; + + mplayer->play(); + // This is a bit slow. +// KAudioPlayer::play(mSoundFileName); + return; + + // the solution seems to be to use MCOP, + // but SimpleSoundServer is not cooperating + + // When using the following code, make sure to link with + // Put " -lsoundserver_idl" in the linker options in KDevelop. + +// SimpleSoundServer server = SimpleSoundServer::_fromString("global:Arts_SimpleSoundServer"); +// SimpleSoundServer *ss = new SimpleSoundServer(Reference("global:Arts_SimpleSoundServer")); +// SimpleSoundServer sound_server2(Reference("global:Arts_SimpleSoundServer")); + +// if(sound_server.isNull()) +// return; +// sound_server.play(mSoundFileName.latin1()); + + // Another approach is to try using QSound. + // QSound depends on Network Audio Server, which doesn't seem to work on my Debian Woody system. + // I haven't spent much time working on it, though. +// QSound::play(mSoundFileName); +} + +KMouseTool::KMouseTool(QWidget *parent, const char *name) : KMouseToolUI(parent, name) +{ + init_vars(); + resetSettings(); + + connect(movementEdit, SIGNAL(valueChanged(int)), this, SLOT(settingsChanged())); + connect(dwellTimeEdit, SIGNAL(valueChanged(int)), this, SLOT(settingsChanged())); + connect(dragTimeEdit, SIGNAL(valueChanged(int)), this, SLOT(settingsChanged())); + connect(cbDrag, SIGNAL(stateChanged(int)), this, SLOT(settingsChanged())); + connect(cbStroke, SIGNAL(stateChanged(int)), this, SLOT(settingsChanged())); + connect(cbClick, SIGNAL(stateChanged(int)), this, SLOT(settingsChanged())); + connect(cbStart, SIGNAL(stateChanged(int)), this, SLOT(settingsChanged())); + + connect(buttonStartStop, SIGNAL(clicked()), this, SLOT(startStopSelected())); + buttonDefault->setGuiItem(KStdGuiItem::defaults()); + connect(buttonDefault, SIGNAL(clicked()), this, SLOT(defaultSelected())); + connect(buttonReset, SIGNAL(clicked()), this, SLOT(resetSelected())); + buttonApply->setGuiItem(KStdGuiItem::apply()); + connect(buttonApply, SIGNAL(clicked()), this, SLOT(applySelected())); + buttonHelp->setGuiItem(KStdGuiItem::help()); + connect(buttonHelp, SIGNAL(clicked()), this, SLOT(helpSelected())); + buttonClose->setGuiItem(KStdGuiItem::close()); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(closeSelected())); +#if KDE_VERSION >= KDE_MAKE_VERSION (3,1,90) + buttonQuit->setGuiItem(KStdGuiItem::quit()); +#endif // KDE 3.2 + connect(buttonQuit, SIGNAL(clicked()), this, SLOT(quitSelected())); + + // When we first start, it's nice to not click immediately. + // So, tell MT we're just starting + mousetool_just_started = true; + + startTimer(100); + trayIcon = new KMouseToolTray (this, "systemTrayIcon"); + updateStartStopText (); + connect(trayIcon, SIGNAL(startStopSelected()), this, SLOT(startStopSelected())); + connect(trayIcon, SIGNAL(configureSelected()), this, SLOT(configureSelected())); + connect(trayIcon, SIGNAL(aboutSelected()), this, SLOT(aboutSelected())); + connect(trayIcon, SIGNAL(helpSelected()), this, SLOT(helpSelected())); + connect(trayIcon, SIGNAL(quitSelected()), this, SLOT(quitSelected())); + + aboutDlg = new KAboutApplication (0, "KMouseToolDlg", false); +} + +KMouseTool::~KMouseTool() +{ +} + +// ********************************************************* +// Raw X functions +// Begin mouse monitoring and event generation code. +// these should be moved to a separate file. +void LeftClick() +{ + XTestFakeButtonEvent(display, 1, TRUE, 0); + XTestFakeButtonEvent(display, 1, FALSE, 0); +} + +void DoubleClick() +{ + XTestFakeButtonEvent(display, 1, TRUE, 0); + XTestFakeButtonEvent(display, 1, FALSE, 100); + XTestFakeButtonEvent(display, 1, TRUE, 200); + XTestFakeButtonEvent(display, 1, FALSE, 300); +} + +void RightClick() +{ + XTestFakeButtonEvent(display, 3, TRUE, 0); + XTestFakeButtonEvent(display, 3, FALSE, 0); +} + + +void LeftDn() +{ + XTestFakeButtonEvent(display, 1, TRUE, 0); +} + + +void LeftUp() +{ + XTestFakeButtonEvent(display, 1, FALSE, 0); +} + + +void queryPointer(Window *pidRoot, int *pnRx, int *pnRy, int *pnX, int *pnY, unsigned int *puMask) +{ + Window id2, idRoot; + int screen_num; + + screen_num = DefaultScreen(display); + idRoot = RootWindow(display,screen_num); + XQueryPointer(display, idRoot, &idRoot, &id2, pnRx, pnRy, pnX, pnY, puMask); + + *pidRoot = idRoot; +} + +// return 1 if cursor has moved, 0 otherwise +int CursorHasMoved (int minMovement) +{ + static int nOldRootX = -1; + static int nOldRootY = -1; + +// XEvent evButtonEvent; + Window idRootWin; + int nRootX, nRootY, nWinX, nWinY; + unsigned int uintMask; + + queryPointer(&idRootWin, &nRootX, &nRootY, &nWinX, &nWinY, &uintMask); + + int nRes = 0; + if ((nRootX>nOldRootX?nRootX-nOldRootX:nOldRootX-nRootX) >= minMovement) + nRes = 1; + if ((nRootY>nOldRootY?nRootY-nOldRootY:nOldRootY-nRootY) >= minMovement) + nRes = 1; + + currentXPosition = nRootX; + currentYPosition = nRootY; + + if (nRes) { + nOldRootX = nRootX; + nOldRootY = nRootY; + } + + return nRes; +} +// End mouse monitoring and event creation code + + +bool KMouseTool::isAutostart() +{ + QString sym = autostartdirname; + sym += "kmousetool"; // sym is now full path to symlink + QFileInfo fi(sym); + + return fi.exists(); +} + +void KMouseTool::setAutostart (bool start) +{ + QString sym = autostartdirname; + sym += "kmousetool"; // sym is now full path to symlink + QFileInfo fi(sym); + QString cmd; + + if (start) { + if (!fi.exists()) // if it doesn't exist, make it + cmd.sprintf("ln -s %s %s", appfilename.latin1(), autostartdirname.latin1()); + } + else { + if (fi.exists()) // if it exists, delete it + cmd.sprintf("rm -f %s", sym.latin1()); + } + system(cmd.ascii()); +} + +bool KMouseTool::applySettings() +{ + int drag, dwell; + + dwell = dwellTimeEdit->value(); + drag = dragTimeEdit->value() ; + + // The drag time must be less than the dwell time + if ( dwell < drag) { + KMessageBox::sorry(this, i18n("The drag time must be less than or equal to the dwell time."), i18n("Invalid Value")); + return false; + } + + // if we got here, we must be okay. + min_movement = movementEdit->value(); + smart_drag_on = cbDrag->isChecked(); + playSound = cbClick->isChecked(); + strokesEnabled = cbStroke->isChecked(); + setAutostart (cbStart->isChecked()); + + dwell_time = dwell; + drag_time = drag; + tick_count = max_ticks; + + saveOptions(); + settingsChanged(); + return true; +} + +// Save options to kmousetoolrc file +void KMouseTool::loadOptions() +{ + kapp->config()->setGroup("UserOptions"); + + playSound = kapp->config()->readBoolEntry("AudibleClick",false); + smart_drag_on = kapp->config()->readBoolEntry("SmartDrag",false); + + dwell_time = kapp->config()->readNumEntry("DwellTime",5); + drag_time = kapp->config()->readNumEntry("DragTime",3); + min_movement = kapp->config()->readNumEntry("Movement",5); + strokesEnabled = kapp->config()->readBoolEntry("strokesEnabled",false); + + QPoint p; + int x = kapp->config()->readNumEntry("x",0); + int y = kapp->config()->readNumEntry("y",0); + p.setX(x); + p.setY(y); + move(p); + + mousetool_is_running = kapp->config()->readBoolEntry("MouseToolIsRunning",false); + display = XOpenDisplay(NULL); +} + +// Save options to kmousetoolrc file +void KMouseTool::saveOptions() +{ + QPoint p = pos(); + int x = p.x(); + int y = p.y(); + + kapp->config()->setGroup("ProgramOptions"); + kapp->config()->writeEntry("Version", KMOUSETOOL_VERSION); + kapp->config()->setGroup("UserOptions"); + kapp->config()->writeEntry("x", x); + kapp->config()->writeEntry("y", y); + kapp->config()->writeEntry("strokesEnabled", strokesEnabled); + kapp->config()->writeEntry("IsMinimized", isHidden()); + kapp->config()->writeEntry("DwellTime", dwell_time); + kapp->config()->writeEntry("DragTime", drag_time); + kapp->config()->writeEntry("Movement", min_movement); + kapp->config()->writeEntry("SmartDrag", smart_drag_on); + kapp->config()->writeEntry("AudibleClick", playSound); + kapp->config()->writeEntry("MouseToolIsRunning", mousetool_is_running); + kapp->config()->sync(); +} + +void KMouseTool::updateStartStopText() +{ + if (mousetool_is_running) + buttonStartStop->setText(i18n("&Stop")); + else + buttonStartStop->setText(i18n("&Start")); + trayIcon->updateStartStopText(mousetool_is_running); +} + +bool KMouseTool::newSettings() +{ + return ((dwell_time != dwellTimeEdit->value()) || + (drag_time != dragTimeEdit->value()) || + (min_movement != movementEdit->value()) || + (smart_drag_on != cbDrag->isChecked()) || + (playSound != cbClick->isChecked()) || + (strokesEnabled != cbStroke->isChecked()) || + (isAutostart() != cbStart->isChecked())); +} + +bool KMouseTool::defaultSettings() +{ + return ((5 == dwellTimeEdit->value()) && + (3 == dragTimeEdit->value()) && + (5 == movementEdit->value()) && + !cbDrag->isChecked() && + !cbClick->isChecked() && + !cbStroke->isChecked() && + !cbStart->isChecked()); +} + +/******** SLOTS **********/ + +// Value or state changed +void KMouseTool::settingsChanged () +{ + buttonReset->setEnabled (newSettings()); + buttonApply->setEnabled (newSettings()); + buttonDefault->setDisabled (defaultSettings()); +} + +// Buttons within the dialog +void KMouseTool::startStopSelected() +{ + mousetool_is_running = !mousetool_is_running; + updateStartStopText(); +} + +void KMouseTool::defaultSelected() +{ + setDefaultSettings(); +} + +void KMouseTool::resetSelected() +{ + resetSettings(); +} + +void KMouseTool::applySelected() +{ + applySettings(); +} + +// Buttons at the bottom of the dialog +void KMouseTool::helpSelected() +{ + kapp->invokeHelp(); +} + +void KMouseTool::closeSelected() +{ + if (newSettings()) + { + int answer = KMessageBox::questionYesNoCancel (this, + i18n("There are unsaved changes in the active module.\nDo you want to apply the changes before closing the configuration window or discard the changes?"), + i18n("Closing Configuration Window"), + KStdGuiItem::apply(), KStdGuiItem::discard(), "AutomaticSave"); + if (answer == KMessageBox::Yes) + applySettings(); + else if (answer == KMessageBox::No) + resetSettings(); + if (answer != KMessageBox::Cancel) + hide(); + } + else + hide(); +} + +void KMouseTool::quitSelected() +{ + if (newSettings()) + { + int answer = KMessageBox::questionYesNoCancel (this, + i18n("There are unsaved changes in the active module.\nDo you want to apply the changes before quitting KMousetool or discard the changes?"), + i18n("Quitting KMousetool"), + KStdGuiItem::apply(), KStdGuiItem::discard(), "AutomaticSave"); + if (answer == KMessageBox::Yes) + applySettings(); + if (answer != KMessageBox::Cancel) + { + saveOptions(); + kapp->quit(); + } + } + else + { + saveOptions(); + kapp->quit(); + } +} + +// Menu functions +void KMouseTool::configureSelected() +{ + show(); + raise(); + setActiveWindow(); +} + +void KMouseTool::aboutSelected() +{ + aboutDlg->show(); +} + + + +KMouseToolTray::KMouseToolTray (QWidget *parent, const char *name) : KSystemTray (parent, name) +{ + startStopId = contextMenu()->insertItem (i18n("&Start"), this, SIGNAL(startStopSelected())); + contextMenu()->insertSeparator(); + contextMenu()->insertItem (KGlobal::iconLoader()->loadIcon("configure", KIcon::Small), + i18n("&Configure KMouseTool..."), this, SIGNAL(configureSelected())); + contextMenu()->insertSeparator(); + contextMenu()->insertItem (KGlobal::iconLoader()->loadIcon("contents", KIcon::Small), + i18n("KMousetool &Handbook"), this, SIGNAL(helpSelected())); + contextMenu()->insertItem (KGlobal::iconLoader()->loadIcon("kmousetool", KIcon::Small), + i18n("&About KMouseTool"), this, SIGNAL(aboutSelected())); +} + +KMouseToolTray::~KMouseToolTray() { +} + +void KMouseToolTray::updateStartStopText(bool mousetool_is_running) +{ + QPixmap icon; + + if (mousetool_is_running) { + contextMenu()->changeItem (startStopId, i18n("&Stop")); + icon = KGlobal::iconLoader()->loadIcon("kmousetool_on", KIcon::Small); + } + else { + contextMenu()->changeItem (startStopId, i18n("&Start")); + icon = KGlobal::iconLoader()->loadIcon("kmousetool_off", KIcon::Small); + } + setPixmap (icon); + show(); +} diff --git a/kmousetool/kmousetool/kmousetool.desktop b/kmousetool/kmousetool/kmousetool.desktop new file mode 100644 index 0000000..1517c3f --- /dev/null +++ b/kmousetool/kmousetool/kmousetool.desktop @@ -0,0 +1,138 @@ +# KDE Config File +[Desktop Entry] +Type=Application +Exec=kmousetool -caption "%c" %i %m +Icon=kmousetool +DocPath=kmousetool/index.html +Comment=Clicks the mouse for you, reducing the effects of RSI +Comment[ar]=ينقر على الفأرة بدلا منك، مُخَفِّفاً عنك آلام RSI +Comment[bg]=Автоматично щракване с бутона на мишката +Comment[bs]=Klika mišem za vas, smanjujući efekte RSI-ja +Comment[ca]=Fa els clics del ratolí, reduint els efectes del RSI (índex de força relativa) +Comment[cs]=Kliká za vás myší, omezuje tak efekt RSI +Comment[cy]=Clicio'r llygoden i chi, wrth esmwytho effeithiau RSI +Comment[da]=Klikker på musen for dig, reducerer virkningen af RSI-smerte +Comment[de]=Führt Mausklicks für Sie aus +Comment[el]=Ενεργεί τα κλικ του ποντικιού για σας, μειώνοντας τις επιδράσεις των τραυμάτων από τη συνεχή επανάληψη (RSI) +Comment[eo]=Klakas la muson por vi, tio reduktas la efekton de RSI +Comment[es]=Pulsa los botones del ratón por usted, reduciendo los efectos de RSI +Comment[et]=Klõpsab hiirt sinu eest, vähendades võimalike lihasevalude ohtu +Comment[eu]=Sagua zure ordez klikatzen du, RSI-aren efektuak gutxitzeko +Comment[fa]=موشی را برایتان فشار میدهد، اثرات RSI را کاهش میدهد +Comment[fi]=Napsauttaa hiirtä puolestasi rannevammojen ehkäisemiseksi +Comment[fr]=Clique sur la souris à votre place, limitant les douleurs liées aux TMS +Comment[ga]=Cliceálann seo an luch duit, chun tionchar gortú athstraidhneála a laghdú +Comment[gl]=Preme o rato por ti, reducindo os efeitos da RSI +Comment[he]=לוחץ על העכבר עבורך, ובכך מקל על פרק היד +Comment[hi]=आपके लिए माउस क्लिक करता है, बार-बार क्लिक के कारण ऊंगलियों में होने वाली क्षति को कम करता है +Comment[hu]=Automatikus egérkattintás (RSI-szindrómában szenvedőknek) +Comment[is]=Smellir músarhnöppunum fyrir þig og dregur úr áhrifum RSI +Comment[it]=Fa clic sul mouse al posto tuo, riducendo gli effetti della RSI +Comment[ja]=RSI (反復運動過多損傷) を防ぐために、あなたの代わりにマウスをクリック +Comment[ka]=დაწკაპავს თაგუნას თქვენს მაგივრად, ამცირებს RSI ეფექტებს +Comment[km]=ចុចកណ្ដុរឲ្យអ្នក ដែលកាត់បន្ថយបែបផែនរបស់ RSI +Comment[lt]=Nuspaudžia pelės klavišą, sumažindamas skausmo sindromą +Comment[ms]=Mengklik tetikus untuk anda, mengurangkan kesan RSI +Comment[mt]=Jikklikkjalek il-maws, biex tevita wġigħ RSI +Comment[nb]=Trykker museknappen for deg, gir mindre musesyke +Comment[nds]=Klickt de Muus för Di, minnert de Effekten vun RSI af +Comment[ne]=तपाईँका लागि RSI को प्रभाव घटाएर माउस क्लिक गर्छ +Comment[nl]=Klikt de muisknop voor u, vermindert de effecten van RSI +Comment[nn]=Klikkar med musa for deg, for å hindra belastningsskadar +Comment[pa]=ਮਾਊਸ ਨੂੰ ਦਬਾਉਣ ਨਾਲ ਤੁਹਾਡੇ ਲਈ RSI ਪਰਭਾਵ ਘੱਟ ਜਾਵੇਗਾ +Comment[pl]=Klika za Ciebie myszą, ograniczając nadwyrężanie mięśni +Comment[pt]=Carrega no rato por si, aliviando dores motivadas por RSI +Comment[pt_BR]= Clica o mouse para você, facilitando a dificuldade do RSI +Comment[ro]=Execută clicuri pentru dumneavoastră, reducînd oboseala mîinii +Comment[ru]=Утилита управления мышью для облегчения болевых синдромов +Comment[sk]=Kliká za vás myšou, uľahčuje bolesti RSI +Comment[sl]=Za vas klika miško, da vam olajša bolečine v zapestju +Comment[sr]=Кликће мишем за вас, умањујући вам болове у зглобу +Comment[sr@Latn]=Klikće mišem za vas, umanjujući vam bolove u zglobu +Comment[sv]=Klickar musen åt dig, för att mildra smärta från musarm +Comment[ta]=Clicks the mouse for you, reducing the effects of RSI RSI +Comment[tg]=Зер кардани муш барои шумо, бо камшавии таъсирҳои RSI +Comment[th]=คลิ้กเม้าส์สำหรับคุณเพื่อลดความเสียงต่อการเป็นโรค RSI +Comment[tr]=RSI özelliklerini azaltarak sizin için fareyi tıklar +Comment[uk]=Клацає мишкою для вас для полегшення відчуття болі в зап'ясті +Comment[vi]=Ấn chuột giúp bạn, giảm tác động của RSI +Comment[zh_CN]=为您点击鼠标,减轻肢体重复性劳损(RSI)效应 +Comment[zh_TW]=為您點擊滑鼠, 減少重複施緊傷害(RSI)的影響 +Terminal=false +Name=KMouseTool +Name[cy]=KErfynLlygoden +Name[eo]=Kmusilo +Name[hi]=के-माउस टूल +Name[km]= KMouseTool +Name[ne]=केडीई माउस उपकरण +Name[pa]=ਕੇ ਮਾਊਸ ਸੰਦ +Name[ro]=Utilitar mouse +Name[sv]=Kmousetool +Name[ta]=கே சுட்டிக்கருவி +Name[tg]=Асбоби КМуш +Name[th]=ปรับแต่งเม้าส์ - K +Name[tr]=Kmousetool +Name[uz]=Sichqoncha vositasi +Name[uz@cyrillic]=Сичқонча воситаси +Name[vi]=Công cụ Chuột KDE +Name[zh_CN]=K 鼠标工具 +Name[zh_TW]=K-滑鼠工具 +GenericName=Automatic Mouse Click +GenericName[ar]=نقر الفأرة التلقائي +GenericName[bg]=Инструмент за мишката +GenericName[bs]=Automatsko klikanje mišem +GenericName[ca]=Clic automàtic del ratolí +GenericName[cs]=Automatické klikání myší +GenericName[cy]=Clic Llygoden Ymysgogol +GenericName[da]=Automatisk museklik +GenericName[de]=Automatische Mausklicks +GenericName[el]=Αυτόματο κλικ ποντικιού +GenericName[eo]=Aŭtomata Musklako +GenericName[es]=Pulsación automática del ratón +GenericName[et]=Hiire automaatne klõpsaja +GenericName[eu]=Saguaren klik automatikoak +GenericName[fa]=فشار خودکار موشی +GenericName[fi]=Automaattinen hiirennapsautus +GenericName[fr]=Clic de souris automatique +GenericName[ga]=Cliceáil uathoibríoch luiche +GenericName[gl]=Preme o rato automaticamente +GenericName[he]=לחיצת עכבר אוטומטית +GenericName[hi]=स्वचालित माउस क्लिक +GenericName[hu]=Automatikus kattintás +GenericName[is]=Sjálfvirkur músahnappasmellir +GenericName[it]=Clic automatico del mouse +GenericName[ja]=自動マウスクリック +GenericName[ka]=თაგუნას ავტომატური წკაპი +GenericName[km]= ចុចកណ្តុរដោយស្វ័យប្រវត្តិ +GenericName[lt]=Automatiniai pelės paspaudimai +GenericName[mk]=Автоматско кликнување на глушецот +GenericName[ms]=Klik Tetikus Automatik +GenericName[mt]=Klikk tal-Maws Awtomatiku +GenericName[nb]=Automatisk museklikk +GenericName[nds]=Automaatsche Muusklicks +GenericName[ne]=स्वचालित माउस क्लिक +GenericName[nl]=Automatische muisklik +GenericName[nn]=Automatisk museklikk +GenericName[pa]=ਐਟੋਮੈਟਿਕ ਮਾਊਸ ਕਲਿੱਕ +GenericName[pl]=Automatyczne klikanie myszą +GenericName[pt]=Carregar no Rato +GenericName[pt_BR]=Clique Automático do Mouse +GenericName[ro]=Clic automat de mouse +GenericName[ru]=Автощелчок мышью +GenericName[sk]=Automatické klikanie myšou +GenericName[sl]=Samodejni klik miške +GenericName[sr]=Аутоматски клик мишем +GenericName[sr@Latn]=Automatski klik mišem +GenericName[sv]=Automatiska musklick +GenericName[ta]=தானியங்கி சுட்டி சொடுக்கல் +GenericName[tg]=Зер кардани автоматии муш +GenericName[th]=คลิ้กเม้าส์อัตโนมัติ +GenericName[tr]=Otomatik Fare Tıklaması +GenericName[uk]=Автоматичне клацання мишкою +GenericName[uz]=Sichqonchani avto-bosish +GenericName[uz@cyrillic]=Сичқончани авто-босиш +GenericName[vi]=Ấn Chuột Tự động +GenericName[zh_CN]=自动鼠标点击 +GenericName[zh_TW]=自動滑鼠點擊 +Categories=Qt;KDE;Utility;Accessibility; + diff --git a/kmousetool/kmousetool/kmousetool.h b/kmousetool/kmousetool/kmousetool.h new file mode 100644 index 0000000..88a05ec --- /dev/null +++ b/kmousetool/kmousetool/kmousetool.h @@ -0,0 +1,209 @@ +/*************************************************************************** + kmousetool.h - description + ------------------- + begin : Sun Jan 20 23:27:58 PST 2002 + copyright : (C) 2002-2003 by Jeff Roush + email : jeff@mousetool.com + copyright : (C) 2003 by Olaf Schmidt + email : ojschmidt@kde.org + copyright : (C) 2003 by Gunnar Schmi Dt + email : gunnar@schmi-dt.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 KMOUSETOOL_H +#define KMOUSETOOL_H + +#include <qdir.h> + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "version.h" + +#include <kapplication.h> +#include <ksystemtray.h> +#include <qwidget.h> +#include "mtstroke.h" +#include "kmousetoolui.h" + +class QLineEdit; +class QLabel; +class QCheckBox; +class QPushButton; +class KAudioPlayer; +class KAboutApplication; +class KMouseToolTray; + + +/** + * KMouseTool is the base class of the project + * + * It is the main widget for the dialog + * + */ + +class KMouseTool : public KMouseToolUI +{ + Q_OBJECT + +private: + MTStroke stroke; + + // boolean flags to keep track of program states + int mouse_is_down; + int continue_timer; + int tick_count; + int dwell_time; + int drag_time; + int max_ticks; + int min_movement; + bool smart_drag_on; + bool playSound; + bool mousetool_is_running; + bool mousetool_just_started; + bool moving; + bool strokesEnabled; + + QString autostartdirname; + QString rcfilename; + QString appfilename; + QString mSoundFileName; + KAudioPlayer *mplayer; + KMouseToolTray *trayIcon; + + KAboutApplication *aboutDlg; + + /** + * Initialize all variables + */ + void init_vars(); + + /** + * Take care of details of playing .wav file + * + * Currently uses KAudioPlayer::play(), which has an annoying delay. + * + * The solution seems to be to use MCOP, but I haven't been able to get that to work yet. + */ + void playTickSound(); + + /** + * Load state of program from "kmousetool.rc" in the user's local .kde folder, + * + */ + void loadOptions(); + + /** + * Save state of program under the user's local .kde folder, + * in a file named "kmousetool.rc" + * + */ + void saveOptions(); + + /** + * This function changes text on button depending on + * state of time (either "start", or "stop"). + **/ + void updateStartStopText(); + + /** + * Returns true if the current values in the settings window are different + * from the settings currently used + **/ + bool newSettings(); + + /** + * Returns true if the current values in the settings window are identical + * with the default settings + **/ + bool defaultSettings(); + + /** + * Resets the values in the settings window to the settings currently used + **/ + void resetSettings(); + + /** + * Sets the values in the settings window to the default settings + **/ + void setDefaultSettings(); + + /** + * Applies the current values in the settings window + **/ + bool applySettings(); + + bool isAutostart(); + void setAutostart (bool start); + +public slots: + /** + * This slot is called whenever a value in the settings window was changed. + * It enabled and disables the three buttons "Defaults", "Reset" and "Apply". + **/ + void settingsChanged(); + + void startStopSelected(); + + void defaultSelected(); + void resetSelected(); + void applySelected(); + + void helpSelected(); + void closeSelected(); + void quitSelected(); + + void aboutSelected(); + void configureSelected(); + +public: + /** + * This function runs the show; it is called once every + * 1/10 second. + * + * It checks to see if SmartDrag is on, and compares the + * current mouse position to its previous position to see + * whether to send a down click, and up click, or wait. + */ + void timerEvent (QTimerEvent *e); + + /** + * This generates a normal click event -- + * down, up, or down-up, depending on smart-drag settings and current state + */ + void normalClick(); + + /** + * construtor + */ + KMouseTool(QWidget* parent=0, const char *name=0); + + /** destructor */ + ~KMouseTool(); +}; + +class KMouseToolTray : public KSystemTray { + Q_OBJECT + int startStopId; +public: + KMouseToolTray (QWidget *parent=0, const char *name=0); + ~KMouseToolTray(); + + void updateStartStopText (bool mousetool_is_running); +signals: + void startStopSelected(); + void configureSelected(); + void aboutSelected(); + void helpSelected(); +}; +#endif diff --git a/kmousetool/kmousetool/kmousetoolui.ui b/kmousetool/kmousetool/kmousetoolui.ui new file mode 100644 index 0000000..05b3322 --- /dev/null +++ b/kmousetool/kmousetool/kmousetoolui.ui @@ -0,0 +1,422 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KMouseToolUI</class> +<widget class="QWidget"> + <property name="name"> + <cstring>KMouseToolUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>544</width> + <height>395</height> + </rect> + </property> + <property name="caption"> + <string>KMouseTool</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="2" column="0"> + <property name="name"> + <cstring>spacer7</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>30</height> + </size> + </property> + </spacer> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>layout9</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="0" column="0"> + <property name="name"> + <cstring>dragTimeSpace</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>dragTimeLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Drag t&ime (1/10 sec):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>dragTimeEdit</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="KIntSpinBox" row="3" column="1"> + <property name="name"> + <cstring>dragTimeEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>40</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>3</number> + </property> + </widget> + <widget class="KIntSpinBox" row="1" column="1"> + <property name="name"> + <cstring>dwellTimeEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>40</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>5</number> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>movementLabel</cstring> + </property> + <property name="text"> + <string>&Minimum movement:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>movementEdit</cstring> + </property> + </widget> + <widget class="KIntSpinBox" row="0" column="1"> + <property name="name"> + <cstring>movementEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>40</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>cbStroke</cstring> + </property> + <property name="text"> + <string>&Enable strokes</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>dwellTimeLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>D&well time (1/10 sec):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>dwellTimeEdit</cstring> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>cbDrag</cstring> + </property> + <property name="text"> + <string>Smar&t drag</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="7" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonDefault</cstring> + </property> + <property name="text"> + <string>&Defaults</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonReset</cstring> + </property> + <property name="text"> + <string>&Reset</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>31</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonApply</cstring> + </property> + <property name="text"> + <string>&Apply</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QCheckBox" row="6" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>cbStart</cstring> + </property> + <property name="text"> + <string>Start with &KDE</string> + </property> + </widget> + <widget class="QCheckBox" row="5" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>cbClick</cstring> + </property> + <property name="text"> + <string>A&udible click</string> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>KMouseTool will run as a background application after you close this dialog. To change the settings again, restart KMouseTool or use the KDE system tray.</string> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="alignment"> + <set>WordBreak|AlignJustify|AlignVCenter</set> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>8</width> + <height>8</height> + </size> + </property> + </spacer> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonStartStop</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Start</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>&Help</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>241</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonClose</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonQuit</cstring> + </property> + <property name="text"> + <string>&Quit</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>cbDrag</sender> + <signal>toggled(bool)</signal> + <receiver>dragTimeLabel</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>cbDrag</sender> + <signal>toggled(bool)</signal> + <receiver>dragTimeEdit</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/kmousetool/kmousetool/main.cpp b/kmousetool/kmousetool/main.cpp new file mode 100644 index 0000000..29c5e30 --- /dev/null +++ b/kmousetool/kmousetool/main.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Sun Jan 20 23:27:58 PST 2002 + copyright : (C) 2002 by Jeff Roush + email : jeff@mousetool.com + copyright : (C) 2003 by Olaf Schmidt + email : ojschmidt@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include <kcmdlineargs.h> +#include <kaboutdata.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kuniqueapplication.h> +#include <dcopclient.h> +#include <qmessagebox.h> +#include <kconfig.h> + +#include "kmousetool.h" + +static const char description[] = + I18N_NOOP("KMouseTool"); +// INSERT A DESCRIPTION FOR YOUR APPLICATION HERE + + +static KCmdLineOptions options[] = +{ + KCmdLineLastOption + // INSERT YOUR COMMANDLINE OPTIONS HERE +}; + +int main(int argc, char *argv[]) +{ + KAboutData aboutData( "kmousetool", I18N_NOOP("KMouseTool"), + KMOUSETOOL_VERSION, description, KAboutData::License_GPL, + "(c) 2002-2003, Jeff Roush\n(c) 2003, Gunnar Schmi Dt", 0, "http://www.mousetool.com", "gunnar@schmi-dt.de"); + + aboutData.addAuthor("Gunnar Schmi Dt", I18N_NOOP("Current maintainer"), "gunnar@schmi-dt.de", "http://www.schmi-dt.de"); + aboutData.addAuthor("Olaf Schmidt", I18N_NOOP("Usability improvements"), "ojschmidt@kde.org"); + aboutData.addAuthor("Jeff Roush", I18N_NOOP("Original author"), "jeff@mousetool.com", "http://www.mousetool.com"); + + aboutData.addCredit("Joe Betts"); + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions( options ); // Add our own options. + KUniqueApplication::addCmdLineOptions(); + + if (!KUniqueApplication::start()) { + DCOPClient *client = new DCOPClient(); + client->attach(); + QByteArray data; + QCString replyType; + QByteArray replyData; + if ( !client->call("kmousetool", "qt/KMouseToolUI", "show()", + data, replyType, replyData, true) || + !client->call("kmousetool", "qt/KMouseToolUI", "raise()", + data, replyType, replyData, true) ) + fprintf(stderr, "The DCOP calls failed\n"); + delete client; + exit(0); + } + KUniqueApplication a; + + KMouseTool *kmousetool = new KMouseTool(); + + if (!kapp->config()->readBoolEntry("IsMinimized", false)) + kmousetool->show(); + + return a.exec(); +} diff --git a/kmousetool/kmousetool/mousetool_tap.wav b/kmousetool/kmousetool/mousetool_tap.wav Binary files differnew file mode 100644 index 0000000..797facb --- /dev/null +++ b/kmousetool/kmousetool/mousetool_tap.wav diff --git a/kmousetool/kmousetool/mtstroke.cpp b/kmousetool/kmousetool/mtstroke.cpp new file mode 100644 index 0000000..16b1078 --- /dev/null +++ b/kmousetool/kmousetool/mtstroke.cpp @@ -0,0 +1,288 @@ +/*************************************************************************** + mtstroke.cpp - description + ------------------- + begin : Fri Oct 11 2002 + copyright : (C) 2002 by Jeff Roush + email : jeff@mousetool.com + copyright : (C) 2003 by Olaf Schmidt + email : ojschmidt@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "mtstroke.h" +#include "kmousetool.h" +#include <iostream> + +// these are for locating the stroke information file +#include <kstandarddirs.h> +#include <qstring.h> + +// #include <string> + +using namespace std; + +const int MTStroke::DontClick = -1; +const int MTStroke::bumped_mouse = 0; +const int MTStroke::normal = 1; +const int MTStroke::RightClick = 2; +const int MTStroke::DoubleClick = 3; +const int MTStroke::circle = 4; +const int MTStroke::LowerLeftStroke = 5; +const int MTStroke::UpperRightStroke = 6; +const int MTStroke::LowerRightStroke = 7; +const int MTStroke::UpperLeftStroke = 8; + +int MTStroke::delta_xy = 10; + +const int MTStroke::min_num_points = 5; + +Pt MTStroke::LowerLeft (0,0); +Pt MTStroke::LowerRight(0,0); +Pt MTStroke::UpperLeft (0,0); +Pt MTStroke::UpperRight(0,0); + + + +MTStroke::MTStroke(){ + readSequence(); +} +MTStroke::~MTStroke(){ +} + +// add the new point, but only if it's not the same as the previous point. +void MTStroke::addPt(const int x, const int y) +{ + if (points.size()==0) { + points.push_back(Pt(x,y)); + } + else { + Pt pt(x,y); + if (!pt.sameAs(points[points.size()-1])) { + points.push_back(Pt(x,y)); + } + } +} + + +/* + * Loop over all the strokes; + * return true if the given point is included + */ +bool MTStroke::pointsContain(Pt pt) +{ + std::vector<Pt>::iterator pos; + for (pos=points.begin(); pos<points.end(); pos++) { + if (pt.x==pos->x && pt.y==pos->y) + return true; + } + return false; +} + +int MTStroke::getStrokeType() +{ + int size = points.size(); + + // If the mouse moved just a bit, it was probably bumped. Don't click. + if (size<min_num_points) + return normal; +// return bumped_mouse; + + Pt lastPoint = points[points.size()-1]; + + // If the mouse is pausing in a corner, then the user is either in the middle of a + // stroke, or wants to rest the mouse. Don't click. + if (lastPoint.sameAs(LowerLeft) || lastPoint.sameAs(LowerRight) + || lastPoint.sameAs(UpperLeft) || lastPoint.sameAs(UpperRight)) + return DontClick; + + // If the mouse visited a corner... + if (pointsContain(LowerLeft)) { + reset(); + return LowerLeftStroke; + } + if (pointsContain(UpperRight)) { + reset(); + return UpperRightStroke; + } + scale(); + + std::map<std::string, int>::iterator keypos = sequenceMap.find(sequence); + if (keypos == sequenceMap.end()) { + reset(); + return normal; + } + reset(); +// return RightClick; + return keypos->second; +} + +void MTStroke::scale() +{ + getExtent(); + int deltax = stroke_maxx - stroke_minx; + int deltay = stroke_maxy - stroke_miny; + int delta = max(deltax, deltay); + int scale = (int) delta/2; + + std::vector<Pt>::iterator pos; + for (pos=points.begin(); pos<points.end(); pos++) { + + // add an extra (scale/2) because the divide rounds _down_, and we want to + // round _up_ or _down_, depending on which is closer. + pos->x = (int) (pos->x-stroke_minx + scale/2)/scale; + pos->y = (int) (pos->y-stroke_miny + scale/2)/scale; + + // now, get the integer representing this position and add it to the stroke sequence + int n = 3*pos->y + pos->x + 1; + int index = sequence.size()-1; + n += '0'; + if (index==-1) + sequence += n; + else if (n!=sequence[index]) + sequence += n; + } +} + +int MTStroke::max(int n, int m) +{ + if (n>m) + return n; + return m; +} + + +/* + * Find the bounding rectangle for the stroke + */ +void MTStroke::getExtent() +{ + stroke_minx = UpperRight.x; + stroke_maxx = 0; + stroke_miny = LowerLeft.y; + stroke_maxy = 0; + + std::vector<Pt>::iterator pos; + for (pos=points.begin(); pos<points.end(); pos++) { + if (stroke_minx > pos->x) + stroke_minx = pos->x; + if (stroke_maxx < pos->x) + stroke_maxx = pos->x; + if (stroke_miny > pos->y) + stroke_miny = pos->y; + if (stroke_maxy < pos->y) + stroke_maxy = pos->y; + } +} + +// test if strokefile exists; if not, create it from defaults. +// if unable to create it, +bool MTStroke::readSequence() +{ + QString strokefilename; + strokefilename = locate("config", "kmousetool_strokes.txt"); + if (strokefilename.isEmpty()) { + // make default + if (sequenceMap.size()==0) + makeDefaultSequenceMap(); + writeSequence(); + return false; + } + ifstream infile (strokefilename.ascii()); + if (!infile) { + // make default + if (sequenceMap.size()==0) + makeDefaultSequenceMap(); + writeSequence(); + return false; + } + + while (!infile.eof()) { + string str; + infile >> str; + if (str[0] == '#') + readToEndOfLine(infile); + else { + // get the associated action + string str2; + infile >> str2; + int n = str2[0] - '0'; // the action is a single integer digit; convert it to an int + sequenceMap[ string(str) ] = n; + } + } + return true; +} + +bool MTStroke::writeSequence() +{ + QString strokefilename; + strokefilename = locateLocal("config", "kmousetool_strokes.txt"); + + ofstream outfile (strokefilename.ascii(), ios::out); + if (!outfile) { + return false; + } + + outfile << "# This file contains definitions for valid strokes for KMouseTool\n"; + outfile << "# To make sense of the numbers: \n"; + outfile << "# The mouse path begins and ends when the mouse is paused.\n"; + outfile << "# Imagine a square enclosing the path.\n"; + outfile << "# Divide the square into 9 boxes, and number them like so:\n"; + outfile << "# 1 2 3\n"; + outfile << "# 4 5 6\n"; + outfile << "# 7 8 9\n"; + outfile << "# \n"; + outfile << "# The mouse path can then be described by a sequence of numbers:\n"; + outfile << "# for example, \"12321\" describes the mouse moving from left to right and back.\n"; + outfile << "# This general scheme follows libstroke (http://www.etla.net/~willey/projects/libstroke/)\n"; + outfile << "# although it was reimplemented from scratch for KMouseTool.\n"; + outfile << "\n"; + outfile << "# For each stroke recognized, provide an integer describing an action\n"; + outfile << "# KMouseTool can take. At the moment, valid actions are:\n"; + outfile << "# -1 Don't click\n"; + outfile << "# 1 Normal click (use Smart Drag if that's enabled)\n"; + outfile << "# 2 Right click\n"; + outfile << "# 3 Double click\n"; + outfile << "\n"; + outfile << "#Stroke\tAction\n"; + std::map<std::string, int>::iterator pos = sequenceMap.begin(); + while (pos != sequenceMap.end()) { + outfile << pos->first << "\t" << pos->second << "\n"; + pos++; + } + return true; +} + +void MTStroke::makeDefaultSequenceMap() +{ + sequenceMap[ string("12321") ] = RightClick; + sequenceMap[ string("1321") ] = RightClick; + sequenceMap[ string("1231") ] = RightClick; + sequenceMap[ string("131") ] = RightClick; + + sequenceMap[ string("32123") ] = DoubleClick; + sequenceMap[ string("3213") ] = DoubleClick; + sequenceMap[ string("3123") ] = DoubleClick; + sequenceMap[ string("313") ] = DoubleClick; +/* + sequenceMap[ string("") ] = ; + sequenceMap[ string("") ] = ; + sequenceMap[ string("") ] = ; + sequenceMap[ string("") ] = ; + sequenceMap[ string("") ] = ; +*/ +} + +void MTStroke::readToEndOfLine(ifstream &infile) +{ + char ch = 'a'; + while (ch != '\n') + infile.get(ch); +} diff --git a/kmousetool/kmousetool/mtstroke.h b/kmousetool/kmousetool/mtstroke.h new file mode 100644 index 0000000..171204c --- /dev/null +++ b/kmousetool/kmousetool/mtstroke.h @@ -0,0 +1,103 @@ +/*************************************************************************** + mtstroke.h - description + ------------------- + begin : Fri Oct 11 2002 + copyright : (C) 2002 by Jeff Roush + email : jeff@mousetool.com + copyright : (C) 2003 by Olaf Schmidt + email : ojschmidt@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 MTSTROKE_H +#define MTSTROKE_H +#include <vector> +#include <fstream> +#include <map> +#include <string> +#include <cstdlib> + +/**Implements stroke recording for MouseTool. + *@author Jeff Roush + */ + +class Pt { + + public: + int x,y; + Pt () { } ; + Pt (const int xx, const int yy) { x=xx; y=yy; }; + bool sameAs(Pt pt) { return (x==pt.x&&y==pt.y); }; + bool nearTo(Pt pt, int delta) { return ( (std::abs(x-pt.x)<delta) && (std::abs(y-pt.y)<delta) ); } + + void dump(); +}; + +class MTStroke { + std::vector<Pt> points; +// std::vector<int> sequence; + std::string sequence; + std::map<std::string, int> sequenceMap; + + int stroke_minx; + int stroke_maxx; + int stroke_miny; + int stroke_maxy; + + void makeDefaultSequenceMap(); + +public: + // stroke types + static const int bumped_mouse; + static const int normal; + static const int RightClick; + static const int DoubleClick; + static const int circle; + static const int DontClick; + static const int LowerLeftStroke; + static const int UpperRightStroke; + static const int LowerRightStroke; + static const int UpperLeftStroke; + + // Static ints + static int delta_xy; + static Pt LowerLeft; + static Pt LowerRight; + static Pt UpperLeft; + static Pt UpperRight; + + // min points before it can be considered a "stroke" + static const int min_num_points; + + static void setLowerLeft (int x, int y) { LowerLeft.x = x; LowerLeft.y = y; }; + static void setLowerRight(int x, int y) { LowerRight.x = x; LowerRight.y = y; }; + static void setUpperLeft (int x, int y) { UpperLeft.x = x; UpperLeft.y = y; }; + static void setUpperRight(int x, int y) { UpperRight.x = x; UpperRight.y = y; }; + + void dump(); + void scale(); + void addPt(int, int); + int max(int, int); + bool pointsContain(Pt pt); + int getStrokeType(); + void getExtent(); +// void getSequence(); + bool readSequence(); + bool writeSequence(); + void readToEndOfLine(std::ifstream &infile); + + void reset() { points.clear(); sequence = ""; } + + MTStroke(); + ~MTStroke(); +}; + +#endif diff --git a/kmousetool/kmousetool/pics/Makefile.am b/kmousetool/kmousetool/pics/Makefile.am new file mode 100644 index 0000000..f80db48 --- /dev/null +++ b/kmousetool/kmousetool/pics/Makefile.am @@ -0,0 +1,3 @@ +kmousetooliconsdir = $(kde_datadir)/kmousetool/icons +kmousetoolicons_ICON = AUTO +KDE_ICON = kmousetool diff --git a/kmousetool/kmousetool/pics/hi16-action-kmousetool_off.png b/kmousetool/kmousetool/pics/hi16-action-kmousetool_off.png Binary files differnew file mode 100644 index 0000000..e1a6fed --- /dev/null +++ b/kmousetool/kmousetool/pics/hi16-action-kmousetool_off.png diff --git a/kmousetool/kmousetool/pics/hi16-action-kmousetool_on.png b/kmousetool/kmousetool/pics/hi16-action-kmousetool_on.png Binary files differnew file mode 100644 index 0000000..2745591 --- /dev/null +++ b/kmousetool/kmousetool/pics/hi16-action-kmousetool_on.png diff --git a/kmousetool/kmousetool/pics/hi16-app-kmousetool.png b/kmousetool/kmousetool/pics/hi16-app-kmousetool.png Binary files differnew file mode 100644 index 0000000..b70b4bf --- /dev/null +++ b/kmousetool/kmousetool/pics/hi16-app-kmousetool.png diff --git a/kmousetool/kmousetool/pics/hi32-action-kmousetool_off.png b/kmousetool/kmousetool/pics/hi32-action-kmousetool_off.png Binary files differnew file mode 100644 index 0000000..db81487 --- /dev/null +++ b/kmousetool/kmousetool/pics/hi32-action-kmousetool_off.png diff --git a/kmousetool/kmousetool/pics/hi32-action-kmousetool_on.png b/kmousetool/kmousetool/pics/hi32-action-kmousetool_on.png Binary files differnew file mode 100644 index 0000000..0613275 --- /dev/null +++ b/kmousetool/kmousetool/pics/hi32-action-kmousetool_on.png diff --git a/kmousetool/kmousetool/pics/hi32-app-kmousetool.png b/kmousetool/kmousetool/pics/hi32-app-kmousetool.png Binary files differnew file mode 100644 index 0000000..391b486 --- /dev/null +++ b/kmousetool/kmousetool/pics/hi32-app-kmousetool.png diff --git a/kmousetool/kmousetool/version.h b/kmousetool/kmousetool/version.h new file mode 100644 index 0000000..9560d03 --- /dev/null +++ b/kmousetool/kmousetool/version.h @@ -0,0 +1,8 @@ +// KMouseTool Version Information +// +#ifndef kmousetool_version_h +#define kmousetool_version_h + +#define KMOUSETOOL_VERSION "1.12" + +#endif /*version_h*/ |