mirror of
https://github.com/ONLYOFFICE/sdkjs-forms.git
synced 2026-02-10 18:05:42 +08:00
664 lines
18 KiB
JavaScript
664 lines
18 KiB
JavaScript
/*
|
||
* (c) Copyright Ascensio System SIA 2010-2024
|
||
*
|
||
* This program is a free software product. You can redistribute it and/or
|
||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||
* version 3 as published by the Free Software Foundation. In accordance with
|
||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||
* of any third-party rights.
|
||
*
|
||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||
*
|
||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||
* street, Riga, Latvia, EU, LV-1050.
|
||
*
|
||
* The interactive user interfaces in modified source and object code versions
|
||
* of the Program must display Appropriate Legal Notices, as required under
|
||
* Section 5 of the GNU AGPL version 3.
|
||
*
|
||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||
* grant you any rights under trademark law for use of our trademarks.
|
||
*
|
||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||
* well as technical writing content are licensed under the terms of the
|
||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||
*
|
||
*/
|
||
|
||
"use strict";
|
||
|
||
(function(window)
|
||
{
|
||
/**
|
||
* Основной класс для работы с форматом oform
|
||
* @param document {AscWord.CDocument}
|
||
* @constructor
|
||
*/
|
||
function OForm(document)
|
||
{
|
||
this.Format = new AscOForm.CDocument(this);
|
||
this.Document = document;
|
||
this.CurrentUser = null;
|
||
|
||
// Сейчас у нас роль - это ровно один userMaster и ровно одна группа полей
|
||
this.Roles = [];
|
||
this.NeedUpdateRoles = true;
|
||
this.NeedRedraw = true;
|
||
}
|
||
/**
|
||
* @returns {AscWord.CDocument}
|
||
*/
|
||
OForm.prototype.getDocument = function()
|
||
{
|
||
return this.Document;
|
||
};
|
||
/**
|
||
* @returns {AscOForm.CDocument}
|
||
*/
|
||
OForm.prototype.getFormat = function()
|
||
{
|
||
return this.Format;
|
||
};
|
||
OForm.prototype.fromZip = function(zip, opt_sdtPrWithFieldPath)
|
||
{
|
||
let xmlPkg = new AscOForm.XmlPackage(zip);
|
||
xmlPkg.setContext(new AscOForm.XmlReaderContext(xmlPkg));
|
||
this.Format.fromPkg(xmlPkg, opt_sdtPrWithFieldPath);
|
||
};
|
||
OForm.prototype.toZip = function(zip, opt_fieldMastersPartMap)
|
||
{
|
||
let writer = new AscCommon.CMemory();
|
||
let xmlPkg = new AscOForm.XmlPackage(zip, writer);
|
||
xmlPkg.setContext(new AscOForm.XmlWriterContext(xmlPkg));
|
||
writer.context = xmlPkg.getContext();
|
||
this.Format.toPkg(xmlPkg, opt_fieldMastersPartMap);
|
||
|
||
// Наш XmlPackage работает в общей папке, а нам нужно запихнуть в zip подпапку oform
|
||
zip.getPaths().forEach(function(path)
|
||
{
|
||
let fileData = zip.getFile(path);
|
||
if (path.startsWith("oform/"))
|
||
zip.addFile(path.substr(6), fileData);
|
||
|
||
zip.removeFile(path);
|
||
});
|
||
};
|
||
OForm.prototype.setCurrentRole = function(roleName)
|
||
{
|
||
let role = this.getRole(roleName);
|
||
if (!role)
|
||
return;
|
||
|
||
this.CurrentUser = role.getUserMaster();
|
||
};
|
||
/**
|
||
* Difference between noRole and when role is not set, is that when role is not set we can fill any field,
|
||
* but when noRole is set then we can't fill anything
|
||
*/
|
||
OForm.prototype.setCurrentNoRole = function()
|
||
{
|
||
this.CurrentUser = AscOForm.getNoRole();
|
||
};
|
||
OForm.prototype.clearCurrentRole = function()
|
||
{
|
||
this.CurrentUser = null;
|
||
};
|
||
OForm.prototype.getCurrentRole = function()
|
||
{
|
||
return this.CurrentUser ? this.CurrentUser.getRole() : null;
|
||
};
|
||
OForm.prototype.getCurrentUserMaster = function()
|
||
{
|
||
return this.CurrentUser;
|
||
};
|
||
OForm.prototype.getAllRoles = function()
|
||
{
|
||
this.updateRoles();
|
||
return this.Roles;
|
||
};
|
||
/**
|
||
* @param roleSettings {AscOForm.CRoleSettings}
|
||
*/
|
||
OForm.prototype.addRole = function(roleSettings)
|
||
{
|
||
let name = "";
|
||
if ("string" === typeof roleSettings)
|
||
{
|
||
name = roleSettings;
|
||
roleSettings = new AscOForm.CRoleSettings();
|
||
roleSettings.setName(name);
|
||
}
|
||
|
||
if (roleSettings instanceof AscOForm.CRoleSettings)
|
||
name = roleSettings.getName();
|
||
else
|
||
return false;
|
||
|
||
if (this.haveRole(name))
|
||
return false;
|
||
|
||
if (!this.startAction(AscDFH.historydescription_OForm_AddRole))
|
||
return false;
|
||
|
||
let userMaster = new AscOForm.CUserMaster(true);
|
||
userMaster.setRole(name);
|
||
|
||
let color = roleSettings.getColor();
|
||
if (color)
|
||
userMaster.setColor(color.r, color.g, color.b);
|
||
|
||
let fieldGroup = new AscOForm.CFieldGroup();
|
||
fieldGroup.setWeight(this.Format.getMaxWeight() + 1);
|
||
fieldGroup.addUser(userMaster);
|
||
|
||
this.Format.addFieldGroup(fieldGroup);
|
||
this.Format.addUserMaster(userMaster);
|
||
|
||
this.endAction();
|
||
return true;
|
||
};
|
||
OForm.prototype.removeRole = function(name, delegateName)
|
||
{
|
||
this.updateRoles();
|
||
|
||
let roleIndex = this.getRoleIndex(name);
|
||
if (-1 === roleIndex)
|
||
return false;
|
||
|
||
let userMaster = this.Roles[roleIndex].getUserMaster();
|
||
let fieldGroup = this.Roles[roleIndex].getFieldGroup();
|
||
|
||
let fields = fieldGroup.getAllFields();
|
||
|
||
|
||
let delegateIndex = this.getRoleIndex(delegateName);
|
||
|
||
// На самом деле можно убрать эту проверку, но тогда мы просто удалим группу по умолчнию и заново её добавим
|
||
if (this.Roles.length <= 1
|
||
&& this.Roles[roleIndex].getUserMaster() === this.Format.getDefaultUserMaster()
|
||
&& -1 === delegateIndex)
|
||
{
|
||
let defaultUserMaster = this.Format.getDefaultUserMaster();
|
||
if (!defaultUserMaster.isDefaultUserProps())
|
||
{
|
||
if (!this.startAction(AscDFH.historydescription_OForm_RemoveRole))
|
||
return false;
|
||
|
||
defaultUserMaster.initDefaultUser();
|
||
|
||
this.NeedRedraw = true;
|
||
this.endAction();
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
if (!this.startAction(AscDFH.historydescription_OForm_RemoveRole))
|
||
return false;
|
||
|
||
fieldGroup.clear();
|
||
this.Format.removeFieldGroup(fieldGroup);
|
||
this.Format.removeUserMaster(userMaster);
|
||
|
||
if (fields.length > 0)
|
||
{
|
||
let delegateUserMaster, delegateFieldGroup;
|
||
if (-1 === delegateIndex || delegateIndex === roleIndex)
|
||
{
|
||
let defaultRole = this.getDefaultRole();
|
||
if (defaultRole)
|
||
{
|
||
delegateUserMaster = defaultRole.getUserMaster();
|
||
delegateFieldGroup = defaultRole.getFieldGroup();
|
||
}
|
||
else
|
||
{
|
||
let defaultGroup = new AscOForm.CFieldGroup();
|
||
defaultGroup.setWeight(this.Format.getMaxWeight() + 1);
|
||
this.Format.addFieldGroup(defaultGroup);
|
||
defaultGroup.addUser(this.Format.getDefaultUserMaster());
|
||
|
||
delegateUserMaster = this.Format.getDefaultUserMaster();
|
||
delegateFieldGroup = defaultGroup;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
delegateUserMaster = this.Roles[delegateIndex].getUserMaster();
|
||
delegateFieldGroup = this.Roles[delegateIndex].getFieldGroup();
|
||
}
|
||
|
||
for (let index = 0, count = fields.length; index < count; ++index)
|
||
{
|
||
let fieldMaster = fields[index];
|
||
fieldMaster.removeUser(userMaster);
|
||
fieldMaster.addUser(delegateUserMaster);
|
||
}
|
||
|
||
delegateFieldGroup.addUser(delegateUserMaster);
|
||
this.Format.addFieldGroup(delegateFieldGroup);
|
||
}
|
||
|
||
this.NeedRedraw = true;
|
||
this.endAction();
|
||
return true;
|
||
};
|
||
OForm.prototype.editRole = function(name, roleSettings)
|
||
{
|
||
let role = this.getRole(name);
|
||
if (!role)
|
||
return false;
|
||
|
||
let newName = roleSettings.getName();
|
||
if (undefined !== newName
|
||
&& null !== newName
|
||
&& name !== newName
|
||
&& this.haveRole(newName))
|
||
return false;
|
||
|
||
if (!this.startAction(AscDFH.historyitem_OForm_EditRole))
|
||
return false;
|
||
|
||
let userMaster = role.getUserMaster();
|
||
if (undefined !== roleSettings.getName())
|
||
userMaster.setRole(roleSettings.getName());
|
||
|
||
let color = roleSettings.getColor();
|
||
if (null === color)
|
||
userMaster.setColor(color);
|
||
else if (undefined !== color)
|
||
userMaster.setColor(color.r, color.g, color.b);
|
||
|
||
this.endAction();
|
||
return true;
|
||
};
|
||
OForm.prototype.moveUpRole = function(name)
|
||
{
|
||
let role = this.getRole(name);
|
||
if (!role)
|
||
return false;
|
||
|
||
let weight = role.getWeight();
|
||
let sameWeightRoles = this.getRolesByWeight(weight);
|
||
|
||
if (weight === this.Format.getMinWeight() && sameWeightRoles.length <= 1)
|
||
return false;
|
||
|
||
if (!this.startAction(AscDFH.historydescription_OForm_ChangeRoleOrder))
|
||
return false;
|
||
|
||
if (sameWeightRoles.length > 1)
|
||
{
|
||
for (let index = 0, count = this.Roles.length; index < count; ++index)
|
||
{
|
||
let curRole = this.Roles[index];
|
||
let curWeight = curRole.getWeight();
|
||
if (role !== curRole && curWeight >= weight)
|
||
{
|
||
curRole.setWeight(curWeight + 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
let prevWeight = -1;
|
||
for (let index = 0, count = this.Roles.length; index < count; ++index)
|
||
{
|
||
let curRole = this.Roles[index];
|
||
let curWeight = curRole.getWeight();
|
||
if (curWeight < weight)
|
||
{
|
||
if (-1 === prevWeight || prevWeight < curWeight)
|
||
prevWeight = curWeight;
|
||
}
|
||
}
|
||
|
||
if (-1 !== prevWeight)
|
||
{
|
||
let prevRoles = this.getRolesByWeight(prevWeight);
|
||
|
||
role.setWeight(prevWeight);
|
||
for (let index = 0, count = prevRoles.length; index < count; ++index)
|
||
{
|
||
prevRoles[index].setWeight(weight);
|
||
}
|
||
}
|
||
|
||
this.endAction();
|
||
return true;
|
||
};
|
||
OForm.prototype.moveDownRole = function(name)
|
||
{
|
||
let role = this.getRole(name);
|
||
if (!role)
|
||
return false;
|
||
|
||
let weight = role.getWeight();
|
||
let sameWeightRoles = this.getRolesByWeight(weight);
|
||
|
||
if (weight === this.Format.getMaxWeight() && sameWeightRoles.length <= 1)
|
||
return false;
|
||
|
||
if (!this.startAction(AscDFH.historydescription_OForm_ChangeRoleOrder))
|
||
return false;
|
||
|
||
if (sameWeightRoles.length > 1)
|
||
{
|
||
weight++;
|
||
if (this.getRolesByWeight(weight + 1).length)
|
||
{
|
||
for (let index = 0, count = this.Roles.length; index < count; ++index)
|
||
{
|
||
let curRole = this.Roles[index];
|
||
let curWeight = curRole.getWeight();
|
||
if (curWeight > weight)
|
||
{
|
||
curRole.setWeight(curWeight + 1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
let nextWeight = -1;
|
||
for (let index = 0, count = this.Roles.length; index < count; ++index)
|
||
{
|
||
let curRole = this.Roles[index];
|
||
let curWeight = curRole.getWeight();
|
||
if (curWeight > weight)
|
||
{
|
||
if (-1 === nextWeight || nextWeight > curWeight)
|
||
nextWeight = curWeight;
|
||
}
|
||
}
|
||
|
||
if (-1 !== nextWeight)
|
||
{
|
||
let nextRoles = this.getRolesByWeight(nextWeight);
|
||
|
||
role.setWeight(nextWeight);
|
||
for (let index = 0, count = nextRoles.length; index < count; ++index)
|
||
{
|
||
nextRoles[index].setWeight(weight);
|
||
}
|
||
}
|
||
else if (weight !== role.getWeight())
|
||
{
|
||
role.setWeight(weight);
|
||
}
|
||
|
||
this.endAction();
|
||
return true;
|
||
};
|
||
OForm.prototype.getRole = function(name)
|
||
{
|
||
let roleIndex = this.getRoleIndex(name);
|
||
if (-1 === roleIndex)
|
||
return null;
|
||
|
||
return this.Roles[roleIndex];
|
||
};
|
||
OForm.prototype.getRoleIndex = function(name)
|
||
{
|
||
this.updateRoles();
|
||
|
||
for (let index = 0, count = this.Roles.length; index < count; ++index)
|
||
{
|
||
if (name === this.Roles[index].getRole())
|
||
return index;
|
||
}
|
||
|
||
return -1;
|
||
};
|
||
OForm.prototype.getRolesByWeight = function(weight)
|
||
{
|
||
this.updateRoles();
|
||
|
||
let roles = [];
|
||
for (let index = 0, count = this.Roles.length; index < count; ++index)
|
||
{
|
||
if (this.Roles[index].getWeight() === weight)
|
||
roles.push(this.Roles[index]);
|
||
}
|
||
|
||
return roles;
|
||
};
|
||
OForm.prototype.haveRole = function(name)
|
||
{
|
||
return !!(this.getRole(name));
|
||
};
|
||
OForm.prototype.getRoleSettings = function(name)
|
||
{
|
||
let role = this.getRole(name);
|
||
if (!role)
|
||
return null;
|
||
|
||
return role.getSettings();
|
||
};
|
||
OForm.prototype.getDefaultRole = function()
|
||
{
|
||
this.updateRoles();
|
||
|
||
let defaultUser = this.Format.getDefaultUserMaster();
|
||
for (let index = 0, count = this.Roles.length; index < count; ++index)
|
||
{
|
||
if (defaultUser === this.Roles[index].getUserMaster())
|
||
return this.Roles[index];
|
||
}
|
||
|
||
return null;
|
||
};
|
||
OForm.prototype.onChangeRoles = function()
|
||
{
|
||
this.NeedUpdateRoles = true;
|
||
};
|
||
OForm.prototype.onChangeFieldGroupFilled = function(fieldGroup)
|
||
{
|
||
if (!this.Document)
|
||
return;
|
||
|
||
for (let i = 0; i < this.Roles.length; ++i)
|
||
{
|
||
let role = this.Roles[i];
|
||
if (fieldGroup === role.getFieldGroup())
|
||
{
|
||
this.Document.sendEvent("asc_onOFormRoleFilled", role.getRole(), fieldGroup.isFilled());
|
||
return;
|
||
}
|
||
}
|
||
};
|
||
OForm.prototype.onChangeRoleColor = function()
|
||
{
|
||
this.NeedRedraw = true;
|
||
};
|
||
OForm.prototype.checkRedraw = function()
|
||
{
|
||
if (!this.NeedRedraw)
|
||
return;
|
||
|
||
this.NeedRedraw = false;
|
||
this.Document.Redraw();
|
||
};
|
||
OForm.prototype.updateRoles = function()
|
||
{
|
||
if (!this.NeedUpdateRoles)
|
||
return;
|
||
|
||
this.NeedUpdateRoles = false;
|
||
|
||
this.Roles = [];
|
||
for (let fgIndex = 0, fgCount = this.Format.getFieldGroupsCount(); fgIndex < fgCount; ++fgIndex)
|
||
{
|
||
let fieldGroup = this.Format.getFieldGroup(fgIndex);
|
||
let user = fieldGroup.getFirstUser();
|
||
if (!user)
|
||
{
|
||
// TODO: Разобраться с такими группами
|
||
}
|
||
|
||
let haveRole = false;
|
||
for (let roleIndex = 0, roleCount = this.Roles.length; roleIndex < roleCount; ++roleIndex)
|
||
{
|
||
if (this.Roles[roleIndex].getUserMaster() === user)
|
||
{
|
||
haveRole = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (haveRole)
|
||
{
|
||
// TODO: Разобраться с такими ситуациями
|
||
}
|
||
|
||
let weight = fieldGroup.getWeight();
|
||
let newRoleIndex = this.Roles.length;
|
||
for (let roleIndex = 0, roleCount = this.Roles.length; roleIndex < roleCount; ++roleIndex)
|
||
{
|
||
let curWeight = this.Roles[roleIndex].getWeight();
|
||
if (weight < curWeight || (weight === curWeight && user.compare(this.Roles[roleIndex].getUserMaster()) < 0))
|
||
{
|
||
newRoleIndex = roleIndex;
|
||
break;
|
||
}
|
||
}
|
||
|
||
let newRole = new AscOForm.CRole(fieldGroup, user);
|
||
if (newRoleIndex === this.Roles.length)
|
||
this.Roles.push(newRole);
|
||
else
|
||
this.Roles.splice(newRoleIndex, 0, newRole);
|
||
}
|
||
|
||
this.onUpdateRoles();
|
||
};
|
||
OForm.prototype.correctFieldGroups = function()
|
||
{
|
||
// Проверяем есть ли хоть одна группа с заданной ролью (где указан userMaster)
|
||
for (let fgIndex = 0, fgCount = this.Format.getFieldGroupsCount(); fgIndex < fgCount; ++fgIndex)
|
||
{
|
||
let fieldGroup = this.Format.getFieldGroup(fgIndex);
|
||
let user = fieldGroup.getFirstUser();
|
||
if (!user)
|
||
continue;
|
||
|
||
return;
|
||
}
|
||
|
||
// Нельзя, чтобы групп не было вообще
|
||
let defaultGroup = new AscOForm.CFieldGroup();
|
||
defaultGroup.setWeight(this.Format.getMaxWeight() + 1);
|
||
this.Format.addFieldGroup(defaultGroup);
|
||
defaultGroup.addUser(this.Format.getDefaultUserMaster());
|
||
};
|
||
OForm.prototype.onEndLoad = function()
|
||
{
|
||
this.NeedUpdateRoles = true;
|
||
this.Format.correctFieldMasters(this.getDocument());
|
||
this.correctFieldGroups();
|
||
this.updateRoles();
|
||
};
|
||
OForm.prototype.onUpdateRoles = function()
|
||
{
|
||
let logicDocument = this.getDocument();
|
||
let api;
|
||
if (!logicDocument || !(api = logicDocument.GetApi()))
|
||
return;
|
||
|
||
api.sendEvent("asc_onUpdateOFormRoles", this.Roles);
|
||
};
|
||
OForm.prototype.onEndAction = function()
|
||
{
|
||
this.Format.removeUnusedFieldMasters();
|
||
this.Format.correctFieldMasters(this.getDocument());
|
||
this.correctFieldGroups();
|
||
this.updateRoles();
|
||
this.checkRedraw();
|
||
};
|
||
OForm.prototype.onUndoRedo = function()
|
||
{
|
||
this.updateRoles();
|
||
this.checkRedraw();
|
||
};
|
||
OForm.prototype.onEndLoadChanges = function()
|
||
{
|
||
this.onUndoRedo();
|
||
};
|
||
OForm.prototype.canFillRole = function(roleName)
|
||
{
|
||
let role = this.getRole(roleName);
|
||
if (!role || role.isFilled())
|
||
return false;
|
||
|
||
let weight = role.getWeight();
|
||
for (let i = 0; i < this.Roles.length; ++i)
|
||
{
|
||
if (this.Roles[i] === role || this.Roles[i].isFilled())
|
||
continue;
|
||
|
||
if (this.Roles[i].getWeight() < weight)
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
OForm.prototype.setRoleFilled = function(roleName, isFilled)
|
||
{
|
||
let role = this.getRole(roleName);
|
||
if (!role)
|
||
return;
|
||
|
||
role.setFilled(isFilled);
|
||
};
|
||
OForm.prototype.setAllRolesNotFilled = function()
|
||
{
|
||
for (let roleIndex = 0, roleCount = this.Roles.length; roleIndex < roleCount; ++roleIndex)
|
||
{
|
||
this.Roles[roleIndex].setFilled(false);
|
||
}
|
||
};
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// Private area
|
||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
OForm.prototype.startAction = function(description)
|
||
{
|
||
let logicDocument = this.getDocument();
|
||
if (!logicDocument)
|
||
return false;
|
||
|
||
if (logicDocument.IsSelectionLocked(AscCommon.changestype_Document_Settings, null, false, false, null))
|
||
return false;
|
||
|
||
logicDocument.StartAction(description);
|
||
return true;
|
||
};
|
||
OForm.prototype.endAction = function()
|
||
{
|
||
let logicDocument = this.getDocument();
|
||
if (!logicDocument)
|
||
return;
|
||
|
||
this.onEndAction();
|
||
|
||
logicDocument.UpdateInterface();
|
||
logicDocument.FinalizeAction();
|
||
};
|
||
//--------------------------------------------------------export----------------------------------------------------
|
||
AscOForm.OForm = OForm;
|
||
//---------------------------------------------interface export-----------------------------------------------------
|
||
OForm.prototype['asc_getAllRoles'] = OForm.prototype.getAllRoles;
|
||
OForm.prototype['asc_addRole'] = OForm.prototype.addRole;
|
||
OForm.prototype['asc_removeRole'] = OForm.prototype.removeRole;
|
||
OForm.prototype['asc_editRole'] = OForm.prototype.editRole;
|
||
OForm.prototype['asc_moveUpRole'] = OForm.prototype.moveUpRole;
|
||
OForm.prototype['asc_moveDownRole'] = OForm.prototype.moveDownRole;
|
||
OForm.prototype['asc_haveRole'] = OForm.prototype.haveRole;
|
||
OForm.prototype['asc_getRole'] = OForm.prototype.getRoleSettings;
|
||
OForm.prototype['asc_canFillRole'] = OForm.prototype.canFillRole;
|
||
|
||
})(window);
|