Difficulty Getting DocumentType From Document

Difficulty Getting DocumentType From Document

TheRealChrisHildebran
Advocate Advocate
1,472 Views
13 Replies
Message 1 of 14

Difficulty Getting DocumentType From Document

TheRealChrisHildebran
Advocate
Advocate

Why cant we get the DocumentType from a Document? 

 

Unless im missing the point, and im certainly not immune to it, it seems we should easily be able to get the DocumentType any time we have a Document object

 

In my case im check to see if a documnet is a Template (DocumentType.Template) and if so quietly return.

 

The only way i know how to is using the DocumentOpeningEvent which certainly is an option. Seems odd to have to do that though considering the Document class has the property "IsFamilyDocument". Perhaps another property "IsTemplateDocument". 

0 Likes
Accepted solutions (1)
1,473 Views
13 Replies
Replies (13)
Message 2 of 14

kraftwerk15
Advocate
Advocate

This is dependent on what event you are trying to get this information from. Are you listening on the Opening Event as you mention, Save Event, or are you trying to gather this from an ExternalCommand?

 

Below is a sample from an event:

/// <summary>
        /// Called when [document closing].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="DocumentClosingEventArgs" /> instance containing the event data.</param>
        /// ReSharper disable once MemberCanBeMadeStatic.Local
        private void OnDocumentClosing(object sender, DocumentClosingEventArgs args)
        {
            try
            {           
                if (Path.GetExtension(args.Document.PathName).Equals(".rvt", StringComparison.CurrentCultureIgnoreCase)
                    && !args.Document.IsFamilyDocument && args.Document.PathName != string.Empty)
                {
......
}
}
}

It does not have to be done like this, but this is a sample.

 

From an ExternalCommand:

 

[Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    public class LaunchSomething : IExternalCommand
    {
        /// <summary>
        /// Executes the specified Revit command <see cref="ExternalCommand"/>.
        /// The main Execute method (inherited from IExternalCommand) must be public.
        /// </summary>
        /// <param name="commandData">The command data / context.</param>
        /// <param name="message">The message.</param>
        /// <param name="elements">The elements.</param>
        /// <returns>The result of command execution.</returns>
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try
            {
                Document doc = commandData.Application.ActiveUIDocument.Document);
                
                    return Result.Succeded;
            }
            catch (Exception ex)
            {
                return Result.Failed;
            }
        }
    }
Message 3 of 14

jeremytammik
Autodesk
Autodesk

You can use IsFamilyDocument for one check, and check the filename extension for others.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 4 of 14

TheRealChrisHildebran
Advocate
Advocate

Micah and Jeremy, thank you for your feedback; it is appreciated. 

I dont think i phrased my original question/rant well or succinctly enough though.

 

The solution i'd already taken was to look at the file extension of the Document using switch/case then return the appropriate DocumentType enumeration. It works fine but this method just seems wrong to me though. Now i still have to handle all possible DocumentTypes. Another switch/case.

 

 

We can get the Category of an Element at any time. 

We can get the CategoryType of a Category at any time.

Why cant we get the DocumentType of a Document at any time?

 

 

0 Likes
Message 5 of 14

jeremytammik
Autodesk
Autodesk

What do you need it for?

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 6 of 14

kraftwerk15
Advocate
Advocate

Well you can get the DocumentType at any time, just not directly from the document. Don't know why, that's up to the API gods.

 

Until then, as I suggested above, Document.PathName will get you the answer.

 

Here is a little helper method I found somewhere that is useful for things like this. Pass in a path, get back a ItemType. Pretty much what you're asking for. Bear in mind, this will only give you a quick check and there are probably better ways to get it using System File or something like this.

 

 

public static class ItemTypeHelper
    {
        #region public methods

        /// <summary>
        /// Gets the type of the item based on the full path to the file.
        /// </summary>
        /// <param name="fullPath">The full path.</param>
        /// <returns></returns>
        public static ItemType GetType(string fullPath)
        {
            // check if provided full path is valid.
            if (string.IsNullOrEmpty(fullPath))
                return ItemType.None;

            // Determine item type.
            if (fullPath.Contains(".rvt") || fullPath.Contains(".rte"))
                return ItemType.Project;
            else if (fullPath.Contains(".rfa"))
                return ItemType.Family;
            else if (fullPath.Contains(".dwg") || fullPath.Contains(".dxf") || fullPath.Contains(".sat"))
                return ItemType.Cad;
            else if (fullPath.Contains(".doc") || fullPath.Contains(".docx") || fullPath.Contains(".pdf") || fullPath.Contains(".txt") || fullPath.Contains(".csv"))
                return ItemType.Document;
            else
                return ItemType.None;
        }

        #endregion
    }

 

 

