PEARL Procedures  rev-distro-3.0.0-0-gfa24916-dirty
Igor procedures for the analysis of PEARL data
pearl-elog.ipf
Go to the documentation of this file.
1 #pragma TextEncoding = "UTF-8"
2 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
3 #pragma version = 1.50
4 #pragma IgorVersion = 6.36
5 #pragma ModuleName = PearlElog
6 
7 // author: matthias.muntwiler@psi.ch
8 // Copyright (c) 2013-20 Paul Scherrer Institut
9 
10 // Licensed under the Apache License, Version 2.0 (the "License");
11 // you may not use this file except in compliance with the License.
12 // You may obtain a copy of the License at
13 // http://www.apache.org/licenses/LICENSE-2.0
14 
80 
85 
86 static strconstant package_name = "pearl_elog"
87 static strconstant package_path = "root:packages:pearl_elog:"
88 
98 function pearl_elog(logbook)
99  string logbook
100 
101  if (init_package() == 0)
102  load_prefs()
103  string templates = list_logbooks(templates=1)
104  if (ItemsInList(templates) < 1)
106  endif
107  endif
108 
109  if (strlen(logbook) == 0)
110  logbook = elog_prompt_logbook()
111  endif
112 
113  string win_name = logbook + "ElogPanel"
114  if (strlen(logbook) > 0)
115  if (strlen(WinList(win_name, ";", "")) > 0)
116  DoWindow /F $win_name
117  else
118  win_name = PearlElogPanel(logbook)
119  STRUCT WMWinHookStruct s
120  s.eventCode = 0
121  s.winName = win_name
122  elog_panel_hook(s)
123  endif
124  endif
125 end
126 
128 static function IgorBeforeNewHook(igorApplicationNameStr)
129  string igorApplicationNameStr
130  save_prefs()
132  return 0
133 end
134 
136 static function IgorQuitHook(igorApplicationNameStr)
137  string igorApplicationNameStr
138  save_prefs()
140  return 0
141 end
142 
144 static function AfterFileOpenHook(refNum,file,pathName,type,creator,kind)
145  Variable refNum,kind
146  String file,pathName,type,creator
147  if( (kind >= 1) && (kind <= 2))
148  init_package(clean=1)
149  load_prefs()
150  endif
151  return 0
152 end
153 
154 static constant kdfRoot = 0
155 static constant kdfVolatile = 1
156 static constant kdfPersistent = 2
157 static constant kdfTemplates = 3
158 
171 static function /df get_elog_df(name, category)
172  string name
173  variable category
174 
175  dfref df_package = $package_path
176  dfref df_persistent = df_package:persistent
177  dfref df_volatile = df_package:volatile
178 
179  switch(category)
180  case kdfRoot:
181  dfref df_parent = df_package
182  break
183  case kdfPersistent:
184  dfref df_parent = df_persistent
185  break
186  case kdfTemplates:
187  dfref df_parent = df_persistent:templates
188  break
189  case kdfVolatile:
190  dfref df_parent = df_volatile
191  break
192  default:
193  Abort "get_elog_df: undefined data folder category."
194  endswitch
195 
196  if ((strlen(name) > 0) && (category >= 1))
197  if (category == kdfTemplates)
198  dfref df_logbooks = df_parent
199  else
200  dfref df_logbooks = df_parent:logbooks
201  endif
202  dfref df_logbook = df_logbooks:$name
203  return df_logbook
204  else
205  return df_parent
206  endif
207 end
208 
218 static function init_package([clean])
219  variable clean
220 
221  if (ParamIsDefault(clean))
222  clean = 0
223  endif
224 
225  dfref savedf = getdatafolderdfr()
226  dfref df_root = get_elog_df("", kdfRoot)
227  if ((clean == 0) && (DataFolderRefStatus(df_root) == 1))
228  return 1
229  endif
230 
231  setdatafolder root:
232  newdatafolder /o/s packages
233  newdatafolder /o/s $package_name
234  dfref df_package_root = getdatafolderdfr()
235  newdatafolder /o/s volatile
236  dfref df_volatile = getdatafolderdfr()
237  newdatafolder /o logbooks
238  setdatafolder df_package_root
239  newdatafolder /o/s persistent
240  dfref df_persistent = getdatafolderdfr()
241  newdatafolder /o logbooks
242  newdatafolder /o templates
243 
244  // common configuration
245  setdatafolder df_persistent
246  string /g elog_path = "c:\\program files (x86)\\ELOG\\elog.exe"
247  string /g hostname = "localhost"
248  variable /g port = 0 // 0 = unspecified (default)
249  variable /g ssl = 0 // 0 = plain text (incl. passwords), 1 = secure connection
250  string /g subdir = ""
251  variable /g loglevel = 4
252 
253  setdatafolder savedf
254  return 0
255 end
256 
264  dfref savedf = getdatafolderdfr()
265 
266  dfref df_root = get_elog_df("", kdfRoot)
267  dfref df_persistent = get_elog_df("", kdfPersistent)
268  dfref df_templates = get_elog_df("", kdfTemplates)
269 
270  // Experiments template
271  setdatafolder df_templates
272  newdatafolder /o/s Experiments
273 
274  // attributes (persistent)
275  // available attributes
276  string /g attributes = "author;project;p-group;sample;source;task;technique;file;valid;"
277  // controls corresponding to attributes
278  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
279  string /g controls = "sv_author;sv_project;sv_pgroup;sv_sample;pm_source;pm_task;pm_technique;sv_file;cb_valid;"
280  // attributes with fixed options, value item declares the options string
281  string /g options = "source=sources;task=tasks;technique=techniques"
282  // attributes which must be defined
283  string /g required_attributes = "author;project;sample;source;task;technique;valid"
284 
285  // option lists
286  string /g sources = "Manual Entry;PShell;Scienta Data;SScan Data;Prosilica Data;OTF Data;Beamline Status;LEED Data;QMS Data;Matrix Data;Igor Pro;Other"
287  string /g tasks = "Measurement;Optimization;Analysis;Sample Preparation;Sample Storage;Comment;Development;Maintenance;Test;Other"
288  string /g techniques = "XPS;UPS;XPD;XAS;XMCD;PhD;ARUPS;STM;STS;LEED;AES;QMS;MBE;Sputter/Anneal;Test;Other"
289 
290  // Calculations template
291  setdatafolder df_templates
292  newdatafolder /o/s Calculations
293 
294  // attributes (persistent)
295  // available attributes
296  string /g attributes = "author;project;p-group;sample;program;revision;machine;job;experiment;source path;result path;valid"
297  // controls corresponding to attributes
298  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
299  string /g controls = "sv_author;sv_project;sv_pgroup;sv_sample;pm_program;sv_revision;pm_machine;sv_job;sv_experiment;sv_sourcepath;sv_resultpath;cb_valid"
300  // attributes with fixed options, value item declares the options string
301  string /g options = "program=programs;machine=machines"
302  // attributes which must be defined
303  string /g required_attributes = "author;project;sample"
304 
305  // option lists
306  string /g programs = "PMSCO;EDAC;MSC;SSC;MUFPOT;DMSUP;Other"
307  string /g machines = "PC;VM;Ra;Merlin;llcx;Other"
308 
309  // System template
310  setdatafolder df_templates
311  newdatafolder /o/s System
312 
313  // attributes (persistent)
314  // available attributes
315  string /g attributes = "author;type;system;source;file"
316  // controls corresponding to attributes
317  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
318  string /g controls = "sv_author;pm_type;pm_system;pm_source;sv_file"
319  // attributes with fixed options, value item declares the options string
320  string /g options = "type=types;system=systems;source=sources"
321  // attributes which must be defined
322  string /g required_attributes = "author;type;system"
323 
324  // option lists
325  string /g types = "Installation;Repair;Maintenance;Test;Commissioning;Bakeout;Incident;Cool-down;Warm-up;Storage;Other"
326  string /g systems = "Vacuum;Control System;BL;XA;XP;SA;SP;T;LL;Monochromator;Carving;Scienta;STM;PC-Scienta;PC-Matrix;PC-Console;PC-Console-Win;PC-XP;EPS;LAC;Desiccator;Other"
327  string /g sources = "Manual Entry;PShell;Scienta Data;SScan Data;Prosilica Data;OTF Data;Beamline Status;LEED Data;QMS Data;Matrix Data;Igor Pro;Other"
328 
329  setdatafolder savedf
330  return 0
331 end
332 
341 static function init_volatile_vars()
342  dfref savedf = GetDataFolderDFR()
343 
344  dfref df_volatile_root = get_elog_df("", kdfVolatile)
345  dfref df_volatile_parent = df_volatile_root:logbooks
346 
347  string logbooks = list_logbooks()
348  string logbook
349  variable nlb = ItemsInList(logbooks)
350  variable ilb
351 
352  SetDataFolder df_volatile_root
353  if (exists("temp_graph_files") != 2)
354  string /g temp_graph_files = ""
355  endif
356 
357  for (ilb = 0; ilb < nlb; ilb += 1)
358  logbook = StringFromList(ilb, logbooks)
359 
360  SetDataFolder df_volatile_parent
361  if (DataFolderExists(logbook))
362  SetDataFolder $logbook
363  else
364  NewDataFolder /o/s $logbook
365  endif
366 
367  if (exists("username") != 2)
368  string /g username = ""
369  endif
370  if (exists("password") != 2)
371  string /g password = ""
372  endif
373  if (exists("msg_id") != 2)
374  variable /g msg_id = 0
375  endif
376  if (exists("att_list") != 1)
377  make /n=(0,3) /t /o attach_list
378  make /n=(0,3) /i /o attach_sel
379  endif
380  if (exists("url") != 2)
381  string /g url = ""
382  endif
383  endfor
384 
385  SetDataFolder savedf
386  return 0
387 end
388 
402 
415 function elog_create_logbook(name, [template])
416  string name
417  string template
418 
419  if (ParamIsDefault(template))
420  template = ""
421  endif
422 
423  dfref savedf = getdatafolderdfr()
424  dfref df_root = get_elog_df("", kdfRoot)
425  dfref df_persistent_root = get_elog_df("", kdfPersistent)
426  dfref df_persistent_parent = df_persistent_root:logbooks
427  dfref df_volatile_root = get_elog_df("", kdfVolatile)
428  dfref df_volatile_parent = df_volatile_root:logbooks
429 
430  setdatafolder df_persistent_parent
431  if (CheckName(name, 11) != 0)
432  setdatafolder savedf
433  Abort "invalid logbook name"
434  return -1
435  endif
436 
437  if (strlen(template) > 0)
438  dfref df_template = get_elog_df(template, kdfTemplates)
439  dfref df_existing = get_elog_df(name, kdfPersistent)
440  if (DataFolderRefStatus(df_existing))
441  KillDataFolder /Z df_existing
442  endif
443  DuplicateDataFolder df_template, df_persistent_parent:$name
444  else
445  NewDataFolder /o/s df_persistent_parent:$name
446 
447  // ELOG logbook name
448  string /g logbook = name
449  // attributes (persistent)
450  // available attributes
451  string /g attributes = ""
452  // controls corresponding to attributes
453  // prefix determines the control type: sv_ = setvariable (string), pm_ = popup menu, cb = check box
454  string /g controls = ""
455  // attributes with fixed options, value item declares the options string
456  string /g options = ""
457  // attributes which must be defined
458  string /g required_attributes = ""
459  endif
460 
461  // usage data (persistent)
462  setdatafolder get_elog_df(name, kdfPersistent)
463  string /g recent = ""
464  string /g recent_message = ""
465 
467 
468  setdatafolder savedf
469  return 0
470 end
471 
474 function elog_config([elog_path, hostname, port, subdir])
475  string elog_path
476  string hostname
477  variable port
478  string subdir
479 
480  dfref df = get_elog_df("", kdfPersistent)
481 
482  if (!ParamIsDefault(elog_path))
483  svar /sdfr=df g_elog_path = elog_path
484  g_elog_path = elog_path
485  endif
486  if (!ParamIsDefault(hostname))
487  svar /sdfr=df g_hostname = hostname
488  g_hostname = hostname
489  endif
490  if (!ParamIsDefault(port))
491  nvar /sdfr=df g_port = port
492  g_port = port
493  endif
494  if (!ParamIsDefault(subdir))
495  svar /sdfr=df g_subdir = subdir
496  g_subdir = subdir
497  endif
498 end
499 
514 function elog_login(logbook, username, password)
515  string logbook
516  string username
517  string password
518 
519  dfref df = get_elog_df(logbook, kdfVolatile)
520  svar /sdfr=df g_username=username
521  svar /sdfr=df g_password=password
522  g_username = username
523  g_password = password
524 end
525 
534 function elog_logout(logbook)
535  string logbook
536 
537  dfref df = get_elog_df(logbook, kdfVolatile)
538  if (strlen(logbook) > 0)
539  svar /z /sdfr=df g_username=username
540  svar /z /sdfr=df g_password=password
541  if (svar_exists(g_username))
542  g_username = ""
543  endif
544  if (svar_exists(g_password))
545  g_password = ""
546  endif
547  else
548  dfref df2 = df:logbooks
549  variable nlb = CountObjectsDFR(df2, 4)
550  variable ilb
551  string slb
552  for (ilb = 0; ilb < nlb; ilb += 1)
553  slb = GetIndexedObjNameDFR(df2, 4, ilb)
554  if (strlen(slb) > 0)
555  elog_logout(slb)
556  endif
557  endfor
558  endif
559 end
560 
565 static function save_prefs()
566  dfref saveDF = GetDataFolderDFR()
567 
568  dfref df = get_elog_df("", kdfPersistent)
569  if (DataFolderRefStatus(df) == 1)
570  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
571  fullPath += package_name
572  NewPath/O/C/Q tempPackagePrefsPath, fullPath
573  fullPath += ":preferences.pxp"
574  SetDataFolder df
575  SaveData /O /Q /R fullPath
576  KillPath/Z tempPackagePrefsPath
577  endif
578 
579  SetDataFolder saveDF
580 end
581 
585 static function load_prefs()
586  dfref saveDF = GetDataFolderDFR()
587 
588  variable result = -1
589  init_package()
590  setdatafolder get_elog_df("", kdfPersistent)
591 
592  string fullPath = SpecialDirPath("Packages", 0, 0, 0)
593  fullPath += package_name
594 
595  GetFileFolderInfo /Q /Z fullPath
596  if (V_Flag == 0) // Disk directory exists?
597  fullPath += ":preferences.pxp"
598  GetFileFolderInfo /Q /Z fullPath
599  if (V_Flag == 0) // Preference file exist?
600  LoadData /O /R /Q fullPath
602  result = 0
603  endif
604  endif
605 
606  SetDataFolder saveDF
607  return result
608 end
609 
619 static function /s list_logbooks([templates])
620  variable templates
621 
622  if (ParamIsDefault(templates))
623  templates = 0
624  endif
625 
626  dfref df_persistent = get_elog_df("", kdfPersistent)
627  if (templates)
628  dfref df_logbooks = df_persistent:templates
629  else
630  dfref df_logbooks = df_persistent:logbooks
631  endif
632  string logbooks = ""
633 
634  variable nlb = CountObjectsDFR(df_logbooks, 4)
635  variable ilb
636  string slb
637  for (ilb = 0; ilb < nlb; ilb += 1)
638  slb = GetIndexedObjNameDFR(df_logbooks, 4, ilb)
639  if (strlen(slb) > 0)
640  logbooks = AddListItem(slb, logbooks)
641  endif
642  endfor
643 
644  return SortList(logbooks, ";", 16)
645 end
646 
654 function elog_validate_attributes(logbook, attributes)
655 
656  string logbook // name of the logbook (as in igor folder name)
657  string attributes // key=value list of attributes, semicolon separated
658 
659  variable result = 0
660  return result
661 end
662 
686 function elog_create_entry(logbook, attributes, message, [encoding, graphs, replyto])
687  string logbook
688  string attributes
689  string message
690  variable encoding
691  string graphs
692  variable replyto
693 
694  if (ParamIsDefault(encoding))
695  encoding = 1
696  endif
697  if (ParamIsDefault(graphs))
698  graphs = ""
699  endif
700  if (ParamIsDefault(replyto))
701  replyto = 0
702  endif
703 
704  dfref savedf = getdatafolderdfr()
705  dfref df_general = get_elog_df("", kdfPersistent)
706  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
707 
708  variable result = 0
709  nvar /sdfr=df_volatile msg_id
710  nvar /sdfr=df_general loglevel
711 
712  if (elog_validate_attributes(logbook,attributes) != 0)
713  if (loglevel >= 2)
714  print "ELOG: failed to validate attributes."
715  endif
716  result = -3
717  endif
718 
719  string cmd = prepare_command_line(logbook)
720  if (strlen(cmd) == 0)
721  if (loglevel >= 2)
722  print "ELOG: failed to prepare command line."
723  endif
724  result = -2
725  endif
726 
727  if (replyto >= 1)
728  cmd += " -r " + num2str(replyto)
729  endif
730  cmd += " -n " + num2str(encoding)
731 
732  variable nattr = ItemsInList(attributes, ";")
733  variable iattr
734  string sattr
735  for (iattr = 0; (iattr < nattr) && (result == 0); iattr += 1)
736  sattr = StringFromList(iattr, attributes, ";")
737  if (strlen(StringFromList(1, sattr, "=")) > 0)
738  sattr = ReplaceString("%", sattr, "")
739  cmd += " -a \"" + sattr + "\""
740  endif
741  endfor
742 
743  if (result == 0)
744  string cmd_graphs = prepare_graph_attachments(graphs)
745  cmd += " " + cmd_graphs
746  endif
747 
748  if ((result == 0) && (strlen(message) > 0))
749  string messagefile = create_message_file(message)
750  if (strlen(messagefile) > 0)
751  cmd += " -m \"" + messagefile + "\""
752  cmd += " > elog.log"
753  if (loglevel >= 5)
754  print cmd
755  endif
756  string cmd_file_path = create_cmd_file(cmd)
757  if (strlen(cmd_file_path) > 0)
758  ExecuteScriptText cmd_file_path
759  variable id = parse_result()
760  if (id > 0)
761  msg_id = id
762  if (loglevel >= 4)
763  print "ELOG: sent message " + num2str(id)
764  endif
765  else
766  if (loglevel >= 2)
767  print "ELOG: sending message failed."
768  endif
769  result = -4
770  endif
771  else
772  result = -2
773  endif
774  else
775  if (loglevel >= 2)
776  print "ELOG: failed to create temporary message file."
777  endif
778  result = -1
779  endif
780  endif
781 
782  setdatafolder savedf
783  return result
784 end
785 
793 function elog_add_attachment(logbook, id, graphs)
794  string logbook
795  variable id // existing entry ID
796  string graphs // names of graph windows to be added as attachments, semicolon separated
797 
798  dfref savedf = getdatafolderdfr()
799  dfref df_general = get_elog_df("", kdfPersistent)
800  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
801 
802  variable result = 0
803  nvar /sdfr=df_volatile msg_id
804  nvar /sdfr=df_general loglevel
805 
806  string cmd = prepare_command_line(logbook)
807  if (strlen(cmd) == 0)
808  result = -2 // error: invalid/missing command line
809  endif
810 
811  cmd += " -e " + num2str(id)
812 
813  if (result == 0)
814  string cmd_graphs = prepare_graph_attachments(graphs)
815  if (strlen(cmd_graphs) == 0)
816  result = -3 // error: invalid/missing graphs
817  endif
818  endif
819 
820  if (result == 0)
821  cmd += " " + cmd_graphs
822  cmd += " > elog.log"
823  string cmd_file_path = create_cmd_file(cmd)
824  if (strlen(cmd_file_path) > 0)
825  ExecuteScriptText cmd_file_path
826  id = parse_result()
827  if (id > 0)
828  msg_id = id
829  if (loglevel >= 4)
830  print "ELOG: attached graphs to message " + num2str(id)
831  endif
832  else
833  if (loglevel >= 2)
834  print "ELOG: failed to attach graphs."
835  endif
836  result = -4 // error: elog returned error
837  endif
838  else
839  result = -2 // error: invalid command line
840  endif
841  endif
842 
843  setdatafolder savedf
844  return result
845 end
846 
854 static function /s prepare_command_line(logbook)
855  string logbook
856 
857  dfref df_general = get_elog_df("", kdfPersistent)
858  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
859  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
860 
861  svar /sdfr=df_general elog_path
862  svar /sdfr=df_general hostname
863  nvar /sdfr=df_general port
864  nvar /sdfr=df_general ssl
865  svar /sdfr=df_general subdir
866  nvar /sdfr=df_general loglevel
867  svar /sdfr=df_volatile username
868  svar /sdfr=df_volatile password
869 
870  string cmd
871  cmd = "\"" + elog_path + "\""
872  if (loglevel >= 5)
873  cmd += " -v"
874  endif
875  cmd += " -h " + hostname
876  if ((nvar_exists(port)) && (port > 0))
877  cmd += " -p " + num2str(port)
878  endif
879  if ((svar_exists(subdir)) && (strlen(subdir) > 0))
880  cmd += " -d " + subdir
881  endif
882  cmd += " -l \"" + logbook + "\""
883  if ((nvar_exists(ssl)) && (ssl != 0))
884  cmd += " -s"
885  endif
886  //cmd += " -w " + password
887  if (svar_exists(username) && svar_exists(password) && (strlen(username) > 0) && (strlen(password) > 0))
888  cmd += " -u " + username + " " + password
889  endif
890 
891  if (loglevel >= 5)
892  print cmd
893  endif
894 
895  return cmd
896 end
897 
903 static function /s format_url(logbook)
904  string logbook
905 
906  dfref df_general = get_elog_df("", kdfPersistent)
907 
908  svar /sdfr=df_general hostname
909  nvar /sdfr=df_general port
910  nvar /sdfr=df_general ssl
911  svar /sdfr=df_general subdir
912 
913  string cmd = ""
914  if ((nvar_exists(ssl)) && (ssl != 0))
915  cmd += "https://"
916  else
917  cmd += "http://"
918  endif
919  cmd += hostname
920  if ((nvar_exists(port)) && (port > 0))
921  cmd += ":" + num2str(port)
922  endif
923  if ((svar_exists(subdir)) && (strlen(subdir) > 0))
924  cmd += "/" + subdir
925  endif
926  cmd += "/" + logbook
927 
928  return cmd
929 end
930 
940 static function /s prepare_graph_attachments(graphs)
941  string graphs // names of graph windows to be added as attachments, semicolon separated
942 
943  string cmd = ""
944  variable ngraphs = ItemsInList(graphs, ";")
945  variable igraph
946  string sgraph
947  string graph_path
948  for (igraph = 0; igraph < ngraphs; igraph += 1)
949  sgraph = StringFromList(igraph, graphs, ";")
950  graph_path = create_graph_file(sgraph, igraph)
951  if (strlen(graph_path) > 0)
952  cmd += " -f \"" + graph_path + "\""
953  endif
954  endfor
955 
956  return cmd
957 end
958 
959 static function /s get_timestamp(sep)
960  string sep
961  Variable now = DateTime
962  string dat = ReplaceString("-", Secs2Date(DateTime, -2), "")
963  string tim = ReplaceString(":", Secs2Time(DateTime, 3), "")
964  return dat + sep + tim
965 end
966 
983 static function /s create_message_file(message)
984  string message
985 
986  message = ReplaceString("%", message, "")
987  string path = SpecialDirPath("Temporary", 0, 1, 0)
988  variable len = strlen(path)
989  string filename
990 
991  if (numtype(len) == 0)
992  filename = "elog_temp_message.txt"
993  path += filename
994  variable f1
995  Open f1 as path
996  fprintf f1, message
997  Close f1
998  else
999  filename = ""
1000  endif
1001 
1002  return filename
1003 end
1004 
1024 static function /s create_graph_file(graphname, fileindex)
1025  string graphname
1026  variable fileindex
1027 
1028  dfref df_volatile_root = get_elog_df("", kdfVolatile)
1029  svar /sdfr=df_volatile_root temp_graph_files
1030 
1031  string path = SpecialDirPath("Temporary", 0, 1, 0)
1032  string ts = get_timestamp("_")
1033  variable len = strlen(path)
1034  string filename
1035 
1036  if (numtype(len) == 0)
1037  filename = "elog_" + ts + "_" + num2str(fileindex) + ".png"
1038  path += filename
1039  SavePICT /B=72 /E=-5 /M /O /W=(0,0,8,6) /WIN=$graphname /Z as path
1040  if (v_flag == 0)
1041  temp_graph_files = AddListItem(path, temp_graph_files, ";", inf)
1042  else
1043  filename = ""
1044  endif
1045  else
1046  filename = ""
1047  endif
1048 
1049  return filename
1050 end
1051 
1060 static function /s create_cmd_file(cmd)
1061  string cmd
1062 
1063  dfref df_general = get_elog_df("", kdfPersistent)
1064  nvar /sdfr=df_general loglevel
1065 
1066  if (strlen(cmd) >= 1024)
1067  if (loglevel >= 2)
1068  print "ELOG: command line too long (add fewer attachments)."
1069  endif
1070  return ""
1071  endif
1072 
1073  string work_path = SpecialDirPath("Temporary", 0, 1, 0)
1074  variable len = strlen(work_path)
1075  if (numtype(len) == 0)
1076  string cmdx
1077  string cmd_path = work_path + "elog_temp_cmd.bat"
1078 
1079  variable f1
1080  Open f1 as cmd_path
1081  cmdx = "c:\r\n"
1082  fprintf f1, cmdx
1083  cmdx = "cd \"" + work_path + "\"\r\n"
1084  fprintf f1, cmdx
1085  cmdx = "del elog.log"
1086  fprintf f1, cmdx + "\r\n"
1087  fprintf f1, cmd
1088  Close f1
1089  else
1090  cmd_path = ""
1091  endif
1092 
1093  return cmd_path
1094 end
1095 
1096 static function /s get_log_path()
1097  string path = SpecialDirPath("Temporary", 0, 1, 0)
1098  variable len = strlen(path)
1099  if (numtype(len) == 0)
1100  path += "elog.log"
1101  else
1102  path = ""
1103  endif
1104 
1105  return path
1106 end
1107 
1116 static function cleanup_temp_files()
1117  dfref df_volatile_root = get_elog_df("", kdfVolatile)
1118  if (DataFolderRefStatus(df_volatile_root))
1119  svar /sdfr=df_volatile_root /z temp_graph_files
1120  if (SVAR_Exists(temp_graph_files))
1121  variable nfi = ItemsInList(temp_graph_files)
1122  variable ifi
1123  string sfi
1124  for (ifi = 0; ifi < nfi; ifi += 1)
1125  sfi = StringFromList(ifi, temp_graph_files)
1126  DeleteFile /Z sfi
1127  endfor
1128  temp_graph_files = ""
1129  endif
1130  endif
1131  return 0
1132 end
1133 
1134 static strconstant elog_success_msg = "Message successfully transmitted"
1135 static strconstant elog_parse_id = "ID=%u"
1136 
1142 static function parse_result()
1143  dfref df_general = get_elog_df("", kdfPersistent)
1144  nvar /sdfr=df_general loglevel
1145 
1146  string path = get_log_path()
1147  string line = ""
1148  string output = ""
1149  variable success = 0
1150  variable id = -1
1151  string part1 = ""
1152  string part2 = ""
1153 
1154  variable len = strlen(path)
1155  if (numtype(len) == 0)
1156  variable f1
1157  Open /R/Z f1 as path
1158  if (v_flag == 0)
1159  do
1160  FReadLine f1, line
1161  if (strlen(line) > 0)
1162  part1 = StringFromList(0, line, ",")
1163  part2 = ReplaceString(" ", StringFromList(1, line, ","), "")
1164  success = cmpstr(part1, elog_success_msg) == 0
1165  if (success)
1166  sscanf part2, elog_parse_id, id
1167  endif
1168  else
1169  break
1170  endif
1171  output += line
1172  while(!success)
1173  Close f1
1174  endif
1175  endif
1176  if (loglevel >= 5)
1177  print output
1178  endif
1179 
1180  return id
1181 end
1182 
1185 function /s elog_prompt_logbook()
1186  string logbooks = list_logbooks(templates=0)
1187  logbooks = AddListItem("(new)", logbooks)
1188  string templates = list_logbooks(templates=1)
1189  templates = AddListItem("(none)", templates)
1190 
1191  string logbook = StringFromList(0, logbooks)
1192  string template = StringFromList(0, logbooks)
1193  string name = ""
1194  string username = ""
1195  string password = ""
1196 
1197  prompt logbook, "logbook", popup logbooks
1198  prompt template, "template", popup templates
1199  prompt name, "new logbook name"
1200 
1201  doprompt "select logbook", logbook, template, name
1202  if (!v_flag)
1203  if (cmpstr(logbook, "(new)") == 0)
1204  elog_create_logbook(name, template=template)
1205  logbook = name
1206  endif
1207  else
1208  logbook = ""
1209  endif
1210  return logbook
1211 end
1212 
1215 function elog_prompt_login(logbook)
1216  string logbook
1217 
1218  string logbooks = list_logbooks(templates=0)
1219 
1220  string username = ""
1221  string password = ""
1222 
1223  prompt logbook, "logbook", popup logbooks
1224  prompt username, "user name"
1225  prompt password, "password (blank to log out)"
1226 
1227  doprompt "log in to logbook", logbook, username, password
1228  if (!v_flag)
1229  elog_login(logbook, username, password)
1230  endif
1231 
1232  return v_flag
1233 end
1234 
1242 function /s PearlElogPanel(logbook)
1243  string logbook
1244 
1245  dfref savedf = getdatafolderdfr()
1246  dfref df_general = get_elog_df("", kdfPersistent)
1247  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
1248  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
1249 
1250  string win_name = logbook + "ElogPanel"
1251  string win_title = "ELOG " + logbook
1252 
1253  NewPanel /K=1 /N=$win_name /W=(600,200,1200,700) as win_title
1254  win_name = s_name
1255  ModifyPanel /w=$win_name cbRGB=(52224,52224,65280)
1256 
1257  svar /sdfr=df_persistent attributes
1258  svar /sdfr=df_persistent controls
1259  svar /sdfr=df_persistent options
1260  wave /t /sdfr=df_volatile attach_list
1261  wave /sdfr=df_volatile attach_sel
1262  svar /sdfr=df_volatile url
1263 
1264  variable iattr
1265  variable nattr = ItemsInList(attributes, ";")
1266  string s_attr
1267  string s_control
1268  string s_option
1269  string persistent_path = GetDataFolder(1, df_persistent)
1270  string volatile_path = GetDataFolder(1, df_volatile)
1271  string options_path
1272  string variable_path
1273  variable ypos = 2
1274  variable height = 0
1275 
1276  for (iattr = 0; iattr < nattr; iattr += 1)
1277  s_attr = StringFromList(iattr, attributes, ";")
1278  s_control = StringFromList(iattr, controls, ";")
1279  strswitch(s_control[0,1])
1280  case "sv":
1281  SetVariable $s_control, win=$win_name, pos={0,ypos}, size={300,16}, bodyWidth=230
1282  SetVariable $s_control, win=$win_name, title=s_attr, value= _STR:""
1283  SetVariable $s_control, win=$win_name, userdata(attribute)=s_attr
1284  ypos += 18
1285  break
1286  case "pm":
1287  options_path = persistent_path + StringByKey(s_attr, options, "=", ";")
1288  PopupMenu $s_control, win=$win_name, pos={0,ypos}, size={300,21}, bodyWidth=230
1289  PopupMenu $s_control, win=$win_name, title=s_attr
1290  PopupMenu $s_control, win=$win_name, mode=1, popvalue="Test", value= #options_path
1291  PopupMenu $s_control, win=$win_name, userdata(attribute)=s_attr
1292  ypos += 23
1293  break
1294  case "cb":
1295  CheckBox $s_control, win=$win_name, pos={70,ypos}, size={300,14}
1296  CheckBox $s_control, win=$win_name, title=s_attr, value= 1
1297  CheckBox $s_control, win=$win_name, userdata(attribute)=s_attr
1298  ypos += 17
1299  break
1300  endswitch
1301  endfor
1302  ypos = max(ypos, 80)
1303 
1304  TitleBox t_attach, win=$win_name, pos={308,5}, size={70,14}, title="Attachments", frame=0
1305  height = ypos - 21 - 4
1306  ListBox lb_attach, win=$win_name, pos={308,21}, size={264,height}
1307  ListBox lb_attach, win=$win_name, listWave=attach_list
1308  ListBox lb_attach, win=$win_name, mode=1, selWave=attach_sel, selRow=-1
1309  ListBox lb_attach, win=$win_name, widths={20,160,80}
1310  ListBox lb_attach, win=$win_name, help={"Choose graphs to attach to the message."}
1311 
1312  Button b_attach_top, win=$win_name, pos={420,2}, size={40,18}, title="top"
1313  Button b_attach_top, win=$win_name, fcolor=(56576,60928,47872)
1314  Button b_attach_top, win=$win_name, proc=PearlElog#bp_attach_top
1315  Button b_attach_top, win=$win_name, help={"Select top graph for attachment."}
1316  Button b_attach_all, win=$win_name, pos={460,2}, size={40,18}, title="all"
1317  Button b_attach_all, win=$win_name, fcolor=(56576,60928,47872)
1318  Button b_attach_all, win=$win_name, proc=PearlElog#bp_attach_allnone
1319  Button b_attach_all, win=$win_name, help={"Select all graphs for attachment."}
1320  Button b_attach_none, win=$win_name, pos={500,2}, size={40,18}, title="none"
1321  Button b_attach_none, win=$win_name, fcolor=(56576,60928,47872)
1322  Button b_attach_none, win=$win_name, proc=PearlElog#bp_attach_allnone
1323  Button b_attach_none, win=$win_name, help={"Deselect all attachments."}
1324  Button b_save_graphs, win=$win_name, pos={540,2}, size={40,18}, title="save"
1325  Button b_save_graphs, win=$win_name, fcolor=(56576,60928,47872)
1326  Button b_save_graphs, win=$win_name, proc=PearlElog#bp_save_graphs
1327  Button b_save_graphs, win=$win_name, help={"Save selected graphs as PNG bitmap files."}
1328  Button b_attach_up, win=$win_name, pos={576,20}, size={20,20}, title="\\W517"
1329  Button b_attach_up, win=$win_name, fcolor=(56576,60928,47872)
1330  Button b_attach_up, win=$win_name, proc=PearlElog#bp_attach_updown
1331  Button b_attach_up, win=$win_name, help={"Move selected graph up."}
1332  Button b_attach_dw, win=$win_name, pos={576,40}, size={20,20}, title="\\W523"
1333  Button b_attach_dw, win=$win_name, fcolor=(56576,60928,47872)
1334  Button b_attach_dw, win=$win_name, proc=PearlElog#bp_attach_updown
1335  Button b_attach_dw, win=$win_name, help={"Move selected graph down."}
1336 
1337  ypos += 246-160
1338  Button b_submit,win=$win_name, pos={70,ypos},size={46,20},proc=PearlElog#bp_submit,title="Submit"
1339  Button b_submit,win=$win_name, help={"Submit form data to ELOG (new entry)."}
1340  Button b_submit,win=$win_name, fcolor=(56576,60928,47872)
1341  Button b_clear,win=$win_name, pos={120,ypos},size={46,20},proc=PearlElog#bp_clear,title="Clear"
1342  Button b_clear,win=$win_name, help={"Clear the form fields"}
1343  Button b_clear,win=$win_name, fcolor=(56576,60928,47872)
1344 
1345  ypos += 272-246
1346  variable_path = volatile_path + "msg_id"
1347  SetVariable sv_id,win=$win_name, pos={51,ypos},size={119,16},bodyWidth=77
1348  SetVariable sv_id,win=$win_name, title="ID",value=$variable_path
1349  SetVariable sv_id,win=$win_name, help={"ID of last submitted message, or message to attach or reply to."}
1350 
1351  TitleBox t_host, win=$win_name, pos={170,ypos+4}, size={112.00,14.00}, frame=0
1352  TitleBox t_host, win=$win_name, variable=url
1353 
1354  ypos += 270-272
1355  Button b_attach,win=$win_name, pos={170,ypos},size={48,20},proc=PearlElog#bp_attach,title="Attach"
1356  Button b_attach,win=$win_name, help={"Attach the selected graph to an existing ELOG entry (correct ID required)."}
1357  Button b_attach,win=$win_name, fcolor=(56576,60928,47872)
1358  Button b_reply,win=$win_name, pos={220,ypos},size={48,20},proc=PearlElog#bp_submit,title="Reply"
1359  Button b_reply,win=$win_name, help={"Submit form data to ELOG as a reply to an existing message (correct ID required)."}
1360  Button b_reply,win=$win_name, fcolor=(56576,60928,47872)
1361  Button b_login,win=$win_name, pos={550,ypos},size={46,20},proc=PearlElog#bp_login,title="Login"
1362  Button b_login,win=$win_name, help={"Enter user name and password."}
1363  Button b_login,win=$win_name, fcolor=(56576,60928,47872)
1364  Button b_logout,win=$win_name, pos={550,ypos},size={46,20},proc=PearlElog#bp_logout,title="Logout"
1365  Button b_logout,win=$win_name, help={"Clear user name and password."}
1366  Button b_logout,win=$win_name, fcolor=(56576,60928,47872), disable=3
1367 
1368  SetWindow $win_name, hook(elogPanelHook)=PearlElog#elog_panel_hook
1369  SetWindow $win_name, userdata(logbook)=logbook
1370 
1371  ypos += 160-270
1372  TitleBox t_message,win=$win_name, pos={10,ypos},size={58,16},fixedSize=1,frame=0,anchor=RT,title="Message"
1373  DefineGuide UGH0={FT,ypos},UGV0={FL,70},UGH1={FB,-52},UGV1={FR,-2}
1374  NewNotebook /F=0 /N=Message /OPTS=3 /W=(115,404,345,341)/FG=(UGV0,UGH0,UGV1,UGH1) /HOST=#
1375  Notebook kwTopWin, defaultTab=20, statusWidth=0, autoSave=0
1376  Notebook kwTopWin fSize=10, fStyle=0, textRGB=(0,0,0)
1377  RenameWindow #,Message
1378  string nb_name = win_name + "#Message"
1379  SetActiveSubwindow ##
1380 
1381  // restore recently used attributes and message
1382  svar /z /sdfr=df_persistent recent
1383  if (svar_exists(recent) && (strlen(recent) > 0))
1384  set_panel_attributes(win_name, recent)
1385  endif
1386  svar /z /sdfr=df_persistent recent_message
1387  if (svar_exists(recent_message) && (strlen(recent_message) > 0))
1388  set_panel_message(win_name, recent_message)
1389  endif
1390  Notebook $nb_name selection={startOfFile,startOfFile}, findText={"",1}
1391 
1392  setdatafolder savedf
1393  return win_name
1394 end
1395 
1396 static function elog_panel_hook(s)
1397  STRUCT WMWinHookStruct &s
1398 
1399  Variable hookResult = 0
1400 
1401  switch(s.eventCode)
1402  case 0: // activate
1403  string logbook = GetUserData(s.winName, "", "logbook")
1404  if (strlen(logbook) > 0)
1405  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
1406  svar /sdfr=df_volatile url
1407  url = format_url(logbook)
1408  update_attach_items(logbook)
1409  endif
1410  break
1411  case 6: // resize
1412  // move bottom-aligned controls when the window is resized
1413  variable b_top = s.winRect.bottom + 4
1414  Button b_submit,pos={70,b_top}
1415  Button b_clear,pos={120,b_top}
1416  TitleBox t_host, pos={170,b_top+4}
1417  b_top += 24
1418  Button b_attach,pos={170,b_top}
1419  Button b_reply,pos={220,b_top}
1420  Button b_login, pos={550,b_top}
1421  Button b_logout, pos={550,b_top}
1422  b_top += 2
1423  SetVariable sv_id,pos={51,b_top}
1424  break
1425  endswitch
1426 
1427  return hookResult // 0 if nothing done, else 1
1428 end
1429 
1430 static constant kAttachColSel = 0
1431 static constant kAttachColTitle = 1
1432 static constant kAttachColName = 2
1433 
1435 static function update_attach_items(logbook)
1436  string logbook
1437 
1438  dfref savedf = getdatafolderdfr()
1439  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
1440  wave /t /sdfr=df_volatile attach_list
1441  wave /sdfr=df_volatile attach_sel
1442 
1443  if (!waveexists(attach_list))
1444  return -1
1445  endif
1446  string names = WinList("*", ";", "WIN:1;VISIBLE:1")
1447  names = SortList(names, ";", 16)
1448 
1449  // remove closed graphs
1450  variable i
1451  variable k
1452  variable n = DimSize(attach_list, 0)
1453  string s
1454  for (i = n-1; i >= 0; i -= 1)
1455  s = attach_list[i][kAttachColName]
1456  if (WhichListItem(s, names) < 0)
1457  DeletePoints /M=0 i, 1, attach_list, attach_sel
1458  endif
1459  endfor
1460 
1461  // add new graphs
1462  n = ItemsInList(names)
1463  for (i = 0; i < n; i += 1)
1464  s = StringFromList(i, names)
1465  FindValue /text=s /txop=4 /z attach_list
1466  if (v_value < 0)
1467  k = DimSize(attach_list, 0)
1468  Redimension /n=(k+1,3) attach_list, attach_sel
1469  //InsertPoints /M=0 k, 1, attach_list, attach_sel
1470  attach_list[k][kAttachColSel] = ""
1471  attach_list[k][kAttachColTitle] = ""
1472  attach_list[k][kAttachColName] = s
1473  attach_sel[k][kAttachColSel] = 32
1474  attach_sel[k][kAttachColTitle] = 0
1475  attach_sel[k][kAttachColName] = 0
1476  endif
1477  endfor
1478 
1479  // update titles
1480  n = DimSize(attach_list, 0)
1481  for (i = n-1; i >= 0; i -= 1)
1482  s = attach_list[i][kAttachColName]
1483  getwindow /z $s, wtitle
1484  if (v_flag == 0)
1485  attach_list[i][kAttachColTitle] = s_value
1486  else
1487  attach_list[i][kAttachColTitle] = s
1488  endif
1489  endfor
1490 
1491  setdatafolder savedf
1492  return 0
1493 end
1494 
1496 static function move_attach_item(logbook, item, distance)
1497  string logbook
1498  variable item
1499  variable distance
1500 
1501  dfref savedf = getdatafolderdfr()
1502  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
1503  wave /t /sdfr=df_volatile attach_list
1504  wave /sdfr=df_volatile attach_sel
1505  variable n = DimSize(attach_list, 0)
1506  variable dest = item + distance
1507 
1508  if ((item >= 0) && (item < n) && (dest >= 0) && (dest < n))
1509  string name = attach_list[item][kAttachColName]
1510  variable sel = attach_sel[item][kAttachColSel]
1511  DeletePoints /M=0 item, 1, attach_list, attach_sel
1512  InsertPoints /M=0 dest, 1, attach_list, attach_sel
1513  attach_list[dest][kAttachColName] = name
1514  update_attach_items(logbook)
1515  attach_sel[dest][kAttachColSel] = sel
1516  endif
1517 end
1518 
1520 static function bp_attach_updown(ba) : ButtonControl
1521  STRUCT WMButtonAction &ba
1522 
1523  switch( ba.eventCode )
1524  case 2: // mouse up
1525  string logbook = GetUserData(ba.win, "", "logbook")
1526  ControlInfo /w=$ba.win lb_attach
1527  variable row = v_value
1528  dfref df = $s_datafolder
1529  wave /t /sdfr=df attach_list = $s_value
1530  if (cmpstr(ba.ctrlName, "b_attach_up") == 0)
1531  // up button
1532  if (row >= 1)
1533  move_attach_item(logbook, row, -1)
1534  ListBox lb_attach, win=$ba.win, selRow=(row-1)
1535  endif
1536  else
1537  // down button
1538  if (row < DimSize(attach_list, 0) - 1)
1539  move_attach_item(logbook, row, +1)
1540  ListBox lb_attach, win=$ba.win, selRow=(row+1)
1541  endif
1542  endif
1543  break
1544  case -1: // control being killed
1545  break
1546  endswitch
1547 
1548  return 0
1549 end
1550 
1552 static function bp_submit(ba) : ButtonControl
1553  STRUCT WMButtonAction &ba
1554 
1555  switch( ba.eventCode )
1556  case 2: // mouse up
1557  string logbook = GetUserData(ba.win, "", "logbook")
1558  string attributes
1559  string message
1560  string graphs
1561  attributes = get_panel_attributes(ba.win)
1562  message = get_panel_message(ba.win)
1563  graphs = get_panel_graphs(ba.win)
1564 
1565  variable id
1566  if (cmpstr(ba.ctrlName, "b_reply") == 0)
1567  // Reply button
1568  ControlInfo /w=$ba.win sv_id
1569  id = v_value
1570  else
1571  // Submit button
1572  id = 0
1573  endif
1574 
1575  if ((elog_validate_attributes(logbook, attributes) == 0) && (strlen(message) > 0))
1576  variable result
1577  result = elog_create_entry(logbook, attributes, message, graphs=graphs, replyto=id)
1578  if (result == 0)
1579  dfref df = get_elog_df(logbook, kdfPersistent)
1580  svar /sdfr=df recent
1581  recent = attributes
1582  svar /sdfr=df recent_message
1583  recent_message = message
1584  else
1585  abort "Submission failed. Error code " + num2str(result) + "."
1586  endif
1587  else
1588  abort "Submission failed due to missing/invalid attribute."
1589  endif
1590  break
1591  case -1: // control being killed
1592  break
1593  endswitch
1594 
1595  return 0
1596 end
1597 
1599 static function bp_attach_top(ba) : ButtonControl
1600  STRUCT WMButtonAction &ba
1601 
1602  switch( ba.eventCode )
1603  case 2: // mouse up
1604  string graphs = WinName(0, 1, 1)
1605  set_panel_graphs(ba.win, graphs)
1606  break
1607  case -1: // control being killed
1608  break
1609  endswitch
1610 
1611  return 0
1612 end
1613 
1615 static function bp_attach_allnone(ba) : ButtonControl
1616  STRUCT WMButtonAction &ba
1617 
1618  switch( ba.eventCode )
1619  case 2: // mouse up
1620  string logbook = GetUserData(ba.win, "", "logbook")
1621  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
1622  wave /sdfr=df_volatile attach_sel
1623  if (cmpstr(ba.ctrlName, "b_attach_all") == 0)
1624  attach_sel[][kAttachColSel] = attach_sel[p][kAttachColSel] | 16
1625  else
1626  attach_sel[][kAttachColSel] = attach_sel[p][kAttachColSel] & ~16
1627  endif
1628  break
1629  case -1: // control being killed
1630  break
1631  endswitch
1632 
1633  return 0
1634 end
1635 
1636 static function bp_attach(ba) : ButtonControl
1637  STRUCT WMButtonAction &ba
1638 
1639  switch( ba.eventCode )
1640  case 2: // mouse up
1641  string logbook = GetUserData(ba.win, "", "logbook")
1642  string graphs
1643  graphs = get_panel_graphs(ba.win)
1644 
1645  variable id
1646  ControlInfo /w=$ba.win sv_id
1647  id = v_value
1648 
1649  // TODO : is there a way around this restriction?
1650  DoAlert /T="ELOG" 1, "This operation will replace all existing attachments. Do you want to continue?"
1651 
1652  if ((id > 0) && (v_flag == 1))
1653  variable result
1654  result = elog_add_attachment(logbook, id, graphs)
1655  if (result != 0)
1656  abort "Submission failed. Error code " + num2str(result) + "."
1657  endif
1658  else
1659  abort "Submission failed due to missing/invalid attribute."
1660  endif
1661  break
1662  case -1: // control being killed
1663  break
1664  endswitch
1665 
1666  return 0
1667 end
1668 
1669 static function bp_save_graphs(ba) : ButtonControl
1670  STRUCT WMButtonAction &ba
1671 
1672  switch( ba.eventCode )
1673  case 2: // mouse up
1674  string logbook = GetUserData(ba.win, "", "logbook")
1675  string graphs = get_panel_graphs(ba.win)
1676  variable ngraphs = ItemsInList(graphs, ";")
1677 
1678  variable igraph
1679  string sgraph
1680  string graph_path
1681  for (igraph = 0; igraph < ngraphs; igraph += 1)
1682  sgraph = StringFromList(igraph, graphs, ";")
1683  graph_path = create_graph_file(sgraph, igraph)
1684  if (strlen(graph_path) > 0)
1685  print graph_path
1686  endif
1687  endfor
1688 
1689  break
1690  case -1: // control being killed
1691  break
1692  endswitch
1693 
1694  return 0
1695 end
1696 
1697 static function bp_clear(ba) : ButtonControl
1698  STRUCT WMButtonAction &ba
1699 
1700  switch( ba.eventCode )
1701  case 2: // mouse up
1702  set_panel_attributes(ba.win, "", clear=1)
1703  set_panel_message(ba.win, "")
1704  set_panel_graphs(ba.win, "")
1705  break
1706  case -1: // control being killed
1707  break
1708  endswitch
1709 
1710  return 0
1711 end
1712 
1713 static function bp_login(ba) : ButtonControl
1714  STRUCT WMButtonAction &ba
1715 
1716  switch( ba.eventCode )
1717  case 2: // mouse up
1718  string logbook = GetUserData(ba.win, "", "logbook")
1719  if (elog_prompt_login(logbook) == 0)
1720  Button b_login, win=$ba.win, disable=3
1721  Button b_logout, win=$ba.win, disable=0
1722  endif
1723  break
1724  case -1: // control being killed
1725  break
1726  endswitch
1727 
1728  return 0
1729 end
1730 
1731 static function bp_logout(ba) : ButtonControl
1732  STRUCT WMButtonAction &ba
1733 
1734  switch( ba.eventCode )
1735  case 2: // mouse up
1736  string logbook = GetUserData(ba.win, "", "logbook")
1737  elog_logout(logbook)
1738  Button b_login, win=$ba.win, disable=0
1739  Button b_logout, win=$ba.win, disable=3
1740  break
1741  case -1: // control being killed
1742  break
1743  endswitch
1744 
1745  return 0
1746 end
1747 
1748 static function /s get_default_panel_name()
1749  string windowname
1750  windowname = StringFromList(0, WinList("*ElogPanel*", ";", "WIN:64"), ";")
1751  return windowname
1752 end
1753 
1761 static function /s get_panel_attributes(windowname)
1762  string windowname
1763 
1764  if (strlen(windowname) == 0)
1765  windowname = get_default_panel_name()
1766  endif
1767  if (strlen(windowname) == 0)
1768  return ""
1769  endif
1770 
1771  string controls = ControlNameList(windowname, ";")
1772  string attributes = ""
1773  string control
1774  string attribute
1775  variable ico
1776  variable nco = ItemsInList(controls, ";")
1777  for (ico = 0; ico < nco; ico += 1)
1778  control = StringFromList(ico, controls, ";")
1779  attribute = GetUserData(windowname, control, "attribute")
1780  if (strlen(attribute) > 0)
1781  ControlInfo /w=$windowname $control
1782  switch(v_flag)
1783  case 2: // checkbox
1784  attributes = ReplaceNumberByKey(attribute, attributes, v_value, "=", ";")
1785  break
1786  case 3: // popupmenu
1787  case 5: // setvariable
1788  attributes = ReplaceStringByKey(attribute, attributes, s_value, "=", ";")
1789  break
1790  endswitch
1791  endif
1792  endfor
1793 
1794  return attributes
1795 end
1796 
1808 static function /s set_panel_attributes(windowname, attributes, [clear])
1809  string windowname
1810  string attributes
1811  variable clear
1812 
1813  if (strlen(windowname) == 0)
1814  windowname = get_default_panel_name()
1815  endif
1816  if (strlen(windowname) == 0)
1817  return ""
1818  endif
1819  if (ParamIsDefault(clear))
1820  clear = 0
1821  endif
1822 
1823  string path
1824 
1825  string logbook = GetUserData(windowname, "", "logbook")
1826  dfref df_persistent = get_elog_df(logbook, kdfPersistent)
1827  string persistent_path = GetDataFolder(1, df_persistent)
1828  svar /sdfr=df_persistent options
1829  string options_path
1830 
1831  string controls = ControlNameList(windowname, ";")
1832  string control
1833  string attribute
1834  string value
1835  variable numval
1836  variable ico
1837  variable nco = ItemsInList(controls, ";")
1838  for (ico = 0; ico < nco; ico += 1)
1839  control = StringFromList(ico, controls, ";")
1840  attribute = GetUserData(windowname, control, "attribute")
1841  if (strlen(attribute))
1842  value = StringByKey(attribute, attributes, "=", ";")
1843  if (strlen(value) || clear)
1844  ControlInfo /w=$windowname $control
1845  switch(v_flag)
1846  case 2: // checkbox
1847  numval = NumberByKey(attribute, attributes, "=", ";")
1848  if ((numtype(numval) != 0) && clear)
1849  numval = 0
1850  endif
1851  if (numtype(numval) == 0)
1852  CheckBox $control, value=numval, win=$windowname
1853  endif
1854  break
1855  case 3: // popupmenu
1856  options_path = persistent_path + StringByKey(attribute, options, "=", ";")
1857  svar values = $options_path
1858  numval = WhichListItem(value, values, ";") + 1
1859  if (numval >= 1)
1860  PopupMenu $control, mode=numval, win=$windowname
1861  endif
1862  break
1863  case 5: // setvariable
1864  SetVariable /z $control, value= _STR:value, win=$windowname
1865  break
1866  endswitch
1867  endif
1868  endif
1869  endfor
1870 
1871  return attributes
1872 end
1873 
1881 static function /s get_panel_message(windowname)
1882  string windowname
1883 
1884  if (strlen(windowname) == 0)
1885  windowname = get_default_panel_name()
1886  endif
1887  if (strlen(windowname) == 0)
1888  return ""
1889  endif
1890 
1891  string nb = windowname + "#Message"
1892  notebook $nb selection={startOfFile, endOfFile}
1893  getselection notebook, $nb, 2
1894 
1895  return s_selection
1896 end
1897 
1907 static function /s set_panel_message(windowname, message)
1908  string windowname
1909  string message
1910 
1911  if (strlen(windowname) == 0)
1912  windowname = get_default_panel_name()
1913  endif
1914 
1915  string nb = windowname + "#Message"
1916  notebook $nb selection={startOfFile, endOfFile},text=message
1917 
1918  return message
1919 end
1920 
1927 static function /s get_panel_graphs(windowname)
1928  string windowname // panel window name
1929 
1930  dfref savedf = getdatafolderdfr()
1931  if (strlen(windowname) == 0)
1932  windowname = get_default_panel_name()
1933  endif
1934  if (strlen(windowname) == 0)
1935  return ""
1936  endif
1937 
1938  string logbook = GetUserData(windowname, "", "logbook")
1939  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
1940  wave /t /sdfr=df_volatile attach_list
1941  wave /sdfr=df_volatile attach_sel
1942  string graphs = ""
1943  string windows = ""
1944  string graphname
1945 
1946  variable n = DimSize(attach_sel, 0)
1947  variable i
1948  for (i = 0; i < n; i += 1)
1949  if (attach_sel[i][kAttachColSel] & 16)
1950  graphname = attach_list[i][kAttachColName]
1951  windows = WinList(graphname, ";", "WIN:1")
1952  if (ItemsInList(windows) == 1)
1953  graphs = AddListItem(graphname, graphs, ";", inf)
1954  endif
1955  endif
1956  endfor
1957 
1958  return graphs
1959 end
1960 
1967 static function /s set_panel_graphs(windowname, graphs)
1968  string windowname
1969  string graphs
1970 
1971  if (strlen(windowname) == 0)
1972  windowname = get_default_panel_name()
1973  endif
1974  if (strlen(windowname) == 0)
1975  return ""
1976  endif
1977 
1978  string logbook = GetUserData(windowname, "", "logbook")
1979  update_attach_items(logbook)
1980  dfref df_volatile = get_elog_df(logbook, kdfVolatile)
1981  wave /t /sdfr=df_volatile attach_list
1982  wave /sdfr=df_volatile attach_sel
1983 
1984  variable n = DimSize(attach_sel, 0)
1985  variable i
1986  string graphname
1987  for (i = 0; i < n; i += 1)
1988  graphname = attach_list[i][kAttachColName]
1989  if (WhichListItem(graphname, graphs)>= 0)
1990  attach_sel[i][kAttachColSel] = 48
1991  else
1992  attach_sel[i][kAttachColSel] = 32
1993  endif
1994  endfor
1995 end
IgorQuitHook
static variable IgorQuitHook(string igorApplicationNameStr)
save preferences and recent values before Igor quits.
Definition: pearl-elog.ipf:136
bp_login
static variable bp_login(WMButtonAction *ba)
Definition: pearl-elog.ipf:1713
get_log_path
static string get_log_path()
Definition: pearl-elog.ipf:1096
elog_login
variable elog_login(string logbook, string username, string password)
set username and password for login to a logbook
Definition: pearl-elog.ipf:514
kdfTemplates
static const variable kdfTemplates
Definition: pearl-elog.ipf:157
list_logbooks
static string list_logbooks(variable templates=defaultValue)
get a list of configured logbooks or templates.
Definition: pearl-elog.ipf:619
get_panel_graphs
static string get_panel_graphs(string windowname)
get the names of the graphs selected for attachment
Definition: pearl-elog.ipf:1927
package_path
static const string package_path
Definition: pearl-elog.ipf:87
bp_attach_top
static variable bp_attach_top(WMButtonAction *ba)
select top graph window for attachment
Definition: pearl-elog.ipf:1599
create_graph_file
static string create_graph_file(string graphname, variable fileindex)
save a graph to a temporary graphics file
Definition: pearl-elog.ipf:1024
bp_attach
static variable bp_attach(WMButtonAction *ba)
Definition: pearl-elog.ipf:1636
bp_logout
static variable bp_logout(WMButtonAction *ba)
Definition: pearl-elog.ipf:1731
kAttachColTitle
static const variable kAttachColTitle
Definition: pearl-elog.ipf:1431
elog_init_pearl_templates
variable elog_init_pearl_templates()
setup PEARL template logbooks.
Definition: pearl-elog.ipf:263
elog_add_attachment
variable elog_add_attachment(string logbook, variable id, string graphs)
add one or more graphs to an existing ELOG entry
Definition: pearl-elog.ipf:793
PearlElogPanel
string PearlElogPanel(string logbook)
open a new panel for submitting data to ELOG.
Definition: pearl-elog.ipf:1242
move_attach_item
static variable move_attach_item(string logbook, variable item, variable distance)
move an attachment item in the list of attachments
Definition: pearl-elog.ipf:1496
pearl_elog
variable pearl_elog(string logbook)
main function to initialize ELOG and to open an ELOG panel.
Definition: pearl-elog.ipf:98
bp_clear
static variable bp_clear(WMButtonAction *ba)
Definition: pearl-elog.ipf:1697
elog_panel_hook
static variable elog_panel_hook(WMWinHookStruct *s)
Definition: pearl-elog.ipf:1396
PearlElog
interface for writing ELOG entries with Igor graphs as attachment.
get_panel_attributes
static string get_panel_attributes(string windowname)
get a list of attributes from the fields of the ELOG panel.
Definition: pearl-elog.ipf:1761
get_timestamp
static string get_timestamp(string sep)
Definition: pearl-elog.ipf:959
elog_success_msg
static const string elog_success_msg
Definition: pearl-elog.ipf:1134
bp_attach_updown
static variable bp_attach_updown(WMButtonAction *ba)
button procedure for the attachment up and down buttons
Definition: pearl-elog.ipf:1520
elog_prompt_logbook
string elog_prompt_logbook()
prompt to open or create a logbook
Definition: pearl-elog.ipf:1185
set_panel_message
static string set_panel_message(string windowname, string message)
set the message field of the ELOG panel
Definition: pearl-elog.ipf:1907
kdfPersistent
static const variable kdfPersistent
Definition: pearl-elog.ipf:156
elog_create_entry
variable elog_create_entry(string logbook, string attributes, string message, variable encoding=defaultValue, string graphs=defaultValue, variable replyto=defaultValue)
create a new entry in ELOG
Definition: pearl-elog.ipf:686
create_cmd_file
static string create_cmd_file(string cmd)
write the command line to a file.
Definition: pearl-elog.ipf:1060
create_message_file
static string create_message_file(string message)
save the message to a temporary text file
Definition: pearl-elog.ipf:983
bp_attach_allnone
static variable bp_attach_allnone(WMButtonAction *ba)
select/deselect all graph windows for attachment
Definition: pearl-elog.ipf:1615
package_name
static const string package_name
Definition: pearl-elog.ipf:86
prepare_graph_attachments
static string prepare_graph_attachments(string graphs)
prepare screenshots of graph windows for attachments
Definition: pearl-elog.ipf:940
IgorBeforeNewHook
static variable IgorBeforeNewHook(string igorApplicationNameStr)
save preferences and recent values before Igor opens a new experiment.
Definition: pearl-elog.ipf:128
elog_parse_id
static const string elog_parse_id
Definition: pearl-elog.ipf:1135
get_elog_df
static dfr get_elog_df(string name, variable category)
get the package, logbook, or template datafolder.
Definition: pearl-elog.ipf:171
parse_result
static variable parse_result()
parse the result file from an elog invokation.
Definition: pearl-elog.ipf:1142
elog_config
variable elog_config(string elog_path=defaultValue, string hostname=defaultValue, variable port=defaultValue, string subdir=defaultValue)
set global module configuration parameters
Definition: pearl-elog.ipf:474
elog_create_logbook
variable elog_create_logbook(string name, string template=defaultValue)
create a new logbook.
Definition: pearl-elog.ipf:415
prepare_command_line
static string prepare_command_line(string logbook)
format the ELOG command and essential address arguments.
Definition: pearl-elog.ipf:854
set_panel_graphs
static string set_panel_graphs(string windowname, string graphs)
update selection of graphs for attachment
Definition: pearl-elog.ipf:1967
elog_prompt_login
variable elog_prompt_login(string logbook)
prompt the user for login to a logbook
Definition: pearl-elog.ipf:1215
cleanup_temp_files
static variable cleanup_temp_files()
delete temporary files created by the ELOG module.
Definition: pearl-elog.ipf:1116
save_prefs
static variable save_prefs()
save persistent package data to the preferences file.
Definition: pearl-elog.ipf:565
update_attach_items
static variable update_attach_items(string logbook)
update the list of attachments
Definition: pearl-elog.ipf:1435
kdfVolatile
static const variable kdfVolatile
Definition: pearl-elog.ipf:155
kAttachColSel
static const variable kAttachColSel
Definition: pearl-elog.ipf:1430
bp_save_graphs
static variable bp_save_graphs(WMButtonAction *ba)
Definition: pearl-elog.ipf:1669
get_panel_message
static string get_panel_message(string windowname)
get the message field of the ELOG panel
Definition: pearl-elog.ipf:1881
elog_logout
variable elog_logout(string logbook)
clear username and password of a logbook or all logbooks.
Definition: pearl-elog.ipf:534
init_volatile_vars
static variable init_volatile_vars()
initialize volatile variables.
Definition: pearl-elog.ipf:341
format_url
static string format_url(string logbook)
format the URL for display to the user
Definition: pearl-elog.ipf:903
kAttachColName
static const variable kAttachColName
Definition: pearl-elog.ipf:1432
bp_submit
static variable bp_submit(WMButtonAction *ba)
button procedure for the Submit and Reply buttons
Definition: pearl-elog.ipf:1552
kdfRoot
static const variable kdfRoot
Definition: pearl-elog.ipf:154
elog_validate_attributes
variable elog_validate_attributes(string logbook, string attributes)
validate attributes
Definition: pearl-elog.ipf:654
load_prefs
static variable load_prefs()
load persistent package data from the preferences file.
Definition: pearl-elog.ipf:585
get_default_panel_name
static string get_default_panel_name()
Definition: pearl-elog.ipf:1748
AfterFileOpenHook
static variable AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind)
initialize the package and reload preferences after an experiment is loaded.
Definition: pearl-elog.ipf:144
init_package
static variable init_package(variable clean=defaultValue)
initialize the package data folder.
Definition: pearl-elog.ipf:218
set_panel_attributes
static string set_panel_attributes(string windowname, string attributes, variable clear=defaultValue)
set the fields of the ELOG panel
Definition: pearl-elog.ipf:1808