Open selected DWG

Add-in for opening selected DWG with 3 options:

EF-Tools Revit API

Add-in for opening selected DWG with 3 options:

  • Open [.dwg file] in default application.
  • Open a folder where [.dwg file] is being stored.
  • Copy Absolute path of [.dwg file] into clipboard (ctrl+C)
code
# -*- coding: utf-8 -*-
__title__ = "DWG: open selected"
__author__ = "Erik Frits"
__helpurl__ = "https://www.erikfrits.com/blog/open-selected-dwg/"
__highlight__ = 'new'
__doc__ = """Version = 1.0
Date    = 12.04.2021
_____________________________________________________________________
Description:
Add-in for opening selected DWG with 3 options:
    1) Open [.dwg file] in default application.
    2) Open a folder where [.dwg file] is being stored.
    3) Copy Absolute path of [.dwg file] into clipboard (ctrl+C).
_____________________________________________________________________
How-to:
Select linked dwg instance and click the button.
If ImportInstance is Linked, a dialog box will pop-up 
to choose action, otherwise it will notify that 
ImportInstance is not a linked one.
_____________________________________________________________________
Prerequisite:
ImportInstance have to be linked and not imported!
_____________________________________________________________________
Last update:
-
_____________________________________________________________________
To-do:
- add header logo to GUI
_____________________________________________________________________
"""
# IMPORTS
from os import startfile
from os.path import dirname
from Autodesk.Revit.DB import ImportInstance, ModelPathUtils, BuiltInParameter
from pyrevit.forms import WPFWindow, alert
from subprocess import Popen

# .NET IMPORTS
from clr import AddReference
AddReference("System")
# from System.Collections.Generic import List
from System.Diagnostics.Process import Start
from System.Windows.Window import DragMove
from System.Windows.Input import MouseButtonState

#_____________________________ MAIN
doc     = __revit__.ActiveUIDocument.Document
uidoc   = __revit__.ActiveUIDocument


class MyWindow(WPFWindow):
    """Add-in for opening selected DWG with 3 options"""

    def __init__(self, xaml_file_name):
        self.form = WPFWindow.__init__(self, xaml_file_name)
        self.dwg_linked = self.selected_dwg_ImportInstance.IsLinked

        if self.dwg_linked:
            self.selected_dwg_path          = self.get_import_instance_path(self.selected_dwg_ImportInstance)
            self.selected_dwg_folder_path   = dirname(self.selected_dwg_path)
            self.dwg_path.Text              = self.selected_dwg_path
            self.main_title.Text            = __title__
            self.ShowDialog()

        else:
            alert("Selected DWG instance is not linked.", __title__, exitscript=False)

    def get_import_instance_path(self, import_instance):
        # type:(ImportInstance) -> str
        """Function to get a path of the selected ImportInstance if it is linked."""
        if import_instance.IsLinked:
            cad_linktype_id = import_instance.get_Parameter(BuiltInParameter.ELEM_FAMILY_PARAM).AsElementId()
            cad_linktype = doc.GetElement(cad_linktype_id)
            efr = cad_linktype.GetExternalFileReference()
            dwg_path = ModelPathUtils.ConvertModelPathToUserVisiblePath(efr.GetAbsolutePath())
            return dwg_path
        else:
            alert("Selected DWG instance is not linked.", __title__, exitscript=True)

    @property
    def selected_dwg_ImportInstance(self):
        """Try to get an ImportInstance from selected elements."""
        selected_elements = uidoc.Selection.GetElementIds()

        if not selected_elements:
            alert("No elements were selected. Please try again.", __title__, exitscript=True)

        for element_id in selected_elements:
            element = doc.GetElement(element_id)

            # FILTER SELECTION
            if type(element) == ImportInstance:
                dwg = element
                return dwg
        alert("Linked ImportInstance was not selected. Please try again.", __title__, exitscript=True)


    # GUI EVENT HANDLERS:
    def button_close(self,sender,e):
        """Stop application by clicking on a <Close> button in the top right corner."""
        self.Close()

    def header_drag(self,sender,e):
        """Drag window by holding LeftButton on the header."""
        if e.LeftButton == MouseButtonState.Pressed:
            DragMove(self)

    def button_open_dwg(self,sender,e):
        """Open DWG in a default application and close the GUI."""
        startfile(self.selected_dwg_path)
        self.Close()

    def button_open_folder(self,sender,e):
        """Open parent folder of DWG file and close the GUI."""
        startfile(self.selected_dwg_folder_path)
        self.Close()

    def button_copy_clipboard(self, sender, e):
        """Add DWG filepath to the copy clipboard."""
        command = 'echo ' + self.selected_dwg_path.strip() + '| clip'
        Popen(command, shell=True)
        self.button_copy_clipboard.Content = "Copied!"

    def Hyperlink_RequestNavigate(self, sender, e):
        """Forwarding for a Hyperlink"""
        Start(e.Uri.AbsoluteUri)

