root/trunk/qt4-gui/src/dialogs/plugindlg.cpp

Revision 6048, 12.0 kB (checked in by erijo, 10 months ago)

Enable KDE4 support.

  • Property svn:eol-style set to native
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of Licq, an instant messaging client for UNIX.
4 * Copyright (C) 1999-2006 Licq developers
5 *
6 * Licq is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Licq 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Licq; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 */
20
21#include "plugindlg.h"
22
23#include "config.h"
24
25#include <algorithm>
26#include <list>
27#include <string>
28
29#include <QDialogButtonBox>
30#include <QDir>
31#include <QString>
32#include <QStringList>
33#include <QTimer>
34#include <QGroupBox>
35#include <QHBoxLayout>
36#include <QHeaderView>
37#include <QPushButton>
38#include <QTableWidget>
39#include <QVBoxLayout>
40
41#include <licq_icqd.h>
42
43#include "core/mainwin.h"
44#include "core/messagebox.h"
45
46#include "helpers/support.h"
47
48#include "editfiledlg.h"
49
50using std::string;
51using std::list;
52using std::find;
53using namespace LicqQtGui;
54/* TRANSLATOR LicqQtGui::PluginDlg */
55
56PluginDlg* PluginDlg::myInstance = NULL;
57
58void PluginDlg::showPluginDlg()
59{
60  if (myInstance == NULL)
61    myInstance = new PluginDlg();
62  else
63    myInstance->raise();
64}
65
66PluginDlg::PluginDlg()
67{
68  Support::setWidgetProps(this, "PluginDialog");
69  setWindowTitle(tr("Plugin Manager"));
70  setAttribute(Qt::WA_DeleteOnClose, true);
71
72  QGroupBox* boxStandard = new QGroupBox(tr("Standard Plugins"));
73  QVBoxLayout* layStandard = new QVBoxLayout(boxStandard);
74
75  tblStandard = new QTableWidget(0, 6);
76  tblStandard->setSelectionMode(QTableWidget::NoSelection);
77  tblStandard->setShowGrid(false);
78  tblStandard->setEditTriggers(QTableWidget::NoEditTriggers);
79  tblStandard->setMinimumHeight(100);
80  layStandard->addWidget(tblStandard);
81
82  QStringList headStdLabels;
83  headStdLabels << tr("Id") << tr("Name") << tr("Version") << tr("Load") << tr("Enable") << tr("Description");
84  tblStandard->setHorizontalHeaderLabels(headStdLabels);
85  tblStandard->verticalHeader()->hide();
86  tblStandard->setWordWrap(false);
87
88  QGroupBox* boxProtocol = new QGroupBox(tr("Protocol Plugins"), this);
89  QVBoxLayout* layProtocol = new QVBoxLayout(boxProtocol);
90
91  tblProtocol = new QTableWidget(0, 5);
92  tblProtocol->setSelectionMode(QTableWidget::NoSelection);
93  tblProtocol->setShowGrid(false);
94  tblProtocol->setEditTriggers(QTableWidget::NoEditTriggers);
95  tblProtocol->setMinimumHeight(100);
96  layProtocol->addWidget(tblProtocol);
97
98  QStringList headProtoLabels;
99  headProtoLabels << tr("Id") << tr("Name") << tr("Version") << tr("Load") << tr("Description");
100  tblProtocol->setHorizontalHeaderLabels(headProtoLabels);
101  tblProtocol->verticalHeader()->hide();
102  tblProtocol->setWordWrap(false);
103
104  // Connect all the signals now
105  connect(tblProtocol, SIGNAL(itemChanged(QTableWidgetItem*)), SLOT(slot_protocol(QTableWidgetItem*)));
106  connect(tblStandard, SIGNAL(itemChanged(QTableWidgetItem*)), SLOT(slot_standard(QTableWidgetItem*)));
107  connect(tblStandard, SIGNAL(cellDoubleClicked(int, int)), SLOT(slot_stdConfig(int, int)));
108
109  QDialogButtonBox* buttons = new QDialogButtonBox();
110
111  QPushButton* btnRefresh = new QPushButton(tr("Refresh"));
112  buttons->addButton(btnRefresh, QDialogButtonBox::ActionRole);
113  connect(btnRefresh, SIGNAL(clicked()), SLOT(slot_refresh()));
114
115  QPushButton* btnDone = new QPushButton(tr("Done"));
116  buttons->addButton(btnDone, QDialogButtonBox::RejectRole);
117  connect(btnDone, SIGNAL(clicked()), SLOT(close()));
118
119  QVBoxLayout* layWindow = new QVBoxLayout(this);
120  layWindow->addWidget(boxStandard);
121  layWindow->addWidget(boxProtocol);
122  layWindow->addWidget(buttons);
123
124  slot_refresh();
125
126  resize(500, 400);
127
128  show();
129}
130
131PluginDlg::~PluginDlg()
132{
133  myInstance = NULL;
134}
135
136
137void PluginDlg::slot_standard(QTableWidgetItem* item)
138{
139  // Signal can be raised for multiple reasons so first check if this is cell with a checkbox.
140  // Also, if it is a checkbox but is not added to the list, it is also a signal that should be ignored.
141  if(mapCheckboxCache.contains(item) == false)
142    return;
143
144  // Next check that the state has actually changed
145  bool state = (item->checkState() == Qt::Checked);
146  if(state == mapCheckboxCache[item])
147    return;
148
149  int nRow = tblStandard->row(item);
150  int nCol = tblStandard->column(item);
151  int index = tblStandard->item(nRow, 0)->text().toInt();
152
153  if (nCol == 3)
154  {
155    //Load or Unload
156    if (state == true)
157    {
158      char* sz[] = { strdup("licq"), NULL };
159      QString plugin = tblStandard->item(nRow, 1)->text();
160      gLicqDaemon->PluginLoad(plugin.toLatin1(), 1, sz);
161      free(sz[0]);
162    }
163    else
164    {
165      gLicqDaemon->PluginShutdown(index);
166    }
167  }
168  else if (nCol == 4)
169  {
170    //Enable or Disable
171    if (state == true)
172      gLicqDaemon->PluginEnable(index);
173    else
174      gLicqDaemon->PluginDisable(index);
175  }
176
177  // Update cached state
178  mapCheckboxCache[item] = state;
179
180  // Schedule an update of the plugin list
181  QTimer::singleShot(1000, this, SLOT(slot_refresh()));
182}
183
184
185void PluginDlg::slot_protocol(QTableWidgetItem* item)
186{
187  // Signal can be raised for multiple reasons so first check if this is cell with a checkbox.
188  // Also, if it is a checkbox but is not added to the list, it is also a signal that should be ignored.
189  if(mapCheckboxCache.contains(item) == false)
190    return;
191
192  // Next check that the state has actually changed
193  bool state = (item->checkState() == Qt::Checked);
194  if(state == mapCheckboxCache[item])
195    return;
196
197  int nRow = tblProtocol->row(item);
198  int nCol = tblProtocol->column(item);
199  int index = tblProtocol->item(nRow, 0)->text().toInt();
200
201  if (nCol == 3)
202  {
203    //Load or Unload
204    if (state == true)
205    {
206      QString plugin = tblProtocol->item(nRow, 1)->text();
207      gLicqDaemon->ProtoPluginLoad(plugin.toLatin1());
208    }
209    else
210    {
211      unsigned long nPPID = 0;
212      ProtoPluginsList l;
213      ProtoPluginsListIter it;
214      gLicqDaemon->ProtoPluginList(l);
215      for (it = l.begin(); it != l.end(); it++)
216      {
217        if ((*it)->Id() == index)
218        {
219          nPPID = (*it)->PPID();
220          break;
221        }
222      }
223
224      // Daemon doesn't notify when plugins are unloaded
225      // so tell mainwin directly from here
226      gMainWindow->slot_pluginUnloaded(nPPID);
227
228      gLicqDaemon->ProtoPluginShutdown(index);
229    }
230  }
231
232  // Update cached state
233  mapCheckboxCache[item] = state;
234
235  // Schedule an update of the plugin list
236  QTimer::singleShot(1000, this, SLOT(slot_refresh()));
237}
238
239void PluginDlg::slot_stdConfig(int nRow, int /* nCol */)
240{
241  int pluginIndex = tblStandard->item(nRow, 0)->text().toUShort();
242
243  PluginsList l;
244  PluginsListIter it;
245  gLicqDaemon->PluginList(l);
246  for (it = l.begin(); it != l.end(); it++)
247  {
248    if ((*it)->Id() == pluginIndex)
249      break;
250  }
251  if (it == l.end()) return;
252
253  if ((*it)->ConfigFile() == NULL)
254  {
255    InformUser(this, tr("Plugin %1 has no configuration file").arg((*it)->Name()));
256    return;
257  }
258
259  QString f;
260  f.sprintf("%s%s", BASE_DIR, (*it)->ConfigFile());
261  new EditFileDlg(f);
262}
263
264void PluginDlg::slot_refresh()
265{
266  // Clear the tables
267  tblStandard->clearContents();
268  tblStandard->setRowCount(0);
269  tblProtocol->clearContents();
270  tblProtocol->setRowCount(0);
271  mapCheckboxCache.clear();
272
273  list< string > lLoadedSPlugins;
274  list< string > lLoadedPPlugins;
275
276  // Load up the standard loaded plugin info
277  PluginsList l;
278  PluginsListIter it;
279  int i = 0;
280  gLicqDaemon->PluginList(l);
281  for (it = l.begin(); it != l.end(); it++)
282  {
283    lLoadedSPlugins.push_back((*it)->LibName());
284
285    tblStandard->setRowCount(i+1);
286    tblStandard->setItem(i, 0, new QTableWidgetItem(QString::number(static_cast<int>((*it)->Id()))));
287    tblStandard->setItem(i, 1, new QTableWidgetItem(QString((*it)->Name())));
288    tblStandard->setItem(i, 2, new QTableWidgetItem(QString((*it)->Version())));
289    QTableWidgetItem* chkLoad = new QTableWidgetItem("");
290    chkLoad->setFlags(chkLoad->flags() | Qt::ItemIsUserCheckable);
291    QTableWidgetItem* chkEnable = new QTableWidgetItem("");
292    chkEnable->setFlags(chkLoad->flags() | Qt::ItemIsUserCheckable);
293    chkLoad->setCheckState(Qt::Checked);
294    QString strStatus((*it)->Status());
295    bool bEnabled = (strStatus.indexOf("enable", 0, Qt::CaseInsensitive) != -1) ||
296                    (strStatus.indexOf("running", 0, Qt::CaseInsensitive) != -1);
297    chkEnable->setCheckState((bEnabled ? Qt::Checked : Qt::Unchecked));
298    tblStandard->setItem(i, 3, chkLoad);
299    tblStandard->setItem(i, 4, chkEnable);
300    tblStandard->setItem(i, 5, new QTableWidgetItem(QString((*it)->Description())));
301    mapCheckboxCache[chkLoad] = true;
302    mapCheckboxCache[chkEnable] = bEnabled;
303    i++;
304  }
305
306  // Load up the standard unloaded plugin info
307  QDir d(LIB_DIR, "licq_*.so", QDir::Name, QDir::Files | QDir::Readable);
308  QStringList s = d.entryList();
309  QStringList::Iterator sit;
310  for (sit = s.begin(); sit != s.end(); sit++)
311  {
312    (*sit).remove(0, 5);
313    (*sit).truncate((*sit).length() - 3);
314    if (::find(lLoadedSPlugins.begin(), lLoadedSPlugins.end(),
315               (*sit).toAscii().constData()) != lLoadedSPlugins.end())
316      continue;
317
318    tblStandard->setRowCount(i+1);
319    tblStandard->setItem(i, 0, new QTableWidgetItem("*"));
320    tblStandard->setItem(i, 1, new QTableWidgetItem(*sit));
321    tblStandard->setItem(i, 2, new QTableWidgetItem(""));
322    QTableWidgetItem* chkLoad = new QTableWidgetItem("");
323    chkLoad->setFlags(chkLoad->flags() | Qt::ItemIsUserCheckable);
324    chkLoad->setCheckState(Qt::Unchecked);
325    QTableWidgetItem* chkEnable = new QTableWidgetItem("");
326    chkEnable->setFlags(chkLoad->flags() | Qt::ItemIsUserCheckable);
327    chkEnable->setCheckState(Qt::Unchecked);
328    tblStandard->setItem(i, 3, chkLoad);
329    tblStandard->setItem(i, 4, chkEnable);
330    tblStandard->setItem(i, 5, new QTableWidgetItem(tr("(Unloaded)")));
331    mapCheckboxCache[chkLoad] = false;
332    mapCheckboxCache[chkEnable] = false;
333    i++;
334  }
335
336  // Load up the protocol plugin info now
337  ProtoPluginsList p_l;
338  ProtoPluginsListIter p_it;
339  i = 0;
340  gLicqDaemon->ProtoPluginList(p_l);
341  for (p_it = p_l.begin(); p_it != p_l.end(); p_it++)
342  {
343    lLoadedPPlugins.push_back((*p_it)->LibName());
344    if (strcmp((*p_it)->Name(), "Licq") == 0)
345      continue;
346
347    tblProtocol->setRowCount(i+1);
348    tblProtocol->setItem(i, 0, new QTableWidgetItem(QString::number(static_cast<int>((*p_it)->Id()))));
349    tblProtocol->setItem(i, 1, new QTableWidgetItem(QString((*p_it)->Name())));
350    tblProtocol->setItem(i, 2, new QTableWidgetItem(QString((*p_it)->Version())));
351    QTableWidgetItem* chkLoad = new QTableWidgetItem("");
352    chkLoad->setFlags(chkLoad->flags() | Qt::ItemIsUserCheckable);
353    chkLoad->setCheckState(Qt::Checked);
354    tblProtocol->setItem(i, 3, chkLoad);
355    tblProtocol->setItem(i, 4, new QTableWidgetItem(""));
356    mapCheckboxCache[chkLoad] = true;
357    i++;
358  }
359
360  QDir d2(LIB_DIR, "protocol_*.so", QDir::Name, QDir::Files | QDir::Readable);
361  s = d2.entryList();
362  for (sit = s.begin(); sit != s.end(); sit++)
363  {
364    (*sit).remove(0, 9);
365    (*sit).truncate((*sit).length() - 3);
366    if (::find(lLoadedPPlugins.begin(), lLoadedPPlugins.end(),
367               (*sit).toAscii().constData()) != lLoadedPPlugins.end())
368      continue;
369
370    tblProtocol->setRowCount(i+1);
371    tblProtocol->setItem(i, 0, new QTableWidgetItem("*"));
372    tblProtocol->setItem(i, 1, new QTableWidgetItem(*sit));
373    tblProtocol->setItem(i, 2, new QTableWidgetItem(""));
374    QTableWidgetItem* chkLoad = new QTableWidgetItem("");
375    chkLoad->setFlags(chkLoad->flags() | Qt::ItemIsUserCheckable);
376    chkLoad->setCheckState(Qt::Unchecked);
377    tblProtocol->setItem(i, 3, chkLoad);
378    tblProtocol->setItem(i, 4, new QTableWidgetItem(tr("(Unloaded)")));
379    mapCheckboxCache[chkLoad] = false;
380    i++;
381  }
382
383  tblStandard->resizeRowsToContents();
384  tblProtocol->resizeRowsToContents();
385
386  tblStandard->resizeColumnsToContents();
387  tblProtocol->resizeColumnsToContents();
388}
Note: See TracBrowser for help on using the browser.