summaryrefslogtreecommitdiffstats
path: root/khotkeys/shared/triggers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'khotkeys/shared/triggers.cpp')
-rw-r--r--khotkeys/shared/triggers.cpp435
1 files changed, 435 insertions, 0 deletions
diff --git a/khotkeys/shared/triggers.cpp b/khotkeys/shared/triggers.cpp
new file mode 100644
index 000000000..1febedfa9
--- /dev/null
+++ b/khotkeys/shared/triggers.cpp
@@ -0,0 +1,435 @@
+/****************************************************************************
+
+ KHotKeys
+
+ Copyright (C) 1999-2001 Lubos Lunak <l.lunak@kde.org>
+
+ Distributed under the terms of the GNU General Public License version 2.
+
+****************************************************************************/
+
+#define _TRIGGERS_CPP_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "triggers.h"
+
+#include <kglobalaccel.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kwinmodule.h>
+#include <klocale.h>
+#include <netwm_def.h>
+#include <kaccel.h>
+
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+
+#include "actions.h"
+#include "action_data.h"
+#include "input.h"
+#include "gestures.h"
+#include "windows.h"
+#include "voices.h"
+
+namespace KHotKeys
+{
+
+// Trigger
+
+void Trigger::cfg_write( KConfig& cfg_P ) const
+ {
+ cfg_P.writeEntry( "Type", "ERROR" );
+ }
+
+Trigger* Trigger::create_cfg_read( KConfig& cfg_P, Action_data* data_P )
+ {
+ QString type = cfg_P.readEntry( "Type" );
+ if( type == "SHORTCUT" || type == "SINGLE_SHORTCUT" )
+ return new Shortcut_trigger( cfg_P, data_P );
+ if( type == "WINDOW" )
+ return new Window_trigger( cfg_P, data_P );
+ if( type == "GESTURE" )
+ return new Gesture_trigger(cfg_P, data_P );
+ if( type == "VOICE" )
+ return new Voice_trigger (cfg_P, data_P );
+
+ kdWarning( 1217 ) << "Unknown Trigger type read from cfg file\n";
+ return NULL;
+ }
+
+// Trigger_list
+
+Trigger_list::Trigger_list( KConfig& cfg_P, Action_data* data_P )
+ : QPtrList< Trigger >()
+ {
+ setAutoDelete( true );
+ _comment = cfg_P.readEntry( "Comment" );
+ QString save_cfg_group = cfg_P.group();
+ int cnt = cfg_P.readNumEntry( "TriggersCount", 0 );
+ for( int i = 0;
+ i < cnt;
+ ++i )
+ {
+ cfg_P.setGroup( save_cfg_group + QString::number( i ));
+ Trigger* trigger = Trigger::create_cfg_read( cfg_P, data_P );
+ if( trigger )
+ append( trigger );
+ }
+ cfg_P.setGroup( save_cfg_group );
+ }
+
+void Trigger_list::cfg_write( KConfig& cfg_P ) const
+ {
+ cfg_P.writeEntry( "Comment", comment());
+ QString save_cfg_group = cfg_P.group();
+ int i = 0;
+ for( Iterator it( *this );
+ it;
+ ++it, ++i )
+ {
+ cfg_P.setGroup( save_cfg_group + QString::number( i ));
+ it.current()->cfg_write( cfg_P );
+ }
+ cfg_P.setGroup( save_cfg_group );
+ cfg_P.writeEntry( "TriggersCount", i );
+ }
+
+Trigger_list* Trigger_list::copy( Action_data* data_P ) const
+ {
+ Trigger_list* ret = new Trigger_list( comment());
+ for( Iterator it( *this );
+ it;
+ ++it )
+ ret->append( it.current()->copy( data_P ));
+ return ret;
+ }
+
+void Trigger_list::activate( bool activate_P )
+ {
+ for( Iterator it( *this );
+ it;
+ ++it )
+ ( *it )->activate( activate_P );
+ }
+
+// Shortcut_trigger
+
+Shortcut_trigger::Shortcut_trigger( Action_data* data_P, const KShortcut& shortcut_P )
+ : Trigger( data_P ), _shortcut( shortcut_P )
+ {
+ keyboard_handler->insert_item( shortcut(), this );
+ }
+
+Shortcut_trigger::Shortcut_trigger( KConfig& cfg_P, Action_data* data_P )
+ : Trigger( cfg_P, data_P ), _shortcut( cfg_P.readEntry( "Key", 0 ))
+ {
+ keyboard_handler->insert_item( shortcut(), this );
+ }
+
+Shortcut_trigger::~Shortcut_trigger()
+ {
+ keyboard_handler->remove_item( shortcut(), this );
+ }
+
+void Shortcut_trigger::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ cfg_P.writeEntry( "Key", _shortcut.toStringInternal());
+ cfg_P.writeEntry( "Type", "SHORTCUT" ); // overwrites value set in base::cfg_write()
+ }
+
+Shortcut_trigger* Shortcut_trigger::copy( Action_data* data_P ) const
+ {
+ kdDebug( 1217 ) << "Shortcut_trigger::copy()" << endl;
+ return new Shortcut_trigger( data_P ? data_P : data, shortcut());
+ }
+
+const QString Shortcut_trigger::description() const
+ {
+ // CHECKME vice mods
+ return i18n( "Shortcut trigger: " ) + _shortcut.toString();
+ // CHECKME i18n pro toString() ?
+ }
+
+bool Shortcut_trigger::handle_key( const KShortcut& shortcut_P )
+ {
+ if( shortcut() == shortcut_P )
+ {
+ windows_handler->set_action_window( 0 ); // use active window
+ data->execute();
+ return true;
+ }
+ return false;
+ }
+
+void Shortcut_trigger::activate( bool activate_P )
+ {
+ if( activate_P && khotkeys_active())
+ keyboard_handler->activate_receiver( this );
+ else
+ keyboard_handler->deactivate_receiver( this );
+ }
+
+// Window_trigger
+
+Window_trigger::Window_trigger( KConfig& cfg_P, Action_data* data_P )
+ : Trigger( cfg_P, data_P ), active( false )
+ {
+// kdDebug( 1217 ) << "Window_trigger" << endl;
+ QString save_cfg_group = cfg_P.group();
+ cfg_P.setGroup( save_cfg_group + "Windows" );
+ _windows = new Windowdef_list( cfg_P );
+ cfg_P.setGroup( save_cfg_group );
+ window_actions = cfg_P.readNumEntry( "WindowActions" );
+ init();
+ }
+
+Window_trigger::~Window_trigger()
+ {
+// kdDebug( 1217 ) << "~Window_trigger :" << this << endl;
+ disconnect( windows_handler, NULL, this, NULL );
+ delete _windows;
+ }
+
+void Window_trigger::init()
+ {
+ kdDebug( 1217 ) << "Window_trigger::init()" << endl;
+ connect( windows_handler, SIGNAL( window_added( WId )), this, SLOT( window_added( WId )));
+ connect( windows_handler, SIGNAL( window_removed( WId )), this, SLOT( window_removed( WId )));
+ if( window_actions & ( WINDOW_ACTIVATES | WINDOW_DEACTIVATES /*| WINDOW_DISAPPEARS*/ ))
+ connect( windows_handler, SIGNAL( active_window_changed( WId )),
+ this, SLOT( active_window_changed( WId )));
+ connect( windows_handler, SIGNAL( window_changed( WId, unsigned int )),
+ this, SLOT( window_changed( WId, unsigned int )));
+ }
+
+void Window_trigger::activate( bool activate_P )
+ {
+ active = activate_P && khotkeys_active();
+ }
+
+void Window_trigger::window_added( WId window_P )
+ {
+ bool matches = windows()->match( Window_data( window_P ));
+ existing_windows[ window_P ] = matches;
+ kdDebug( 1217 ) << "Window_trigger::w_added() : " << matches << endl;
+ if( active && matches && ( window_actions & WINDOW_APPEARS ))
+ {
+ windows_handler->set_action_window( window_P );
+ data->execute();
+ }
+ }
+
+void Window_trigger::window_removed( WId window_P )
+ {
+ if( existing_windows.contains( window_P ))
+ {
+ bool matches = existing_windows[ window_P ];
+ kdDebug( 1217 ) << "Window_trigger::w_removed() : " << matches << endl;
+ if( active && matches && ( window_actions & WINDOW_DISAPPEARS ))
+ {
+ windows_handler->set_action_window( window_P );
+ data->execute();
+ }
+ existing_windows.remove( window_P );
+ // CHECKME jenze co kdyz se window_removed zavola pred active_window_changed ?
+ }
+ else
+ kdDebug( 1217 ) << "Window_trigger::w_removed()" << endl;
+ }
+
+void Window_trigger::active_window_changed( WId window_P )
+ {
+ bool was_match = false;
+ if( existing_windows.contains( last_active_window ))
+ was_match = existing_windows[ last_active_window ];
+ if( active && was_match && ( window_actions & WINDOW_DEACTIVATES ))
+ {
+ windows_handler->set_action_window( window_P );
+ data->execute();
+ }
+/* bool matches = windows()->match( Window_data( window_P ));
+ existing_windows[ window_P ] = matches;*/
+ bool matches = existing_windows.contains( window_P )
+ ? existing_windows[ window_P ] : false;
+ if( active && matches && ( window_actions & WINDOW_ACTIVATES ))
+ {
+ windows_handler->set_action_window( window_P );
+ data->execute();
+ }
+ kdDebug( 1217 ) << "Window_trigger::a_w_changed() : " << was_match << "|" << matches << endl;
+ last_active_window = window_P;
+ }
+
+void Window_trigger::window_changed( WId window_P, unsigned int dirty_P )
+ { // CHECKME snad nebude mit vliv, kdyz budu kaslat na properties_P a zkratka
+ // kontrolovat kazdou zmenu
+ // CHECKME kdyz se zmeni okno z match na non-match, asi to nebrat jako DISAPPEAR
+ if( ! ( dirty_P & ( NET::WMName | NET::WMWindowType )))
+ return;
+ kdDebug( 1217 ) << "Window_trigger::w_changed()" << endl;
+ bool was_match = false;
+ if( existing_windows.contains( window_P ))
+ was_match = existing_windows[ window_P ];
+ bool matches = windows()->match( Window_data( window_P ));
+ existing_windows[ window_P ] = matches;
+ if( active && matches && !was_match )
+ if( window_actions & WINDOW_APPEARS )
+ {
+ windows_handler->set_action_window( window_P );
+ data->execute();
+ }
+ else if( window_actions & WINDOW_ACTIVATES && window_P == windows_handler->active_window())
+ {
+ windows_handler->set_action_window( window_P );
+ data->execute();
+ }
+ kdDebug( 1217 ) << "Window_trigger::w_changed() : " << was_match << "|" << matches << endl;
+ }
+
+void Window_trigger::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ QString save_cfg_group = cfg_P.group();
+ cfg_P.setGroup( save_cfg_group + "Windows" );
+ windows()->cfg_write( cfg_P );
+ cfg_P.setGroup( save_cfg_group );
+ cfg_P.writeEntry( "WindowActions", window_actions );
+ cfg_P.writeEntry( "Type", "WINDOW" ); // overwrites value set in base::cfg_write()
+ }
+
+#ifndef COVARIANT_RETURN_BROKEN // stupid gcc, it doesn't even warn it can't do this
+Window_trigger* Window_trigger::copy( Action_data* data_P ) const
+#else
+Trigger* Window_trigger::copy( Action_data* data_P ) const
+#endif
+ {
+ Window_trigger* ret = new Window_trigger( data_P ? data_P : data, windows()->copy(),
+ window_actions );
+ ret->existing_windows = existing_windows; // CHECKME je tohle vazne treba ?
+ return ret;
+ }
+
+const QString Window_trigger::description() const
+ {
+ return i18n( "Window trigger: " ) + windows()->comment();
+ }
+
+// Gesture_trigger
+
+Gesture_trigger::Gesture_trigger( Action_data* data_P, const QString &gesturecode_P )
+ : Trigger( data_P ), _gesturecode( gesturecode_P )
+ {
+ }
+
+Gesture_trigger::Gesture_trigger( KConfig& cfg_P, Action_data* data_P )
+ : Trigger( cfg_P, data_P )
+ {
+ _gesturecode = cfg_P.readEntry( "Gesture" );
+ }
+
+Gesture_trigger::~Gesture_trigger()
+ {
+ gesture_handler->unregister_handler( this, SLOT( handle_gesture( const QString&, WId )));
+ }
+
+void Gesture_trigger::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ cfg_P.writeEntry( "Gesture", gesturecode());
+ cfg_P.writeEntry( "Type", "GESTURE" ); // overwrites value set in base::cfg_write()
+ }
+
+Trigger* Gesture_trigger::copy( Action_data* data_P ) const
+ {
+ kdDebug( 1217 ) << "Gesture_trigger::copy()" << endl;
+ return new Gesture_trigger( data_P ? data_P : data, gesturecode());
+ }
+
+const QString Gesture_trigger::description() const
+ {
+ return i18n( "Gesture trigger: " ) + gesturecode();
+ }
+
+void Gesture_trigger::handle_gesture( const QString &gesture_P, WId window_P )
+ {
+ if( gesturecode() == gesture_P )
+ {
+ windows_handler->set_action_window( window_P );
+ data->execute();
+ }
+ }
+
+void Gesture_trigger::activate( bool activate_P )
+ {
+ if( activate_P )
+ gesture_handler->register_handler( this, SLOT( handle_gesture( const QString&, WId )));
+ else
+ gesture_handler->unregister_handler( this, SLOT( handle_gesture( const QString&, WId )));
+ }
+
+
+// Voice_trigger
+
+ Voice_trigger::Voice_trigger( Action_data* data_P, const QString &Voicecode_P, const VoiceSignature& signature1_P, const VoiceSignature& signature2_P )
+ : Trigger( data_P ), _voicecode( Voicecode_P )
+ {
+ _voicesignature[0]=signature1_P;
+ _voicesignature[1]=signature2_P;
+ }
+
+Voice_trigger::Voice_trigger( KConfig& cfg_P, Action_data* data_P )
+ : Trigger( cfg_P, data_P )
+ {
+ _voicecode = cfg_P.readEntry( "Name" );
+ _voicesignature[0].read( &cfg_P , "Signature1" );
+ _voicesignature[1].read( &cfg_P , "Signature2" );
+ }
+
+Voice_trigger::~Voice_trigger()
+ {
+ voice_handler->unregister_handler( this );
+ }
+
+void Voice_trigger::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ cfg_P.writeEntry( "Name", voicecode());
+ cfg_P.writeEntry( "Type", "VOICE" ); // overwrites value set in base::cfg_write()
+ _voicesignature[0].write( &cfg_P , "Signature1" );
+ _voicesignature[1].write( &cfg_P , "Signature2" );
+ }
+
+Trigger* Voice_trigger::copy( Action_data* data_P ) const
+ {
+ kdDebug( 1217 ) << "Voice_trigger::copy()" << endl;
+ return new Voice_trigger( data_P ? data_P : data, voicecode(), voicesignature(1) , voicesignature(2) );
+ }
+
+const QString Voice_trigger::description() const
+ {
+ return i18n( "Voice trigger: " ) + voicecode();
+ }
+
+void Voice_trigger::handle_Voice( )
+ {
+ windows_handler->set_action_window( 0 ); // use active window
+ data->execute();
+
+ }
+
+void Voice_trigger::activate( bool activate_P )
+ {
+ if( activate_P && khotkeys_active())
+ voice_handler->register_handler( this );
+ else
+ voice_handler->unregister_handler( this );
+ }
+
+
+} // namespace KHotKeys
+
+#include "triggers.moc"