Drawings SDK Developer Guide > Working with .dwg Files > Working with Databases > Working with Database Containers > Working with Dictionaries of Objects > Working with Specific Dictionaries > Multi-Line Styles Dictionary > Example of Working with the Multi-Line Style Dictionary
Example of Working with the Multi-Line Style Dictionary

This example demonstrates working with the multi-line style dictionary for adding, renaming, coping, deleting, modifying, and printing multi-line style objects. This example uses a console menu that represents the following operations: printing a list of the accessible multi-line styles [L], printing specific properties of all multi-line styles contained in the dictionary [P], exposing predefined multi-line style settings [E], creating a new multi-line style and adding it in the dictionary [A], renaming an existing multi-line style [N], copying one multi-line style to another [C], setting a multi-line style to be active [S], deleting an existing multi-line style [D], and modifying the specific properties of a selected multi-line style [M].

The example uses the following header files, examples, and functions implemented in them:


#include "..\Common\DemoMain.h"
#include "DbMlineStyle.h"
#include "DbDictionary.h"
#include <iostream>
using namespace std;

// Example of Working with the Multi-line Style Object
void PrintMLStyleProperties(OdDbMlineStyle* pMLStyle);
void ModifyMLStyleProperties(OdDbMlineStyle* pMLStyle);

// Example of Using the Record-Table and Dictionary Interfaces for Entering Names
OdString EntryRecordName(OdDbObject* pCollection, enum enumCheckName isExist = kDontCheck);

void PrintObjectProperties(OdDbObject* pObject);

The ModifyMLStyles() function requires a pointer to the database object in which it manipulates the multi-line styles. The function organizes a loop that inquires about the operation code and uses the switch statement to select whether the case must be performed. The function processes user actions in the loop until the user selects the [Q] operation. The function uses the PrintMLStyleProperties() function for displaying the specific properties of a multi-line style object, ModifyMLStyleProperties() function for modifying the properties of an existing multi-line style object, and the EntryRecordName() function for entering the external multi-line style name and checking whether this name is correct and exists or is absent from the dictionary. The DemoBase() function obtains the smart pointer to the multi-line style dictionary using the getMLStyleDictionaryId() method of the passed database object. The multi-line style dictionary object is not a predefined object and can be absent from the database, therefore the function passes True as an argument of this method to create the dictionary for multi-line styles if it is absent. Before the loop, the function declares a smart pointer to the iterator and a smart pointer to the multi-line style object.

When the user selects [L], the function displays a list of the external multi-line style names that are accessible in the dictionary. The function uses an iterator for traversing through the dictionary and the name() method of the iterator for displaying the external name of each multi-line style object to which the iterator refers. When the user selects [P], the function prints the specific properties of all multi-line style objects contained in the dictionary. The function uses an iterator for traversing through the dictionary and the getObject() method of the iterator for getting the smart pointer of the multi-line style object to which the iterator refers. The function displays the common object properties using the PrintObjectProperties() function and the specific multi-line style properties using the PrintMLStyleProperties() function. To traverse through the dictionary, the function creates a new iterator for each traverse using the newIterator() method, organizes a loop if the traverse is not completed using the done() method, moves the iterator to the next multi-line style object using the next() method, and gets the pointer to each multi-line style instance using the getObject() method of the iterator and get() method of the smart pointer.

When the user selects [A], the function inquires about the multi-line style name using the EntryRecordName() function. The name must be absent from the dictionary because the dictionary cannot contain duplicate names. The function passes the kMustAbsent value as an argument for checking the new name. If the entered name is correct and is absent from the dictionary, the function creates a new multi-line style object using its static pseudo-constructor. Then, the function assigns the specified name as the internal name using the setName() method of the multi-line style object, adds the new multi-line style object in the dictionary, and specifies the same name for it as the dictionary key using its setAt() method of the dictionary object. The function uses the try…catch statement to catch exceptions when the object is added. If the addition is successful, the function goes to the [L] operation for printing the multi-line stylelist. If an exception occurs, the function displays an error message and breaks to the console menu.

When the user selects [N], the function inquires about the name of the existing multi-line style object to be renamed and a new name using the EntryRecordName() function. The first name must exist in the dictionary; the function passes the kMustExist value as an argument for checking the entered name. The second name must be absent from the dictionary because it cannot contain duplicates; the function passes the kMustAbsent value as an argument for checking the new name. If both names are correct, the function calls the setName() method of the multi-line style object and passes to it the new name as an argument to change the internal name, and then, calls the setName() method of the dictionary object and passes to it the old and new names as arguments to change the external name. The external and internal names must coincide, otherwise errors occur. The function uses the try…catch statement to catch exceptions when the object changes names. If an exception occurs, the function displays an error message and breaks to the console menu.

When the user selects [C], the function inquires about the name of the existing multi-line style object whose setting must be replaced and the name of the existing multi-line style object whose setting must be copied using the EntryRecordName() function. Both names must exist in the dictionary; the function passes the kMustExist value as an argument for checking these names. If both names are correct, the function gets the smart pointers to both objects using the getAt() method of the dictionary object. Then, the function calls the set() method of the multi-line style object being replaced and passes to it the reference to the multi-line style object being copied. After copying, the function synchronizes the internal name of the replaced object with its external name in the dictionary and calls the setName() method, passing to it the external name (key). If an exception occurs, the function displays an error message and breaks to the console menu.

When the user selects [D], the function inquires about the name of the existing multi-line style object to be deleted using the EntryRecordName() function. The name must exist in the dictionary; the function passes the kMustExist value as an argument for checking the entered name. If the entered name is correct and exists, the function calls the remove() method of the dictionary object and passes to it the name as an argument to remove the multi-line style object from the dictionary. The removed multi-line style object continues to exist outside of the dictionary, therefore the function gets the OdDbObjectId instance associated with the removed object using the remove() method. To delete the removed object, the function uses the safeOpenObject() method to get a smart pointer to it, calls the erase() method of the object, and passes to it a True value as an argument. After deletion, the function checks the result returned by the erase() method. If the result is non-zero, the function displays an error message using the getErrorDescription() method of the host object.

When the user selects [E], the function displays the predefined multi-line setting using the getCMLSTYLE(), getCMLSCALE(), and getCMLJUST() methods of the database object. The getCMLSTYLE() method returns the Object ID of the current active multi-line style. The getCMLSCALE() method returns the default scale factor for new multi-line styles. The getCMLJUST() method returns the default justification for new multi-line styles.

When the user selects [S], the function inquires about the name of the existing multi-line style object which should be active using the EntryRecordName() function and passes to it the kMustExist value as an argument for checking the name. If the entered name is correct and exists in the table, the function gets the Object ID of the multi-line style object using the getAt() method, calls the setCMLSTYLE() method of the database object, passes to it the obtained Object ID as an argument, and goes to the [E] operation. The setCMLSTYLE() method makes the specified multi-line style active.

When the user selects [M], the function inquires about the name of the existing multi-line style object to be modified using the EntryRecordName() function. The name must exist in the dictionary; the function passes the kMustExist value as an argument for checking the entered name. If the entered name is correct and exists, the function gets a smart pointer to the multi-line style object specified by the name using the getAt() method and opens it in write mode. Then, the function calls the ModifyMLStyleProperties() function that organizes its own console menu for modifying the specific properties of the specified multi-line style object.

When the user selects [Q], the function ends the loop and returns to the calling function.

The ModifyMLStyles() function has the following implementation:


void ModifyMLStyles(OdDbDatabase* pDb)
{
  wchar_t ch = L'L';
  OdString sName, sNewName;
  OdResult result;

  OdDbDictionaryPtr pMLStyles = pDb->getMLStyleDictionaryId(true).safeOpenObject(OdDb::kForWrite);
  OdDbDictionaryIteratorPtr itMLStyle;
  OdDbMlineStylePtr pMLStyle;

  wcout << L"\n\nStart testing of multi-line styles";
  wcout << L"\nMulti-Line Style Class: " << OdDbMlineStyle::desc()->name() 
        << L", Container: " << pMLStyles->handle().ascii()
        << L", " << pMLStyles->isA()->name() << L"\n";

  do {
    switch(ch)
    {
      case L'A':          // Add a new multi-line style
      case L'a':
        wcout << L"\nEntry the name of a new multi-line style:>";
        if((sName = EntryRecordName(pMLStyles, kMustAbsent)).isEmpty()) break;

        pMLStyle = OdDbMlineStyle::createObject();
        
        try {
          pMLStyle->setName(sName);
          pMLStyles->setAt(sName, pMLStyle);
        }
        catch(OdError& e)
        {
          wcout << L"\nError: " << e.code() << L" - " << e.description() << L"\n";
          pMLStyle->erase();
          break;
        }


      case L'L':          // List the accessible multi-line styles
      case L'l':
        wcout << L"\nList of multi-line styles:\n"; 
        for(itMLStyle = pMLStyles->newIterator() ; !itMLStyle->done() ; itMLStyle->next())
          wcout << L"\"" << itMLStyle->name() << L"\"\n";
        break;


      case L'P':          // Print the specific properties of all multi-line styles
      case L'p':
        wcout << L"\nList of multi-line styles:"; 
        for(itMLStyle = pMLStyles->newIterator() ; !itMLStyle->done() ; itMLStyle->next())
        {
          pMLStyle = itMLStyle->getObject();
          wcout << L"\nH=" << pMLStyle->handle().ascii();
          PrintObjectProperties(pMLStyle);
          wcout << L"\n  ------ Specific Properties";
          PrintMLStyleProperties(pMLStyle.get());
        }
        wcout << L"\n";        
        break;


      case L'S':          // Set the current active multi-line style
      case L's':
        wcout << L"\nEntry the name of the multi-line style to be set active:>";
        if((sName = EntryRecordName(pMLStyles, kMustExist)).isEmpty()) break;

        pMLStyle = pMLStyles->getAt(sName, OdDb::kForRead);

        pDb->setCMLSTYLE(pMLStyle->objectId());


      case L'E':          // Expose the predefined multi-line settings
      case L'e':
        pMLStyle = pDb->getCMLSTYLE().safeOpenObject();
        wcout << L"\nCurrent active multi-line style: \"" << pMLStyle->name() << L"\""
              << L"\nCurrent multi-line scale factor = " << pDb->getCMLSCALE() 
              << L"\nCurrent multi-line justification = " << pDb->getCMLJUST() << L"\n";
        break;


      case L'N':          // Rename the selected multi-line style
      case L'n':
        wcout << L"\nEntry the name of the multi-line style to be renamed:>";
        if((sName = EntryRecordName(pMLStyles, kMustExist)).isEmpty()) break;

        pMLStyle = pMLStyles->getAt(sName, OdDb::kForWrite);

        wcout << L"\nEntry the new name of the multi-line style:>";
        if((sNewName = EntryRecordName(pMLStyles, kMustAbsent)).isEmpty()) break;

        try {
          pMLStyle->setName(sNewName);     
          pMLStyles->setName(sName, sNewName);
        }
        catch(OdError& e) { wcout << L"\nError: " << e.code() << L" - " << e.description() << L"\n"; }
        break;


      case L'C':          // Copy a one multi-line style to another
      case L'c':
        wcout << L"\nEntry the name of the multi-line style to be replaced:>";
        if((sName = EntryRecordName(pMLStyles, kMustExist)).isEmpty()) break;

        pMLStyle = pMLStyles->getAt(sName, OdDb::kForWrite);

        wcout << L"\nEntry the name of the multi-line style to be copied:>";
        if((sNewName = EntryRecordName(pMLStyles, kMustExist)).isEmpty()) break;

        try {
          pMLStyle->set( *((OdDbMlineStyle*)pMLStyles->getAt(sNewName, OdDb::kForRead).get()) );
          pMLStyle->setName(sName);
        }
        catch(OdError& e) { wcout << L"\nError: " << e.code() << L" - " << e.description() << L"\n"; }
        break;


      case L'D':          // Delete the selected multi-line style
      case L'd':
        wcout << L"\nEntry the name of the multi-line style to be deleted:>";
        if((sName = EntryRecordName(pMLStyles, kMustExist)).isEmpty()) break;

        pMLStyle = pMLStyles->remove(sName).safeOpenObject(OdDb::kForWrite);

        result = pMLStyle->erase(true);

        if(result) wcout << L"\nError: " << result << L" - " 
                         << pDb->appServices()->getErrorDescription(result) << L"\n"; 
        break;


      case L'M':          // Modify the selected multi-line style
      case L'm':
       	wcout << L"\nEntry the name of the multi-line style to be modified:>";
        if((sName = EntryRecordName(pMLStyles, kMustExist)).isEmpty()) break;

        pMLStyle = pMLStyles->getAt(sName, OdDb::kForWrite);

        ModifyMLStyleProperties(pMLStyle.get());
        break;


      case L'\0':         // Skip an action
        break;

      default:
        wcout << L"Error: Incorrect operation\n";
    }
    wcout << L"\nL. List the accessible multi-line styles";
    wcout << L"\nP. Print the properties of multi-line styles";
    wcout << L"\nS. Set the current active multi-line style";
    wcout << L"\nE. Expose the predefined multi-line settings";
    wcout << L"\nA. Add a new multi-line style";
    wcout << L"\nC. Copy one multi-line style to another";
    wcout << L"\nN. Rename the selected multi-line style";
    wcout << L"\nM. Modify the selected multi-line style";
    wcout << L"\nD. Delete the selected multi-line style";
    wcout << L"\nQ. Quit";
    wcout << L"\nSelect operation:>";
    wcin >> ch;
  }
  while(ch != L'Q' && ch != L'q');

  wcout << L"Stop testing of multi-line styles\n";
}

Testing gives the following results:


Start testing of multi-line styles
Multi-Line Style Class: AcDbMlineStyle, Container: 17, AcDbDictionary

List of multi-line styles:
"Standard"

L. List the accessible multi-line styles
P. Print the properties of multi-line styles
S. Set the current active multi-line style
E. Expose the predefined multi-line settings
A. Add a new multi-line style
C. Copy one multi-line style to another
N. Rename the selected multi-line style
M. Modify the selected multi-line style
D. Delete the selected multi-line style
Q. Quit
Select operation:>

When the operation is A-"Add a new multi-line style":


Entry the name of a new multi-line style:>Style1
List of multi-line styles:
"Standard"
"Style1"

When the operation is A-"Add a new multi-line style" and the name exists in the dictionary:


Entry the name of a new multi-line style:>Standard
Error: the name "Standard" - already exists

When the operation is A-"Add a new multi-line style" and the name is incorrect:


Entry the name of a new multi-line style:>st*l?
Error: the name contains inadmissible letters: <>/\":;?,|=`

When the operation is N-"Rename the selected multi-line style":


Entry the name of the multi-line style to be renamed:>Style1
Entry the new name of the multi-line style:>MLStyle

When the operation is N-"Rename the selected multi-line style" and the name is absent from the dictionary:


Entry the name of the multi-line style to be renamed:>Style1
Error: the name "Style1" - is not found

When the operation is M-"Modify the selected multi-line style":


Entry the name of the multi-line style to be modified:>MLStyle

Start modifying of the multi-line style properties
Selected multi-line style: "MLStyle"
C. Set the fill color
F. Set the fill status
D. Set the description
M. Set the miter status
--------------------------------
1. Set the start angle cap
2. Set the start square cap
3. Set the start outer round cap
4. Set the start inner round cap
5. Set the end angle cap
6. Set the end square cap
7. Set the end outer round cap
8. Set the end inner round cap
--------------------------------
A. Add a new element
a. Add an element by offset
R. Remove an existing element
S. Set the element properties
L. Print the list of elements
P. Print the whole properties
p. Print the specific properties
Q. Quit
Select operation:>M

Set the miter status [N-on|F-off]:>N
Miter status is set to: On

Select operation:>1

Current start angle cap = 1.5708
Entry a new angle [1/18 PI to 17/18 PI]:>0.785
Start angle cap is set to: 0.785 radians

Select operation:>5

Current end angle cap = 1.5708
Entry a new angle [1/18 PI to 17/18 PI]:>2.867
End angle cap is set to: 2.867 radians

Select operation:>2

Set the start square cap [N-on|F-off]:>N
Start square cap is set to: On

Select operation:>7

Set the end outer round cap [N-on|F-off]:>N
End outer round cap is set to: On

Select operation:>a

Entry an offset for new element:>0.2

  ------ Multi-Line Style Elements
  0. Offset=0.2, Color=[Foreground], [16-"Continuous"-Linetype]

Select operation:>a

Entry an offset for new element:>-0.4

  ------ Multi-Line Style Elements
  0. Offset=0.2, Color=[Foreground], [16-"Continuous"-Linetype]
  1. Offset=-0.4, Color=[Foreground], [16-"Continuous"-Linetype]
  
