Добрый день.

При нажатии на кнопку у меня должна меняться иконка кнопки. Я заместила  CTI panel, добавила картинку "MyButtonIcon" такого же размера как и остальные иконки. Как передавать новую иконку в "ImageConfig" каждый раз когда я совершаю нажатие.

Нравится

1 комментарий

В схеме CommunicationPanel для иконок почты, виз и прочего заведено по несколько изображений с однотипными названиями: VisaMenuIcon, VisaMenuPressedIcon, VisaMenuCounterIcon и VisaMenuPressedCounterIcon. И в функции выбирается то или иное:

/**
 * Creates menu icon image for current menu item state.
 * @private
 * @param {String} itemTag Menu item tag.
 * @return {Object} Menu item icon config.
 */
getItemImageConfig: function(itemTag) {
	var resourceName = "";
	var menuItemIconNameTemplate = this.get("MenuItemIconNameTemplate");
	if (!this.getIsFeatureEnabled("OldUI")) {
		resourceName = this.Ext.String.format(menuItemIconNameTemplate, itemTag, "", "");
		return this.get("Resources.Images." + resourceName + "SVG");
	}
	var isItemPressed = (this.get("SelectedMenuItem") === itemTag);
	var isItemCounter = this.get(itemTag + "Counter");
	var pressedSuffix = isItemPressed ? "Pressed" : Ext.emptyString;
	var counterSuffix = isItemCounter ? "Counter" : Ext.emptyString;
	resourceName = Ext.String.format(menuItemIconNameTemplate, itemTag, pressedSuffix, counterSuffix);
	return this.get("Resources.Images." + resourceName);
},

 

Показать все комментарии

Добрый день! 

Возник вопрос как сделать Деталь, где помимо строковых полей, будет содержаться поле с изображениями(маленькие иконки, по нажатию на которую из них, будет открываться отдельная страница с оригинальным размером изображений).

Вопрос:

Как этого можно достичь? Возможно как то переопределить базовую деталь с полями? Или возможно вместо "списка с иконками отображений" (в случае не возможности или трудоемкости достижения поставленной задачи) добавить поле с ссылкой на "хранилище"(вкладку) с изображениями(возможностью редактирования, т.е. добавления/удаления)?

  

Нравится

2 комментария

Такое сделано в дополнении Image preview for bpm'online.

Зверев Александр,

Большое спасибо!

Показать все комментарии

Хочу добавить картинку в ImageList.

ImageL = Services.GetSingleItemByUSI('il_TDpics');
var FileName = System.CreateObject('TSObjectLibrary.Value');
if (!(System.OpenDialog(FileName, '*.jpg|*.jpg', EmptyStr, EmptyStr, EmptyStr))) {
return;
}
var ImageItem = ImageL.CreateImage();
ImageItem.ImageType = 2;
ImageItem.LoadFromFile(FileName);

Выдает ошибку. См. присоединенный файл. Просьба подсказать решение.
Вручную рисунки добавляются. Такой код работает

var part1 = 'C:\\Program Files\\Terrasoft\\Res\\';
var part2 = dlData.Dataset.DataFields('DeliveryPointID').Value;
var Final_5 = part1 + part2 + '5.jpg';
if (fso.FileExists(Final_5)) {
var ImageList = Services.GetNewItemByUSI('il_CommunicationActionSmartTag');
var ImageItem = ImageList.CreateImage();
ImageItem.LoadFromFile(Final_5);

Нравится

5 комментариев

Если картинка лежит где-то в файловой системе — нужно получить строку с её адресом. У Вас в работающем примере в функцию LoadFromFile передаётся строковая константа. А в первом — какой-то объект, возвращаемый из диалогового окна. Попробуйте в отладчике посмотреть, что передаётся в переменную FileName и в чём отличие от работающего примера.

Также см. пример отсюда, где для аналогичным образом полученного значения используется FileName.Value. Возможно, нужная Вам строка находится там.

Спасибо от ошибки избавился. Но завершить работу не получается. Вот код:

var ImageList = Services.GetNewItemByUSI('il_DPpics');
var FileName = System.CreateObject('TSObjectLibrary.Value');
if (!(System.OpenDialog(FileName, '*.jpg|*.jpg', EmptyStr, EmptyStr, EmptyStr))) {
return;
}
var ImageItem = ImageList.CreateImage();
ImageItem.ImageType = 2;
imgTDp1.ImageList = ImageList;
ImageItem.LoadFromFile(FileName.Value);
ImageList.Add(ImageItem);
imgTDp1.ImageList = ImageList;
imgTDp1.ImageName = dlData.Dataset.DataFields('DeliveryPointID').Value + '1';

Все вроде бы работает. В отладчике я виж, что число изображений в ImageList увеличилось с 3 до 4, вижу правильные размеры картинки. Потом уже из ImageList заполняю imgTDp1 и вижу картинку на форме. Но после того, как я закрываю карточку редактирования, введенная картинка исчезает из ImageList. Методов Open / Save для ImageList я не нашел. Как правильно все закрыть, чтобы результаты работы сохранились? Подробности в присоединенном файле.

Вы меняете объект в памяти, а GetNewItemByUSI берёт его сериализированное представление из базы, где оно хранится вместе с другими сервисами.

Для сохранения сервиса делается:

Services.SaveItem(ImageList, sdoaSave);

См. пример реализации в мастере разделов, в скрипте wnd_LoadWorkspaceIconScript.

Спасибо. Уже почти у цели (см. вложение). Может подскажете, как удалить ImageItem из ImageList
Пробовал, что пришло в голову: Remove(), Delete(), ImageList.Items(i) = ImageList.Items(i + 1)? но не вышло. Может быть, менять Name, это возможно?

Увидеть названия всех методов, которые есть у объектов ImageList и ImageItem, можно прямо в отладчике. Если таких методов нет — простым способом удалить не получится.

Показать все комментарии

Не нашел в документации, как пользоваться ImageControl. Мне от него и нужно немного. Как на нем поместить картинку. Событие OnClick есть, и функция к нему написана.

Нравится

1 комментарий
var ImageList = Services.GetSingleItemByUSI('il_OverlayIcons');
img1.ImageList = ImageList;
img1.ImageName = 'Warning';
Показать все комментарии

I found a few discussions about using filestreams in Terrasoft applications. The last one was at http://www.community.terrasoft.ua/forum/topic/7454. So I decided to share instruction and some scripts, that are needed to setup filestreams for tbl_Files table, as a separate blog post. The solutions is tested in few projects.
It also can be used for tbl_MailMessage and other tables, that contains column with datatype IMAGE.

Why to setup filestreams is also discussed in previous topics.

After making these changes there might be a problem to add new workspace, that contains Files detail using TS Master window or PVC, because the service tbl_Files can not be saved correctly, so some workarounds are needed, for example, You can create workspace with Terrasoft Master window without Files detail, and add this detail manually, if needed.

1. Make DATABASE backup

2. CREATE filestream files
ALTER DATABASE DATABASE_NAME ADD filegroup FileStreamGroup1 CONTAINS filestream
ALTER DATABASE DATABASE_NAME ADD FILE (NAME = FileStreamFile1, FILENAME = 'f:\database\tcr_xxx_332_lt\FileStreamData') TO FILEGROUP FileStreamGroup1;

3. Make COLUMN copy
ALTER TABLE tbl_Files ADD FileDataBackup IMAGE;
UPDATE tbl_Files SET FileDataBackup = FileData;

4. FOR ALL tbl_FileIn..  do this

DROP TRIGGER tr_tbl_FileInAccount_ID
ALTER TABLE dbo.tbl_FileInAccount DROP CONSTRAINT FFileInAccountFileID
ALTER TABLE dbo.tbl_FileInAccount ADD CONSTRAINT FFileInAccountFileID FOREIGN KEY ( FileID ) REFERENCES dbo.tbl_Files ( ID ) ON UPDATE NO ACTION ON DELETE CASCADE

DROP TRIGGER tr_tbl_FileInContact_ID
ALTER TABLE dbo.tbl_FileInContact DROP CONSTRAINT FFileInContactFileID
ALTER TABLE dbo.tbl_FileInContact ADD CONSTRAINT FFileInContactFileID FOREIGN KEY ( FileID ) REFERENCES dbo.tbl_Files ( ID ) ON UPDATE NO ACTION ON DELETE CASCADE

...

5. tbl_FileRight AND tbl_Files instead of TRIGGER

ALTER TABLE dbo.tbl_FilesRight DROP CONSTRAINT FFilesRightRecordID
ALTER TABLE dbo.tbl_FilesRight ADD CONSTRAINT FFilesRightRecordID FOREIGN KEY ( RecordID ) REFERENCES dbo.tbl_Files ( ID ) ON UPDATE NO ACTION ON DELETE CASCADE
DROP TRIGGER tr_tbl_Files_ID

6. CHANGE FileData COLUMN type TO VARBINARY(MAX):

ALTER TABLE tbl_Files DROP COLUMN FileData;
ALTER TABLE tbl_Files ADD FileData VARBINARY(MAX) filestream;


7. Move DATA TO updated COLUMN
UPDATE tbl_Files SET FileData = FileDataBackup
ALTER TABLE tbl_Files DROP COLUMN FileDataBackup

8. DROP vw_Files triggers
DROP TRIGGER tr_vw_Files_ID
DROP TRIGGER tr_vw_Files_IU

9. Recreate files VIEW
ALTER VIEW [dbo].[vw_Files]
AS
  SELECT [P].*
  FROM [dbo].[tbl_Files] AS [P] WITH(nolock)
  WHERE EXISTS (
    SELECT * FROM [dbo].[tbl_FilesRight] AS [R] WITH(nolock)
    WHERE (([R].[RecordID] = [P].[ID])
    AND EXISTS(
      SELECT * FROM [dbo].[tbl_UserAdminUnit] AS [U] WITH(nolock)
      WHERE ([R].[AdminUnitID] = [U].[AdminUnitID])
      AND ([U].[UserName] = SYSTEM_USER))))
GO

10. Make additional triggers OR modifications IN TS client side TO make correct access rights TO the files

Нравится

Поделиться

0 комментариев
Показать все комментарии

Ниже описан вариант решения для отображения необходимой иконки в зависимости от определенного условия возле записи в реестре. Релизовано на примере признака "Важность" в окне напоминаний.

1

То есть, при установке признака «Важность» будет появляться иконка возле записи в реестре.

Перед изменениями советую сделать бекап базы данных.

Для этой реализации необходимо:

1. Создать новый сервис ImageList:

1

2. Заполнить поля обращения к нему и добавить изображение:

1

3. Загрузить картинку и сохранить изменения:

1

4. Открыть окно редактирования грида (wnd_RemindingsGridArea).
5. Выделить элемент grdData. В нем выбрать созданный ImageList, установить свойство HasCustomDraw – True.

1

6. Теперь необходимо перейти на вкладку «события» и дважды щелкнуть на поле «OnGetRowDrawInfo» для создания функции. Откроется окно скрипта, необходимо вернуться обратно к окну wnd_RemindingsGridArea и сохранить изменения.

1

7. В открывшемся окне скрипта, необходимо добавить текст кода, как показано на скриншоте и сохранить изменения:

            var Dataset = dlData.Dataset;    

            var check = GetFieldValueFromDisabledField(Dataset,'Urgent');

            if (check) {
            ImageName.Value = 'Check';
            }
            else
            {
            ImageName.Value = '';
            }

1

8. Необходимо добавить поле в таблицу tbl_Reminding, как показано на скриншоте и сохранить изменения:

1

9. Далее требуется добавить выборку в sq_Reminding, как показано на скриншоте:

1

10. Добавить новое булевское поле в ds_Reminding:

1

11. Заполнить поля и сохранить изменения:

1

12. Открыть карточку wnd_RemindingEdit и добавить элемент BoolDataControl:

1

13. Заполнить свойства, как показано на скриншоте, и сохранить изменения:

1

Нравится

Поделиться

0 комментариев
Показать все комментарии

Здравствуйте, уважаемые коллеги!

Столкнулся с ситуацией: требуется вставить в ImageDataСontrol на карточке картинку из буфера обмена. Не важно, напрямую или через временный файл. Я испытал три различных способа, но все три - безуспешно:

http://community.terrasoft.ua/blogs/6286

Подскажите, пожалуйста, где я ошибся; возможно, кто-то уже решил подобную задачу. Версия 3.2.1.58

Нравится

3 комментария

Судя по Вашему блогу, данные в датасет записались. А если попробовать переприсвоить DataField для контрола картинки?

edtScreenShot.DataField = System.EmptyValue;
edtScreenShot.DataField = Dataset.DataFields('ScreenShot');

Идея интересная, только, конечно, не датафилд обратить в Null, а просто поле отключить-подключить. Вот так:

edtScreenShot.DataFieldName = '';
edtScreenShot.DataFieldName = 'ScreenShot';

Но толку никакого. Мне кажется, что картинка не отрисовывается не из-за отсутствия данных, а именно из-за того, что двоичный Stream не содержит правильного заголовка картинки. Контрол просто не знает, что от него ожидают. Сунули, мол, каких-то каракатиц, а к чему они - неизвестно.

По идее, все дело в том, как сохраняется в буфер обмена само изображение. Думаю, нужно ждать совета разработчиков ядра, которые бы объяснили происходящее с точки зрения контрола.

Показать все комментарии

Здравствуйте, уважаемые коллеги!

Столкнулся с ситуацией: требовалось вставить в ImageDataСontrol на карточке картинку из буфера обмена. К примеру, нажал пользователь PrintScreen, щёлкнул на карточке кнопку, картинка и вставилась. Казалось бы, чего проще... А не тут-то было!

Самый очевидный способ не сработал. Пишет в ответ: "Разрушительный сбой":

var Stream = System.CopyClipboardToStream();
edtScreenShot.DataField.SetValAsBlob(Stream);

Stream этот какой-то странный, ни свойств, ни методов, просто кусок двоичного кода. Я этот код увидел, когда сделал так:

System.StreamToMime(Stream);

На восемь мегабайт каракатиц. Но где наша не пропадала! Есть ведь путь посложнее, взять ImageList, и через Image прочитать картинку из Stream, сохранить в файл, а потом этот файл автоматически открыть методом поля типа Blob.

Написал так:

var Stream = System.CopyClipboardToStream();
var ImageList = Services.CreateItem('ImageList');  
var Image = ImageList.CreateImage();
Image.ImageType = 1;
Image.LoadFromStream(Stream);
Image.SaveToFile('c:\Temp.bmp');

Система всё это лихо выполнила, ни разу не кашлянула. Но файл получился нулевой длины. Так что вставлять в Blob после этой операции уже было нечего...

Наконец (верно от отчаяния) я решил подсунуть вместо этого таинственного Stream известный и понятный ADODB.Stream. Только как бы в него засунуть то, что в буфере обмена? Я написал такое:

var Stream = System.CopyClipboardToStream();
var Mime = System.StreamToMime(Stream);
var ADODBStream = new ActiveXObject('ADODB.Stream');
ADODBStream.Mode = 3;//Кстати, кто знает, что означают эти числа?
ADODBStream.Type = 1;//Расскажите, а то я просто скопировал из другого примера...
ADODBStream.Open();
System.MimeToStream(Mime, ADODBStream);
ADODBStream.SaveToFile('c:\Temp1.bmp');

Способ сработал, все весемь мегабайт каракатиц выгрузились в Temp1.bmp, только файл был не в формате BMP, а именно в виде строки Mime. Естественно, картинку прочитать невозможно.

Итак, у меня ничего не получилось. Но, может быть, я просто пошёл неправильным путём? Кто подскажет, вдруг эта задача уже решалась? Кто что знает о сохранении картинок из буфера обмена, либо об их вставке в Blob-поле? Использовал версию 3.2.1.58.

Нравится

Поделиться

2 комментария

"Будак Анатолий Васильевич" написал:Пишет в ответ: "Разрушительный сбой":

Анатолий, а вы уверены что контрол подключен к DataSet, в корректном состоянии?

Спасибо, Саша, что обратили моё внимание на этот момент! Действительно, здесь стоит посмотреть внимательно. Вот, что я выяснил. Если ставить в контроле по умолчанию ImageType = itBMP, то сообщение о разрушительном сбое пропадает. Его нет и при использовании itJPG (хотя скриншот явно не в виде jpg попадает в Stream). Сообщение о разрушительном сбое бывает только при itPNG. Однако вставки картинки всё равно не происходит, хотя сообщение об ошибке я убрал, принудительно устанавливая ему itBMP перед вставкой. Так что мы на правильном пути!

Датасет, по-видимому, подключен корректно. Рядом с кнопкой "Вставить из буфера" размещена кнопка "Вставить из файла". Там стоит такая конструкция для того же поля того же датасета:

edtScreenShot.DataField.LoadFromFile(FilePath);

Работает безупречно, картинка загружается.

Но ни в чём нельзя быть уверенным до конца. С моим-то склерозом :) Для эксперимента попробовал и такое обращение:

var Dataset = dlData.Dataset;
Dataset.DataFields('ScreenShot').LoadFromFile(FilePath);

Тоже отлично работает.

Ну, и чем чёрт не шутит:

var Dataset = dlData.Dataset;
var Stream = System.CopyClipboardToStream();
Dataset.DataFields('ScreenShot').SetValAsBlob(Stream);

Увы, хоть сообщения об ошибке нет, картинка не видна...

Однако самое поразительное - вот что! Хоть картинки в контроле и не видно, если сделать

Dataset.DataFields('ScreenShot').SaveToFile('c:\Test3.bmp');

то по указанному пути появится восьмимегабайтный файл, со структурой, похожей на bmp (куча каракатиц стройными рядами), но без характерного bmp-заголовка. Который, увы, ни одна графическая программа не считает bmp-файлом. Удивительно ещё и то, что запись сохраняется, и в blob двоичные данные попадают, это видно как в таблице, так и при открытии карточки (ощутимо замедленном из-за такого объёма картинки). Но саму картинку по-прежнему не видно.

Мне кажется, что добавив в Stream правильный заголовок bmp проблема бы решилась. Он явно идёт без него, хотя структура bmp-шная. Но как бы его добавить?

Показать все комментарии

Добрый день, участники комьюнити.

Исходные данные:
Есть тулбар на форме редактирования. Есть ActionMenu привязанный к тулбару. Есть ActionMenuItem привязанный к ActionMenu. Есть ImageList с картинками и привязанный к ActionMenu. В общем есть всё что нужно для нормального отображения тулбара.

