Научноизследователски развоен проект
Transcription
Научноизследователски развоен проект
Research and Development Project: "A new approach to developing software systems for business management and control intended for mass use: concept, methodology, software tools, experiments and analysis" Technology for Developing Complex Software Systems ArMSBuilder FOI Consult Ltd, Sandanski 2015 2 Table of Contents Introduction ............................................................................................................... 5 1 Working with Data. Muli-Domain Information Model ........................................ 7 1.1 Non-relational database ArM32 ......................................................................... 7 1.1.1 1.1.2 1.1.3 1.2 1.3 2 Main functions for processing data in ArM32 DBMS ....................................... 15 Implementation of some technologies for data storage on the Internet ....... 17 Improving the Ergonomics of Software Screen Forms - FOI Smart Monitor Mechanism....................................................................................................... 19 2.1 2.2 3 Loading the best possible monitor resolution ................................................. 21 Automatic conversion of visual components - FOI Smart Monitor ................. 22 Options for Displaying Information .................................................................. 24 3.1 Mechanisms for generating reports ................................................................. 24 3.1.1 3.1.2 3.1.3 3.1.4 3.2 Text editor ..................................................................................... 41 Building a gallery of images and documents ................................. 46 Visualizing images .......................................................................... 49 Visualizing charts and graphs ........................................................ 53 Integrated Software System. General Functions of Program Modules in Integrated Software Systems ........................................................................... 56 4.1 4.2 4.3 4.4 4.5 5 Generating reports through the use of document templates ...... 24 Generating a package of documents............................................. 26 Generating reports by creating a RTF document .......................... 28 Generating reports by creating graphics and images ................... 38 License-free options for displaying information .............................................. 40 3.2.1 3.2.2 3.2.3 3.2.4 4 Multi-dimensional numbered information spaces.......................... 7 Multi-domain information model ................................................... 8 Multi-dimensional access method ArM32 .................................... 13 Implementation of functions for backup storage and data recovery .............. 57 Implementation of functions for copying, moving, and deleting operating data .................................................................................................. 59 Implementation of functions for specifying the system settings .................... 62 Implementation of functions for updating the system modules ..................... 63 Implementation of functions for working with nomenclatures ...................... 65 Tools Assisting the Operation and Settings of Integrated Software Systems .... 67 5.1 5.2 Tool for creating and editing ArM archives containing large objects .............. 67 Tool for maintenance of ArM archives............................................................. 74 3 5.3 5.4 5.5 5.6 5.7 Tool for emailing ............................................................................................... 76 Tool for file compression .................................................................................. 77 Tool for file decompression .............................................................................. 78 Tools for creating self-extracting archives ....................................................... 80 Installer ............................................................................................................. 82 6 ArMSBuilder Ver. 1.03 – Developer’s Guide ..................................................... 84 7 ArMSBuilder Vver. 1.03 – Procedures, Functions, and Methods .................... 108 4 Introduction "Technology for Developing Complex Software Systems" (the Technology) is a programming environment for developing complex software systems. The technology acronym is ArMSBuilder. The technology is based on the rules of the "Concept for a New Approach to Developing Software Systems for Business Management designed for mass use" (the Concept). It builds a technological development environment for the practical implementation of the Concept. The main elements of this programming environment are as follows: using the ArM32 non-relational database as a basis for operating with data in the process of modeling complex and dynamically time-varying processes, including modeling of business activities with a pyramidal structure of interaction; design of a new type of graphical user interface (GUI) in building integrated software systems for company management by putting a tight limit on the number of various forms displaying simultaneously, maximum optimization of the functionality and hierarchical structuring of the user’s interaction with the systems; greater use of artistic methods in shaping the design of the GUI and options for automated ergonomic customization during continuous operation with the systems; single programming and user interface for all modules in an integrated software system. Besides being a technological solution to the theoretical rules of the Concept, the creation of the Technology enables the achieving of several immediate goals, as follows: 1. A method for building integrated software systems with a better interface in terms of ergonomics for users; with better functionality facilitating and assisting the work with them; not demanding special hardware and utilizing the capabilities of the available computer equipment to the maximum. 2. A mechanism is demonstrated for creating license-free software products (business systems for management and control in particular) operating on the principle of “Install and run” which do not require the presence of other software (besides an operating system) in order to operate fully. 3. New rules and tools for building complex software systems are applied, covering all stages of development of the software product: design, programming and user interface, maintenance and upgrading. 4. It presents an option for developing reasonably-priced integrated software system of competitive quality for usage in small and medium-sized enterprises with a small staff and for a short amount of time. ArMSBuilder was developed by FOI Consult Ltd. The latest version of ArMSBuilder – ver. 1.03 was used as a basis for developing the company’s software products designed for the information support of business processes and building integrated business management systems [www.foi9.eu]. 5 ArMSBuilder ver. 1.03 is written using CodeGear Delphi 2007 (CodeGear RAD Studio 2007 Version 11.0) of Embarcadero Technologies. The Technology is not a programming textbook. Its understanding and application requires basic knowledge of object-oriented programming (in this case of Delphi Pascal, but not necessarily). An added advantage is also knowledge of the basic mechanisms of work in economic structures and participation in the development and/or implementation of software systems for automation of business processes. Throughout the text the description of the programming methods and tools is made based on the state of the Technology attained in ArMSBuilder ver. 1.03. 6 1 Working with Data. Muli-Domain Information Model In the early years of information technology, data was stored in files that were created and manipulated by commands of the operating system and/or by specific applications. Later, data began to be organized in databases and processed by systems for database management. A key element of any software system processing data is the part of the software providing data storage and ensuring the smooth operation with data in the course of time. These activities are performed by database management systems (DBMS). DBMS is usually a separate software program other than the application software, but interacting with it following a strictly described model for storing and accessing data and mechanisms for operating with it. Many models exist for describing the methods of storing and using data. [Review 11]. Depending on which model of data organization and operation the respective database maintains, the type of the database is determined. The most frequently used type of DBMS in practice is the relational type. In recent years, in connection with the emergence of new application areas and the increased requirements for application software systems, databases from the non-relational type are becoming increasingly popular. They operate under different models of data organization [Review 1]. The ArMSBuilder technology for developing integrated software systems is based on the use of a non-relational type of database. The model which describes the work of the database is called "a multi-domain information model" and the implemented method of accessing the data supporting the lowest level for interacting with the data is called "a multi-domain access method." Due to the fundamental and innovative nature of these basic concepts, we will examine them in greater detail. 1.1 Non-relational database ArM32 1.1.1 Multi-dimensional numbered information spaces The implemented mechanisms for operating with data in a multi-domain information model are based on numbering as the primary approach to express connections. The main idea consists in replacing the values of the objects’ attributes with integer numbers corresponding to the number of the respective attribute in the ordered sets of attribute values. Thus, each object can be described by a vector of integer values and can be used as a coordinate address in a multidimensional information space. 1 [Review 1] – Review №1 of the project "A new approach for developing integrated software systems for business management and control for mass use: concept, methodology, programming tools, experiments and analysis” 7 In other words, the process of replacing names with numbers allows the use of mathematical functions and address vectors to access the information. This type of memory organization is called "Multi-dimensional numbered information spaces" (Fig. 1). Its advantages are demonstrated in a number of practical applications over a period of more than twenty-five years [Markov, 1984], [Markov, 2004], [Markov, 2005]. 1.1.2 Multi-domain information model Being independent from the limitations of dimensionality is very important for the development of new intelligent systems aimed at processing high-dimensional data. To achieve this, it is necessary that the information models and the corresponding access method overcome the boundary of the limitations of dimensionality and obtain the possibility to work with information spaces of a virtually unlimited number of dimensions. The first step is to construct context-independent multi-dimensional models and, based on them, to develop contextdependent high-level applications. Studying the current state of the problem shows that there are practically no available context-independent multi-dimensional information models and access methods. One attempt in this direction is the creation of the Multi-Domain Information Model MDIM [Markov, 2004] and the corresponding Multi-domain Access Method. Their capabilities to operate with context-independent multidimensional data structures are described below. 1.1.2.1 Key structures of MDIM The main structures of an MDIM are the basic information elements, information spaces, indexes, meta-indexes, and aggregates. The definitions for each of these structures are given below: Basic information element The Basic Information Element (BIE) of the MDIM is an arbitrarily long string of machine code (bytes). Let E1 be a set of basic information elements: E1 = {ei | ei – basic information element, i=1,…, m1} Let 1 be a function that defines a biunique correspondence between the elements of the set E1 and the elements of the set C1 of natural numbers: C1 = {ci | ci N, i = 1,…, m1}, i.e. 1 : E1 C1 The elements of C1 are said to be co-ordinates of the elements of E1. Information spaces The triple S1 = (E1, 1, C1) is said to be a numbered information space of range 1. Due to the specificity of information spaces of range 1, for the sake of convenience we will also refer to them as one-dimensional or one-domain information spaces. Each basic information element has length – a characteristic that matters in the practical implementation. A certain element is called “empty” if it has zero length (Fig. 2). 8 The triple Sn = (En, n, Cn), n ≥ 2, is said to be a numbered information space of range n iff En is a set whose elements are numbered information spaces of range n-1 and n is a function which defines a biunique correspondence between the elements of the set En and the elements of the set Cn of positive integer numbers (coordinates of range n): Cn = {ck | ck N, k = 1,…,mn}, i.e. n : En Cn Every basic information element "e" is considered as an information space S0 of range 0. It is clear that the information space S0 = (E0, 0, C0) is constructed in the same manner as all the rest: machine code (bytes) bi,i=1,…,m0 are considered as elements of E0; the position pi,iN of bi in the string is considered as co-ordinate of bi, i.e. C0 = {pl | pl N, l = 1,…,m0}; the function 0 is defined by the physical order of bi in e and then we have: 0 : E0 C0 Thus, the string S0 may be considered as a set of sub-elements (sub-strings). The number and length of sub-elements may vary. This option is very helpful but it heavily depends on the specific realizations and is not regarded as a standard characteristic of MDIM. а) one-dimensional information space – S1 б) two-dimensional information space – S2 в) four-dimensional information space – S4 9 Fig. 1 Graphical representation of the structure of information spaces of range 1, 2, and 4 The information space Sn which contains all information spaces of a given application is called information base of range n. Usually, the term information base without specifying the range is used as a generalized concept to denote all accessible information spaces. Fig 2. Graphical representation of a three-dimensional information space with information elements with data Indexes and Meta-Indexes The sequence A = (cn, cn-1, …, c1), where ciCi, i=1, …, n, is called space address of range n. Every space address of range m,m≤n, may be expanded to a space address of range n by adding nm zero codes at the front. Each sequence of space addresses A1, A2, …, Ak, where k is an arbitrary natural number, is said to be a space index. A special type of space index is the projection which represents the given space index in an analytical manner. There are two types of projections: hierarchical projection - where the upper part of the co-ordinates is fixed and the lower part varies among all possible values of the co-ordinates where non-empty elements exist; arbitrary projection – in this case it is possible to fix the coordinates in arbitrary positions as the remaining co-ordinates vary among all possible values of the co-ordinates where non-empty elements exist. Every index may be regarded also as a basic information element and may be stored in the position of any information space. In this case, it will be assigned a multi-dimensional space address which may point to other indexes and thus a hierarchy of indexes can be built. Each index pointing only to indexes is called a meta-index. 10 The method of representing the interconnections among the elements of information spaces using (hierarchies of) meta-indexes is called poly-indexation. Aggregates G={Si|i=1,…,m} be a set of numbered information spaces. Let τ={νij:Si→ Sj|i=const,j=1..m} be a set of mappings of one “main” numbered information space Si, into the others Sj and, in particular, into itself. The couple: D=(G, τ) is said to be an “aggregate”. It is clear that we can build m aggregates using the set G, as each information space Sj may be chosen as the main information space. 1.1.2.2 Operations in the MDIM After having defined the information structures, we must outline the operations which are admissible in the model. It is clear that the operations are closely tied to the defined structures. In MDIM an assumption is made that all information elements of all information spaces exist. If for any i Si:Еi=ø and Ci=ø then it is called empty. Usually, the majority of information elements and spaces are empty. This is very important for the practical applications. Operations with basic information elements (BIE) Because of the rule that all above-described structures exist, only two operations are needed: (1) updating and (2) getting the value of BIE. For both operations two service operations are required: (1) getting the length of a BIE and (2) positioning in a BIE. The updating, or simply writing the element, has several modifications with obvious meaning: writing the BIE as a whole, adding/inserting in a BIE, removing/replacing of part of a BIE and deleting a BIE. There is only one operation for getting the value of a BIE, i.e. reading (Read) a portion of a BIE starting from a given position. We may get the whole BIE if the starting position coincides with the beginning of the BIE and the length of the portion is equal to the length of the BIE. Operations with spaces In the case of a single space we can conduct only one operation - clearing (deleting) the space, i.e. replacing all BIE from the space with empty BIE - . After completing this operation, all BIE from the space will have zero length. In fact, the space gets cleared by replacing it with an empty space. In the case of two spaces two operations are possible, each with two modifications: (1) copying and (2) moving the first space into the second. Modifications define how BIEs are processed in the recipient space. We may have: copy/move with clearing the recipient space and copy/move with merging the spaces. 11 The modifications with deleting first clear the recipient space and then provide a copy or move operation. Modifications with merging offer two types of processing: destructive or constructive. The destructive merging can be “conservative” or “alternative”. With the conservative approach, the BIE from the recipient space remains in the result if it has a non-zero length. With the second approach, the BIE from the donor space remains in the result. In the constructive union, the result is any union of the respective BIE of the two spaces. Of course, the move operation deletes the donor space after completing the operation. Operations with indexes and meta-indexes Indexes are the main approach in describing connections between structures. We can get the space addresses of the next or previous, empty or non-empty element of the space starting from any given co-ordinate. This corresponds to the processing of given hierarchical projections. By analogy, we can get the spatial address of the superceding (nextproj) or preceding (previousproj) non-empty element of the projection for the current address in operating with a given arbitrary projection. The option to count the number of non-empty elements of a given projection is helpful in practical realizations. Operations with indexes are based on simple logical operations between sets. The difference to ordinary sets is that information spaces are built on the basis of the connection between two major sets: the set of co-ordinates and the set of information elements. Therefore, operations with indexes may be classified in two major types: contextindependent and context-dependent operations. Context-independent operations defined in MDIM are based on the classical logical operations - intersection, union and complement, but these operations are not so trivial. Due to the complexity of the structure of information spaces, these operations have at least two completely different realizations based on: co-ordinates information elements. Operations based on co-ordinates are defined by the presence of the respective space information elements. For this reason the values for the co-ordinates of the existing information elements determine the operations. In the second case, existing BIE values determine the logical operations. In both cases, the result of the logical operations is an index. Context-dependent operations need special realizations for specific goals. The main information operation is the creation of indexes and meta-indexes. The main objective of MDIM is to enable access to the practically unlimited information space and an easy approach to building an interconnection among its elements. The aim of the specific applications is to build tools for creating and using indexes and meta-indexes and use these tools in the implementation of systems required by users. For example, such tools can carry out transfers from one structure to another, retrieval of information, sorting, reporting, more complex information processing, etc. Information operations 12 may be grouped into four sets based on the involved basic data structures: basic information elements, information spaces, and index or meta-index structures. 1.1.3 Multi-dimensional access method ArM32 The program realization of MDIM is called a multi-domain access method. For a long time, it was used as the basis for the organization of various information bases. Several realizations of MDIM exist for various hardware and/or software platforms. The most recent one is FOI Archive Manager – ArM. One of the first goals of the development of ArM was to describe the situation of a digitalized military defense characterized by a variety of complex objects and events arising in time and space and having a continuous period of variable existence. The large number of layers, aspects and interconnections of the real situation can be represented only via the hierarchy of an information space. In addition to this, the various types of users with individual access rights and needs insist on the implementation of a special tool for organizing such information base. In the course of years, the efficiency of ArM has been proven across broad fields of IT servicing of company management. The data organization in an appropriate model on the basis of a multidimensional information space enables skipping the hard work on creating OLAP structures [Markov, 2005]. The latest version of ArM – Version No.9, called ArM32, is developed for MS Windows and implements the proposed algorithms. The maximum range of information spaces in this version may reach 198 (Fig. 3). 13 Fig.3 ArM32 Archive The ArM32 elements are organized in numbered information spaces with variable ranges. Each single element may be accessed via a respective multi-dimensional space address (coordinates) set via a co-ordinate array of type cardinal. In the first position of this massif the range of the space has to be given. For this reason we have two main constructs of the physical organization of ArM32 – numbered information spaces and elements. Each co-ordinate of an element can take values from 1 to 4294967295. The set of ArM32 archives forms the ArM32 database (Fig. 4). 14 Fig.4 ArM32 DB 1.2 Main functions for processing data in ArM32 DBMS The specific and extended functions for operating with ArM32 DBMS are described in detail in “Chapter 7. ArMSBuilder Ver. 1.03 - Procedures, Functions, and Methods” of the current Technology. We will provide a graphical illustration of the work of one of the most important and interesting specific functions for working with ArM32 DBMS – NextPresentA. The function returns the space address of the next existing element (data element) from a given information space which is located after a given position of the co-ordinates in increasing a given co-ordinate. This function is used for traversing data in an information sub-space. 15 Fig. 1 Traversal of the subspace of S2 by using NextPresentA The following programming code illustrates the process of scanning of the existing elements in a sub-space with the first co-ordinate 3 of S2. The traversing starts with 0 starting value of the variable co-ordinate (0). var xex : cardinal; … begin … xex := 0; xex := DArm.NextPresent2(3, xex, 2); while xex > 0 do begin <User’s block> xex := DArm.NextPresent2(3, xex, 2); end; … end; As a result of the execution of the cycle, xex will consecutively take the values 1,3,4, and 7. If there are no more data elements, xex takes a 0 value and the traversing is stopped. 16 1.3 Implementation of some technologies for data storage on the Internet Software systems for business management and control process considerable amounts of different types of data. This data may be input by many different employees of a company. Often these employees are not geographically located in one and the same building or city, but they are rather distributed over a huge area (e.g. across an entire country or even on different continents). Yet each one of them may need access to the common data. In cloud computing, service providers offer various Internet-based services, as one of the most traditional is the storage of user data on their server accessible over the Internet. Users pay only for the storage space used. They receive a guarantee for data protection from unauthorized access as well as from the loss and damage of the data through application of appropriate technologies for data storage and recovery. The access to the data is performed using both standard protocols and one’s own (often closed-source) protocols. When using own protocols, service providers provide their users with specially designed software to access the data. Thus, accessing data from third-party software (e.g. a business management and control system) may be significantly hindered. Sometimes it is appropriate to choose a service provider offering access also via standard protocols for data exchange, such as FTP. FTP (File Transfer Protocol) is a widespread standard network protocol used to transfer files between computers via a TCP-based network such as the Internet. Many service providers offer data storage via FTP access. There are many components for the development of applications, ensuring the implementation of the FTP protocol. All these factors greatly facilitate the development of software with the ability to store data on the Internet via FTP. Not all data processed by the software system for business management and control need to be located on the FTP server. It should be assessed very carefully which data should be accessible to all users of the system. This is necessitated by a host of reasons such as lower speed for access to files on an FTP server, data consistency, different access rights to the data. One of the best libraries with components for the realization of network interactions is Indy. It supports a large amount of protocols at different levels, such as TCP, UDP, RAW, SMTP, POP3, IMAP, NNTP, HTTP, FTP. It is open-source and is distributed along with the development environment Delphi. To create an FTP client through which to carry out the file transfer with the FTP server, the component TIdFTP can be used. Using this component, several features have been developed to facilitate the work with company archives uploaded to an FTP server. They are declared in the program module u_FTP.pas. A detailed description of the functions in the programming module is done in “Chapter 7. ArMSBuilder Ver. 1.03 - Procedures, Functions, and Methods”. A major problem in processing data common for the business management system is their consistency. If a user reads a given file and begins to modify it, yet at the same time another user reads the same file and begins to make his or her own modifications, after the users upload the already revised data, the data from the user who uploaded his modifications second will necessarily overlap the data by the user who uploaded his modifications first. It is therefore necessary to create a mechanism that ensures the use of certain files by one user only at a time. This is achieved by using the functions UpLoadURLArch and LoadURLArch. The sequence of use is the following: using LoadURLArch, the user downloads the group of data files from the server to 17 their own computer (copy them); files remain on the server, but access to them is denied to other users (they cannot be downloaded with LoadURLArch and then uploaded via UpLoadURLArch by another user); the user edits the files and then uploads them to the server using UpLoadURLArch. After the user uploads the files, they can now be downloaded by other users. By uploading files on the server, local copies of the files are sent to the RecycleBin. Another important aspect of the issue of the consistency of information is creating new data files. Two users can start creating the same data simultaneously. To avoid this situation, the combination of functions LoadURLArch and UpLoadURLArch is also used in creating new files. The following order needs to be observed: an initial attempt is made to download the non-existent files from the FTP server using LoadURLArch; the LoadURLArch function returns a value indicating that the files have not yet been created but the creation is reserved for this user; creating the required files is reserved for this user (another user cannot create the new files and upload them to the server); the user creates the files and with the help of the function UpLoadURLArch uploads them to the server; thus the files can now be used by other users, and the files created on the local computer are sent to RecycleBin (by default, depending on the flag DeleteSourceFiles of the function UpLoadURLArch). The combination of input parameters UserNumber and UserInstallationNum enables the precise identification of the user and the provisional reservation of the access to the files namely for this user. Two different installations of the program for one and the same user cannot access the files simultaneously. Reserving an existing file on the FTP server is done through its renaming. Using the function LoadURLArch one can download only files with simple names (e.g. ‘filename’). After renaming the file it receives an expanded name (e.g. ‘filename_UserNum’). ‘UserNum’ corresponds to the number of the specific user along with the number of the installation and identifies ‘filename’ user. A file with an extended name cannot be downloaded via LoadURLArch. Reserving the creation of a new file is done by creating a file with the same name on the FTP server but with the extension ‘.INI’, which contains identification information for the user and installation (e.g. ‘filename.ini’). Another user by using the function UpLoadURLArch cannot upload their own INI-file if there is already another INI-file with somebody else’s identification available on the server. Only a user whose details match those of an uploaded INI-file can upload the relevant new files and delete the INI-file. Reservation of the file creation is eliminated with the deletion of the INI-file. By using the function UpLoadURLArch, only a file that was previously reserved for a particular user can be uploaded to the FTP server. When updating an existing file uploading is permitted only of a file with an extended name that corresponds to a particular user (e.g. ‘filename_UserNum’). A file with a simple name (e.g. ‘filename’) cannot be uploaded. When creating a new file, it can be uploaded only if an INI file that contains data for the particular user has already been uploaded to the FTP server. Other useful features facilitating the work with company files stored on an FTP server are: FileExistFTP, RenameFTP, DeleteFTP, List_FTP_Dir. The FileExistFTP function is used to verify whether a file exists on the FTP server. RenameFTP renames the specified file on the server and DeleteFTP deletes it. The List_FTP_Dir function is used to review the contents of a directory from the FTP server and to search for files in the directory by name (file masks can be set). It also allows the retrieval of additional information about the files (file size, creation date). 18 2 Improving the Ergonomics of Software Screen Forms FOI Smart Monitor Mechanism An integral part of the design process of any software system for business management and control is the development of an effective and convenient interface for visualization of inputs (entered data) and outputs (the displayed results) of computer processing. Primary attention should be paid to the way the end user perceives the interface. With this type of systems, the end user devotes considerable time to work with the software. Therefore, the interface should be easy to use and not tiring to the user. With the advancement of information technology, computer monitors have undergone serious development - starting from monochrome monitor matrices of 80x25 symbols and reaching to the latest full-color monitors with a resolution of 7680x4320 pixels. There is a constantly growing variety of monitors and their technical features. Thus, one and the same operating system with one and the same application software may run on computers that have not only monitors from different generations, but also seriously differ in the number of pixels vertically and horizontally and in the pixel sizes. Furthermore, the operating system offers several modes of work for a monitor - different resolution, orientation, color characteristics, size of the image (number of pixels for an object, e.g. the height of a button). As a result, this leads to considerable differences in the visualization of a programming interface. A problem arises that should be resolved by the developer – given the wide variety of hardware with different technical characteristics and the wide variety of settings of the operating system, the image on the screen should be proportional to the size of the monitor and be user-friendly. As a result of increasing the resolution and reducing the size of the pixels, in the case of incorrect design of the interface of the system, excessive reduction of the sizes of the screen forms might occur (Fig. 6). This causes significant inconvenience to users. They need to strain their eyesight in order to read the heavily downsized text. Also working with the interface is complicated because of the reduced size of the regions to be targeted with the mouse. One solution is to create an interface that adapts to the changing nature of the environment. Mechanisms are implemented for automatic scaling of the software screens and/or scaling done by the user. This approach, however, also has its peculiarities. The main goal should be to maintain the proportions of all the components of the interface. The failure to do this might cause problems, confusion and even frustration to the user. 19 Fig. 6 Excessive reduction in the size of the program windows For example, Figure 7 shows an example in which, after scaling, only the working area is resized and the rest of the interface does not change. Even after the scaling the user will experience difficulties using small and unreadable controls at the top of the window. Another common adverse side effect is the disproportionate resizing of the various components of the interface. Thus all controls might be grouped at one side of the window, while the other end remains completely empty. Fig. 7 Disproportionate scaling of the program windows Sometimes, when zooming the interface, a change occurs in the habitual location and look of controls. Rulers appear for scrolling down the contents of the window, buttons for hiding and showing of a group of controls. Part of the command controls can even disappear. This may confuse users and disrupt their work rhythm. A common problem in scaling program windows is that the inscriptions on the interface are either not scaled proportionately with other graphical components or are not scaled at all. Yet a well-readable text is one of the fundamentals for the creation of an easy-to-use and vision-friendly interface. Also, problems arise in zooming controls, the inscriptions on which are formed on the basis of pre-recorded images. In a poorly-designed interface, one can face a paradox in which older monitors with lower resolution might turn out to be more convenient to work with than the new ones that have significantly higher resolution. Developers need to pay serious attention to the design of the interface of modern software systems in order to avoid making an issue out of a positive trend of reducing the size of the pixels on the monitors. In ArMSBuilder a mechanism has been implemented for selecting the best options for visualizing screen forms depending on the specific parameters of the user hardware - FOI Smart Monitor (FSM). Its main tasks are optimal use of available resources and even scaling of the 20 individual components of the interface. The mechanism consists in: 1) loading the best possible resolution for the screen visualizing the forms of the program; 2) automatic conversion of visual components and the textual part of the software forms, corresponding to the monitor resolution. 2.1 Loading the best possible monitor resolution One of the main tasks of the FOI Smart Monitor mechanism is to achieve maximum utilization of the capabilities of a computer monitor. It aims to use the maximum possible resolution. At the same time, it selects a mode of monitor operation where the screen forms of the developed software are reproduced in an optimal way. Higher resolution contributes to the efficient use of each pixel on the screen and subsequently to building a smoother image more pleasing to the eye. To implement the FSM mechanism, the following methods are used: 1). procedure SaveSettings_monitor; 2). function TuneUpMonitor(ityp: integer): Boolean; 3). function SetScreen_monitor(BPP: byte; width, height, FR: integer; flshow: boolean): boolean; The mechanism allows the user to choose the most comfortable resolution settings. Subsequently, each time you start the program it changes accordingly the resolution of the image displayed on the screen. Presumably, if the user began working with the business management system, then they would not have much need for additional software and therefore the modified resolution will not cause discomfort when working with other unadjusted software applications. Upon completion of the work, the business management system restores the settings established at its start-up. The SaveSettings_monitor procedure is called at the start of the program. Its task is to determine and record the screen settings at the launch of the program - the number of pixels in width, number of pixels in height, color depth (number of bits per pixel), the monitor refresh rate. The function TuneUpMonitor carries out the change of the resolution. Its input parameter ityp sets the new resolution. ityp depends on the settings made by the user. The user can choose out of several options: 1). automatic change of the resolution (ityp=0) - the program tries to apply the highest resolution that is best suited for the screen forms of the system; 2). applying resolution 2048x1152 (ityp=1); 3). applying resolution 1920x1080 (ityp=2); 4). applying resolution 1600x900 (ityp=3); 5). applying resolution 1360x768 (ityp=4); 6). applying resolution 1280x768 (ityp=5); 7). applying resolution 1280x720 (ityp=6); 8). resolution remains unchanged (ityp=99). Upon successful change of the resolution the function returns as a result the value true. During the completion of the work of the program, the SetScreen_monitor function must be called with its default monitor settings (prerecorded by calling SaveSettings_monitor). This leads to the recovery of the parameters valid before starting the program. The parameter BPP sets the color depth (number of bits per pixel), width sets the width of the image displayed on the screen, 21 height sets the height, FR sets the refresh rate of the image, and flshow represents a flag determining whether to show an error message in the event of unsuccessful setting of the specified parameters. Upon successful application of preliminarily defined settings, the function returns the value true. 2.2 Automatic conversion of visual components - FOI Smart Monitor The other main task of the FOI Smart Monitor mechanism is the automatic scaling of the graphical interface. With its help, proportionate screens are received, effectively filling the increased monitor resolution. The FSM mechanism consists in automatic scanning of the visual components of the ArM form and re-sizing of the components in width and height. In addition to the size of the components, also the font size of the text displayed on the component (if any) changes automatically. The mechanism is realized through the use of the procedures scale_foi and scale_form_foi when re-sizing the form and the procedure scale_frame_foi when converting a frame. The procedures scale_foi and scale_form_foi are automatically called when displaying the ArM form. For banning the automatic scaling of ArM forms the flag ApplicationScaling is used. When the programmer needs to scale an individual section of the form, such as in a dynamic change of part of the ArM form to display other command fields (this is usually done by using the Frame component) it is necessary to manually call the procedure scale_frame_foi. Declaration of scaling procedures: 1). procedure scale_foi(form: TArmForm); 2). procedure scale_form_foi(form: TArmForm; scalew, scaleh: real; fl_full_screen: Boolean); 3). procedure scale_frame_foi(ownerform: TArmForm; ownerpanel: TPanel; frame: TFrame; scalew, scaleh: real); The input parameter form sets the ArM form which must be scaled. The parameters scalew and scaleh set the scaling co-efficient of the form respectively in terms of width and height. The flag fl_full_screen indicates whether the form is in full screen display mode. With the procedure scale_frame_foi the parameters ownerform and ownerpanel set the output form and panel for the frame which needs to be re-sized. The frame itself is set by the parameter frame. Forms with the ArMSBuilder technology are relatively static - the sizes of the forms cannot be changed by moving the mouse pointer over the edges of the forms, as in standard Windows forms. This is necessitated by the need to maintain the ratio between width and height of components and to keep the overall look of the form with different screen resolutions. One of the main features of the FOI Smart Monitor mechanism is the proportional re-sizing not only of the visual components of the form, but also of the text in the components. Thus good visual perception of the interface is achieved and eye fatigue is reduced. As an example of how the mechanism operates, we can look at both forms in Fig. 8 which look exactly the same, regardless of the different screen resolutions. In making a comparison of the effectiveness of the mechanism one can see the difference in the display of icons on the 22 bottom task bar on the screen, which appear significantly different with different monitor resolutions. Fig. 8 Comparing the results from using the FOI Smart Monitor mechanism in various monitor resolutions. 23 3 Options for Displaying Information In this chapter we pay attention to the two components of the process of displaying information - the generation of outbound reports (various opportunities that technology provides) and the displaying of the output information through license-free software for visualization, editing and printing. 3.1 Mechanisms for generating reports One of the main features of each software system for business management and control is the generation of various types of reports. The data required for them is generated by summarizing and analyzing the various types and amounts of input data about the company, its staff, production activity and legislation. The output data obtained is mainly presented in two ways - 1) by generating text reports and 2) by generating charts and graphs. Text reports primarily serve as different types of documents - official notes, certificates, references, etc. Graphs and charts are particularly useful for visualizing certain characteristics, such as trends in revenue and expenditure. 3.1.1 Generating reports through the use of document templates One way to generate text reports is through the automated filling out of pre-defined templates. When creating a template the so-called key strings and expressions are added to it. These key strings will later be replaced with useful data when generating the report. Key strings and expressions consist of certain character combinations that are not found in the text of the final report and can be recognized by the program. Every key string must have a corresponding system variable whose value is added to the report in its generation. Key expressions differ from key strings in the fact that they take additional parameters that determine the results in the report. For example, the key expression for adding an image can contain the preset size that this image will get upon generating the report. With this mechanism for generating reports, the program reads the predefined template and replaces each key string and expression it comes across with its corresponding value from the system (Fig. 9). As a result, the template is completed and the user can make use of the generated document with concrete data. The main advantage of this method is that the end user is given the opportunity to edit the contents of the report. For example, users can change the formatting of an existing template, add or remove text from the template, or, using the capabilities of key strings and expressions, create their own template corresponding to their needs. Also this mechanism contributes to the rapid development of many different reports by the programmer. Creating a new report consists in designing the template and setting a correspondence between the key expressions and the necessary data from the system. One disadvantage is the requirement that for each type of report there must be a separate template saved on the disc. Also difficulties arise when creating reports, the contents of which depend on the fulfillment of certain conditions. For 24 example, it is difficult to create tables in which the number of rows varies (e.g. enumeration of types of items). Fig. 9 Generating a report via filling out a template Creating a report by filling out a template uses the methods of the programming module u_RTFoperations.pas. As key strings one uses combinations of characters of the type: "#N#", where N is an integer (e.g. "#1001#"). In key expressions the character combination has the following general look: "#N:P1,...,Pk#" (e.g. "#1000:100.10#"). N is an integer encoding a certain unit of data in the system (e.g. name of the employee or the employee's photograph). The numbers following ":" match parameters for displaying this unit of data in the report - they may be integer or real numbers. For example, these parameters can match the size the image must obtain in the document. When creating a report using this method, initially it is necessary to set equivalence between the code from the key string and the content that should be put in the report instead of the key string. This is done by forming the function MyNumberEquivalence. Each of the codes is assigned a respective RTF string. Here is an example for the formation of MyNumberEquivalence: function MyNumberEquivalence(cod: integer; arpar: arrparams): string; begin case cod of 10: Result := 'INVOICE'; 11: Result := TraderName; 12: Result := TraderAddress; 21: Result := CustomerName; 22: Result := CustomerAddress; // Key expressions with paramener – number of item 25 31: Result := ItemName[arpar[0]]; 32: Result := FloatToStr(ItemPrice[arpar[0]]); ... else Result := '#' + IntToStr(cod) + '#'; end; end; After the function of the equivalence is formed, the MemoryStream with the contents of the report template needs to be loaded. Then filling the template is carried out by calling the procedure FillInTemplate from the module u_RTFoperations.pas. The MemoryStream with the content of the template and the equivalence function are passed as parameters: u_RTFoperations.FillInTemplate(Loaded_Stream, FilledIn_Stream, '#', MyNumberEquivalence); The content of the filled-in template is recorded in FilledIn_Stream. Then it can be shown via a component for visualizing RTF text or be saved as a disk file. 3.1.2 Generating a package of documents The mechanism for generating documents could be upgraded to a mechanism for generating packages of documents. The document packages include more than one document and can be used to generate reports for a group of items (personnel, materials, etc.). Figure 10 shows the interface of a software system that allows the compilation of packages of documents. The user checks the box "package document" and then chooses various templates from drop-down lists. The program fills in each template and adds it at the end of the common package document. This is how the document shown in Figure 11 is formed. Fig. 10 Interface for generating a package document 26 Fig. 11 Package document The programming code for generating a package of documents is as follows: var SRVE : TSRichViewEdit; … if not fl_pakDoc then begin // not in package mode SRVE.Clear; // NumberOfDocuments := 0; // end else begin // in package mode of document generation if NumberOfDocuments = 0 then SRVE.Clear // else begin SRVE.RichViewEdit.SetSelectionBounds( SRVE.RichViewEdit.ItemCount-1, SRVE.RichViewEdit.GetOffsAfterItem(SRVE.RichViewEdit.ItemCount-1), SRVE.RichViewEdit.ItemCount-1, SRVE.RichViewEdit.GetOffsAfterItem(SRVE.RichViewEdit.ItemCount-1)); // points the cursor at the end of the document/ LastItemOfPrevDocument := SRVE.RichViewEdit.ItemCount-1; //Contains the number of the last Item of the most recently added document end; end; LoadedFromDB_Stream := TMemoryStream.Create; try //Loading from DB of the metadata for the file (in BOMetaData) ReadMD_Success := ReadMD3(ArmDI, 1, 1, FXHCB.getposition(self.num_doc), 27 BOMetaData); if ReadMD_Success then begin // Retrieval of the file from the DB if Copy(BOMetaData.DataType, Length(BOMetaData.DataType)-3, 4)='_zip' then FileIsZipped := true else FileIsZipped := false; ReadBO_Success := ReadBO3(ArmDI, BOMetaData.Position[1], BOMetaData.Position[2], BOMetaData.Position[3], LoadedFromDB_Stream, FileIsZipped); if ReadBO_Success then begin FilledIn_Stream := TMemoryStream.Create; try // Filling in the template u_RTFoperations.FillInTemplate(LoadedFromDB_Stream, FilledIn_Stream, '#', MyNumberEquivalence); // Displaying the RTF file if SRVE.RichViewEdit.LoadRTFFromStream(FilledIn_Stream) then begin if NumberOfDocuments > 0 then SRVE.RichViewEdit.PageBreaksBeforeItems[ LastItemOfPrevDocument + 1] := true; SRVE.RichViewEdit.RVData.Normalize; SRVE.Format; SRVE.ZoomToFullPages(1); NumberOfDocuments := NumberOfDocuments + 1; end else ShowMessage(‘The template cannot be loaded'); finally FilledIn_Stream.Free; end; end else ShowMessage('The template cannot be loaded'); end else ShowMessage('The template cannot be loaded'); finally LoadedFromDB_Stream.Free; end; … 3.1.3 Generating reports by creating a RTF document Another way to generate text reports is by creating a new RTF document. The program creates the report by consecutively adding content to a blank document. This removes the need to create and preserve an appropriate template for each report in advance. The developer has much 28 bigger opportunities in compiling the report (e.g. Individual parts of the report can only be added when there is fulfillment of certain conditions). However, this approach deprives the end users of the opportunity to create reports of their own (by editing existing templates or by creating their own templates using the options of key strings and expressions). To create reports by generating new RTF documents, the methods of the programming module u_Report.pas. are used. This module contains the declaration of the class TArmReport, in which the content of the created RTF report is built. Its methods are sufficient for consistent construction of complex RTF documents (texts with different types of formatting, tables with complex layouts, images). At the same time, the use of the module u_Report.pas is not complicated and does not require in-depth knowledge of the RTF specifications. Generating a new RTF report begins with the creation of a new instance of the class TArmReport, in which the content of the report will be built. This is done by calling the constructor Create: var rep : TArmReport; begin rep := TArmReport.Create(FileName, ArmBaseAddress.Arm, 'p', 1, 9); Then the following information is given: name of the created new RTF document, archive containing data to add to the report, initial settings of the document (fonts, colors, orientation of the page, margins, information about the document). The next necessary action is setting the title of the document. It is done by using the procedure WrtTit1. The subsequent building of the document consists in adding new paragraphs, formatting and adding text, adding images and tables. The procedures SetDefFont and SetDefAlign are used to set the default font and text alignment. The text which is added to the document after calling these procedures has a default font type and font size and alignment relative to the page. To change them one needs to call again SetDefFont and SetDefAlign. Starting a new paragraph is done by using the procedure WrtParBeg. Adding text to a paragraph started in this way is made by repeatedly calling the procedure WrtString. The completion of the paragraph is done by calling the procedure WrtParEnd. A whole new paragraph can be added to the document only through the use of the procedure WrtLine. The entire content of the paragraph is supplied as its parameter. Images can also be added to the created report. For this purpose, the procedure WrtJpg is used. The methods of U_Report.pas allow easy addition also of tables. The steps to create them are described in the next few subchapters. At the end of the report generation, it is necessary to call the procedure FinishRep. It ends the description of the created RTF report and releases the file. 3.1.3.1 Automatic generation of tables via describing the columns One of the most important components of any text report is the table. The software module U_Report.pas offers several ways for adding a table to the constructed RTF report. The first is through describing each column of the table and setting an archive which contains the data to display. All rows of the table are filled automatically based on certain index array. All rows of the table have the same number of columns, as the formatting is the same. The methods used when generating a table in this way are the following: SetIndex, TArmReport.Columns.Add, SetTableParams, WrtTableHeader, WrtTableRows, WrtTableBottom. 29 Upon the creation of the report with TArmReport.Create the archive that contains the data to be displayed is set. Then an index array is formed with the coordinates of the data that must be included in the table. Subsequently, using a SetIndex, the formed Index is fed to u_Report.pas. The actual construction of the table consists of a description of each of the constituent columns. Adding a new column is carried out by the method TArmReport.Columns.Add. The parameters assigned are the name of the column (which will appear in the header of the table), number of column, type of column, coordinates for retrieval of the data for the column from the data archive, various settings of formatting the column (column width, alignment, bold/italic of the text). Adding the columns determine the structure of the table and how the contents of the cells are filled. After all columns have been described, it is necessary to call the procedure SetTableParams. It sets the format of the table as a whole. It assigns the alignment relative to the page, the type of the range of cells, the overall width of the table. Also the width of the individual columns for optimal display of the data therein is specified. After setting the parameters the header row of the table can now be added. This is done by calling the procedure WrtTableHeader. Thus a line containing the column names is added to the RTF report. This procedure is repeated at the upper part of each page. The body of the table is generated by calling the procedure WrtTableRows. It causes adding multiple rows of data to the report. Data is retrieved from the archive specified when creating the report. The contents of the cells are formed on the basis of data from the archive, the index array specifying which data from the archive are to be read and the settings of the individual columns. If a column is of type arm_f, then the event handler OnFUser of the report is also used in the formation of its content. For each element of the index array a new row is added to the table. At the end of the table a conclusive row can be added. This is done by calling the procedure WrtTableBottom. Example for creating a table: Creating the contents of the columns of type arm_f: procedure TeventHandlers.wrk_days_and_ots_fuser(Arm: TArm; itm: TArmReportColumn); var ss : string; begin case itm.FUserNumber of 1 : begin if DMD.ArmBA_FE.Arm.Length5(itm.FCoord[1], itm.FCoord[2], itm.FCoord[3], 12, itm.FCoord[5]) > 0 then begin inc(br_num); ss := int2str(br_num, 0); fl_init_pers := true; end else begin fl_init_pers := false; end; end; 30 2 : begin if fl_init_pers then ss := DMD.ArmBA_FE.Arm.ReadSStrA(@itm.FCoord) else begin if monthbeg_query = monthend_query then begin ss := ' >>> ' + DMD.ArmBA_FE.Arm.ReadSStrA(@itm.FCoord); end; end; end; 3, 4,..10 : <user programming block> end; itm.fvals := ss + ' ' end; Creating the table rep.Columns.Add('No:', 1, arm_f, FillArmCoords5(month, 1, 1, 17, 0), 5, 0, 0, 0, false, 5, 0, false, false, 0, 'r'); rep.Columns.Add(‘name of employee’, 2, arm_f, FillArmCoords5(month, 1, 1, 17, 0), 5, 0, 0, 0, false, 35, 0, false, false, 0, 'l'); rep.Columns.Add('number of days worked', 3, arm_f, FillArmCoords5(month, 1, 1, 51, 0), 5, 0, 0, 0, false, 12, 0, false, false, 0, 'r'); rep.Columns.Add('', 4, arm_f, FillArmCoords5(month, 1, 1, 52, 1), 5, 0, 0, 0, false, 1, 0, false, false, 0, 'r'); rep.Columns.Add('paid leave', 5, arm_f, FillArmCoords5(month, 1, 1, 52, 1), 5, 0, 0, 0, false, 12, 0, false, false, 0, 'r'); rep.Columns.Add('non-paid leave', 6, arm_f, FillArmCoords5(month, 1, 1, 52, 1), 5, 0, 0, 0, false, 12, 0, false, false, 0, 'r'); rep.Columns.Add('absence from work', 7, arm_f, FillArmCoords5(month, 1, 1, 52, 1), 5, 0, 0, 0, false, 12, 0, false, false, 0, 'r'); rep.Columns.Add('sick leave', 8, arm_f, FillArmCoords5(month, 1, 1, 52, 1), 5, 0, 0, 0, false, 12, 0, false, false, 0, 'r'); rep.Columns.Add('pregnancy leave', 9, arm_f, FillArmCoords5(month, 1, 1, 52, 1), 5, 0, 0, 0, false, 13, 0, false, false, 0, 'r'); rep.Columns.Add(‘maternity leave', 10, arm_f, FillArmCoords5(month, 1, 1, 52, 1), 5, 0, 0, 0, false, 12, 0, false, false, 0, 'r'); rep.SetTableParams('l', 1, 0); rep.WrtTableHeader; // rep.OnFUser := EvHandler.wrk_days_and_ots_fuser; rep.SetIndex(sind, afia); rep.WrtTableRows; //writes the table rows depending on the formed index rep.WrtLine(' '); 31 As a result of the execution of the code, the table shown in Figure 12 is added to the RTF file. Fig.12 RTF report with a table automatically generated via describing the columns 3.1.3.2 Generating tables by describing rows Often in the creation of reports it is necessary to add complex tables which consist of rows of different numbers of columns containing different types of information, as the different cells have different formatting. Adding such tables to an RFT report cannot be achieved through the methods described in Item 3.1.3.1. To complete this task, it is necessary that the table be built by consistently adding new rows. Before adding a new row different settings for the row can be assigned. In this way a very complex table can be built. In generating a table in this way the following methods of the programming module are used: u_Report.pas: WrtTableFromStringArray_Beg, WrtTableFromStringArray_End, SetRowParams_StrArr, EvaluateZeroWidthCells_StrArr, WrtTableRowFromStringArray. The entire table is constructed by successively adding each one of the rows. The content of each row is set by the programmer by loading an array of strings storing the contents of the cells of the row. Each cell in the row can be formatted separately. To add a new table to the original RTF report, first it is required to complete the paragraph if already started (e.g. by using the procedure WrtParEnd). Then you need to call the procedure WrtTableFromStringArray_Beg, which begins creating the table. The subsequent action is setting the parameters of the header row of the table. This is done by calling the procedure SetRowParams_StrArr. It loads the array TArmReport.RowParams_StrArr with the parameters for formatting the cells of the row. It also sets the number of columns composing the row. All cells receive the same parameters. 32 If desired, some of the cells in a row can get different formatting settings. For this purpose the settings of the array TArmReport.RowParams_StrArr must be given directly. It represents an array of records, each one characterizing one cell of the row. The zero element of the array corresponds to the left-most cell. The following parameters can be set: type of cell borders, background color, width of the cell, text alignment inside the cell, bold and italic fonts. When specifying the width of the cell, it can be set to be automatically calculated (by setting 0). In this case, the cells with zero width will share equally the remaining space of the area for writing on the page. If in setting the parameters of the cells one of them has a width of 0, then after assigning all the settings, it is necessary to call the procedure EvaluateZeroWidthCells_StrArr, calculating the width of cells. The next necessary action is loading the string array with the column headings. Each element of the array contains the text of one cell in the row, as the zero element contains the text of the left-most cell. The number of elements must match the number of columns set when calling SetRowParams_StrArr. Once the settings of each cell from the header row are formed and their content is set, it is necessary to call the procedure WrtTableRowFromStringArray. In calling it, the array with the content of the row is given and the flag fl_header is raised, by which the header row will be displayed at the top of each new page of the table. It adds the header row of the table to the RTF report. Once the header row is added, the body of the table starts to be built. It consists of repeated loading of the array with the content of the row and calling the procedure for adding a new row WrtTableRowFromStringArray. Besides, setting the formatting the cells can be performed only once and each new row will have the same parameters as the previous or the settings can be done before adding a new row and thus different rows will have different formatting (the number of cells in one row can also be modified). The cells of each of the rows are formatted according to the parameters set in RowParams_StrArr. When all the rows of the table are added, for its completion it is necessary to call the procedure WrtTableFromStringArray_End. The text following the table should be placed in a new paragraph. An example for creating a table: rep.WrtTableFromStringArray_Beg; //Setting the beginning of the table ColCnt := 4 + num_days + 1; //Sets the number of cells of the table rep.SetRowParams_StrArr(ColCnt, 's', 's', 's', 's', 16, true, false, 'c', 0); // Sets the settings for the row (equal for all cells) if ColCnt>1 then begin rep.RowParams_StrArr[0].Width := rep.mm2twips(10); // cell width rep.RowParams_StrArr[1].Width := rep.mm2twips(75); rep.RowParams_StrArr[2].Width := rep.mm2twips(10); rep.RowParams_StrArr[3].Width := rep.mm2twips(10); rep.EvaluateZeroWidthCells_StrArr; 0 width // Calculates the widths of colums with set 33 end; SetLength(RowElems, ColCnt); // Loading of RowElems with the names of table columns RowElems[0] RowElems[1] RowElems[2] RowElems[3] := := := := '№'; 'name of employee'; 'number of days worked'; 'absence from work'; for ii:=1 to num_days do begin iday := u_date.DayOfWeek(u_date.EncodeDate(cyear, ii_mon, ii)); if montharray[ii] > 0 then rep.RowParams_StrArr[ii+3].BackgroundColor := 21 // cell color else rep.RowParams_StrArr[ii+3].BackgroundColor := 16; case iday of 1 : ss := '[н]'; 2 : ss := 'П'; 3 : ss := 'В'; 4 : ss := 'С'; 5 : ss := 'Ч'; 6 : ss := 'П'; 7 : ss := '[с]'; end; arr_day_week[ii] := iday; RowElems[ii+3] := ss; end; RowElems[colCnt-1] := ' !!! '; rep.WrtTableRowFromStringArray(@RowElems, true, 'l'); // Adding the header row of the table RowElems[0] := '-'; RowElems[1] := ' '; RowElems[2] := ' '; RowElems[3] := ' '; for ii:=1 to num_days do begin ss := lead_zeroi(ii, 2); RowElems[ii+3] := ss; end; RowElems[colCnt-1] := ' '; rep.WrtTableRowFromStringArray(@RowElems, true, 'l'); fl_pers := false; for ii_brp:=1 to tree_ind_br begin do 34 if DMD.ArmBA_FE.Arm.Length5(ii_mon, 1, 1, 12, tree_ind_leafe[ii_brp]) > 0 then begin if not fl_pers then begin rep.SetRowParams_StrArr(ColCnt, 's', 's', 's', 's', 8, true, false, 'c', 0); rep.RowParams_StrArr[0].Alignment := 'r'; rep.RowParams_StrArr[1].Alignment := 'l'; rep.RowParams_StrArr[0].Width rep.RowParams_StrArr[1].Width rep.RowParams_StrArr[2].Width rep.RowParams_StrArr[3].Width rep.EvaluateZeroWidthCells_StrArr; set 0 width := := := := rep.mm2twips(10); rep.mm2twips(75); rep.mm2twips(10); rep.mm2twips(10); // Calculates the width of the columns with // The first 4 columns have a width of 10 mm and 50 mm, and the rest take the remaining space fl_pers := true; end; SetLength(RowElems, ColCnt); inc(br_num); RowElems[0] := int2str(br_num, 0) + ' '; RowElems[1] := DMD.ArmBA_FE.Arm.ReadSStr5(ii_mon, 1, 1, 17, tree_ind_leafe[ii_brp]); <user programming block> end else begin rep.SetDefFont(2, 10); fl_pers := false; rep.SetRowParams_StrArr(3, 's', 's', 's', 's', 8, true, false, 'l', 0); rep.RowParams_StrArr[0].Width := rep.mm2twips(10); rep.RowParams_StrArr[1].Width := rep.mm2twips(95); rep.EvaluateZeroWidthCells_StrArr; SetLength(RowElems, 3); RowElems[0] := ' '; RowElems[1] := ' >>> ' + DMD.ArmBA_FE.Arm.ReadSStr5(ii_mon, 1, 1, 17, tree_ind_leafe[ii_brp]); 35 RowElems[2] := ' '; end; rep.WrtTableRowFromStringArray(@RowElems, false, 'l'); rep.SetDefFont(2, 7); end; rep.WrtTableFromStringArray_End; // Завършване на таблицата As a result of executing the coce, a table is added to the RTF file as shown in Figure 13. Fig. 13 An RTF report with a table generated via description of each of the rows 3.1.3.3 Genrating tables by using pseudographic characters Another way to create complex tables is by using pseudographic characters. In this case, the programmer draws the table elements manually. Characters such as "-", "|", "+" are used to outline the contours of the table. Each of the rows of the table is a sequence of these characters. Overall, the table is made of plain text. No RTF control words are added to describe the tabular structure. The table is constructed by successively adding separate rows to the RTF with an appropriately selected sequence of characters. For adding a row one uses the procedure WrtLine. In constructing a table of this type it is necessary to use fonts of equal width of the characters (the so-called called Monospaced). Example for creating a table: ii_mon := month; num_br := 0; 36 dim_nam := 35; ss0 := '-' + + + + + + + fs_str('---------- ', 5, 'r') '-' + fs_str('-------------------------------------', dim_nam, 'l') '-' + fs_str('------------------------------------------', 35, 'l') '-' + fs_str('---------------', 10, 'l') '-' + fs_str('---------------', 10, 'l') '-' + fs_str('---------------', 8, 'r') '-'; ss1 := '|' + + + + + + + fs_str('---------- ', 5, 'r') '+' + fs_str('-------------------------------------', dim_nam, 'l') '+' + fs_str('------------------------------------------', 35, 'l') '+' + fs_str('---------------', 10, 'l') '+' + fs_str('---------------', 10, 'l') '+' + fs_str('---------------', 8, 'r') '|'; rep.WrtLine(ss0); rep.WrtLine('|' + + + + + + + rep.WrtLine(ss1); fs_str(' No: ', 5, 'r') '|' + fs_str('name of employee', dim_nam, 'c') '|' + fs_str('type of leave/absence', 35, 'c') '|' + fs_str('from date', 10, 'c') '|' + fs_str('until data', 10, 'c') '|' + fs_str('working days', 8, 'c') '|'); for iip:=1 to tree_ind_br do begin fl_not_read_name := true; xex := 0; xex := ArmBA_F.Arm.NextPresent5(ii_mon, 1, 10, xex, tree_id[iip], 4); while xex > 0 do begin if ArmBA_F.Arm.Length5(ii_mon, 1, 10, xex, tree_id[iip]) > 0 then begin if fl_not_read_name then begin inc(num_br); ssnum := int2str(num_br, 0) + ' '; ssnam := ArmBA_FE.Arm.ReadSStr5(ii_mon, 1, 1, 17, tree_id[iip]); fl_not_read_name := false; end else begin ssnum := ''; ssnam := ''; end; <User programming block> 37 end; xex := ArmBA_F.Arm.NextPresent5(ii_mon, 1, 10, xex, tree_id[iip], 4); end; end; rep.WrtLine(ss0); rep.WrtLine(' '); As a result of the execution of the code, a table is added to the RTF file as shown in Fig. 14. Fig. 14 A RTF report with a table generated by using pseudographic characters 3.1.4 Generating reports by creating graphics and images The best way to visualize information is via using charts and graphs. It is the easiest way to track trends and make comparisons of numerical characteristics. One of the most comprehensive libraries of components for creating and displaying graphics and images in the development environment Delphi is the library TeeChart. The standard version of TeeChart is distributed freely with Delphi. Its components provide a wide range of opportunities for the presentation of sequences of data. With their help, complex diagrams with an abundance of data and visualization tools can be built. The component TChart offers the programmer a wide range of options to build charts. For example, one can set the chart title, the names of the axes, a legend can be added with the listed types of sequences. Each of the sequences may be displayed using a different type of graph separate bars, a continuous line, shaded areas, single points, etc. The value of each dot in the image in the chart can be increased, reduced, rotated. The end users can set which sequences they want to make visible by ticking the appropriate box shown in the field of the legend next to 38 the name of each of the sequences. There are several options to set the background of the chart a specific color, image, gradient. These and many other tools for visualization contribute to the construction of informative and good-looking graphics that appeal to the end users of the software system. Sample code for creating a chart by using the component TChart (Chart_Reports: TChart ;, NewSeriesClass: TChartSeriesClass;): Chart_Reports.Title.Text.Clear; Chart_Reports.Title.Text.Add('WORKERS'); Chart_Reports.BottomAxis.Title.Caption := 'Months'; Chart_Reports.LeftAxis.Title.Caption := 'Number of employees'; Chart_Reports.Legend.Visible := true; Chart_Reports.Legend.Title.Text.Clear; Chart_Reports.Title.Text.Add('"PROFESSIONAL QUALIFICATION" for ' + IntToStr(monthbeg) + '-' + IntToStr(monthend) + 'month'); Chart_Reports.Legend.Title.Text.Add('Professional qualification'); Chart_Reports.Foot.Clear; Chart_Reports.FreeAllSeries; // Deletes all created series for k := 0 to Length(Kinds_Array) - 1 do begin // Adds a series for each type of qualification NewSeriesClass := TBarSeries; // Sets the type of the graphics Chart_Reports.AddSeries(NewSeriesClass.Create(AForm)); Chart_Reports.Series[k].Title := Kinds_Array[k]; // Sets an inscription in Legend Chart_Reports.Series[k].Marks.Style := smsValue; // The value on the Y-axis is written above the columns for i := monthbeg to monthend do // Sets the values of the series Chart_Reports.Series[k].AddXY(i, Num_perMonth_perKind[i][k], IntToStr(i), clTeeColor); end; (Chart_Reports.Series[0] as TBarSeries).MultiBar := mbNone; // Shows the bars one behind the other Chart_Reports.Axes.Depth.Inverted := true; // To show Series[0] first; direction for Z order Chart_Reports.Axes.Bottom.LabelsAngle := 0; // Shows inscription on X-axis horizontally Chart_Reports.Legend.Symbol.Squared := true; // Sets the width of the color box to be equal to its height Chart_Reports.Legend.CheckBoxes := true; // Adds CheckBoxes that hide or show certain graphics Chart_Reports.Legend.CheckBoxesStyle := cbsCheck; // Adds CheckBoxes which hide and show separate graphics Chart_Reports.Gradient.StartColor := GrStartColor; // Sets background gradient Chart_Reports.Gradient.EndColor := GrEndColor; // Sets background gradient Chart_Reports.Gradient.Direction := gdBottomTop; // Sets background gradient Chart_Reports.Gradient.Visible := true; // Sets background gradient 39 As a result of the execution of the code, a chart is displayed in Chart_Reports as shown in Fig. 15. Fig. 15 Generating a graphic report by using the component Tchart 3.2 License-free options for displaying information End users of developed software systems for business management and control are not inclined to make excessive costs for the acquisition of additional software. Their desire is to make a certain investment (purchasing a software system) and thus obtain all things necessary for their further work. Consumers do not want the purchase of a product or service to require the purchase of additional products and services from other vendors, without which the use of the original product or service is impossible. It is therefore desirable in the development of a software product that it can be fully completed and self-sufficient, not requiring for its operation the installation of additional software of third-party producers. Most often the result from the operation of software systems for business management and control is textual and graphical information presented in the form of text documents, reports, spreadsheets, graphics, and images. Displaying this data on the screen is done through the respective standardized editors and viewers, often produced by other manufacturers. The independence from the products of third-party developers can be achieved by developing one’s own modules and programs to provide the necessary functionality. The so-called free software or open source software can also be used. Very often, however, free software is really free and gratuitous only for use by individuals, while its use by companies (which are most often the end 40 users of systems for business management and control) is allowed only upon payment of a fee. Therefore, it is preferable to develop one’s own visualizing tools. It is also desirable to give the user the opportunity to choose which software tools to use – they may not generate additional costs and they may use the built-in programs of the software for displaying information or can optionally purchase the product of external producers and use them to visualize the information resulting from the work of the product. For example, an organization may already have purchased a product (such as Microsoft office package) and have no technological time to study how additional software tools operate. The development of a data viewer or editor is a long and complicated process if starting from scratch. It requires excellent knowledge of various specifications and formats of displayed data, algorithms for compression and decompression, methods for data processing. Also the retrieved data can be of several different types - text, spreadsheets, and images. Each type requires a separate software tool. Thus the development of all necessary viewers for a given software product may turn out to be a more complex task than the creation of the product itself. Therefore, at the design phase it is helpful to use ready-made components from third-party developers. With them, the design process is limited to the construction of the main interface, the setting of components, introducing small changes to achieve the necessary functionality and directing the data. This approach allows a significant reduction in design time and ensures achievement of the desired result. There are different components for visualization and processing of a given type of information. Some are free and may be incorporated in the project without additional payment of license fees. Other components require the payment of certain sums. However, this is a one-time investment that enables the creation of a better final product and meeting the needs of the end user. 3.2.1 Text editor Most often in the work of software systems for business management and control, text data is generated for displaying the received results. There are different standardized formats for storing text. The simplest is plain text. It is merely a sequence of character codes (depending on the encoding used, e.g. ASCII, UTF-8, UTF-16). With it there is no information about the formatting of the text (font, font size, color, etc.). It is the most compact and easiest to use in a project - for its visualization one can use the standard components supplied with Delphi. RTF (Rich Text Format) is a text format which, unlike plain text, contains additional formatting information. Developed by Microsoft in 1982 for the editor Word, it continues to evolve. RTF is a meta-tag cross-platform format (its specifications are publicly available). Most text editors can import and export text in this format. When viewing the RTF file as plain text, it is readable to humans – both the tags for formatting and the actual text can be seen. A variety of components exist to display RTF text, as many of them are even distributed for free. They have varying complexity and not all have implemented the visualization of more complex structures such as tables. The Microsoft Word format is the basic one for the widespread text editor MS Word. The files created in this format have the extension ".DOC" (from "document") and therefore are sometimes called "DOC" format. Binary ".DOC" files often contain more information about the formatting of the text compared to other formats such as RTF or HTML. Since the data is stored in binary form, the files of this type are not human-readable when viewing them as plain text. There are different versions of the format. The Microsoft Word format is not free. Thus this format is less 41 widely compatible with other editors. Therefore, its use for the output of information from the system may limit the consumer. Another text format that can be used to display information is PDF (Portable Document Format). The format was created by Adobe Systems in 1993 and is used for visualizing of documents in one and the same manner regardless of the hardware, operating system or application software. The PDF file includes a complete description of the fixed document, which includes - text, fonts, images, vector and raster graphics. The format has the ability to embed and replace fonts, which allows combining the used fonts with the documents. An important feature is that it is standardized (ISO 32000-1: 2008) and can be used freely. This results in a large number of different components to create and display PDF files. HTML (HyperText Markup Language) is a language for describing the text used for creating web pages. The text formatting is saved by using tags (keywords written in angle brackets, e.g. "<html>"). Thus, the plain text corresponding to the formatted text is readable for humans. HTML formatting provides a means to create structured documents by denoting the structural elements of the text - titles, paragraphs, enumerations. Scripts written in languages such as JavaScript can be embedded to influence the behavior of the web page. When displaying one and the same HTML file in different web browsers, it might look different. HTML was originally developed by Tim Berners-Lee as it was originally conceived and implemented as a free format. Subsequently it was standardized. This determines its extremely high distribution. There are many different components to create and display HTML-formatted text. Some of them are a standard part of Delphi. Many of the components for work with other formats (e.g. RTF) support methods for converting from/to HTML and for displaying such text. Another important feature is that many editors of spreadsheets can extract data from HTML tables (HTML has a well-structured description of tabular data). Thus, HTML can be used for putting the data in tabular form without the need to use additional components for working with spreadsheets. Very suitable for working with RTF files are the packages of components TRichView and ScaleRichView developed by the same manufacturer2. TRichView is a package of components for Delphi/C++Builder (VCL) for displaying, editing and printing of hypertext documents. The components support different attributes for formatting of the text (font, superscript and subscript, text color and background, options for innovative painting). The documents can contain tables, images, animation, any visual components of Delphi. Other formatting options include: alignment of paragraphs left, right, centered, justified, customizable fields and margins, numbering lists with numbers, arrows, bullets, background images, print with preview, export to HTML and DocX, import and export in RTF, styles of the text and paragraphs, the ability to spell check, etc. The components are written entirely in Delphi, they are not descendants of the standard component TRichEdit and require no additional libraries (DLL) or ActiveX for their work. They are paid, but have a trial version which can be used to get to know their options. Some of the components included in the package are: TRichView - component for displaying hypertext documents, images and tables. TRichViewEdit - component for editing documents TRVStyle - set of properties and styles for text and paragraphs in TRichView and TRichViewEdit TRVPrint - component to print the contents of TRichView and TRichViewEdit 2 www.trichview.com 42 TRVPrintPreview - component for document preview before printing. ScaleRichView is a package of components for document editing in the WYSIWYG mode (What You See Is What You Get), created on the basis of TRichView and RichViewActions. Using TRichView for formatting the document, ScaleRichView in its own way paints, scales and breaks it down into pages. Access to the document in the editor ScaleRichView is carried out through an internal TRichViewEdit, therefore when working the same methods are used as in dealing with TRichViewEdit. Some features of ScaleRichView are: breaking down pages in real-time, support of more than 120 standard paper formats (ISO, ANSI, JIS, etc.), the ability to convert formats during printing (e.g. the document is with format A5 but is printed on A3), location of the pages on the screen managed by the program, multiple modes for displaying the document (web mode, draft, breaking down into pages, etc.), vertical and horizontal toolbars in the areas of scroll bars. TRichView has its own file format - RVF (RichView Format). It is quite easy and compact. It can be used to record all features of the document accessible for editing (including text, images, separators for lists, links, Delphi controls, check boxes, tables). For reading and writing of RVF files the functions LoadRVF() and SaveRVF() are used and for loading and saving of RVF formatted text in TMemoryStream the functions LoadRVFFromStream() and SaveRVFToStream() are used. The disadvantage of the RVT format is that it can be used only by TRichView components. Nevertheless, the TRichView components supper other widespread formats - RTF, HTML, plain text. For example, to read and save RTF files the functions LoadRTF() and SaveRTF() are used; for loading and saving the RTF formatted text in TMemoryStream - LoadRTFFromStream() and SaveRTFToStream(); for reading and saving plain ANSI text (in a file and TMemoryStream) LoadText(), LoadTextFromStream(), SaveText(), SaveTextToStream(); to read and save plain Unicode text (in a file and TMemoryStream) - LoadTextW(), LoadTextFromStreamW(), SaveTextW(), SaveTextToStreamW(); to export to HTML format - SaveHTML(), SaveHTMLToStream(). When saving in these formats, it is possible that not all characteristics of the document will be exported due to lack of correspondence (e.g. Delphi controls cannot be saved). Packages of TRichView and ScaleRichView components are completely sufficient to build a sophisticated text editor resembling in functionality the product MS Word. Together with ScaleRichView freely distributed is a sample project showing a great part of the functionality of the components - ActionTest. It represents quite a rich text editor built from components of the package. It can be used as a full editor of RTF, RVF, plain text files. Developers have the right to enrich it and develop it in a way that best fits their needs. The text editor FED_RTF.exe is developed based on ActionTest (Fig. 16). Its interface is different - the number of command buttons is reduced, Bulgarian language is used for the menus, there is an additional button for adding the displayed document to an ArM archive of reports. 43 Fig. 16 “FED_RTF.exe” – how the program looks A major change is the added possibility of program management by setting parameters at its launch: Command Line: FED_RTF.exe "Filename" "SaveDisabledFlag" "OnCloseAction" "ClipboardFormatID" "ArchFilename" "OperatorName" The parameters are as follows: "Filename" text file; these may be RTF and TXT files; in "Filename" the full name (path+name) is entered. "Filename" indicates the name for the displayed file (content); this name appears in the title of the Editor window; the path in "Filename" defines the directory which is available by default in an attempt to save the file; If no name is assigned (i.e. "Filename" = "."), then the default name is used when you create a new file; "SaveDisabledFlag" defines the manner of displaying the editor: o "SaveDisabledFlag" = "0" – normal display o "SaveDisabledFlag" = "1" – the functions for saving are banned (the save button is missing, the key combination Ctrl+S does not work); "OnCloseAction" determines the behavior of the editor in closing it: 44 o o "OnCloseAction" = "0" – does nothing; "OnCloseAction" = "1" – the editor saves the contents of the file specified by "Filename" (automatically, without asking the user); o "OnCloseAction" = "2" –copies the contents in the Clipboard-a; a special clipboard format is used; it serves to exchange data between applications (point 4); "ClipboardFormatID" – sets the number of the created special clipboard format; its presence defines loading the contents of the Clipboard at the start of the editor; this clipboard format is created by the program calling the editor (this mode is used for exchanging data between programs - a certain program creates the clipboard format, then using this format, it copies the text in the Clipboard and launches the editor that copies the data from the Clipboard and displays them); in the creation of a new user clipboard format Windows assigns it a unique number that is valid until Windows is switched off; with subsequent creation of the format in the same session of Windows with the same name, but by another application, the value remains the same; "ArchFilename" sets the display of the button for saving in the archive. It sets the location of the archive with company reports, which is fed to the format for saving of the archive. The full name (path + name) is entered. "OperatorName" specifies the name of the operator entering the document in the archive. The name is supplied to the save format. The call can be made with a different number of parameters: Launching the program without parameters – the editor opens normally in a mode to create a new file; Launching the program only with the first parameter set ("Filename") - the editor opens the text file specified by "Filename"; Launching the program with the first three parameters set ("Filename", "SaveDisabledFlag" and "OnCloseAction") - the editor opens the text file specified by "Filename" with the corresponding parameters; Launching the program with the first four parameters set ("Filename", "SaveDisabledFlag", "OnCloseAction" and "ClipboardFormatID") - the editor opens in the mode for creating a new file and then it fills with the contents placed in the Clipboard; it is necessary to copy the content to the Clipboard in advance (for example, the program that sends data to the editor); a special clipboard format is used; Launching the program with all six parameters set - depending on the value set for "ClipboardFormatID", the editor either loads a file saved on the disc or loads content from the Clipboard, as in both cases a save button appears to record the edited file in a special ArM archive for reports and statements. This display mode is used in "Complex FOI", version 9, to give the user the ability to create corporate documentary reports. Setting the value for "ArchFilename" causes display of the button for adding the document to the archive. Upon pressing the button, a window appears that shows the hierarchical structure of the company archive with reports and the user can save the document with an appropriate description in the respective group. 45 If "ClipboardFormatID" = "-1", then the editor works in the manner described in point 3) (loading a file saved on the disc). In "ClipboardFormatID" <> "-1", the editor operates in the same manner as in point 4) (loading the content from the Clipboard). The generation of PDF files in displaying the information from the software systems for business management and control can be achieved using Synopse PDF engine3. Synopse PDF engine is a Delphi library for creating PDF documents. It is open-source and is distributed freely. The entire library is encapsulated in one program module - SynPdf.pas. Features of the Synopse PDF engine: Only Delphi code without external dll-s, increasing slightly the size of the executable file; Can be used in Delphi 5 - XE7, for Win32 and Win64 platforms; The full source code is included; Included are most commands for vector graphics, including for text, lines, and curves; The library can handle BMP images and metafiles; Added are metadata, bookmarks, and data for describing the separate parts of the document; Much smaller PDF files are created; Encryption of the PDF content is possible using 40 bit and 128 bit keys; Fast generation of the files with low consumption of memory (tested with several thousand pages); True Type fonts may be embedded; Ability to publish PDF/A-1 backup files; There is good support. 3.2.2 Building a gallery of images and documents One attractive way to display the contents of an archive with large objects is by using a TFrame_PFG_mix gallery (Fig. 17). It represents a frame that is created on a panel in which the content of large objects stored in a chosen database is visualized. The frame automatically adjusts to the size of the panel. It contains two buttons for scrolling forward and backward along the positions in the DB, a button to hide the frame and several images to display the contents of the read large objects. The number of images is specified when creating the gallery. Also the starting position in the database is specified as well as the dimension based on which the search for the next large object is done. The objects along the sought dimension which are located before the set starting position are not shown. Upon reaching the initial and final (after which no more objects exist) position, the corresponding button for scrolling disappears. Double clicking on an image brings up displaying the content of the respective large object. In search of the next large object for display, the algorithm skips the empty positions (does no show positions that cannot be read). The button for hiding the frame may or may not be displayed. 3 http://synopse.info 46 Fig. 17 Form with two different galleries The code for loading the upper gallery is: Arch_data.ArchName := 'D:\Gallery_DB.DAT'; // Opens the archive PFGalery := TFrame_PFG_mix.Create(Self); PFGalery.Parent := self.Gallery_Panel; PFGalery.Name := 'PFG1'; PFGalery.TextEditorFileName := 'D:\FED_RTF.exe'; // Specifies a program for displaying the text files PFGalery.PFGmix_FrameShow_inForm(self, self.Gallery_Panel, Arch_data, Coord_First_MD, 3, 4, true); The execution of the code leads to the appearance of the gallery in the panel Gallery_Panel. The frame of the gallery tries to adjust to the size of the panel. The number of images showing the contents of the archive Arch_data is specified at the call of PFGmix_FrameShow_inForm and in this case equals 4. The gallery displays all the major objects from the archive Arch_data, starting from the object whose metadata is stored in the position with coordinates Coord_First_MD . The search for metadata for the next large object is done through traversal of the 3 coordinate (set by calling PFGmix_FrameShow_inForm). The archive with data for display must be open before calling the procedure to display the gallery PFGmix_FrameShow_inForm. In the lower right corner of the gallery a button for hiding the frame is shown. Upon double click on a displayed large object from the archive depending on the type of the large object, the following happens: On DataType='image' and DataType='image_zip' – metadata are read for the saved image, based on them the coordinates of the image are determined, the image is read from the archive and displayed by the viewer for zoomed viewing of images TPictViewer_Form; On DataType='rtf' and DataType='rtf_zip' – metadata for the RTF text are shown, based on them the coordinates of the document are determined, it is read from the archive and displayed via the text editor FED_RTF.exe; 47 On DataType='link' – In the field Position of the metadata the position is saved of the image that this link represents and which is shown in the gallery itself. The actual location of the object is determined by the field LinkData of the metadata. There are several types of links. The type is determined by the first few characters, recorded in LinkData. When the LinkData string begins with 'L:', then these characters are followed by a URL or a full path to the file from the disk of the computer. A double click on the image from the gallery leads to loading the indicated web page in the browser or opening the specified file with the respective default program. When the LinkData string starts with 'R:' or 'RZ:', then the link points to an RTF text document. The location (coordinates) of the document in the archive are saved after the symbol ':'. A double click on the image from the gallery leads to reading the coordinates of the field LinkData, retrieving the document from the archive and loading it into the text editor FED_RTF.exe. When the string LinkData begins with 'I:' or 'IZ:', then the link points to an image (usually with much greater quality and size compared to the image the location of which was saved in the field Position of the metadata). The coordinates from the field LinkData are read, the image is read from the archive and is displayed by the viewer TPictViewer_Form. When the LinkData string begins with 'E:' or 'EZ:', then the link points to an executable file. The double click on the image from the gallery leads to reading the coordinates of the field LinkData, retrieving the executable file from the archive to the temporary directory, executing the file and subsequently – deleting the executable file from the temporary directory. When the LinkData string begins with 'H:' or 'HZ:', then the link points to an HTML file. A double click on the image from the gallery leads to reading the coordinates of the field LinkData, retrieving the HTML file from the archive of the temporary directory and displaying the file using the default browser. When the LinkData string begins with 'P:' or 'PZ:', then the link points to a PDF file. A double click on the image from the gallery leads to reading the coordinates of the field LinkData, retrieving the PDF file from the archive in the temporary directory and displaying the file using the default program. One example of how the gallery can be used in the implementation of the application software can be seen in Fig. 18. The window workspace shows three galleries that provide the user the ability to open the documentation for use of the software, visit useful sites, view interesting images. 48 Fig. 18 Example for using galleries in application software 3.2.3 Visualizing images Another commonly used type of information when displaying the results is graphical information. It contributes to a more rapid and natural understanding of the resulting trends. Graphical information is much better perceived by people as compared to textual. Also, the images have a much greater information density. These features of graphical information enable the much faster comprehension of large amounts of data, greatly reducing the time required for analysis and decision making. And time is a crucial factor in modern business processes. Therefore the best software systems for business management and control must provide the possibility for displaying the results of the work in graphics. Also, experience shows that customers remain extremely pleased with neat graphical reports. One disadvantage of putting the results in graphic form is the quite large volume of output files. Graphical information is mainly divided into two types - vector graphics and bitmap (raster) graphics. In vector graphics images are described by using mathematical formulas, functions, vectors and other suitable operators. Also, information about lighting, perspective and coverage may be specified. Vector graphics is characterized by the small volume of the output file (but not with complex images). The received image is of high quality at different levels of zoom, since scaling is performed by recalculation of the image displayed on the screen. In vector graphics there is scope for an unlimited number of distortions and transformations - rotation, translation, transformation and others. As a major disadvantage one can point out the impossibility of recreating photorealistic images. Bitmap (raster) graphics is generally a rectangular matrix of pixels (elementary parts of the image), as each pixel in the image corresponds to a numeric value which contains information about the color in it. In order to obtain a higher quality image it is necessary to divide the image into a larger quantity of smaller elements (dots). Bitmap graphics is widespread. For example, it is generated by digital cameras, scanners, editors of raster images. The image displayed on the computer screen represents a bitmap image. Even the editors of vector graphics have export functions in raster format. One advantage of raster graphics is that it 49 allows the creation of virtually any type of images without depending on the complexity. If scaling is not necessary, the speed of processing of complex images is high. Also, bitmap graphics lies at the basis of most input and output devices for graphical information - printers, scanners, monitors, cameras. A major disadvantage of raster graphics is the incapacity for quality image scaling. Furthermore, when saving simple images much larger files are created in comparison with those in vector graphics. There are different file formats for saving graphic information. Widely distributed across the Windows systems is the format BMP (from "bitmap"). It represents a file format for storing bitmap graphics developed by Microsoft around 1986. Files of this type always contain RGB data, as color depth may vary. BMP does not use data compression, so the file sizes are greater than in other bitmap formats. JPEG (from Joint Photographic Experts Group) is another type of bitmap format in which compression of images is performed. It was developed in the late 1980s. The compression is with a loss of data, i.e. it causes a distortion of the image characteristics. The degree of compression (and respectively loss of quality) can be specified. JPEG is more suitable for photos than for images containing large monochrome areas. GIF (from Graphics Interchange Format) is a file format for saving raster graphics distributed widely on the Internet. It is often used for storing the image of a logo or a small animation. The color palette is limited to 256 colors. GIF uses a LZWcompression, enabling the compression of images in which there are many monochrome areas (logos, inscriptions, schemes). PNG (from Portable Network Graphics) is a file format for saving bitmap images which uses a lossless compression based on the Deflate algorithm. It originally was created as a free format to improve and replace the patented GIF format. The color palette is greatly expanded to 16.7 million colors. It supports transparency beneath the objects. PNG is best for small images, such as buttons, icons or thumbnails. Examples of file formats for vector graphics are WMF (from Windows MetaFile) and EMF (from Enhanced MetaFile). These formats are used for storing the images from Microsoft Clip Gallery. The formats were developed by Microsoft and constitute an integral part of Windows, since they store the set of device independent functions of the GDI (Graphical Device Interface) in displaying the image on a particular graphic device (monitor, printer, etc.). In MS Windows saving and reading files from these formats is extremely fast and easy. The formats are supported by many powerful applications (e.g. AutoCAD, OpenOffice.org, Word, PowerPoint). WMF and EMF files contain a list of records, each representing a specific command with a set of parameters. The main differences between the WMF and EMF are: in EMF there are new functions added; in EMF the codes of existing functions are changed in comparison to WMF; the parameters in WMF are 16-bit, while the EMF they are 32-bit; some functions of EMF have new parameters added. The Delphi integrated development environment (IDE) is distributed in a wide range of components, sufficient for the development of different types of applications. One of them is the component for handling images TImage. It has a large range of functionalities and supports a number of file formats. TImage is sufficient to solve the task of visualizing a system-generated graphic report. In this way one can build quality software systems with displaying the results in graphic form without the need to purchase separate specialized components. Another option to create license-free software is by using the library Graphics32. This is a library of components for Delphi, Kylix and Lazarus, designed for fast 32-bit processing and visualization of graphics. Released as an open source library, Graphics32 provides fast image processing – accessing pixels is almost 100 times faster than that in standard TCanvas classes and the drawing of lines is about 2-5 times faster. Another component for visualizing with an open 50 source is TZSImage. It offers additional options for image display – e.g. zooming a portion of the image (the "Magnifying glass" effect), a slideshow of multiple images, editing images. Fig. 19 Image viewer TPictViewer_Form Often when developing the interface of a software system a certain image needs to share the screen with many different fields and controls. But sometimes the end user wants to look at a chart in more detail. To this end, the form TPictViewer_Form was developed. It represents a window for magnified display of images (Fig. 19). With its help one can view different images that occupy a small part of the program interface. For example, the viewer may be displayed when double clicking on the picture of an employee in the window for entering company data, thus allowing detailed examination of the photo. TPictViewer_Form is declared in the programming module PFGallery_PictViewer_U.pas. It represents an ArM form. As a major component for displaying images a modified TZSImage is used (a function is added for loading the image from TMemoryStream - SetImageFromStream ()). The form can display images from different file formats - BMP, JPEG, GIF, PNG, EMF, WMF, ICO. The window consists of a display area of the image (on the right) and a toolbar to manipulate the image (on the left). There is an option to display the image in full screen, while the toolbar is hidden. The toolbar contains a few buttons and sliders with different functions. The “Magnifying glass” button turns on and off the mode for magnifying parts of the image. When the mode is turned on, upon pressing the left mouse button in the image a magnifying glass appears, containing magnification of the portion of the image underneath the lens. In Fig. 19 the lens is shown in the upper right corner. The size of the magnifying glass can be increased and decreased by dragging the slider "Size of the magnifying glass." The coefficient for magnifying the lens is set by dragging the slider "Scale of the magnifying glass". 51 The "Select" button is used to mark a specific part of the image. Thus, the properties of the selected area are determined - the dimensions and coordinates of the encircled rectangle. The properties can be real (i.e. the number of pixels in the image file itself) and visible (i.e. the number of pixels from the screen). The "Full Screen" button (located in the upper right side of the toolbox) is used to display the image in full screen. Doing this, the toolbox and the taskbar of Windows are hidden and the image is stretched to the maximum screen. To exit the full screen display mode, it is necessary to press any key on the keyboard or click with the left mouse button. Also, one can direct the mouse pointer to the top of the screen and click on the displayed button "Exit Full Screen mode". The "Save" button is used to save the image in a special ArM archive with reports. This button is used in Complex FOI, version 9, to give the user the ability to create corporate documentary reports. On pressing the button, a window appears that shows the hierarchical structure of the company archive with reports and the user can save the document with an appropriate description in the group. The "Export" button is used to save the image file. The image can be saved in different file formats - JPEG, BMP, GIF, ICO. By pressing the button, a dialog window to save the image, it can choose the location of the created image file, its name and type. Displaying the viewer is done by initially creating TPictViewer_Form, then loading the image to be displayed and then specifying the required settings of the form, for example: PictViewer_Form := TPictViewer_Form.Create(self); if PictViewer_Form.ZSImage.SetImageFromStream(Image_MemoryStream,Image_Filename) then begin PictViewer_Form.pcolor := self.Color; PictViewer_Form.Btn_Magnifier.Visible := false; PictViewer_Form.Btn_Selection.Visible := false; PictViewer_Form.Btn_FullScreen.Visible := false; PictViewer_Form.ImageFileName := Image_Filename; PictViewer_Form.ColBtn_ExportImage.Visible := true; PictViewer_Form.ReportArch_FileName := ArM_ArchiveFileName; PictViewer_Form.Report_Name := ReportTitle; PictViewer_Form.Operator_Name := Name_Operator; PictViewer_Form.ColBtn_AddToArch.Visible := true; PictViewer_Form.ShowModal; end; PictViewer_Form.Free; SetImageFromStream() is used to load an image. The image must be loaded in advance in TMemoryStream (Image_MemoryStream). Image_Filename is used to determine the file type. Only the file extension is used (for example, only ".bmp" can be used). The function SetImageFromStream() recognizes different file formats - BMP, JPEG, GIF, PNG, EMF, WMF, ICO. PictViewer_Form.pcolor is used to set the color of the form. The buttons Btn_Magnifier ("Lens"), Btn_Selection ("Select"), Btn_FullScreen ("Full Screen") are visible by default, but if necessary they can be hidden. PictViewer_Form.ImageFileName is used to specify the file name in displaying the dialogue for exporting the file. Also based on it, the file type is determined on opening the form for saving the image in the ArM archive with reports (pressing the "Save" button). PictViewer_Form.ReportArch_FileName is used to set the location of the archive for reports in 52 which the image will be saved by pressing the "Save" button. The full name of the archive is entered (file path and file name). The value is supplied to the form for saving the image in the ArM archive upon its display. PictViewer_Form.Report_Name is necessary to specify the name of the report on displaying the form for saving the image in the ArM archive with queries and reports. PictViewer_Form.Operator_Name is used to specify the name of the operator at the display of the form for saving the image in the ArM archive (the name of the operation that introduced the image in the archive is saved). The buttons ColBtn_AddToArch and ColBtn_ExportImage are hidden by default, but if necessary can be displayed. If on displaying the viewer TPictViewer_Form it is specified that all buttons on the toolbox be invisible, then the toolbox is hidden and the field for displaying the image takes up the entire form. 3.2.4 Visualizing charts and graphs A library very suitable for license free generation and visualization of graphs and charts is TeeChart. Its components are distributed together with the Delphi development environment and provide tools for building informative and good-looking charts. In building the interface of software systems for business management and control, often it is necessary that a large part of the screen is occupied with various controls and information fields, while insufficient space is left for locating the graphical report and its size is limited (Fig. 20). That’s why the form TChartViewer_Form is created. It represents a window for magnified display of TChart diagrams (Fig. 21). With its help the chart can be viewed in detail. For example, under standard conditions the chart will occupy only a small part of the interface. But when users want to carefully examine the chart, they click twice on it and it is loaded in the form TChartViewer_Form, which is displayed in full screen. Fig. 20 The chart takes up a small part of the program interface The viewer of TChart charts not only enables their detailed examination, but also gives the end user of the software system the opportunity to adjust the displayed graphics to their needs. 53 TChartViewer_Form form has several controls that are used to fine-tune the displayed image. For example, you can assign different font sizes to different elements of the chart, specify different depth, rotation and size of the chart, determine the type of the chart, and set a different background for the graphics (color, gradient, image). Also, the form allows exporting the diagram in several different graphic formats. In this way the user can use the resulting output data for further processing. Several raster image formats are supported (JPEG, BMP, GIF, ICO) and one vector format - WMF. Fig. 21 Viewer of TChart charts TChartViewer_Form The display of the viewer is done by initially creating TChartViewer_Form. The form contains a TChart component (ChartViewer_Form.Chart), which must be loaded with the sequences of the source chart. Once the sequences are cloned, it is necessary to specify certain settings of the form and it can be displayed. Here is sample code for displaying the viewer (Chart_Reports: TChart;): ChartViewer_Form := TChartViewer_Form.Create(self); ChartViewer_Form.Chart.FreeAllSeries; ChartViewer_Form.Chart.Assign(Chart_Reports); // Copying the properties for i:=0 to Chart_Reports.SeriesCount-1 do // Copying the sequences CloneChartSeries(Chart_Reports[i]).ParentChart := ChartViewer_Form.Chart; ChartViewer_Form.Pcolor := self.Color; ChartViewer_Form.ChartImgFileName := 'Diagram.jpg'; // Specifies the default name for the file upon exporting ChartViewer_Form.ReportArch_FileName := RepArch_FileName; // Specifies the archive for reports where the chart can be saved ChartViewer_Form.Report_Name := Chart_Report_Name; // Specifies the name of the report upon saving the chart in the archive for reports ChartViewer_Form.Operator_Name := OpName; // Specifies the name of the operator in saving the chart in the archive 54 ChartViewer_Form.ShowModal; ChartViewer_Form.Free; 55 4 Integrated Software System. General Functions of Program Modules in Integrated Software Systems In the development of complex software systems a need arises for the implementation of multiple functions and operations of different application areas (e.g. paycheck, accounting, warehousing). Very often some functionalities overlap, but in different contexts. Therefore, a proper hierarchical structure of programming system as a whole should be built to make its usage easy and efficient. The finished product incorporating all the functionality and software modules will be referred to as an integrated software system. An integrated software system consists of several core modules based on their purpose (e.g. paycheck module, accounting module, warehouse management module). Each of the modules includes only those features and operations that are related to the specific application area. Besides the strictly specific functions, each of the modules may include functionality that can be repeated with minor changes also in other modules. These are the so-called general functions. Examples of such common features can be the functions for backup storage and data recovery, functions to copy, move and delete archives with data, functions for updating the programming module. A convenient and very effective approach is to use the same configurable source code files for the implementation of the common functions by the various modules of the system. Thus for the building of a common function in a module of the system it will be sufficient to provide the general programming code and to determine the specific settings for the respective module. For each of the common functions only a single program file will need to be developed. Thus the time required for the development of the integrated programming system is greatly reduced. Furthermore, the likelihood of programming errors is reduced. As a result of this approach, the interface of the system is unified. Thus, the work of the end user is facilitated and the time for training is reduced. In building the interface it is desirable to create a main panel for work with the integrated software system from which one can shift between each of the modules. It will appear at the system startup. An example of a basic starter panel is shown in Fig. 22. By pressing the button in the right side of the window, the user opens the necessary system module: a module for payroll and human resources, a module for service contracts, warehouse module, a module for payment documents, etc. 56 Fig. 22 Example for the main panel for working with an integrated software system We will list several sample implementations of some common features that are found in most integrated software systems. 4.1 Implementation of functions for backup storage and data recovery Fig. 23 shows an indicative interface for performing the functions of backup storage and data recovery. It represents a frame through which users can initiate backup and recovery of data for companies. The data for each of the companies in the system are stored in a separate set of files as there is a separate group of files for each year. In the archiving a backup (archive) copy of these files is created, as it can contain data both about a company and also about all companies introduced into the system both for a specific year and also for the last five years, starting from the current year backwards. 57 a) Archiving b) Recovery c) Sending an email with data Fig. 23 Example frame for backup storage and recovery Repeatedly over time, users need to create backups of data for the companies so that in the event of a system crash the company data could be recovered to the form it had upon creating the archive. It is therefore desirable that they are carried out often enough. Deleting old backups is not desirable, because they can be used in the event of failure of the most recent backup. It is recommended that backups of the archives be kept on separate storage devices other than the working one (e.g. external hard drives, flash drives, optical discs). Four different types of archives can be created. They differ in the scope of data included in them. With the first type the archive includes all data about all companies in the system for both 58 the current year and the preceding four years (a total of 5 years). The second type of archives includes data for all companies in the system, but only for the current year. The third type of archives includes the data about one particular company for the current year and the preceding four years (the last 5 years). The fourth type of archive includes data about a particular company for the current year only. Features for backup storage and data recovery are divided into three groups, visualized by three TTabSheet components as switching between them is carried out by three tabs at the top left corner of the frame. The page "Data backup" (Fig. 23a) is used to create the backup archive. It allows the user to select the company and the time period for which data will be included in the archive. The page "Recovery from backup" (Fig. 23b) serves to restore company data to the state in which they were in a previous point in time. The use of this operation may be caused by failure of one of the files with company data, or for example by introducing on the part of the user of large amounts of incorrect data. The user sets the type of archive (companies and period for which the data relates). Thus the page displays a listing of all archives that meet the search criteria. The user must choose the most relevant one. When choosing an archive, its content is displayed and the user can select a particular file or restore all files from the archive. The page "Send an e-mail with data" (Fig. 23c) allows direct sending of company data via email. The user needs only to specify for which company and what period of time data should be involved in creating an archive and in the next window that appears to compile the letter (the recipient's address, subject, text). This feature is useful when moving the company’s documentation to another computer or if a problem arises with the data that can be solved remotely. 4.2 Implementation of functions for copying, moving, and deleting operating data Each module of the integrated programming system operates with its own data files, but generally the names of various files are formed by the same rules. Thus common functions for copying, moving and deleting data can be realized through a common interface for all modules. An example of this is the frame shown in Fig. 24. In its upper left corner there are buttons for switching between the functions copy, move and delete. a) Local –> Local б)Local –> FTP 59 в) FTP –> Local г) FTP –> FTP Fig. 24 Frame for copying, moving and deleting of company data (4 versions of copying are shown) The "Copy" page is used to copy data for companies. The data for each of the companies in the system is stored in a separate set of files as there is a separate group of files for each year. Through the 'Copy' operation, data about a particular company can be copied to another folder, while the original data will remain in place. It is also possible to change the company the corresponding company (the name of each file includes the number under which the company is entered in the system). Depending on the physical location of the files, the page has four different views: 1) Copy from a local folder to another local folder – the company data are in a folder that is located on the computer used or on a local network; copied files will also be located in a local folder (Fig. 24a). 2) Copy from a local folder to a folder located on a remote FTP server - the company data are in local folder; copied files will be located on an FTP server, the access to which is provided over the Internet (Fig. 24b). 3) Copy from an FTP folder to a local folder – the company data is located on a remote FTP server; copied files will be placed in a local folder (Fig. 24c). 4) Copy from a FTP folder to another FTP folder – the company data are located on a remote FTP server; copied files can be placed in the same folder on the same FTP server or any other FTP server (Fig. 24d). To copy the data, the user must choose the company to which the data relates, the year, the place where the copied data must be located (there is a choice of both a local folder and a remote FTP folder). The copied data can be added as a new company (by checking the box "Reflect the operation in the list of companies"). Also in copying the data the number of the company in file names can be changed. The "Move" page is used to move the company data and to change the numbers of the companies in the system (Fig. 25). Through the operation "Move", the data about a specific company can be moved to another folder. It is also possible to change the company the corresponding number of the company (the name of each file includes the number under which the company is entered in the system). As with the "Copy" page, also here there are four possible different views depending on the physical location of the files. 60 Fig 25 “Move” page (visible is only the view when moving from one local folder to another) For the realization of the transfer of data, the user must select the company the data refers to, the year, and the location for the data after moving (there is a choice from both a local folder and a remote FTP folder). In moving the data, also the number of the company in the file names can be changed. The "Delete" page is used to delete the data of companies (Fig. 26). Through the operation "Delete" one can delete the data about any given year and for all years in the period from 2000 to the year current now for the system. Depending on the physical location of the files for the selected company, the page is displayed in two ways - 1) for deleting data from the local folder (the data is in a folder that is located on the computer or local network) and 2) for deleting data from an FTP folder (the data is located on a remote FTP server, the access to which is provided through the Internet). In order to erase the data about a company, the user must simply select the appropriate company from the list of companies available in the system, to select the year the data refers to and press the "Delete" button. 61 Fig. 26 “Delete” page (visible is only the view when deleting data from a local folder) 4.3 Implementation of functions for specifying the system settings Each module of the integrated software system has a set of identical settings, which repeat at each of the modules. These include settings for the monitor mechanism Smart Monitor, system parameters for the standard location of the operating data, the number of fractional digits when rounding, adjustments to the design of the windows. It is convenient to use a uniform interface for their setting. An example of this is given in Fig. 27. a) 62 b) c) Fig. 27 Frame for specifying system settings The frame for specifying the system settings consists of three pages, as switching between them is done through the tabs at the top left corner. The "System Settings" page is used to specify the settings for the mechanism Smart Monitor – the working resolution of the image displayed on the screen. The "System parameters" page serves to indicate the system directories where the user data will be stored. Also via this page one specifies the number of digits after the decimal point to be used in rounding totals. The "Screen design" page presents to the user the functions for configuring the module interface. The user can set the default color palette of the windows, as they can either choose one of the three recommended colors or mix their own color. Also, the user can specify their preferred colors also for the other additional windows of the system module. 4.4 Implementation of functions for updating the system modules Over time, each integrated software system for business management loses its relevance and should be updated. This is necessary because of the dynamic changes that occur in the economy and because of the constantly changing regulatory framework. Updating the system, the end user receives a product meeting the latest requirements as in addition to this they obtain advanced functionality and improved stability because of bug fixes. 63 The need to update the various modules of the system arises at different points in time. The complete system update takes considerable time, and in the eventual collapse during update, the recovery of a single module is significantly easier. Therefore, it is desirable that each of the modules have their own functions for update, as they can be implemented through a uniform interface. An example of this is given in Fig. 28. a) Page "Program update" b) Page "Historical notes" Fig. 28 Frame for updating the system module The frame is very easy to use. It consists of two pages - "Program update" and "Historical Notes". Upon the initial display of the frame, the program connects to the Internet server of the product developer and checks for any new versions. The page "Program update" appears, in which the current version and the latest available version are inscribed. In need of updating, the user is prompted through the display of a relevant text written in red to attract attention. All he needs to do to start the update is to press the button "Upgrade to the latest version." The program automatically connects to the server, downloads the necessary files and installs them. For cases where there is no Internet connection, there is an opportunity for updating a special file, which the user can supply to the computer, for example by using a flash drive. The "History Notes" page provides information about the updates of the system module, as well as updates available to install from the Internet. It consists of two tables - "Updates made" and "Updates available on the Internet." The table "Installed updates" shows the data for all updates made to date. After each installation of a new version, the data in the table is updated. In 64 the first column of the table the version of the update made is recorded, in the second column the date on which the update was installed, in the third column - the time of installation and in the fourth - the operator who carried out the program update. The table "Available updates on the Internet" lists all updates available on the server. With its help one can trace the history of changes taking place in the program. In the left column of the table the version of the update is recorded and in the right column a short commentary of the version is provided. 4.5 Implementation of functions for working with nomenclatures Nomenclatures are lists for systematization of a certain type of objects (elements). The objects can be of different types - goods, suppliers, customers, employees, professions and occupations, economic activities, etc. Each of the elements in the nomenclature has a unique number (ID), based on which it is unambiguously identified. All identifiers consist of the same number of digits. For each of the elements there are one or several characteristics describing the element. Integrated software systems for business management use many different types of nomenclatures. Working with them is uniform - creation of the nomenclature, addition of elements, editing and viewing of the data for an item. The search is carried out mainly based on the identification number of the element. The difference between the various nomenclatures consists only in the data that is recorded. Therefore, when working with nomenclatures it is convenient to use the same programming interface in each of the modules. An example of this is the frame shown in Fig. 29. a) Page "Initialization of a nomenclature" 65 b) Page "Entering/editing" Fig. 29 Frame for operating with nomenclatures The frame is divided into two areas of work - 1) to the left are listed all nomenclatures that are recorded in this ArM archive and 2) to the right is the area for editing the nomenclature selected in the left list. The user creates a new nomenclature by entering in the desired position on the left a name for the created nomenclature by pressing twice against the corresponding name in the column "Edit". By doing this, a page "Initialization of the nomenclature" opens in the section for editing the nomenclature (Fig. 29a). The user specifies the characteristics that describe the elements in the created nomenclature and presses on the button "Save changes in the structure of the nomenclature." This opens the page "Enter/Edit nomenclature" (Fig. 29b). The user can now introduce new elements. When introducing a new element, initially an identification number is specified, and the remaining characteristics of the element are entered. The frame for working with nomenclatures allows the user to create and delete nomenclatures. When considering a specific nomenclature, the user can edit the structure of the nomenclature - the number and type of characteristics that describe the entries in the nomenclature. Also through this frame the user can introduce new elements in the nomenclature, to edit the characteristics of pre-recorded elements and delete unnecessary items. 66 5 Tools Assisting the Operation and Settings of Integrated Software Systems Integrated software systems for business management and control have a complex structure. They have to perform different functions, as often the functions are identical in the different modules of the system. It is therefore appropriate to develop separate software tools to solve different uniform problems. For example, each module can use ArM archives for storage of data. Thus, the same tools can be used in each of the modules. Furthermore, for the realization of part of the standard functions it is necessary to use products from third-party developers. For example, for an ordinary backup of a group of files it is necessary to have an installed archiver. The availability of the company’s proprietary tools to perform these functions ensures the independence of the software system from third-party software. For facilitating the operation and settings of integrated software systems several useful software tools are developed. All tools can be accessed by the developed application systems. Some of the tools use initial parameters to customize the user interface. For work with ArM archives, the programs Arm_BO_Wrk.exe and Arm_Profilaktika.exe have been developed. Compression and decompression of files is done with the help of programs and CreateZipArchiveProject.exe and UnZipArchiveProject.exe. The tool FSendEMail.exe is used to send emails directly from the software system. The programs CreateSelfExtractingFileProject.exe, SelfStub.exe and MakeSelfExtProject.exe are used to create self-extracting files suitable for use as autonomous software installers. As an example of an installer suitable for internet distribution of the software the installer FOI_Installer.exe is presented. 5.1 Tool for creating and editing ArM archives containing large objects For the convenience of working with multi-dimensional archives containing large objects, the tool Arm_BO_Wrk.exe is created. The program is used to create and edit ArM archives of this type. It allows adding new data, reading the existing data, editing, deleting and exporting data from the database. Fig. 30 shows a program window with a loaded company archive which contains templates of text documents. The large object read from the archive represents an RTF file which has been compressed before saving. 67 Fig. 30 View of the program Arm_BO_Wrk.exe A large object usually represents a file saved in the ArM database. This could be an image, an RTF file or another type of file for which the database stores both the file content itself as well as metadata about it (file name, description, type, location of the file in the archive). In saving a large object (e.g. RTF file or JPEG image) in the ArM archive two objects with different coordinates are saved in the archive: 1) The first contains the data itself, which can be compressed by Zip; 2) The second contains metadata for the large object (including the coordinates of the first object). Selecting an archive In order to start work, the respective ArM archive needs to be selected. Through the Select button in the upper left corner of the window, the file can be contacted among the files on the computer. To create a new archive it is necessary to insert an arbitrary new name in the field Path and name of the DB. Once the name of the archive is set, it is necessary to press Open database button. This opens an existing archive or creates a new one. 68 Selecting a file to add to the archive To activate the right side of the window (for working with database) the associated archive has to be selected and opened and also a file to add to the archive has to be selected. Choosing a file goes through Select button until the field Load from file. Adding a large object to the ArM archive For adding a new large object is required to meet the following conditions: An archive is selected and opened; In the left pane is for adding data (selected file is opened or previously existing large object read from the archive and has shown an image or RTF file) In the text boxes at the upper right-hand side of the window the metadata for large objects are entered; At the bottom right of the window the positions are selected in which the file contents and relevant metadata should be saved. Once these conditions are met it is necessary to press Save to Database Button. This saves the file and the about it in two different positions in the ArM archive. The content of the file is stored in the database in the position specified in the panel Location of the file in the DB. The content itself is derived either from the displayed image or an RTF file on the left side of the screen, or from the file referred to in the Load from file (when its content cannot be shown on the left). When saving the file to the database, its content can be further compressed. The compression is set by the value in the field DataType:. For compressing the file it is necessary that this value ends in "_zip", e.g. "image_zip". The metadata for the file saved in the archive is a record of type TBigObjectMetaData (declared in Arm_BO.pas). They describe the saved file and are used when reading (for example, based on them one determines the file type and its location in the archive). The metadata is saved in the archive in the position whose coordinates are set in the panel Location of metadata in the database. Description of the fields: FileName – sets a name to the file added to the database; used for example to determine the type of file in displaying an image (by the extension - JPEG, BMP, PNG); DataType – sets the type of the large object; used in reading data; determines whether the file is compressed (with compressed files the entered string ends in "_zip"); accepts values: o image – the saved file is an image; o rtf – the saved file is an RTF text file; o link – this type is used for example in the creation of galleries (the frame TFrame_PFG_mix); with it metadata describe a reference to an Internet resource (URL), a file from the disk space on your computer or an object from the DB; in the selected item in the panel Location of the file in the DB an image is saved that 69 describes the link (e.g. a screenshot of the web page, a small image corresponding to a larger one); in the box LinkData the specific path of the link is specified; o image_zip, rtf_zip, link_zip – the file located in the position specified in the panel Location of the file in the DB is compressed; "LinkData" –it is used for large objects of the type "link"; sets a path for the link; can point to an Internet resource (URL), a file from the disk space on your computer or an object from DB; the reference type is determined by the first few characters: o "L:<link>" – sets a reference to an Internet resource or file from your computer; in place of "<link>" the URL of the website or the full name of a file located on a disk on your compute is saved; used to open web pages or to open/launch local files (these may also be software programs, for example. "L: calc.exe"); o "R:<coords>" –sets a reference to an RTF file located in the DB; in place of "<coords>" the coordinates of the position in which the corresponding RTF file is stored are saved; the position coordinates are saved immediately after the ":" as between the separate coordinates "," (comma) is placed without spaces; the dimensionality of the dimension is determined automatically based on the set number of coordinates; o "I:<coords>" – sets a reference to an image located in the DB; in place of "<coords>" the coordinates of the position in which the respective image is stored are saved; the position coordinates are recorded immediately after the ":" as between the individual coordinates "," (comma) is placed without spaces; the dimensionality of the dimension is determined automatically based on the set number of coordinates; the type of the file of the image saved in the position <coords> must match the type of image that describes the link (as the type is determined by the extension of the name saved in the field "File name:"); o "E:<coords>" – sets a reference to the executable file located in the DB; in place of "<coords>" the coordinates of the position in which the corresponding executable file is stored are saved; the position coordinates are recorded immediately after the ":" as between the separate coordinates "," (comma) without spaces is placed; the dimensionality of the dimension is determined automatically based on the set number of coordinates; o "H:<coords>" – sets a reference to an HTML file located in the database; in place of "<coords>" the coordinates of the position in which the corresponding HTML file is stored are saved; position coordinates are recorded immediately after the ":" as "," (comma) is placed between the coordinates without spaces; the dimensionality of the dimension is determined automatically based on a set number of coordinates; o "P:<coords>" – sets a reference to a PDF file located in the database; in place of "<coords>" the coordinates of the position in which the corresponding PDF file is stored; the position coordinates are saved immediately after ":", as between the individual coordinates "," (comma) is placed without intervals; the dimensionality of the dimension is determined automatically based on the set number of coordinates. When the link points to a file located in the DB, adding the symbol "Z" before ":" indicates that the file is compressed. For example, if "LinkData" has "IZ: 1,2,3", it means that in the position with coordinates [1,2,3] from the 3-dimensional space there is a compressed image file. "Keywords:" - keywords are specified for the saved large object; 70 "Short text" - sets a short description of the large object; "Text" - sets a more detailed description of the large object. Adding a large object of the type "link" to a file saved in the DB In this case three positions in the database need to be saved - one for metadata, one for the descriptive image and one for the actual file. This is done in two steps, by using the box "Save/Delete/Export the file only": 1). Unchecking the box "Save/delete/export the file only"; 2). Loading an image that describes the file saved in the DB. If both files are images (e.g, one with lower resolution, and the other - a higher resolution), they must be of the same type (JPEG, BMP, PNG), as the type of the image is determined only by the field "File name"; 3). In the "DataType" field, "link" or "link_zip" is set (under "link_zip" the descriptive representation is further compressed); 4). In the "LinkData" field, the type of the file indicated in the link is set ("R:", "RZ:", "I:", "IZ:", "E:", "EZ:", "H:", " HZ: "," P: "," PZ: "; depending on the file type and on whether to be compressed) and its coordinates in the database (separated by commas); 5). Additional metadata is specified; 6). In the panel "Location of the metadata in the database" the coordinates of the position where the metadata will be saved is specified; 7). In the panel "Location of the file in the DB" the coordinates are specified of the position where the descriptive image will be saved; 8). The button "Save to DB" is pessed. This saves the metadata and the descriptive image; 9). Checking the box "Save/Delete /Export the file only "; 10). Through the "Select" button next to the text field "Load from file:" in the left side of the window the file that will be stored in the database and to which the link will point is selected; 11). In the panel "Location of the file in the DB" the position coordinates in which the selected file will be saved are specified. They must match the coordinates entered in step 4 in the field "LinkData"; 12). The button "Save to DB" is pressed. Thus only one object is added to the database the file with the actual image. The data for the file are further compressed if "LinkData" has a "Z" before ":". Reading a large object from the DB The search for a large object is done by reading the metadata about it. In the panel "Location of the metadata in the DB" the position for the sought metadata is chosen and the button "Read from the DB (based on the metadata)" is pressed. When changing the value in any of the coordinates, verification is made whether data is available in that position and if any data is found - then at the bottom of the panel an inscription appears "Data exists in the selected position!" (as this data may not necessarily be metadata for a large object). Pressing the button "Read from database (based on metadata)" leads to reading the data in the position specified by the panel "Location of the metadata in the database". If this is indeed 71 metadata, it is displayed in the right pane. Then an attempt is made in the left pane to display the file located in the position indicated in the field "Position" of the loaded metadata (the large object itself). The relevant RTF file is displayed, as well as an image or a descriptive image (when the large object is of the type "link"). Thus, the loaded large object (RTF file, image) can be used for subsequent saving in the DB (such as copying or editing a large object). Editing a large object in the database Initially through the button "Read from database (based on the metadata)" the desired large object should be read (see above). Then its data needs to be edited (changing the metadata in the right pane, choosing a new file in the left pane). Finally, it is necessary to press the button "Save to DB". This leads to saving the changes in the DB. Exporting a file from the DB Exporting a file using its metadata - in this case the metadata from the position specified in the panel "Location of the metadata in the DB" is read and the file is exported from the position indicated in the field "Position" of the read metadata. The procedure for exporting the file is as follows: 1). In the panel "Location of the metadata in the DB" the position of the metadata for the respective large object is selected; 2). The button "Export a file" is pressed; 3). In the window that appears for saving the file (Fig. 31) a directory is selected, where the exported file will be saved and its name will be specified (the name of the metadata is suggested by default); 4). The button "Save" is pressed, via which the file is read from the position specified in the metadata and is stored in the indicated place. Determining whether the file is compressed is done based on the contents of the field "DataType" of the metadata. 72 Fig. 31 Window for saving the exported file Exporting the actual file given a large object of the type "link" to a file saved in the DB – in the cases where there is a large object of the type "link" to a file saved in the database, exporting the actual file that is specified by the link in the field "LinkData" (e.g. large image) is performed as follows: 1). The position in which the actual file is located is determined (for example by reading the large object and examining the field "LinkData" - see above); 2). The box "Save/Delete/Export the file only" is checked; 3). In the panel "Location of the file in the DB" the position of the file specified in paragraph 1 is entered; 4). The button "Export to a file" is pressed; 5). In the window that appears to save the file (Fig. 31) a directory is selected where the exported file will be saved and its name will be specified (an extension should be selected corresponding to the type of the file saved in the DB; the type can be determined based on the content of the field "LinkData"); 6). The button "Save" is pressed, by which the file is read from the position specified in the panel "Location of the file in the DB" and is saved in the indicated place. Determining whether the file is compressed is carried out based on the contents of the field "LinkData" in the right side of the window (if before ":" the symbol "Z" is located, then the file is compressed). Deleting a large object from the DB In the panel "Location of the metadata in the DB" the position for the metadata for the deleted large object is selected. The button "Delete" is pressed. A dialog box appears for 73 confirmation (Fig. 32a). The button "Yes" is pressed. This erases the position of the metadata and the position in which the relevant metadata file is located (its position is defined by the metadata). а) б) Fig. 32a Window for confirming the deletion When a large object of the type "link" to a file saved in the database needs to be deleted, it is necessary to further delete also the actual file. For this purpose the box "Save/Delete/Export the file only" needs to be checked, the position of the file needs to be specified in the panel "Location of the file in the DB" and the Delete button to be pressed. This calls a dialog box for confirmation (Fig. 32b). The "Yes" button needs to be pressed. This deletes only the position referred to in the panel "Location of the file in the database". Editing an open RTF file When the left side of the window shows an RTF file (extracted from the database or loaded from a file located on the disc), its contents can be further edited. For this purpose the location has to be indicated in advance of the RTF editor which will be used to edit the content (i.e. the location of "FED_RTF.exe"). This is done by pressing the "Select" button in the lower left corner of the window. A dialog box appears, from which the executable file of the editor must be found and selected. The path to the selected RTF editor is written under the panel displaying the RTF file. For editing an RTF file shown in the left side of the window, it is necessary to press twice with the left mouse button on the text. This launches the preset text editor with which the necessary changes can be made. After completion of the editing, the editor simply has to be closed, by which the edited text is loaded in the RTF box in the left side of the window "Arm_BO_Wrk.exe". Upon further pressing of the button "Save to DB", the text is taken from precisely this field and saved to the database (already edited). 5.2 Tool for maintenance of ArM archives As a result of the extensive work in ArM archives, unnecessary data can accumulate and empty areas can be created. This leads to an increase in the volume of the respective archive. For the purpose of cleaning up these areas and consequently of reducing the volume of ArM records, the tool Arm_Profilaktika.exe has been developed (Fig. 33). 74 Fig. 33 View of the program Arm_Profilaktika.exe Working with the program is quite easy - the user simply has to specify the archive which needs maintenance and to start the process by pressing the button "Start maintenance". The program reads the content from the archive and saves the data from scratch in a new backup by restoring the structure. Finally the updated archive replaces the original file, as the user has the opportunity to choose whether to keep the old one for backup or delete it. The tool also has a second function – reviewing the location of the data in the archive (Fig. 34). By using this tool, the coordinates of all objects stored in the archive can be determined. Statistics is obtained on the distribution of objects by spaces and on the total number of objects and used spaces. The size of each saved object can be determined. Fig. 34 Reviewing the statistics of the archive 75 The operation of the program may be adjusted additionally by setting additional parameters at its launch: Command Line: Arm_Profilaktika.exe "ArchName" "DelSource_Flag" "ManualStart_Flag" The first parameter "ArchName" sets the name and path to the archive of which maintenance has to be made. If the first parameter is preset, the program starts with an already specified archive for processing as the user does not need to specify its location. The parameter "DelSource_Flag" represents a flag specifying whether the initial archive should be deleted after completing the maintenance. If "DelSource_Flag" is set to 1, then after the completion of the prophylaxis the old archive will be sent to the recycle bin (the same behavior as with checking the box "Delete the source file"). The parameter "ManualStart_Flag" represents a flag specifying whether the user should launch the maintenance or it can be done automatically. If "ManualStart_Flag" is set to 1, then in displaying the program window it will wait for the user to press the button "Start maintenance" in order to start the maintenance of the specified archive. With a value set other than 1, in showing the program window it automatically starts the maintenance of the archive specified via the first parameter "ArchName" without waiting for confirmation from the user. The presence of these input parameters contributes to the flexible use of the tool for embedding it in integrated software systems. 5.3 Tool for emailing Sometimes in the course of work the need arises to send emails (e.g. sending a document for consultation or a report). The number of letters can be significant. In such a situation it is convenient that the integrated system for management and control has an implemented mechanism for quick and easy emailing of the necessary data. For this purpose the tool FSendEMail.exe has been developed (Fig. 35). The program is used for sending emails with attachments directly from the integrated software system The e-mails are sent through an existing mailbox using the SMTP protocol. Therefore, it is necessary that the data for connection to the mailbox is entered (and respectively to have a preliminarily created account on a postal site, e.g. www.mail.bg or www.abv.bg). The history of sent letters can be seen on the site of the selected mail (but not always, it depends on the settings). The data needed for connecting with the existing mailbox are: host of the mailbox, port, user name (e.g. "[email protected]"), password and an SSL version for encrypting the connection. This data can be found in the settings of the respective mailboxes. It is fed to FSendEMail.exe through the command line parameters when starting the program: Command Line: FSendEMail.exe "Host" "Port" "Username" "Pass" "SSLMethod" "AttachedFile" The parameter "SSLMethod" takes the values: "SSLV2", "SSLV23", "SSLV3", "TLSV1", "0" (when no data is entered). For the parameter "AttachedFile" the full name of the file to be 76 attached to the letter is specified. Thus the file necessary for sending can be set automatically by the program. Fig. 35 View of the program FSendEMail.exe Working with the program is extremely easy. The end user must enter the recipient's address in the box "Recipient Address:", and they can select it from the drop-down list right of the field, which lists recent addresses of recipients. They also need to enter the topic of the letter in the box "Subject:" and the contents of the letter itself in the box "Text of the letter". All attachments to the letter are listed in the box "Attached files". The user can add a new file to the letter by clicking on the button "Attach more files". This opens a dialog box for opening a file in which the user can select any file from the disk space. Sending a letter is done by pressing the button "Send letter". Information about the process of sending is displayed in the text box below the button. It displays a message also if a problem arises (e.g. incorrectly entered data connected to the mailbox - username, password). Upon successful submission of the letter the box displays the message "The letter was sent". 5.4 Tool for file compression One of the common tasks when working with data is to create archives of backup files. In archiving the overall amount of files reduces and therefore compressed archives are useful for the exchange of files, for example via e-mail. This determines the need for software tools that work with archives. For this purpose the tool CreateZipArchiveProject.exe has been developed (Fig. 36). It is used to create ZIP archives. The program allows adding to the created archive both individual files as well as entire directories (these directories and their entire contents are added to the archive). 77 Fig. 36 View of the program CreateZipArchiveProject.exe The way the program operates is as follows: initially the user specifies which files and directories will be included in the archive. This is done by using the "Add file" and "Add directory" buttons. Pressing the button "Add File" a dialog box appears for selecting a file from the disk space on your computer. By pressing the button for opening, the file name is added to the list with the contents of the created archive. The selected file will be added to the top level of the archive. Pressing the button "Add directory" a dialog box opens for selecting a folder. After confirming the selection of the folder, the selected folder also appears in the list with the contents of the created archive. The specified directory will also be located in the upper level of the archive as its original structure will be preserved. When you add a file to the list of the contents, it is denoted by "file:". The directories are denoted with the string "dir:". Once the content of the created archive is specified, the button "Create" must be pressed. This leads to displaying a dialog box for saving the archive, where the directory in which the archive and its name should be saved must be specified. The creation of the archive is started by pressing the Save button. When the archive is created, a message appears to complete the process. 5.5 Tool for file decompression Another tool for operating with ZIP archives is the program UnZipArchiveProject.exe (Fig. 37). It is used to decompress archives. It allows extracting individual files or the entire contents of the archive. While decompressing, it is possible to preserve the paths from the archive (the necessary subdirectories are created in the recipient directory) and also to ignore the paths (all files from the archive regardless of the directory structure of the archive are placed in the specified recipient directory without creating new subfolders). 78 Fig. 37 View of the program UnZipArchiveProject.exe The manner of operating with the tool is as follows: first a file to uncompress needs to be selected. This is done by clicking on the button "Browse..." at the top of the window. Upon pressing it, a dialog box appears for selecting a file from the disk space on your computer. Navigation is done to the desired archive and the Open button is pressed. Thus, the contents of the archive are displayed in the list below the button. The list lists all files from the archive. The location of the files in the archive tree is given in the column "Path". In the other columns of the list additional features are given for the files such as size and date of last modification. When extracting, only those files that are marked in the list of contents will be decompressed. Originally all files are marked (via a default check of the box "Extract all files"). In order to extract not all files from the archive, but only some of them, the box "Extract all files" should be unchecked. Then in the list of the contents of the archive those files that need to be decompressed must be checked. Once all files for decompression are indicated, a directory must be selected where these files will be copied. This is done by clicking on the "Browse..." button located to the right of the box for the recipient directory. Pressing the button displays a dialog box for selecting the directory. Launching the process of extracting these files is done by pressing the button "Extract files". When the extracting is done, a message for completion appears. Often archives have a tree structure (the files in the archive are located in different directories and subdirectories). When decompressing such an archive, it is possible to preserve its structure (automatically the appropriate directories are created and files are put in them) or to ignore this structure and unzip all files in the specified directory. The checkbox "Save paths to the archive" is used to switch between the two modes. When it is checked, the structure of the archive is recreated and the selected files are placed in the appropriate directories. When it is not checked, all files in the archive are placed in one directory. CAUTION! If the archive contains files with the same name but located in different directories, then in the decompression mode without keeping the paths only one of these files will be extracted. 79 5.6 Tools for creating self-extracting archives A self-extracting archive is a combination of a ZIP archive and small software for extracting archives (STUB file) combined in a single executable file. When starting an executable file, the STUB file is executed, as it unpacks data from the archive. This eliminates the need to install extracting software. Self-extracting archives can be used for creating installers of integrated software systems. One of the tools developed to create self-extracting files is the program CreateSelfExtractingFileProject.exe (Fig. 38). It allows adding both individual files and entire directories to the created self-extracting archives (these directories and all their contents are added to the archive). For the creation of the archives it is necessary to indicate a preliminarily created STUB file. Fig. 38 View of the program CreateSelfExtractingFileProject.exe The way of operating with the program is the following: first one needs to select all files and directories to be included in the self-extracting file. To add a new file to be included to the created archive, the button "Add File" must be pressed and then the required file from the appearing dialog box must be selected. As a result, the selected file appears in the list under the "Add file" button. To add a new directory to the archive, you must press the button "Add Directory". In the appearing dialog box the desired directory is selected and the button "OK" is pressed. This directory is added to the list of contents. The content of the created self-extracting file is displayed in the text box below the add buttons. The newly created archive of the upper level will contain all indicated files and directories as the directories will retain their original structure. In the list of content the files are identified by the string "file:", and the directories are marked with "dir:". Once all the necessary files and directories are selected, a STUB file should be chosen that will carry out the decompression. For this purpose one should press the button "Browse ..." and 80 select the appropriate previously created STUB file. The STUB file is an application for extracting. It is implemented at the start of the created self-extracting file. Besides extracting files, the STUB application can be used for creating shortcuts to files from the archive to the desktop, as well as for adding entries to the REGISTRY. The checkbox "Delete temporary ZIP file" is used to indicate whether the ZIP file created together with the self-extracting file after the file creation process is complete should be deleted. The temporary ZIP file is created in the same directory where the self-extracting file is created. This ZIP file can be used to review the structure of the created self-extracting file. Once the files and directories composing the archive are specified and the developed STUB file is selected, one must press the button "Create". This opens a dialog box to save the file in which you can choose the place and the name of the created self-extracting file. Pressing the "Save" button starts the process of creating a self-extracting file. Information on its performance is displayed in the field above the "Create" button and in the fleeing indicators. After the file is created the appropriate message is displayed. One example of an STUB file that can be used in creating a self-extracting archive is the SelfStub.exe program (Fig. 39). It represents a simple program installer. It provides the user the capability to choose the directory in which to install the files from the archive. It also allows the addition of a shortcut to the program on the Desktop. Fig. 39 View of the program SelfStub.exe Another tool for creating self-extracting files is the program MakeSelfExtProject.exe (Fig. 40). It does not specify individual files and directories, but directly points to an already created archive. The user sets the archive, the STUB file and presses the button "Create a self-extracting file". A dialog box appears for saving a file. The user sets the folder in which the self-extracting file should be created, specifies its name and presses the Save button. This puts the start to the unification of the two files and creating the self-extracting file. 81 Fig. 40 View of the program MakeSelfExtProject.exe 5.7 Installer One of the main components of any integrated software system is the installer of the system. It should provide an easy and complete process of installing the product on the computer of the end user. When creating the installer one can use third-party products (such as InstallShield, InstallAware). However, this imposes some inconvenience - additional investment to purchase the product, lack of the necessary functionality, a rather complicated setup. Another approach is the proprietary development of an installer. It can quickly and easily perform the functions required in the installation process. Fig. 41 as an example of such self-developed installer shows the installer of the system "Complex FOI" - FOI_Installer.exe. The developed installer provides a quick, easy and intuitive installation of the system. To install the entire program complex, it is sufficient for the user to perform the following steps: 1) specify the directory where to install the files in the complex (by pressing the button "Browse ..." and choosing a directory in the dialog box that appears) 2) enter the data for connecting with the client, 3) choose whether to add a shortcut to the program on the Desktop (by checking "Display an icon for the program on the monitor screen") and 4) press the "Install" button. Thus the full installation of the software can be made also by end users without in-depth knowledge of computer technology. 82 Fig. 41 Window of the installer FOI_Installer.exe For the operation of the installer it is necessary to have an Internet connection as the installer does not contain within itself the files of the software product and upon installment it downloads the files in a ZIP archive from the web server of the manufacturer. This results in an installation file of a small size. The small size of the installer allows easy download from the website of the product and the rapid start of the installation, which contributes to creating a good impression of the product in the user. The installer has a few extra features. For example, when installing the product every user must enter contact details to be sent to the developer. This data is used to communicate with customers in case of difficulties and problems with the program. There is an option for specifying the created structure of directories for locating the files of the system. At the request of the user, the installer can display a link to the main executable file of the system on the Desktop. Also the installation process itself allows the use of a single installer to install different versions of the product, thereby eliminating the need for processing the installer at launching a new update of the system. It is simply necessary to create a new ZIP archive with the new files of the system and upload it on the server for download. The structure of the installer generally allows the quick and easy development of new installers for other software systems on its basis. 83 6 ArMSBuilder Ver. 1.03 – Developer’s Guide The technology for building complex software systems ArMSBuilder Ver. 1.03 was implemented in the programming language Object Pascal of the programming environment Delphi 2007 of CodeGear (Embarcadero). All examples and all source code texts are written in Object Pascal. The terms of the text are used in the sense of Delphi 2007 or CodeGear RAD Studio and will not be explained here. This manual is not a guide to programming in Delphi 2007. In order to understand the texts and examples, basic knowledge in Object Pascal and Delphi 2007 is required. 6.1.1.1 Creating an ArM form An ArM form (TArmForm) is a successor to the standard class TForm (Fig. 42). It has a number of improvements compared to its parent class. For example, the ArM form has improved behavior in displaying in the cases when in the system settings of Windows enlarged display has been selected (more than 96 points per inch). Also, the ArM form allows easier handling of the other ArM components. The semaphore in the lower left part of the status bar contributes to a safer entry of data in the forms. All ArM components for data input from the keyboard depend on the semaphore. Each new data entry can only start after pressing the "Enter" key or after a double click with the left mouse button on the component. By this, the semaphore switches from green to red, requiring from the user additional attention. The need to make additional arrangements to start editing of the data reduces the likelihood of unintentional mistakes. Fig. 42 ArM form with a Button component on it To create a new ArM form, first it is necessary to create a new simple form to the opened project. This can be done for example by pressing in Project Manager with a right-click on the project name and selecting "Add New->Form" in the shortcut menu that appears in the field. Then 84 the new form should be re-declared as an ArM form. To this end, it is necessary to change the class of the form to TArmForm in the upper part of the programming code of the form, e.g.: type TNewForm = class(TForm) => type TNewForm = class(TArmForm) Once the form is pre-declared, it is necessary to replace the standard frame of the window with an ArM frame. In the Object Inspector, the property BorderStyle of the form of bsNone needs to be changed. Then in the event handler OnShow of the form, the method RefillHeader() must be called, which re-writes the header row of the window, e.g.: Self.RefillHeader('NewForm', 10, clWhite, nil, clBlue, true, true, true, true, true); In order to add to the bottom of the window the status line, it is necessary to add in the event handler OnShow of the form: Self.StatusLine.Visible := true; The design process of the form continues as in any ordinary form - by placing the form on the necessary visual and non-visual components and their adjustment. Sometimes it is necessary to forcibly update the content displayed on the screen of the ArM form. This is done by setting the value true of the property of the form ArmRefresh. A good practice is to carry out re-writing of the form via "self.ArmRefresh: = true;" in the event handler OnShow of the form. Thus the components which are associated with ArM archives are loaded with data and the latest information is displayed. 6.1.1.2 Using standard ArM sub-forms Very often during the work of a programming system it is necessary to draw the user's attention and inform them of certain important situations. For example, it is necessary to look for their consent when initiating irreversible changes such as deletion or modification of large amounts of data. Moreover, it is desirable for consumers to be well-informed about what is happening in the system processes and upon the occurrence of a certain error that cannot be resolved by the system, they must receive an appropriate message with a description of the problem. Also in the construction of the interface of the system it is desirable that it be made sufficiently interactive. For example, when clicking on a field for entering a date, a window with a calendar can appear from which the user can select the desired day. 85 To implement this functionality, several standard ArM forms are developed (sub-forms meaning that they are not basic forms). They are repeated in many places in the code. Their unified look makes it easier for users to work. The display of these forms is done by calling the function or procedure declared in the program module of the specific form. Thus showing the relevant form usually consists in calling the function by setting the necessary input parameters. Forms are developed for displaying messages, requiring a response from the user, selecting a date and month. Yes/no option Confirm dialogue box This form is used to request a response from the user. The answer is given by pressing one of the two available buttons. The form can be used to attract attention at the start of a delicate or irreversible operation. The programmer can set the text of the message/question, the font size and color, the inscriptions on the buttons, the layout of the dialog window on the screen, the size and color of the window. The name of the form is FormYN. Its declaration is made at the programming module AF_YesNo.pas. Also the function that is used to display the form is declared there - Ask_YesNo (description of the function is given in chapter V). The answer to the question from the dialogue window returns as a result of the execution of the function, for example: if Ask_YesNo(self, '!!!', 'Confirm the deletion of the image from the archive:', 10, '', 10, Mouse.CursorPos.X, Mouse.CursorPos.Y + 10, rgb(240, 240, 240), rgb(250, 50 , 50), 'Yes', 'No', (CurrentArmForm as TArmForm).scalew, (CurrentArmForm as TArmForm).scaleh) then DeleteFile(PictureFileName); As a result of the execution of the code a dialog window appears shown in Fig. 43. If the user presses the "Yes" button, the image will be deleted. Fig. 43 Confirmation dialogue box 86 Confirmation dialogue box with Yes/No option and the possibility of refusal of further activation This is another form for requesting a response from the user, but with the possibility that they might ban the subsequent display of the dialog window. There are two buttons for answering the shown question/message and a checkbox with which the user can specify that the window does not appear any more. The form can be used to attract attention at the start of a delicate operation, especially when it comes to a cyclic process, such as deleting a sequence of files. Besides the parameters of FormYN, the programmer can also set the state of the checkbox upon displaying the window. The name of the form is FormYNCheck. Its declaration is made in the programming module AF_YesNoCheck.pas. There also the function for displaying the form is declared - Ask_YesNoCheck (description of the function is given in Chapter V). The answer to the question from the dialogue box returns as a result of the execution of the function. The programmer must ensure the reading of the state of the box upon closing the window (parameter checked) and if it is checked, ban the subsequent display of the dialog window, for example: if flagAskForMonitor then begin AskChBox := false; if Ask_YesNoCheck(application, ' !!! ', 'Would you like automatic monitor setttings’, 11, 'according to the interface of the program?', 11, AskChBox, 0, 0, RGB(225, 225, 225), RGB(220, 80, 80), 'Yes', 'No', 1.2, 1.2) then < user programming block> // automatic setting if AskChBox then flagAskForMonitor := false else flagAskForMonitor := true; end; // to stop asking // to keep asking As a result of the execution of the code a dialog box appears, shown in Fig. 44. If the user checks the box, in the subsequent execution of the code the window will be displayed. 87 Fig. 44 Confirmation dialogue box with Yes/No option and possibility for refusal from further activation Form for displaying a message The FormAM is used to display to the user different types of messages, such as error messages that arose during in the execution. Its task is informative - the user can only close the window that appeared. The programmer can set the text of the message, the font size and color, location, size and color of the window, the text in the title bar and the color of the title bar, an auxiliary file describing the situation. The form is declared in the program module AF_ArmMessage.pas. The declaration of the procedure ExecMessages, which is used to display the form, is also made in this program module (the description of the procedure is given in Chapter V). Here is an example for displaying the form: ExecMessages(self, ' Error!!! ', 'The entered digits do not correspond to the form for PIN', 14, ' "' + self.EGN_Edit.Text + '" ??? ', 15, ' ', 12, Mouse.CursorPos.X - 20, Mouse.CursorPos.Y + 10, BarColor, BackgroundColor, TextColor, false, ''); As a result of the execution of the code the message shown in Fig. 45 appears. The user can only close the window. Fig. 45 Form for displaying a message 88 Form for selecting a date The form Frm_Choise_day11 is used when the user must enter a date. It has a calendar as the month and year displayed on it can be changed. Thus, the user can easily specify the required date. Also, there is the possibility of introducing a date from the keyboard and of deleting the previously entered date by pressing Delete. The form is declared in the program module AF_ChoiseDay.pas. It shows by calling the function ChoiseDay, declared in the same programming module (description of the function is given in Chapter V). The programmer can set the text in the title bar of the dialog box, the location of the window on the screen, the initially displayed date on the calendar, such as year, month and day can be set separately or a specific time can be specified through the TDateTime parameter ccdate. The button for deleting the previously entered date may be hidden. In order to show the form, it is enough to call the function ChoiseDay in the program code. The date chosen by the user returns through the parameter chday. The results of the execution of the function depends on the user's actions – with a chosen date the result is "1" and when a button is pressed to delete the inputted date - the result is "2": fl_exit := ChoiseDay((CurrentArmForm as TArmForm), AFrame, ' Date of birth:', Mouse.CursorPos.X - 150, Mouse.CursorPos.Y + 30, u_date.EncodeDate(CrntYear, CrntMonth, CrntDay), 1990, 5, 1, // 01.05.1990г. false, true, chday); if fl_exit > 0 // Selection of date or deletion of date then if fl_exit = 2 then BirthDateEdit.Text := ''; // deletion of date else BirthDateEdit.Text := DateToStr(chday); As a result of the execution of the code a dialog box appears, shown in Fig. 46. 89 Fig. 46 Form for selecting a date Form for selecting a month The Frm_Choise_Month11 is used when users need to enter a month. The displayed dialog box gives the user the opportunity to select the month and year. Also there is a button for deleting the previous month entered. The form is declared in the program module AF_ChoiseMonth.pas. It opens by calling the function ChoiseMonth declared in the same program module (description of the function is given in chapter V). The programmer can set the text in the title bar of the dialog box, the location of the window on the screen, the initially displayed year and month. The selection of the month may be limited - the user can choose only from January to endmonth. They can also set whether to display the delete button and the buttons for selecting the year. The month and year selected by the user are returned by the parameters chyear and chMonth. The result of the execution of the function depends on the user's actions - in selected month the result is "1" and when a button is pressed to delete the entered month - the result is "2": chyear := CrntYear; chmonth := CrntMonth; fl_exit := ChoiseMonth(nil, self, 'selection of month', Mouse.CursorPos.X, Mouse.CursorPos.Y, CrntYear, CrntMonth, LimitMonth, false, true, true, chyear, chmonth); if fl_exit > 0 // selection of month or deletion of month then if fl_exit = 2 then begin 90 YearEdit.Text := ''; // deletion of year MonthEdit.Text := ''; // deletion of month end else begin YearEdit.Text := IntToStr(chyear); MonthEdit.Text := IntToStr(chmonth); end; As a result of the execution of the code a dialog box appears, shown in Fig. 47. Fig. 47 Form for selecting a month 6.1.1.3 Using ArM components TArmBaseAddress A non-visual component to specify the working archive in an ArM form. The name of the archive is set by the property ArchName. There is no requirement for the name format. It can be an arbitrary file name. By the property of the component Arm the connection with the functions for working with data in the archive is carried out. Opening the archive for work is done by setting 91 a specific name to the archive and closing the working archive is done by assigning an empty string to the property ArchName. TArmBaseCoords A non-visual component for specifying information spaces. It is used with the component TArmBaseAddress when working with the visual ArM visual. In the property of the component BC0 the dimension of the defined information space is set. At one TArmBaseAddress there can be several TArmBaseCoords for each used informational space in the archive. TArmGrid The TArmGrid represents an ArM component for displaying information in tabular form (Fig. 48). It is used to retrieve and write data from/to ArM archives. TArmGrid has two modes of operation with archives - automatic (in which data is read and saved automatically) and user (where the programmer explicitly specifies the necessary actions). The component is a successor to the class TstringGrid. Fig. 48 TArmGrid component with entered data To use the TArmGrid component, it is necessary to connect it to an existing ArM archive. This is achieved as in the Object Inspector the properties BaseAddress and BaseCoords are specified. In the drop-down selection lists only one component is selected of the respective type existing in the format or arranged in the data module for the project. The property BaseAddress is of the type TArmBaseAddress and is used to point to the data archive. BaseCoords is of the type TArmBaseCoords and is used to indicate the basic coordinates in the archive, based on which the coordinates of the object to read or write are calculated. The component TArmGrid has an added property Columns, which is used to edit the individual columns of the table. Columns is a list of components of the type TArmGridColumn, corresponding to the displayed columns in TArmGrid. Each of the columns in the table can be edited using the relevant properties. 92 Editing a column of the TArmGrid component The corresponding TArmGrid component is selected in the form and in ObjectInspector one clicks twice in the right margin of the property Columns. This opens a window with a list of existing table columns. Clicking on an item from the list leads to displaying its properties in the ObjectInspector: Title – specifies a title for the column which is written in the uppermost cell; Width – specifies the width of the column; Editable – allows and bans the entry of text in the column by the user; UserNumber – specifies an identification number of the column which could later be used for recognizing the column; C0, C1, C2, …, C9 – specifies the coordinates of the ArM archive from/in which the data should be read/written in automatic mode. C0 determines the number of used dimensions for specifying the coordinates of the object. CellType – Specifies the type of data which is written in the indicated coordinates. Thus for example, in CellType:=arm_s; saved data is of the type ShortString, in CellType:=arm_i; – of the type Integer, in CellType:=arm_r; – of the type Double. When CellType:=arm_f; the data is not saved automatically but the programmer needs to specify the necessary actions (in the event handler OnFUser or OnFUserHeader of TArmGrid). Automatic mode for working with archives In this mode, data is automatically loaded from the ArM archive in the fields of the TArmGrid upon the creation of the component, and after their change by the user the changes are automatically saved in the archive. The working mode of the archive is set for each column of the table - some columns can be loaded automatically, while for others additional processing of the data may be assigned before their saving (filtering, additional calculations, saving data in multiple locations). The setting is done through the property CellType of the column. In automatic mode, it is necessary to set a value different from arm_f (which corresponds to the user mode). In automatic mode it is necessary to enter values for the properties of the columns C0, C1, C2, ..., C9. On their basis and based on the coordinates entered in BaseCoords of TArmGrid, the coordinates are calculated of the archive with which should be worked. Reading/writing from a range of coordinates When data should be read not from one object with given coordinates, but from several objects with several consecutive coordinate addresses using the properties IfFromTo, IndAddress and IndCoords of TArmGrid. IfFromTo is a flag defining the reading and saving of an interval of values in the archive. 93 User mode for operating with archives In this mode, data is not read and saved automatically. The programmer must specify the code for processing and saving the data. If there is no code specified, then the data is not saved in the archive. The mode of operation of the archive is set for each of the columns of the table. The setting is done through the property CellType of the column. For the user mode the property CellType: = arm_f. is necessary. Thus, when there are variations in the cell of this column (e.g. The user begins to enter text) the events OnFUser and OnFUserHeader for TarmGrid arise. The programmer must create handlers of these events in which to set the necessary data processing (computing, data recording in the ArM archives, changes in the interface). In recording the data in the archive the type of data and details are expressly defined. The cells of a column whose property is CellType = arm_f, are called f-cells. In the event handler OnFUser of the TArmGrid as input parameters accessible are the variables UserNumber, ACol, ARow of the type Integer. ACol and ARow contain the numbers of the column and of the cell row whose editing was started by the user. UserNumber contains the value of the property UserNumber of the respective column. These variables are used in determining the edited cell. In processing the event OnFUser of the TArmGrid, it is useful to use the property EditFlag of the ArM form (e.g. (CurrentArmForm as TArmForm).EditFlag). EditFlag determines the type of the editing operation, which has caused the event OnFUser. EditFlag=0 when OnFUser is triggered upon the initial display of the form; EditFlag=1 when the user has pressed twice the left mouse button on a cell of TArmGrid or has pressed "Enter" (enters editing mode for the contents of the cell); EditFlag=2 when the user exits the cell by pressing "Enter" (goes out of the editing mode for the cell contents). In processing the event OnFUser, when the case EditFlag=1 is handled (the user has started to edit an f-box) it is necessary at the end of processing to set EditFlag:=3;, which terminates the editing mode (without being necessary for the user to press "Enter"). The focus moves to the next component, and the semaphore in the left side of the status bar of the form switches to "green". procedure TFrame.ArmGrid_FUser(Sender: TObject; UserNumber, ACol, ARow: Integer); var iit : integer; begin case UserNumber of 11 : begin // EditFlag = 0-create; 1-edit enter; 2-edit exit; 3case (CurrentArmForm as TArmForm).EditFlag of 0 : self.ArmGrid_udr_edn.Cells[acol, arow] := DMD.ArmBA_F.Arm.ReadSStr3(cmonth, 50, 700 + arow); 2 : begin DMD.ArmBA_F.Arm.WriteSStr3(cmonth, 51, 700 + arow, self.ArmGrid_udr_edn.Cells[acol, arow]); <user programming block> end; end; end; 12 : begin // type of deductions – one-time 94 if self.ArmGrid_udr_edn.Cells[1, arow] = '' then begin (CurrentArmForm as TArmForm).EditFlag := 3; exit; end; iit := DMD.ArmBA_F.Arm.ReadInt3(cmonth, 52, 700 + arow); <user programming block> end; end; end; Dynamic adding of columns The number of displayed columns is specifies by the property ColCount. During the execution it is possible to add or remove columns dynamically, adjusting ColCount. In adding columns, it is mandatory to specify also coordinates for the respective column (i.e. the properties C0, C1, …, C9). Here is one example for dynamic addition of a column to ArmGrid1: ArmGrid1.ColCount := ArmGrid1.ColCount + 1; i := ArmGrid1.ColCount - 1; // Numbering starts from 0 ArmGrid1.Columns.Items[i].C0 := 3; // Mandatory ArmGrid1.Columns.Items[i].C1 := 1; // Mandatory ArmGrid1.Columns.Items[i].C2 := 1; // Mandatory ArmGrid1.Columns.Items[i].C3 := 1; // Mandatory ArmGrid1.Columns.Items[i].Title := 'ColumnTitle'; ArmGrid1.Columns.Items[i].CellType := arm_f; ArmGrid1.Columns.Items[i].UserNumber := i; TArmTree TArmTree represents an ArM component for visualizing data in a tree structure (Fig. 49). It is used to visualize the tree structure data stored in the ArM archive. The component is a successor to the class TTreeView. 95 Fig. 49 The Component TArmTree To use the component TArmTree, it is necessary to connect it to an existing ArM archive. This is achieved as in the Object Inspector the properties BaseAddress and BaseCoords are specified. In the drop-down lists for selection, one of the components is selection of the respective type existing in the form or located in the data module of the project. The BaseAddress property is of type TArmBaseAddress and is used to point to the data archive. BaseCoords is of the type TArmBaseCoords. Along with the properties of C0, C1, C2, ..., C9, it is used to indicate the coordinates of the tree structure located in the archive. An example of using the component TArmTree in application software can be seen in Fig. 50. In the left side of the window there is a tree structure of the company products arranged in different subgroups. The user can add new items, edit existing ones, set new subgroups. When choosing a product, the relevant technological operations are presented in the TArmGrid component located in the right part of the window. 96 Fig. 50 Example for using TArmGrid and TArmTree components in ArM form Description of the tree structure The tree structure is suitable for presentation of hierarchical structures. The individual elements of the structure are called nodes. There is an initial node (the root of the tree). It is at the highest level in the hierarchy. The root is associated logically with one or several nodes of the second, lower hierarchical level. Each of the nodes may be coupled to another node from a lower hierarchical level, a node from a lower level can be linked only to a single node from an upper level. When a node has no relation to nodes of a lower level, this node is called a leaf. The tree structure with ArM archives is implemented as follows: each node of the tree is saved in the archive by 11 items (not all objects are required); in each of these objects a certain type of information characterizing an individual unit is saved; all objects containing data for the tree structure are saved in one and the same area (the number of coordinates in the address for each of the objects is the same) as the minimum allowable space is the two-dimensional space; the addresses of all objects in the tree differ only in terms of two neighboring coordinates – the coordinate for the type of data obj_type and the coordinate for the node index node_idx, other coordinates match; the address of each object is calculated as follows: ([xx, ..., xx,] obj_type, node_idx [, xx, ..., xx]), xx - random value; obj_type is located to the left of node_idx; the addresses of all objects that describe a node of the tree differ only in the coordinate for the data type obj_type; the data of the same type for two different nodes are stored in objects whose coordinate addresses differ only in the coordinate of the node index node_idx; different types of information about a certain node are saved in objects with consistent values along the coordinate obj_type; usually the first object has the coordinate 10, but 97 can be specified also by shift; at the start of the 10 coordinate the distribution over coordinates is as follows: o obj_type=10 – the object stores the base area for processing, i.e. the actual connection of the node to other nodes, determining the hierarchy. An array of type cardinal is saved, in which at zero position the value of the coordinate node_idx of the previous node is recorded and in the other positions values of the node_idx coordinates of the heirs to the node in question are recorded; o obj_type=11 – the level of nesting in a tree for the node considered is recorded in the object, i.e. it determines the number of nodes to the root of the tree; the recorded data is of type cardinal; o obj_type=12 – a flag is saved in the object if the node is initialized; used when working with the component TArmTree; the recorded data is of type cardinal; in an empty object or 0 value the node is not initialized; o obj_type=13 – in the object a flag is saved if the node is deleted (disconnected from the tree structure, physically the objects of the node are not deleted from the archive to allow for further recovery); the recorded data is of type cardinal; in an empty object the node is not deleted, and with a value of 99 the node is disconnected from the structure of the tree; o obj_type=14 – left for future development; o obj_type=15 – left for future development; o obj_type=16 – used when working with the TArmTree component; the object stores a textual number of the tree node that is to be displayed in the component for visualizing the tree TArmTree; the recorded data is of type string; o obj_type=17 – the object stores the full name of the node; the recorded data is of type string; o obj_type=18 – the full name of the node in English is written in the object, the recoded data is of type string; o obj_type=19 – the object stores the full name of the node in another language; the recorded data is of type string; o obj_type=20 – used when working with the component TArmTree; the object stores the index of the icon in ListImage, which is displayed before the number of the node when displaying the tree in the component TArmTree; the recorded data is of type integer. Form for inserting elements in a tree For convenient entry and editing of elements in the tree a special form has been developed TFormETN (Fig. 51). The description of the class is done in the software module AF_EditTreeNode.pas. This dialog box can be displayed as pressing the right mouse button in the TArmTree component and the subsequent selection of the shortcut menu that appears in the corresponding box. The user can enter element number, element name and specify an image describing the type of element. The programmer has the ability to set the text in the title bar of the dialog box, the location of window on the screen, the text to be displayed in the fields "Number:" and "Name:" when showing the window, the image describing the data. 98 Fig. 51 Form for introducing elements in tree To display the dialog box for entering and editing elements in the tree, one can use the function EditArmTreeNode declared in ArmAccess.pas: if EditArmTreeNode(kobj, Window_Left, Window_Top, OperationText, PrevNodeName, NodeNum, NodeName, ImageIndex, ImаgeList, TreeColor, self) and (NodeName<>'') then begin <user programming block> // adding an element end; The element number entered by the user is returned by the parameter snum of EditArmTreeNode. The name of the element is returned by the parameter sname, while the index of the selected image - by imindex. The Function for displaying the form EditArmTreeNode returns true if the user has confirmed editing or adding elements, otherwise - false. The TArmLabel component is a successor to the standard visual component TLabel. As such it retains all the properties and methods of TLabel, but also receives additional functionality for working with ArM archives. The TArmLabel component is used to display text in the form (Fig. 52), as this text can be loaded from a specified ArM archive. The ArM archive is set by the property BaseAddress (type TArmBaseAddress). There are two modes to extract data from the archive - automatic and user. The mode is set by the property CellType. Fig. 52 The component TArmLabel 99 The automatic mode of extraction is done by setting the CellType property to a value other than arm_f. When creating an ArM form or changing the basic coordinates (set by the property BaseCoords, type TArmBaseCoords), the value of a certain object is read from the archive and it is displayed automatically in the component TArmLabel (in the property Caption). The coordinate address of the object is formed based on the properties BaseCoords and C0, C1, C2, ..., C9 – sums of the values of correspondent coordinates are calculated. The type of data in the object is determined by the property CellType (e.g. with CellType:=arm_s; the data is of type ShortString, with CellType:=arm_i; - of type Integer, with CellType:=arm_r; - of type Double). The user mode for extraction is done by setting the value arm_f to the property CellType. In this case the data is not retrieved automatically and the programmer must specify an additional code. It is used in cases where data must be further processed. When creating an ArM form or changing the basic coordinates (change in the relevant TArmBaseCoords component), the OnFUser event occurs for the TArmLabel component and its correspondent event handler is executed. In the event handler OnFUser the programmer specifies the data retrieval from the archive and its required processing. The TArmLabel component can operate with 9-dimensional spaces at the maximum. TArmLEdit The TArmLEdit component is a field for entering text to which a label for specifying the name of the field is added (Fig. 53). Its properties and events largely coincide with those of the standard visual component TLabeledEdit. A major difference is the added functionality for working with ArM archives - the content of the text field can be automatically loaded and saved from/to an ArM archive. The ArM archive is set by the property BaseAddress (of type TArmBaseAddress). There are two modes for retrieval and saving of data from the archive - automatic and user. The mode is set by using the property CellType. Fig. 53 The component TArmLEdit The automatic mode of retrieving and saving data is specified by setting the CellType property to a value other than arm_f. Then in creating the ArM form or changing the basic coordinates (set by the property BaseCoords, type TArmBaseCoords), the value of a certain object from the archive is read and it is displayed automatically in TArmLEdit. The coordinate address of the object is formed based on the properties BaseCoords and C0, C1, C2, ..., C9 - by summation of the values of correspondent coordinates. The type of data in the object is determined by the property CellType (e.g. with CellType:=arm_s; the data type is ShortString, with CellType:=arm_i; – of the Integer, with CellType:=arm_r; – of the Double).). Also, when a user enters data in the field, they are automatically saved in the appropriate object from the archive. The user mode for retrieving and saving is specified by setting the value arm_f to the property CellType. In it the data is not retrieved/saved automatically and the programmer must specify an additional code. This is used in cases where data must be further processed. In creating 100 the ArM form, when user enters data in the field or when changing the basic coordinates (change in the relevant TArmBaseCoords component), the OnFUser event occurs for the TArmLEdit component and its corresponding event handler is executed. In the event handler OnFUser the programmer sets the appropriate action - extracting data from archives, processing, saving. When processing the event OnFUser of the TArmLEdit component, it is helpful to use the property EditFlag of the ArM form (e.g. (CurrentArmForm as TArmForm).EditFlag). EditFlag determines the type of the action for editing, which initiated the event OnFUser. EditFlag=0 when OnFUser is triggered upon initial display of the form; EditFlag=1 when the user has pressed twice on the left mouse button on the text box of TArmLEdit or has pressed "Enter" (enters a mode for editing the contents of the field); EditFlag=2 when the user exits the box by pressing "Enter" (exits the mode for editing the contents of the field). When processing the event OnFUser, when the case EditFlag=1 is handled (the user has started editing the field) it is required at the end of processing to set EditFlag:=3;, which terminates the editing mode (as there is no need for the user to press an additional "Enter"). Focus shifts to the next component, and the semaphore on the left side of the form’s status bar switches to "green". The TArmLEdit component can work with 9-dimensional spaces at the maximum. TArmMemo The TArmMemo component is a field for entering multiline text (Fig. 54). The content of the field can be automatically loaded and saved from/to a specified ArM archive. The ArM archive is specified by the property BaseAddress (of the type TArmBaseAddress). There are two modes to retrieve and save data from the archive - automatic and user. The mode is specified by using the property CellType. Fig. 54 The component TArmMemo The automatic mode for retrieving and saving data is specified by setting the CellType property to a value other than arm_f. Then in creating the ArM form or changing the basic coordinates (set by the property BaseCoords, of type TArmBaseCoords), the value of an object is read from the archive and it is displayed automatically in TArmMemo. Coordinate address of the object is formed based on properties BaseCoords and C0, C1, C2, ..., C9 - is realized by summation of values of corresponding coordinates. The type of data in the object is determined by the property CellType (e.g. with CellType:=arm_s; the data type is ShortString). Also, when a user enters data in the field, it is automatically saved in the appropriate object from the archive. The user mode for retrieval and saving is specified by setting the value arm_f of the property CellType. In it the data is not retrieved/saved automatically and the programmer must specify an additional code. It is used in cases where data must be further processed. In creating the ArM form when the user enters data in the field or the basic coordinates are changed (change in the relevant TArmBaseCoords component), for the TArmMemo component the event OnFUser occurs 101 and its corresponding handler is executed. In the event handler OnFUser the programmer sets the appropriate action – retrieving data from the archive, processing, saving When processing the event OnFUser of the TArmMemo component, it is useful to use the property EditFlag of the ArM form (e.g. (CurrentArmForm as TArmForm).EditFlag). EditFlag determines the type of the action for editing, which initiated the event OnFUser. EditFlag=0 when OnFUser is triggered upon the initial display of the form; EditFlag=1 when the user enters the mode for editing the content of TArmMemo; EditFlag=2 when the user exits the mode for eiting the content of TArmMemo). The TArmMemo component can operate with 9-dimensional spaces at the maximum. TArmCheckBox The TArmCheckBox component is a field for checking, by means of which bit data is displayed (Fig. 55). Its properties and events largely coincide with those of the standard visual component TCheckBox. In addition TArmCheckBox allows setting the type of marker (the property CheckBoxType) and its color (the property CheckColor). Its main feature is the ability to load and save the state of the field (checked/unchecked) automatically by a specified ArM archive. The ArM archive is specified by the property BaseAddress (of the type TArmBaseAddress). Fig. 55 The component TArmCheckBox When creating the ArM form or changing the basic coordinates (specified by the property BaseCoords, of the type TArmBaseCoords), the ArM functionality of the component allows the automatic reading of the binary value of an object from the archive and its visualization in TArmCheckBox. The coordinate address of the object is formed based on the properties BaseCoords and C0, C1, C2, ..., C9 - summation of the values of the corresponding coordinates is done. Also, when a user changes the status of the field, the corresponding binary value is automatically saved in the appropriate object from the archive. The TArmCheckBox component can work with 9-dimensional spaces at the maximum. TArmComboBox The TArmComboBox component is a successor to the component TLabComboBox (described below). As such it retains all the properties and methods of TLabComboBox, but also receives additional functionality regarding its operation with ArM archives. TArmComboBox is a drop-down list (Fig. 56) providing the user the ability to choose between several specified options. The list is accompanied by a label for specifying the name. 102 Fig. 56 The component TArmComboBox A key feature of the component is the added ArM functionality – the version selected by the user can be saved and retrieved in/from a specified ArM archive automatically. The ArM archive is specifies by the property BaseAddress (of the type TArmBaseAddress). When creating an ArM form or changing the basic coordinates (specified by the property BaseCoords, of the type TArmBaseCoords), a selected version saved in a specific object is automatically read from the archive and it is displayed in TArmComboBox. The coordinate address of the object in which the chosen version is saved is formed based on the properties BaseCoords and C0, C1, C2, ..., C9 summation of the values along the corresponding coordinates is always carried out. Also, when the user selects another option from the list, the preferred option is automatically saved in the appropriate object from the archive. The TArmComboBox component can operate with 9-dimensional spaces at the maximum. TArmListView The TArmListView component is a successor to the standard component TListView. As such it retains much of the properties and events of TListView, but also takes additional functionality for operating with ArM archives. TArmListView is a visual component for displaying a list of elements as the visualization resembles the one of files and folders in Windows Explorer (Fig. 57). The elements can be displayed in columns with the respective titles as the name of each element may be preceded by a small or big picture. Also there may be a radio button for selecting Fig. 57 The component TArmListView A key feature of the component is the added ArM functionality – the listed items can be saved and retrieved to/from a specified ArM archive automatically. The ArM archive is set by the property BaseAddress (of the type TArmBaseAddress). When creating an ArM form or changing the basic coordinates (specified by the property BaseCoords, of the type TArmBaseCoords), the saved data is automatically read from the archive and displayed in TArmListView. The coordinate addresses of the objects where the data is saved are formed based on the properties BaseCoords 103 and C0, C1, C2, ..., C9 for the respective ArmColumns. Also, when a user enters data, it is automatically saved in the corresponding objects from the archive. TArmListView component can operate with 9-dimensional spaces at the maximum. TLabComboBox TLabComboBox is a visual component that gives the user the ability to choose between several options. It is a combo box for choice. TLabComboBox and TComboBox are created based on the same base class - TCustomComboBox. That's why many of their properties and methods match. The main difference between TLabComboBox and TComboBox is that TLabComboBox has an added built-in label (TBoundLabel), which appears next to the box for text input (Fig. 58). Access to the properties of the label is done through the property EditLabel (e.g. "LabComboBox1.EditLabel.Caption:= 'Text';"). Fig. 58 The component TlabComboBox In connection with the added label, TLabComboBox has an additional two properties controlling the position of the label: LabelPosition – sets the position of the label in regard to the combo box; may take the following values: lpAbove (the label is located above the selection box), lpBelow (located under the box), lpLeft (located on the left), lpRight (located on the right); LabelSpacing – sets the distance between the label and combo box. TFXComboBox The TFXComboBox is a component providing the user a choice between several options. It is a successor to the class TLabComboBox. As such, it is a combo box of choice, but with added additional functionality. To the component TFXComboBox an additional possibility is added for indexing the items from the list. To each of the list items two integer indexes can be added - group and position. Thus each of the elements can be identified both by its serial number and also by the added identifiers. The identifiers group and position are connected firmly to the item from the list, i.e. in sorting, adding or removing of elements they do not change (values remain as they were specified on adding the element). These identifiers can match the indexes in other lists, coordinates in ArM archives with data, certain coefficients corresponding to the selected item from the list. Adding an item to the list is performed using the method AddNewItem (sname: shortstring; vgroup, vposition: Cardinal). The text that will be shown in the list is specified for sname, and for vgroup and vposition the respective identifiers are specified. For example, the code: FXComboBox1.AddNewItem('ItemText', 0, 1); 104 Is added to the folding component FXComboBox1 in the order "ItemText", in the selection of which its corresponding values can be obtained: group=0, position=1. If you need to add an element to a list sorted in alphabetical order, it is necessary first to repeal the sorting. This is done by setting the value false of the property Sorted. Then sorting may again be applied, e.g .: Temp_Sorted_Flag := FXComboBox1.Sorted; FXComboBox1.Sorted := false; FXComboBox1.AddNewItem('ItemText', 0, 1); FXComboBox1.Sorted := Temp_Sorted_Flag; The properties cgroup and cposition take the corresponding values of the identifiers of the currently selected item from the list. To obtain the values of the identifiers of an element in its serial number, the methods getgroup(ind:Cardinal):cardinal and getposition(ind:Cardinal):cardinal are used. For example, in the execution of the code: Gr_ID := FXComboBox1.getgroup(0); Gr_ID will receive the value of the group identifier of the first element from the drop-down list FXComboBox1. The method RetIndexIndFromGroupPos (vgroup, vposition: Cardinal): integer is used to obtain the serial number of the item whose identifiers match the indicated ones. If no such element is found, then the function returns a value "-1". If there are several elements in the list with the given identifiers, it returns the serial number of the last such item found. TFXHintComboBox TFXHintComboBox is a component providing the user a choice between several options. It is a successor to the class TFXComboBox. As such, it is a combo of choice with a built-in label (TBoundLabel) and additional identifiers for each of the elements. In TFXHintComboBox one of the problems of TComboBox is solved – when there is insufficient width of the component for displaying the full text, a pop-up prompt (Hint) appears from the indicated element, in which the entire text of the element is written (Fig. 59). To solve and disable the display of the pop-up hint, the property ShowToolTips is used. Fig. 59 The component TFXHintComboBox 105 One example for the use of ArM components in building the interface for business management software can be seen in the window shown in Fig. 60. The window is used to enter data for a specific employee of the company. Fig. 60 Example for using ArM components in building the interface of a software system 6.1.1.4 Other components supporting the design of the user interface To build a more convenient and attractive interface and implement greater functionality, components developed by other software vendors are used. Some of these components have open source and can be used in projects without additional payment of licensing fees. Another part refers to paid products that include regular updates of the components and technical support. A good open-source component is TZSImage developed by ThWilliam. It is used for visualization of images, by offering additional options for viewing - such as magnifying a portion of the image (the "Magnifying glass" effect), a slideshow of multiple images, editing of images. To compress and decompress files, one can use the components of the package Abbrevia of TurboPower Software. The package supports multiple compression formats - PKZip, Microsoft CAB, tar, gzip, bzip2 and zlib (eg. the components TAbUnZipper, TAbZipper, TAbCabKit). It provides the opportunity to create self-extracting executable files (the component TAbMakeSelfExe). It also includes several visual components that facilitate the visualization of the contents of the compressed archives (e.g. the components TAbZipView, TAbMeter, TAbTreeView). In displaying information from the software systems, commonly used are PDF files. The creation of such files can be performed using Synopse PDF engine. Synopse PDF engine 106 represents a Delphi library for creating PDF documents. It is open source and is distributed free. The entire library is encapsulated in a software module - SynPdf.pas. To diversify the interface of the programming system multiple visual components can be used of DevExpress (Developer Express Inc). They are paid and for their use payment is required of license fees by the manufacturer of the software. The components are suitable for example for building diverse menus attractive to consumers (TdxNavBar, TdxBar, TdxBarManager, TcxStyleRepository). Such a menu is shown in Fig. 61. Fig. 61 TdxNavBar component Very helpful in creating, displaying and editing RTF text files are the paid components of the TRichView package. They allow the processing of hypertext documents (RTF, HTML, in-house RVF format). They have convenient functions for printing documents. They also provide editing of the documents regarding how they will look when printed on paper (WYSIWYG). Some of the most used components of the package are: TRichViewEdit (field for viewing and editing hypertext documents, not taking into account the page format), TRVPrintPreview (component for viewing the document before printing), TRVStyle (non-visual component, sets the style for the entered text), TSRichViewEdit (field for displaying and editing hypertext documents, displays the information in the page - WYSIWYG), TSclRVRuler (ruler at the side of the page to specify the writing field). 107 7 ArMSBuilder Vver. 1.03 – Procedures, Functions, and Methods The technology for developing complex software systems ArMSBuilder ver. 1.03 consists of several code libraries, where according to the specifics of supported functionalities different forms, procedures, functions and components are grouped: Arm32.pas, ArmAccess.pas, ArM_BO.pas, u_Tree.pas, u_String.pas, u_Image.pas, u_RTFoperations.pas, u_Report.pas, u_Nom.pas, u_FTP.pas. Index of the procedures, functions and methods used in the technology for developing complex software systems ArMSBuilder ver. 1.03. I. Arm32 I.1 General methods of ArM32 Create(ArchName: ShortString; IfShare: Boolean; Info: string); Free; LengthA(pca: PCoordArray): cardinal; Length1(obj: cardinal): cardinal; Length2(dom, obj: cardinal): cardinal; Length3(spc, dom, obj: cardinal): cardinal; Length4(hyp, spc, dom, obj: cardinal): cardinal; Length5(glb, hyp, spc, dom, obj: cardinal): cardinal; ReadA(pca: PCoordArray; var buff; len, skip: cardinal): cardinal; Read1(obj: cardinal; var buff; len, skip: cardinal): cardinal; Read2(dom, obj: cardinal; var buff; len, skip: cardinal): cardinal; Read3(spc, dom, obj: cardinal; var buff; len, skip: cardinal): cardinal; Read4(hyp, spc, dom, obj: cardinal; var buff; len, skip: cardinal): cardinal; Read5(glb, hyp, spc, dom, obj: cardinal; var buff; len, skip: cardinal): cardinal; WriteA(pca: PCoordArray; var buff; len: cardinal): cardinal; AppendA(pca: PCoordArray; var buff; len: cardinal): cardinal; InsertA(pca: PCoordArray; var buff; len, skip: cardinal): cardinal; CutA(pca: PCoordArray; len, skip: cardinal): cardinal; ReplaceA(pca: PCoordArray; var buff; len, skip: cardinal): cardinal; DeleteA(pca: PCoordArray): cardinal; DelSpaceA(pca: PCoordArray; lvl: cardinal): cardinal; 108 CountSpaceA(pca: PCoordArray; lvl: cardinal): cardinal; RetProjectionA(cpattern: PCoordArray; cind: PCoordIndArray): cardinal; RetProjectionA_Applic(Applic: TApplication; cpattern: PCoordArray; cind: PCoordIndArray): Cardinal; Get(pca: PCoordArray; var buff; len: cardinal; var skip: cardinal): cardinal; NextPresentA(pca: PCoordArray; lvl: cardinal): cardinal; NextEmptyA(pca: PCoordArray; lvl: cardinal): cardinal; PrevPresentA(pca: PCoordArray; lvl: cardinal): cardinal; PrevEmptyA(pca: PCoordArray; lvl: cardinal): cardinal; CopyA(pca1, pca2: PCoordArray; lvl: cardinal; del0: boolean): cardinal; I.2 Auxiliary methods на ArM32 ReadStringA(pca: PCoordArray): String; WriteStringA(pca: PCoordArray; ss: String); ReadSStrA(pca: PCoordArray): ShortString; WriteSStrA(pca: PCoordArray; ss: ShortString); ReadRealA(pca: PCoordArray): Real; WriteRealA(pca: PCoordArray; rr: Real); ReadDoubleA(pca: PCoordArray): Double; WriteDoubleA(pca: PCoordArray; rr: Double); ReadIntA(pca: PCoordArray): Integer; WriteIntA(pca: PCoordArray; ii: Integer); ReadCardA(pca: PCoordArray): Cardinal; WriteCardA(pca: PCoordArray; ii: Cardinal); II. ArM components RefillHeader(aCaption: String; afontsize: Integer; atextcolor: Tcolor; abmp: TBitmap; abackgrcolor: Tcolor; fl_help, fl_info, fl_move, fl_mini, fl_cancel: Boolean); TArmBaseAddress TArmBaseCoords TArmGrid TArmLEdit TArmMemo TArmCheckBox TArmComboBox TArmListView III. ArM procedures and functions for operation with large objects WriteMDA(ArmBA: TArmBaseAddress; PCoordinatesArray: PCoordArray; BOMD: TBigObjectMetaData): boolean; WriteBOA(ArmBA: TArmBaseAddress; PCoordinatesArray: PCoordArray; BO_Stream: TMemoryStream; ZipIt: boolean): boolean; 109 ReadMDA(ArmBA: TArmBaseAddress; PCoordinatesArray: PCoordArray; var BOMD: TBigObjectMetaData): boolean; ReadBOA(ArmBA: TArmBaseAddress; PCoordinatesArray: PCoordArray; var BO_Stream: TMemoryStream; Zipped: boolean): boolean; CopyStreamToClipboard(MemStream: TMemoryStream; FormatID: cardinal): boolean; CopyStreamFromClipboard(var MemStream: TMemoryStream; FormatID: cardinal): boolean; Load_FXHintComboBox_from_FileDB(FXHComboBox: TFXHintComboBox; DB: TArmBaseAddress; DimNum, glb, hyp, spc, dom, obj, lvl: Cardinal; Numbering: Char = #0); IV. ArM procedures and functions for operation with tree data structures: ret_ind_leafe_of_node(ArmD: TArm; Treecord: TCoordArray; ncoord, k_obj: cardinal; var br_ind: cardinal; var leafe_ind: TIndArray); ret_ind_of_node(ArmD: TArm; Treecord: TCoordArray; ncoord, k_obj: cardinal; var br_ind: cardinal; var node_ind: TIndArray); ret_ind_Init_of_node(ArmD: TArm; Treecord: TCoordArray; ncoord, k_obj: cardinal; var br_ind: cardinal; var init_ind: TIndArray); ret_selected_index_init(ArmBA: TArm; TreeCA: TCoordArray; ArmTree: TArmTree; var tr_br_sel: cardinal; var Tree_Sel_Array: TIndArray; var tr_ind_br: cardinal; var Tree_Ind_Array: TIndArray); ret_selected_index_leafe(ArmBA: TArm; TreeCA: TCoordArray; ArmTree: TArmTree; fl_structure: string; var tr_br_sel: cardinal; var Tree_Sel_Array: TIndArray; var tr_ind_br: cardinal; var Tree_Ind_Array: TIndArray); PathNodeTree(pTreeNode: TTreeNode; var sRuta: string): string; PozInArmTree(var ArmTree: TArmTree; kobj: cardinal); ExpandOrCollapsNode(cNode: TTreeNode; fl_expand_collaps: boolean); SetStateTreeNodes(curnode: TTreeNode; Flags: Integer); SetStateTreeChilds(curnode: TTreeNode; Flags: Integer); pin_new_child_node(FArm: TArm; PTreecord: PCoordArray; par_node: cardinal; num_new_node, name_new_node: string; var new_node: cardinal): boolean; Del_Tree_node_noRestore(FArm: TArm; Pnodecord10: PCoordArray; var new_objnode: cardinal): boolean; Disconnect_Tree_node(FArm: TArm; Pnodecord10: PCoordArray): boolean; V. ArM forms Ask_YesNo(aOwner: TComponent; aCaption: string; strcoment1: string; fn1: integer; strcoment2: string; fn2: integer; fleft, ftop: integer; fcolor, tcolor: Tcolor; StrYes, StrNo: shortstring; scalew, scaleh: Real): Boolean; 110 Ask_YesNoCheck( aOwner: TComponent; aCaption: string; strcoment1: string; fn1: integer; strcoment2: string; fn2: integer; var checked: boolean; fleft, ftop: integer; fcolor, tcolor: Tcolor; StrYes, StrNo: shortstring; scalew, scaleh: Real): Boolean; ExecMessages(aOwner: TComponent; aCaption: string; strcomment1: string; fn1: integer; strcomment2: string; fn2: integer; strcomment3: string; fn3: integer; fleft, ftop: integer; colorBar, colorBgr, colorTxt: Tcolor; fl_AlfaBlend: boolean; fullpath_help: string) ChoiseDay( self_ArmForm: TArmForm; self_Frame: TFrame; caption_text: string; left, top: integer; ccdate: TDateTime; ayear, amonth, aday: Integer; fl_AlfaBlend, fl_delButton: boolean; var chday: TDateTime): integer; ChoiseMonth( self_ArmForm: TArmForm; self_Frame: TFrame; caption_text: string; left, top: integer; ayear, amonth, endmonth: word; fl_AlfaBlend, fl_delbutton, fl_cngYear: boolean; var chyear, chMonth: word): integer; VI. Other ArM procedures and functions VI.1 Procedures and functions for processing strings LastPos(ch: char; ss: shortstring): integer; roundc(r1: double; deg: integer): double; lead_zeroi(ii: int64; cnt: word): shortstring; lead_zeror(rr: double; cnt, dec: word): shortstring; lead_zeros(s: shortstring; cnt: word): shortstring; fs_str(st: shortstring; d: integer; ch: char): shortstring; del_sbl(s: shortstring): shortstring; del_sbr(s: shortstring): shortstring; del_sblr(s: shortstring): shortstring; del_lasts0(s: shortstring): shortstring; split_name3(s: string; var s1, s2, s3: string); VI.2 Procedures and functions for processing graphical information DarkerColor(const Color: TColor; Percent: Integer): TColor; LighterColor(const Color: TColor; Percent: Integer): TColor; MixColors(const Colors: array of TColor): TColor; GrayColor(Color: TColor): TColor; make_mixed_colorN1(bcolor, mcolor: TColor; ncol: integer): TColor; GradientRect(FromRGB, ToRGB: TColor; Canvas: TCanvas); VI.3 Procedures and functions for RTF processing SRVE_StringReplace_All(SRVE: TSRichViewEdit; OldPattern, NewPattern: string): integer; 111 FillInTemplate(TemplateStream: TMemoryStream; var FilledInStream: TMemoryStream; KeyDelimiter: Char; MyNumberEquivalence: TMyNumberEquivalence); BitmapToRTF(pict: TBitmap; ScaleX, ScaleY: integer): string; PictToRTF(PictStream: TMemoryStream; PictName: string; PictWidth_cm: Double=0; PictHeight_cm: Double=0): string; PictFileToRTF(PictFileName: string; PictWidth_cm: Double=0; PictHeight_cm: Double=0): string; ExportSrveToPdf(srve: TSRichViewEdit; PdfFileName: string); ExportRtfFileToPdf(ParentForm: TForm; RtfFileName, PdfFileName: string; Overwrite: boolean); ExportRtfFileToHtml(ParentForm: TForm; RtfFileName, HtmlFileName: string; Overwrite: boolean); ConvertRTFtoOther(ParForm: TForm; SourceFileName, DestFileName: string; Overwrite: boolean); VconvertRTF(PrnForm: TForm; RtfFileName: string; ViewCase: Byte; params_3_6: string); BindRtfFiles(ParentForm: TForm; MainRtfFile, AddedRtfFile: string; AddPageBreak: boolean); VI.4 Procedures and functions for generating reports Create(afilename: shortstring; aarchd: TArm; p_l: char; nfont: integer; npixels: integer); SetIndex(aarchi: shortstring; acoordi: TCoordArray); SetTableParams(talign: char; tbrd: integer; len_table: integer); SetDefFont(nfont: integer; npixels: integer); SetDefAlign(align: char); WrtParBeg(align: char); WrtParEnd; WrtTit1(nfont: integer; npixels: integer; ss: string); mm2twips(Length_mm: integer): integer; WrtTableFromStringArray_Beg; WrtTableFromStringArray_End; SetRowParams_StrArr(ColCount: integer; TopBorderStyle, LeftBorderStyle, BottomBorderStyle, RightBorderStyle: char; BackgroundColor: integer; Bold, Italic: boolean; Alignment: char; Width: integer); EvaluateZeroWidthCells_StrArr; WrtTableRowFromStringArray(PRowElements : PRowElementsArray; fl_header: boolean; talign: char); WrtTableHeader; WrtTableRows; WrtTableBottom; WrtLine(sline: string); 112 WrtString(sline: string); WrtJpg(nam_jpg: shortstring; PictWidth_cm : Double = 0; PictHeight_cm : Double = 0); FinishRep; VI.5 Procedures and functions for working with nomenclatures StringToCoordArray(aString: string): TCoordArray; CoordArrayToString(aCoordArray: TCoordArray): string; RetCoords_NomElemData(NomNumber, CharNumber: integer; ID_String: string): TCoordArray; VI.6 Procedures and functions for working with Internet and FTP LoadURLArch(ModuleAbbr, Year2Digits, No_Firma, FTPHost, FTPUserName, FTPPass: string; FTPPort: integer; SourcePath, DestPath, UserNumber, UserInstallationNum: string): integer; UpLoadURLArch(ModuleAbbr, Year2Digits, No_Firma, FTPHost, FTPUserName, FTPPass: string; FTPPort: integer; SourcePath, DestPath, UserNumber, UserInstallationNum: string; DeleteSourceFiles: boolean=true): integer; FileExistFTP(FileName, FilePath, FTPHost, FTPUserName, FTPPass: string; FTPPort: integer): integer; DeleteFTP(FileName, FilePath, FTPHost, FTPUserName, FTPPass: string; FTPPort: integer): integer; RenameFTP(OldFileName, NewFileName, FilePath, FTPHost, FTPUserName, FTPPass: string; FTPPort: integer): integer; List_FTP_Dir(FileNameMask, FilePath, FTPHost, FTPUserName, FTPPass: string; FTPPort: integer; WithDetails: boolean; var Files_StrList: TStringList): integer; 113