⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 object.class

📁 是一个经济学管理应用软件 很难找的 但是经济学学生又必须用到
💻 CLASS
📖 第 1 页 / 共 2 页
字号:
/*                                object

	Base class for all objects
*/
*! version 1.0.1  02jul2003

version 8

class {
    class:
	class dbstyle dbstyle
}

/* -------------------------------------------------------------------------*/
/*  Returns the name of the class, instance, or dynamic attribute at the
    specified index of the requested (classmv, instancemv, or dynamicmv) array.

	Usage:  attribname array_name index

		where:  array_name is "classmv", "instancemv", or "dynamicmv"
*/

program define attribname 

	capture _cls nameoflocal .`1'[`2']
	class exit `"`r(name)'"'
end


/* -------------------------------------------------------------------------*/
/*  Pops the last command off the command log.

	Usage:  .poplog

*/

program define poplog

	.popifendsin poplog
	.__LOG.Arrpop 
end


/* -------------------------------------------------------------------------*/
/*  Pops the last command off the command log if the command terminates in
    <str>.  Note <str> may not contain ".", or "]", or " ".

	Usage:  .popifendsin str

*/

program define popifendsin

	args str

	local lastcmd `.__LOG[`.__LOG.arrnels']'

	gettoken tok lastcmd : lastcmd , parse(".] ")
	while `"`lastcmd'"' != `""' {
		gettoken tok lastcmd : lastcmd , parse(".] ")
	}

	if `"`tok'"' == `"`str'"' {
		.__LOG.Arrpop
	}
end


/* -------------------------------------------------------------------------*/
/*  Pops the last command if it contains <str>

	Usage:  .popifcontains str

*/

program define popifcontains

	args str

	local lastcmd `.__LOG[`.__LOG.arrnels']'

	local str : subinstr local lastcmd `"`str'"' `"`str'"', count(local ct)

	if `ct' {
		.__LOG.Arrpop
	}
end

/* -------------------------------------------------------------------------*/
/* Saves all objects of the specified class that are attributes of the 
   specified object or any object it contains recursively.  
   Builds a Map of the keys of the saved objects.
*/

program define saveall

	args class save

						// recurse on all attribs
	foreach attrib_arr in instancemv dynamicmv {
		if 0`.`attrib_arr'.arrnels' {
			_saveall_arr `attrib_arr' `class' `save'
		}
	}

	if ! `.isofclass `class'' {			// not saving these
		exit
	}
	if "`.__Map.`.uname'.isa'" != "" {	// already saved
		exit
	}
	.__Map.Declare `.uname' = .ref		// maintain map

	if `save' {
		if "`._scheme.isa'" != "" {
			local scm <UseScheme> `._scheme.uname'
		}
		file write $T_loghndl 					///
			"<BeginItem> `.classname' `.uname' `scm'" _n
		if !`.isofclass serset' | 0$T_savesers {
			.savetofile $T_loghndl		 // object's own save 
		}
		file write $T_loghndl "<EndItem>" _n
	}

end

program define _saveall_arr
	args array class save

	forvalues i = 1/0`.`array'.arrnels' {
		local attrib `array'[`i']

		if "`.`attrib'.isa'" == "class" {
			if `.`attrib'.isofclass cell' |			/*
			*/ "`.`attrib'.classname'" == "serset"  |	/*
			*/ `.`attrib'.isofclass scheme'    |		/*
			*/ `.`attrib'.isofclass container' {
				.`attrib'.saveall `class' `save'
			}
		}
		else if "`.`attrib'.isa'" == "array" {
			_saveall_arr `attrib' `class' `save'
		}
	}
end

/* -------------------------------------------------------------------------*/
/* Default program for an object to save itself to disk.
   If the object has a __LOG array, then that log is saved, regardless 
   <EndItem> is spewed.
*/
 
