Moved the command to the first column, treat the PID specially.
[kdbg.git] / kdbg / procattach.cpp
blob66c446237ce1540647a3b4d9c7ac17ee645b7deb
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include "procattach.h"
7 #include <qlistview.h>
8 #include <kprocess.h>
9 #include <ctype.h>
10 #include <kapp.h>
11 #include <klocale.h> /* i18n */
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
17 ProcAttachPS::ProcAttachPS(QWidget* parent) :
18 ProcAttachBase(parent),
19 m_pidCol(-1)
21 m_ps = new KProcess;
22 connect(m_ps, SIGNAL(receivedStdout(KProcess*, char*, int)),
23 this, SLOT(slotTextReceived(KProcess*, char*, int)));
25 processList->setColumnAlignment(1, Qt::AlignRight);
27 // set the command line
28 static const char* const psCommand[] = {
29 #ifdef PS_COMMAND
30 PS_COMMAND,
31 #else
32 "/bin/false",
33 #endif
36 for (int i = 0; psCommand[i] != 0; i++) {
37 *m_ps << psCommand[i];
40 runPS();
43 ProcAttachPS::~ProcAttachPS()
45 delete m_ps; // kills a running ps
48 void ProcAttachPS::runPS()
50 // clear the parse state from previous runs
51 m_token = "";
52 m_line.clear();
53 m_pidCol = -1;
55 m_ps->start(KProcess::NotifyOnExit, KProcess::Stdout);
58 void ProcAttachPS::slotTextReceived(KProcess*, char* buffer, int buflen)
60 const char* end = buffer+buflen;
61 while (buffer < end)
63 // check new line
64 if (*buffer == '\n')
66 // push a tokens onto the line
67 if (!m_token.isEmpty()) {
68 m_line.push_back(QString::fromLatin1(m_token));
69 m_token = "";
71 // and insert the line in the list
72 pushLine();
73 m_line.clear();
74 ++buffer;
76 // blanks: the last column gets the rest of the line, including blanks
77 else if ((m_pidCol < 0 || int(m_line.size()) < processList->columns()-1) &&
78 isspace(*buffer))
80 // push a token onto the line
81 if (!m_token.isEmpty()) {
82 m_line.push_back(QString::fromLatin1(m_token));
83 m_token = "";
85 do {
86 ++buffer;
87 } while (buffer < end && isspace(*buffer));
89 // tokens
90 else
92 const char* start = buffer;
93 do {
94 ++buffer;
95 } while (buffer < end && !isspace(*buffer));
96 // append to the current token
97 m_token += QCString(start, buffer-start+1); // must count the '\0'
102 void ProcAttachPS::pushLine()
104 if (m_line.size() < 2) // we need the PID and COMMAND columns
105 return;
107 if (m_pidCol < 0)
109 // create columns if we don't have them yet
110 bool allocate = processList->columns() == 2;
112 // we assume that the last column is the command
113 m_line.pop_back();
115 for (uint i = 0; i < m_line.size(); i++) {
116 // we don't allocate a PID column,
117 // but we need to know which column it is
118 if (m_line[i] == "PID") {
119 m_pidCol = i;
120 } else if (allocate) {
121 processList->addColumn(m_line[i]);
122 // these columns are normally numbers
123 processList->setColumnAlignment(processList->columns()-1,
124 Qt::AlignRight);
128 else
130 // insert a line
131 // we assume that the last column is the command
132 QListViewItem* item = new QListViewItem(processList, m_line.back());
133 m_line.pop_back();
134 int k = 2;
135 for (uint i = 0; i < m_line.size(); i++)
137 // display the pid column's content in the second column
138 if (int(i) == m_pidCol)
139 item->setText(1, m_line[i]);
140 else
141 item->setText(k++, m_line[i]);
146 void ProcAttachPS::processSelected(QListViewItem* item)
148 pidEdit->setText(item->text(1));
149 processText->setText(item->text(0));
152 void ProcAttachPS::refresh()
154 if (!m_ps->isRunning())
156 processList->clear();
157 runPS();
162 ProcAttach::ProcAttach(QWidget* parent) :
163 QDialog(parent, "procattach", true),
164 m_label(this, "label"),
165 m_processId(this, "procid"),
166 m_buttonOK(this, "ok"),
167 m_buttonCancel(this, "cancel"),
168 m_layout(this, 8),
169 m_buttons(4)
171 QString title = kapp->caption();
172 title += i18n(": Attach to process");
173 setCaption(title);
175 m_label.setMinimumSize(330, 24);
176 m_label.setText(i18n("Specify the process number to attach to:"));
178 m_processId.setMinimumSize(330, 24);
179 m_processId.setMaxLength(100);
180 m_processId.setFrame(true);
182 m_buttonOK.setMinimumSize(100, 30);
183 connect(&m_buttonOK, SIGNAL(clicked()), SLOT(accept()));
184 m_buttonOK.setText(i18n("OK"));
185 m_buttonOK.setDefault(true);
187 m_buttonCancel.setMinimumSize(100, 30);
188 connect(&m_buttonCancel, SIGNAL(clicked()), SLOT(reject()));
189 m_buttonCancel.setText(i18n("Cancel"));
191 m_layout.addWidget(&m_label);
192 m_layout.addWidget(&m_processId);
193 m_layout.addLayout(&m_buttons);
194 m_layout.addStretch(10);
195 m_buttons.addStretch(10);
196 m_buttons.addWidget(&m_buttonOK);
197 m_buttons.addSpacing(40);
198 m_buttons.addWidget(&m_buttonCancel);
199 m_buttons.addStretch(10);
201 m_layout.activate();
203 m_processId.setFocus();
204 resize(350, 120);
207 ProcAttach::~ProcAttach()