Index: include/licq_events.h
===================================================================
RCS file: /cvsroot/licq/licq/include/licq_events.h,v
retrieving revision 1.15
diff -u -d -p -r1.15 licq_events.h
--- include/licq_events.h	7 Jul 2002 22:44:20 -0000	1.15
+++ include/licq_events.h	1 Aug 2002 21:33:14 -0000
@@ -299,6 +299,7 @@ const unsigned long USER_MORE           
 const unsigned long USER_WORK                   = 7;
 const unsigned long USER_ABOUT                  = 8;
 const unsigned long USER_SECURITY               = 9;
+const unsigned long USER_MORE2			= 10;
 
 const unsigned long LIST_ADD                     = 1;
 const unsigned long LIST_REMOVE                  = 2;
Index: include/licq_icq.h
===================================================================
RCS file: /cvsroot/licq/licq/include/licq_icq.h,v
retrieving revision 1.29
diff -u -d -p -r1.29 licq_icq.h
--- include/licq_icq.h	17 Jul 2002 06:26:36 -0000	1.29
+++ include/licq_icq.h	1 Aug 2002 21:33:14 -0000
@@ -205,10 +205,11 @@ const unsigned short ICQ_CMDxMETA_WORKxI
 const unsigned short ICQ_CMDxMETA_MORExINFO        = 0x00DC; // 220
 const unsigned short ICQ_CMDxMETA_ABOUT            = 0x00E6; // 230
 const unsigned short ICQ_CMDxMETA_EMAILxINFO       = 0x00EB; // 235
-const unsigned short ICQ_CMDxMETA_UNKNOWNx240      = 0x00F0; // 240
+const unsigned short ICQ_CMDxMETA_INTERESTSxINFO   = 0x00F0; // 240
 const unsigned short ICQ_CMDxMETA_PASTxINFO        = 0x00FA; // 250
 const unsigned short ICQ_CMDxMETA_BASICxINFO       = 0x0104; // 260
 const unsigned short ICQ_CMDxMETA_UNKNOWNx270      = 0x010E; // 270
+
 // Meta commands (sent)
 const unsigned short ICQ_CMDxMETA_GENERALxINFOxSET = 0x03E9; // 1001
 const unsigned short ICQ_CMDxMETA_WORKxINFOxSET    = 0x03F2; // 1010
Index: include/licq_icqd.h
===================================================================
RCS file: /cvsroot/licq/licq/include/licq_icqd.h,v
retrieving revision 1.36
diff -u -d -p -r1.36 licq_icqd.h
--- include/licq_icqd.h	23 Jul 2002 13:04:59 -0000	1.36
+++ include/licq_icqd.h	1 Aug 2002 21:33:14 -0000
@@ -159,6 +159,9 @@ public:
                            unsigned short nBirthYear, char nBirthMonth,
                            char nBirthDay, char nLanguage1,
                            char nLanguage2, char nLanguage3);
+  unsigned long CICQDaemon::icqSetMore2Info( const ICQUserCategory *interests,
+  					     const ICQUserCategory *pasts,
+  					     const ICQUserCategory *affils);
   unsigned long icqSetSecurityInfo(bool bAuthorize, bool bHideIp, bool bWebAware);
   unsigned long icqSetAbout(const char *szAbout);
   unsigned long icqSetPassword(const char *szPassword);
Index: include/licq_user.h
===================================================================
RCS file: /cvsroot/licq/licq/include/licq_user.h,v
retrieving revision 1.30
diff -u -d -p -r1.30 licq_user.h
--- include/licq_user.h	26 Jul 2002 03:32:33 -0000	1.30
+++ include/licq_user.h	1 Aug 2002 21:33:15 -0000
@@ -144,9 +144,37 @@ const unsigned short LAST_RECV_EVENT    
 const unsigned short LAST_SENT_EVENT    = 2;
 const unsigned short LAST_CHECKED_AR    = 3;
 
+const unsigned short MAX_CATEGORY_SIZE  = 72;
 
-//+++++OBJECTS++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
+//+++++OBJECTS+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//====ICQUserCategory==========================================================
+class ICQUserCategory
+{
+public:
+	ICQUserCategory();
+	~ICQUserCategory();
+	bool AddCategory (unsigned short cat, const char *descr);
+	void Clean();
+	bool SaveToDisk  (CIniFile &m_fConf,const char *const szN,
+	                  const char *const szCat,const char *const szDescr );
+	bool LoadFromDisk(CIniFile &m_fConf, const char *const szN,
+	                  const char *const szCat,const char *const szDescr );
+
+	unsigned begin();
+	bool get(unsigned *d,unsigned short *id, char const ** descr );
+	void end(unsigned *d);
+	static const unsigned MAX_CATEGORIES = 4;
+private:
+	unsigned short used;
+	
+	struct 	cat
+	{	unsigned short id;
+		char *descr;
+	};
+	struct cat data[MAX_CATEGORIES];
+	
+};
 
 //=====ICQUser==================================================================
 class ICQUser
@@ -162,6 +190,9 @@ public:
   void SaveMoreInfo();
   void SaveWorkInfo();
   void SaveAboutInfo();
+  void SaveInterestsInfo();
+  void SaveBackgroundsInfo();
+  void SaveAffilationsInfo();
   void SaveExtInfo();
   void SaveNewMessagesInfo();
 
@@ -212,6 +243,12 @@ public:
   // About Info
   char *GetAbout()                      { return m_szAbout; }
 
+  // More2 Info
+  // Don't touch the pointers
+  ICQUserCategory *GetInterests()	{ return m_Interests; }
+  ICQUserCategory *GetBackgrounds()	{ return m_Backgrounds;}
+   ICQUserCategory *GetAffiliations()	{ return m_Affiliations;}
+  
   // Licq Info
   unsigned short GetSID()               { return m_nSID; }
   unsigned short GetGSID()              { return m_nGSID; }
@@ -292,6 +329,10 @@ public:
 
   // About Info
   void SetAbout(const char *n)        {  SetString(&m_szAbout, n);  SaveAboutInfo();  }
