Drawings SDK Developer Guide > Working with .dwg Files > Working with Databases > Working with Database Containers > Working with Predefined Tables of Named Records > Working with Specific Predefined Tables of Named Records > Linetypes Table > Example of Working with the Linetype Table Object
Example of Working with the Linetype Table Object

The example demonstrates working with the linetype table object for adding, renaming, deleting, recovering, modifying and printing of linetype record objects. This example uses a console menu to represent the following operations: printing the list of accessible linetypes [L], printing the specific properties of all linetypes contained in the table [P], exposing the predefined linetypes [E], creating a new linetype and adding it in the table [A], renaming an existing linetype [N], deleting an existing linetype [D], recovering a deleted linetype [R], and setting a linetype to be the active linetype [S].

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


#include "..\Common\DemoMain.h"
#include "DbLinetypeTable.h"
#include "DbLinetypeTableRecord.h"
#include <iostream>
using namespace std;

// Example of Working with the Linetype Record Object
void PrintLinetypeProperties(OdDbLinetypeTableRecord* pLinetype);
void ModifyLinetypeProperties(OdDbLinetypeTableRecord* pLinetype);

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

The ModifyLinetypes() function requires the pointer to the database object and implements the console menu for the listed operations. The function creates the loop that asks for the operation code and uses the switch statement to select whether the case must be performed. The ModifyLinetypes() function uses the PrintLinetypeProperties() function for printing the specific properties of the linetype record object, ModifyLinetypeProperties() function for modifying the specific properties of the selected linetype record object, and EntryRecordName() function for entering the linetype name and checking whether the name is correct and whether the name exists or is absent from the table. The EntryRecordName() function returns the entered name as an OdString value when the name is correct for the specified options, or it returns an empty string when the name is incorrect or is conflict with other names. The ModifyLinetypes() function obtains a smart pointer to the linetype table object using the getLinetypeTableId() method of the passed database object. Before the loop, the function creates an iterator using the newIterator() method of the linetype table object and declares the smart pointer to the linetype record object. The ModifyLinetypes() function processes user actions in the loop until the user selects the [Q] operation.

When the user selects [L], the ModifyLinetypes() function prints the list of linetype names accessed in the linetype table. The function uses the iterator for traversing through the linetype table, getRecord() method of the Iterator object for getting the pointer to each linetype record object, and getName() method for displaying the name for the each linetype record object to which the iterator refers. When the user selects [P], the function prints the specific properties of all linetype record objects contained in the linetype table object, including objects marked as "erased". The function uses the iterator for traversing through the linetype table and the PrintLinetypeProperties() function for displaying specific properties of the linetype record object to which the iterator refers. For the [P] operation, the function initializes the start() method of the iterator using parameters: True – begriming with the first record to the end record of the table, False – the record marked as unerased or erased, and the step() method of the iterator using parameters: True – traversing to the next record in the table, False – including the unerased and erased records. For the [L] operation, the function initializes the arguments of the start() and step() methods using default values:  True – beginning with the first record to the next record, and True – only unerased records. When a linetype record object is permanently deleted, the getRecord() method returns NULL, and the function and iterator skip the record.

When the user selects [A], the ModifyLinetypes() function inquires about the name of a new linetype record object using the EntryRecordName() function. The name must be absent from the linetype table because the table cannot contain duplicate records; the function passes the kMustAbsent value as the second argument for checking the new name. If the entered name is correct and absent from the table, the function creates a new linetype record object using its static pseudo-constructor. Then, the function sets the specified name for the created linetype record object using its setName() method and adds the new linetype in the linetype table using the add() method of the linetype table 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 of the linetype list. When an exception occurs, the function displays the error message and breaks to the console menu.

When the user selects [N], the ModifyLinetypes() function inquires about the name of the existing linetype record object to be renamed and inquires about the new name using the EntryRecordName() function for both names. The first name must exist in the linetype table; the function passes the kMustExist value as the second argument for checking the entered name. The second name must be absent from the linetype table because the table can not contain duplicate records; the function passes the kMustAbsent value as the second argument for checking the new name. If the first entered name is correct and exists in the table, the function gets a smart pointer to the corresponding linetype record object using the getAt() method of the linetype table object and opens it in write mode. Then, the function sets the second name as a new name of the opened linetype record object using the its setName() method. The function uses the try…catch statement to catch exceptions when the object changes the name. When an exception occurs, the function displays an error message and breaks to the console menu.

