[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    =?utf-8?q?=5Bnetworkmanagement=5D_/=3A_Try_to_unlock_=28PIN/PUK?=
From:       "Lamarque V.Souza" <lamarque () gmail ! com>
Date:       2011-05-01 1:18:08
Message-ID: 20110501011808.A25BFA60A6 () git ! kde ! org
[Download RAW message or body]

Git commit 835c65da3ac5ee01fa2b5cf2387e2650440a4b89 by Lamarque V. Souza.
Committed on 01/05/2011 at 03:01.
Pushed by lvsouza into branch 'master'.

Try to unlock (PIN/PUK) and enable modem before connecting to Gsm
connections.

BUG: 264083

M  +20   -0    backends/NetworkManager/nmdbussettingsservice.cpp     
M  +2    -0    libs/internals/CMakeLists.txt     
M  +7    -0    libs/service/CMakeLists.txt     
M  +97   -1    libs/service/networkinterfacemonitor.cpp     
M  +11   -0    libs/service/networkinterfacemonitor.h     
A  +110  -0    libs/service/pindialog.cpp         [License: GPL]
A  +58   -0    libs/service/pindialog.h         [License: GPL]
A  +201  -0    libs/service/pinwidget.ui         [License: UNKNOWN]  *

The files marked with a * at the end have a non valid license. Please read: \
http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are \
listed at that page.


http://commits.kde.org/networkmanagement/835c65da3ac5ee01fa2b5cf2387e2650440a4b89

diff --git a/backends/NetworkManager/nmdbussettingsservice.cpp \
b/backends/NetworkManager/nmdbussettingsservice.cpp index 4dda4de..6d12abf 100644
--- a/backends/NetworkManager/nmdbussettingsservice.cpp
+++ b/backends/NetworkManager/nmdbussettingsservice.cpp
@@ -41,6 +41,11 @@ License along with this library.  If not, see \
<http://www.gnu.org/licenses/>.  #include <interfaceconnection.h>
 #include <vpninterfaceconnection.h>
 
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+#include <solid/control/networkgsminterface.h>
+#include <solid/control/modeminterface.h>
+#endif
+
 #include "busconnection.h"
 #include "exportedconnection.h"
 #include "exportedconnectionsecrets.h"
@@ -232,6 +237,21 @@ void NMDBusSettingsService::interfaceConnectionActivated()
             deviceToActivateOn = ic->deviceUni();
         }
 
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+        // Enable modem before connecting.
+        Solid::Control::GsmNetworkInterface *iface = \
qobject_cast<Solid::Control::GsmNetworkInterface \
*>(Solid::Control::NetworkManager::findNetworkInterface(deviceToActivateOn)); +       \
if (iface) { +            Solid::Control::ModemGsmCardInterface *modem = \
iface->getModemCardIface(); +            if (modem && !modem->enabled()) {
+                // Try to pin-unlock the modem.
+                QMetaObject::invokeMethod(modem, "unlockRequiredChanged", \
Qt::DirectConnection, +                                          Q_ARG(QString, \
modem->unlockRequired())); +                kDebug() << "Trying to enable modem";
+                modem->enable(true);
+            }
+        }
+#endif
+
         Solid::Control::NetworkManager::activateConnection(deviceToActivateOn,
                 QString::fromLatin1("%1 %2")
                 .arg(ic->property("NMDBusService").toString(), \
                ic->property("NMDBusObjectPath").toString()),
diff --git a/libs/internals/CMakeLists.txt b/libs/internals/CMakeLists.txt
index d00c980..709acdd 100644
--- a/libs/internals/CMakeLists.txt
+++ b/libs/internals/CMakeLists.txt
@@ -5,6 +5,8 @@ include_directories(
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/../../solidcontrolfuture
    ${CMAKE_CURRENT_SOURCE_DIR}/../libs/client
+   ${CMAKE_CURRENT_SOURCE_DIR}/../../backends/NetworkManager
+   ${CMAKE_CURRENT_SOURCE_DIR}/../../libs
    )
 
 ## next target: internals layer library
diff --git a/libs/service/CMakeLists.txt b/libs/service/CMakeLists.txt
index 5a0bc0b..7bd4cc4 100644
--- a/libs/service/CMakeLists.txt
+++ b/libs/service/CMakeLists.txt
@@ -67,8 +67,15 @@ set(knmservice_SRCS
 
    # sort logic for activatables
    sortedactivatablelist.cpp
+
+   # dialog to ask for PIN code
+   pindialog.cpp
    )
 
+kde4_add_ui_files(knmservice_SRCS
+   # Ask for PIN unlock code
+   pinwidget.ui
+)
 
 qt4_add_dbus_adaptor(
     knmservice_SRCS
diff --git a/libs/service/networkinterfacemonitor.cpp \
b/libs/service/networkinterfacemonitor.cpp index fd868ba..e126521 100644
--- a/libs/service/networkinterfacemonitor.cpp
+++ b/libs/service/networkinterfacemonitor.cpp
@@ -20,6 +20,7 @@ License along with this library.  If not, see \
<http://www.gnu.org/licenses/>.  
 #include <KToolInvocation>
 #include <KStandardDirs>
+#include <KLocale>
 
 #include "networkinterfacemonitor.h"
 
@@ -34,7 +35,15 @@ License along with this library.  If not, see \
<http://www.gnu.org/licenses/>.  #include \
"wirelessnetworkinterfaceactivatableprovider.h"  
 #ifdef COMPILE_MODEM_MANAGER_SUPPORT
+#include <KAuth/Action>
+#include <kauthactionreply.h>
+#include <KMessageBox>
+
+#include <solid/control/modeminterface.h>
+#include <solid/control/modemmanager.h>
+
 #include "gsmnetworkinterfaceactivatableprovider.h"
+#include "pindialog.h"
 #endif
 
 class NetworkInterfaceMonitorPrivate
@@ -63,6 +72,17 @@ NetworkInterfaceMonitor::NetworkInterfaceMonitor(ConnectionList * \
                connectionList
     foreach (Solid::Control::NetworkInterface * iface, \
Solid::Control::NetworkManager::networkInterfaces()) {  \
networkInterfaceAdded(iface->uni());  }
+
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+    dialog = 0;
+    QObject::connect(Solid::Control::ModemManager::notifier(),
+            SIGNAL(modemInterfaceAdded(const QString&)),
+            this, SLOT(modemInterfaceAdded(const QString&)));
+
+    foreach (Solid::Control::ModemInterface * iface, \
Solid::Control::ModemManager::modemInterfaces()) { +        \
modemInterfaceAdded(iface->udi()); +    }
+#endif
 }
 
 NetworkInterfaceMonitor::~NetworkInterfaceMonitor()
@@ -88,7 +108,7 @@ void NetworkInterfaceMonitor::networkInterfaceAdded(const QString \
                & uni)
         } else if (iface->type() == Solid::Control::NetworkInterface::Bluetooth) {
             kDebug() << "Bluetooth interface added";
             provider = new GsmNetworkInterfaceActivatableProvider(d->connectionList, \
                d->activatableList, \
                qobject_cast<Solid::Control::GsmNetworkInterface*>(iface), this);
-#endif	    
+#endif
         } else if (iface->type() == Solid::Control::NetworkInterface::Gsm) {
             kDebug() << "Gsm interface added";
             provider = new GsmNetworkInterfaceActivatableProvider(d->connectionList, \
d->activatableList, qobject_cast<Solid::Control::GsmNetworkInterface*>(iface), this); \
@@ -133,4 +153,80 @@ void NetworkInterfaceMonitor::networkInterfaceRemoved(const \
QString & uni)  delete provider;
 }
 
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+void NetworkInterfaceMonitor::modemInterfaceAdded(const QString & udi)
+{
+    Solid::Control::ModemGsmCardInterface * modem = \
qobject_cast<Solid::Control::ModemGsmCardInterface \
*>(Solid::Control::ModemManager::findModemInterface(udi, \
Solid::Control::ModemInterface::GsmCard)); +
+    if (!modem) {
+        return;
+    }
+
+    connect(modem, SIGNAL(unlockRequiredChanged(const QString &)), \
SLOT(requestPin(const QString &))); +
+    if (dialog || modem->unlockRequired().isEmpty()) {
+        return;
+    }
+
+    // Using queued invokation to prevent kded stalling here until user enter the \
pin. +    QMetaObject::invokeMethod(modem, "unlockRequiredChanged", \
Qt::QueuedConnection, +                              Q_ARG(QString, \
modem->unlockRequired())); +}
+
+void NetworkInterfaceMonitor::requestPin(const QString & unlockRequired)
+{
+    kDebug() << "unlockRequired == " << unlockRequired;
+    if (unlockRequired.isEmpty() || unlockRequired == QLatin1String("sim-puk2") ||
+                                    unlockRequired == QLatin1String("sim-pin2")) {
+        return;
+    }
+
+    Solid::Control::ModemGsmCardInterface * modem = \
qobject_cast<Solid::Control::ModemGsmCardInterface *>(sender()); +    if (!modem) {
+        return;
+    }
+
+    // PinDialog already running.
+    if (dialog) {
+        kDebug() << "PinDialog already running";
+        return;
+    }
+
+    if (unlockRequired == QLatin1String("sin-pin")) {
+        dialog = new PinDialog(PinDialog::Pin);
+    } else if (unlockRequired == QLatin1String("sin-puk")) {
+        dialog = new PinDialog(PinDialog::PinPuk);
+    } else {
+        kWarning() << "Unhandled unlock request for '" << unlockRequired << "'";
+        return;
+    }
+
+    if (dialog->exec() != QDialog::Accepted) {
+        goto OUT;
+    }
+
+    {
+    // See /usr/share/polkit-1/actions/org.freedesktop.modem-manager.policy
+    // KAuth is the KDE's Polkit wrapper.
+    KAuth::Action action(QLatin1String("org.freedesktop.ModemManager.Device.Control"));
 +
+    KAuth::ActionReply reply = \
action.execute(QLatin1String("org.freedesktop.ModemManager.Device")); +    if \
(reply.failed()) { +        KMessageBox::error(0, i18n("Unlock failed. Error code is \
%1/%2 (%3).").arg(QString::number(reply.type()), QString::number(reply.errorCode()), \
reply.errorDescription()), i18n("Error")); +        goto OUT;
+    }
+    }
+
+    kDebug() << "Sending unlock code";
+    if (dialog->type() == PinDialog::Pin) {
+        modem->sendPin(dialog->pin());
+    } else if (dialog->type() == PinDialog::PinPuk) {
+        modem->sendPuk(dialog->puk(), dialog->pin());
+    }
+
+OUT:
+    delete dialog;
+    dialog = 0;
+}
+#endif
 // vim: sw=4 sts=4 et tw=100
diff --git a/libs/service/networkinterfacemonitor.h \
b/libs/service/networkinterfacemonitor.h index 2733784..d209b77 100644
--- a/libs/service/networkinterfacemonitor.h
+++ b/libs/service/networkinterfacemonitor.h
@@ -29,6 +29,10 @@ class ConnectionList;
 class ActivatableList;
 class NetworkInterfaceMonitorPrivate;
 
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+class PinDialog;
+#endif
+
 /**
  * Monitors network hardware and maintains NetworkInterfaceActivatableProviders for \
                them
  */
@@ -42,8 +46,15 @@ public:
 public Q_SLOTS:
     void networkInterfaceAdded(const QString &);
     void networkInterfaceRemoved(const QString &);
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+    void modemInterfaceAdded(const QString&);
+    void requestPin(const QString &);
+#endif
 private:
     NetworkInterfaceMonitorPrivate * d_ptr;
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+    PinDialog * dialog;
+#endif
 };
 
 #endif // NETWORKINTERFACEMONITOR_H
diff --git a/libs/service/pindialog.cpp b/libs/service/pindialog.cpp
new file mode 100644
index 0000000..b4aceca
--- /dev/null
+++ b/libs/service/pindialog.cpp
@@ -0,0 +1,110 @@
+/*
+Copyright 2011 Lamarque Souza <lamarque@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of
+the License or (at your option) version 3 or any later version
+accepted by the membership of KDE e.V. (or its successor approved
+by the membership of KDE e.V.), which shall act as a proxy
+defined in Section 14 of version 3 of the license.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+#include "pindialog.h"
+#include "ui_pinwidget.h"
+
+#include <QVBoxLayout>
+
+#include <KDebug>
+#include <kwindowsystem.h>
+
+PinDialog::PinDialog(const Type type, QWidget *parent)
+    : KDialog(parent), m_type(type)
+{
+    QWidget *w = new QWidget();
+    ui = new Ui::PinWidget();
+    ui->setupUi(w);
+    ui->pin->setEchoMode(QLineEdit::Password);
+    ui->errorMessage->setHidden(true);
+    QRect desktop = KGlobalSettings::desktopGeometry(topLevelWidget());
+    setMinimumWidth(qMin(1000, qMax(sizeHint().width(), desktop.width() / 4)));
+
+    pixmapLabel = new QLabel( mainWidget() );
+    pixmapLabel->setAlignment( Qt::AlignLeft | Qt::AlignTop );
+    ui->gridLayout->addWidget( pixmapLabel, 0, 0 );
+    pixmapLabel->setPixmap( KIcon("dialog-password").pixmap(KIconLoader::SizeHuge) \
); +
+    setButtons( KDialog::Ok | KDialog::Cancel);
+    setDefaultButton( KDialog::Ok );
+    button(KDialog::Ok)->setText(i18nc("As in 'Unlock cell phone with this pin \
code'", "Unlock")); +    setMainWidget(w);
+
+    if (m_type == PinPuk) {
+        setWindowTitle(i18n("SIM PIN unlock required"));
+        ui->title->setText(i18n("SIM PIN Unlock Required"));
+        ui->prompt->setText(i18n("The mobile broadband device '%s' requires a SIM \
PIN PUK code before it can be used.")); +        ui->pukLabel->setText(i18n("PUK \
code:")); +        ui->pinLabel->setText(i18n("New PIN code:"));
+        ui->pin2Label->setText(i18n("Re-enter new PIN code:"));
+        ui->chkShowPass->setText(i18n("Show PIN/PUK code"));
+
+        ui->puk->setFocus();
+        ui->pukLabel->show();
+        ui->pin2Label->show();
+    } else {
+        setWindowTitle(i18n("SIM PIN unlock required"));
+        ui->title->setText(i18n("SIM PIN Unlock Required"));
+        ui->prompt->setText(i18n("The mobile broadband device '%s' requires a SIM \
PIN code before it can be used.")); +        ui->pinLabel->setText(i18n("PIN \
code:")); +        ui->chkShowPass->setText(i18n("Show PIN code"));
+
+        ui->pin->setFocus();
+        ui->pukLabel->hide();
+        ui->pin2Label->hide();
+    }
+
+    KWindowSystem::setState( winId(), NET::KeepAbove );
+    KWindowSystem::setOnAllDesktops( winId(), true );
+    KWindowSystem::activateWindow( winId());
+
+    move((desktop.width() - width()) / 2, (desktop.height() - height()) / 2);
+    connect(ui->chkShowPass, SIGNAL(stateChanged(int)), this, \
SLOT(chkShowPassToggled())); +}
+
+PinDialog::~PinDialog()
+{
+}
+
+void PinDialog::chkShowPassToggled()
+{
+    bool on = ui->chkShowPass->isChecked();
+    ui->pin->setEchoMode(on ? QLineEdit::Normal : QLineEdit::Password);
+    ui->pin2->setEchoMode(on ? QLineEdit::Normal : QLineEdit::Password);
+    ui->puk->setEchoMode(on ? QLineEdit::Normal : QLineEdit::Password);
+}
+
+PinDialog::Type PinDialog::type() const
+{
+    return m_type;
+}
+
+QString PinDialog::pin() const
+{
+    return ui->pin->text();
+}
+
+QString PinDialog::puk() const
+{
+    return ui->puk->text();
+}
+
+#endif
diff --git a/libs/service/pindialog.h b/libs/service/pindialog.h
new file mode 100644
index 0000000..692e2cb
--- /dev/null
+++ b/libs/service/pindialog.h
@@ -0,0 +1,58 @@
+/*
+Copyright 2011 Lamarque Souza <lamarque@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of
+the License or (at your option) version 3 or any later version
+accepted by the membership of KDE e.V. (or its successor approved
+by the membership of KDE e.V.), which shall act as a proxy
+defined in Section 14 of version 3 of the license.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef COMPILE_MODEM_MANAGER_SUPPORT
+#ifndef PINDIALOG_H
+#define PINDIALOG_H
+
+#include <QWidget>
+#include "ui_pinwidget.h"
+
+#include <KDialog>
+#include <KLocale>
+#include <KPushButton>
+
+class PinWidget;
+
+class PinDialog : public KDialog
+{
+Q_OBJECT
+public:
+    enum Type {Pin, PinPuk};
+
+    PinDialog(const Type type = Pin, QWidget *parent=0);
+    ~PinDialog();
+
+    Type type() const;
+    QString pin() const;
+    QString puk() const;
+
+protected Q_SLOTS:
+    void chkShowPassToggled();
+protected:
+    Ui::PinWidget * ui;
+    QLabel* pixmapLabel;
+private:
+    Type m_type;
+};
+
+#endif
+
+#endif
diff --git a/libs/service/pinwidget.ui b/libs/service/pinwidget.ui
new file mode 100644
index 0000000..81b6a6c
--- /dev/null
+++ b/libs/service/pinwidget.ui
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PinWidget</class>
+ <widget class="QWidget" name="PinWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>218</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>SIM PIN unlock required</string>
+  </property>
+  <layout class="QVBoxLayout">
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item>
+    <layout class="QGridLayout">
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item row="0" column="1">
+      <widget class="QLabel" name="title">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>10</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>9</pointsize>
+         <weight>75</weight>
+         <bold>true</bold>
+        </font>
+       </property>
+       <property name="text">
+        <string>SIM PIN unlock required</string>
+       </property>
+       <property name="textFormat">
+        <enum>Qt::RichText</enum>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter|Qt::AlignHCenter|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
 +       </property>
+       <property name="wordWrap">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLabel" name="prompt">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+         <horstretch>10</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>9</pointsize>
+         <weight>50</weight>
+         <bold>false</bold>
+        </font>
+       </property>
+       <property name="text">
+        <string>The mobile broadband device '%s' requires a SIM PIN code before it \
can be used.</string> +       </property>
+       <property name="textFormat">
+        <enum>Qt::RichText</enum>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
+       </property>
+       <property name="wordWrap">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer>
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Fixed</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>400</width>
+       <height>16</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="KTitleWidget" name="errorMessage"/>
+   </item>
+   <item>
+    <layout class="QFormLayout" name="formLayout">
+     <property name="fieldGrowthPolicy">
+      <enum>QFormLayout::ExpandingFieldsGrow</enum>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item row="0" column="0">
+      <widget class="QLabel" name="pukLabel">
+       <property name="text">
+        <string>PUK code:</string>
+       </property>
+       <property name="buddy">
+        <cstring>puk</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="KLineEdit" name="puk">
+       <property name="inputMask">
+        <string>99999999; </string>
+       </property>
+       <property name="passwordMode">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="pinLabel">
+       <property name="text">
+        <string>New PIN code:</string>
+       </property>
+       <property name="buddy">
+        <cstring>pin</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="KLineEdit" name="pin">
+       <property name="inputMask">
+        <string>99990000; </string>
+       </property>
+       <property name="passwordMode">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="pin2Label">
+       <property name="text">
+        <string>Re-enter PIN code:</string>
+       </property>
+       <property name="buddy">
+        <cstring>pin2</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="KLineEdit" name="pin2">
+       <property name="inputMask">
+        <string>99990000; </string>
+       </property>
+       <property name="passwordMode">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <widget class="QCheckBox" name="chkShowPass">
+       <property name="text">
+        <string>Show PIN/PUK code</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KTitleWidget</class>
+   <extends>QWidget</extends>
+   <header>ktitlewidget.h</header>
+  </customwidget>
+  <customwidget>
+   <class>KLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>klineedit.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>pin</tabstop>
+  <tabstop>chkShowPass</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic