How to accurately determine if an SPFile instance is a converted file? - sharepoint

I have been working on a document conversion feature for converting a docx file to a pdf file using MOSS 2007. The SPFile.Convert() call is being made in the ItemAdded event and the ItemFileConverted event is fired fine as well. The eventing seems to be working fine, but the IsConvertedFile and SourceLeafName properties of the converted SPFile instance are not always set by the conversion process. This is what I was attempting to use to determine if a call to SPFile.Convert should be made.
In digging into the code for SPFile IsConvertedFile, GeneratingConverterId and SourceLeafName properties, it seems these are based on SPFile.Properties "vti_dttransformerid" and "vti_dtparentleafname". The problem is, these two properties are not being set consistently whenever I have code in my ISPConversionProcessor.PostProcess() implementation in which I was hoping to do some post processing of the file. If there is no code in the PostProcess method (only the runDefaultPostProcessing = true; statement) the properties are set more consistently.
I have some additional details here in a Wiki pageabout what is going on, but using .NET Reflector to determine where these fields are updated from hit a brick wall at OWSTIMER.EXE (I could find all of the reads for the properties, but even the HtmlLauncher and LoadBalancer services had no mention of these properties).
Has anyone done a complete Document Conversion implmentation and used the SPFile.IsConvertedFile and SPFile.SourceLeafName properties successfully?

If you can't trust the API, store the IsConverted metadata in the property bag for the SPListItem. Or if you prefer to show it in the UI, add another field to your list. This should all work fine from the event handler.
It's annoying to do the extra work but I guess there might be additional metadata that you can add which SPFile wouldn't have been able to provide anyway.

I have created a PDF Converter for SharePoint, but didn't use the Document Converter functionality as it didn't match our needs and was not flexible enough.
Not sure if this reply will be thrown out as spam as I am now going to link you to the place where you can download a free trial version. Download PDF Converter for SharePoint.
I feel a bit dirty now, but I may have actually helped you ;-)

Related

Co-authoring when using WorkBook Settings/CustomProperties

I've been looking for any documentation which suggests whether there is a way of saving Document Settings & CustomProperties such that they're automatically propagated to co-authors of the current document.
I've done some testing which suggests that's these settings aren't automatically propagated even when the document is saved. I'm also storing XML inside the document so I'm concerned that this won't be propagated as well. Since I'm doing this in Excel, I could always create a hidden sheet to store the properties in and have a watch on the table (or some similar set-up) but this isn't really the avenue I want to go down since some user could easily come along and delete the hidden sheet or manipulate its contents.
Has anyone come across this issue and managed to find a solution to it?
Welcome to Excel JS world.
I have verified this issue, it looks like a co-auth bug in settings and custom properties API. We have created 2 bugs (BUG 4173957 and BUG 4173952) for tracking this issue.
As a workaround, you could use our beta API worksheet custom properties, which is in preview, this API support co-auth. You could try it out, please let me know if you have any suggestion on this API. thanks.

xpages display the document history

In some 'old' lotus notes applications, we created a history of each document: who created the doc, every person which edited it + the respective dates. The code contained several libraries in lotusScript.
For xpages, is there any snippet / sample working example which I could use? I found this but I couldn't download any example ...
ValueChangeListeners allow you to capture changes to specific components. I've used them to create audit trails in customer applications before.
Tony McGuckin has an XSnippet for it:
http://openntf.org/XSnippets.nsf/snippet.xsp?id=server-side-value-change-events-listeners
Declan Lynch covered it in a blog post:
http://www.qtzar.com/using-a-valuechangelistener-to-build-an-audit-trail/
Don McNally has also done a blog post:
http://dmcnally.blogspot.co.uk/2013/02/xpages-detecting-and-logging-field.html
I don't know of any pre-done snippet yet. But this becomes a lot easier in XPages especially if expand into Java. When I create an application these days I basically convert the document to a Java object. I don't do this yet but it would be easy to store in the object a Map of all the fields and their current values and then on save, look for differences and then write them out to a log document.
this could be done without java of course. Create an map object in scope. Populate it on loading of the document and on save do the compare and write.
Something went wrong with that project on OpenNTF (don't ever use an ampersand in the name). I'm the original author of that custom control. AFter some digging I found a direct url to the project here.

How Do You Create a Page that Selects and Clones part of a Document Library in Sharepoint 2007?

I am trying to set up a MySite allowing individuals to create and modify multiple projects, each which will contain a partial copy of a master Document Library. I have already created the Library and uploaded the documents, and I have a page on which I have been experimenting with how to do this.
I need to be able to display a list of the documents in the document library, allow the user to select which ones they want, and then when they click on a button, I need to initialize the database with some information about that prjoect, some information about each of the files, and the documents need to be copied to a new location, so that the user can pull them up and edit and save the changes that are specific to the one project. Also we will need to be able to be able to add/remove them through a similar interface after the project has already been created, if possible.
And, unfortunately, anything at all that uses code has been restricted; so, we can't use anything that will require anything to be installed in the GAC, and I can't even use any server-side scripts within the ASPX file. It seems like almost everything I find when I search for "Sharepoint 2007 clone Master Document Library" or the like involves using code.
I have been playing around with things in SharePoint designer for creating the UI, and I figured out how to get a list of the documents to show, although I'm having a hard time duplicating it. It created a <WebPartPages:DataFormWebPart> with a <SharePoint:SPDataSource> in it. However, when I've tried to pull over things like a Data View CheckBoxList to the document list, either it just won't let me drop it (this includes anywhere on the form, not just in the document list), or, as expected actually, it doesn't actually bind to each line of the list. It's not entirely clear to me what to do to create this.
I do get (more or less) that you can bind the controls via the .xslt in the form, but I'm figuring it's got to be simpler than writing them by hand since the designer looks so much like the Visual Studio designer. I am having a very hard time figuring out what exactly to do to get any of the controls to work, though; most of them have the same issue as the CheckBoxList and won't even drop on the form. I'm assuming there's a panel of some type, or some other thing, that I need to add to the form first, but this is so different from what I'm used to that I'm having a hard time even getting my bearings.
So, can someone point me in the right direction here? I'm going to need to be able to create the projects, select the documents, copy them over with some other information into a new project, including creating some items in the database. I have been developing software for a long time, on many different platforms with many different languages, although lately it's mainly been WinForms, with a fair bit of .aspx stuff (but nothing too fancy), and it's never been this hard. I figure there's just something I'm not getting about the model here; like, how do you tell the form you want to use x/y/z control connected to particular datasource? How do you tell sharepoint to create a new location for the files? How can you submit the selected files once you have them to Sharepoint and tell them where to copy to?
Any help would be so appreciated I have been tearing my hair out for days. :)
You might have had a change with SharePoint 2010, as there is a javascript/jQuery programming model, but without that you don't have a realistic of coding what you will need. You may get lucky and be able to call the SharePoint web services using jQuery, but it is going to be a lot of work to get around a "no code" requirement.
Okay, well, I was finally able to get this mostly working, although there are still some issues with displaying the data once I get it back; I will try to update this question once I have a better answer for that.
There's a cool library called SPServices which combines with JQuery to give an interface to the web services for SharePoint 2007. It seems to more or less provide an interface to anything that you need to do to use the web services without a lot of extra work on your part.
For example, to query a document library, I set up a function something like this in a helper class (based upon the examples from the SPServices documentation).
ServiceClass.prototype.getSpecialDocLib = function (onComplete) {
var sc = this;
$().SPServices({
operation: "GetListItems",
async: false,
listName: "Special Document Library",
CAMLViewFields: "<ViewFields><FieldRef Name='Title' /></ViewFields>",
completefunc: function (xData, Status) {
var outTable = new DocTable();
$(xData.responseXML).find("[nodeName='z:row']").each(function () {
var i;
var outRow = new DocTableRow();
for (i = 0; i < this.attributes.length; ++i) {
outRow.addField(this.attributes[i].localName, this.attributes[i].value);
};
outTable.addRow(outRow);
});
sc.onDocumentListComplete(xData, Status);
if (onComplete != null)
onComplete(resultTable);
}
});
};
For copying a document library from one place to another, I believe you can use Lists.AddList to create it, (not specifically documented in SPServices but is based upon this Web Service call) either from scratch or a template, and I believe you can use the SPServices Copy.CopyIntoItemsLocal method.
Anyway, I seem to be making progress with this so far; I will update and accept this answer once I have a little more experience and time to make sure everything works, but so far I seem to be making progress toward the "no code" goal.

Determine the property name in a SharePoint Webpart for XML

