standard.net.ym

standard.net.ym is available since version 1.0.
Import library : standard.net.ym
(you must include this at the top of your source: "import standard.net.ym" (no quotes) Require : standard.net.ym

Description:

Yahoo! Messenger client library based on the libyahoo library.

TODO: Documentation. Only example is available for now.

Methods

TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
TODO: Document this
Example
include lang.con

import standard.net.ym
import standard.C.io
import standard.lib.str
import standard.lib.thread

include Application.con
include RButton.con
include RVBox.con
include RHBox.con
include RHButtonBox.con
include RTreeView.con
include RNotebook.con
include RScrolledWindow.con
include RStatusbar.con
include RCombobox.con
include RImage.con
include RVPaned.con
include RTextView.con
include RFrame.con
include REdit.con
include RCheckButton.con
include RLabel.con
include Serializable.con
include RHButtonBox.con

define 	MSG_IM			0x1000
define 	MSG_ADDED		0x1001
define 	MSG_MAIL		0x1002


define MAX_NOTIFY		10

class Message extends Serializable {
	var who="";
	var name="";
	var msg="";
}

class BeAdded extends RForm {
	var InfoText;
	var RejectText;
	var lbl1;
	var who="";
	var delegate;

	public function AcceptClicked(Sender, EventData) {
		delegate(1);
		Hide();
	}

	public function RejectClicked(Sender, EventData) {
		//yahoo_reject_buddy(who, RejectText.Text);
		delegate(0, RejectText.Text);
		Hide();
	}

	public function EventHide(Sender, EventData) {
		delegate(0, RejectText.Text);
	}

	public function BeAdded(Owner, who, msg, deleg) {
		BeginUpdateSession();
		super(Owner);
		delegate=deleg;

		var vbox=new RVBox(this);
		vbox.Show();
		lbl1=new RLabel(vbox);
		lbl1.Caption=LANG_WANTS_TO_ADD;
		lbl1.Show();

		InfoText=new RTextView(vbox);
		InfoText.CursorVisible=false;
		InfoText.ReadOnly=true;
		InfoText.Text=msg;
		InfoText.Show();


		var lbl2=new RLabel(vbox);
		lbl2.Caption=LANG_REJECT_MESSAGE;
		lbl2.Show();

		RejectText=new RTextView(vbox);
		RejectText.Text=DEFAULT_REJECT;
		RejectText.Show();

		var btnbox=new RHButtonBox(vbox);
		btnbox.Show();

		var btn1=new RButton(btnbox);
		btn1.Caption=LANG_ACCEPT;
		btn1.OnClicked=AcceptClicked;
		btn1.Show();

		var btn2=new RButton(btnbox);
		btn2.Caption=LANG_REJECT;
		btn2.OnClicked=RejectClicked;
		btn2.Show();

		BorderWidth=20;

		Width=200;
		Height=200;

		Caption=LANG_ADD_REQUEST;
		SkipTaskbar=true;

		Decorations=DECOR_TITLE;
		Type=WT_DIALOG;

		Modal=true;
		OnHide=EventHide;
		EndUpdateSession();
	}
}

class LoginForm extends RForm {
	var EditUser;
	var EditPass;
	var CheckInvisible;
	var Button;

	var delegate;

	function LogInClicked(Sender, EventData) {
		delegate(EditUser.Text, EditPass.Text, CheckInvisible.Checked);
		Hide();
	}

	function LoginForm(Owner, deleg) {
		super(Owner);

		BeginUpdateSession();
		Caption=LANG_SIGN_IN;

		delegate=deleg;
		var Frame=new RFrame(this);
		Frame.Caption=LANG_Y_ACCOUNT;
		Frame.Show();

		var vbox=new RVBox(Frame);
		vbox.Show();

		var lbl1=new RLabel(vbox);
		lbl1.Caption=LANG_USERNAME;
		lbl1.Show();

		EditUser=new REdit(vbox);
		EditUser.ActivateDefault=true;
		EditUser.Show();

		EditPass=new REdit(vbox);
		EditPass.Masked=true;
		EditPass.MaskedChar="*";
		EditPass.ActivateDefault=true;
		EditPass.Show();

		var lbl2=new RLabel(vbox);
		lbl2.Caption=LANG_PASSWORD;
		lbl2.Show();

		CheckInvisible=new RCheckButton(vbox);
		CheckInvisible.Caption=LANG_SIGN_INVISIBLE;
		CheckInvisible.Checked=false;
		CheckInvisible.Show();

		Button=new RButton(vbox);
		Button.Caption=LANG_SIGN_IN;
		Button.OnClicked=LogInClicked;
		Button.Show();

		Modal=true;
		DefaultControl=Button;
		EndUpdateSession();
	}
}

class IMForm extends RForm {
	var TextView;
	var ScrollView;
	var InputView;
	var Status;
	var yid="";
	var my_id="";
	//var names;


	public function Timer(Sender, EventData) {
		Urgent=false;
	}

	public function SetTyping(flag) {
		if (flag) {
			Status.Caption=yid+" "+LANG_TYPING;
		} else {
			Status.Caption="";
		}
	}

	public function AddMessage(who, message, name) {
		BeginUpdateSession();
		var must_scroll=false;

		/*if (names[who])
			who=names[who];*/

		var vadj=ScrollView.VAdjustment;
		if (vadj.Value==vadj.Upper-vadj.PageSize)
			must_scroll=true;

		if (name)
			who=name;

		TextView.AddStyledText(who+": ","otheruser");
		TextView.AddStyledText(message+"\n","text");

		if (must_scroll)
			vadj.Value=vadj.Upper-vadj.PageSize;
		Urgent=true;
		AddTimer(Timer, 3000);
		EndUpdateSession();
	}

	public function SendClicked(Sender, EventData) {
		var text=InputView.Text;

		if (text) {
			BeginUpdateSession();
			InputView.Text="";
			var must_scroll=false;
			var vadj=ScrollView.VAdjustment;
			if (vadj.Value==vadj.Upper-vadj.PageSize)
				must_scroll=true;

			TextView.AddStyledText(my_id+": ","myuser");
			TextView.AddStyledText(text+"\n","text");
			EndUpdateSession();

			if (must_scroll)
				vadj.Value=vadj.Upper-vadj.PageSize;

			yahoo_send_im(yid,text,false);
		}
	}

	public function IMForm(Owner, who, my_id, names) {
		super(null);
		//this.names=names;
		LinkIfNotLinked(Owner);

		var vbox=new RVBox(this);
		vbox.Show();
		yid=who;
		this.my_id=my_id;

		var hpane=new RVPaned(vbox);
		hpane.Show();
		hpane.Position=280;

		ScrollView=new RScrolledWindow(hpane);
		ScrollView.HScrollPolicy=POLICY_AUTOMATIC;
		ScrollView.VScrollPolicy=POLICY_ALWAYS;
		ScrollView.Show();

		TextView=new RTextView(ScrollView);
		TextView.CursorVisible=false;
		TextView.ReadOnly=true;
		TextView.LeftMargin=5;
		TextView.RightMargin=5;
		TextView.Wrap=WRAP_WORD;
		TextView.Show();

		var style0=TextView.CreateStyle("text");
		style0.FontName="arial 10";
		style0.ForeColor=0x000000;

		var style1=TextView.CreateStyle("myuser");
		style1.FontName="arial bold 10";
		style1.ForeColor=0x505050;

		var style2=TextView.CreateStyle("otheruser");
		style2.FontName="arial bold 10";
		style2.ForeColor=0x0000A0;


		var hbox=new RHBox(hpane);
		hbox.Packing=PACK_SHRINK;
		hbox.Show();

		var Scroll1=new RScrolledWindow(hbox);
		Scroll1.HScrollPolicy=POLICY_AUTOMATIC;
		Scroll1.VScrollPolicy=POLICY_AUTOMATIC;
		Scroll1.Show();

		InputView=new /*RTextView*/REdit(Scroll1);
		InputView.Packing=PACK_EXPAND_WIDGET;
		InputView.Font.Name="arial 10";
		InputView.ActivateDefault=true;
		InputView.Show();
		
		var Button=new RButton(hbox);
		Button.Caption=LANG_SEND;
		Button.Packing=PACK_SHRINK;
		Button.MinWidth=75;
		Button.OnClicked=SendClicked;
		Button.Show();

		Width=500;
		Height=350;
		DefaultControl=Button;

		Status=new RStatusbar(vbox);
		Status.Show();
	}
}


class MainForm extends RForm {
	var Tabs;
	var Buddies;
	var AddressBook;
	var StatusBar;
	var StatusCombo;
	var yab_done=false;
	var[] groups;
	var[] Images;
	var[] ids;
	var   my_id="";
	var   to_add=-1;
	var   reject_reason="";
	var   ScrollStatus;
	var   StatusList;


	var[] IM_windows;

	var logindialog;

	public function Notify(evt,text) {
		StatusList.InsertItem(0, [ Images[evt],text]);

		while (StatusList.Items.Count>MAX_NOTIFY)
			StatusList.DeleteItem(StatusList.Items.Count-1);
	}

	function GetIMWindow(who) {
		var len=length IM_windows;
		
		if (IM_windows[who]) {
			IM_windows[who].Show();
			//IM_windows[who].Urgent=true;
		} else {
			IM_windows[who]=new IMForm(this, who, my_id, ids);
			IM_windows[who].Show();
			IM_windows[who].Caption=""+ids[who]+" ("+who+") -- "+LANG_INSTANT_MESSAGE;
			//IM_windows[who].Urgent=true;
		}
		return IM_windows[who];
	}


	function OnIM(id, who, msg, tm, stat, utf8) {
		//var frm=GetIMWindow(who);
		//frm.AddMessage(who, msg);
		var im=new Message();

		im.who=who;
		im.msg=msg;
		im.name=ids[who];

		SendAPMessage(GetAPID(), MSG_IM, im.Serialize(""));
	}

	function OnStatus(id, who, stat, msg, away) {
		//echo "$who is now ${yahoo_status_code(stat)}/$away/$msg\n";
		var buddie=this.FindId(who);
		if (buddie) {
			var item=Buddies.Items.GetPath(buddie);

			if (stat!=YAHOO_STATUS_OFFLINE) {
				item[0]=Images["online"];
				if (item[3]==1) {
					who=item[1];
					Notify("online", LANG_IS_NOW_AVAILABLE);
					item[3]=2;
				}
				item[2]=yahoo_status_code(stat);
			} else {
				item[0]=Images["offline"];
				item[3]=1;
				who=item[1];
				Notify("offline", LANG_IS_NOW_OFFLINE);
				item[2]=" ";
			}

			Buddies.UpdateItem(buddie, item);
		}
	}

	function OnType(id, who, stat) {
		var frm=GetIMWindow(who);
		frm.SetTyping(stat);
	}

	function OnYab(id, arr) {
		var len=length arr;

		// group messages (optimeze Concept network traffic)
		BeginUpdateSession();
		for (var i=0;i<len;i++) {
			var arr2=arr[i];
			var group=arr2["group"];
			if (arr2["id"]) {

				if (typeof groups[group]!="string") {
					groups[group]=group;

					Buddies.AddItem([ Images["group"], group, "(group)", 0, 0]);
				}

				groups[group]=group;

				var path=this.FindGroup(group);

				var name="";
				if (arr2["yab_entry"]) {
					name=arr2["yab_entry"]["fname"]+" "+arr2["yab_entry"]["lname"];
					yab_done=true;
				}

				if (path>=0) {
					var bud_id=this.FindId(arr2["id"]);
					if (bud_id) {
						var item_upd=Buddies.Items.GetPath(bud_id);
						if ((item_upd) && (item_upd[1]!=name) && (trim(name))) {
							var bud_item=Buddies.Items.GetPath(bud_id);
							bud_item[1]=name;
							Buddies.UpdateItem(bud_id, bud_item);
							ids[arr2["id"]]=name;
						}
					} else {
						if (!trim(name))
							name=arr2["id"];

						ids[arr2["id"]]=name;
						Buddies.AddChild([path], [ Images["offline"], name, "", 1, arr2["id"] ]);
					}
				}
			}
		}
		Buddies.ExpandAll();
		EndUpdateSession();

	}

	public function OnContact(id, myid, who, msg) {
		var my_msg=new Message();
		my_msg.who=who;
		my_msg.msg=msg;
		to_add=-1;

		SendAPMessage(GetAPID(), MSG_ADDED, my_msg.Serialize(""));

		while (to_add==-1) {
			Sleep(1000);
		}

		if (!to_add)
			yahoo_reject_buddy(who, reject_reason);
	}

	public function Login(username, password, invisible=false) {
		my_id=username;
		if (invisible)
			yahoo_login(username,password,YAHOO_STATUS_INVISIBLE);
		else
			yahoo_login(username,password,YAHOO_STATUS_AVAILABLE);
		
	}

	public function OnError(id, err, fatal) {
		CApplication::MessageBox(err);
	}

	public function OnSysMsg(id, msg) {
		CApplication::MessageBox(msg);
	}

	public function FindId(id) {
		var len=Buddies.Items.Count;
		for (var i=0;i<len;i++) {
			var item=Buddies.Items.GetPath(i);
			
			var j=0;
			do {
				var child_item=Buddies.Items.GetPath([i,j]);
				if ((child_item) && (child_item[4]==id))
					return [i,j];
				j++;
			} while (child_item);
		}
		return 0;
	}


	public function FindGroup(group) {
		var len=Buddies.Items.Count;
		for (var i=0;i<len;i++) {
			var item=Buddies.Items.GetPath(i);
			if (item[1]==group) {
				return i;
			}
		}
		return -1;
	}


	public function TimerBuddies(Sender,EventData) {
		yahoo_get_yab();
	}

	public function OnLogin(id, succ, url) {
		var err;

		switch (succ) {
			case YAHOO_LOGIN_OK:
				StatusBar.Caption=LANG_LOGGED;
				// don't interrupt this procedure (no yahoo function should be called here ... so ... add a timer !)
				AddTimer(TimerBuddies,1000);
				break;
			case YAHOO_LOGIN_UNAME:
				err="Could not log into Yahoo service - username not recognised.  Please verify that your username is correctly typed.";
				break;
			case YAHOO_LOGIN_PASSWD:
				err="Could not log into Yahoo service - password incorrect.  Please verify that your password is correctly typed.";
				break;
			case YAHOO_LOGIN_LOCK:
				err="Could not log into Yahoo service.  Your account has been locked.\nVisit $url to reactivate it.";
				break;
			case YAHOO_LOGIN_DUPL:
				err="You have been logged out of the yahoo service, possibly due to a duplicate login.";
				break;
			case YAHOO_LOGIN_SOCK:
				err="The server closed the socket.";
				break;
			default:
				err="Could not log in, unknown reason: $succ.";
		}

		if (err) {
			CApplication::MessageBox(err);
			logindialog.Show();
			logindialog.Raise();
		}
	}


	public function SimpleOnMail(from, subj, cnt) {
		if (from)
			Notify("mail", LANG_MAIL);
		if (cnt)
			Notify("multimail", LANG_MULTIMAIL);
	}

	public function OnMail(id, from, subj, cnt) {
		// reusing Message to store mail data
		var msg=new Message();

		msg.who=from;
		msg.msg=subj;
		msg.name=cnt;		

		SendAPMessage(GetAPID(), MSG_MAIL, msg.Serialize(""));
	}

	private function InitYahoo() {
		yahoo_set_callback(YM_ON_GOT_IM, OnIM);
		yahoo_set_callback(YM_ON_TYPING_NOTIFY, OnType);
		yahoo_set_callback(YM_ON_STATUS_CHANGED, OnStatus);
		yahoo_set_callback(YM_ON_GOT_BUDDIES, OnYab);

		yahoo_set_callback(YM_ON_YAHOO_ERROR, OnError);
		yahoo_set_callback(YM_ON_SYSTEM_MESSAGE, OnSysMsg);
		yahoo_set_callback(YM_ON_LOGIN_RESPONSE, OnLogin);

		yahoo_set_callback(YM_ON_CONTACT_ADDED, OnContact);

		yahoo_set_callback(YM_ON_MAIL_NOTIFY, OnMail);
		
	}

	public function OnBuddySelect(Sender, EventData) {
		var path=Sender.RowIndex;
		if (path!="-1") {
			var item=Buddies.Items.GetPath(path);
			var who=item[4];

			GetIMWindow(who);
		}
	}

	private function LoadImages() {
		var img=new RImage(null);
		img.Filename="res/offline.gif";
		Images["offline"]=img;
		
		var img1=new RImage(null);
		img1.Filename="res/online.gif";
		Images["online"]=img1;

		var img2=new RImage(null);
		img2.Filename="res/friend_root.bmp";
		Images["group"]=img2;

		var img3=new RImage(null);
		img3.Filename="res/mail.gif";
		Images["mail"]=img3;

		var img4=new RImage(null);
		img4.Filename="res/multiplemail.gif";
		Images["multimail"]=img4;
	}

	public function StatusChanged(Sender, EventData) {
		var index=StatusCombo.RowIndex;
		var status=-1;

		switch (index) {
			case 0:
				status=YAHOO_STATUS_AVAILABLE;
				break;
			case 1:
				status=YAHOO_STATUS_BRB;
				break;
			case 2:
				status=YAHOO_STATUS_BUSY;
				break;
			case 3:
				status=YAHOO_STATUS_NOTATHOME;
				break;
			case 4:
				status=YAHOO_STATUS_NOTATDESK;
				break;
			case 5:
				status=YAHOO_STATUS_NOTINOFFICE;
				break;
			case 6:
				status=YAHOO_STATUS_ONPHONE;
				break;
			case 7:
				status=YAHOO_STATUS_ONVACATION;
				break;
			case 8:
				status=YAHOO_STATUS_OUTTOLUNCH;
				break;
			case 9:
				status=YAHOO_STATUS_STEPPEDOUT;
				break;
			case 10:
				status=YAHOO_STATUS_INVISIBLE;
				break;
			case 11:
				status=YAHOO_STATUS_IDLE;
				break;
			case 12:
				status=YAHOO_STATUS_OFFLINE;
				break;
			case 13:
				status=YAHOO_STATUS_CUSTOM;
				break;
			case 14:
				status=YAHOO_STATUS_NOTIFY;
				break;
		}
		if (status!=-1)
			yahoo_set_away(status,"", 1);
	}

	public function OnAcceptAdd(added, rejtxt="") {
		to_add=added;
		reject_reason=rejtxt;
	}

	public function DebugCallback(SenderAPID, MSGID, szData) {
		switch (MSGID) {
			case MSG_IM:
				var im2=Serializable.UnSerialize(szData, true);
				if (im2) {
					var frm=GetIMWindow(im2.who);
					if (frm)
						frm.AddMessage(im2.who, im2.msg, im2.name);
				}
				break;
			case MSG_ADDED:
				im2=Serializable.UnSerialize(szData, true);
				if (im2) {
					var b=new BeAdded(this, im2.who, im2.msg, OnAcceptAdd);
					b.Show();
				}
				break;
			case MSG_MAIL:
				im2=Serializable.UnSerialize(szData, true);
				if (im2) {
					SimpleOnMail(im2.who, im2.msg, im2.name);
				}
				break;			
		}
	}

	public function MainForm(Owner) {
		super(Owner);
		Caption=LANG_APP_NAME;

		var box=new RVBox(this);
		box.Show();

		StatusCombo=new RComboBox(box);
		StatusCombo.Show();
		StatusCombo.AddColumns(1);


		StatusCombo.AddItem(STATUS_AVAILABLE);
		StatusCombo.AddItem(STATUS_BRB);
		StatusCombo.AddItem(STATUS_BUSY);
		StatusCombo.AddItem(STATUS_NOTATHOME);
		StatusCombo.AddItem(STATUS_NOTATDESK);
		StatusCombo.AddItem(STATUS_NOTINOFFICE);
		StatusCombo.AddItem(STATUS_ONPHONE);
		StatusCombo.AddItem(STATUS_ONVACATION);
		StatusCombo.AddItem(STATUS_OUTTOLUNCH);
		StatusCombo.AddItem(STATUS_STEPPEDOUT);
		StatusCombo.AddItem(STATUS_INVISIBLE);
		StatusCombo.AddItem(STATUS_IDLE);
		StatusCombo.AddItem(STATUS_OFFLINE);
		StatusCombo.AddItem(STATUS_CUSTOM);
		StatusCombo.AddItem(STATUS_NOTIFY);
		StatusCombo.OnChanged=StatusChanged;
		StatusCombo.RowIndex=0;


		var hpaned=new RVPaned(box);
		hpaned.Show();

		Tabs=new RNotebook(hpaned);
		Tabs.Show();

		var scroll1=new RScrolledWindow(Tabs);
		scroll1.HScrollPolicy=POLICY_AUTOMATIC;
		scroll1.VScrollPolicy=POLICY_AUTOMATIC;
		scroll1.Show();

		Buddies=new RTreeView(scroll1);
		Buddies.Model=MODEL_TREEVIEW;
		Buddies.Sorted=true;
		Buddies.SortColumn=1;
		Buddies.OnRowActivated=OnBuddySelect;
		Buddies.AddColumn(" ", IMAGE_COLUMN);
		Buddies.AddColumn("Contact", NORMAL_COLUMN);
		Buddies.AddColumn("Status", NORMAL_COLUMN);
		Buddies.SearchColumn=2;
		Buddies.HoverSelection=true;
		Buddies.HeadersVisible=false;

		Buddies.Show();
		Tabs.Pages[0].Caption=LANG_MESSENGER;

		var scroll2=new RScrolledWindow(Tabs);
		scroll2.HScrollPolicy=POLICY_AUTOMATIC;
		scroll2.VScrollPolicy=POLICY_AUTOMATIC;
		//scroll2.Show();

		AddressBook=new RTreeView(scroll2);
		AddressBook.Model=MODEL_LISTVIEW;
		AddressBook.Show();
		Tabs.Pages[1].Caption=LANG_ADDRESSBOOK;

		var ScrollStatus=new RScrolledWindow(hpaned);
		ScrollStatus.HScrollPolicy=POLICY_AUTOMATIC;
		ScrollStatus.VScrollPolicy=POLICY_AUTOMATIC;
		ScrollStatus.Show();

		StatusList=new RTreeView(ScrollStatus);
		StatusList.Model=MODEL_LISTVIEW;
		StatusList.HeadersVisible=false;
		StatusList.HoverSelection=true;

		StatusList.AddColumn(" ", IMAGE_COLUMN);
		StatusList.AddColumn("Event", NORMAL_COLUMN);
		StatusList.Show();
		

		hpaned.Position=450;
		StatusBar=new RStatusbar(box);
		StatusBar.Show();
		StatusBar.Caption=LANG_NOT_LOGGED;

		LoadImages();
		InitYahoo();

		Width=250;
		Height=600;

		logindialog=new LoginForm(this, Login);
		logindialog.Show();

	}
}


class Main {
	function Main() {
			try {
				var Application=new CApplication(new MainForm(NULL));
				Application.ShellDebug=Application.ApplicationForm.DebugCallback;


				Application.Init();
				Application.Run();
				Application.Done();

			} catch (var Exception) {
				echo Exception;
			}
	}
}