When the user selects [D], the ModifyLinetypes() function inquires about the name of the existing linetype record object to be deleted using the EntryRecordName() function. The name must exist in the linetype table; the function passes the kMustExist value as the second argument for checking the entered name. If the entered name is correct and exists in the table, the ModifyLinetypes() function gets the smart pointer to the corresponding linetype record object using the getAt() method of the linetype table object and opens it in write mode. The function passes a False value as the third argument of the getAt() method that identifies the unerased record of the table. If the getAt() method returns the pointer to the specified linetype record object, the function calls the erase() method of the linetype record object and passes to it a True value as an argument. The erase(true) method marks the linetype record object as "erased" and keeps it in the table if and only if the database is performing an undo procedure, otherwise the object is deleted permanently. After deleting, the function checks the result returned by the erase() method. If the result is zero, the deleting was successful, and the function breaks to the the console menu. If the result is non-zero, the function displays an error message using the getErrorDescription() method of the host object.

When the user selects [R], the ModifyLinetypes() function inquires about the name of the deleted linetype record object to be recovered using the EntryRecordName() function. The name must absent from the linetype table because the deleted record is not accessible in the table; the function passes the kMustAbsent value as the second argument for checking the entered name. If the entered name is correct and absent from the table, the ModifyLinetypes() function tries to get the smart pointer to the corresponding linetype record object using the getAt() method of the linetype table object and tries to open it in write mode, but the function passes a True value as the third argument of the getAt() method that identifies the erased record of the table. If the getAt() method returns NULL, the linetype record object was deleted permanently and recovery is impossible. In this case, the function displays an error message and breaks to the console menu. If the getAt() method returns the pointer to the deleted linetype record object, the function calls the erase() method of the linetype record object and passes to it a False value as an argument.  The erase(false) method marks the linetype record object as "unerased" and the record becomes accessible in the table. After recovery, the function checks the result returned by the erase() method. If the result is zero, recovery was successful, and the function breaks to the the console menu. If the result is non-zero, the function displays an error message using the getErrorDescription() method of the host object.

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

When the user selects [S], the ModifyLinetypes() function inquires about the name of the existing linetype record object to be set as the active linetype using the EntryRecordName() function. The name must exist in the linetype table; the function passes the kMustExist value as the second argument for checking the entered name. If the entered name is correct and exists in the table, the ModifyLinetypes() function gets the Object ID of the linetype record object using the getAt() method and passes the Object ID as an argument of the setCELTYPE() method of the database object. The setCELTYPE() method makes the specified linetype active.

When the user selects [E], the ModifyLinetypes() function displays the predefined linetypes using the getCELTYPE(), getLinetypeByLayerId(), getLinetypeByBlockId(), and getLinetypeContinuousId() methods of the database object. The getCELTYPE() method returns the Object ID of the current active linetype.

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

