~ubuntu-branches/ubuntu/gutsy/kdebase-workspace/gutsy-backports

« back to all changes in this revision

Viewing changes to kicker/menuext/konsole/konsole_mnu.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2007-09-05 20:45:14 UTC
  • Revision ID: james.westby@ubuntu.com-20070905204514-632hhspl0nvrc84i
Tags: upstream-3.93.0
ImportĀ upstreamĀ versionĀ 3.93.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************
 
2
 
 
3
Copyright (c) 1996-2001 the kicker authors. See file AUTHORS.
 
4
 
 
5
Permission is hereby granted, free of charge, to any person obtaining a copy
 
6
of this software and associated documentation files (the "Software"), to deal
 
7
in the Software without restriction, including without limitation the rights
 
8
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
9
copies of the Software, and to permit persons to whom the Software is
 
10
furnished to do so, subject to the following conditions:
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
18
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 
 
22
******************************************************************/
 
23
 
 
24
#include <stdlib.h>
 
25
#include <dirent.h>
 
26
#include <fcntl.h>
 
27
#include <unistd.h>
 
28
#include <sys/stat.h>
 
29
 
 
30
#include <QDir>
 
31
#include <QFileInfo>
 
32
 
 
33
#include <kapplication.h>
 
34
#include <kglobal.h>
 
35
#include <kicon.h>
 
36
#include <kiconloader.h>
 
37
#include <kio/global.h>
 
38
#include <klocale.h>
 
39
#include <krun.h>
 
40
#include <kshell.h>
 
41
#include <kconfig.h>
 
42
#include <kdesktopfile.h>
 
43
#include <kstandarddirs.h>
 
44
#include <ktoolinvocation.h>
 
45
#include <kworkspace.h>
 
46
#include "konsole_mnu.h"
 
47
 
 
48
extern "C"
 
49
{
 
50
    KDE_EXPORT void* init_kickermenu_konsole()
 
51
    {
 
52
        KGlobal::locale()->insertCatalog("libkickermenu_konsole");
 
53
        return new KonsoleMenuFactory;
 
54
    }
 
55
}
 
56
 
 
57
KonsoleMenu::KonsoleMenu(QWidget *parent)
 
58
    : KPanelMenu("", parent),
 
59
      m_profileMenu(0),
 
60
      m_bookmarksSession(0),
 
61
      m_bookmarkHandlerSession(0)
 
62
{
 
63
}
 
64
 
 
65
KonsoleMenu::~KonsoleMenu()
 
66
{
 
67
    KGlobal::locale()->removeCatalog("libkickermenu_konsole");
 
68
}
 
69
 
 
70
static void insertItemSorted(KMenu *menu,
 
71
                             const QIcon &iconSet,
 
72
                             const QString &txt, int id)
 
73
{
 
74
  const int defaultId = 1; // The id of the 'new' item.
 
75
  int index = menu->indexOf(defaultId);
 
76
  int count = menu->actions().count();
 
77
  if (index >= 0)
 
78
  {
 
79
     index++; // Skip separator
 
80
     while(true)
 
81
     {
 
82
        index++;
 
83
        if (index >= count)
 
84
        {
 
85
           index = -1; // Insert at end
 
86
           break;
 
87
        }
 
88
        if (menu->text(menu->idAt(index)) > txt)
 
89
           break; // Insert before this item
 
90
     }
 
91
  }
 
92
  menu->insertItem(iconSet, txt, id, index);
 
93
}
 
94
 
 
95
 
 
96
void KonsoleMenu::initialize()
 