Message 7 of 14

TheRealChrisHildebran
Advocate
Advocate

Jeremy, for our company we have a couple of processes that would use the easier theoretical "Document.DocumentType" property i mentioned.

  • We have notifcations sent if a user is opening, linking, certain document types.
  • We have process that watches for third party addin "quietly" opening Documents and attempting to transfer standards or similar operation.

The watching had become necessary to keep our projects uniform and clean.

 

Perhaps it seems that the property mentioned would be seldomly used.

 

Perhaps if we had access to it, more uses would come. I dont know but regardless of that it would be so much cleaner than a switch/case block .

 

 

0 Likes
Message 8 of 14

TheRealChrisHildebran
Advocate
Advocate

Thanks again Micah, ive already been using .PathName in a switch/case block returning the DocumentType Enumeration. I just posed the question to see why must we do this rather than simply have it available from the Document. 

Message 9 of 14

jeremytammik
Autodesk
Autodesk
Accepted solution

Dear Chris,

 

Yes, I fully agree, that makes perfect sense, and Micah's pre-existing implementation proves the usefulness for others as well.

 

I would recommend searching for a corresponding wish list for this in the Revit Idea Station, and adding your comments there, or creating a new entry, if there is none already present there yet for the suggested functionality:

 

https://forums.autodesk.com/t5/revit-ideas/idb-p/302

 

Tag it as an API wish:

 

https://forums.autodesk.com/t5/revit-ideas/idb-p/302/tab/most-recent/label-name/api

 

Ensure it gets as many votes as possible to underline its importance to you and the rest of the developer community.

 

The Revit Idea Station is currently one of the main driving input forces for Revit API enhancements.

 

The Revit development team look there. Your comment here in the discussion forum might be overlooked.

 

Thank you!

 

Cheers, Jeremy.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 10 of 14

jeremytammik
Autodesk
Autodesk

I like this method and its implementation.

  

I am not a great fan of the method and enumeration naming, though.

 

GetType is a standard method of the .NET base Object class.

 

ItemType is an awfully generic name used all over the place, including within the Revit API, by a RibbonItem to return its RibbonItemType:

  

https://www.revitapidocs.com/2020/a2684698-096c-d278-a29f-698bc487716c.htm

  

So you have set yourself up to become well confused.

  

Thank you very much for the suggestion anyway!

 

It definitely seems to me to be the simplest solution to the needs expressed here.

  



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 11 of 14

TheRealChrisHildebran
Advocate
Advocate

Jeremy, i attempted to submit an idea (using Chrome and then Firefox) but the required dropdown to select a product, had nothing to select from!

 

See attached screenshot.

 

 

0 Likes
Message 12 of 14

TripleM-Dev.net
Advisor
Advisor

Hi,

 

I would recommend replacing ".Contains" with ".EndsWidth" and also make sure to ignore Case.

now a file with ".Rvt" won't be recognized, and a dwg named:  exportrvt.dwg would be considered a Revit project file.

 

All together use Path.GetExtension, and lowercase result and use a Switch?

System.IO.Path.GetExtension(fullpath);

 

Something like this.

public ItemType DocumentType(string fullpath)
        {
            if ((fullpath != ""))
            {
                string fileexe = System.IO.Path.GetExtension(fullpath).ToLower();
                switch (fileexe)
                {
                    case ".rvt":
                        return ItemType.Project;
                   
                    case ".rfa":
                        return ItemType.Family;
                     
                    case ".dwg":
                        return ItemType.Cad;

                        // Etc...

                     default:
                        return ItemType.None;
                   
                }
            }
            else
            {
                return ItemType.None;
            }

        }

 

- Michel

0 Likes
Message 13 of 14

TheRealChrisHildebran
Advocate
Advocate

Thanks for the feedback Michel!

0 Likes
Message 14 of 14

TheRealChrisHildebran
Advocate
Advocate

On Jeremy's suggestion i submitted an idea here. (https://forums.autodesk.com/t5/revit-ideas/implement-documenttype-property-on-the-document-class/idi...)

 

Please take a look and if you see value please vote in favor. 

0 Likes