summaryrefslogtreecommitdiff
path: root/noncore/applets/keyhelper/keyhelperapplet/anylnk
Side-by-side diff
Diffstat (limited to 'noncore/applets/keyhelper/keyhelperapplet/anylnk') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/AnyLnk.cpp94
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/AnyLnk.h45
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkManager.cpp5
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkManager.h56
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkWrapper.cpp43
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkWrapper.h44
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/DocLnkWrapper.h47
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/ExecLnk.h38
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/LnkWrapper.cpp32
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/LnkWrapper.h33
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/MenuLnk.h41
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/ProcessInvoker.cpp424
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/ProcessInvoker.h114
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/QCopLnk.cpp63
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/QCopLnk.h34
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/TextLnk.cpp34
-rw-r--r--noncore/applets/keyhelper/keyhelperapplet/anylnk/TextLnk.h38
17 files changed, 1185 insertions, 0 deletions
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/AnyLnk.cpp b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AnyLnk.cpp
new file mode 100644
index 0000000..3c2298e
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AnyLnk.cpp
@@ -0,0 +1,94 @@
+#include "AnyLnk.h"
+#include "KHUtil.h"
+
+void AnyLnk::loadPixmap()
+{
+ if(m_params.count() >= 3){
+ QString& str = m_params[2];
+ QImage image = Resource::loadImage(str);
+ if(image.isNull() == false){
+ const QSize& size = AppLnkManager::getIconSize();
+ m_pixmap.convertFromImage(
+ image.smoothScale(size.width(), size.height()) );
+ }
+ }
+}
+
+void AnyLnk::parseText()
+{
+ if(m_params.count() >= 2){
+ QString& str = m_params[1];
+ if(str != QString::null && str.length() > 0){
+ replaceKeyword(str);
+ replaceDate(str);
+ }
+ }
+}
+
+void AnyLnk::replaceText(QString& str, const QString& s1, const QString& s2)
+{
+ int index = 0;
+ int idx;
+ int len = s1.length();
+ idx = str.find(s1, index);
+ for(;;){
+ idx = str.find(s1, index);
+ if(idx < 0) break;
+ str.replace(idx, len, s2);
+ index = idx;
+ }
+}
+
+void AnyLnk::replaceDate(QString& str)
+{
+ time_t t;
+ struct tm lct;
+ char buf[4096];
+ int nLen;
+ QString group;
+
+ t = ::time(NULL);
+ ::localtime_r(&t, &lct);
+
+ ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
+ group = cfg.getGroup();
+ cfg.setGroup("Global");
+ QString charset = cfg.readEntry("SystemCharSet", "eucJP");
+ if(charset.length() == 0){
+ charset = "eucJP";
+ }
+ cfg.setGroup(group);
+
+ QTextCodec* codec = QTextCodec::codecForName(charset);
+ if(codec == NULL){
+ codec = QTextCodec::codecForLocale();
+ }
+ QTextDecoder* decoder = codec->makeDecoder();
+ QTextEncoder* encoder = codec->makeEncoder();
+ nLen = str.length();
+ QCString localeString = encoder->fromUnicode(str, nLen);
+
+ memset(buf, '\0', sizeof(buf));
+ int n = ::strftime(buf, sizeof(buf), localeString, &lct);
+ if(n > 0){
+ str = decoder->toUnicode(buf, n);
+ }
+ delete decoder;
+ delete encoder;
+}
+
+void AnyLnk::replaceKeyword(QString& str)
+{
+ QString txt;
+ /* clipboard text */
+ QClipboard* cb = QApplication::clipboard();
+ if(cb == NULL){
+ txt == "";
+ } else {
+ txt = cb->text();
+ }
+ replaceText(str, "%clipboard%", txt);
+ /* current app */
+ txt = KHUtil::currentApp();
+ replaceText(str, "%currentapp%", txt);
+}
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/AnyLnk.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AnyLnk.h
new file mode 100644
index 0000000..9853942
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AnyLnk.h
@@ -0,0 +1,45 @@
+#ifndef _ANYLNK_H_
+#define _ANYLNK_H_
+
+#include <time.h>
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qclipboard.h>
+#include <qtextcodec.h>
+
+#include <qpe/qpeapplication.h>
+#include <qpe/resource.h>
+
+#include "AppLnkManager.h"
+#include "ConfigEx.h"
+
+class AnyLnk
+{
+public:
+ AnyLnk(){}
+ AnyLnk(const QStringList& params){
+ m_params = params;
+ loadPixmap();
+ }
+ virtual ~AnyLnk(){
+ }
+ virtual bool isValid() = 0;
+ virtual void execute() = 0;
+ virtual QString name() = 0;
+ virtual const QPixmap& pixmap() = 0;
+
+protected:
+ QStringList m_params;
+ QPixmap m_pixmap;
+
+ virtual void loadPixmap();
+ virtual void parseText();
+ virtual void replaceText(QString& str, const QString& s1, const QString& s2);
+ virtual void replaceDate(QString& str);
+ virtual void replaceKeyword(QString& str);
+};
+
+#endif /* _ANYLNK_H_ */
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkManager.cpp b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkManager.cpp
new file mode 100644
index 0000000..5e244a4
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkManager.cpp
@@ -0,0 +1,5 @@
+#include "AppLnkManager.h"
+
+AppLnkSet* AppLnkManager::m_pLnkSet = NULL;
+QSize AppLnkManager::m_oIconSize;
+bool AppLnkManager::m_notfound = true;
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkManager.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkManager.h
new file mode 100644
index 0000000..8446578
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkManager.h
@@ -0,0 +1,56 @@
+#ifndef _APPLNK_MANAGER_H_
+#define _APPLNK_MANAGER_H_
+
+#include <qsize.h>
+
+#include <qpe/applnk.h>
+#include <qpe/mimetype.h>
+
+class AppLnkManager
+{
+public:
+ AppLnkManager(){
+ }
+ ~AppLnkManager(){
+ if(m_pLnkSet) delete m_pLnkSet;
+ }
+ static void init(bool force=false){
+ if(m_notfound || force){
+ if(m_pLnkSet){
+ delete m_pLnkSet;
+ }
+ qDebug("AppLnkManager::init()");
+ m_pLnkSet = new AppLnkSet(MimeType::appsFolderName());
+ m_notfound = false;
+ }
+ }
+ static AppLnkSet* getInstance(){
+ if(m_pLnkSet == NULL){
+ init(true);
+ }
+ return(m_pLnkSet);
+ }
+ static const QSize& getIconSize(){
+ if(m_oIconSize.isValid()){
+ return(m_oIconSize);
+ }
+ const QList<AppLnk>& lnkList = getInstance()->children();
+ QListIterator<AppLnk> it(lnkList);
+ for(; it.current(); ++it){
+ if((*it)->pixmap().isNull() == false){
+ m_oIconSize = (*it)->pixmap().size();
+ break;
+ }
+ }
+ return(m_oIconSize);
+ }
+ static void notfound(){
+ m_notfound = true;
+ }
+private:
+ static bool m_notfound;
+ static AppLnkSet* m_pLnkSet;
+ static QSize m_oIconSize;
+};
+
+#endif /* _APPLNK_MANAGER_H_ */
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkWrapper.cpp b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkWrapper.cpp
new file mode 100644
index 0000000..1c3dbfe
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkWrapper.cpp
@@ -0,0 +1,43 @@
+#ifndef _APPLNK_WRAPPER_H_
+#define _APPLNK_WRAPPER_H_
+
+#include <qpe/qpeapplication.h>
+#include <qpe/applnk.h>
+#include "AnyLnk.h"
+
+class AppLnkWrapper : public AnyLnk
+{
+public:
+ AppLnkWrapper(){}
+ AppLnkWrapper(const QStringList& params)
+ : AnyLnk(params)
+ {
+ m_pLnk = new AppLnk(QPEApplication::qpeDir()
+ + "apps/" + m_params[0] + ".desktop");
+ }
+ virtual ~AppLnkWrapper(){
+ delete m_pLnk;
+ }
+
+ virtual bool isValid() {
+ return(m_pLnk->isValid());
+ }
+ virtual void execute(){
+ parseText();
+ m_pLnk->execute(m_params[1]);
+ }
+ virtual QString name() {
+ return(m_pLnk->name());
+ }
+ virtual const QPixmap& pixmap(){
+ if(m_pixmap.isNull()){
+ return(m_pLnk->pixmap());
+ } else {
+ return(m_pixmap);
+ }
+ }
+protected:
+ AppLnk* m_pLnk;
+};
+
+#endif /* _APPLNK_WRAPPER_H_ */ \ No newline at end of file
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkWrapper.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkWrapper.h
new file mode 100644
index 0000000..6907dbe
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/AppLnkWrapper.h
@@ -0,0 +1,44 @@
+#ifndef _APPLNK_WRAPPER_H_
+#define _APPLNK_WRAPPER_H_
+
+#include <qpe/qpeapplication.h>
+#include <qpe/applnk.h>
+#include "AnyLnk.h"
+
+class AppLnkWrapper : public AnyLnk
+{
+public:
+ AppLnkWrapper(){}
+ AppLnkWrapper(const QStringList& params)
+ : AnyLnk(params)
+ {
+ m_pLnk = new AppLnk(QPEApplication::qpeDir()
+ + "apps/" + m_params[0] + ".desktop");
+ }
+ virtual ~AppLnkWrapper(){
+ delete m_pLnk;
+ }
+
+ virtual bool isValid() {
+ return(m_pLnk->isValid());
+ }
+ virtual void execute(){
+ parseText();
+ m_pLnk->execute(m_params[1]);
+ }
+ virtual QString name() {
+ return(m_pLnk->name());
+ }
+ virtual const QPixmap& pixmap(){
+ if(m_pixmap.isNull()){
+ return(m_pLnk->pixmap());
+ } else {
+ return(m_pixmap);
+ }
+ }
+protected:
+ AppLnk* m_pLnk;
+};
+
+#endif /* _APPLNK_WRAPPER_H_ */
+
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/DocLnkWrapper.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/DocLnkWrapper.h
new file mode 100644
index 0000000..d6f2be5
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/DocLnkWrapper.h
@@ -0,0 +1,47 @@
+#ifndef _DOCLNK_WRAPPER_H_
+#define _DOCLNK_WRAPPER_H_
+
+#include <qpe/applnk.h>
+#include "AnyLnk.h"
+
+class DocLnkWrapper : public AnyLnk
+{
+public:
+ DocLnkWrapper(){}
+ DocLnkWrapper(const QStringList& params)
+ : AnyLnk(params)
+ {
+ m_pLnk = new DocLnk(m_params[0], false);
+ }
+ virtual ~DocLnkWrapper(){
+ delete m_pLnk;
+ }
+
+ virtual bool isValid() {
+ if(m_pLnk->exec().length() > 0){
+ return(true);
+ } else {
+ return(false);
+ }
+ }
+ virtual void execute(){
+ parseText();
+ m_pLnk->execute(m_params[1]);
+ }
+ virtual QString name() {
+ return(m_pLnk->name());
+ }
+ virtual const QPixmap& pixmap(){
+ if(m_pixmap.isNull()){
+ return(m_pLnk->pixmap());
+ } else {
+ return(m_pixmap);
+ }
+ }
+protected:
+ DocLnk* m_pLnk;
+};
+
+#endif /* _DOCLNK_WRAPPER_H_ */
+
+
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/ExecLnk.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/ExecLnk.h
new file mode 100644
index 0000000..7e595df
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/ExecLnk.h
@@ -0,0 +1,38 @@
+#ifndef _EXECLNK_H_
+#define _EXECLNK_H_
+
+#include <qpe/qpeapplication.h>
+
+#include "AnyLnk.h"
+#include "ProcessInvoker.h"
+
+class ExecLnk : public AnyLnk
+{
+public:
+ ExecLnk(){}
+ ExecLnk(const QStringList& params)
+ : AnyLnk(params){}
+ virtual ~ExecLnk() {
+ }
+
+ virtual bool isValid() {
+ return(true);
+ }
+ virtual void execute() {
+ parseText();
+ ProcessInvoker& pi = ProcessInvoker::getInstance();
+ pi.setArguments(m_params[1]);
+ pi.setNotify();
+ pi.run();
+ }
+ virtual QString name() {
+ return("exec");
+ }
+ virtual const QPixmap& pixmap() {
+ return(m_pixmap);
+ }
+protected:
+};
+
+#endif /* _EXECLNK_H_ */
+
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/LnkWrapper.cpp b/noncore/applets/keyhelper/keyhelperapplet/anylnk/LnkWrapper.cpp
new file mode 100644
index 0000000..39806e5
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/LnkWrapper.cpp
@@ -0,0 +1,32 @@
+#include "LnkWrapper.h"
+
+LnkWrapper::LnkWrapper(const QStringList& params)
+{
+ if(params[0][0] == '/'){
+ qDebug("create DocLnk instance");
+ m_pLnk = new DocLnkWrapper(params);
+ } else if(params[0] == "@exec"){
+ qDebug("create ExecLnk instance");
+ m_pLnk = new ExecLnk(params);
+ } else if(params[0] == "@qcop"){
+ qDebug("create QCopLnk instance");
+ m_pLnk = new QCopLnk(params);
+ } else if(params[0] == "@text"){
+ qDebug("create TextLnk instance");
+ m_pLnk = new TextLnk(params);
+ } else if(params[0] == "@menu"){
+ qDebug("create MenuLnk instance");
+ m_pLnk = new MenuLnk(params);
+ } else {
+ qDebug("create AppLnk instance");
+ m_pLnk = new AppLnkWrapper(params);
+ }
+}
+
+LnkWrapper::~LnkWrapper()
+{
+ if(m_pLnk){
+ delete m_pLnk;
+ }
+}
+
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/LnkWrapper.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/LnkWrapper.h
new file mode 100644
index 0000000..6b9536b
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/LnkWrapper.h
@@ -0,0 +1,33 @@
+#ifndef _LNK_WRAPPER_H_
+#define _LNK_WRAPPER_H_
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include <qpe/applnk.h>
+
+#include "AppLnkWrapper.h"
+#include "DocLnkWrapper.h"
+#include "ExecLnk.h"
+#include "QCopLnk.h"
+#include "TextLnk.h"
+#include "MenuLnk.h"
+
+class LnkWrapper
+{
+public:
+ LnkWrapper(const QStringList& params);
+ virtual ~LnkWrapper();
+
+ bool isValid(){
+ return(m_pLnk && m_pLnk->isValid());
+ }
+ AnyLnk& instance(){
+ return(*m_pLnk);
+ }
+private:
+ AnyLnk* m_pLnk;
+};
+
+#endif /* _LNK_WRAPPER_H_ */
+
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/MenuLnk.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/MenuLnk.h
new file mode 100644
index 0000000..19f75d6
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/MenuLnk.h
@@ -0,0 +1,41 @@
+#ifndef _MENULNK_H_
+#define _MENULNK_H_
+
+#include <qpe/qpeapplication.h>
+
+#include "AnyLnk.h"
+#include "ConfigEx.h"
+
+class MenuLnk : public AnyLnk
+{
+public:
+ MenuLnk(){}
+ MenuLnk(const QStringList& params)
+ : AnyLnk(params){}
+ virtual ~MenuLnk() {
+ }
+
+ virtual bool isValid() {
+ ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
+ QString group = cfg.getGroup();
+ cfg.setGroup(name());
+ bool valid = (cfg.getKeys().isEmpty() == false);
+ cfg.setGroup(group);
+ return(valid);
+ }
+ virtual void execute() {
+ }
+ virtual QString name() {
+ QString group;
+ group = m_params[1];
+ group[0] = group[0].upper();
+ return(group);
+ }
+ virtual const QPixmap& pixmap() {
+ return(m_pixmap);
+ }
+protected:
+};
+
+#endif /* _MENULNK_H_ */
+
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/ProcessInvoker.cpp b/noncore/applets/keyhelper/keyhelperapplet/anylnk/ProcessInvoker.cpp
new file mode 100644
index 0000000..09605bd
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/ProcessInvoker.cpp
@@ -0,0 +1,424 @@
+#include "ProcessInvoker.h"
+
+static ProcessInvoker* g_this;
+/* ------------------------------------------------------------------------ */
+/* static functions */
+/* ------------------------------------------------------------------------ */
+
+static Sigfunc* setSignalHandler(int signo, Sigfunc* handler)
+{
+ struct sigaction act,oact;
+
+ act.sa_handler = handler;
+ ::sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+#ifdef SA_RESTART
+ act.sa_flags |= SA_RESTART;
+#endif
+ if(::sigaction(signo, &act, &oact) < 0){
+ return(NULL);
+ }
+ return(oact.sa_handler);
+}
+
+static void childHandler(int /*signo*/)
+{
+ pid_t pid;
+ int status;
+ while((pid = ::waitpid(-1, &status, WNOHANG)) > 0){
+ if(pid == g_this->m_child){
+ g_this->notifyFinish(status);
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+/* ProcessInvoker Class : parent process */
+/* ------------------------------------------------------------------------ */
+ProcessInvoker::ProcessInvoker()
+{
+ g_this = this;
+ m_isRunning = false;
+ m_child = 0;
+ m_defChildHandler = SIG_DFL;
+ m_pTimer = new QTimer(this);
+ m_stdfd[0] = m_stdfd[1] = -1;
+ m_errfd[0] = m_errfd[1] = -1;
+ connect(m_pTimer, SIGNAL(timeout()),
+ this, SLOT(readOutputs()));
+}
+
+ProcessInvoker::~ProcessInvoker()
+{
+ qDebug("ProcessInvoker::~ProcessInvoker()");
+}
+
+bool ProcessInvoker::openPipe()
+{
+ if(m_stdfd[0] >= 0) closePipe(m_stdfd, 0);
+ if(m_stdfd[1] >= 0) closePipe(m_stdfd, 1);
+ if(::pipe(m_stdfd) < 0){
+ return(false);
+ }
+ if(m_errfd[0] >= 0) closePipe(m_errfd, 0);
+ if(m_errfd[1] >= 0) closePipe(m_errfd, 1);
+ if(::pipe(m_errfd) < 0){
+ closePipe(m_stdfd);
+ return(false);
+ }
+ m_maxfdp1 = m_stdfd[0];
+ if(m_errfd[0] > m_maxfdp1){
+ m_maxfdp1 = m_errfd[0];
+ }
+ m_maxfdp1++;
+ return(true);
+}
+
+void ProcessInvoker::closePipe(int fd[], int n)
+{
+ if(fd == NULL){
+ closePipe(m_stdfd, n);
+ closePipe(m_errfd, n);
+ } else {
+ if(n != 1 && fd[0] >= 0){
+ ::close(fd[0]);
+ fd[0] = -1;
+ }
+ if(n != 0 && fd[1] >= 0){
+ ::close(fd[1]);
+ fd[1] = -1;
+ }
+ }
+}
+
+void ProcessInvoker::setRunning(int pid)
+{
+ m_child = pid;
+ m_isRunning = true;
+}
+
+bool ProcessInvoker::run(const QString& args)
+{
+ //setArguments(KHUtil::parseArgs(args));
+ setArguments(StringParser::split(' ', args));
+ return(run());
+}
+
+bool ProcessInvoker::run()
+{
+ if(m_isRunning){
+ return(false);
+ }
+ m_isRunning = true;
+ if(m_arguments.isEmpty()){
+ m_isRunning = false;
+ return(false);
+ }
+ if(m_arguments[0][0] != '/'){
+ m_isRunning = false;
+ return(false);
+ }
+
+ for(QStringList::Iterator it=m_arguments.begin();
+ it!=m_arguments.end(); ++it){
+ qDebug("arguments[%s]", (*it).ascii());
+ }
+
+ /* open pipe */
+ if(openPipe() == false){
+ m_isRunning = false;
+ return(false);
+ }
+
+ /* signal handler reset */
+ m_defChildHandler = setSignalHandler(SIGCHLD, SIG_DFL);
+
+ m_child = ::fork();
+ if(m_child < 0){
+ /* fork error */
+ closePipe();
+ setSignalHandler(SIGCHLD, m_defChildHandler);
+ m_isRunning = false;
+ return(false);
+ } else if(m_child == 0){
+ /* child process */
+ qDebug("child process[%d]", ::getpid());
+ m_child = ::getpid();
+ //setSignalHandler(SIGCHLD, SIG_DFL);
+ workerProc();
+ /* no return */
+ }
+ /* close pipe(write) */
+ closePipe(NULL, 1);
+#if 0
+ m_pTimer = new QTimer(this);
+ connect(m_pTimer, SIGNAL(timeout()),
+ this, SLOT(readOutputs()));
+#endif
+ m_pTimer->start(500);
+ {
+ emit start(m_child, m_arguments);
+ QCopEnvelope e(SC_CHANNEL, "start(int,QStringList)");
+ e << m_child << m_arguments;
+ if(m_isNotify){
+ int idx = m_arguments[0].findRev('/');
+ notifyStatus(m_arguments[0].mid(idx+1), m_child);
+ }
+ }
+ int status;
+ if(::waitpid(-1, &status, WNOHANG) > 0){
+ qDebug("finish");
+ notifyFinish(status);
+ } else {
+ /* signal handler set */
+ setSignalHandler(SIGCHLD, childHandler);
+ }
+ return(true);
+}
+
+void ProcessInvoker::terminate()
+{
+ if(m_isRunning && m_child > 0){
+ terminate(m_child);
+ }
+}
+
+void ProcessInvoker::terminate(pid_t pid)
+{
+ ::kill(pid, SIGTERM);
+}
+
+void ProcessInvoker::kill()
+{
+ if(m_isRunning && m_child > 0){
+ kill(m_child);
+ }
+}
+
+void ProcessInvoker::kill(pid_t pid)
+{
+ ::kill(pid, SIGKILL);
+}
+
+#if 0
+const QStringList ProcessInvoker::parseArgs(const QString& arguments)
+{
+ QString str;
+ QStringList args;
+ char quote = 0;
+ char c;
+ for(unsigned int i=0; i<arguments.length(); i++){
+ c = arguments[i];
+ switch(c){
+ case '\"':
+ if(quote == 0){
+ quote = c;
+ } else if(quote == '\"'){
+ if(str.length() > 0){
+ args.append(str);
+ }
+ str = "";
+ quote = 0;
+ } else {
+ str += c;
+ }
+ break;
+ case '\'':
+ if(quote == 0){
+ quote = c;
+ } else if(quote == '\''){
+ if(str.length() > 0){
+ args.append(str);
+ }
+ str = "";
+ quote = 0;
+ } else {
+ str += c;
+ }
+ break;
+ case ' ':
+ if(quote == 0){
+ if(str.length() > 0){
+ args.append(str);
+ str = "";
+ }
+ } else {
+ str += c;
+ }
+ break;
+ default:
+ str += c;
+ break;
+ }
+ }
+ if(str.length() > 0){
+ args.append(str);
+ }
+ return(args);
+}
+#endif
+
+void ProcessInvoker::readOutputs()
+{
+ struct timeval tmval;
+ tmval.tv_sec = 0;
+ tmval.tv_usec = 0;
+ fd_set rset;
+
+ QByteArray stdBuf, errBuf, resBuf;
+ QDataStream stdStream(stdBuf, IO_WriteOnly);
+ QDataStream errStream(errBuf, IO_WriteOnly);
+
+ int iRet;
+ bool running;
+ char buf[PIPE_BUF+1];
+ while(true){
+ running = false;
+ FD_ZERO(&rset);
+ if(m_stdfd[0] >= 0){
+ FD_SET(m_stdfd[0], &rset);
+ running = true;
+ }
+ if(m_errfd[0] >= 0){
+ FD_SET(m_errfd[0], &rset);
+ running = true;
+ }
+ if(running == false){
+ m_pTimer->stop();
+ //delete m_pTimer;
+ break;
+ }
+
+ if((iRet = ::select(m_maxfdp1, &rset, NULL, NULL, &tmval)) <= 0){
+ qDebug("select[%d]", iRet);
+ break;
+ }
+
+ if(m_stdfd[0] >= 0 && FD_ISSET(m_stdfd[0], &rset)){
+ int n = ::read(m_stdfd[0], buf, PIPE_BUF);
+ if(n > 0){
+ stdStream.writeRawBytes(buf, n);
+ } else {
+ qDebug("stdout close");
+ closePipe(m_stdfd, 0);
+ }
+ }
+ if(m_errfd[0] >= 0 && FD_ISSET(m_errfd[0], &rset)){
+ int n = ::read(m_errfd[0], buf, PIPE_BUF);
+ if(n > 0){
+ errStream.writeRawBytes(buf, n);
+ } else {
+ qDebug("stderr close");
+ closePipe(m_errfd, 0);
+ }
+ }
+ }
+
+ if(stdBuf.size() > 0){
+ QCopEnvelope e(SC_CHANNEL, "stdout(int,QByteArray)");
+ e << m_child << stdBuf;
+ }
+ if(errBuf.size() > 0){
+ QCopEnvelope e(SC_CHANNEL, "stderr(int,QByteArray)");
+ e << m_child << errBuf;
+ }
+ if(running == false){
+ QCopEnvelope e(SC_CHANNEL, "close(int)");
+ e << m_child;
+ }
+}
+
+#if 0
+void ProcessInvoker::waitFinish()
+{
+ int status;
+ if(::waitpid(m_child, &status, 0) > 0){
+ notifyFinish(status);
+ } else {
+ notifyFinish(0, false);
+ }
+}
+#endif
+
+void ProcessInvoker::notifyFinish(int status, bool success)
+{
+ bool stopped = false;
+ QString result;
+ int code;
+ if(success){
+ if(WIFEXITED(status)){
+ code = WEXITSTATUS(status);
+ if(code == 127){
+ result = "error";
+ } else {
+ result = "exit";
+ }
+ } else if(WIFSIGNALED(status)){
+ result = "terminated";
+ code = WTERMSIG(status);
+ } else if(WIFSTOPPED(status)){
+ result = "stopped";
+ code = WSTOPSIG(status);
+ stopped = true;
+ } else {
+ /* ¤³¤ì¤Ï̵¤¤¤Ï¤º? */
+ result = "error";
+ code = -2;
+ qWarning("ProcessInvoker: unknown status");
+ }
+ } else {
+ result = "error";
+ code = -1;
+ qWarning("ProcessInvoker: wait error");
+ }
+ emit finish(result, code);
+ QCopEnvelope e(SC_CHANNEL, "finish(int,QString,int)");
+ e << m_child << result << code;
+ if(m_isNotify){
+ notifyStatus(result, code);
+ setNotify(false);
+ }
+ if(stopped == false){
+ setSignalHandler(SIGCHLD, m_defChildHandler);
+ m_isRunning = false;
+ }
+}
+
+void ProcessInvoker::notifyStatus(const QString& result, int code)
+{
+ QString message = QString::number(code);
+ message.append(":");
+ message.append(result);
+ Global::statusMessage(message);
+}
+
+/* ------------------------------------------------------------------------ */
+/* ProcessInvoker Class : child process */
+/* ------------------------------------------------------------------------ */
+void ProcessInvoker::workerProc()
+{
+ closePipe(m_stdfd, 0);
+ closePipe(m_errfd, 0);
+ if(m_stdfd[1] != STDOUT_FILENO){
+ ::dup2(m_stdfd[1], STDOUT_FILENO);
+ closePipe(m_stdfd, 1);
+ }
+ if(m_errfd[1] != STDERR_FILENO){
+ ::dup2(m_errfd[1], STDERR_FILENO);
+ closePipe(m_errfd, 1);
+ }
+
+ QCString* arglist = new QCString[m_arguments.count()+1];
+ const char** argv = new const char*[m_arguments.count()+1];
+ unsigned int i;
+ for(i=0; i<m_arguments.count(); i++){
+ //arglist[i] = m_arguments[i].local8Bit();
+ arglist[i] = m_arguments[i];
+ argv[i] = arglist[i];
+ }
+ argv[i] = 0;
+ ::execv(argv[0], (char*const*)argv);
+ delete[] arglist;
+ delete[] argv;
+ ::_exit(127);
+}
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/ProcessInvoker.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/ProcessInvoker.h
new file mode 100644
index 0000000..1f53cd6
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/ProcessInvoker.h
@@ -0,0 +1,114 @@
+#ifndef _PROCESS_INVOKER_H_
+#define _PROCESS_INVOKER_H_
+
+#include <qobject.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <qtimer.h>
+#include <qdatastream.h>
+#include <qcstring.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/global.h>
+//#include "KHUtil.h"
+#include "StringParser.h"
+
+typedef void Sigfunc(int);
+
+#define SC_CHANNEL "QPE/ShellCommander"
+
+/* Sigleton Object */
+class ProcessInvoker : public QObject
+{
+ Q_OBJECT
+public:
+ static ProcessInvoker& getInstance()
+ {
+ static ProcessInvoker instance;
+ return(instance);
+ }
+
+ bool run();
+ bool run(const QString& args);
+ void terminate();
+ void terminate(pid_t pid);
+ void kill();
+ void kill(pid_t pid);
+ void setCommand(const QString& command){
+ m_arguments.clear();
+ addArgument(command);
+ }
+ void setArguments(const QStringList& arglist){
+ m_arguments = arglist;
+ }
+ void setArguments(const QString& arguments){
+ //setArguments(KHUtil::parseArgs(arguments));
+ setArguments(StringParser::split(' ', arguments));
+ }
+ void addArgument(const QString& argument){
+ m_arguments.append(argument);
+ }
+ void addArguments(const QString& arguments){
+ QStringList arglist;
+ //arglist = KHUtil::parseArgs(arguments);
+ arglist = StringParser::split(' ', arguments);
+ addArguments(arglist);
+ }
+ void addArguments(const QStringList& arglist){
+ for(QStringList::ConstIterator it=arglist.begin();
+ it!=arglist.end(); ++it){
+ addArgument(*it);
+ }
+ }
+ //const QStringList parseArgs(const QString& arguments);
+ void setRunning(int pid);
+ void setNotify(bool enable=true){
+ m_isNotify = enable;
+ }
+
+ bool isRunning(){
+ return(m_isRunning);
+ }
+ void notifyFinish(int status, bool success=true);
+
+ pid_t m_child;
+
+ friend class Dummy; /* for compile warning */
+signals:
+ void start(int, QStringList);
+ void finish(QString,int);
+private:
+ ProcessInvoker();
+ ProcessInvoker(const ProcessInvoker&);
+ ProcessInvoker& operator=(const ProcessInvoker&);
+ ~ProcessInvoker();
+
+ class Dummy{}; /* for compile warning */
+
+ QTimer* m_pTimer;
+ QStringList m_arguments;
+
+ bool m_isRunning;
+ bool m_isNotify;
+
+ Sigfunc* m_defChildHandler;
+
+ int m_stdfd[2];
+ int m_errfd[2];
+ int m_maxfdp1;
+
+ bool openPipe();
+ void closePipe(int fd[] = NULL, int n = 2);
+ void notifyStatus(const QString& result, int code);
+
+ void workerProc();
+private slots:
+ void readOutputs();
+};
+
+#endif /* _PROCESS_INVOKER_H_ */
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/QCopLnk.cpp b/noncore/applets/keyhelper/keyhelperapplet/anylnk/QCopLnk.cpp
new file mode 100644
index 0000000..991bf87
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/QCopLnk.cpp
@@ -0,0 +1,63 @@
+#include "QCopLnk.h"
+#include "StringParser.h"
+
+void QCopLnk::execute()
+{
+ parseText();
+ //QStringList argList = KHUtil::parseArgs(m_params[1]);
+ QStringList argList = StringParser::split(' ', m_params[1]);
+ if(argList.count() < 2){
+ return;
+ }
+ QStringList paramList =
+ QStringList::split(QRegExp("[(),]"), argList[1]);
+ if(argList.count() < paramList.count()+1){
+ return;
+ }
+ paramList.remove(paramList.begin());
+ if(paramList.count() == 0){
+ /* send qcop message */
+ QCopEnvelope env(argList[0].latin1(), argList[1].latin1());
+ } else {
+ QCopEnvelope* e = NULL;
+ QStringList::Iterator it=paramList.end();
+ for(unsigned int index = 2; index<argList.count(); index++){
+ if(it == paramList.end()){
+ if(argList.count() - index < paramList.count()){
+ break;
+ }
+ /* initialize */
+ it = paramList.begin();
+ e = new QCopEnvelope(
+ argList[0].latin1(), argList[1].latin1());
+ }
+ QString arg = argList[index];
+ if(*it == "QString"){
+ *e << arg;
+ } else if(*it == "int"){
+ *e << arg.toInt();
+ } else if(*it == "bool"){
+ QString s = arg.lower();
+ int on;
+ if(s == "true"){
+ on = TRUE;
+ } else if(s == "false"){
+ on = FALSE;
+ } else {
+ on = s.toInt();
+ }
+ *e << on;
+ }
+ ++it;
+ if(it == paramList.end()){
+ /* send qcop message */
+ delete e;
+ if(argList.count() - index >= paramList.count()){
+ e = new QCopEnvelope(
+ argList[0].latin1(), argList[1].latin1());
+ it = paramList.begin();
+ }
+ }
+ }
+ }
+}
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/QCopLnk.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/QCopLnk.h
new file mode 100644
index 0000000..f994149
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/QCopLnk.h
@@ -0,0 +1,34 @@
+#ifndef _QCOPLNK_H_
+#define _QCOPLNK_H_
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include "AnyLnk.h"
+#include "KHUtil.h"
+
+class QCopLnk : public AnyLnk
+{
+public:
+ QCopLnk(){}
+ QCopLnk(const QStringList& params)
+ : AnyLnk(params){}
+ virtual ~QCopLnk() {
+ }
+
+ virtual bool isValid() {
+ return(true);
+ }
+ virtual QString name() {
+ return("qcop");
+ }
+ virtual const QPixmap& pixmap() {
+ return(m_pixmap);
+ }
+
+ virtual void execute();
+protected:
+};
+
+#endif /* _QCOPLNK_H_ */
+
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/TextLnk.cpp b/noncore/applets/keyhelper/keyhelperapplet/anylnk/TextLnk.cpp
new file mode 100644
index 0000000..abb432c
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/TextLnk.cpp
@@ -0,0 +1,34 @@
+#include "TextLnk.h"
+
+void TextLnk::execute()
+{
+ QClipboard* cb = QApplication::clipboard();
+ parseText();
+ cb->setText(m_params[1]);
+ QWSServer::sendKeyEvent('V'-'@',Qt::Key_V, Qt::ControlButton,
+ true, false);
+ QWSServer::sendKeyEvent('V'-'@',Qt::Key_V, Qt::ControlButton,
+ false, false);
+}
+
+void TextLnk::parse(QString& str)
+{
+ replace(str, "\\\\", "\\");
+ replace(str, "\\n", "\n");
+ replace(str, "\\r", "\r");
+ replace(str, "\\t", "\t");
+}
+
+void TextLnk::replace(QString& str, const QString& s1, const QString& s2)
+{
+ int index = 0;
+ int idx;
+ int len = s1.length();
+ idx = str.find(s1, index);
+ for(;;){
+ idx = str.find(s1, index);
+ if(idx < 0) break;
+ str.replace(idx, len, s2);
+ index = idx;
+ }
+}
diff --git a/noncore/applets/keyhelper/keyhelperapplet/anylnk/TextLnk.h b/noncore/applets/keyhelper/keyhelperapplet/anylnk/TextLnk.h
new file mode 100644
index 0000000..3ae13c5
--- a/dev/null
+++ b/noncore/applets/keyhelper/keyhelperapplet/anylnk/TextLnk.h
@@ -0,0 +1,38 @@
+#ifndef _PASTELNK_H_
+#define _PASTELNK_H_
+
+#include <qwindowsystem_qws.h>
+
+#include <qpe/qpeapplication.h>
+#include <qclipboard.h>
+#include <qregexp.h>
+
+#include "AnyLnk.h"
+
+class TextLnk : public AnyLnk
+{
+public:
+ TextLnk(){}
+ TextLnk(const QStringList& params)
+ : AnyLnk(params){}
+ virtual ~TextLnk() {
+ }
+
+ virtual bool isValid() {
+ return(true);
+ }
+ virtual QString name() {
+ return("text");
+ }
+ virtual const QPixmap& pixmap() {
+ return(m_pixmap);
+ }
+
+ virtual void execute();
+protected:
+ virtual void parse(QString& str);
+ virtual void replace(QString& str, const QString& s1, const QString& s2);
+};
+
+#endif /* _PASTELNK_H_ */
+