if __name__ == '__main__':
    MyWindow("Script.xaml")
code
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="Views: Find and Replace"
    Height="110" Width="400"
    WindowStartupLocation="CenterScreen"
    HorizontalAlignment="Center"
    ShowInTaskbar="True"
    WindowStyle="None"
    ResizeMode="NoResize"
    Background="#181735">

    <Window.Resources>
        <ResourceDictionary>
            <SolidColorBrush x:Key="header_background"  Color="#0f0f2d" />
            <SolidColorBrush x:Key="text_white"         Color="White" />
            <SolidColorBrush x:Key="button_fg_normal"   Color="White" />
            <SolidColorBrush x:Key="button_bg_normal"   Color="#39385D" />
            <SolidColorBrush x:Key="button_bg_hover"    Color="#FF4C70" />

            <!--[BUTTON] STYLE START-->
            <Style TargetType="Button">
                <!--[BUTTON] STYLES-->
                <Setter Property="TextElement.FontFamily" Value="Arial"/>
                <Setter Property="Background" Value="{StaticResource button_bg_normal}"/>
                <Setter Property="Foreground" Value="{StaticResource button_fg_normal}"/>
                <Setter Property="Cursor" Value="Hand"/>
                <!--[BUTTON] TEMPLATE-->
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <Border CornerRadius="8"
                                    Background="{TemplateBinding Background}">
                                <ContentPresenter  VerticalAlignment="Center"
                                                   HorizontalAlignment="Center"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <!--[BUTTON] TRIGGERS-->
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="{StaticResource button_bg_hover}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
            <!--[BUTTON] - STYLE END-->
        </ResourceDictionary>
    </Window.Resources>

    <!--MAIN-->
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="25"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <!--HEADER START-->
        <Grid   MouseDown="header_drag"
                Background="{StaticResource header_background}"
                Grid.ColumnSpan="2">
            <!--HEADER GRID-->
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <!--LOGO-->
            <DockPanel  Grid.Column="0"
                        Grid.ColumnSpan="2"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Left">
                <Image Width="20" Height="20"
                      />
                <!--Source="https://www.erikfrits.com/media/images/LOGO.png"-->

                <TextBlock>
                    <Hyperlink  
                        RequestNavigate="Hyperlink_RequestNavigate" 
                        NavigateUri="https://erikfrits.com/blog/"
                        FontSize="14px"
                        FontWeight="Heavy"
                        Foreground="{StaticResource text_white}">
                        EF-Tools
                    </Hyperlink>
                </TextBlock>
            </DockPanel>

            <!--__TITLE__-->
            <TextBlock x:Name="main_title"
                Text="__title__"
                Grid.Column="1"
                VerticalAlignment="Center"
                HorizontalAlignment="Center"
                Foreground="{StaticResource text_white}"
                />

            <!--CLOSE-->
            <Button 
                Content="Close"
                Grid.Column="2"
                Width="60" Height="20"
                FontSize="10"
                Click="button_close"
                VerticalAlignment="Center"
                HorizontalAlignment="Right"
                    />
        </Grid>
        <!--HEADER END-->






        <StackPanel Grid.Row="1"
                    VerticalAlignment="Top"
                    Margin="5">

            <!--DWG PATH-->
            <DockPanel Margin="5">
                <TextBlock Text="Selected DWG path: "
                           Foreground="{StaticResource text_white}"
                           FontWeight="Medium"
                           FontSize="12"/>
                <TextBlock x:Name="dwg_path"
                           Text="test/folder/Test.dwg"
                           Foreground="{StaticResource text_white}"/>
            </DockPanel>

            <!--BUTTONS-->
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">

                <!--BUTTON_1-->
                <Button Content="Open DWG File"
                        Click="button_open_dwg"
                        Height="30"
                        Width="120"
                        Margin="5"
                        />
                <!--BUTTON_2-->
                <Button Content="Open DWG Folder"
                        Click="button_open_folder"
                        Height="30"
                        Width="120"
                        Margin="5"
                        />
                <!--BUTTON_3-->
                <Button x:Name="button_copy_clipboard"
                        Content="Copy to Clipborad"
                        Click="button_copy_clipboard"
                        Height="30"
                        Width="120"
                        Margin="5"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>