Select operation:>Q
Stop modifying of the multi-line style properties

When the operation is P-"Print the properties of multi-line styles":


List of multi-line styles:
H=18
  Type: AcDbMlineStyle
  Status: unerased,resident,forRead
  Database: c:\test.dwg
  ------ Specific Properties
  Key = <Standard>
  Name = "Standard"
  Elements = 2
  Fill color = [byLayer]
  Fill status = Off
  Miter status = Off
  Start angle cap = 1.5708 radians
  Start square cap = Off
  Start outer round cap = Off
  Start inner round cap = Off
  End angle cap = 1.5708 radians
  End square cap = Off
  End outer round cap = Off
  End inner round cap = Off
  Description = ""
H=6A
  Type: AcDbMlineStyle
  Status: unerased,resident,forRead
  Database: c:\test.dwg
  ------ Specific Properties
  Key = <MLStyle>
  Name = "MLStyle"
  Elements = 2
  Fill color = [byLayer]
  Fill status = Off
  Miter status = On
  Start angle cap = 0.785 radians
  Start square cap = On
  Start outer round cap = Off
  Start inner round cap = Off
  End angle cap = 2.867 radians
  End square cap = Off
  End outer round cap = On
  End inner round cap = Off
  Description = ""

When the operation is E-"Expose the predefined multi-line settings":


Current active multi-line style: "Standard"
Current multi-line scale factor = 1
Current multi-line justification = 0

When the operation is C-"Copy one multi-line style to another":


Entry the name of the multi-line style to be replaced:>Standard
Entry the name of the multi-line style to be copied:>MLStyle

When the operation is P-"Print the properties of multi-line styles":


List of multi-line styles:
H=18
  Type: AcDbMlineStyle
  Status: unerased,resident,modified,forRead,forWrite
  Database: c:\test.dwg
  ------ Specific Properties
  Key = <Standard>
  Name = "Standard"
  Elements = 2
  Fill color = [byLayer]
  Fill status = Off
  Miter status = On
  Start angle cap = 0.785 radians
  Start square cap = On
  Start outer round cap = Off
  Start inner round cap = Off
  End angle cap = 2.867 radians
  End square cap = Off
  End outer round cap = On
  End inner round cap = Off
  Description = ""
H=6A
  Type: AcDbMlineStyle
  Status: unerased,resident,forRead
  Database: c:\test.dwg
  ------ Specific Properties
  Key = <MLStyle>
  Name = "MLStyle"
  Elements = 2
  Fill color = [byLayer]
  Fill status = Off
  Miter status = On
  Start angle cap = 0.785 radians
  Start square cap = On
  Start outer round cap = Off
  Start inner round cap = Off
  End angle cap = 2.867 radians
  End square cap = Off
  End outer round cap = On
  End inner round cap = Off
  Description = ""

When the operation is S-"Set the current active multi-line style":


Entry the name of the multi-line style to be set active:>MLStyle
Current active multi-line style: "MLStyle"
Current multi-line scale factor = 1
Current multi-line justification = 0

When the operation is D-"Delete the selected multi-line style":


Entry the name of the multi-line style to be deleted:>standard

When the operation is D-"Delete the selected multi-line style" and the multi-line style is absent from the dictionary or the object was already deleted:


Entry the name of the multi-line style to be deleted:>standard
Error: the name "standard" - is not found

When the operation is P-"Print the properties of multi-line styles":


List of multi-line styles:
H=6A
  Type: AcDbMlineStyle
  Status: unerased,resident,forRead
  Database: c:\test.dwg
  ------ Specific Properties
  Key = <MLStyle>
  Name = "MLStyle"
  Elements = 2
  Fill color = [byLayer]
  Fill status = Off
  Miter status = On
  Start angle cap = 0.785 radians
  Start square cap = On
  Start outer round cap = Off
  Start inner round cap = Off
  End angle cap = 2.867 radians
  End square cap = Off
  End outer round cap = On
  End inner round cap = Off
  Description = ""

Use the Q-"Quit" operation to exit:


Stop testing of multi-line styles

See Also

Working with Multi-Line Styles

Example of Working with the Multi-Line Style Object

Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.