3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include "procattach.h"
11 #include <klocale.h> /* i18n */
17 ProcAttachPS::ProcAttachPS(QWidget
* parent
) :
18 ProcAttachBase(parent
),
23 connect(m_ps
, SIGNAL(receivedStdout(KProcess
*, char*, int)),
24 this, SLOT(slotTextReceived(KProcess
*, char*, int)));
26 processList
->setColumnWidth(0, 300);
27 processList
->setColumnWidthMode(0, QListView::Manual
);
28 processList
->setColumnAlignment(1, Qt::AlignRight
);
29 processList
->setColumnAlignment(2, Qt::AlignRight
);
31 // set the command line
32 static const char* const psCommand
[] = {
40 for (int i
= 0; psCommand
[i
] != 0; i
++) {
41 *m_ps
<< psCommand
[i
];
47 ProcAttachPS::~ProcAttachPS()
49 delete m_ps
; // kills a running ps
52 void ProcAttachPS::runPS()
54 // clear the parse state from previous runs
60 m_ps
->start(KProcess::NotifyOnExit
, KProcess::Stdout
);
63 void ProcAttachPS::slotTextReceived(KProcess
*, char* buffer
, int buflen
)
65 const char* end
= buffer
+buflen
;
71 // push a tokens onto the line
72 if (!m_token
.isEmpty()) {
73 m_line
.push_back(QString::fromLatin1(m_token
));
76 // and insert the line in the list
81 // blanks: the last column gets the rest of the line, including blanks
82 else if ((m_pidCol
< 0 || int(m_line
.size()) < processList
->columns()-1) &&
85 // push a token onto the line
86 if (!m_token
.isEmpty()) {
87 m_line
.push_back(QString::fromLatin1(m_token
));
92 } while (buffer
< end
&& isspace(*buffer
));
97 const char* start
= buffer
;
100 } while (buffer
< end
&& !isspace(*buffer
));
101 // append to the current token
102 m_token
+= QCString(start
, buffer
-start
+1); // must count the '\0'
107 void ProcAttachPS::pushLine()
109 if (m_line
.size() < 3) // we need the PID, PPID, and COMMAND columns
114 // create columns if we don't have them yet
115 bool allocate
= processList
->columns() == 3;
117 // we assume that the last column is the command
120 for (uint i
= 0; i
< m_line
.size(); i
++) {
121 // we don't allocate the PID and PPID columns,
122 // but we need to know where in the ps output they are
123 if (m_line
[i
] == "PID") {
125 } else if (m_line
[i
] == "PPID") {
127 } else if (allocate
) {
128 processList
->addColumn(m_line
[i
]);
129 // these columns are normally numbers
130 processList
->setColumnAlignment(processList
->columns()-1,
138 // find the parent process
139 QListViewItem
* parent
= 0;
140 if (m_ppidCol
>= 0 && m_ppidCol
< int(m_line
.size())) {
141 parent
= processList
->findItem(m_line
[m_ppidCol
], 1);
144 // we assume that the last column is the command
147 item
= new QListViewItem(processList
, m_line
.back());
149 item
= new QListViewItem(parent
, m_line
.back());
154 for (uint i
= 0; i
< m_line
.size(); i
++)
156 // display the pid and ppid columns' contents in columns 1 and 2
157 if (int(i
) == m_pidCol
)
158 item
->setText(1, m_line
[i
]);
159 else if (int(i
) == m_ppidCol
)
160 item
->setText(2, m_line
[i
]);
162 item
->setText(k
++, m_line
[i
]);
165 if (m_ppidCol
>= 0 && m_pidCol
>= 0) { // need PID & PPID for this
167 * It could have happened that a process was earlier inserted,
168 * whose parent process is the current process. Such processes
169 * were placed at the root. Here we go through all root items
170 * and check whether we must reparent them.
172 QListViewItem
* i
= processList
->firstChild();
175 // advance before we reparent the item
176 QListViewItem
* it
= i
;
177 i
= i
->nextSibling();
178 if (it
->text(2) == m_line
[m_pidCol
]) {
179 processList
->takeItem(it
);
180 item
->insertItem(it
);
187 void ProcAttachPS::processSelected(QListViewItem
* item
)
190 pidEdit
->setText(item
->text(1));
191 processText
->setText(item
->text(0));
195 void ProcAttachPS::refresh()
197 if (!m_ps
->isRunning())
199 processList
->clear();
204 void ProcAttachPS::pidEdited(const QString
& text
)
209 // get the process and select it
210 QListViewItem
* item
= processList
->findItem(text
, 1);
212 processList
->clearSelection();
214 processList
->setSelected(item
, true);
215 processList
->ensureItemVisible(item
);
220 ProcAttach::ProcAttach(QWidget
* parent
) :
221 QDialog(parent
, "procattach", true),
222 m_label(this, "label"),
223 m_processId(this, "procid"),
224 m_buttonOK(this, "ok"),
225 m_buttonCancel(this, "cancel"),
229 QString title
= kapp
->caption();
230 title
+= i18n(": Attach to process");
233 m_label
.setMinimumSize(330, 24);
234 m_label
.setText(i18n("Specify the process number to attach to:"));
236 m_processId
.setMinimumSize(330, 24);
237 m_processId
.setMaxLength(100);
238 m_processId
.setFrame(true);
240 m_buttonOK
.setMinimumSize(100, 30);
241 connect(&m_buttonOK
, SIGNAL(clicked()), SLOT(accept()));
242 m_buttonOK
.setText(i18n("OK"));
243 m_buttonOK
.setDefault(true);
245 m_buttonCancel
.setMinimumSize(100, 30);
246 connect(&m_buttonCancel
, SIGNAL(clicked()), SLOT(reject()));
247 m_buttonCancel
.setText(i18n("Cancel"));
249 m_layout
.addWidget(&m_label
);
250 m_layout
.addWidget(&m_processId
);
251 m_layout
.addLayout(&m_buttons
);
252 m_layout
.addStretch(10);
253 m_buttons
.addStretch(10);
254 m_buttons
.addWidget(&m_buttonOK
);
255 m_buttons
.addSpacing(40);
256 m_buttons
.addWidget(&m_buttonCancel
);
257 m_buttons
.addStretch(10);
261 m_processId
.setFocus();
265 ProcAttach::~ProcAttach()