summaryrefslogtreecommitdiff
path: root/noncore/applets/keyhelper/keyhelperapplet/anylnk
Unidiff
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 @@
1#include "AnyLnk.h"
2#include "KHUtil.h"
3
4void AnyLnk::loadPixmap()
5{
6 if(m_params.count() >= 3){
7 QString& str = m_params[2];
8 QImage image = Resource::loadImage(str);
9 if(image.isNull() == false){
10 const QSize& size = AppLnkManager::getIconSize();
11 m_pixmap.convertFromImage(
12 image.smoothScale(size.width(), size.height()) );
13 }
14 }
15}
16
17void AnyLnk::parseText()
18{
19 if(m_params.count() >= 2){
20 QString& str = m_params[1];
21 if(str != QString::null && str.length() > 0){
22 replaceKeyword(str);
23 replaceDate(str);
24 }
25 }
26}
27
28void AnyLnk::replaceText(QString& str, const QString& s1, const QString& s2)
29{
30 int index = 0;
31 int idx;
32 int len = s1.length();
33 idx = str.find(s1, index);
34 for(;;){
35 idx = str.find(s1, index);
36 if(idx < 0) break;
37 str.replace(idx, len, s2);
38 index = idx;
39 }
40}
41
42void AnyLnk::replaceDate(QString& str)
43{
44 time_t t;
45 struct tm lct;
46 char buf[4096];
47 int nLen;
48 QString group;
49
50 t = ::time(NULL);
51 ::localtime_r(&t, &lct);
52
53 ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
54 group = cfg.getGroup();
55 cfg.setGroup("Global");
56 QString charset = cfg.readEntry("SystemCharSet", "eucJP");
57 if(charset.length() == 0){
58 charset = "eucJP";
59 }
60 cfg.setGroup(group);
61
62 QTextCodec* codec = QTextCodec::codecForName(charset);
63 if(codec == NULL){
64 codec = QTextCodec::codecForLocale();
65 }
66 QTextDecoder* decoder = codec->makeDecoder();
67 QTextEncoder* encoder = codec->makeEncoder();
68 nLen = str.length();
69 QCString localeString = encoder->fromUnicode(str, nLen);
70
71 memset(buf, '\0', sizeof(buf));
72 int n = ::strftime(buf, sizeof(buf), localeString, &lct);
73 if(n > 0){
74 str = decoder->toUnicode(buf, n);
75 }
76 delete decoder;
77 delete encoder;
78}
79
80void AnyLnk::replaceKeyword(QString& str)
81{
82 QString txt;
83 /* clipboard text */
84 QClipboard* cb = QApplication::clipboard();
85 if(cb == NULL){
86 txt == "";
87 } else {
88 txt = cb->text();
89 }
90 replaceText(str, "%clipboard%", txt);
91 /* current app */
92 txt = KHUtil::currentApp();
93 replaceText(str, "%currentapp%", txt);
94}
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 @@
1#ifndef _ANYLNK_H_
2#define _ANYLNK_H_
3
4#include <time.h>
5
6#include <qstring.h>
7#include <qstringlist.h>
8#include <qpixmap.h>
9#include <qimage.h>
10#include <qclipboard.h>
11#include <qtextcodec.h>
12
13#include <qpe/qpeapplication.h>
14#include <qpe/resource.h>
15
16#include "AppLnkManager.h"
17#include "ConfigEx.h"
18
19class AnyLnk
20{
21public:
22 AnyLnk(){}
23 AnyLnk(const QStringList& params){
24 m_params = params;
25 loadPixmap();
26 }
27 virtual ~AnyLnk(){
28 }
29 virtual bool isValid() = 0;
30 virtual void execute() = 0;
31 virtual QString name() = 0;
32 virtual const QPixmap& pixmap() = 0;
33
34protected:
35 QStringList m_params;
36 QPixmap m_pixmap;
37
38 virtual void loadPixmap();
39 virtual void parseText();
40 virtual void replaceText(QString& str, const QString& s1, const QString& s2);
41 virtual void replaceDate(QString& str);
42 virtual void replaceKeyword(QString& str);
43};
44
45#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 @@
1#include "AppLnkManager.h"
2
3AppLnkSet* AppLnkManager::m_pLnkSet = NULL;
4QSize AppLnkManager::m_oIconSize;
5bool 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 @@
1#ifndef _APPLNK_MANAGER_H_
2#define _APPLNK_MANAGER_H_
3
4#include <qsize.h>
5
6#include <qpe/applnk.h>
7#include <qpe/mimetype.h>
8
9class AppLnkManager
10{
11public:
12 AppLnkManager(){
13 }
14 ~AppLnkManager(){
15 if(m_pLnkSet) delete m_pLnkSet;
16 }
17 static void init(bool force=false){
18 if(m_notfound || force){
19 if(m_pLnkSet){
20 delete m_pLnkSet;
21 }
22 qDebug("AppLnkManager::init()");
23 m_pLnkSet = new AppLnkSet(MimeType::appsFolderName());
24 m_notfound = false;
25 }
26 }
27 static AppLnkSet* getInstance(){
28 if(m_pLnkSet == NULL){
29 init(true);
30 }
31 return(m_pLnkSet);
32 }
33 static const QSize& getIconSize(){
34 if(m_oIconSize.isValid()){
35 return(m_oIconSize);
36 }
37 const QList<AppLnk>& lnkList = getInstance()->children();
38 QListIterator<AppLnk> it(lnkList);
39 for(; it.current(); ++it){
40 if((*it)->pixmap().isNull() == false){
41 m_oIconSize = (*it)->pixmap().size();
42 break;
43 }
44 }
45 return(m_oIconSize);
46 }
47 static void notfound(){
48 m_notfound = true;
49 }
50private:
51 static bool m_notfound;
52 static AppLnkSet* m_pLnkSet;
53 static QSize m_oIconSize;
54};
55
56#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 @@
1#ifndef _APPLNK_WRAPPER_H_
2#define _APPLNK_WRAPPER_H_
3
4#include <qpe/qpeapplication.h>
5#include <qpe/applnk.h>
6#include "AnyLnk.h"
7
8class AppLnkWrapper : public AnyLnk
9{
10public:
11 AppLnkWrapper(){}
12 AppLnkWrapper(const QStringList& params)
13 : AnyLnk(params)
14 {
15 m_pLnk = new AppLnk(QPEApplication::qpeDir()
16 + "apps/" + m_params[0] + ".desktop");
17 }
18 virtual ~AppLnkWrapper(){
19 delete m_pLnk;
20 }
21
22 virtual bool isValid() {
23 return(m_pLnk->isValid());
24 }
25 virtual void execute(){
26 parseText();
27 m_pLnk->execute(m_params[1]);
28 }
29 virtual QString name() {
30 return(m_pLnk->name());
31 }
32 virtual const QPixmap& pixmap(){
33 if(m_pixmap.isNull()){
34 return(m_pLnk->pixmap());
35 } else {
36 return(m_pixmap);
37 }
38 }
39protected:
40 AppLnk* m_pLnk;
41};
42
43#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 @@
1#ifndef _APPLNK_WRAPPER_H_
2#define _APPLNK_WRAPPER_H_
3
4#include <qpe/qpeapplication.h>
5#include <qpe/applnk.h>
6#include "AnyLnk.h"
7
8class AppLnkWrapper : public AnyLnk
9{
10public:
11 AppLnkWrapper(){}
12 AppLnkWrapper(const QStringList& params)
13 : AnyLnk(params)
14 {
15 m_pLnk = new AppLnk(QPEApplication::qpeDir()
16 + "apps/" + m_params[0] + ".desktop");
17 }
18 virtual ~AppLnkWrapper(){
19 delete m_pLnk;
20 }
21
22 virtual bool isValid() {
23 return(m_pLnk->isValid());
24 }
25 virtual void execute(){
26 parseText();
27 m_pLnk->execute(m_params[1]);
28 }
29 virtual QString name() {
30 return(m_pLnk->name());
31 }
32 virtual const QPixmap& pixmap(){
33 if(m_pixmap.isNull()){
34 return(m_pLnk->pixmap());
35 } else {
36 return(m_pixmap);
37 }
38 }
39protected:
40 AppLnk* m_pLnk;
41};
42
43#endif /* _APPLNK_WRAPPER_H_ */
44
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 @@
1#ifndef _DOCLNK_WRAPPER_H_
2#define _DOCLNK_WRAPPER_H_
3
4#include <qpe/applnk.h>
5#include "AnyLnk.h"
6
7class DocLnkWrapper : public AnyLnk
8{
9public:
10 DocLnkWrapper(){}
11 DocLnkWrapper(const QStringList& params)
12 : AnyLnk(params)
13 {
14 m_pLnk = new DocLnk(m_params[0], false);
15 }
16 virtual ~DocLnkWrapper(){
17 delete m_pLnk;
18 }
19
20 virtual bool isValid() {
21 if(m_pLnk->exec().length() > 0){
22 return(true);
23 } else {
24 return(false);
25 }
26 }
27 virtual void execute(){
28 parseText();
29 m_pLnk->execute(m_params[1]);
30 }
31 virtual QString name() {
32 return(m_pLnk->name());
33 }
34 virtual const QPixmap& pixmap(){
35 if(m_pixmap.isNull()){
36 return(m_pLnk->pixmap());
37 } else {
38 return(m_pixmap);
39 }
40 }
41protected:
42 DocLnk* m_pLnk;
43};
44
45#endif /* _DOCLNK_WRAPPER_H_ */
46
47
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 @@
1#ifndef _EXECLNK_H_
2#define _EXECLNK_H_
3
4#include <qpe/qpeapplication.h>
5
6#include "AnyLnk.h"
7#include "ProcessInvoker.h"
8
9class ExecLnk : public AnyLnk
10{
11public:
12 ExecLnk(){}
13 ExecLnk(const QStringList& params)
14 : AnyLnk(params){}
15 virtual ~ExecLnk() {
16 }
17
18 virtual bool isValid() {
19 return(true);
20 }
21 virtual void execute() {
22 parseText();
23 ProcessInvoker& pi = ProcessInvoker::getInstance();
24 pi.setArguments(m_params[1]);
25 pi.setNotify();
26 pi.run();
27 }
28 virtual QString name() {
29 return("exec");
30 }
31 virtual const QPixmap& pixmap() {
32 return(m_pixmap);
33 }
34protected:
35};
36
37#endif /* _EXECLNK_H_ */
38
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 @@
1#include "LnkWrapper.h"
2
3LnkWrapper::LnkWrapper(const QStringList& params)
4{
5 if(params[0][0] == '/'){
6 qDebug("create DocLnk instance");
7 m_pLnk = new DocLnkWrapper(params);
8 } else if(params[0] == "@exec"){
9 qDebug("create ExecLnk instance");
10 m_pLnk = new ExecLnk(params);
11 } else if(params[0] == "@qcop"){
12 qDebug("create QCopLnk instance");
13 m_pLnk = new QCopLnk(params);
14 } else if(params[0] == "@text"){
15 qDebug("create TextLnk instance");
16 m_pLnk = new TextLnk(params);
17 } else if(params[0] == "@menu"){
18 qDebug("create MenuLnk instance");
19 m_pLnk = new MenuLnk(params);
20 } else {
21 qDebug("create AppLnk instance");
22 m_pLnk = new AppLnkWrapper(params);
23 }
24}
25
26LnkWrapper::~LnkWrapper()
27{
28 if(m_pLnk){
29 delete m_pLnk;
30 }
31}
32
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 @@
1#ifndef _LNK_WRAPPER_H_
2#define _LNK_WRAPPER_H_
3
4#include <qstring.h>
5#include <qstringlist.h>
6
7#include <qpe/applnk.h>
8
9#include "AppLnkWrapper.h"
10#include "DocLnkWrapper.h"
11#include "ExecLnk.h"
12#include "QCopLnk.h"
13#include "TextLnk.h"
14#include "MenuLnk.h"
15
16class LnkWrapper
17{
18public:
19 LnkWrapper(const QStringList& params);
20 virtual ~LnkWrapper();
21
22 bool isValid(){
23 return(m_pLnk && m_pLnk->isValid());
24 }
25 AnyLnk& instance(){
26 return(*m_pLnk);
27 }
28private:
29 AnyLnk* m_pLnk;
30};
31
32#endif /* _LNK_WRAPPER_H_ */
33
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 @@
1#ifndef _MENULNK_H_
2#define _MENULNK_H_
3
4#include <qpe/qpeapplication.h>
5
6#include "AnyLnk.h"
7#include "ConfigEx.h"
8
9class MenuLnk : public AnyLnk
10{
11public:
12 MenuLnk(){}
13 MenuLnk(const QStringList& params)
14 : AnyLnk(params){}
15 virtual ~MenuLnk() {
16 }
17
18 virtual bool isValid() {
19 ConfigEx& cfg = ConfigEx::getInstance("keyhelper");
20 QString group = cfg.getGroup();
21 cfg.setGroup(name());
22 bool valid = (cfg.getKeys().isEmpty() == false);
23 cfg.setGroup(group);
24 return(valid);
25 }
26 virtual void execute() {
27 }
28 virtual QString name() {
29 QString group;
30 group = m_params[1];
31 group[0] = group[0].upper();
32 return(group);
33 }
34 virtual const QPixmap& pixmap() {
35 return(m_pixmap);
36 }
37protected:
38};
39
40#endif /* _MENULNK_H_ */
41
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 @@
1#include "ProcessInvoker.h"
2
3static ProcessInvoker* g_this;
4/* ------------------------------------------------------------------------ */
5 /* static functions */
6/* ------------------------------------------------------------------------ */
7
8static Sigfunc* setSignalHandler(int signo, Sigfunc* handler)
9{
10 struct sigaction act,oact;
11
12 act.sa_handler = handler;
13 ::sigemptyset(&act.sa_mask);
14 act.sa_flags = 0;
15 #ifdefSA_RESTART
16 act.sa_flags |= SA_RESTART;
17#endif
18 if(::sigaction(signo, &act, &oact) < 0){
19 return(NULL);
20 }
21 return(oact.sa_handler);
22}
23
24static void childHandler(int /*signo*/)
25{
26 pid_t pid;
27 int status;
28 while((pid = ::waitpid(-1, &status, WNOHANG)) > 0){
29 if(pid == g_this->m_child){
30 g_this->notifyFinish(status);
31 }
32 }
33}
34
35/* ------------------------------------------------------------------------ */
36 /* ProcessInvoker Class : parent process */
37/* ------------------------------------------------------------------------ */
38ProcessInvoker::ProcessInvoker()
39{
40 g_this = this;
41 m_isRunning = false;
42 m_child = 0;
43 m_defChildHandler = SIG_DFL;
44 m_pTimer = new QTimer(this);
45 m_stdfd[0] = m_stdfd[1] = -1;
46 m_errfd[0] = m_errfd[1] = -1;
47 connect(m_pTimer, SIGNAL(timeout()),
48 this, SLOT(readOutputs()));
49}
50
51ProcessInvoker::~ProcessInvoker()
52{
53 qDebug("ProcessInvoker::~ProcessInvoker()");
54}
55
56bool ProcessInvoker::openPipe()
57{
58 if(m_stdfd[0] >= 0) closePipe(m_stdfd, 0);
59 if(m_stdfd[1] >= 0) closePipe(m_stdfd, 1);
60 if(::pipe(m_stdfd) < 0){
61 return(false);
62 }
63 if(m_errfd[0] >= 0) closePipe(m_errfd, 0);
64 if(m_errfd[1] >= 0) closePipe(m_errfd, 1);
65 if(::pipe(m_errfd) < 0){
66 closePipe(m_stdfd);
67 return(false);
68 }
69 m_maxfdp1 = m_stdfd[0];
70 if(m_errfd[0] > m_maxfdp1){
71 m_maxfdp1 = m_errfd[0];
72 }
73 m_maxfdp1++;
74 return(true);
75}
76
77void ProcessInvoker::closePipe(int fd[], int n)
78{
79 if(fd == NULL){
80 closePipe(m_stdfd, n);
81 closePipe(m_errfd, n);
82 } else {
83 if(n != 1 && fd[0] >= 0){
84 ::close(fd[0]);
85 fd[0] = -1;
86 }
87 if(n != 0 && fd[1] >= 0){
88 ::close(fd[1]);
89 fd[1] = -1;
90 }
91 }
92}
93
94void ProcessInvoker::setRunning(int pid)
95{
96 m_child = pid;
97 m_isRunning = true;
98}
99
100bool ProcessInvoker::run(const QString& args)
101{
102 //setArguments(KHUtil::parseArgs(args));
103 setArguments(StringParser::split(' ', args));
104 return(run());
105}
106
107bool ProcessInvoker::run()
108{
109 if(m_isRunning){
110 return(false);
111 }
112 m_isRunning = true;
113 if(m_arguments.isEmpty()){
114 m_isRunning = false;
115 return(false);
116 }
117 if(m_arguments[0][0] != '/'){
118 m_isRunning = false;
119 return(false);
120 }
121
122 for(QStringList::Iterator it=m_arguments.begin();
123 it!=m_arguments.end(); ++it){
124 qDebug("arguments[%s]", (*it).ascii());
125 }
126
127 /* open pipe */
128 if(openPipe() == false){
129 m_isRunning = false;
130 return(false);
131 }
132
133 /* signal handler reset */
134 m_defChildHandler = setSignalHandler(SIGCHLD, SIG_DFL);
135
136 m_child = ::fork();
137 if(m_child < 0){
138 /* fork error */
139 closePipe();
140 setSignalHandler(SIGCHLD, m_defChildHandler);
141 m_isRunning = false;
142 return(false);
143 } else if(m_child == 0){
144 /* child process */
145 qDebug("child process[%d]", ::getpid());
146 m_child = ::getpid();
147 //setSignalHandler(SIGCHLD, SIG_DFL);
148 workerProc();
149 /* no return */
150 }
151 /* close pipe(write) */
152 closePipe(NULL, 1);
153#if 0
154 m_pTimer = new QTimer(this);
155 connect(m_pTimer, SIGNAL(timeout()),
156 this, SLOT(readOutputs()));
157#endif
158 m_pTimer->start(500);
159 {
160 emit start(m_child, m_arguments);
161 QCopEnvelope e(SC_CHANNEL, "start(int,QStringList)");
162 e << m_child << m_arguments;
163 if(m_isNotify){
164 int idx = m_arguments[0].findRev('/');
165 notifyStatus(m_arguments[0].mid(idx+1), m_child);
166 }
167 }
168 int status;
169 if(::waitpid(-1, &status, WNOHANG) > 0){
170 qDebug("finish");
171 notifyFinish(status);
172 } else {
173 /* signal handler set */
174 setSignalHandler(SIGCHLD, childHandler);
175 }
176 return(true);
177}
178
179void ProcessInvoker::terminate()
180{
181 if(m_isRunning && m_child > 0){
182 terminate(m_child);
183 }
184}
185
186void ProcessInvoker::terminate(pid_t pid)
187{
188 ::kill(pid, SIGTERM);
189}
190
191void ProcessInvoker::kill()
192{
193 if(m_isRunning && m_child > 0){
194 kill(m_child);
195 }
196}
197
198void ProcessInvoker::kill(pid_t pid)
199{
200 ::kill(pid, SIGKILL);
201}
202
203#if 0
204const QStringList ProcessInvoker::parseArgs(const QString& arguments)
205{
206 QString str;
207 QStringList args;
208 char quote = 0;
209 char c;
210 for(unsigned int i=0; i<arguments.length(); i++){
211 c = arguments[i];
212 switch(c){
213 case '\"':
214 if(quote == 0){
215 quote = c;
216 } else if(quote == '\"'){
217 if(str.length() > 0){
218 args.append(str);
219 }
220 str = "";
221 quote = 0;
222 } else {
223 str += c;
224 }
225 break;
226 case '\'':
227 if(quote == 0){
228 quote = c;
229 } else if(quote == '\''){
230 if(str.length() > 0){
231 args.append(str);
232 }
233 str = "";
234 quote = 0;
235 } else {
236 str += c;
237 }
238 break;
239 case ' ':
240 if(quote == 0){
241 if(str.length() > 0){
242 args.append(str);
243 str = "";
244 }
245 } else {
246 str += c;
247 }
248 break;
249 default:
250 str += c;
251 break;
252 }
253 }
254 if(str.length() > 0){
255 args.append(str);
256 }
257 return(args);
258}
259#endif
260
261void ProcessInvoker::readOutputs()
262{
263 struct timeval tmval;
264 tmval.tv_sec = 0;
265 tmval.tv_usec = 0;
266 fd_set rset;
267
268 QByteArray stdBuf, errBuf, resBuf;
269 QDataStream stdStream(stdBuf, IO_WriteOnly);
270 QDataStream errStream(errBuf, IO_WriteOnly);
271
272 int iRet;
273 bool running;
274 char buf[PIPE_BUF+1];
275 while(true){
276 running = false;
277 FD_ZERO(&rset);
278 if(m_stdfd[0] >= 0){
279 FD_SET(m_stdfd[0], &rset);
280 running = true;
281 }
282 if(m_errfd[0] >= 0){
283 FD_SET(m_errfd[0], &rset);
284 running = true;
285 }
286 if(running == false){
287 m_pTimer->stop();
288 //delete m_pTimer;
289 break;
290 }
291
292 if((iRet = ::select(m_maxfdp1, &rset, NULL, NULL, &tmval)) <= 0){
293 qDebug("select[%d]", iRet);
294 break;
295 }
296
297 if(m_stdfd[0] >= 0 && FD_ISSET(m_stdfd[0], &rset)){
298 int n = ::read(m_stdfd[0], buf, PIPE_BUF);
299 if(n > 0){
300 stdStream.writeRawBytes(buf, n);
301 } else {
302 qDebug("stdout close");
303 closePipe(m_stdfd, 0);
304 }
305 }
306 if(m_errfd[0] >= 0 && FD_ISSET(m_errfd[0], &rset)){
307 int n = ::read(m_errfd[0], buf, PIPE_BUF);
308 if(n > 0){
309 errStream.writeRawBytes(buf, n);
310 } else {
311 qDebug("stderr close");
312 closePipe(m_errfd, 0);
313 }
314 }
315 }
316
317 if(stdBuf.size() > 0){
318 QCopEnvelope e(SC_CHANNEL, "stdout(int,QByteArray)");
319 e << m_child << stdBuf;
320 }
321 if(errBuf.size() > 0){
322 QCopEnvelope e(SC_CHANNEL, "stderr(int,QByteArray)");
323 e << m_child << errBuf;
324 }
325 if(running == false){
326 QCopEnvelope e(SC_CHANNEL, "close(int)");
327 e << m_child;
328 }
329}
330
331#if 0
332void ProcessInvoker::waitFinish()
333{
334 int status;
335 if(::waitpid(m_child, &status, 0) > 0){
336 notifyFinish(status);
337 } else {
338 notifyFinish(0, false);
339 }
340}
341#endif
342
343void ProcessInvoker::notifyFinish(int status, bool success)
344{
345 bool stopped = false;
346 QString result;
347 int code;
348 if(success){
349 if(WIFEXITED(status)){
350 code = WEXITSTATUS(status);
351 if(code == 127){
352 result = "error";
353 } else {
354 result = "exit";
355 }
356 } else if(WIFSIGNALED(status)){
357 result = "terminated";
358 code = WTERMSIG(status);
359 } else if(WIFSTOPPED(status)){
360 result = "stopped";
361 code = WSTOPSIG(status);
362 stopped = true;
363 } else {
364 /* ¤³¤ì¤Ï̵¤¤¤Ï¤º? */
365 result = "error";
366 code = -2;
367 qWarning("ProcessInvoker: unknown status");
368 }
369 } else {
370 result = "error";
371 code = -1;
372 qWarning("ProcessInvoker: wait error");
373 }
374 emit finish(result, code);
375 QCopEnvelope e(SC_CHANNEL, "finish(int,QString,int)");
376 e << m_child << result << code;
377 if(m_isNotify){
378 notifyStatus(result, code);
379 setNotify(false);
380 }
381 if(stopped == false){
382 setSignalHandler(SIGCHLD, m_defChildHandler);
383 m_isRunning = false;
384 }
385}
386
387void ProcessInvoker::notifyStatus(const QString& result, int code)
388{
389 QString message = QString::number(code);
390 message.append(":");
391 message.append(result);
392 Global::statusMessage(message);
393}
394
395/* ------------------------------------------------------------------------ */
396 /* ProcessInvoker Class : child process */
397/* ------------------------------------------------------------------------ */
398void ProcessInvoker::workerProc()
399{
400 closePipe(m_stdfd, 0);
401 closePipe(m_errfd, 0);
402 if(m_stdfd[1] != STDOUT_FILENO){
403 ::dup2(m_stdfd[1], STDOUT_FILENO);
404 closePipe(m_stdfd, 1);
405 }
406 if(m_errfd[1] != STDERR_FILENO){
407 ::dup2(m_errfd[1], STDERR_FILENO);
408 closePipe(m_errfd, 1);
409 }
410
411 QCString* arglist = new QCString[m_arguments.count()+1];
412 const char** argv = new const char*[m_arguments.count()+1];
413 unsigned int i;
414 for(i=0; i<m_arguments.count(); i++){
415 //arglist[i] = m_arguments[i].local8Bit();
416 arglist[i] = m_arguments[i];
417 argv[i] = arglist[i];
418 }
419 argv[i] = 0;
420 ::execv(argv[0], (char*const*)argv);
421 delete[] arglist;
422 delete[] argv;
423 ::_exit(127);
424}
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 @@
1#ifndef _PROCESS_INVOKER_H_
2#define _PROCESS_INVOKER_H_
3
4#include <qobject.h>
5#include <sys/wait.h>
6#include <sys/types.h>
7#include <sys/time.h>
8#include <signal.h>
9#include <stdio.h>
10#include <unistd.h>
11#include <errno.h>
12
13#include <qtimer.h>
14#include <qdatastream.h>
15#include <qcstring.h>
16#include <qpe/qcopenvelope_qws.h>
17#include <qpe/global.h>
18//#include "KHUtil.h"
19#include "StringParser.h"
20
21typedef void Sigfunc(int);
22
23 #define SC_CHANNEL"QPE/ShellCommander"
24
25/* Sigleton Object */
26class ProcessInvoker : public QObject
27{
28 Q_OBJECT
29public:
30 static ProcessInvoker& getInstance()
31 {
32 static ProcessInvoker instance;
33 return(instance);
34 }
35
36 bool run();
37 bool run(const QString& args);
38 void terminate();
39 void terminate(pid_t pid);
40 void kill();
41 void kill(pid_t pid);
42 void setCommand(const QString& command){
43 m_arguments.clear();
44 addArgument(command);
45 }
46 void setArguments(const QStringList& arglist){
47 m_arguments = arglist;
48 }
49 void setArguments(const QString& arguments){
50 //setArguments(KHUtil::parseArgs(arguments));
51 setArguments(StringParser::split(' ', arguments));
52 }
53 void addArgument(const QString& argument){
54 m_arguments.append(argument);
55 }
56 void addArguments(const QString& arguments){
57 QStringList arglist;
58 //arglist = KHUtil::parseArgs(arguments);
59 arglist = StringParser::split(' ', arguments);
60 addArguments(arglist);
61 }
62 void addArguments(const QStringList& arglist){
63 for(QStringList::ConstIterator it=arglist.begin();
64 it!=arglist.end(); ++it){
65 addArgument(*it);
66 }
67 }
68 //const QStringList parseArgs(const QString& arguments);
69 void setRunning(int pid);
70 void setNotify(bool enable=true){
71 m_isNotify = enable;
72 }
73
74 bool isRunning(){
75 return(m_isRunning);
76 }
77 void notifyFinish(int status, bool success=true);
78
79 pid_t m_child;
80
81 friend class Dummy; /* for compile warning */
82signals:
83 void start(int, QStringList);
84 void finish(QString,int);
85private:
86 ProcessInvoker();
87 ProcessInvoker(const ProcessInvoker&);
88 ProcessInvoker& operator=(const ProcessInvoker&);
89 ~ProcessInvoker();
90
91 class Dummy{}; /* for compile warning */
92
93 QTimer* m_pTimer;
94 QStringList m_arguments;
95
96 bool m_isRunning;
97 bool m_isNotify;
98
99 Sigfunc* m_defChildHandler;
100
101 int m_stdfd[2];
102 int m_errfd[2];
103 int m_maxfdp1;
104
105 bool openPipe();
106 void closePipe(int fd[] = NULL, int n = 2);
107 void notifyStatus(const QString& result, int code);
108
109 void workerProc();
110private slots:
111 void readOutputs();
112};
113
114#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 @@
1#include "QCopLnk.h"
2#include "StringParser.h"
3
4void QCopLnk::execute()
5{
6 parseText();
7 //QStringList argList = KHUtil::parseArgs(m_params[1]);
8 QStringList argList = StringParser::split(' ', m_params[1]);
9 if(argList.count() < 2){
10 return;
11 }
12 QStringList paramList =
13 QStringList::split(QRegExp("[(),]"), argList[1]);
14 if(argList.count() < paramList.count()+1){
15 return;
16 }
17 paramList.remove(paramList.begin());
18 if(paramList.count() == 0){
19 /* send qcop message */
20 QCopEnvelope env(argList[0].latin1(), argList[1].latin1());
21 } else {
22 QCopEnvelope* e = NULL;
23 QStringList::Iterator it=paramList.end();
24 for(unsigned int index = 2; index<argList.count(); index++){
25 if(it == paramList.end()){
26 if(argList.count() - index < paramList.count()){
27 break;
28 }
29 /* initialize */
30 it = paramList.begin();
31 e = new QCopEnvelope(
32 argList[0].latin1(), argList[1].latin1());
33 }
34 QString arg = argList[index];
35 if(*it == "QString"){
36 *e << arg;
37 } else if(*it == "int"){
38 *e << arg.toInt();
39 } else if(*it == "bool"){
40 QString s = arg.lower();
41 int on;
42 if(s == "true"){
43 on = TRUE;
44 } else if(s == "false"){
45 on = FALSE;
46 } else {
47 on = s.toInt();
48 }
49 *e << on;
50 }
51 ++it;
52 if(it == paramList.end()){
53 /* send qcop message */
54 delete e;
55 if(argList.count() - index >= paramList.count()){
56 e = new QCopEnvelope(
57 argList[0].latin1(), argList[1].latin1());
58 it = paramList.begin();
59 }
60 }
61 }
62 }
63}
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 @@
1#ifndef _QCOPLNK_H_
2#define _QCOPLNK_H_
3
4#include <qpe/qpeapplication.h>
5#include <qpe/qcopenvelope_qws.h>
6
7#include "AnyLnk.h"
8#include "KHUtil.h"
9
10class QCopLnk : public AnyLnk
11{
12public:
13 QCopLnk(){}
14 QCopLnk(const QStringList& params)
15 : AnyLnk(params){}
16 virtual ~QCopLnk() {
17 }
18
19 virtual bool isValid() {
20 return(true);
21 }
22 virtual QString name() {
23 return("qcop");
24 }
25 virtual const QPixmap& pixmap() {
26 return(m_pixmap);
27 }
28
29 virtual void execute();
30protected:
31};
32
33#endif /* _QCOPLNK_H_ */
34
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 @@
1#include "TextLnk.h"
2
3void TextLnk::execute()
4{
5 QClipboard* cb = QApplication::clipboard();
6 parseText();
7 cb->setText(m_params[1]);
8 QWSServer::sendKeyEvent('V'-'@',Qt::Key_V, Qt::ControlButton,
9 true, false);
10 QWSServer::sendKeyEvent('V'-'@',Qt::Key_V, Qt::ControlButton,
11 false, false);
12}
13
14void TextLnk::parse(QString& str)
15{
16 replace(str, "\\\\", "\\");
17 replace(str, "\\n", "\n");
18 replace(str, "\\r", "\r");
19 replace(str, "\\t", "\t");
20}
21
22void TextLnk::replace(QString& str, const QString& s1, const QString& s2)
23{
24 int index = 0;
25 int idx;
26 int len = s1.length();
27 idx = str.find(s1, index);
28 for(;;){
29 idx = str.find(s1, index);
30 if(idx < 0) break;
31 str.replace(idx, len, s2);
32 index = idx;
33 }
34}
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 @@
1#ifndef _PASTELNK_H_
2#define _PASTELNK_H_
3
4#include <qwindowsystem_qws.h>
5
6#include <qpe/qpeapplication.h>
7#include <qclipboard.h>
8#include <qregexp.h>
9
10#include "AnyLnk.h"
11
12class TextLnk : public AnyLnk
13{
14public:
15 TextLnk(){}
16 TextLnk(const QStringList& params)
17 : AnyLnk(params){}
18 virtual ~TextLnk() {
19 }
20
21 virtual bool isValid() {
22 return(true);
23 }
24 virtual QString name() {
25 return("text");
26 }
27 virtual const QPixmap& pixmap() {
28 return(m_pixmap);
29 }
30
31 virtual void execute();
32protected:
33 virtual void parse(QString& str);
34 virtual void replace(QString& str, const QString& s1, const QString& s2);
35};
36
37#endif /* _PASTELNK_H_ */
38