A comment came in on this previous post regarding how best to know whether a media name is valid during your plot configuration.
There are a few approaches, other than the one I chose of hardcoding the device and media names. The first is to implement a user interface of some kind which allows the user to select the device and media names. Another approach for setting the media name is to use PlotSettingsValidator.SetClosestMediaName() to choose the media name that most closely matches the paper size you desire.
Today I'll focus on the first option, although I'm only going to implement a basic, command-line user interface. It should be straightforward to extend this to implement a WinForm with comboboxes for the device and media names.
I implemented a simple function called ChooseDeviceAndMedia() which queries the current device list, allows selection from it, and then gets the media name list and allows selection from that. I chose not to worry about displaying locale-specific names, for now - I'll leave that for a future post (let me know if you're interested :-).
Here's the function integrated into the C# code from this previous post, which defines a command called MPLOT:
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.PlottingServices;
using System.Collections.Specialized;
namespace PlottingApplication
{
public class PlottingCommands
{
static public string[] ChooseDeviceAndMedia()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
// Assign default return values
string devname = "", medname = "";
PlotSettingsValidator psv =
PlotSettingsValidator.Current;
// Let's first select the device
StringCollection devlist =
psv.GetPlotDeviceList();
for (int i = 0; i < devlist.Count; i++)
{
ed.WriteMessage(
"\n{0} {1}",
i + 1,
devlist[i]
);
}
PromptIntegerOptions opts =
new PromptIntegerOptions(
"\nEnter number of device to select: "
);
opts.LowerLimit = 1;
opts.UpperLimit = devlist.Count;
PromptIntegerResult pir =
ed.GetInteger(opts);
if (pir.Status == PromptStatus.OK)
{
devname = devlist[pir.Value - 1];
ed.WriteMessage(
"\nSelected: {0}\n",
devname
);
// Now let's select the media
PlotSettings ps = new PlotSettings(true);
using (ps)
{
// We should refresh the lists,
// in case setting the device impacts
// the available media
psv.SetPlotConfigurationName(
ps,
devname,
null
);
psv.RefreshLists(ps);
StringCollection medlist =
psv.GetCanonicalMediaNameList(ps);
for (int i = 0; i < medlist.Count; i++)
{
ed.WriteMessage(
"\n{0} {1}",
i + 1,
medlist[i]
);
}
opts.Message =
"\nEnter number of media to select: ";
opts.LowerLimit = 1;
opts.UpperLimit = medlist.Count;
pir = ed.GetInteger(opts);
if (pir.Status == PromptStatus.OK)
{
medname = medlist[pir.Value - 1];
ed.WriteMessage(
"\nSelected: {0}\n",
medname
);
}
}
}
return new string[2] { devname, medname };
}
[CommandMethod("mplot")]
static public void MultiSheetPlot()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
PlotInfo pi = new PlotInfo();
PlotInfoValidator piv =
new PlotInfoValidator();
piv.MediaMatchingPolicy =
MatchingPolicy.MatchEnabled;
// A PlotEngine does the actual plotting
// (can also create one for Preview)
if (PlotFactory.ProcessPlotState ==
ProcessPlotState.NotPlotting)
{
string[] devmed = ChooseDeviceAndMedia();
// Only proceed if we have values for both
if (devmed[0] != "" && devmed[1] != "")
{
string devname = devmed[0];
string medname = devmed[1];
PlotEngine pe =
PlotFactory.CreatePublishEngine();
using (pe)
{
// Collect all the paperspace layouts
// for plotting
ObjectIdCollection layoutsToPlot =
new ObjectIdCollection();
foreach (ObjectId btrId in bt)
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
btrId,
OpenMode.ForRead
);
if (btr.IsLayout &&
btr.Name.ToUpper() !=
BlockTableRecord.ModelSpace.ToUpper())
{
layoutsToPlot.Add(btrId);
}
}
// Create a Progress Dialog to provide info
// and allow thej user to cancel
PlotProgressDialog ppd =
new PlotProgressDialog(
false,
layoutsToPlot.Count,
true
);
using (ppd)
{
int numSheet = 1;
foreach (ObjectId btrId in layoutsToPlot)
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
btrId,
OpenMode.ForRead
);
Layout lo =
(Layout)tr.GetObject(
btr.LayoutId,
OpenMode.ForRead
);
// We need a PlotSettings object
// based on the layout settings
// which we then customize
PlotSettings ps =
new PlotSettings(lo.ModelType);
ps.CopyFrom(lo);
// The PlotSettingsValidator helps
// create a valid PlotSettings object
PlotSettingsValidator psv =
PlotSettingsValidator.Current;
// We'll plot the extents, centered and
// scaled to fit
psv.SetPlotType(
ps,
Autodesk.AutoCAD.DatabaseServices.PlotType.Extents
);
psv.SetUseStandardScale(ps, true);
psv.SetStdScaleType(ps, StdScaleType.ScaleToFit);
psv.SetPlotCentered(ps, true);
// We'll use the standard DWFx PC3, as
// this supports multiple sheets
psv.SetPlotConfigurationName(
ps,
devname,
medname
);
// We need a PlotInfo object
// linked to the layout
pi.Layout = btr.LayoutId;
// Make the layout we're plotting current
LayoutManager.Current.CurrentLayout =
lo.LayoutName;
// We need to link the PlotInfo to the
// PlotSettings and then validate it
pi.OverrideSettings = ps;
piv.Validate(pi);
if (numSheet == 1)
{
ppd.set_PlotMsgString(
PlotMessageIndex.DialogTitle,
"Custom Plot Progress"
);
ppd.set_PlotMsgString(
PlotMessageIndex.CancelJobButtonMessage,
"Cancel Job"
);
ppd.set_PlotMsgString(
PlotMessageIndex.CancelSheetButtonMessage,
"Cancel Sheet"
);
ppd.set_PlotMsgString(
PlotMessageIndex.SheetSetProgressCaption,
"Sheet Set Progress"
);
ppd.set_PlotMsgString(
PlotMessageIndex.SheetProgressCaption,
"Sheet Progress"
);
ppd.LowerPlotProgressRange = 0;
ppd.UpperPlotProgressRange = 100;
ppd.PlotProgressPos = 0;
// Let's start the plot, at last
ppd.OnBeginPlot();
ppd.IsVisible = true;
pe.BeginPlot(ppd, null);
// We'll be plotting a single document
pe.BeginDocument(
pi,
doc.Name,
null,
1,
true, // Let's plot to file
"c:\\test-multi-sheet"
);
}
// Which may contains multiple sheets
ppd.set_PlotMsgString(
PlotMessageIndex.SheetName,
doc.Name.Substring(
doc.Name.LastIndexOf("\\") + 1
) +
" - sheet " + numSheet.ToString() +
" of " + layoutsToPlot.Count.ToString()
);
ppd.OnBeginSheet();
ppd.LowerSheetProgressRange = 0;
ppd.UpperSheetProgressRange = 100;
ppd.SheetProgressPos = 0;
PlotPageInfo ppi = new PlotPageInfo();
pe.BeginPage(
ppi,
pi,
(numSheet == layoutsToPlot.Count),
null
);
pe.BeginGenerateGraphics(null);
ppd.SheetProgressPos = 50;
pe.EndGenerateGraphics(null);
// Finish the sheet
pe.EndPage(null);
ppd.SheetProgressPos = 100;
ppd.OnEndSheet();
numSheet++;
ppd.PlotProgressPos +=
(100 / layoutsToPlot.Count);
}
// Finish the document
pe.EndDocument(null);
// And finish the plot
ppd.PlotProgressPos = 100;
ppd.OnEndPlot();
pe.EndPlot(null);
}
}
}
}
else
{
ed.WriteMessage(
"\nAnother plot is in progress."
);
}
}
}
}
}
Here's what I see at the command-line when I run the MPLOT command on my system (items 7-18 below are network printers in various Autodesk offices):
Command: MPLOT
1 None
2 SnagIt 8
3 PDF-XChange 3.0
4 Microsoft XPS Document Writer
5 Microsoft Office Live Meeting Document Writer
6 Adobe PDF
7 \\adscctps1\cctprn000
8 \\adsneups2\neuprn304
9 \\adsneups2\neuprn306
10 \\adsneups2\neuprn307
11 \\adsneups2\neuprn317
12 \\banhpa001\banprn001
13 \\beihpa001\BEIPRN002
14 \\beihpa001\BEIPRN003
15 \\farhpa001\FARPRN101
16 \\pra-pc61237\Xerox WorkCentre Pro 35 PCL6
17 \\tokhpa001\tokprn401
18 \\tokhpa001\tokprn402
19 Default Windows System Printer.pc3
20 DWF6 ePlot.pc3
21 DWFx ePlot (XPS Compatible).pc3
22 DWG To PDF.pc3
23 PublishToWeb JPG.pc3
24 PublishToWeb PNG.pc3
Enter number of device to select: 22
Selected: DWG To PDF.pc3
1 ISO_expand_A0_(841.00_x_1189.00_MM)
2 ISO_A0_(841.00_x_1189.00_MM)
3 ISO_expand_A1_(841.00_x_594.00_MM)
4 ISO_expand_A1_(594.00_x_841.00_MM)
5 ISO_A1_(841.00_x_594.00_MM)
6 ISO_A1_(594.00_x_841.00_MM)
7 ISO_expand_A2_(594.00_x_420.00_MM)
8 ISO_expand_A2_(420.00_x_594.00_MM)
9 ISO_A2_(594.00_x_420.00_MM)
10 ISO_A2_(420.00_x_594.00_MM)
11 ISO_expand_A3_(420.00_x_297.00_MM)
12 ISO_expand_A3_(297.00_x_420.00_MM)
13 ISO_A3_(420.00_x_297.00_MM)
14 ISO_A3_(297.00_x_420.00_MM)
15 ISO_expand_A4_(297.00_x_210.00_MM)
16 ISO_expand_A4_(210.00_x_297.00_MM)
17 ISO_A4_(297.00_x_210.00_MM)
18 ISO_A4_(210.00_x_297.00_MM)
19 ARCH_expand_E1_(30.00_x_42.00_Inches)
20 ARCH_E1_(30.00_x_42.00_Inches)
21 ARCH_expand_E_(36.00_x_48.00_Inches)
22 ARCH_E_(36.00_x_48.00_Inches)
23 ARCH_expand_D_(36.00_x_24.00_Inches)
24 ARCH_expand_D_(24.00_x_36.00_Inches)
25 ARCH_D_(36.00_x_24.00_Inches)
26 ARCH_D_(24.00_x_36.00_Inches)
27 ARCH_expand_C_(24.00_x_18.00_Inches)
28 ARCH_expand_C_(18.00_x_24.00_Inches)
29 ARCH_C_(24.00_x_18.00_Inches)
30 ARCH_C_(18.00_x_24.00_Inches)
31 ANSI_expand_E_(34.00_x_44.00_Inches)
32 ANSI_E_(34.00_x_44.00_Inches)
33 ANSI_expand_D_(34.00_x_22.00_Inches)
34 ANSI_expand_D_(22.00_x_34.00_Inches)
35 ANSI_D_(34.00_x_22.00_Inches)
36 ANSI_D_(22.00_x_34.00_Inches)
37 ANSI_expand_C_(22.00_x_17.00_Inches)
38 ANSI_expand_C_(17.00_x_22.00_Inches)
39 ANSI_C_(22.00_x_17.00_Inches)
40 ANSI_C_(17.00_x_22.00_Inches)
41 ANSI_expand_B_(17.00_x_11.00_Inches)
42 ANSI_expand_B_(11.00_x_17.00_Inches)
43 ANSI_B_(17.00_x_11.00_Inches)
44 ANSI_B_(11.00_x_17.00_Inches)
45 ANSI_expand_A_(11.00_x_8.50_Inches)
46 ANSI_expand_A_(8.50_x_11.00_Inches)
47 ANSI_A_(11.00_x_8.50_Inches)
48 ANSI_A_(8.50_x_11.00_Inches)
Enter number of media to select: 35
Selected: ANSI_D_(34.00_x_22.00_Inches)
Effective plotting area: 15.29 wide by 20.60 high
Effective plotting area: 13.29 wide by 17.31 high
Plotting viewport 2.
Plotting viewport 1.
Regenerating layout.
Regenerating model.
Effective plotting area: 15.69 wide by 20.60 high
Effective plotting area: 15.69 wide by 20.59 high
Plotting viewport 2.
Plotting viewport 1.
Regenerating layout.
Regenerating model.
Effective plotting area: 15.69 wide by 20.60 high
Effective plotting area: 15.69 wide by 20.59 high
Plotting viewport 2.
Plotting viewport 1.
Regenerating layout.
Regenerating model.
Effective plotting area: 15.69 wide by 20.60 high
Effective plotting area: 14.07 wide by 18.34 high
Plotting viewport 2.
Plotting viewport 1.
Regenerating layout.
Regenerating model.