• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • kio
connection.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
3 David Faure <faure@kde.org>
4 Copyright (C) 2007 Thiago Macieira <thiago@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "connection.h"
23#include "connection_p.h"
24
25#include <errno.h>
26
27#include <QQueue>
28#include <QPointer>
29#include <QTime>
30
31#include <kdebug.h>
32#include <kcomponentdata.h>
33#include <kglobal.h>
34#include <klocale.h>
35#include <kstandarddirs.h>
36#include <ktemporaryfile.h>
37#include <kurl.h>
38
39using namespace KIO;
40
41class KIO::ConnectionPrivate
42{
43public:
44 inline ConnectionPrivate()
45 : backend(0), suspended(false)
46 { }
47
48 void dequeue();
49 void commandReceived(const Task &task);
50 void disconnected();
51 void setBackend(AbstractConnectionBackend *b);
52
53 QQueue<Task> outgoingTasks;
54 QQueue<Task> incomingTasks;
55 AbstractConnectionBackend *backend;
56 Connection *q;
57 bool suspended;
58};
59
60class KIO::ConnectionServerPrivate
61{
62public:
63 inline ConnectionServerPrivate()
64 : backend(0)
65 { }
66
67 ConnectionServer *q;
68 AbstractConnectionBackend *backend;
69};
70
71void ConnectionPrivate::dequeue()
72{
73 if (!backend || suspended)
74 return;
75
76 while (!outgoingTasks.isEmpty()) {
77 const Task task = outgoingTasks.dequeue();
78 q->sendnow(task.cmd, task.data);
79 }
80
81 if (!incomingTasks.isEmpty())
82 emit q->readyRead();
83}
84
85void ConnectionPrivate::commandReceived(const Task &task)
86{
87 //kDebug() << this << "Command " << task.cmd << " added to the queue";
88 if (!suspended && incomingTasks.isEmpty())
89 QMetaObject::invokeMethod(q, "dequeue", Qt::QueuedConnection);
90 incomingTasks.enqueue(task);
91}
92
93void ConnectionPrivate::disconnected()
94{
95 q->close();
96 QMetaObject::invokeMethod(q, "readyRead", Qt::QueuedConnection);
97}
98
99void ConnectionPrivate::setBackend(AbstractConnectionBackend *b)
100{
101 backend = b;
102 if (backend) {
103 q->connect(backend, SIGNAL(commandReceived(Task)), SLOT(commandReceived(Task)));
104 q->connect(backend, SIGNAL(disconnected()), SLOT(disconnected()));
105 backend->setSuspended(suspended);
106 }
107}
108
109AbstractConnectionBackend::AbstractConnectionBackend(QObject *parent)
110 : QObject(parent), state(Idle)
111{
112}
113
114AbstractConnectionBackend::~AbstractConnectionBackend()
115{
116}
117
118SocketConnectionBackend::SocketConnectionBackend(Mode m, QObject *parent)
119 : AbstractConnectionBackend(parent), socket(0), len(-1), cmd(0),
120 signalEmitted(false), mode(m)
121{
122 localServer = 0;
123 //tcpServer = 0;
124}
125
126SocketConnectionBackend::~SocketConnectionBackend()
127{
128 if (mode == LocalSocketMode && localServer &&
129 localServer->localSocketType() == KLocalSocket::UnixSocket)
130 QFile::remove(localServer->localPath());
131}
132
133void SocketConnectionBackend::setSuspended(bool enable)
134{
135 if (state != Connected)
136 return;
137 Q_ASSERT(socket);
138 Q_ASSERT(!localServer); // !tcpServer as well
139
140 if (enable) {
141 //kDebug() << this << " suspending";
142 socket->setReadBufferSize(1);
143 } else {
144 //kDebug() << this << " resuming";
145 socket->setReadBufferSize(StandardBufferSize);
146 if (socket->bytesAvailable() >= HeaderSize) {
147 // there are bytes available
148 QMetaObject::invokeMethod(this, "socketReadyRead", Qt::QueuedConnection);
149 }
150
151 // We read all bytes here, but we don't use readAll() because we need
152 // to read at least one byte (even if there isn't any) so that the
153 // socket notifier is reenabled
154 QByteArray data = socket->read(socket->bytesAvailable() + 1);
155 for (int i = data.size(); --i >= 0; )
156 socket->ungetChar(data[i]);
157 }
158}
159
160bool SocketConnectionBackend::connectToRemote(const KUrl &url)
161{
162 Q_ASSERT(state == Idle);
163 Q_ASSERT(!socket);
164 Q_ASSERT(!localServer); // !tcpServer as well
165
166 if (mode == LocalSocketMode) {
167 KLocalSocket *sock = new KLocalSocket(this);
168 QString path = url.path();
169#if 0
170 // TODO: Activate once abstract socket support is implemented in Qt.
171 KLocalSocket::LocalSocketType type = KLocalSocket::UnixSocket;
172
173 if (url.queryItem(QLatin1String("abstract")) == QLatin1String("1"))
174 type = KLocalSocket::AbstractUnixSocket;
175#endif
176 sock->connectToPath(path);
177 socket = sock;
178 } else {
179 socket = new QTcpSocket(this);
180 socket->connectToHost(url.host(),url.port());
181
182 if (!socket->waitForConnected(1000)) {
183 state = Idle;
184 kDebug() << "could not connect to " << url;
185 return false;
186 }
187 }
188 connect(socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
189 connect(socket, SIGNAL(disconnected()), SLOT(socketDisconnected()));
190 state = Connected;
191 return true;
192}
193
194void SocketConnectionBackend::socketDisconnected()
195{
196 state = Idle;
197 emit disconnected();
198}
199
200bool SocketConnectionBackend::listenForRemote()
201{
202 Q_ASSERT(state == Idle);
203 Q_ASSERT(!socket);
204 Q_ASSERT(!localServer); // !tcpServer as well
205
206 if (mode == LocalSocketMode) {
207 QString prefix = KStandardDirs::locateLocal("socket", KGlobal::mainComponent().componentName());
208 KTemporaryFile *socketfile = new KTemporaryFile();
209 socketfile->setPrefix(prefix);
210 socketfile->setSuffix(QLatin1String(".slave-socket"));
211 if (!socketfile->open())
212 {
213 errorString = i18n("Unable to create io-slave: %1", strerror(errno));
214 delete socketfile;
215 return false;
216 }
217
218 QString sockname = socketfile->fileName();
219 KUrl addressUrl(sockname);
220 addressUrl.setProtocol("local");
221 address = addressUrl.url();
222 delete socketfile; // can't bind if there is such a file
223
224 localServer = new KLocalSocketServer(this);
225 if (!localServer->listen(sockname, KLocalSocket::UnixSocket)) {
226 errorString = localServer->errorString();
227 delete localServer;
228 localServer = 0;
229 return false;
230 }
231
232 connect(localServer, SIGNAL(newConnection()), SIGNAL(newConnection()));
233 } else {
234 tcpServer = new QTcpServer(this);
235 tcpServer->listen(QHostAddress::LocalHost);
236 if (!tcpServer->isListening()) {
237 errorString = tcpServer->errorString();
238 delete tcpServer;
239 tcpServer = 0;
240 return false;
241 }
242
243 address = "tcp://127.0.0.1:" + QString::number(tcpServer->serverPort());
244 connect(tcpServer, SIGNAL(newConnection()), SIGNAL(newConnection()));
245 }
246
247 state = Listening;
248 return true;
249}
250
251bool SocketConnectionBackend::waitForIncomingTask(int ms)
252{
253 Q_ASSERT(state == Connected);
254 Q_ASSERT(socket);
255 if (socket->state() != QAbstractSocket::ConnectedState) {
256 state = Idle;
257 return false; // socket has probably closed, what do we do?
258 }
259
260 signalEmitted = false;
261 if (socket->bytesAvailable())
262 socketReadyRead();
263 if (signalEmitted)
264 return true; // there was enough data in the socket
265
266 // not enough data in the socket, so wait for more
267 QTime timer;
268 timer.start();
269
270 while (socket->state() == QAbstractSocket::ConnectedState && !signalEmitted &&
271 (ms == -1 || timer.elapsed() < ms))
272 if (!socket->waitForReadyRead(ms == -1 ? -1 : ms - timer.elapsed()))
273 break;
274
275 if (signalEmitted)
276 return true;
277 if (socket->state() != QAbstractSocket::ConnectedState)
278 state = Idle;
279 return false;
280}
281
282bool SocketConnectionBackend::sendCommand(const Task &task)
283{
284 Q_ASSERT(state == Connected);
285 Q_ASSERT(socket);
286
287 static char buffer[HeaderSize + 2];
288 sprintf(buffer, "%6x_%2x_", task.data.size(), task.cmd);
289 socket->write(buffer, HeaderSize);
290 socket->write(task.data);
291
292 //kDebug() << this << " Sending command " << hex << task.cmd << " of "
293 // << task.data.size() << " bytes (" << socket->bytesToWrite()
294 // << " bytes left to write";
295
296 // blocking mode:
297 while (socket->bytesToWrite() > 0 && socket->state() == QAbstractSocket::ConnectedState)
298 socket->waitForBytesWritten(-1);
299
300 return socket->state() == QAbstractSocket::ConnectedState;
301}
302
303AbstractConnectionBackend *SocketConnectionBackend::nextPendingConnection()
304{
305 Q_ASSERT(state == Listening);
306 Q_ASSERT(localServer || tcpServer);
307 Q_ASSERT(!socket);
308
309 //kDebug() << "Got a new connection";
310
311 QTcpSocket *newSocket;
312 if (mode == LocalSocketMode)
313 newSocket = localServer->nextPendingConnection();
314 else
315 newSocket = tcpServer->nextPendingConnection();
316 if (!newSocket)
317 return 0; // there was no connection...
318
319 SocketConnectionBackend *result = new SocketConnectionBackend(Mode(mode));
320 result->state = Connected;
321 result->socket = newSocket;
322 newSocket->setParent(result);
323 connect(newSocket, SIGNAL(readyRead()), result, SLOT(socketReadyRead()));
324 connect(newSocket, SIGNAL(disconnected()), result, SLOT(socketDisconnected()));
325
326 return result;
327}
328
329void SocketConnectionBackend::socketReadyRead()
330{
331 bool shouldReadAnother;
332 do {
333 if (!socket)
334 // might happen if the invokeMethods were delivered after we disconnected
335 return;
336
337 // kDebug() << this << "Got " << socket->bytesAvailable() << " bytes";
338 if (len == -1) {
339 // We have to read the header
340 static char buffer[HeaderSize];
341
342 if (socket->bytesAvailable() < HeaderSize) {
343 return; // wait for more data
344 }
345
346 socket->read(buffer, sizeof buffer);
347 buffer[6] = 0;
348 buffer[9] = 0;
349
350 char *p = buffer;
351 while( *p == ' ' ) p++;
352 len = strtol( p, 0L, 16 );
353
354 p = buffer + 7;
355 while( *p == ' ' ) p++;
356 cmd = strtol( p, 0L, 16 );
357
358 // kDebug() << this << " Beginning of command " << hex << cmd << " of size "
359 // << len;
360 }
361
362 QPointer<SocketConnectionBackend> that = this;
363
364 // kDebug() << this << "Want to read " << len << " bytes";
365 if (socket->bytesAvailable() >= len) {
366 Task task;
367 task.cmd = cmd;
368 if (len)
369 task.data = socket->read(len);
370 len = -1;
371
372 signalEmitted = true;
373 emit commandReceived(task);
374 } else if (len > StandardBufferSize) {
375 kDebug(7017) << this << "Jumbo packet of" << len << "bytes";
376 socket->setReadBufferSize(len + 1);
377 }
378
379 // If we're dead, better don't try anything.
380 if (that.isNull())
381 return;
382
383 // Do we have enough for an another read?
384 if (len == -1)
385 shouldReadAnother = socket->bytesAvailable() >= HeaderSize;
386 else
387 shouldReadAnother = socket->bytesAvailable() >= len;
388 }
389 while (shouldReadAnother);
390}
391
392Connection::Connection(QObject *parent)
393 : QObject(parent), d(new ConnectionPrivate)
394{
395 d->q = this;
396}
397
398Connection::~Connection()
399{
400 close();
401 delete d;
402}
403
404void Connection::suspend()
405{
406 //kDebug() << this << "Suspended";
407 d->suspended = true;
408 if (d->backend)
409 d->backend->setSuspended(true);
410}
411
412void Connection::resume()
413{
414 // send any outgoing or incoming commands that may be in queue
415 QMetaObject::invokeMethod(this, "dequeue", Qt::QueuedConnection);
416
417 //kDebug() << this << "Resumed";
418 d->suspended = false;
419 if (d->backend)
420 d->backend->setSuspended(false);
421}
422
423void Connection::close()
424{
425 if (d->backend) {
426 d->backend->disconnect(this);
427 d->backend->deleteLater();
428 d->backend = 0;
429 }
430 d->outgoingTasks.clear();
431 d->incomingTasks.clear();
432}
433
434bool Connection::isConnected() const
435{
436 return d->backend && d->backend->state == AbstractConnectionBackend::Connected;
437}
438
439bool Connection::inited() const
440{
441 return d->backend;
442}
443
444bool Connection::suspended() const
445{
446 return d->suspended;
447}
448
449void Connection::connectToRemote(const QString &address)
450{
451 //kDebug(7017) << "Connection requested to " << address;
452 KUrl url = address;
453 QString scheme = url.protocol();
454
455 if (scheme == QLatin1String("local")) {
456 d->setBackend(new SocketConnectionBackend(SocketConnectionBackend::LocalSocketMode, this));
457 } else if (scheme == QLatin1String("tcp")) {
458 d->setBackend(new SocketConnectionBackend(SocketConnectionBackend::TcpSocketMode, this));
459 } else {
460 kWarning(7017) << "Unknown requested KIO::Connection protocol='" << scheme
461 << "' (" << address << ")";
462 Q_ASSERT(0);
463 return;
464 }
465
466 // connection succeeded
467 if (!d->backend->connectToRemote(url)) {
468 //kWarning(7017) << "could not connect to " << url << "using scheme" << scheme ;
469 delete d->backend;
470 d->backend = 0;
471 return;
472 }
473
474 d->dequeue();
475}
476
477QString Connection::errorString() const
478{
479 if (d->backend)
480 return d->backend->errorString;
481 return QString();
482}
483
484bool Connection::send(int cmd, const QByteArray& data)
485{
486 if (!inited() || !d->outgoingTasks.isEmpty()) {
487 Task task;
488 task.cmd = cmd;
489 task.data = data;
490 d->outgoingTasks.enqueue(task);
491 return true;
492 } else {
493 return sendnow(cmd, data);
494 }
495}
496
497bool Connection::sendnow(int _cmd, const QByteArray &data)
498{
499 if (data.size() > 0xffffff)
500 return false;
501
502 if (!isConnected())
503 return false;
504
505 //kDebug() << this << "Sending command " << _cmd << " of size " << data.size();
506 Task task;
507 task.cmd = _cmd;
508 task.data = data;
509 return d->backend->sendCommand(task);
510}
511
512bool Connection::hasTaskAvailable() const
513{
514 return !d->incomingTasks.isEmpty();
515}
516
517bool Connection::waitForIncomingTask(int ms)
518{
519 if (!isConnected())
520 return false;
521
522 if (d->backend)
523 return d->backend->waitForIncomingTask(ms);
524 return false;
525}
526
527int Connection::read( int* _cmd, QByteArray &data )
528{
529 // if it's still empty, then it's an error
530 if (d->incomingTasks.isEmpty()) {
531 //kWarning() << this << "Task list is empty!";
532 return -1;
533 }
534 const Task task = d->incomingTasks.dequeue();
535 //kDebug() << this << "Command " << task.cmd << " removed from the queue (size "
536 // << task.data.size() << ")";
537 *_cmd = task.cmd;
538 data = task.data;
539
540 // if we didn't empty our reading queue, emit again
541 if (!d->suspended && !d->incomingTasks.isEmpty())
542 QMetaObject::invokeMethod(this, "dequeue", Qt::QueuedConnection);
543
544 return data.size();
545}
546
547ConnectionServer::ConnectionServer(QObject *parent)
548 : QObject(parent), d(new ConnectionServerPrivate)
549{
550 d->q = this;
551}
552
553ConnectionServer::~ConnectionServer()
554{
555 delete d;
556}
557
558void ConnectionServer::listenForRemote()
559{
560#ifdef Q_WS_WIN
561 d->backend = new SocketConnectionBackend(SocketConnectionBackend::TcpSocketMode, this);
562#else
563 d->backend = new SocketConnectionBackend(SocketConnectionBackend::LocalSocketMode, this);
564#endif
565 if (!d->backend->listenForRemote()) {
566 delete d->backend;
567 d->backend = 0;
568 return;
569 }
570
571 connect(d->backend, SIGNAL(newConnection()), SIGNAL(newConnection()));
572 kDebug(7017) << "Listening on " << d->backend->address;
573}
574
575QString ConnectionServer::address() const
576{
577 if (d->backend)
578 return d->backend->address;
579 return QString();
580}
581
582bool ConnectionServer::isListening() const
583{
584 return d->backend && d->backend->state == AbstractConnectionBackend::Listening;
585}
586
587void ConnectionServer::close()
588{
589 delete d->backend;
590 d->backend = 0;
591}
592
593Connection *ConnectionServer::nextPendingConnection()
594{
595 if (!isListening())
596 return 0;
597
598 AbstractConnectionBackend *newBackend = d->backend->nextPendingConnection();
599 if (!newBackend)
600 return 0; // no new backend...
601
602 Connection *result = new Connection;
603 result->d->setBackend(newBackend);
604 newBackend->setParent(result);
605
606 return result;
607}
608
609void ConnectionServer::setNextPendingConnection(Connection *conn)
610{
611 AbstractConnectionBackend *newBackend = d->backend->nextPendingConnection();
612 Q_ASSERT(newBackend);
613
614 conn->d->backend = newBackend;
615 conn->d->setBackend(newBackend);
616 newBackend->setParent(conn);
617
618 conn->d->dequeue();
619}
620
621#include "connection_p.moc"
622#include "connection.moc"
KIO::AbstractConnectionBackend
Definition: connection_p.h:35
KIO::AbstractConnectionBackend::nextPendingConnection
virtual AbstractConnectionBackend * nextPendingConnection()=0
KIO::AbstractConnectionBackend::state
enum KIO::AbstractConnectionBackend::@0 state
KIO::AbstractConnectionBackend::errorString
QString errorString
Definition: connection_p.h:39
KIO::AbstractConnectionBackend::address
QString address
Definition: connection_p.h:38
KIO::AbstractConnectionBackend::commandReceived
void commandReceived(const Task &task)
KIO::AbstractConnectionBackend::disconnected
void disconnected()
KIO::AbstractConnectionBackend::newConnection
void newConnection()
KIO::AbstractConnectionBackend::~AbstractConnectionBackend
~AbstractConnectionBackend()
Definition: connection.cpp:114
KIO::AbstractConnectionBackend::setSuspended
virtual void setSuspended(bool enable)=0
KIO::AbstractConnectionBackend::Connected
@ Connected
Definition: connection_p.h:40
KIO::AbstractConnectionBackend::Idle
@ Idle
Definition: connection_p.h:40
KIO::AbstractConnectionBackend::Listening
@ Listening
Definition: connection_p.h:40
KIO::AbstractConnectionBackend::AbstractConnectionBackend
AbstractConnectionBackend(QObject *parent=0)
Definition: connection.cpp:109
KIO::SocketConnectionBackend
Definition: connection_p.h:59
KIO::SocketConnectionBackend::~SocketConnectionBackend
~SocketConnectionBackend()
Definition: connection.cpp:126
KIO::SocketConnectionBackend::connectToRemote
bool connectToRemote(const KUrl &url)
Definition: connection.cpp:160
KIO::SocketConnectionBackend::SocketConnectionBackend
SocketConnectionBackend(Mode m, QObject *parent=0)
Definition: connection.cpp:118
KIO::SocketConnectionBackend::localServer
KLocalSocketServer * localServer
Definition: connection_p.h:69
KIO::SocketConnectionBackend::listenForRemote
bool listenForRemote()
Definition: connection.cpp:200
KIO::SocketConnectionBackend::Mode
Mode
Definition: connection_p.h:62
KIO::SocketConnectionBackend::TcpSocketMode
@ TcpSocketMode
Definition: connection_p.h:62
KIO::SocketConnectionBackend::LocalSocketMode
@ LocalSocketMode
Definition: connection_p.h:62
KIO::SocketConnectionBackend::setSuspended
void setSuspended(bool enable)
Definition: connection.cpp:133
KIO::SocketConnectionBackend::waitForIncomingTask
bool waitForIncomingTask(int ms)
Definition: connection.cpp:251
KIO::SocketConnectionBackend::socketDisconnected
void socketDisconnected()
Definition: connection.cpp:194
KIO::SocketConnectionBackend::nextPendingConnection
AbstractConnectionBackend * nextPendingConnection()
Definition: connection.cpp:303
KIO::SocketConnectionBackend::tcpServer
QTcpServer * tcpServer
Definition: connection_p.h:70
KIO::SocketConnectionBackend::socketReadyRead
void socketReadyRead()
Definition: connection.cpp:329
KIO::SocketConnectionBackend::sendCommand
bool sendCommand(const Task &task)
Definition: connection.cpp:282
KLocalSocketServer
KLocalSocketServer::localSocketType
KLocalSocket::LocalSocketType localSocketType() const
KLocalSocketServer::errorString
QString errorString() const
KLocalSocketServer::listen
bool listen(const QString &path, KLocalSocket::LocalSocketType type=KLocalSocket::UnixSocket)
KLocalSocketServer::localPath
QString localPath() const
KLocalSocketServer::nextPendingConnection
virtual KLocalSocket * nextPendingConnection()
KLocalSocket
KLocalSocket::LocalSocketType
LocalSocketType
KLocalSocket::AbstractUnixSocket
AbstractUnixSocket
KLocalSocket::UnixSocket
UnixSocket
KLocalSocket::connectToPath
void connectToPath(const QString &path, LocalSocketType type, OpenMode mode=ReadWrite)
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, bool createDir, const KComponentData &cData=KGlobal::mainComponent())
KTemporaryFile
KTemporaryFile::setPrefix
void setPrefix(const QString &prefix)
KTemporaryFile::setSuffix
void setSuffix(const QString &suffix)
KUrl
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::setProtocol
void setProtocol(const QString &proto)
KUrl::protocol
QString protocol() const
KUrl::queryItem
QString queryItem(const QString &item) const
QObject
QTcpSocket
connection.h
connection_p.h
kDebug
#define kDebug
kWarning
#define kWarning
kcomponentdata.h
kdebug.h
kglobal.h
klocale.h
i18n
QString i18n(const char *text)
kstandarddirs.h
prefix
QString prefix()
ktemporaryfile.h
kurl.h
KGlobal::mainComponent
const KComponentData & mainComponent()
KIO
A namespace for KIO globals.
Definition: kbookmarkmenu.h:55
close
KAction * close(const QObject *recvr, const char *slot, QObject *parent)
KIO::Task
Definition: connection_p.h:29
KIO::Task::data
QByteArray data
Definition: connection_p.h:31
KIO::Task::cmd
int cmd
Definition: connection_p.h:30
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal