Bug 143297

Summary: "Groups" feature (grouping keys) does not work and is not documented
Product: [Applications] kgpg Reporter: Jürgen Starek <juergen>
Component: generalAssignee: bj
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Ubuntu   
OS: Linux   
Latest Commit: Version Fixed In:

Description Jürgen Starek 2007-03-21 16:54:47 UTC
Version:           1.2.2 (using KDE KDE 3.5.6)
Installed from:    Ubuntu Packages
OS:                Linux

KGPG includes a "Groups" menu that is supposed to allow grouping of keys. At least, that's what I could draw together from various sources -- it is not really documented in kgpg's help file...

Anyway, a Linux Journal article (http://www.linuxjournal.com/article/7616) leads me to believe that groups should be shown as items in the main key list. This does not happen here, in fact, I cannot observe that the first option in the menu does anything at all. I use a German KDE version and have to back-translate, but I suppose it's called "Create a group from selected keys" in English.

In order to reproduce this, I have to

1. Open KGPG
2. Select several keys by holding CTRL and klicking on them
3. Select "Create group from selected keys", the first entry in the "Groups" menu
4. Observe nothing happening

There are no visible groups created, and additionally, the contacts "added" seemingly aren't:

5. Remove selection by klicking on some key that was not selected in step 2, or alternatively close and re-start the application
6. Select a key that was previously (in step 2) selected
7. Open the Groups menu
8. Observe the second and third menu option grayed out

Thus, the "groups" feature is effectively useless.
Comment 1 Rolf Eike Beer 2007-08-29 12:13:14 UTC
SVN commit 706061 by dakon:

Make key groups usable

-Show group members as children of the group. Double clicking on them brings 
 you to the key.
-Show the number of keys in size column of the group

FEATURE:104820
BUG:143297


 M  +25 -8     keylistview.cpp  
 M  +7 -1      keylistview.h  
 M  +11 -17    keysmanager.cpp  


--- trunk/KDE/kdeutils/kgpg/keylistview.cpp #706060:706061
@@ -38,6 +38,7 @@
     m_type = type;
     m_key = NULL;
     m_sig = NULL;
+    groupId = NULL;
 }
 
 KeyListViewItem::KeyListViewItem(KeyListViewItem *parent, const QString &name, const QString &email, const QString &trust, const QString &expiration, const QString &size, const QString &creation, const QString &id, const bool isdefault, const bool isexpired, ItemType type)
@@ -48,6 +49,7 @@
     m_type = type;
     m_key = NULL;
     m_sig = NULL;
+    groupId = NULL;
 }
 
 KeyListViewItem::KeyListViewItem(K3ListView *parent, const KgpgKey &key, const bool isbold)
@@ -58,6 +60,7 @@
 	m_type = Public;
 	m_key = new KgpgKey(key);
 	m_sig = NULL;
+	groupId = NULL;
 	if (key.secret())
 		m_type |= Secret;
 	setText(0, key.name());
@@ -76,6 +79,7 @@
 	m_exp = false;	// TODO: sign expiration
 	m_type = Sign;
 	m_key = NULL;
+	groupId = NULL;
 	m_sig = new KgpgKeySign(sig);
 
 	QString tmpname = sig.name();
@@ -107,6 +111,7 @@
 {
 	delete m_key;
 	delete m_sig;
+	delete groupId;
 }
 
 void KeyListViewItem::setItemType(const ItemType &type)
@@ -143,11 +148,6 @@
 {
     QColorGroup _cg(cg);
 
-    if (itemType() & Group) {
-        if (column > 0)
-           return;
-    }
-    else
     if (itemType() & Public)
     {
         if (m_def && (column < 2))
@@ -615,9 +615,10 @@
     for (QStringList::Iterator it = groups.begin(); it != groups.end(); ++it)
         if (!QString(*it).isEmpty())
         {
-            item = new KeyListViewItem(this, QString(*it), "-", "-", "-", "-", "-", "-", false, false, KeyListViewItem::Group);
+            QStringList keys = KgpgInterface::getGpgGroupSetting(QString(*it), KGpgSettings::gpgConfigPath());
+            item = new KeyListViewItem(this, QString(*it), "-", "-", "-", i18np("%1 key", "%1 keys", keys.count()), "-", "-", false, false, KeyListViewItem::Group);
             item->setPixmap(0, Images::group());
-            item->setExpandable(false);
+            item->setExpandable(true);
         }
 
     emit statusMessage(i18n("%1 Keys, %2 Groups", childCount() - groupNb, groupNb), 1);
@@ -695,6 +696,11 @@
     if (item->childCount() != 0)
         return;   // key has already been expanded
 
+    if (item->itemType() == KeyListViewItem::Group) {
+        expandGroup(item);
+        return;
+    }
+
     QString keyid = item->keyId();
 
     KgpgInterface *interface = new KgpgInterface();
@@ -778,7 +784,18 @@
     for (QStringList::Iterator it = keysGroup.begin(); it != keysGroup.end(); ++it)
     {
         KeyListViewItem *item2 = new KeyListViewItem(item, QString(*it));
-        item2->setPixmap(0, Images::group());
+        KeyListViewItem *target = findItemByKeyId(QString(*it));
+
+        if (target == NULL) {
+          item2->setPixmap(0, Images::single());
+          item2->setItemType(KeyListViewItem::GPublic);
+        } else {
+          item2->setPixmap(0, *target->pixmap(0));
+          item2->setText(0, target->text(0));
+          item2->setItemType(target->itemType() | KeyListViewItem::Group);
+          item2->setGroupId(QString(*it));
+        }
+        item2->setText(6, QString(*it).right(8));
         item2->setExpandable(false);
     }
 }
--- trunk/KDE/kdeutils/kgpg/keylistview.h #706060:706061
@@ -38,6 +38,9 @@
         Secret = 2,
         Public = 4,
         Pair = Secret | Public,
+        GSecret = Group | Secret,
+        GPublic = Group | Public,
+        GPair = Group | Pair,
         Sub = 8,
         Uid = 16,
         Uat = 32,
@@ -61,6 +64,8 @@
     void setExpired(const bool &exp);
     bool isExpired() const;
 
+    void setGroupId(const QString &nid) { delete groupId; groupId = new QString(nid); }
+
     virtual void paintCell(QPainter *p, const QColorGroup &cg, int col, int width, int align);
     virtual int compare(Q3ListViewItem *item, int c, bool ascending) const;
     virtual QString key(int column, bool) const;
@@ -68,7 +73,7 @@
     virtual KeyListViewItem *nextSibling() const { return static_cast<KeyListViewItem*>(K3ListViewItem::nextSibling()); }
     virtual KeyListViewItem *firstChild() const { return static_cast<KeyListViewItem*>(K3ListViewItem::firstChild()); }
     virtual KgpgKey* getKey() { return m_key; }
-    virtual QString keyId(void) const { return m_key ? m_key->fullId() : m_sig ? m_sig->fullId() : text(6); }
+    virtual QString keyId(void) const { return m_key ? m_key->fullId() : m_sig ? m_sig->fullId() : groupId ? *groupId : text(6); }
 
 private:
     bool m_def; /// Is set to \em true if it is the default key, \em false otherwise.
@@ -76,6 +81,7 @@
     ItemType m_type;
     KgpgKey *m_key;
     KgpgKeySign *m_sig;
+    QString *groupId;
 };
 Q_DECLARE_OPERATORS_FOR_FLAGS(KeyListViewItem::ItemType)
 
--- trunk/KDE/kdeutils/kgpg/keysmanager.cpp #706060:706061
@@ -1165,6 +1165,10 @@
                                     break;
     case KeyListViewItem::Secret:   changeMessage(i18n("Orphaned Secret Key"), 0);
                                     break;
+    case KeyListViewItem::GPublic:
+    case KeyListViewItem::GSecret:
+    case KeyListViewItem::GPair:    changeMessage(i18n("Group member"), 0);
+                                    break;
     default:
 kDebug(3125) << "Oops, unmatched type value" << keysList2->currentItem()->itemType();
     }
@@ -1656,7 +1660,7 @@
             // display photo
             slotShowPhoto();
         }
-        if (isSignatureUnknown(cur))
+        if (isSignatureUnknown(cur) && !(cur->itemType() & KeyListViewItem::Group))
           return;
         KeyListViewItem *tgt = keysList2->findItemByKeyId(cur->keyId());
         if (tgt == NULL)
@@ -1799,27 +1803,17 @@
 
 void KeysManager::groupInit(const QStringList &keysGroup)
 {
-    kDebug(2100) << "preparing group" ;
+    kDebug(2100) << "preparing group" << keysGroup;
     QStringList lostKeys;
-    bool foundId;
 
     for (QStringList::ConstIterator it = keysGroup.begin(); it != keysGroup.end(); ++it)
     {
-        KeyListViewItem *item = static_cast<KeyListViewItem*>(gEdit->availableKeys->firstChild());
-        foundId = false;
-        while (item)
-        {
-            kDebug(2100) << "Searching in key: " << item->text(0) ;
-            if (QString(*it).right(8).toLower() == item->text(2).right(8).toLower())
-            {
-                gEdit->groupKeys->insertItem(item);
-                foundId = true;
-                break;
-            }
-            item = item->nextSibling();
-        }
-        if (!foundId)
+        KeyListViewItem *item = keysList2->findItemByKeyId(QString(*it));
+        if (item != NULL)
+            gEdit->groupKeys->insertItem(item);
+        else
             lostKeys += QString(*it);
+
     }
 
     if (!lostKeys.isEmpty())