ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilPCFileListGUI.php
Go to the documentation of this file.
1 <?php
2 
26 {
27  protected string $requested_file_ref_id;
28  protected ilObjUser $user;
29  protected ilTabsGUI $tabs;
30  protected ilTree $tree;
32  protected ilSetting $settings;
33 
34  public function __construct(
35  ilPageObject $a_pg_obj,
36  ?ilPageContent $a_content_obj,
37  string $a_hier_id,
38  string $a_pc_id = ""
39  ) {
40  global $DIC;
41 
42  $this->user = $DIC->user();
43  $this->tabs = $DIC->tabs();
44  $this->ctrl = $DIC->ctrl();
45  $this->tpl = $DIC["tpl"];
46  $this->tree = $DIC->repositoryTree();
47  $this->lng = $DIC->language();
48  $this->toolbar = $DIC->toolbar();
49  $this->settings = $DIC->settings();
50  parent::__construct($a_pg_obj, $a_content_obj, $a_hier_id, $a_pc_id);
51  $this->setCharacteristics(array("FileListItem" => $this->lng->txt("cont_FileListItem")));
52  $this->requested_file_ref_id = $this->request->getString("file_ref_id");
53  }
54 
58  public function executeCommand(): void
59  {
60  // get next class that processes or forwards current command
61  $next_class = $this->ctrl->getNextClass($this);
62 
63  $this->getCharacteristicsOfCurrentStyle(["flist_li"]); // scorm-2004
64 
65  // get current command
66  $cmd = $this->ctrl->getCmd();
67 
68  switch ($next_class) {
69  default:
70  $this->$cmd();
71  break;
72  }
73  }
74 
78  public function insert(ilPropertyFormGUI $a_form = null): void
79  {
80  $ilTabs = $this->tabs;
82 
83  if (in_array($sub_command, ["insertNew", "insertFromRepository", "insertFromWorkspace"])) {
84  $this->edit_repo->setSubCmd($sub_command);
85  }
86 
87  if (($sub_command == "") && $this->edit_repo->getSubCmd() != "") {
88  $sub_command = $this->edit_repo->getSubCmd();
89  }
90 
91  switch ($sub_command) {
92  case "insertFromWorkspace":
93  $this->insertFromWorkspace();
94  break;
95 
96  case "insertFromRepository":
97  $this->insertFromRepository();
98  break;
99 
100  case "selectFile":
101  $this->selectFile();
102  break;
103 
104  default:
105  $this->setTabs();
106  $ilTabs->setSubTabActive("cont_new_file");
107 
108  $this->displayValidationError();
109 
110  if ($a_form != null) {
111  $form = $a_form;
112  } else {
113  $form = $this->initEditForm("create");
114  }
115  $this->tpl->setContent($form->getHTML());
116  break;
117  }
118  }
119 
120  public function selectFile(): void
121  {
122  $ilTabs = $this->tabs;
123  $this->setTabs();
124  $ilTabs->setSubTabActive("cont_file_from_repository");
125 
126  $this->displayValidationError();
127  $form = $this->initEditForm("select_file");
128 
129  $this->tpl->setContent($form->getHTML());
130  }
131 
135  public function insertFromRepository(string $a_cmd = "insert"): void
136  {
137  $ilTabs = $this->tabs;
138  $ilCtrl = $this->ctrl;
139  $tpl = $this->tpl;
140 
141  if ($a_cmd == "insert") {
142  $this->setTabs();
143  } else {
144  $this->setItemTabs($a_cmd);
145  }
146 
147  $ilTabs->setSubTabActive("cont_file_from_repository");
148  $ilCtrl->setParameter($this, "subCmd", "insertFromRepository");
149 
150  $exp = new ilPCFileItemFileSelectorGUI(
151  $this,
152  $a_cmd,
153  $this,
154  $a_cmd,
155  "file_ref_id"
156  );
157  if (!$exp->handleCommand()) {
158  $tpl->setContent($exp->getHTML());
159  }
160  }
161 
165  public function insertFromWorkspace(
166  string $a_cmd = "insert"
167  ): void {
168  $ilTabs = $this->tabs;
169  $ilCtrl = $this->ctrl;
170  $tpl = $this->tpl;
171  $ilUser = $this->user;
172 
173  if ($a_cmd == "insert") {
174  $this->setTabs();
175  } else {
176  $this->setItemTabs($a_cmd);
177  }
178 
179  $ilTabs->setSubTabActive("cont_file_from_workspace");
180 
181  $exp = new ilWorkspaceExplorerGUI($ilUser->getId(), $this, $a_cmd, $this, $a_cmd, "fl_wsp_id");
182  $ilCtrl->setParameter($this, "subCmd", "selectFile");
183  $exp->setCustomLinkTarget($ilCtrl->getLinkTarget($this, $a_cmd));
184  $ilCtrl->setParameter($this, "subCmd", "insertFromWorkspace");
185  $exp->setTypeWhiteList(array("wsrt", "wfld", "file"));
186  $exp->setSelectableTypes(array("file"));
187  if ($exp->handleCommand()) {
188  return;
189  }
190  $tpl->setContent($exp->getHTML());
191  }
192 
196  public function create(): void
197  {
198  global $DIC;
199 
200  $mode = ($this->requested_file_ref_id != "")
201  ? "select_file"
202  : "create";
203  $form = $this->initEditForm($mode);
204  if (!$form->checkInput()) {
205  $form->setValuesByPost();
206  $this->insert($form);
207  return;
208  }
209 
210  // from personal workspace
211  if (substr($this->requested_file_ref_id, 0, 4) == "wsp_") {
212  $fileObj = new ilObjFile(substr($this->requested_file_ref_id, 4), false);
213  }
214  // upload
215  elseif ($this->requested_file_ref_id == "") {
216  $fileObj = new ilObjFile();
217  $fileObj->setType("file");
218  $fileObj->setTitle($_FILES["file"]["name"]);
219  $fileObj->setDescription("");
220  $fileObj->setFileName($_FILES["file"]["name"]);
221  $fileObj->setMode("filelist");
222  $fileObj->create();
223  // upload file to filesystem
224 
225  $upload = $DIC->upload();
226  if ($upload->hasBeenProcessed() !== true) {
227  $upload->process();
228  }
229 
230  $fileObj->getUploadFile(
231  $_FILES["file"]["tmp_name"],
232  $_FILES["file"]["name"]
233  );
234  }
235  // from repository
236  else {
237  $fileObj = new ilObjFile($this->requested_file_ref_id);
238  }
239  $this->setCurrentTextLang($form->getInput("flst_language"));
240 
241  //echo "::".is_object($this->dom).":";
242  $this->content_obj = new ilPCFileList($this->getPage());
243  $this->content_obj->create($this->pg_obj, $this->hier_id, $this->pc_id);
244  $this->content_obj->setListTitle(
245  $form->getInput("flst_title"),
246  $form->getInput("flst_language")
247  );
248  $this->content_obj->appendItem(
249  $fileObj->getId(),
250  $fileObj->getFileName(),
251  $fileObj->getFileType()
252  );
253 
254  $this->updated = $this->pg_obj->update();
255  if ($this->updated === true) {
256  $this->afterCreation();
257  } else {
258  $this->insert();
259  }
260  }
261 
262  public function afterCreation(): void
263  {
264  $this->pg_obj->stripHierIDs();
265  $this->pg_obj->addHierIDs();
266  $this->ctrl->setParameter($this, "hier_id", $this->content_obj->readHierId());
267  $this->ctrl->setParameter($this, "pc_id", $this->content_obj->readPCId());
268  $this->ctrl->redirect($this, "editFiles");
269  }
270 
271  public function edit(): void
272  {
273  $this->editFiles();
274  }
275 
279  public function editProperties(): void
280  {
281  $this->setTabs(false);
282 
283  $form = $this->initEditForm();
284  $this->tpl->setContent($form->getHTML());
285  }
286 
290  public function initEditForm(string $a_mode = "edit"): ilPropertyFormGUI
291  {
292  $lng = $this->lng;
293  $ilCtrl = $this->ctrl;
294  $ilUser = $this->user;
295 
296  $ti = null;
297  $si = null;
298  $form = new ilPropertyFormGUI();
299 
300  if ($a_mode != "add_file") {
301  // title
302  $ti = new ilTextInputGUI($lng->txt("title"), "flst_title");
303  $ti->setMaxLength(80);
304  $ti->setSize(40);
305  $form->addItem($ti);
306 
307  // language
308  $languages = [];
309  foreach ($this->lom_services->dataHelper()->getAllLanguages() as $language) {
310  $languages[$language->value()] = $language->presentableLabel();
311  }
312  $si = new ilSelectInputGUI($lng->txt("language"), "flst_language");
313  $si->setOptions($languages);
314  $form->addItem($si);
315  }
316 
317  if (in_array($a_mode, array("create", "add_file"))) {
318  // file
319  $fi = new ilFileInputGUI($lng->txt("file"), "file");
320  $fi->setRequired(true);
321  $form->addItem($fi);
322  } elseif (in_array($a_mode, array("select_file"))) {
323  // file
324  $ne = new ilNonEditableValueGUI($lng->txt("file"), "");
325 
326  $file_ref_id = (int) $this->requested_file_ref_id;
327  $fl_wsp_id = $this->request->getInt("fl_wsp_id");
328 
329  if ($file_ref_id > 0) {
330  $file_obj = new ilObjFile($file_ref_id);
331  if (is_object($file_obj)) {
332  // ref id as hidden input
333  $hi = new ilHiddenInputGUI("file_ref_id");
334  $hi->setValue($file_ref_id);
335  $form->addItem($hi);
336 
337  $ne->setValue($file_obj->getTitle());
338  }
339  } elseif ($fl_wsp_id > 0) {
340  // we need the object id for the instance
341  $tree = new ilWorkspaceTree($ilUser->getId());
342  $node = $tree->getNodeData($fl_wsp_id);
343 
344  $file_obj = new ilObjFile($node["obj_id"], false);
345  if (is_object($file_obj)) {
346  // ref id as hidden input
347  $hi = new ilHiddenInputGUI("file_ref_id");
348  $hi->setValue("wsp_" . (int) $node["obj_id"]);
349  $form->addItem($hi);
350 
351  $ne->setValue($file_obj->getTitle());
352  }
353  $this->tpl->parseCurrentBlock();
354  }
355 
356  $form->addItem($ne);
357  }
358 
359 
360  switch ($a_mode) {
361  case "edit":
362  $ti->setValue($this->content_obj->getListTitle());
363  $si->setValue($this->content_obj->getLanguage());
364  $form->addCommandButton("saveProperties", $lng->txt("save"));
365  $form->addCommandButton("cancelUpdate", $lng->txt("cancel"));
366  $form->setTitle($lng->txt("cont_edit_file_list_properties"));
367  break;
368 
369  case "create":
370  case "select_file":
371  if ($this->getCurrentTextLang() != "") {
372  $s_lang = $this->getCurrentTextLang();
373  } else {
374  $s_lang = $ilUser->getLanguage();
375  }
376  $si->setValue($s_lang);
377  $form->addCommandButton("create", $lng->txt("save"));
378  $form->addCommandButton("cancelCreate", $lng->txt("cancel"));
379  $form->setTitle($lng->txt("cont_insert_file_list"));
380  break;
381 
382  case "add_file":
383  $form->addCommandButton("insertNewFileItem", $lng->txt("save"));
384  $form->addCommandButton("editFiles", $lng->txt("cancel"));
385  $form->setTitle($lng->txt("cont_insert_file_item"));
386  break;
387  }
388 
389  $form->setFormAction($ilCtrl->getFormAction($this));
390 
391  return $form;
392  }
393 
394 
398  public function saveProperties(): void
399  {
400  $form = $this->initEditForm("edit");
401  $form->checkInput();
402  $this->content_obj->setListTitle(
403  $form->getInput("flst_title"),
404  $form->getInput("flst_language")
405  );
406  $this->updated = $this->pg_obj->update();
407  if ($this->updated === true) {
408  $this->tpl->setOnScreenMessage('success', $this->lng->txt("msg_obj_modified"), true);
409  $this->ctrl->redirect($this, "editProperties");
410  } else {
411  $this->pg_obj->addHierIDs();
412  $this->edit();
413  }
414  }
415 
419  public function editFiles(): void
420  {
421  $tpl = $this->tpl;
422  $ilToolbar = $this->toolbar;
423  $ilCtrl = $this->ctrl;
424  $lng = $this->lng;
425 
426  $this->setTabs(false);
427  $this->tabs->activateTab("cont_ed_edit_files");
428 
429  $ilToolbar->addButton(
430  $lng->txt("cont_add_file"),
431  $ilCtrl->getLinkTarget($this, "addFileItem")
432  );
433 
435  $fl = $this->content_obj;
436  $table_gui = new ilPCFileListTableGUI($this, "editFiles", $fl);
437  $tpl->setContent($table_gui->getHTML());
438  }
439 
443  public function setTabs(bool $a_create = true): void
444  {
445  $ilTabs = $this->tabs;
446  $ilCtrl = $this->ctrl;
447  $lng = $this->lng;
449 
450  if ($a_create) {
451  $cmd = "insert";
452 
453  $ilCtrl->setParameter($this, "subCmd", "insertNew");
454  $ilTabs->addSubTabTarget(
455  "cont_new_file",
456  $ilCtrl->getLinkTarget($this, $cmd),
457  $cmd
458  );
459 
460  $ilCtrl->setParameter($this, "subCmd", "insertFromRepository");
461  $ilTabs->addSubTabTarget(
462  "cont_file_from_repository",
463  $ilCtrl->getLinkTarget($this, $cmd),
464  $cmd
465  );
466  $ilCtrl->setParameter($this, "subCmd", "");
467 
468  if (!$ilSetting->get("disable_personal_workspace") &&
469  !$ilSetting->get("disable_wsp_files")) {
470  $ilCtrl->setParameter($this, "subCmd", "insertFromWorkspace");
471  $ilTabs->addSubTabTarget(
472  "cont_file_from_workspace",
473  $ilCtrl->getLinkTarget($this, $cmd),
474  $cmd
475  );
476  $ilCtrl->setParameter($this, "subCmd", "");
477  }
478  } else {
479  $ilTabs->setBackTarget(
480  $lng->txt("pg"),
481  $this->ctrl->getParentReturn($this)
482  );
483 
484  $ilTabs->addTarget(
485  "cont_ed_edit_files",
486  $ilCtrl->getLinkTarget($this, "editFiles"),
487  "editFiles",
488  get_class($this)
489  );
490 
491  $ilTabs->addTarget(
492  "cont_ed_edit_prop",
493  $ilCtrl->getLinkTarget($this, "editProperties"),
494  "editProperties",
495  get_class($this)
496  );
497  }
498  }
499 
504  public function addFileItem(): void
505  {
506  $ilCtrl = $this->ctrl;
507 
508  $files = $this->content_obj->getFileList();
509 
510  if (count($files) >= 1) {
511  $ilCtrl->setParameterByClass(
512  "ilpcfileitemgui",
513  "hier_id",
514  $files[count($files) - 1]["hier_id"]
515  );
516  $ilCtrl->setParameterByClass(
517  "ilpcfileitemgui",
518  "pc_id",
519  $files[count($files) - 1]["pc_id"]
520  );
521  $ilCtrl->redirectByClass("ilpcfileitemgui", "newItemAfter");
522  } else {
523  $ilCtrl->redirect($this, "newFileItem");
524  }
525  }
526 
530  public function deleteFileItem(): void
531  {
532  $ilCtrl = $this->ctrl;
533 
534  $fid = $this->request->getIntArray("fid");
535  if (count($fid) > 0) {
536  $this->content_obj->deleteFileItems(array_keys($fid));
537  }
538  $this->updated = $this->pg_obj->update();
539  $ilCtrl->redirect($this, "editFiles");
540  }
541 
545  public function savePositions(): void
546  {
547  $ilCtrl = $this->ctrl;
548 
549  $pos = $this->request->getIntArray("position");
550  if (count($pos) > 0) {
551  $this->content_obj->savePositions($pos);
552  }
553  $this->updated = $this->pg_obj->update();
554  $ilCtrl->redirect($this, "editFiles");
555  }
556 
560  public function savePositionsAndClasses(): void
561  {
562  $ilCtrl = $this->ctrl;
563 
564  $pos = $this->request->getIntArray("position");
565  $class = $this->request->getStringArray("class");
566  if (count($pos) > 0) {
567  $this->content_obj->savePositions($pos);
568  }
569  if (count($class) > 0) {
570  $this->content_obj->saveStyleClasses($class);
571  }
572  $this->updated = $this->pg_obj->update();
573  $ilCtrl->redirect($this, "editFiles");
574  }
575 
579  public function checkStyleSelection(): bool
580  {
581  // check whether there is more than one style class
582  $chars = $this->getCharacteristics();
583 
584  $classes = $this->content_obj->getAllClasses();
585  if (count($chars) > 1) {
586  return true;
587  }
588  foreach ($classes as $class) {
589  if ($class != "" && $class != "FileListItem") {
590  return true;
591  }
592  }
593  return false;
594  }
595 
596  //
597  //
598  // New file item
599  //
600  //
601 
605  public function newFileItem(): void
606  {
607  $ilTabs = $this->tabs;
608 
610  if (in_array($sub_command, ["insertNew", "insertFromRepository", "insertFromWorkspace"])) {
611  $this->edit_repo->setSubCmd($sub_command);
612  }
613 
614  if (($sub_command == "") && $this->edit_repo->getSubCmd() != "") {
615  $sub_command = $this->edit_repo->getSubCmd();
616  }
617 
618  switch ($sub_command) {
619  case "insertFromWorkspace":
620  $this->insertFromWorkspace("newFileItem");
621  break;
622 
623  case "insertFromRepository":
624  $this->insertFromRepository("newFileItem");
625  break;
626 
627  case "selectFile":
628  $this->insertNewFileItem($this->requested_file_ref_id);
629  break;
630 
631  default:
632  $this->setItemTabs("newFileItem");
633  $ilTabs->setSubTabActive("cont_new_file");
634 
635  $this->displayValidationError();
636 
637  $form = $this->initEditForm("add_file");
638  $this->tpl->setContent($form->getHTML());
639  break;
640  }
641  }
642 
646  public function insertNewFileItem(int $a_file_ref_id = 0): void
647  {
648  $ilUser = $this->user;
649 
650  $fl_wsp_id = $this->request->getInt("fl_wsp_id");
651 
652  // from personal workspace
653  if ($fl_wsp_id > 0) {
654  // we need the object id for the instance
655  $tree = new ilWorkspaceTree($ilUser->getId());
656  $node = $tree->getNodeData($fl_wsp_id);
657 
658  $file_obj = new ilObjFile($node["obj_id"], false);
659  }
660  // upload
661  elseif ($a_file_ref_id == 0) {
662  $file_obj = $this->createFileItem();
663  }
664  // from repository
665  else {
666  $file_obj = new ilObjFile($a_file_ref_id);
667  }
668  if (is_object($file_obj)) {
669  $this->content_obj->appendItem(
670  $file_obj->getId(),
671  $file_obj->getTitle(),
672  $file_obj->getFileType()
673  );
674  $this->updated = $this->pg_obj->update();
675  if ($this->updated === true) {
676  //$this->ctrl->returnToParent($this, "jump".$this->hier_id);
677  $this->ctrl->redirect($this, "editFiles");
678  }
679  }
680 
681  $this->newFileItem();
682  }
683 
687  public function createFileItem(): ?ilObjFile
688  {
689  global $DIC;
690 
691  $lng = $this->lng;
692 
693  if ($_FILES["file"]["name"] == "") {
694  throw new ilCOPageFileHandlingException($lng->txt("upload_error_file_not_found"));
695  }
696 
697  $form = $this->initEditForm();
698  // see #22541
699  // $form->checkInput();
700 
701  $fileObj = new ilObjFile();
702  $fileObj->setType("file");
703  $fileObj->setTitle($_FILES["file"]["name"]);
704  $fileObj->setDescription("");
705  $fileObj->setFileName($_FILES["file"]["name"]);
706  $fileObj->setMode("filelist");
707  $fileObj->create();
708  // upload file to filesystem
709 
710  $upload = $DIC->upload();
711  if ($upload->hasBeenProcessed() !== true) {
712  $upload->process();
713  }
714 
715  $fileObj->getUploadFile(
716  $_FILES["file"]["tmp_name"],
717  $_FILES["file"]["name"]
718  );
719 
720  return $fileObj;
721  }
722 
723 
727  public function setItemTabs(string $a_cmd = ""): void
728  {
729  $ilTabs = $this->tabs;
730  $ilCtrl = $this->ctrl;
732 
733  $ilTabs->addTarget(
734  "cont_back",
735  $this->ctrl->getParentReturn($this),
736  "",
737  ""
738  );
739 
740  if ($a_cmd != "") {
741  $ilCtrl->setParameter($this, "subCmd", "insertNew");
742  $ilTabs->addSubTabTarget(
743  "cont_new_file",
744  $ilCtrl->getLinkTarget($this, $a_cmd),
745  $a_cmd
746  );
747 
748  $ilCtrl->setParameter($this, "subCmd", "insertFromRepository");
749  $ilTabs->addSubTabTarget(
750  "cont_file_from_repository",
751  $ilCtrl->getLinkTarget($this, $a_cmd),
752  $a_cmd
753  );
754  $ilCtrl->setParameter($this, "subCmd", "");
755 
756  if (!$ilSetting->get("disable_personal_workspace") &&
757  !$ilSetting->get("disable_wsp_files")) {
758  $ilCtrl->setParameter($this, "subCmd", "insertFromWorkspace");
759  $ilTabs->addSubTabTarget(
760  "cont_file_from_workspace",
761  $ilCtrl->getLinkTarget($this, $a_cmd),
762  $a_cmd
763  );
764  $ilCtrl->setParameter($this, "subCmd", "");
765  }
766  }
767  }
768 }
newFileItem()
New file item (called, if there is no file item in an existing)
getNodeData(int $a_node_id, ?int $a_tree_pk=null)
get all information of a node.
getCharacteristicsOfCurrentStyle(array $a_type)
Get characteristics of current style and call setCharacteristics, if style is given.
This class represents a selection list property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
redirect(object $a_gui_obj, string $a_cmd=null, string $a_anchor=null, bool $is_async=false)
__construct(ilPageObject $a_pg_obj, ?ilPageContent $a_content_obj, string $a_hier_id, string $a_pc_id="")
createFileItem()
insert new file item
setTabs(bool $a_create=true)
Set Tabs.
deleteFileItem()
Delete file items from list.
This class represents a file property in a property form.
insertFromRepository(string $a_cmd="insert")
Insert file from repository.
insertFromWorkspace(string $a_cmd="insert")
Insert file from personal workspace.
setParameterByClass(string $a_class, string $a_parameter, $a_value)
setOptions(array $a_options)
setCharacteristics(array $a_chars)
Content object of ilPageObject (see ILIAS DTD).
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
editProperties()
edit properties form
insertNewFileItem(int $a_file_ref_id=0)
insert new file item after another item
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
User Interface for Editing of Page Content Objects (Paragraphs, Tables, ...)
executeCommand()
execute command
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setContent(string $a_html)
Sets content for standard template.
Class ilPageObject Handles PageObjects of ILIAS Learning Modules (see ILIAS DTD)
Class ilObjFile.
global $DIC
Definition: shib_login.php:25
Explorer for selecting a personal workspace item.
ilGlobalTemplateInterface $tpl
setItemTabs(string $a_cmd="")
output tabs
setCurrentTextLang(string $lang_key)
setRequired(bool $a_required)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
checkStyleSelection()
Checks whether style selection shoudl be available or not.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $ilSetting
Definition: privfeed.php:32
__construct(Container $dic, ilPlugin $plugin)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
initEditForm(string $a_mode="edit")
Init edit form.
create()
create new file list in dom and update page in db
insert(ilPropertyFormGUI $a_form=null)
insert new file list form
saveProperties()
save table properties in db and return to page edit screen
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
savePositionsAndClasses()
Save positions of file items and style classes.
addFileItem()
Add file item.
savePositions()
Save positions of file items.