В скрипте происходит смена картинок у ActionMenuItem (amiTemp.ImageName = 'Pic1' или amiTemp.ImageName = 'Pic2' в зависимости от условий).

Проблема в том, что смена картинок не происходит пока не наведешь мышку на кнопку.
Что делать ума не приложу.
Что пробовал:
-BeginUpdate/EndUpdate/Prepare у Toolbar, ActionMenu, ActionMenuItem.
Ничего не помогло.

Вся надежда на вас.
Направьте меня на путь истинный :smile:.

Нравится

8 комментариев

Здравствуйте.
Сейчас в COM для ActionMenu не вынесена функция Invalidate.
Но Вы можете инициировать ее вызов "передернув" свойство IsVisible у ActionMenuItem после смены ImageName:

ActionMenuItem.IsVisible = false;
ActionMenuItem.IsVisible = true;

Евгений, попробовал изменять ImageName в зависимости от значения типа контрагента при обработке события dlDataOnDatasetDataChange. Всё получилось. Пример скрипта:

	if (FieldName == 'AccountTypeID') {
		if (DataField.Value == '{3EAC7195-607B-4DAC-A832-8954E3201031}') {
			amiTest.ImageName = 'IncidentID';
		} else {
			amiTest.ImageName = 'TaskID';
		}
	}

