summaryrefslogtreecommitdiffstats
path: root/khotkeys/shared/actions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'khotkeys/shared/actions.cpp')
-rw-r--r--khotkeys/shared/actions.cpp450
1 files changed, 450 insertions, 0 deletions
diff --git a/khotkeys/shared/actions.cpp b/khotkeys/shared/actions.cpp
new file mode 100644
index 000000000..144a277af
--- /dev/null
+++ b/khotkeys/shared/actions.cpp
@@ -0,0 +1,450 @@
+/****************************************************************************
+
+ KHotKeys
+
+ Copyright (C) 1999-2001 Lubos Lunak <[email protected]>
+
+ Distributed under the terms of the GNU General Public License version 2.
+
+****************************************************************************/
+
+#define _ACTIONS_CPP_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "actions.h"
+
+#include <krun.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kurifilter.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <kdesktopfile.h>
+#include <klocale.h>
+#include <kaccel.h>
+#include <kservice.h>
+#include <kprocess.h>
+
+#include "windows.h"
+#include "action_data.h"
+
+#include <X11/X.h>
+
+namespace KHotKeys
+{
+
+// Action
+
+Action* Action::create_cfg_read( KConfig& cfg_P, Action_data* data_P )
+ {
+ QString type = cfg_P.readEntry( "Type" );
+ if( type == "COMMAND_URL" )
+ return new Command_url_action( cfg_P, data_P );
+ if( type == "MENUENTRY" )
+ return new Menuentry_action( cfg_P, data_P );
+ if( type == "DCOP" )
+ return new Dcop_action( cfg_P, data_P );
+ if( type == "KEYBOARD_INPUT" )
+ return new Keyboard_input_action( cfg_P, data_P );
+ if( type == "ACTIVATE_WINDOW" )
+ return new Activate_window_action( cfg_P, data_P );
+ kdWarning( 1217 ) << "Unknown Action type read from cfg file\n";
+ return NULL;
+ }
+
+void Action::cfg_write( KConfig& cfg_P ) const
+ {
+ cfg_P.writeEntry( "Type", "ERROR" ); // derived classes should call with their type
+ }
+
+// Action_list
+
+Action_list::Action_list( KConfig& cfg_P, Action_data* data_P )
+ : QPtrList< Action >()
+ {
+ setAutoDelete( true );
+ QString save_cfg_group = cfg_P.group();
+ int cnt = cfg_P.readNumEntry( "ActionsCount", 0 );
+ for( int i = 0;
+ i < cnt;
+ ++i )
+ {
+ cfg_P.setGroup( save_cfg_group + QString::number( i ));
+ Action* action = Action::create_cfg_read( cfg_P, data_P );
+ if( action )
+ append( action );
+ }
+ cfg_P.setGroup( save_cfg_group );
+ }
+
+void Action_list::cfg_write( KConfig& cfg_P ) const
+ {
+ 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( "ActionsCount", i );
+ }
+
+// Command_url_action
+
+Command_url_action::Command_url_action( KConfig& cfg_P, Action_data* data_P )
+ : Action( cfg_P, data_P )
+ {
+ _command_url = cfg_P.readEntry( "CommandURL" );
+ }
+
+void Command_url_action::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ cfg_P.writeEntry( "CommandURL", command_url());
+ cfg_P.writeEntry( "Type", "COMMAND_URL" ); // overwrites value set in base::cfg_write()
+ }
+
+void Command_url_action::execute()
+ {
+ if( command_url().isEmpty())
+ return;
+ KURIFilterData uri;
+ QString cmd = command_url();
+ static bool sm_ready = false;
+ if( !sm_ready )
+ {
+ kapp->propagateSessionManager();
+ sm_ready = true;
+ }
+// int space_pos = command_url().find( ' ' );
+// if( command_url()[ 0 ] != '\'' && command_url()[ 0 ] != '"' && space_pos > -1
+// && command_url()[ space_pos - 1 ] != '\\' )
+// cmd = command_url().left( space_pos ); // get first 'word'
+ uri.setData( cmd );
+ KURIFilter::self()->filterURI( uri );
+ if( uri.uri().isLocalFile() && !uri.uri().hasRef() )
+ cmd = uri.uri().path();
+ else
+ cmd = uri.uri().url();
+ switch( uri.uriType())
+ {
+ case KURIFilterData::LOCAL_FILE:
+ case KURIFilterData::LOCAL_DIR:
+ case KURIFilterData::NET_PROTOCOL:
+ case KURIFilterData::HELP:
+ {
+ ( void ) new KRun( uri.uri());
+ break;
+ }
+ case KURIFilterData::EXECUTABLE:
+ {
+ if (!kapp->authorize("shell_access"))
+ return;
+ if( !uri.hasArgsAndOptions())
+ {
+ KService::Ptr service = KService::serviceByDesktopName( cmd );
+ if( service != NULL )
+ {
+ KRun::run( *service, KURL::List());
+ break;
+ }
+ }
+ // fall though
+ }
+ case KURIFilterData::SHELL:
+ {
+ if (!kapp->authorize("shell_access"))
+ return;
+ if( !KRun::runCommand(
+ cmd + ( uri.hasArgsAndOptions() ? uri.argsAndOptions() : "" ),
+ cmd, uri.iconName())) {
+ // CHECKME ?
+ }
+ break;
+ }
+ default: // error
+ return;
+ }
+ timeout.start( 1000, true ); // 1sec timeout
+ }
+
+QString Command_url_action::description() const
+ {
+ return i18n( "Command/URL : " ) + command_url();
+ }
+
+Action* Command_url_action::copy( Action_data* data_P ) const
+ {
+ return new Command_url_action( data_P, command_url());
+ }
+
+// Menuentry_action
+
+void Menuentry_action::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ cfg_P.writeEntry( "Type", "MENUENTRY" ); // overwrites value set in base::cfg_write()
+ }
+
+KService::Ptr Menuentry_action::service() const
+ {
+ if (!_service)
+ {
+ const_cast<Menuentry_action *>(this)->_service = KService::serviceByStorageId(command_url());
+ }
+ return _service;
+ }
+
+void Menuentry_action::execute()
+ {
+ (void) service();
+ if (!_service)
+ return;
+ KRun::run( *_service, KURL::List());
+ timeout.start( 1000, true ); // 1sec timeout
+ }
+
+QString Menuentry_action::description() const
+ {
+ (void) service();
+ return i18n( "Menuentry : " ) + (_service ? _service->name() : QString::null);
+ }
+
+Action* Menuentry_action::copy( Action_data* data_P ) const
+ {
+ return new Menuentry_action( data_P, command_url());
+ }
+
+// Dcop_action
+
+Dcop_action::Dcop_action( KConfig& cfg_P, Action_data* data_P )
+ : Action( cfg_P, data_P )
+ {
+ app = cfg_P.readEntry( "RemoteApp" );
+ obj = cfg_P.readEntry( "RemoteObj" );
+ call = cfg_P.readEntry( "Call" );
+ args = cfg_P.readEntry( "Arguments" );
+ }
+
+void Dcop_action::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ cfg_P.writeEntry( "Type", "DCOP" ); // overwrites value set in base::cfg_write()
+ cfg_P.writeEntry( "RemoteApp", app );
+ cfg_P.writeEntry( "RemoteObj", obj );
+ cfg_P.writeEntry( "Call", call );
+ cfg_P.writeEntry( "Arguments", args );
+ }
+
+void Dcop_action::execute()
+ {
+ if( app.isEmpty() || obj.isEmpty() || call.isEmpty())
+ return;
+ QStringList args_list;
+ QString args_str = args;
+ while( !args_str.isEmpty())
+ {
+ unsigned int pos = 0;
+ while( args_str[ pos ] == ' ' )
+ ++pos;
+ if( args_str[ pos ] == '\"' || args_str[ pos ] == '\'' )
+ {
+ QString val = "";
+ QChar sep = args_str[ pos ];
+ bool skip = false;
+ ++pos;
+ for(;
+ pos < args_str.length();
+ ++pos )
+ {
+ if( args_str[ pos ] == '\\' )
+ {
+ skip = true;
+ continue;
+ }
+ if( !skip && args_str[ pos ] == sep )
+ break;
+ skip = false;
+ val += args_str[ pos ];
+ }
+ if( pos >= args_str.length())
+ return;
+ ++pos;
+ args_str = args_str.mid( pos );
+ args_list.append( val );
+ }
+ else
+ {
+ // one word
+ if( pos != 0 )
+ args_str = args_str.mid( pos );
+ int nxt_pos = args_str.find( ' ' );
+ args_list.append( args_str.left( nxt_pos )); // should be ok if nxt_pos is -1
+ args_str = nxt_pos >= 0 ? args_str.mid( nxt_pos ) : "";
+ }
+ }
+ kdDebug( 1217 ) << "DCOP call:" << app << ":" << obj << ":" << call << ":" << args_list << endl;
+ KProcess proc;
+ proc << "dcop" << app << obj << call << args_list;
+ proc.start( KProcess::DontCare );
+ }
+
+QString Dcop_action::description() const
+ {
+ return i18n( "DCOP : " ) + remote_application() + "::" + remote_object() + "::"
+ + called_function();
+ }
+
+Action* Dcop_action::copy( Action_data* data_P ) const
+ {
+ return new Dcop_action( data_P, remote_application(), remote_object(),
+ called_function(), arguments());
+ }
+
+// Keyboard_input_action
+
+Keyboard_input_action::Keyboard_input_action( KConfig& cfg_P, Action_data* data_P )
+ : Action( cfg_P, data_P )
+ {
+ _input = cfg_P.readEntry( "Input" );
+ if( cfg_P.readBoolEntry( "IsDestinationWindow" ))
+ {
+ QString save_cfg_group = cfg_P.group();
+ cfg_P.setGroup( save_cfg_group + "DestinationWindow" );
+ _dest_window = new Windowdef_list( cfg_P );
+ _active_window = false; // ignored with _dest_window set anyway
+ cfg_P.setGroup( save_cfg_group );
+ }
+ else
+ {
+ _dest_window = NULL;
+ _active_window = cfg_P.readBoolEntry( "ActiveWindow" );
+ }
+ }
+
+Keyboard_input_action::~Keyboard_input_action()
+ {
+ delete _dest_window;
+ }
+
+void Keyboard_input_action::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ cfg_P.writeEntry( "Type", "KEYBOARD_INPUT" ); // overwrites value set in base::cfg_write()
+ cfg_P.writeEntry( "Input", input());
+ if( dest_window() != NULL )
+ {
+ cfg_P.writeEntry( "IsDestinationWindow", true );
+ QString save_cfg_group = cfg_P.group();
+ cfg_P.setGroup( save_cfg_group + "DestinationWindow" );
+ dest_window()->cfg_write( cfg_P );
+ cfg_P.setGroup( save_cfg_group );
+ }
+ else
+ cfg_P.writeEntry( "IsDestinationWindow", false );
+ cfg_P.writeEntry( "ActiveWindow", _active_window );
+ }
+
+void Keyboard_input_action::execute()
+ {
+ if( input().isEmpty())
+ return;
+ Window w = InputFocus;
+ if( dest_window() != NULL )
+ {
+ w = windows_handler->find_window( dest_window());
+ if( w == None )
+ w = InputFocus;
+ }
+ else
+ {
+ if( !_active_window )
+ w = windows_handler->action_window();
+ if( w == None )
+ w = InputFocus;
+ }
+ int last_index = -1, start = 0;
+ while(( last_index = input().find( ':', last_index + 1 )) != -1 ) // find next ';'
+ {
+ QString key = input().mid( start, last_index - start ).stripWhiteSpace();
+ if( key == "Enter" && KKey( key ).keyCodeQt() == 0 )
+ key = "Return"; // CHECKE hack
+ keyboard_handler->send_macro_key( KKey( key ), w );
+ start = last_index + 1;
+ }
+ // and the last one
+ QString key = input().mid( start, input().length()).stripWhiteSpace();
+ if( key == "Enter" && KKey( key ).keyCodeQt() == 0 )
+ key = "Return";
+ keyboard_handler->send_macro_key( KKey( key ), w ); // the rest
+ XFlush( qt_xdisplay());
+ }
+
+QString Keyboard_input_action::description() const
+ {
+ QString tmp = input();
+ tmp.replace( '\n', ' ' );
+ tmp.truncate( 30 );
+ return i18n( "Keyboard input : " ) + tmp;
+ }
+
+Action* Keyboard_input_action::copy( Action_data* data_P ) const
+ {
+ return new Keyboard_input_action( data_P, input(),
+ dest_window() ? dest_window()->copy() : NULL, _active_window );
+ }
+
+// Activate_window_action
+
+Activate_window_action::Activate_window_action( KConfig& cfg_P, Action_data* data_P )
+ : Action( cfg_P, data_P )
+ {
+ QString save_cfg_group = cfg_P.group();
+ cfg_P.setGroup( save_cfg_group + "Window" );
+ _window = new Windowdef_list( cfg_P );
+ cfg_P.setGroup( save_cfg_group );
+ }
+
+Activate_window_action::~Activate_window_action()
+ {
+ delete _window;
+ }
+
+void Activate_window_action::cfg_write( KConfig& cfg_P ) const
+ {
+ base::cfg_write( cfg_P );
+ cfg_P.writeEntry( "Type", "ACTIVATE_WINDOW" ); // overwrites value set in base::cfg_write()
+ QString save_cfg_group = cfg_P.group();
+ cfg_P.setGroup( save_cfg_group + "Window" );
+ window()->cfg_write( cfg_P );
+ cfg_P.setGroup( save_cfg_group );
+ }
+
+void Activate_window_action::execute()
+ {
+ if( window()->match( windows_handler->active_window()))
+ return; // is already active
+ WId win_id = windows_handler->find_window( window());
+ if( win_id != None )
+ windows_handler->activate_window( win_id );
+ }
+
+QString Activate_window_action::description() const
+ {
+ return i18n( "Activate window : " ) + window()->comment();
+ }
+
+Action* Activate_window_action::copy( Action_data* data_P ) const
+ {
+ return new Activate_window_action( data_P, window()->copy());
+ }
+
+} // namespace KHotKeys