+  // More2 Info
+  void SetInterests(ICQUserCategory *in );
+  void SetBackgrounds(ICQUserCategory *in );
+  void SetAffiliations(ICQUserCategory *in );
 
   // Licq Info
   void SetSID(unsigned short s)       { m_nSID = s; }
@@ -431,6 +472,9 @@ protected:
   void LoadMoreInfo();
   void LoadWorkInfo();
   void LoadAboutInfo();
+  void LoadInterestsInfo();
+  void LoadBackgroundsInfo();
+  void LoadAffiliationInfo();
   void LoadLicqInfo();
   void Init(unsigned long nUin);
   bool LoadInfo();
@@ -520,6 +564,11 @@ protected:
 
   // About Info
   char *m_szAbout;
+  
+  // More2 Info
+  ICQUserCategory *m_Interests;
+  ICQUserCategory *m_Backgrounds;
+  ICQUserCategory *m_Affiliations;
 
   // Server Side ID, Group SID
   unsigned short m_nSID;
Index: plugins/qt-gui/src/Makefile.am
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/Makefile.am,v
retrieving revision 1.32
diff -u -d -p -r1.32 Makefile.am
--- plugins/qt-gui/src/Makefile.am	26 Jul 2002 03:22:57 -0000	1.32
+++ plugins/qt-gui/src/Makefile.am	1 Aug 2002 21:33:15 -0000
@@ -19,7 +19,7 @@ noinst_HEADERS = adduserdlg.h authuserdl
 	securitydlg.h showawaymsgdlg.h sigman.h skin.h skinbrowser.h userbox.h\
 	utilitydlg.h wharf.h randomchatdlg.h forwarddlg.h chatjoin.h \
 	mmlistview.h mmsenddlg.h userinfodlg.h usereventdlg.h keyrequestdlg.h \
-  jfcstyle.h usercodec.h reqauthdlg.h
+        jfcstyle.h usercodec.h reqauthdlg.h catdlg.h
 
 licq_gui = adduserdlg.cpp authuserdlg.cpp awaymsgdlg.cpp \
 	refusedlg.cpp chatdlg.cpp editgrp.cpp editfile.cpp eventdesc.cpp \
@@ -30,7 +30,7 @@ licq_gui = adduserdlg.cpp authuserdlg.cp
 	sigman.cpp skin.cpp skinbrowser.cpp userbox.cpp utilitydlg.cpp \
 	wharf.cpp randomchatdlg.cpp forwarddlg.cpp chatjoin.cpp mmlistview.cpp \
   mmsenddlg.cpp userinfodlg.cpp usereventdlg.cpp keyrequestdlg.cpp \
-  jfcstyle.cpp usercodec.cpp reqauthdlg.cpp
+  jfcstyle.cpp usercodec.cpp catdlg.cpp reqauthdlg.cpp 
 
 licq_qt_gui_la_SOURCES = $(licq_gui)
 licq_kde_gui_la_SOURCES = $(licq_gui) wrap_kde_malloc.cpp
