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