program define savetofile
	args filehndl

	if "`.Local.__LOG.isa'" == "array" {
		forvalues i = 1/0`.__LOG.arrnels' {
			file classwrite `filehndl' __LOG[`i']
			file write `filehndl' _n
		}
	}

end

/* -------------------------------------------------------------------------*/
/* Default program to run a log for an item from a file.  Each line 
   tends to be,

         .<memberpgm or memberattrib>....

   Often the first few lines of the object's log are processed by the object,
   then runfromfile is called to run the remaining lines in the class context.
   Processes log until an <EndItem> is encountered.

*/

program define runfromfile
	args loghndl

	local push 1
	file read `loghndl' cmd
	gettoken tok : cmd
	while "`tok'" != "<EndItem>" & r(eof) == 0 {
	    if "`tok'" == "<BeginCmd>" {		/* stop push */
		local push 0
	    }
	    else if "`tok'" == "<EndCmd>" {		/* restart push */
		local push 1
	    }
	    else {
	    	if "`tok'" == "__NOLOG__" {
			gettoken tok cmd : cmd
			local push2 0
		}
		else	local push2 1

		if 0$T_nostyles {
		    if ! 0`._is_scheme_edit `cmd'' {
			`cmd'
			if `push' & `push2' {
			    gettoken target : cmd , parse(" =")
			    if substr(`"`target'"', 1, 9) == ".sersets[" {
						// must get new serset key
				.__LOG.Arrpush `target' =		///
					.__Map.``target'.uname'.ref
			    }
			    else {			// Standard "push"
				.__LOG.Arrpush `macval(cmd)'
			    }
			}
		    }
		}
		else {
		    `cmd'
		    if `push' & `push2' {
			    gettoken target : cmd , parse(" =")
			    if substr(`"`target'"', 1, 9) == ".sersets[" {
						// must get new serset key
				.__LOG.Arrpush `target' =		///
					.__Map.``target'.uname'.ref
			    }
			    else {			// Standard "push"
				.__LOG.Arrpush `macval(cmd)'
			    }
		    }
		}
	    }
	    file read `loghndl' cmd
	    gettoken tok : cmd
	}

end


/* -------------------------------------------------------------------------*/
/*  Examines a cmd and returns 1 if it is a scheme edit and 0 otherwise.
*/

program define _is_scheme_edit

	local unused : subinstr local 0 ".decl_style" "",  count(local ct1)
	local unused : subinstr local 0 ".style_edit" "",  count(local ct2)
	local unused : subinstr local 0 ".editstyle" "" ,  count(local ct3)
							// all editstyles ?

	class exit = `ct1' | `ct2' | `ct3'
end

/* -------------------------------------------------------------------------*/
/*  Types the log for the object to the screen.

	Usage:  .showlog [ , lines(#) ]

*/

program define showlog

	if "`.__LOG.isa'" != "array" { 
		exit 
	}

	syntax [, Lines(integer -1) ]

	.popifcontains .showlog

	if `lines' == -1 { 
		local lines = `.__LOG.arrnels' 
	}

	forvalues i = 1/`lines' {
		di `"`.__LOG[`i']'"'
	}

end


/* -------------------------------------------------------------------------*/
/*  Puts up a dialog box that allows the attributes of a class to be edited.

    !? Passing name is a real kludge, so that we can have a fullname to post
       to the log when an attribute is edited, much better if we had an
       internal way of tracking this, but the first attempt was VERY
       inefficient.  
*/