Index: plugins/qt-gui/src/gui-defines.h
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/gui-defines.h,v
retrieving revision 1.18
diff -u -d -p -r1.18 gui-defines.h
--- plugins/qt-gui/src/gui-defines.h	17 Jul 2002 04:38:28 -0000	1.18
+++ plugins/qt-gui/src/gui-defines.h	1 Aug 2002 21:33:15 -0000
@@ -22,6 +22,7 @@ enum UserMenu {
   mnuUserCustomAutoResponse,
   mnuUserGeneral,
   mnuUserMore,
+  mnuUserMore2,
   mnuUserWork,
   mnuUserAbout,
   mnuUserLast,
@@ -34,6 +35,7 @@ enum OwnerMenu_Identifiers {
   OwnerMenuView = mnuUserView,
   OwnerMenuGeneral = mnuUserGeneral,
   OwnerMenuMore = mnuUserMore,
+  OwnerMenuMore2 = mnuUserMore2,
   OwnerMenuWork = mnuUserWork,
   OwnerMenuAbout = mnuUserAbout,
   OwnerMenuLast = mnuUserLast,
Index: plugins/qt-gui/src/mainwin.cpp
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/mainwin.cpp,v
retrieving revision 1.237
diff -u -d -p -r1.237 mainwin.cpp
--- plugins/qt-gui/src/mainwin.cpp	26 Jul 2002 07:12:31 -0000	1.237
+++ plugins/qt-gui/src/mainwin.cpp	1 Aug 2002 21:33:17 -0000
@@ -1676,9 +1676,10 @@ void CMainWindow::callOwnerFunction(int 
     callFunction(index, gUserManager.OwnerUin());
 
   else if (index == OwnerMenuGeneral ||
-      index == OwnerMenuMore  || index == OwnerMenuWork ||
-      index == OwnerMenuAbout || index == OwnerMenuLast ||
+      index == OwnerMenuMore  || index == OwnerMenuMore2  || 
+      index == OwnerMenuWork  || index == OwnerMenuAbout  ||
       index == OwnerMenuHistory)
+
     callInfoTab(index, gUserManager.OwnerUin());
 
   else if (index == OwnerMenuSecurity)
@@ -1780,6 +1781,7 @@ void CMainWindow::callUserFunction(int i
     case mnuUserHistory:
     case mnuUserGeneral:
     case mnuUserMore:
+    case mnuUserMore2:
     case mnuUserWork:
     case mnuUserAbout:
     case mnuUserLast:
@@ -1834,6 +1836,9 @@ void CMainWindow::callInfoTab(int fcn, u
     case mnuUserMore:
       tab = UserInfoDlg::MoreInfo;
       break;
+    case mnuUserMore2:
+      tab = UserInfoDlg::More2Info;
+      break;
     case mnuUserWork:
       tab = UserInfoDlg::WorkInfo;
       break;
@@ -1873,6 +1878,9 @@ void CMainWindow::callInfoTab(int fcn, u
     case mnuUserMore:
       f->showTab(UserInfoDlg::MoreInfo);
       break;
+    case mnuUserMore2:
+      f->showTab(UserInfoDlg::More2Info);
+      break;
     case mnuUserWork:
       f->showTab(UserInfoDlg::WorkInfo);
       break;
@@ -2997,6 +3005,7 @@ void CMainWindow::initMenu()
    mnuOwnerAdm->insertSeparator();
    mnuOwnerAdm->insertItem(pmInfo, tr("&General Info"), OwnerMenuGeneral);
    mnuOwnerAdm->insertItem(tr("&More Info"), OwnerMenuMore);
+   mnuOwnerAdm->insertItem(tr("M&ore II Info"), OwnerMenuMore2);
    mnuOwnerAdm->insertItem(tr("&Work Info"), OwnerMenuWork);
    mnuOwnerAdm->insertItem(tr("&About"), OwnerMenuAbout);
    mnuOwnerAdm->insertItem(pmHistory, tr("&History"), OwnerMenuHistory);
@@ -3106,6 +3115,7 @@ void CMainWindow::initMenu()
    QPopupMenu *m = new QPopupMenu(this);
    m->insertItem(tr("&General Info"), mnuUserGeneral);
    m->insertItem(tr("&More Info"), mnuUserMore);
+   m->insertItem(tr("M&ore II Info"), mnuUserMore2);
    m->insertItem(tr("&Work Info"), mnuUserWork);
    m->insertItem(tr("&About"), mnuUserAbout);
    m->insertItem(tr("&Last"), mnuUserLast);
Index: plugins/qt-gui/src/userinfodlg.cpp
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/userinfodlg.cpp,v
retrieving revision 1.44
diff -u -d -p -r1.44 userinfodlg.cpp
--- plugins/qt-gui/src/userinfodlg.cpp	23 Jul 2002 13:10:45 -0000	1.44
+++ plugins/qt-gui/src/userinfodlg.cpp	1 Aug 2002 21:33:18 -0000
@@ -53,7 +53,6 @@
 #include "sigman.h"
 
 // -----------------------------------------------------------------------------
-
 UserInfoDlg::UserInfoDlg(CICQDaemon *s, CSignalManager *theSigMan, CMainWindow *m,
                          unsigned long _nUin, QWidget* parent)
   : QWidget(parent, "UserInfoDialog", WDestructiveClose)
@@ -67,6 +66,7 @@ UserInfoDlg::UserInfoDlg(CICQDaemon *s, 
 
   CreateGeneralInfo();
   CreateMoreInfo();
+  CreateMore2Info();
   CreateWorkInfo();
   CreateAbout();
   CreateHistory();
@@ -79,6 +79,7 @@ UserInfoDlg::UserInfoDlg(CICQDaemon *s, 
 
   tabs->addTab(tabList[GeneralInfo].tab, tabList[GeneralInfo].label);
   tabs->addTab(tabList[MoreInfo].tab, tabList[MoreInfo].label);
+  tabs->addTab(tabList[More2Info].tab, tabList[More2Info].label);
   tabs->addTab(tabList[WorkInfo].tab, tabList[WorkInfo].label);
   tabs->addTab(tabList[AboutInfo].tab, tabList[AboutInfo].label);
   tabs->addTab(tabList[HistoryInfo].tab, tabList[HistoryInfo].label);
@@ -145,6 +146,7 @@ UserInfoDlg::UserInfoDlg(CICQDaemon *s, 
     setIconText(codec->toUnicode(u->GetAlias()));
     gUserManager.DropUser(u);
   }
+
 }
 
 
@@ -619,6 +621,264 @@ void UserInfoDlg::SaveMoreInfo()
   gUserManager.DropUser(u);
 }
 
+//-----------------------------------------------------------------------------
+
+
+// Juan XXX Move the tables to a config file?
+// Juan XXX How to i18n a static table ?
+static struct category interests_table[] =
+{	{	0x0064,"Art"	},
+	{	0x0065,"Cars"	},
+	{	0x0066,"Celebrity Fans"	},
+	{	0x0067,"Collections"	} ,
+	{	0x0068,"Computers"	},
+	{	0x0069,"Culture & Literature"	},
+	{	0x006A,"Fitness"	},
+	{	0x006B,"Games"	},
+	{	0x006C,"Hobbies"	},
+	{	0x006D,"ICQ - Providing Help"	},
+	{	0x006E,"Internet"	},
+	{	0x006F,"Lifestyle"	},
+	{	0x0070,"Movies/TV"	},
+	{	0x0071,"Music"	},
+	{	0x0072,"Outdoor Activities"	},
+	{	0x0073,"Parenting"	},
+	{	0x0074,"Pets/Animals"	},
+	{	0x0075,"Religion"	},
+	{	0x0076,"Science/Technology"	},
+	{	0x0077,"Skills"	},
+	{	0x0078,"Sports"	},
+	{	0x0079,"Web Design"	},
+	{	0x007A,"Nature and Environment"	},
+	{	0x007B,"News & Media"	},
+	{	0x007C,"Government"	},
+	{	0x007D,"Business & Economy"	},
+	{	0x007E,"Mystics"	},
+	{	0x007F,"Travel"	},
+	{	0x0080,"Astronomy"	},
+	{	0x0081,"Space"	},
+	{	0x0082,"Clothing"	},
+	{	0x0083,"Parties"	},
+	{	0x0084,"Women"	},
+	{	0x0085,"Social science"	},
+	{	0x0086,"60's"	},
+	{	0x0087,"70's"	},
+	{	0x0088,"80's"	},
+	{	0x0089,"50's"	},
+	{	0x008A,"Finance and corporate"	},
+	{	0x008B,"Entertainment"	},
+	{	0x008C,"Consumer electronics"	},
+	{	0x008D,"Retail stores"	},
+	{	0x008E,"Health and beauty"	},
+	{	0x008F,"Media"	},
+	{	0x0090,"Household products"	},
+	{	0x0091,"Mail order catalog"	},
+	{	0x0092,"Business services"	},
+	{	0x0093,"Audio and visual"	},
+	{	0x0094,"Sporting and athletic"	},
+	{	0x0095,"Publishing"	},
+	{	0x0096,"Home automation"	},
+	{	0x0000, NULL	 		}
+};
+static struct category background_table[] =
+{	
+	{	0x012C,"Elementary School"	},
+	{	0x012D,"High School"	},
+	{	0x012E,"College"	},
+	{	0x012F,"University"	},
+	{	0x0130,"Military"	},
+	{	0x0131,"Past Work Place"	},
+	{	0x0132,"Past Organization"	},
+	{	0x018F,"Other"	},
+	{	0x0000, NULL	   }
+};
+
+static struct category affil_table[]=
+{
+	{	0x00C8,"Alumni Org."	},
+	{	0x00C9,"Charity Org."	},
+	{	0x00CA,"Club/Social Org."	},
+	{	0x00CB,"Community Org."	},
+	{	0x00CC,"Cultural Org."	},
+	{	0x00CD,"Fan Clubs"	},
+	{	0x00CE,"Fraternity/Sorority"	},
+	{	0x00CF,"Hobbyists Org."	},
+	{	0x00D0,"International Org."	},
+	{	0x00D1,"Nature and Environment Org."	},
+	{	0x00D2,"Professional Org."	},
+	{	0x00D3,"Scientific/Technical Org."	},
+	{	0x00D4,"Self Improvement Group"	},
+	{	0x00D5,"Spiritual/Religious Org."	},
+	{	0x00D6,"Sports Org."	},
+	{	0x00D7,"Support Org."	},
+	{	0x00D8,"Trade and Business Org."	},
+	{	0x00D9,"Union"	},
+	{	0x00DA,"Volunteer Org."	},
+	{	0x012B,"Other"	},
+	{	0x0000,NULL	}
+};
+
+static const char * category2str( const struct  category *t,unsigned short cat )
+{	unsigned i;
+	const char *ret = NULL ;
+
+	for( i=0 ; t[i].str ; i++ )
+	{	if( cat == t[i].cat )
+		{	ret = t[i].str;
+		 	break;
+		}
+	}
+	if( t[i].str == NULL )
+		ret = "Unknown";
+	
+	return ret;
+}
+
+enum
+{	MORE2_MENU_ADD,
+	MORE2_MENU_REM,
+	MORE2_MENU_EDIT,
+	MORE2_MENU_CLEAR
+};
+
+void UserInfoDlg::CreateMore2Info()
+{	QVBox *p;
+	QListViewItem *lvi;
+	unsigned i;
+	static const struct 
+	{	enum More2Things id;
+		const char *const name;
+	} table[] =  
+	{	{ LVIM2_PERSONAL, "Personal Interests"               },
+		{ LVIM2_BACK,     "Past Background"                  }, 
+		{ LVIM2_AFFIL,    "Organization, Affiliation, Group"},
+		{ LVIM2_MAX,      NULL                               }
+	};
+
+	tabList[More2Info].label = tr("M&ore II");
+	tabList[More2Info].tab=new QVBox(this,tabList[AboutInfo].label.latin1());
+	tabList[More2Info].loaded = false;
+
+        p = (QVBox *)tabList[More2Info].tab;
+        Q_CHECK_PTR(p);
+	p->setMargin(8);
+	p->setSpacing(8);
+
+	lsvMore2 = new QListView(p);
+	Q_CHECK_PTR(lsvMore2);
+	lsvMore2->addColumn(tr("Item"),-1);
+	lsvMore2->setEnabled(true);
+	lsvMore2->setAllColumnsShowFocus(true);
+	lsvMore2->setShowSortIndicator( TRUE );
+	lsvMore2->setSorting(-1);
+
+	for( i=0; table[i].name ; i++ )
+	{	lvi = lviMore2Top[table[i].id] =new QListViewItem(lsvMore2,
+						tr(table[i].name));
+		Q_CHECK_PTR(lvi);
+		lvi->setOpen(true);
+	}
+
+	ecDlg = NULL;
+
+}	
+
+static int
+splitCategory( QListViewItem *parent,int id, const char *descr)
+{	char *p,*q,*s;
+	QListViewItem *lvi;
+
+	if( descr == NULL || !*descr )
+		return -1;
+
+	s = p = strdup( descr );
+	if( p == NULL )
+		return -1;
+
+	while( (q = strchr(s,',')) )
+	{	if( q )
+		{	*q='\0';
+			if( *s)
+				new QListViewItem(parent,s);
+			s = q+1;
+		}
+	}
+	if( *s )
+	{	lvi = new QListViewItem(parent,s);
+		Q_CHECK_PTR(lvi);
+		lvi->setSelectable(FALSE);
+	}
+
+	parent->setOpen(true);
+	
+	free( p );
+	return 0;
+}
+
+void UserInfoDlg::SetMore2Info(ICQUser *u)
+{	QListViewItem *lvi, *lvChild;
+	ICQUserCategory *cat=0;
+	static const struct 
+	{	enum More2Things id;
+		const struct category * const ptr;
+	} table[] =  
+	{	{ LVIM2_PERSONAL, interests_table },
+		{ LVIM2_BACK,     background_table},
+		{ LVIM2_AFFIL,    affil_table     },
+		{ LVIM2_MAX,	  NULL		  }
+	};
+	unsigned i,j,n;
+	bool drop = false;
+	unsigned short id;
+	const char *descr;
+	
+	tabList[More2Info].loaded = true;
+
+	if (u == NULL)
+	{	drop = true;
+		u = gUserManager.FetchUser(m_nUin, LOCK_R);
+		if (u == NULL)
+			return;
+	}
+
+	// clean all the fields
+	for( i=0 ; i < LVIM2_MAX ; i++ )
+		while( (lvChild = lviMore2Top[i]->firstChild()) )
+			delete lvChild;
+
+	for( j=0 ; table[j].ptr ; j++ )
+	{	if( table[j].id == LVIM2_PERSONAL )
+			cat = u->GetInterests();
+		else if( table[j].id == LVIM2_BACK )
+			cat = u->GetBackgrounds();
+		else if( table[j].id == LVIM2_AFFIL )
+			cat = u->GetAffiliations();
+		else
+			Q_ASSERT(FALSE);
+		if( cat != 0 )
+		{	for( n=0,i=cat->begin() ; cat->get(&i,&id,&descr); n++) 
+			{	lvi = new QListViewItem(lviMore2Top[j],
+						category2str(table[j].ptr,id));
+				Q_CHECK_PTR(lvi);
+				splitCategory(lvi,id,descr);
+			}
+			if( n == 0 )
+				lvi = new QListViewItem(lviMore2Top[j],
+					tr("(none)"));
+			cat->end(&i);
+			
+		}
+
+	}
+	if( drop ) 
+		gUserManager.DropUser(u);
+}
+
+void UserInfoDlg::SaveMore2Info()
+{
+	// Nothing yet
+}
+
 // -----------------------------------------------------------------------------
 
 void UserInfoDlg::CreateWorkInfo()
@@ -1233,6 +1493,15 @@ void UserInfoDlg::updateTab(const QStrin
     if (!tabList[MoreInfo].loaded)
       SetMoreInfo(NULL);
   }
+  else if (txt == tabList[More2Info].label)
+  {  btnMain3->setText(tr("&Update"));
+     btnMain2->setText(m_bOwner ? tr("Retrieve") : tr("&Save"));
+     btnMain3->setEnabled(true);
+     btnMain2->setEnabled(true);
+     currentTab = More2Info;
+     if (!tabList[More2Info].loaded)
+	SetMore2Info(NULL);
+  }
   else if (txt == tabList[WorkInfo].label)
   {
     btnMain3->setText(tr("&Update"));
@@ -1289,6 +1558,8 @@ void UserInfoDlg::SaveSettings()
   case MoreInfo:
     SaveMoreInfo();
     break;
+  case More2Info:
+    SaveMoreInfo();
   case WorkInfo:
     SaveWorkInfo();
     break;
@@ -1331,6 +1602,7 @@ void UserInfoDlg::slotRetrieve()
   {
     case GeneralInfo: icqEventTag = server->icqRequestMetaInfo(m_nUin);  break;
     case MoreInfo:    icqEventTag = server->icqRequestMetaInfo(m_nUin);  break;
+    case More2Info:   icqEventTag = server->icqRequestMetaInfo(m_nUin);  break;
     case WorkInfo:    icqEventTag = server->icqRequestMetaInfo(m_nUin);  break;
     case AboutInfo:   icqEventTag = server->icqRequestMetaInfo(m_nUin);  break;
   }
@@ -1400,6 +1672,9 @@ void UserInfoDlg::slotUpdate()
                                          GetLanguageByIndex(cmbLanguage[1]->currentItem())->nCode,
                                          GetLanguageByIndex(cmbLanguage[2]->currentItem())->nCode);
   break;
+  case More2Info:
+
+  	break;
   case WorkInfo:
     i = cmbCompanyCountry->currentItem();
     cc = GetCountryByIndex(i)->nCode;
@@ -1483,6 +1758,8 @@ void UserInfoDlg::updatedUser(CICQSignal
   case USER_MORE:
     SetMoreInfo(u);
     break;
+  case USER_MORE2:
+    SetMore2Info(u);
   case USER_WORK:
     SetWorkInfo(u);
     break;
@@ -1497,7 +1774,6 @@ void UserInfoDlg::resetCaption()
 {
   setCaption(m_sBasic);
 }
-
 
 // -----------------------------------------------------------------------------
 
Index: plugins/qt-gui/src/userinfodlg.h
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/userinfodlg.h,v
retrieving revision 1.16
diff -u -d -p -r1.16 userinfodlg.h
--- plugins/qt-gui/src/userinfodlg.h	5 Mar 2002 17:32:04 -0000	1.16
+++ plugins/qt-gui/src/userinfodlg.h	1 Aug 2002 21:33:18 -0000
@@ -23,6 +23,7 @@
 
 #include "licq_history.h"
 #include "mainwin.h"
+#include "catdlg.h"
 
 class QSpinBox;
 class QLabel;
@@ -30,6 +31,8 @@ class QCheckBox;
 class QPushButton;
 class QTabWidget;
 class QProgressBar;
+class QListView;
+class QListViewItem;
 
 class CInfoField;
 class CICQDaemon;
@@ -48,6 +51,7 @@ public:
   enum Tab {
     GeneralInfo,
     MoreInfo,
+    More2Info,
     WorkInfo,
     AboutInfo,
     HistoryInfo,
@@ -100,6 +104,13 @@ protected:
   CEComboBox *cmbLanguage[3], *cmbGender;
   QSpinBox *spnBirthDay, *spnBirthMonth, *spnBirthYear;
 
+  // More2 info
+  void CreateMore2Info();
+  QListView *lsvMore2;
+  QListViewItem *lviMore2Top[3];
+  enum More2Things{LVIM2_PERSONAL,LVIM2_BACK,LVIM2_AFFIL,LVIM2_MAX};
+  EditCategoryDlg *ecDlg;
+
   // Work info
   void CreateWorkInfo();
   CInfoField *nfoCompanyName, *nfoCompanyCity, *nfoCompanyState,
@@ -135,16 +146,19 @@ protected:
 
   void SetGeneralInfo(ICQUser *);
   void SetMoreInfo(ICQUser *);
+  void SetMore2Info(ICQUser *);
   void SetWorkInfo(ICQUser *);
   void SetAbout(ICQUser *);
   void SetLastCountersInfo(ICQUser *);
   void SaveGeneralInfo();
   void SaveMoreInfo();
+  void SaveMore2Info();
   void SaveWorkInfo();
   void SaveAbout();
 
   virtual void keyPressEvent(QKeyEvent*);
-
+public slots:
+void prueba();
 protected slots:
   void ShowHistory();
   void ShowHistoryPrev();
@@ -160,7 +174,6 @@ protected slots:
   void doneFunction(ICQEvent*);
   void resetCaption();
   void ShowUsermenu() { gMainWindow->SetUserMenuUin(m_nUin); }
-
 signals:
   void finished(unsigned long);
   void signal_updatedUser(CICQSignal *);
Index: src/icqd-srv.cpp
===================================================================
RCS file: /cvsroot/licq/licq/src/icqd-srv.cpp,v
retrieving revision 1.52
diff -u -d -p -r1.52 icqd-srv.cpp
--- src/icqd-srv.cpp	23 Jul 2002 13:21:29 -0000	1.52
+++ src/icqd-srv.cpp	1 Aug 2002 21:33:19 -0000
@@ -397,6 +397,15 @@ unsigned long CICQDaemon::icqSetMoreInfo
   return e->EventId();
 }
 
+//-----icqSetMore2Info-------------------------------------------------------
+unsigned long CICQDaemon::icqSetMore2Info(const ICQUserCategory* interests,
+					 const ICQUserCategory* pasts,
+					 const ICQUserCategory* affils)
+{
+
+	return 0;
+}
+
 //-----icqSetWorkInfo--------------------------------------------------------
 unsigned long CICQDaemon::icqSetWorkInfo(const char *_szCity, const char *_szState,
                                      const char *_szPhone,
@@ -1257,6 +1266,7 @@ void CICQDaemon::ProcessServiceFam(CBuff
   }
 }
 
+
 //--------ProcessLocationFam-----------------------------------------------
 void CICQDaemon::ProcessLocationFam(const CBuffer &packet, unsigned short nSubtype)
 {
@@ -3071,31 +3081,82 @@ void CICQDaemon::ProcessVariousFam(CBuff
 	    break;
 	}
 
-	case 0x00F0:
-        {
+	case ICQ_CMDxMETA_INTERESTSxINFO:
+        {   unsigned i,n;
+	    bool nRet=true;
+	    
 	    // personal interests info
+	    gLog.Info("%sPersonal Interests Info on %s (%ld).\n", L_SRVxSTR,
+	   		u->GetAlias(), u ->Uin());
 
-	    char * buf;
+	    u->m_Interests->Clean();
+            n = msg.UnpackChar();
 
-	    gLog.Unknown("%spersonal interests: %04hx\n%s\n", L_UNKNOWNxSTR,
-				    nSubSequence, packet.print(buf));
-	    delete [] buf;
+	    for ( i=0 ; nRet && i<n ; i++)
+	    {	nRet = u->m_Interests->AddCategory( msg.UnpackUnsignedShort(),
+	                                            msg.UnpackString() );
+	    }
+
+	    // save the user infomation
+	    u->SetEnableSave(true);
+	    u->SaveInterestsInfo();
 
+	    // Juan XXX TODO: I still don't know how to use these, but works
+	    // Juan XXX TODO: all fine :=P
 	    PushExtendedEvent(e);
 	    multipart = true;
 
+	    PushPluginSignal(new CICQSignal(SIGNAL_UPDATExUSER, USER_MORE2,
+	    			u->Uin()));
 	    break;
         }
 
         case ICQ_CMDxMETA_PASTxINFO:
-        {
+        {   
 	    // past background info
+            unsigned i,n;
+            bool nRet = true;
+            
+	    // personal interests info
+	    gLog.Info("%sPast background Info / Affiliations  on %s (%ld).\n",
+	    		L_SRVxSTR, u->GetAlias(), u ->Uin());
 
-	    char* buf;
+	    // the fields may be contains data
+	    u->m_Backgrounds->Clean();
+	    
+	    n = msg.UnpackChar();
 
-	    gLog.Unknown("%spast backgrounds: %04hx\n%s\n", L_UNKNOWNxSTR,
-				    nSubSequence, packet.print(buf));
-	    delete [] buf;
+	    for ( i=0 ; nRet && i<n ; i++)
+	    {	nRet = u->m_Backgrounds->AddCategory( msg.UnpackUnsignedShort(),
+	                                              msg.UnpackString());
+	    }
+
+	    // save the user infomation
+	    u->SetEnableSave(true);
+	    u->SaveBackgroundsInfo();
+
+	    //---- Affiliations
+	    u->m_Affiliations->Clean();
+            nRet = true;
+	    n = msg.UnpackChar();
+
+	    for( i=0 ; nRet &&  i<n ; i++)	    
+	    {		nRet = u->m_Affiliations->AddCategory(
+	                                              msg.UnpackUnsignedShort(),
+                                                      msg.UnpackString());
+	    }
+	    
+	    // save the user infomation
+	    u->SetEnableSave(true);
+	    u->SaveAffilationsInfo();
+
+	    // Juan XXX TODO: i still don't know how to use these, but all 
+	    // Juan XXX TODO: works :=P
+	    //PushExtendedEvent(e);
+	    //multipart = true;
+	    
+	    PushPluginSignal(new CICQSignal(SIGNAL_UPDATExUSER, USER_MORE2,
+	    			u->Uin()));
 
 	    break;
         }
Index: src/icqd-udp.cpp
===================================================================
RCS file: /cvsroot/licq/licq/src/icqd-udp.cpp,v
retrieving revision 1.33
diff -u -d -p -r1.33 icqd-udp.cpp
--- src/icqd-udp.cpp	15 Jul 2002 04:46:12 -0000	1.33
+++ src/icqd-udp.cpp	1 Aug 2002 21:33:21 -0000
@@ -1971,7 +1971,7 @@ void CICQDaemon::ProcessMetaCommand(CBuf
     case ICQ_CMDxMETA_WORKxINFO:
     case ICQ_CMDxMETA_GENERALxINFO:
     case ICQ_CMDxMETA_ABOUT:
-    case ICQ_CMDxMETA_UNKNOWNx240:
+    case ICQ_CMDxMETA_INTERESTSxINFO:
     case ICQ_CMDxMETA_UNKNOWNx250:
     case ICQ_CMDxMETA_UNKNOWNx270:
     case ICQ_CMDxMETA_BASICxINFO:
Index: src/user.cpp
===================================================================
RCS file: /cvsroot/licq/licq/src/user.cpp,v
retrieving revision 1.45
diff -u -d -p -r1.45 user.cpp
--- src/user.cpp	26 Jul 2002 03:32:33 -0000	1.45
+++ src/user.cpp	1 Aug 2002 21:33:22 -0000
@@ -26,6 +26,143 @@
 #include "support.h"
 #include "pthread_rdwr.h"
 
+ICQUserCategory::ICQUserCategory()
+{	
+	used = 0;
+}
+
+ICQUserCategory::~ICQUserCategory()
+{
+	Clean();
+}
+
+void ICQUserCategory::Clean()
+{	unsigned short i;
+
+	for( i = 0; i<used ; i++ )
+		free( (void *) data[i].descr );
+
+}
+
+bool ICQUserCategory::SaveToDisk(CIniFile &m_fConf,const char *const szN,
+                             const char *const szCat,const char *const szDescr )
+{	char buff[255];
+	unsigned short i;
+
+
+	if (!m_fConf.ReloadFile())
+	{	 gLog.Error("%sError opening '%s' for reading.\n"
+   		    "%sSee log for details.\n", L_ERRORxSTR, m_fConf.FileName(),
+   		    L_BLANKxSTR);
+		return false;
+	}
+
+	m_fConf.SetSection("user");
+	m_fConf.WriteNum(szN, used);
+
+	for( i=0 ; i < used ; i ++ )
+	{	snprintf(buff,sizeof(buff),szCat,i);
+		m_fConf.WriteNum( buff, data[i].id );
+		snprintf(buff,sizeof(buff),szDescr,i);
+		m_fConf.WriteStr(buff,data[i].descr );
+	}
+
+	if (!m_fConf.FlushFile())
+	{	gLog.Error(	"%sError opening '%s' for writing.\n"
+				"%sSee log for details.\n", L_ERRORxSTR,
+				m_fConf.FileName(), L_BLANKxSTR);
+		return false;
+	}
+
+	m_fConf.CloseFile();
+	return true;
+}
+
+bool ICQUserCategory::LoadFromDisk(CIniFile &m_fConf, const char *const szN,
+       const char *const szCat,const char *const szDescr )
+{	unsigned short i,j,ret,n;
+	char buff[255];
+	char szTemp[MAX_DATA_LEN];
+
+	Clean();
+	m_fConf.SetSection("user");
+	ret = m_fConf.ReadNum(szN,used,0 );
+
+	if( used > MAX_CATEGORIES)
+	{	gLog.Warn("%sTrying to load more categories than the max limit."
+		          "Truncating.\n",L_WARNxSTR);
+		used = MAX_CATEGORIES;
+	}
+
+	for( i=j=0, n=used ; i<n ; i++)
+	{	snprintf(buff,sizeof(buff),szCat,i);
+		ret = m_fConf.ReadNum( buff, data[j].id,0);
+
+		snprintf(buff,sizeof(buff),szDescr,i);
+		if( ret )
+		{	ret = m_fConf.ReadStr(buff,szTemp);
+			if( ret )
+			{	data[j].descr = strdup(szTemp);
+				if(  data[j].descr == NULL )
+					ret = 0;
+			}		
+		}
+		/* this one failed loading. we ignore and keep trying */
+		if( !ret )
+			used--;
+		else 
+			j++;
+	}
+	return true;
+}
+
+bool ICQUserCategory::AddCategory(unsigned short cat_, const char *descr_)
+{ 	bool nRet = true;
+	
+	if( used == MAX_CATEGORIES || descr_ == 0)
+		nRet =  false;
+	else 
+	{
+		used ++;
+		data[used].id = cat_;
+		data[used].descr = strdup(descr_);
+	
+		if( data[used].descr == NULL )
+		{	nRet = false;
+			used--;
+		}
+			
+	}
+
+	return nRet;
+}
+
+unsigned ICQUserCategory::begin()
+{	
+	return 0;
+}
+
+bool ICQUserCategory::get(unsigned *d,short unsigned *id, char const*  * descr)
+{	bool nRet;
+
+	assert ( d && id && descr );
+	if( nRet = (*d != used ) )
+	{	nRet = true;
+		*id = data[*d].id;
+		*descr = (const char *)data[*d].descr;
+		(*d)++;
+		
+	}
+
+	return nRet;
+}
+
+void ICQUserCategory::end( unsigned *d )
+{
+	return ;
+}
+
+//===========================================================================
 class CUserManager gUserManager;
 
 const char *GroupsSystemNames[NUM_GROUPS_SYSTEM+1] = {
@@ -1079,6 +1216,9 @@ bool ICQUser::LoadInfo()
   LoadMoreInfo();
   LoadWorkInfo();
   LoadAboutInfo();
+  LoadInterestsInfo();
+  LoadBackgroundsInfo();
+  LoadAffiliationInfo();
   LoadLicqInfo();
 
   return true;
@@ -1290,6 +1430,9 @@ ICQUser::~ICQUser()
       free( m_szAbout );
   if ( m_szCustomAutoResponse )
       free( m_szCustomAutoResponse );
+  delete m_Interests;
+  delete m_Backgrounds;
+  delete m_Affiliations;
 
 /*
   // Destroy the mutex
@@ -1363,6 +1506,11 @@ void ICQUser::Init(unsigned long _nUin)
   m_nLanguage[1] = 0;
   m_nLanguage[2] = 0;
 
+  // More2
+  m_Interests    = new ICQUserCategory();
+  m_Backgrounds  = new ICQUserCategory();
+  m_Affiliations = new ICQUserCategory();
+  
   // Work Info
   m_szCompanyCity = NULL;
   m_szCompanyState = NULL;
@@ -2145,6 +2293,61 @@ void ICQUser::SaveAboutInfo()
    m_fConf.CloseFile();
 }
 
+//-----ICQUser::Save<categories>Info()-----------------------------------------
+static const char *const szN_int    = "InterestN";
+static const char *const szCat_int  = "InterestsCat%04X";
+static const char *const szDesc_int = "InterestsDesc%04X";
+
+static const char *const szN_bac    = "BackgroundsN";
+static const char *const szCat_bac  = "BackgroundsCat%04X";
+static const char *const szDesc_bac = "BackgroundsDesc%04X";
+
+static const char *const szN_aff    = "AffiliationN";
+static const char *const szCat_aff  = "AffiliationCat%04X";
+static const char *const szDesc_aff = "AffiliationDesc%04X";
+
+
+void ICQUser::SaveInterestsInfo()
+{
+	if (!EnableSave()) 
+		return;
+
+	m_Interests->SaveToDisk(m_fConf,szN_int, szCat_int, szDesc_int);
+}
+
+void ICQUser::LoadInterestsInfo()
+{
+	m_Interests->LoadFromDisk(m_fConf,szN_int, szCat_int, szDesc_int);
+
+}
+
+void ICQUser::SaveBackgroundsInfo()
+{
+	if (!EnableSave()) 
+		return;
+
+
+	m_Backgrounds->SaveToDisk(m_fConf,szN_bac, szCat_bac, szDesc_bac);
+}
+
+void ICQUser::LoadBackgroundsInfo()
+{
+
+	m_Backgrounds->LoadFromDisk(m_fConf,szN_bac, szCat_bac, szDesc_bac);
+}
+
+void ICQUser::SaveAffilationsInfo()
+{
+	if (!EnableSave()) 
+		return;
+
+	m_Affiliations->SaveToDisk(m_fConf,szN_aff,szCat_aff, szDesc_aff);
+}
+
+void ICQUser::LoadAffiliationInfo()
+{
+	m_Affiliations->LoadFromDisk(m_fConf, szN_aff,szCat_aff, szDesc_aff);
+}
 
 //-----ICQUser::SaveLicqInfo-------------------------------------------------
 void ICQUser::SaveLicqInfo()
--- /dev/null	1969-12-31 21:00:00.000000000 -0300
+++ plugins/qt-gui/src/catdlg.cpp	2002-07-17 13:43:00.000000000 -0300
@@ -0,0 +1,99 @@
+/*
+ *  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) any later version.
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qapplication.h>
+#include <qwidget.h>
+
+#include "catdlg.h"
+
+
+EditCategoryDlg::EditCategoryDlg(QWidget *parent = 0,
+                                 const struct category *table=0)
+  : QDialog(parent, "AwayMessageDialog", false, WDestructiveClose)
+{ 	QBoxLayout* top_lay,*ll,* l;
+	int bw = 200; 
+	unsigned i,j;
+	ICQUserCategory *cat;
+	if( table == 0 )
+		return;
+	top_lay = new QVBoxLayout(this, 10);
+	l = new QHBoxLayout(top_lay, 10);
+	Q_CHECK_PTR(l); Q_CHECK_PTR(top_lay);
+	
+	btnOk = new QPushButton(tr("&Ok"), this );
+	Q_CHECK_PTR(btnOk);
+	btnOk->setDefault(true);
+	connect( btnOk, SIGNAL(clicked()), SLOT(ok()) );
+
+	btnCancel = new QPushButton(tr("&Cancel"), this );
+	Q_CHECK_PTR(btnCancel);
+	connect( btnCancel, SIGNAL(clicked()), SLOT(close()) );
+
+	bw = QMAX(bw, btnOk->sizeHint().width());
+	bw = QMAX(bw, btnCancel->sizeHint().width());
+
+	btnOk->setFixedWidth(bw);
+	btnCancel->setFixedWidth(bw);
+
+	for( i = 0 ; i < MAX_CAT ; i++ )
+	{
+		ll = new QHBoxLayout(top_lay, 10);
+		Q_CHECK_PTR(ll);
+		cbCat[i] = new QComboBox(this);
+		Q_CHECK_PTR(cbCat[i]);
+		cbCat[i]->insertStringList("Select One",0);
+		for( j = 0; table[j].str ; j++ )
+			cbCat[i]->insertStringList(table[j].str,table[j].cat);
+	
+		leDescr[i] = new QLineEdit(this);
+		Q_CHECK_PTR(leDescr);
+		leDescr[i]->setMaxLength( MAX_CATEGORY_SIZE );
+		ll->addWidget(cbCat[i]);
+		ll->addWidget(leDescr[i]);
+	}
+	gUserManager.DropOwner();
+	l->addWidget(btnOk);
+	l->addWidget(btnCancel);
+}
+
+
+// -----------------------------------------------------------------------------
+
+EditCategoryDlg::~EditCategoryDlg()
+{
+	emit done();
+}
+
+// -----------------------------------------------------------------------------
+
+void EditCategoryDlg::ok()
+{	ICQOwner *o ;
+
+	o = gUserManager.FetchOwner(LOCK_W);
+	// do something
+	gUserManager.DropOwner();
+	close();
+}
+
+// -----------------------------------------------------------------------------
+
+
+#include "catdlg.moc"
--- /dev/null	1969-12-31 21:00:00.000000000 -0300
+++ plugins/qt-gui/src/catdlg.h	2002-07-13 22:27:55.000000000 -0300
@@ -0,0 +1,36 @@
+#ifndef CATDLG_H
+#define CATDLG_H
+
+#include <qdialog.h>
+
+#include "licq_user.h"
+
+class QPushButton;
+class QComboBox;
+class QLineEdit;
+
+struct category
+{	unsigned short cat;
+	const char *const str;
+};
+
+class EditCategoryDlg : public QDialog
+{
+	Q_OBJECT
+public:
+	EditCategoryDlg(QWidget *parent = 0,const struct category *table=0);
+	~EditCategoryDlg();
+
+protected:
+	static const unsigned MAX_CAT = ICQUserCategory::MAX_CATEGORIES;
+	QPushButton *btnOk, *btnCancel;
+	QComboBox *cbCat[MAX_CAT];
+	QLineEdit *leDescr[MAX_CAT];
+signals:
+	void done();
+
+protected slots:
+	void ok();
+};
+
+#endif