The ModifyLinetypes() function has the following implementation:


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

  OdDbLinetypeTablePtr pLinetypes = pDb->getLinetypeTableId().safeOpenObject(OdDb::kForWrite);
  OdDbLinetypeTableIteratorPtr itLinetype = pLinetypes->newIterator();
  OdDbLinetypeTableRecordPtr pLinetype;

  wcout << L"\n\nStart modifying of linetypes"
        << L"\nLinetype's Table: " << pLinetypes->handle().ascii() 
        << L", Class: " << OdDbLinetypeTable::desc()->name() 
        << L", Record: " << OdDbLinetypeTableRecord::desc()->name()
        << L", Iterator: " << itLinetype->isA()->name() << L"\n";

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

        pLinetype = OdDbLinetypeTableRecord::createObject();
        
        try {
          pLinetype->setName(sName);     
          pLinetypes->add(pLinetype);
        }
        catch(OdError& e)
        {
          wcout << L"\nError: " << e.code() << L" - " << e.description() << L"\n";
          pLinetype->erase();
          break;
        }


      case L'L':          // List the accessible linetypes
      case L'l':
        wcout << L"\nList of the accessible linetypes:\n"; 
        for(itLinetype->start() ; !itLinetype->done() ; itLinetype->step())
        {
          wcout << "\"" << itLinetype->getRecord()->getName() << L"\"\n";
        }
        break;


      case L'P':          // Print the specific properties of all linetypes
      case L'p':
        wcout << L"\nList the specific properties of linetypes:"; 
        for(itLinetype->start(true, false) ; !itLinetype->done() ; itLinetype->step(true, false))
        {
          pLinetype = itLinetype->getRecord(OdDb::kForRead, true);
          if(!pLinetype.isNull()) PrintLinetypeProperties(pLinetype.get());
        }
        wcout << L"\n";
        break;


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

        pDb->setCELTYPE(pLinetypes->getAt(sName));
        break;


      case L'E':          // Expose the predefined linetypes
      case L'e':
        pLinetype = pDb->getLinetypeByLayerId().safeOpenObject(OdDb::kForRead);
        wcout << L"\nByLayer linetype: \"" << pLinetype->getName() << L"\"";

        pLinetype = pDb->getLinetypeByBlockId().safeOpenObject(OdDb::kForRead);
        wcout << L"\nByBlock linetype: \"" << pLinetype->getName() << L"\"";

        pLinetype = pDb->getLinetypeContinuousId().safeOpenObject(OdDb::kForRead);
        wcout << L"\nContinuous linetype: \"" << pLinetype->getName() << L"\"";

        pLinetype = pDb->getCELTYPE().safeOpenObject();
        wcout << L"\nCurrent active linetype: \"" << pLinetype->getName() << L"\"\n";
        break;


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

        pLinetype = pLinetypes->getAt(sName, OdDb::kForWrite);

        wcout << L"\nEntry the new linetype name:>";
        if((sName = EntryRecordName(pLinetypes, kMustAbsent)).isEmpty()) break;

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


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

        pLinetype = pLinetypes->getAt(sName, OdDb::kForWrite, false);

        if(pLinetype->objectId() == pDb->getLinetypeByLayerId())
        {
          wcout << L"\nError: The predefined ByLayer linetype can not be deleted\n";
          break;
        }
        if(pLinetype->objectId() == pDb->getLinetypeByBlockId())
        {
          wcout << L"\nError: The predefined ByBlock linetype can not be deleted\n";
          break;
        }
        if(pLinetype->objectId() == pDb->getLinetypeContinuousId())
        {
          wcout << L"\nError: The predefined Continuous linetype can not be deleted\n";
          break;
        }
        if(pLinetype->objectId() == pDb->getCELTYPE())
        {
          wcout << L"\nError: Current active linetype can not be deleted\n";
          break;
        }

        result = pLinetype->erase(true);

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


      case L'R':          // Recover the deleted linetype
      case L'r':
        wcout << L"\nEntry the linetype name to be recovered:>" ;
        if((sName = EntryRecordName(pLinetypes, kMustAbsent)).isEmpty()) break;

        pLinetype = pLinetypes->getAt(sName, OdDb::kForWrite, true);

        if(pLinetype.isNull())
        {
          wcout << L"\nThe linetype \"" << sName << L"\" - was deleted permanently\n";
          break;
        }

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


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

        pLinetype = pLinetypes->getAt(sName, OdDb::kForWrite);

        ModifyLinetypeProperties(pLinetype.get());
        break;


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

      default:
        wcout << L"Incorrect operation\n";
    }
    wcout << L"\nL. List the accessible linetypes";
    wcout << L"\nP. Print the properties of all linetypes";
    wcout << L"\nE. Expose the predefined linetypes";
    wcout << L"\nA. Add a new linetype";
    wcout << L"\nS. Set the current active linetype";
    wcout << L"\nN. Rename the selected linetype";
    wcout << L"\nM. Modify the selected linetype";
    wcout << L"\nD. Delete the selected linetype";
    wcout << L"\nR. Recover the deleted linetype";
    wcout << L"\nQ. Quit";
    wcout << L"\nSelect operation:>";
    wcin >> ch;
  }
  while(ch != L'Q' && ch != L'q');

  wcout << L"Stop modifying of linetypes\n";
}

Testing gives the following results:


Start modifying of linetypes
Linetype's Table: 5, Class: AcDbLinetypeTable, Record: AcDbLinetypeTableRecord, Iterator: OdDbLinetypeTableIterator

List of the accessible linetypes:
"ByBlock"
"ByLayer"
"Continuous"

L. List the accessible linetypes
P. Print the properties of all linetypes
E. Expose the predefined linetypes
A. Add a new linetype
S. Set the current active linetype
N. Rename the selected linetype
M. Modify the selected linetype
D. Delete the selected linetype
R. Recover the deleted linetype
Q. Quit
Select operation:>

When the operation is A-"Add a new linetype":


Entry the name of a new linetype:>Dashes
List of the accessible linetypes:
"ByBlock"
"ByLayer"
"Continuous"
"Dashes"

When the operation is A-"Add a new linetype" and the name exists in the table:


Entry the name of a new linetype:>Continuous
Error: the name "Continuous" - already exists