97
{
 
98
    if (initialized())
 
99
    {
 
100
        clear();
 
101
    }
 
102
 
 
103
    setInitialized(true);
 
104
 
 
105
    QStringList list = KGlobal::dirs()->findAllResources("data",
 
106
                                                         "konsole/*.desktop",
 
107
                                                         KStandardDirs::NoDuplicates);
 
108
 
 
109
    QString defaultShell = KStandardDirs::locate("data", "konsole/shell.desktop");
 
110
    list.prepend(defaultShell);
 
111
 
 
112
    int id = 1;
 
113
 
 
114
    sessionList.clear();
 
115
    for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
 
116
    {
 
117
        if ((*it == defaultShell) && (id != 1))
 
118
        {
 
119
           continue;
 
120
        }
 
121
 
 
122
        KDesktopFile conf(*it);
 
123
        const KConfigGroup cg = conf.desktopGroup();
 
124
        QString text = cg.readEntry("Name");
 
125
 
 
126
        // try to locate the binary
 
127
        QString exec= cg.readPathEntry("Exec");
 
128
        if (exec.startsWith("su -c \'"))
 
129
        {
 
130
             exec = exec.mid(7,exec.length()-8);
 
131
        }
 
132
 
 
133
        exec = KRun::binaryName(exec, false);
 
134
        exec = KShell::tildeExpand(exec);
 
135
        QString pexec = KGlobal::dirs()->findExe(exec);
 
136
        if (text.isEmpty() ||
 
137
            cg.readEntry("Type") != "KonsoleApplication" ||
 
138
            (!exec.isEmpty() && pexec.isEmpty()))
 
139
        {
 
140
            continue;
 
141
        }
 
142
        insertItemSorted(this, KIcon(cg.readEntry("Icon", "konsole")),
 
143
                                            text, id++);
 
144
        QFileInfo fi(*it);
 
145
        sessionList.append(fi.completeBaseName());
 
146
 
 
147
        if (id == 2)
 
148
        {
 
149
           addSeparator();
 
150
        }
 
151
    }
 
152
 
 
153
    m_bookmarkHandlerSession = new KonsoleBookmarkHandler(this, false);
 
154
    m_bookmarksSession = m_bookmarkHandlerSession->menu();
 
155
    addSeparator();
 
156
    insertItem(KIcon("keditbookmarks"),
 
157
               i18n("New Session at Bookmark"), m_bookmarksSession);
 
158
    connect(m_bookmarkHandlerSession,
 
159
            SIGNAL(openUrl(const QString&, const QString&)),
 
160
            SLOT(newSession(const QString&, const QString&)));
 
161
 
 
162
 
 
163
    screenList.clear();
 
164
    QByteArray screenDir = getenv("SCREENDIR");
 
165
 
 
166
    if (screenDir.isEmpty())
 
167
    {
 
168
        screenDir = QFile::encodeName(QDir::homePath()) + "/.screen/";
 
169
    }
 
170
 
 
171
    QStringList sessions;
 
172
    // Can't use QDir as it doesn't support FIFOs :(
 
173
    DIR *dir = opendir(screenDir);
 
174
    if (dir)
 
175
    {
 
176
        struct dirent *entry;
 
177
        while ((entry = readdir(dir)))
 
178
        {
 
179
            QByteArray path = screenDir + '/' + QByteArray(entry->d_name);
 
180
            struct stat st;
 
181
            if (stat(path, &st) != 0)
 
182
            {
 
183
                continue;
 
184
            }
 
185
 
 
186
            int fd;
 
187
            if (S_ISFIFO(st.st_mode) && !(st.st_mode & 0111) && // xbit == attached
 
188
                (fd = open(path, O_WRONLY | O_NONBLOCK)) != -1)
 
189
            {
 
190
                ::close(fd);
 
191
                screenList.append(QFile::decodeName(entry->d_name));
 
192
                insertItem(KIcon("konsole"),
 
193
                           i18nc("Screen is a program for controlling screens",
 
194
                                "Screen at %1", entry->d_name), id);
 
195
                id++;
 
196
            }
 
197
        }
 
198
        closedir(dir);
 
199
    }
 
200
 
 
201
    // reset id as we are now going to populate the profiles submenu
 
202
    id = 0;
 
203
 
 
204
    delete m_profileMenu;
 
205
    m_profileMenu = new KMenu(this);
 
206
    QStringList profiles = KGlobal::dirs()->findAllResources("data",
 
207
                                                             "konsole/profiles/*",
 
208
                                                             KStandardDirs::NoDuplicates);
 
209
    m_profiles.resize(profiles.count());
 
210
    QStringList::ConstIterator pEnd = profiles.end();
 
211
    for (QStringList::ConstIterator pIt = profiles.begin(); pIt != pEnd; ++pIt)
 
212
    {
 
213
        QFileInfo info(*pIt);
 
214
        QString profileName = KIO::decodeFileName(info.baseName());
 
215
        QString niceName = profileName;
 
216
        KConfig cfg(*pIt, KConfig::OnlyLocal);
 
217
        if (cfg.hasGroup("Profile"))
 
218
        {
 
219
            const KConfigGroup cg( &cfg, "Profile" );
 
220
            if (cg.hasKey("Name"))
 
221
            {
 
222
                niceName = cg.readEntry("Name");
 
223
            }
 
224
        }
 
225
 
 
226
        m_profiles[id] = profileName;
 
227
        ++id;
 
228
        m_profileMenu->insertItem(niceName, id);
 
229
    }
 
230
 
 
231
    int profileID = insertItem(i18n("New Session Using Profile"),
 
232
                               m_profileMenu);
 
233
    if (id == 1)
 
234
    {
 
235
        // we don't have any profiles, disable the menu
 
236
        setItemEnabled(profileID, false);
 
237
    }
 
238
    connect(m_profileMenu, SIGNAL(activated(int)), SLOT(launchProfile(int)));
 
239
 
 
240
    addSeparator();
 
241
    insertItem(KIcon("view-refresh"),
 
242
               i18n("Reload Sessions"), this, SLOT(reinitialize()));
 
243
}
 