program define dialog_box

	.popifcontains .dialog_box

	syntax , Name(string) [ALL Classmv Instancemv Dynamicmv Redraw Apply ]

	if "`all'`classmv'`instancemv'`dynamicmv'" == "" {  /* set defaults */
		local instancemv instancemv
		local dynamicmv dynamicmv
	}

	global T_Name `name'				/* just easier */
	global T_SubNm `._restname'
	global T_TopNm `._topname $T_Name'

	global T_is_style 0				/* is this a style */
	if 0`.isofclass style' {
		if ! 0`.hasstyles' {
			._populate_stylenames
		}
		global T_is_style = 0`.hasstyles'
	}

	local showopts `all' `classmv' `instancemv' `dynamicmv' `apply'
	global T_opts `showopts'			/* for apply */


							/* count attributes */
	local tnels 0
	foreach opt in classmv instancemv dynamicmv {
		if "`all'``opt''" != "" { 
			local tnels = `tnels' + 0`.`opt'.arrnels'
		}
	}
	if $T_is_style { 
		local tnels = `tnels' + 1 
	}

	if `tnels' > 400 {
		di as error "class has too many attributes for a dialog box"
		exit 198
	}

							/* set up for redraws
							 * and applies */
	if "`redraw'" != "" {
		if `.isofclass grid' | `.isofclass graph_g' {
			global T_drawobj `.objkey'
			/* .implements member_pgm_name would be nice */
		}
		else {
			local apply
			di in green "note:  object is not a graph, ignoring " /*
				*/ "redraw option"
		}
	}

	if "`apply'" != "" { 
		global T_curobj `.objkey' 
	}

						/* place attribute controls */

	global T_percol = 1 + int( (`tnels'-1) /			/*
		*/ (1 + int((`tnels'-1) / `.dbstyle.ctrls_per_col')) )
	local x `.dbstyle.xspace'
	local y 0
	local ymax 0
	local offset 0
	if $T_is_style {
	      ._place_controls_from x y ymax : ownstyle `x' `y' `ymax' `offset'
	      local offset = `offset' + 1
	}
	if "`all'`classmv'"    != "" { 
	      ._place_controls_from x y ymax : classmv   `x' `y' `ymax' `offset'
	      local offset = `offset' + 0`.classmv.arrnels'
	}
	if "`all'`instancemv'" != "" { 
	      ._place_controls_from x y ymax : instancemv `x' `y' `ymax' `offset'
	      local offset = `offset' + 0`.instancemv.arrnels'
	}
	if "`all'`dynamicmv'"  != "" { 
	      ._place_controls_from x y ymax : dynamicmv `x' `y' `ymax' `offset'
	      local offset = `offset' + 0`.dynamicmv.arrnels'
	}
	global T_numctrls `offset'


						/* OK, Cancel buttons */
	._place_ok_cancel ymax : `.dbstyle.xspace' `ymax' "`apply'"

	local ysz = `ymax' + `.dbstyle.ysize' + 2 * `.dbstyle.yspace' + 8
	local xsz = `x' + `.dbstyle.ctrlsize' + `.dbstyle.edctrlsz' + 	/*
		*/ `.dbstyle.txtsize' + 2*`.dbstyle.xgap' + `.dbstyle.xspace'

						/* put up the dialog box */
	capture noisily window dialog "`name'" . . `xsz' `ysz'
	local rc = _rc

	/* --------------- process the results -------------------------- */

	global T_changed 0
	tempname self				// just in case edits
	.`self' = .ref				// delete ourself

	if `rc' == 3098 {			/* cancelled */
						/* possibly reset and redraw */
		._post_all , `showopts' reset 
		if "$T_drawobj" != "" & $T_changed { 
			.${T_drawobj}.drawgraph 
			global T_changed 0
		}
		._style_cleanup
		exit 
	}

	._post_all , `showopts'		/* post any changes to attributes */


	if "$T_drawobj" != "" & $T_changed { 	/* redraw if changed */
		.${T_drawobj}.drawgraph 
		global T_changed 0
	}
					/* run a sub-view dialog box if
					 * requested */
	local xpnd = `rc'-3000-$T_is_style

	if `xpnd' == 0 & $T_is_style {
		._copy_style_db
	}

	if `xpnd' < 1 { 
		exit 
	}

	local nels 0
	foreach opt in classmv instancemv dynamicmv {
		if "`all'``opt''" != "" & "`.`opt'.arrnels'" != "" { 
			if `xpnd' <= `.`opt'.arrnels' {
				_cls nameoflocal `opt'[`xpnd']
				._run_view "`opt'[`xpnd']" , `showopts'   /*
					*/ name(`name'.`r(name)')

							/* rerun self */
				.dialog_box, `showopts' name(`name')
				continue, break
			}

			local xpnd = `xpnd' - `.`opt'.arrnels'
		}
	}
	._style_cleanup

end

program define _place_controls_from
	args xmac ymac ymaxmac colon array x y ymax offset

	local ctrlsize	`.dbstyle.ctrlsize'
	local edsize    `.dbstyle.edctrlsz'
	local txtsize	`.dbstyle.txtsize'
	local ysize	`.dbstyle.ysize'
	local yspace	`.dbstyle.yspace'
	local ycombosz  = `.dbstyle.ysize' * `.dbstyle.combo_lines'

				/* put out edit controls for all of
				 * the attributes */ local x0   = `x'
	local xctl = `x0' + `edsize' + `.dbstyle.xgap'
	local xtxt = `xctl' + `ctrlsize' + `.dbstyle.xgap'
	local xfullsz = `edsize' + `ctrlsize' + `txtsize' + 2*`.dbstyle.xgap'

	if "`array'" == "ownstyle" & 0`.hasstyles' {
		local j = 1 + 0`offset'
		if `j' > 1 & mod((`j'-1), $T_percol) == 0 {
							/* shift a column */
			local x0 = `x0' + `xfullsz' + `.dbstyle.xspace'
			local xctl = `x0' + `edsize' + `.dbstyle.xgap'
			local xtxt = `xctl' + `ctrlsize' + `.dbstyle.xgap'
			local y = 0
		}
		local y = `y' + `ysize' + `yspace'
		local ymax = max(`y', `ymax')

		global T_txt`j' `.classname'

						/* combo and label */
		window control static T_txt`j' `xctl' 			/*
			*/ `y' `ctrlsize' `ysize' right
		global T_codes`j' `.Global.$T_Name.stylelist'
		global T_v`j' `.Global.$T_Name.stylename'
		global T_hv`j' ${T_v`j'}
		window control scombo T_codes`j' `xtxt' `y' 		/*
			*/ `=`ctrlsize'-8' `ycombosz' T_v`j'

						/* copy button */
		local rc = 3000 + `j'
		global T_act`j' exit `rc'
		window control button "copy" `x0' `y' `edsize' `ysize' T_act`j'

		c_local `xmac' `x0'
		c_local `ymac' `y'
		c_local `ymaxmac' `ymax'

		exit						/* EXIT */
	}

	if "`.`array'.isa'" != "array" { 
		exit 
	}

	forvalues i = 1/`.`array'.arrnels' {
		local j = `i' + 0`offset'
		if `j' > 1 & mod((`j'-1), $T_percol) == 0 {
							/* shift a column */
			local x0 = `x0' + `xfullsz' + `.dbstyle.xspace'
			local xctl = `x0' + `edsize' + `.dbstyle.xgap'
			local xtxt = `xctl' + `ctrlsize' + `.dbstyle.xgap'
			local y = 0
		}
		local y = `y' + `ysize' + `yspace'
		local ymax = max(`y', `ymax')

		local attrib `array'[`i']

		capture _cls nameoflocal `array'[`i']
		local name `r(name)'
		if "`name'" == "" {
			local name `.`attrib'.classname'
			if "`name'" == "" { 
				local name `j' 
			}
		}
		global T_txt`j' "`name'"


		if "`.`attrib'.isa'" == "string" {
			window control static T_txt`j' `xtxt' `y' 	/*
				*/ `txtsize' `ysize'
			global T_v`j' `.`array'[`i']'
			global T_hv`j' ${T_v`j'}
			window control edit `xctl' `y' `ctrlsize' `ysize' T_v`j'
			continue
		}

		if "`.`attrib'.isa'" == "double" {
			window control static T_txt`j' `xtxt' `y' 	/*
				*/ `txtsize' `ysize'
			global T_v`j' `.`array'[`i']'
			global T_hv`j' ${T_v`j'}
			window control edit `xctl' `y' `ctrlsize' `ysize' T_v`j'
			continue
		}

		if "`.`attrib'.isa'" == "class" {

			if `.`attrib'.isofclass code' {
				window control static T_txt`j' `xtxt' `y'   /*
					*/ `txtsize' `ysize'
				global T_codes`j' `.`attrib'.namelist'
				global T_v`j' `.`attrib'.setting'
				global T_hv`j' ${T_v`j'}
				window control scombo T_codes`j' `xctl' `y' /*
					*/ `ctrlsize' `ycombosz' T_v`j'
				continue
			}

/* merge above ? */
			if `.`attrib'.isofclass style' & 0`.`attrib'.hasstyles'{

							/* combo and label */
				window control static T_txt`j' `xtxt' `y'   /*
					*/ `txtsize' `ysize'	/*same*/
				global T_codes`j' `.`attrib'.stylelist'
				global T_v`j' `.`attrib'.stylename'
				global T_hv`j' ${T_v`j'}
				window control scombo T_codes`j' `xctl' `y' /*
					*/ `ctrlsize' `ycombosz' T_v`j'

							/* edit button */
				local rc = 3000 + `j'
				global T_act`j' exit `rc'
				window control button "edit" `x0' `y'	/*
					*/ `edsize' `ysize' T_act`j'
				continue
			}

			local rc = 3000 + `j'
			global T_act`j' exit `rc'
			window control button "`name'" `x0' `y' 	/*
				*/ `xfullsz' `ysize' T_act`j'
			continue

			/* !? might add boxes for small styles */
		}

		if "`.`attrib'.isa'" == "array" {
			local rc = 3000 + `j'
			global T_act`j' exit `rc'
			window control button "`name' (array)" `x0' `y'  /*
				*/ `xfullsz' `ysize' T_act`j'
		}
		/* would be nice to have booleans and check boxes */
		/* should disallow things that are not inherited from object */

	}

	c_local `xmac' `x0'
	c_local `ymac' `y'
	c_local `ymaxmac' `ymax'
end


program define _place_ok_cancel
	args ymac colon x y apply

	local y = `y' + `.dbstyle.ysize' + 2 * `.dbstyle.yspace'
	global T_cancel "exit 3098"
	global T_ok     "exit 3099"
	window control button "OK"     `x'  `y' 30 `.dbstyle.ysize' T_ok
	local sx = `x' + 40
	window control button "Cancel" `sx' `y' 30 `.dbstyle.ysize' T_cancel

	if "`apply'" == "apply" {
		local sx = `sx' + 40
		global T_apply  ".${T_curobj}._db_apply"
		window control button "Apply" `sx' `y' 30 	/*
			*/ `.dbstyle.ysize' T_apply
	}

	c_local `ymac' `y'
end

program define _post_all

	syntax [, All Classmv Instancemv Dynamicmv Redraw Apply REset ]
					/* post any changes to attributes */
	local log $T_TopNm.__LOG

	if ! `._set_changed' {
		exit
	}

	if $T_is_style {
		._post_style

		if ! 0$T_changed_p1 {
			exit
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -