Using itextsharp to set ocg state of existing pdf - wpf

I have spent several hours researching this and can't seem to locate the answer.
I have downloaded and referenced itextsharp in my wpf .net application. (VB)
What I am doing is needing to turn off a specific layer (ocg object) in an exisiting .pdf that was created in Autocad that is defaulted on.
I have successfully opened and displayed the .pdf but i can't seem to use the setOCGstate control correctly
pdf name is "random.pdf"
layer name that i can see once i open the .pdf is "Option 1"
where im getting stuck is i know the layer names are stored in an array inside the .pdf. i know the name of the layer i am trying to turn off, so how do i reference that layer and turn it off using the setocgstate.
example code
dim doc1 as New PdfReader("random.pdf")
PdfAction.SetOCGstate ("confused", False)

I've created an example that turns off the visibility of a specific layer. See ChangeOCG
The concept is really simple. You already have a PdfReader object and you want to apply a change to a file. As documented, you create a PdfStamper object. As you want to change an OCG layer, you use the getPdfLayers() method and you select the layer you want to change by name. (In my example, the layer I want to turn off is named "Nested layer 1"). You use the setOn() method to change its status, and you're done:
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
Map<String, PdfLayer> layers = stamper.getPdfLayers();
PdfLayer layer = layers.get("Nested layer 1");
layer.setOn(false);
stamper.close();
reader.close();
This is Java code. Please read it as if it were pseudo-code and adapt it to your language of choice.

Related

Check whether file has read only flag in UWP

I am working on an UWP text editor. I have added desktop extension to it to modify system files and other read only files. The problem I have is there is no reliable way to detect if a file has read-only attribute. FileInfo.IsReadOnly doesn't work and StorageFile.Attributes has FileAttributes.ReadOnly when file is dragged and dropped from file explorer.
How do I reliably check whether the file has read only flag or not?
While there is no way to detect the readonly attribute by using dotnet methods, however GetFileAttributesExFromApp can be used to get a lot of attributes(readonly, hidden etc.) of the file that aren't available via StorageFile api. Also, SetFileAttributesFromApp can be used to change/remove these attributes.
Edit
After some research and deep dive in MSDN, I came to know about RetrievePropertiesAsync(IEnumerable<String>) and
SavePropertiesAsync(IEnumerable<KeyValuePair<String,Object>>) methods for Windows.Storage.FileProperties.StorageItemContentProperties which can be used to get and set properties by name (Full list of properties names), the name System.FileAttributes can be used to get file attributes and can be used to detect if read-only flag is present. While retrieving properties always works modifying properties will only work if app has write access to file (Windows.Storage.StorageFile.Attributes doesn't contain ReadOnly flag), although SetFileAttributesFromApp works for that scenario but limitation of SetFileAttributesFromApp is it won't work for sensitive file types (.bat, .cmd etc.). So both those methods could be used combined to have maximum effect.
You can see the Attributes property has ReadOnly or not.
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
foreach (string format in HelperUP.subtitlesFormat)
filePicker.FileTypeFilter.Add(format);
var file = await filePicker.PickSingleFileAsync();
if (file == null)
return;
Debug.WriteLine(file.Attributes);
The reason FileAttributes.ReadOnly throws an exception is that the System.IO APIs don't have access to arbitrary file locations on the hard drive in UWP.
On the other hand, a StorageFile opened in the app via drag & drop has this attribute set too, which is a problem that is continuously being discussed and hopefully will be fixed in a future version.
The only workaround I can think of (apart from always using the desktop extension) is declaring the broadFileSystemAccess capability (I have described the process here for example). This is a capability which gives you access to the whole filesystem and allows you to get a file using an arbitrary path with the StorageFile.GetFileFromPathAsync method (see Docs). Please note you will need to explain why this capability is required when you submit the application to the Microsoft Store.
With broad filesystem access, you could take the drag & drop StorageFile, take its Path and retrieve the same file again using StorageFile.GetFileFromPathAsync. This new copy of the file will no longer have the "false-positive" Read Only attribute and will reflect the actual attribute state from the filesystem.

How to handle Solutions, Projects and their contents in a VisualStudio extension

In short:
I'm new to VisualStudio Extensibility and my goal is to create an extension with a ToolWindow (which already works) showing different views for each context of a VisualStudio solution, i. e. a view for the solution, a view for a project etc.. The window should be opened by clicking on a context menu entry in the context menus of the Solution Explorer, Class View, Object Browser and (ideally) any other window showing contents like projects, namespaces, classes etc..
After searching I found a lot of information, but for some points I couldn't find very helpful information. How do I ...
... create a context menu item for the VisualStudio views?
... get the currently open solution as an instance in code?
... get the projects of the solution and their contens as instances in code?
... add/remove items to/from a solution/project/class/... in code?
... react to selection changes in the Solution Explorer?
What I've done, so far:
I read the docs for Starting to Develop Visual Studio Extensions and downloaded the VSSDK-Extensibility-Samples. Especially the WPF_Toolwindow example was interesting for my purposes, so I built and ran it, which was successful, so far. Another interesting sample would have been the WPFDesigner_XML, but it always throws a NullReferenceException, so I decided to stick with the former ToolWindow, which is completely fine, for now.
Furtermore, I tried to understand the example by having a close look at each file in the project, running it in the debugger and analyzing what happened. I'm confident I understood it, but am also open for corrections of my possibly misguided thoughts following.
Now, I have created a new project, based on the WPF_Toolwindow sample, renamed and adapted to my needs (basically, I created new GUIDs, renamed the namespaces and removed things I won't use). This extension still works in the debugger. I even uninstalled everything from the experimental instance and debugged the extension from scratch.
What I try to achieve:
Have the ToolWindow load a specific view/viewmodel, when the selection changes in the Solution Explorer (or any other VisualStudio view). Alternatively, there should be a context menu item for every node's context menu in the Solution Explorer tree (or any other VisualStudio view).
Get the currently open solution, the containing projects and basically everything from the Solution Explorer's content as instances processable in my viewmodel. I need to properly add/remove
classes/structs/enums to/from
a folder in a project
a namespace
properties/fields to/from a class/struct
Generate code based on information of the solution and add the file properly to a project.
Does anyone know of examples for something like this or can anyone give me some hints, where I can find further information? Any help would be appreciated. Thanks in advance.
(1) The items already have a context menu and I want to add a new command to this menu.
if you want to add a sub menu to the context menu, the following link provide a complete sample
https://github.com/visualstudioextensibility/VSX-Samples/tree/master/CommandSubmenu
(3) Yes, basically adding a file to a project without manually manipulating the project file would be nice.
You can add the file to project via Project.ProjectItems.AddFromFile, and the following provide a sample for your reference.
https://www.mztools.com/Articles/2014/MZ2014009.aspx
Update:
I select a project and a similar event is fired. Are there such events I can subscribe to?
You could use IVsMonitorSelection to implement. here is the code which retrieve related project path for your reference.
IntPtr hierarchyPointer, selectionContainerPointer;
Object selectedObject = null;
IVsMultiItemSelect multiItemSelect;
uint projectItemId;
IVsMonitorSelection monitorSelection =
(IVsMonitorSelection)Package.GetGlobalService(
typeof(SVsShellMonitorSelection));
monitorSelection.GetCurrentSelection(out hierarchyPointer,
out projectItemId,
out multiItemSelect,
out selectionContainerPointer);
IVsHierarchy selectedHierarchy = Marshal.GetTypedObjectForIUnknown(
hierarchyPointer,
typeof(IVsHierarchy)) as IVsHierarchy;
if (selectedHierarchy != null)
{
ErrorHandler.ThrowOnFailure(selectedHierarchy.GetProperty(
projectItemId,
(int)__VSHPROPID.VSHPROPID_ExtObject,
out selectedObject));
}
Project selectedProject = selectedObject as Project;
string projectPath = selectedProject.FullName;
For more information about the usage, please refer to:
https://www.mztools.com/articles/2007/mz2007024.aspx

drag and drop Outlook attachment from Outlook in to a WPF datagrid

I saw this code ealier about drag and dropping attachment files (http://www.codeproject.com/Articles/28209/Outlook-Drag-and-Drop-in-C) from Outlook into Windows Form and it works fine in windows Forms, but I can't seem to make it work with WPF.
I tried to simply change System.windows.form.IDataObject to System.Windows.IDataObject but it doesn't work (as I should have guessed).
I also simply tried to get the content of the e.Data FileContents but always get errors (which seems to be the case to everyone when I check on the web).
Did anyone ever did drag and dropping attachment from Outlook to WPF ? I am at a complete loss.
Edit : I am not trying to get file from a Windows Explorer windows ( I do but I know how to). It's really the whole getting attachment from Outlook directly that doesn't work . I am fully aware too that I could simple take the file from outlook into a temp folder and then drop it into my program, but I would like to avoid this unncessary step if possible.
so in the end I was able to find out a link where someone did exactly that :
https://gist.github.com/MattyBoy4444/521547
For those who wonders. Here is what I did exactly.
Create a new project in C# (my code is in VB) and add the code to it
Reference the new project in my main project to be able to use it
In my drop Event, check whether or not I had the "FileGroupDescriptorW" object in the drop data and called the method if I do to retrieve the files.
Here is the complete code
If obj.GetDataPresent("FileGroupDescriptorW") Then 'Outlook
Dim oOutLookObj As New Helpers.OutlookDataObject(e.Data)
Dim StrFiles() As String = oOutLookObj.GetData("FileGroupDescriptorW")
Dim contentStream() As System.IO.MemoryStream = oOutLookObj.GetData("FileContents")
' Do intended work...
End if
The names of the files are in StrFiles and the content are found in the streams. Both have the same array size and are order correctly.

Different XAP files in Silverlight - Sharing context

I have a silverlight application which I recently split them into separate xap files.
The intention is this. There is xap file 1 which takes a few inputs from the user persists it to the database. And when the user clicks a button on this UI (from xap file 1), it loads xap file 2, which asks for more inputs and saves it to the database.
I was able to invoke xap file 2 from xap file 1, but the UI doesn't seem to be able to get the information from the database (the UI shows what was persisted by the previous UI), nor it is able to persist the user's input. I realize that the xap file 2 somehow needs to told somehow where and how to persist.
This is how I load the xap file 2
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(OpenReadCompleted);
Uri uri = new Uri("xapfile2.xap", UriKind.Relative);
wc.OpenReadAsync(uri);
private void OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
Uri uri = new Uri("xapfile2.dll", UriKind.Relative);
StreamResourceInfo resource_stream = App.GetResourceStream(new StreamResourceInfo(e.Result, null), uri);
AssemblyPart part = new AssemblyPart();
Assembly assembly = part.Load(resource_stream.Stream);
UIElement control = assembly.CreateInstance("xapfile2.Window") as UIElement;
if (control != null)
{
RadWindow window = (RadWindow)control;
window.ShowDialog();
}
}
(All of this UI was working before I split them into separate xap's. We had good reasons to splitting them)
Any help would be greatly appreciated
UPDATE
I tried following the example link and was able to launch the second UI from the separate xap file with all the information from the database.
Now I seem to have hit a new problem. When I do a cancel on the second UI, do I have to unload the second xap calling removeXap from the catalog? When I do so I get Composition remains unchanged error.
1) Change in exports prevented by non-recomposable import 'xapfile2.Views.ViewModel (ContractName="MyViewModel")' on part 'xapfile2.Views.MyView'. Any ideas?.
Thanks
K
You should use a framework to bring in your XAP file. You're reinventing the wheel.
My suggestion is to use MEF, a framework created by Microsoft to do exactly what you are creating.
MEF has a concept of a deployment catalog, which downloads xap files and loads them. Then, using patterns like interfaces and contracts, you can create objects, show them on the screen and take more input.
See this example: http://codebetter.com/glennblock/2010/03/08/building-hello-mef-part-iv-deploymentcatalog/
Good Luck!
Having seperate XAP files doesn't create any boundries -- when the 2nd XAP is loaded, its types are loaded into the same AppDomain. Seems like you need some kind of common messaging bus between classes in your Xap1 and Xap2. You can use an Event Aggregator. Many frameworks have one or you can use your own -- Build it (and custom event types) in a dll referenced by both xap's.
I think I've used http://www.keith-woods.com/Blog/post/Rx-Event-Aggregator.aspx
After a lot of struggle I found out that I had redundant assemblies in the xap files. Apparently there should not be a conflict in assemblies. Setting CopyLocal = False on the assemblies required for the second xap seemed to have solved the issue.
Thanks guys for your tips
K

how to override image in media library in WP7

I want to save image to media library in windows phone 7. I`m using this example http://msdn.microsoft.com/en-us/library/ff769549(v=VS.92).aspx . It works fine, the only problem that i have is that after image modification i call save procedure with the same file name, exactly like in example
MediaLibrary library = new MediaLibrary();
Picture pic = library.SavePicture("SavedPicture.jpg", myFileStream);
myFileStream.Close();
but modification is saved to another file, even thought i use the same file name when i call SavePicture (and i want to override the image file). What am i doing wrong?
Reading between the lines a little you are seeing a new picture appear in the phone saved pictures collection where you were expecting an existing one to be replaced?
You should note that the code you have referenced creates duplicate pictures. One is stored in the phones saved pictures collection and another is saved in isolated storage for the application.
Its not possible for an application to mutate an existing picture in the saved pictures collection even if that application is the original creator of the picture. When saved, a new picture is created in the saved pictures collection.
On the other hand the existing content of the file in the isolated storage is replaced with the new content.
You can't.
It's only possible to read and add images in/to the MediaLibrary.
It is not possible to edit or delete images.
This is by design.

Resources