244
 
 
245
void KonsoleMenu::slotExec(int id)
 
246
{
 
247
    if (id < 1)
 
248
    {
 
249
        return;
 
250
    }
 
251
 
 
252
    --id;
 
253
    KWorkSpace::propagateSessionManager();
 
254
    QStringList args;
 
255
    if (id < sessionList.count())
 
256
    {
 
257
        args << "--type";
 
258
        args << sessionList[id];
 
259
    }
 
260
    else
 
261
    {
 
262
        args << "-e";
 
263
        args << "screen";
 
264
        args << "-r";
 
265
        args << screenList[id - sessionList.count()];
 
266
    }
 
267
    KToolInvocation::kdeinitExec("konsole", args);
 
268
    return;
 
269
}
 
270
 
 
271
void KonsoleMenu::launchProfile(int id)
 
272
{
 
273
    if (id < 1 || id > m_profiles.count())
 
274
    {
 
275
        return;
 
276
    }
 
277
 
 
278
    --id;
 
279
    // this is a session, not a bookmark, so execute that instead
 
280
   QStringList args;
 
281
   args << "--profile" << m_profiles[id];
 
282
   KToolInvocation::kdeinitExec("konsole", args);
 
283
}
 
284
 
 
285
KUrl KonsoleMenu::baseURL() const
 
286
{
 
287
    KUrl url;
 
288
    /*url.setPath(se->getCwd()+'/');*/
 
289
    return url;
 
290
}
 
291
 
 
292
void KonsoleMenu::newSession(const QString& sURL, const QString& title)
 
293
{
 
294
    QStringList args;
 
295
 
 
296
    KUrl url = KUrl(sURL);
 
297
    if ((url.protocol() == "file") && (url.hasPath()))
 
298
    {
 
299
        args << "-T" << title;
 
300
        args << "--workdir" << url.path();
 
301
        KToolInvocation::kdeinitExec("konsole", args);
 
302
        return;
 
303
    }
 
304
    else if ((!url.protocol().isEmpty()) && (url.hasHost()))
 
305
    {
 
306
        QString protocol = url.protocol();
 
307
        QString host = url.host();
 
308
        args << "-T" << title;
 
309
        args << "-e" << protocol.toLatin1(); /* argv[0] == command to run. */
 
310
        if (url.hasUser()) {
 
311
            args << "-l" << url.user().toLatin1();
 
312
        }
 
313
        args << host.toLatin1();
 
314
        KToolInvocation::kdeinitExec("konsole", args);
 
315
        return;
 
316
    }
 
317
    /*
 
318
     * We can't create a session without a protocol.
 
319
     * We should ideally popup a warning, about an invalid bookmark.
 
320
     */
 
321
}
 
322
 
 
323
 
 
324
//*****************************************************************
 
325
 
 
326
KonsoleMenuFactory::KonsoleMenuFactory(QObject *parent, const char *name)
 
327
: KLibFactory(parent)
 
328
{
 
329
    setObjectName(name);
 
330
    KIconLoader::global()->addAppDir("konsole");
 
331
    KGlobal::locale()->insertCatalog("konsolemenuapplet");
 
332
}
 
333
 
 
334
QObject* KonsoleMenuFactory::createObject(QObject *parent, const char*, const QStringList&)
 
335
{
 
336
    return new KonsoleMenu((QWidget*)parent);
 
337
}
 
338
 
 
339
#include "konsole_mnu.moc"