When the operation A-"Add a new linetype" and the name is incorrect:


Entry the name of a new linetype:>Da?h:s
Error: the name contains inadmissible letters: <>/\":;?,|=`

When the operation is N-"Rename the selected linetype":


Entry the linetype name to be renamed:>Dashes
Entry the new linetype name:>DashDot

When the operation is N-"Rename the selected linetype" and the name is absent from the table:


Entry the linetype name to be renamed:>Dashes
Error: the name "Dashes" - is not found

When the operation is N-"Rename the selected linetype" and the name is incorrect:


Entry the linetype name to be renamed:>DashDot
Entry the new linetype name:>Da?h:s
Error: the name contains inadmissible letters: <>/\":;?,|=`

When the operation is N-"Rename the selected linetype" and the new name exists in the table:


Entry the linetype name to be renamed:>DashDot
Entry the new linetype name:>Continuous
Error: the name "Continuous" - already exists

Repeat the operation A-"Add a new linetype":


Entry the name of a new linetype:>GAS-Line
List of the accessible linetypes:
"ByBlock"
"ByLayer"
"Continuous"
"DashDot"
"GAS-Line"

When the operation is S-"Set the current active linetype":


Entry the linetype name to be set active:>GAS-Line

When the operation is E-"Expose the predefined linetypes":


ByLayer linetype: "ByLayer"
ByBlock linetype: "ByBlock"
Continuous linetype: "Continuous"
Current active linetype: "GAS-Line"

When the operation is D-"Delete the selected linetype":


Entry the linetype name to be deleted:>DashDot

When the operation is D-"Delete the selected linetype" and the name is absent from the table or the record is already deleted:


Entry the linetype name to be deleted:>DashDot
Error: the name "DashDot" - is not found

When the operation is D-"Delete the selected linetype" and the linetype is active or is predefined:


Entry the linetype name to be deleted:>GAS-Line
Error: Current active linetype can not be deleted

Entry the linetype name to be deleted:>byLayer
Error: The predefined ByLayer linetype can not be deleted

When the operation is M-"Modify the selected linetype":


Entry the linetype name to be modified:>GAS-Line
Start modifying of the linetype properties

Selected linetype: "GAS-Line"
P. Print the specific properties
D. Set the description
F. Set the scale to fit flag
N. Set the number of dashes
L. Set the pattern length
M. Modify the selected dash
Q. Quit
Select operation:>N

Number of dashes = 0
Entry a new number:>2
Number of dashes is set to: 2

Select operation:>L

Pattern length = 0
Entry a new length:>1.4
Pattern length is set to: 1.4

Select operation:>Q
Stop modifying of the linetype properties

When the operation is P-"Print the specific properties of all linetypes":


List the specific properties of linetypes:
H=14
  Name = "ByBlock"
  Status: unerased,resident
  Pattern length = 0
  Number of dashes = 0
H=15
  Name = "ByLayer"
  Status: unerased,resident
  Pattern length = 0
  Number of dashes = 0
H=16
  Name = "Continuous"
  Status: unerased,resident
  Pattern length = 0
  Number of dashes = 0
H=40
  Name = "DashDot"
  Status: erased,resident
  Pattern length = 0
  Number of dashes = 0
H=41
  Name = "GAS-Line"
  Status: unerased,resident
  Pattern length = 1.4
  Number of dashes = 2
  Dash (0) relative,inline, Style=[Db:kNull], Shape=0, Text=""
  Length=0, Scale=0, Angle=0, Offset=(0,0)
  Dash (1) relative,inline, Style=[Db:kNull], Shape=0, Text=""
  Length=0, Scale=0, Angle=0, Offset=(0,0)

When the operation is L-"List the accessible linetypes":


List of the accessible linetypes:
"ByBlock"
"ByLayer"
"Continuous"
"GAS-Line"

When the operation is R-"Recover the deleted linetype":


Entry the linetype name to be recovered:>DashDot

When the operation is L-"List the accessible linetypes":


List of the accessible linetypes:
"ByBlock"
"ByLayer"
"Continuous"
"DashDot"
"GAS-Line"

When the operation is R-"Recover the deleted linetype" and the name is absent from the table or the record is permanently deleted:


Entry the linetype name to be recovered:>Dot
The linetype "Dot" - was deleted permanently

Use the Q-"Quit" operation to exit:


Stop modifying of linetypes

See Also

Working with Linetypes

Organization of Linetypes

Example of Working with the Linetype Dash

Example of Working with the Linetype Record Object

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