diff options
Diffstat (limited to 'khotkeys/shared/actions.cpp')
-rw-r--r-- | khotkeys/shared/actions.cpp | 450 |
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 |