I'm employing a custom webpart that is made by an unaffiliated third party. I've created a feature which adds this webpart to a page. It's working mostly fine, except that I can't figure out the name of a specific property that needs to be defined. I tried obvious ones that match the display name on the tool pane view, adding the company's name in front of said display name, and many similar permutations. All of which to no avail. I would much prefer to include the property to the feature, as this will be necessary to deploy across multiple sites in the future. Manually configuring it every time will be a pain for my client.
The short, obvious answer is "Ask the third party". This can potentially work, particularly for this specific one (it is a CodePlex webpart and the author has posted a comment as recent as last week). But my experience with previous third party solutions has been less than optimal, usually even getting no response until they ask me three weeks later if I still like their product. So, since this is not always a reliable method to obtain this information, I was thinking the best option is to find out a way to figure out the name of properties in a webpart that I can use not just with this particular one, but in all future situations.
I did check out this earlier question which addresses a similar topic. However, I don't have access to the class for the webpart so I can't just find a convenient property in the code to modify. Or, at least, if I do have access to it in some fashion, I'm certainly unaware of it.
Thank you in advance!
From what I understand, you are trying to set a certain webpart property for which you do not know the corresponding XML attribute name.
Did you try to export the web part? One possible check might be to try to export the webpart to see what properties come up in the webpart XML. If it is a common property, chances are the webpart XML will have that property already defined with no value e.g.
<data>
<properties>
<property name="Your property Name" type="yourType"></property>
<properties>
</data>
To export the webpart, go to Edit Page mode, click the down arrow on the webpart and choose Export.
Also, if you have the webpart code in a dll, can you use reflector to open it and see what properties are being set in code?
Hope this helps.

SharePoint SPContext.List in a custom application page

I have a custom SharePoint application page deployed to the _layouts folder. It's a custom "new form" for a custom content type. During my interactions with this page, I will need to add an item to my list. When the page first loads, I can use SPContext.Current.List to see the current list I'm working with. But after I fill in my form and the form posts back onto itself and IsPostBack is true, then SPContext.Current.List is null so I can't find the list that I need to add my stuff into.
Is this expected?
How should I retain some info about my context list across the postback? Should I just populate some asp:hidden control with my list's guid and then just pull it back from that on the postback? That seems safe, I guess.
FWIW, this is the MOSS 2007 Standard version.
Generally speaking I try and copy whatever approach the product group has taken when looking to add functionality of my own. In this case they add their own edit/view/add pages via the list definition itself.
I built a solution that also needed its own custom "New" form, not open source unfortunately, though if you are interested you can download it, its called "Tagged Links" (Social Bookmarking for SharePoint) and you can find some links on my blog.
To give you a few hints and tips, the following should set you off in the right direction:
Created a new list definition.
Created a new Content Type In the content type you can define your own "FormTemplates" that references a Rendering Template which determine what gets displayed in the "Middle" bit of those forms.
Copied the standard Rendering Template, but then made the changes to it that I
needed.
Wrapped it all up in a solution, and deployed.
My Rendering Template actually included an overridden "Save" Button where I did a lot of the extra work I needed to do during the save.
Anyway, it is a little too much work in my opinion but, I think, it most closely matches the standard approach taken by the product developers. Let me know if you need more detail and I will see if I can put together a step-by-step blog post, but hopefully this gets you off on the right direction.
I would be surprised if you could do something in a _Layouts file that you can't do in a forms template. You have pretty much the same technologies at your disposal.
Looking at the way SharePoint works with ListItems and Layouts pages (for example "Manage Permissions" on a list item), I can see that they pass some variables in via querystrings:
?obj={76113B3A-FABA-4389-BC85-4BB2CC5AB423},6,LISTITEM&List={76113B3A-FABA-4389-BC85-4BB2CC5AB423}
Perhaps they grab the context back each time programmatically using these values.
I'm not using a custom "new form", so this might not apply. I added an event receiver to my custom content type and then do my custom code in the ItemAdded or ItemAdding events. This code fires when the event is added to a list. You can use the event receiver properties to get to the parent List, Web, and Site.
I'd like to think my issue is "special" here, since I am using a custom form. I chose to use a custom form rather than a custom FormTemplate simply because I'm doing a lot of stuff that's not very SharePoint list-like (making ajax calls to get info from a third-party app then generating some dynamic form elements based on that ajax result, then subsequent processing of that data on postback). I thought it'd be a nightmare to try this within the usual custom rendering template mechanism.
I also don't think I can supply the custom form declarations in the list definition itself, because I have multiple content types associated with this list, and each content type has its own custom form (the other type is thankfully much simpler).
Actually, my simple way of keeping the list guid in my hidden field was a very low impact way to address this specific problem. My main concern is that I'm not sure why the SPContext just loses all its usefulness when I postback here, which makes me think I'm doing something wrong.

Resources