You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
488 lines
14 KiB
488 lines
14 KiB
/****************************************************************************
|
|
|
|
KHotKeys
|
|
|
|
Copyright (C) 1999-2001 Lubos Lunak <l.lunak@kde.org>
|
|
|
|
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 <tdeconfig.h>
|
|
#include <kdebug.h>
|
|
#include <kurifilter.h>
|
|
#include <tdeglobal.h>
|
|
#include <kstandarddirs.h>
|
|
#include <tdeapplication.h>
|
|
#include <dcopclient.h>
|
|
#include <kdesktopfile.h>
|
|
#include <tdelocale.h>
|
|
#include <tdeaccel.h>
|
|
#include <kservice.h>
|
|
#include <kprocess.h>
|
|
#include <tdemessagebox.h>
|
|
|
|
#include "windows.h"
|
|
#include "action_data.h"
|
|
|
|
#include <X11/X.h>
|
|
|
|
namespace KHotKeys
|
|
{
|
|
|
|
// Action
|
|
|
|
Action* Action::create_cfg_read( TDEConfig& cfg_P, Action_data* data_P )
|
|
{
|
|
TQString 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 );
|
|
if( type == "WAITING" )
|
|
return new Waiting_action( cfg_P, data_P );
|
|
kdWarning( 1217 ) << "Unknown Action type read from cfg file: " << type << endl;
|
|
return NULL;
|
|
}
|
|
|
|
void Action::cfg_write( TDEConfig& cfg_P ) const
|
|
{
|
|
cfg_P.writeEntry( "Type", "ERROR" ); // derived classes should call with their type
|
|
}
|
|
|
|
// Action_list
|
|
|
|
Action_list::Action_list( TDEConfig& cfg_P, Action_data* data_P )
|
|
: TQPtrList< Action >()
|
|
{
|
|
setAutoDelete( true );
|
|
TQString 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 + TQString::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( TDEConfig& cfg_P ) const
|
|
{
|
|
TQString save_cfg_group = cfg_P.group();
|
|
int i = 0;
|
|
for( Iterator it( *this );
|
|
it;
|
|
++it, ++i )
|
|
{
|
|
cfg_P.setGroup( save_cfg_group + TQString::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( TDEConfig& cfg_P, Action_data* data_P )
|
|
: Action( cfg_P, data_P )
|
|
{
|
|
_command_url = cfg_P.readEntry( "CommandURL" );
|
|
}
|
|
|
|
void Command_url_action::cfg_write( TDEConfig& 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;
|
|
TQString 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 )
|
|
{
|
|
if (!KRun::run( *service, KURL::List()))
|
|
{
|
|
KMessageBox::sorry(0, "<qt>" + i18n("KHotKeys was unable to execute") + " '" + cmd + "'<p>" + i18n("Please verify existence of the service") + "</qt>", i18n("Unable to launch service!"));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
// fall though
|
|
}
|
|
case KURIFilterData::SHELL:
|
|
{
|
|
if (!kapp->authorize("shell_access"))
|
|
return;
|
|
if( !KRun::runCommand(
|
|
cmd + ( uri.hasArgsAndOptions() ? uri.argsAndOptions() : "" ),
|
|
cmd, uri.iconName())) {
|
|
KMessageBox::sorry(0, "<qt>" + i18n("KHotKeys was unable to execute") + " '" + cmd + "'<p>" + i18n("Please verify existence and permissions of the executable file") + "</qt>", i18n("Unable to launch program"));
|
|
}
|
|
break;
|
|
}
|
|
default: // error
|
|
KMessageBox::sorry(0, "<qt>" + i18n("KHotKeys was unable to execute") + " '" + cmd + "'<p>" + i18n("Please verify existence and permissions of the executable file") + "</qt>", i18n("Unable to launch program"));
|
|
return;
|
|
}
|
|
timeout.start( 1000, true ); // 1sec timeout
|
|
}
|
|
|
|
TQString 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( TDEConfig& 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
|
|
}
|
|
|
|
TQString Menuentry_action::description() const
|
|
{
|
|
(void) service();
|
|
return i18n( "Menuentry : " ) + (_service ? _service->name() : TQString::null);
|
|
}
|
|
|
|
Action* Menuentry_action::copy( Action_data* data_P ) const
|
|
{
|
|
return new Menuentry_action( data_P, command_url());
|
|
}
|
|
|
|
// Dcop_action
|
|
|
|
Dcop_action::Dcop_action( TDEConfig& 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( TDEConfig& 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;
|
|
TQStringList args_list;
|
|
TQString args_str = args;
|
|
while( !args_str.isEmpty())
|
|
{
|
|
unsigned int pos = 0;
|
|
while( args_str[ pos ] == ' ' )
|
|
++pos;
|
|
if( args_str[ pos ] == '\"' || args_str[ pos ] == '\'' )
|
|
{
|
|
TQString val = "";
|
|
TQChar 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;
|
|
TDEProcess proc;
|
|
proc << "dcop" << app << obj << call << args_list;
|
|
proc.start( TDEProcess::DontCare );
|
|
}
|
|
|
|
TQString 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( TDEConfig& cfg_P, Action_data* data_P )
|
|
: Action( cfg_P, data_P )
|
|
{
|
|
_input = cfg_P.readEntry( "Input" );
|
|
if( cfg_P.readBoolEntry( "IsDestinationWindow" ))
|
|
{
|
|
TQString 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( TDEConfig& 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 );
|
|
TQString 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 ';'
|
|
{
|
|
TQString 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
|
|
TQString 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( tqt_xdisplay());
|
|
}
|
|
|
|
TQString Keyboard_input_action::description() const
|
|
{
|
|
TQString 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( TDEConfig& cfg_P, Action_data* data_P )
|
|
: Action( cfg_P, data_P )
|
|
{
|
|
TQString 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( TDEConfig& cfg_P ) const
|
|
{
|
|
base::cfg_write( cfg_P );
|
|
cfg_P.writeEntry( "Type", "ACTIVATE_WINDOW" ); // overwrites value set in base::cfg_write()
|
|
TQString 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 );
|
|
}
|
|
|
|
TQString 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());
|
|
}
|
|
|
|
// Waiting_action
|
|
|
|
Waiting_action::Waiting_action( TDEConfig& cfg_P, Action_data* data_P )
|
|
: Action( cfg_P, data_P )
|
|
{
|
|
_waiting_time = cfg_P.readNumEntry("Time");
|
|
}
|
|
|
|
void Waiting_action::cfg_write( TDEConfig& cfg_P ) const
|
|
{
|
|
base::cfg_write( cfg_P );
|
|
cfg_P.writeEntry( "Type", "WAITING" ); // overwrites value set in base::cfg_write()
|
|
cfg_P.writeEntry( "Time", _waiting_time);
|
|
}
|
|
|
|
void Waiting_action::execute()
|
|
{
|
|
usleep(_waiting_time * 1000);
|
|
}
|
|
|
|
TQString Waiting_action::description() const
|
|
{
|
|
return i18n( "Waiting %1 ms" ).arg(_waiting_time);
|
|
}
|
|
|
|
Action* Waiting_action::copy( Action_data* data_P ) const
|
|
{
|
|
return new Waiting_action( data_P, _waiting_time);
|
|
}
|
|
|
|
} // namespace KHotKeys
|