Возможно, Вам тоже стоит попробовать обработку какого-либо другого события.

Отлично!
Спасибо, Александр.
Всё заработало.

Олег, возможно вы делаете обработку на OnPrepare, а возможно дело и в бинарниках. У меня 3.3.2.114. Я делаю обработку когда карточка уже открыта, с определенным интервалом.
Забегая чуть вперед скажу - это отслеживание состояния свободных линий IP телефона.

Проверял на 3.3.2.104.

"Евгений Либин" написал:Олег, возможно вы делаете обработку на OnPrepare

нет

"Лабьяк Олег Игоревич" написал:при обработке события dlDataOnDatasetDataChange

Больше нигде изменений не вносил. Карточка тоже уже открыта, при изменении типа меняется картинка в меню.

Видимо, у Вас не совсем такая реализация.

Вот что сейчас получилось

		if (Connector.Attributes('LiTPhone').GetLineStatus(Lines[i].Tag))
			Lines[i].ImageName = 'ActiveLine'
		else
			Lines[i].ImageName = 'InactiveLine';
 
//ранее  этого куска не было
		Lines[i].BeginUpdate();
		Lines[i].IsVisible  = false
		Lines[i].IsVisible  = true;
		Lines[i].EndUpdate()
 

Евгений, я понимаю, что сам код такой же. Вопрос в том, когда (во время какого события) он выполняется. Возможно, в Вашем случае обойтись без нижнего блока не получится.

Да, скорее всего вы правы.
Самое главное что решение найдено :wink:

Показать все комментарии