| Comments

If you want some great Silverlight information, be sure to subscribe to at least two feeds: Microsoft Silverlight Bloggers and Silverlight community feeds.  I’ve recently just added a bunch of great feeds to both of these including all the members of the Silverlight Toolkit team and some Silverlight MVPs such as John Papa.

There are also a bunch of resources being added to the Silverlight community site over the next month.  We also added 27 new showcase entries to the Silverlight Showcase on the site.  One in particular that I think is interesting is a project Gantt representation done in Silverlight with complete capabilities for moving the timeline, etc.

This example, created by iLog, demonstrates some creative uses of Silverlight for line of business applications.  Check out the other 27 new showcase entries on the site and subscribe to the feeds to stay up-to-date on what is happening on the Silverlight community.

| Comments

FeedReader is a web part for Microsoft SharePoint server products (MOSS and WSS).  It’s purpose is to aggregate more than one feed in a single web part.  The built-in XML and RSS web parts for SharePoint only allow one feed by default.  feedreader can support Atom or RSS feeds.  Please report any issues as a Work Item on the project.  Source code is also available on the project site under a very permissive license.

Thanks for using feedreader!


This work is licensed under a Creative Commons Attribution By license.

| Comments

Sharing Knowledge.  That was the theme of the Øredev conference held this past week in Malmö, Sweden.  I was invited this year to participate in this conference in the Scandanavian area to speak on Silverlight technologies.  I am very humbled to have been invited.  This was truly a great conference and let me tell you my impressions.

I’ve attended Microsoft’s PDC, TechEd, VSLive, DevConnections, etc.  I’ve got most of them all under my belt (as an attendee).  They are all good in their own regard.  The ones that are most interesting, however, are those that have an intensity about them and a collaboration among the other attendees who may or may not know each other.  That is what I felt at Øredev this past week.  This was the ultimate “code camp” which brought together a ton of different technology conversations in the setting of a large conference.  There was representation from both technology and practices: .NET, Java, project management, user experience, Agile/Scrum methodologies, mobile development, etc., etc.  You name it, it was there.

Along with Beatriz Stollnitz (Costa), I spoke on Silverlight, specifically accessing data and writing custom controls.  After each session we were invited to dig deeper with any attendees who wanted in a “chalk talk” setting, which I did and was able to get some good feedback to take back to a few teams at Microsoft.  After each time I presented, I was presented with a “thank you” certificate on behalf of the conference, which represented a donation to UNICEF.  The conference decided to ensure that the technical community in that area give back to a cause that needed assistance.  At the end of the conference, representatives of UNICEF were presented with a donation of around 200,000 SEK from the Øredev conference.  Very nice.

At the beginning of the conference, the city hosting us, Malmö, invited the speakers to attend a nice dinner at the city hall with the deputy mayor.  I personally thought it was very cool of the city to be involved and a classy act on their behalf (and the conference organizers).

What made Øredev special to me was the sincerity of learning and diversity in attendees.  Generally, even at the local code camps I’ve attended, there always seems to be this animosity between technology experts.  Not here.  In fact I spent an hour talking with an engineer from the JavaFX team about what they are doing, seeing some of their thoughts and learning about what essentially amounts to a competitive platform for the area I work in.  There was no “ours is better” moments in that conversation.  In fact he also mentioned that he’d not really paid attention to Silverlight until this week and is impressed with some of what he saw.  People from Google were there showing Android and getting people excited about that (and they brought it on a few different devices other than what I think is the ugly G1 form factor).  It was a perfect environment for learning together about different things and having open conversations about the technology, and as well as what we as software engineers can do to help create better software and innovate more in what we are already doing.

One cool logistic thing I liked about the conference was removing the long form evaluation concept for speakers.  Instead of relying on people to go to a web site after the fact and enter in an evaluation (which is very hard to collect and usually yields an incredibly low ratio of those who attend sessions actually filling out feedback), each attendee of every session was asked to “vote” on their way out of the room.  There were 3 stacks of cards: Red, Yellow, Green.  You pick the one that fit your impression of the session and put it in the bucket.  This removes the negative marks from the speaker for things like “couldn’t hear, chairs squeeky (which they were), too cold” and so on.  Those type of feedback are needed and still collected by the various delegates that are mingling with the crowd throughout the week.  I wish every conference I went to simplified down to this!

Of the other cool things, I was able to get a demonstration of Strangeloop Network’s AS1000 appliance for ASP.NET applications.  I spent time talking with Richard Campbell and understanding what it does and then proceeded to actually see the effective results in action.  Holy crap it was cool.  If you want better overall performance of your site to our users, you owe it to yourself to check it out.  I’m trying to convince my manager now that we need one!

It was also very fun to meet Linus, Chris, George, Magnus and Michael who all had a part in organizing the conference either as a speaker, track lead, and Michael as one of the main organizers with Emily.  Magnus had invited some people to his flat at the beginning of the conference, but jetlag was evil on me and I didn’t make it…I heard it was a blast as well.  Having dinner with Ted “The Dude” Neward watching him trying to survive a 600gr steak was also a great night in Sweden.  I was able to stay through the weekend and hang out with Richard and Carl and Glenn Block in Copenhagen touring the city and having some great conversations (or at least I think they were).

Overall, hanging out with smart and fun people and participating in this conference was a really exciting time.  If you are close to the area, it is a not-miss conference in my opinion, so mark your calendars for next year.  I hope that I might be invited back in the future.

So thank you to Linus, Magnus, Emily and Michael for inviting me to participate and making it special.  I think the show was a success and your region should be very proud of this conference!  Great job to all!

| Comments

At PDC the WPF Tookit was made available which provides several new controls to WPF to help bring even more compatibility to the WPF and Silverlight story.  The new controls were the DatePicker, Calendar, DataGrid and the VisualStateManager concept to WPF.  Ribbon controls were also provided to the WPF Toolkit, but are not covered here.

With the introduction of this toolkit, developers now have a way to get some even more common XAML code-base between projects.

Let’s take a look at a very simple example of both UI and code sharing with WPF and Silverlight.  Here’s the simple scenario.  I’m going to use a common “Customer” class that I want to use in both a WPF and Silverlight implementation.  Since there is no binary compatibility for Silverlight and WPF, I’m going to maintain source-level compatibility.  In order to do this, I’m going to create a Silverlight Class Library project and implement my Customer class in that…here’s my simple customer class:

   1: namespace SilverlightClassLibrary1
   2: {
   3:     public class Customer
   4:     {
   5:         public string FirstName { get; set; }
   6:         public string LastName { get; set; }
   7:         public int CustomerId { get; set; }
   8:         public string CustomerLevel { get; set; }
   9:         public DateTime Birthdate { get; set; }
  10:  
  11:         public static ObservableCollection<Customer> GetCustomerData()
  12:         {
  13:             ObservableCollection<Customer> ppl = new ObservableCollection<Customer>();
  14:  
  15:             ppl.Add(new Customer() { FirstName = "Tim", LastName = "Heuer", CustomerId = 1, CustomerLevel = "Platinum", Birthdate = Convert.ToDateTime("9/18/1965") });
  16:             ppl.Add(new Customer() { FirstName = "Ray", LastName = "Ozzie", CustomerId = 1, CustomerLevel = "Gold", Birthdate = Convert.ToDateTime("1/12/1960") });
  17:             ppl.Add(new Customer() { FirstName = "Bill", LastName = "Gates", CustomerId = 1, CustomerLevel = "Silver", Birthdate = Convert.ToDateTime("12/1/1976") });
  18:             ppl.Add(new Customer() { FirstName = "Bart", LastName = "Simpson", CustomerId = 1, CustomerLevel = "Tin", Birthdate = Convert.ToDateTime("7/4/1985") });
  19:  
  20:             return ppl;
  21:         }
  22:     }
  23: }

Now in my Silverlight project and my WPF application I add a linked file to that class library for customer.  While not binary compat, each time I compile I’m using a common source compat for both projects.  Here’s what my project structure looks like and you can see the linked source code:

Now in my WPF project I want to add some XAML, so I’ll add this to my Window1.xaml:

   1: <Window x:Class="WpfSampler.Window1"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
   5:     Title="Window1" Height="600" Width="600">
   6:     <Grid>
   7:         <StackPanel Orientation="Vertical" Margin="15">
   8:             <TextBlock Text="Your Birthdate" />
   9:             <controls:DatePicker x:Name="MyBirthdate" Text="9/18/1965" />
  10:             <controls:DataGrid Height="400" x:Name="CustomerList"/>
  11:         </StackPanel>
  12:     </Grid>
  13: </Window>

Here’s the backing source code logic for the simple windows app:

   1: namespace WpfSampler
   2: {
   3:     /// <summary>
   4:     /// Interaction logic for Window1.xaml
   5:     /// </summary>
   6:     public partial class Window1 : Window
   7:     {
   8:         public Window1()
   9:         {
  10:             InitializeComponent();
  11:             Loaded += new RoutedEventHandler(Window1_Loaded);
  12:         }
  13:  
  14:         void Window1_Loaded(object sender, RoutedEventArgs e)
  15:         {
  16:             CustomerList.ItemsSource = SilverlightClassLibrary1.Customer.GetCustomerData();
  17:         }
  18:     }
  19: }

Now in my Silverlight project I’m going to paste the same XAML:

   1: <UserControl x:Class="SilverlightWpfReuse.Page"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:     xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
   5:     xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
   6:     Width="600" Height="600">
   7:     <Grid x:Name="LayoutRoot" Background="White">
   8:         <StackPanel Orientation="Vertical" Margin="15">
   9:             <TextBlock Text="Your Birthdate" />
  10:             <controls:DatePicker x:Name="MyBirthdate" Text="9/18/1965" />
  11:             <data:DataGrid Height="400" x:Name="CustomerList"/>
  12:         </StackPanel>
  13:     </Grid>
  14: </UserControl>

and here’s the Silverlight source code logic as well:

   1: namespace SilverlightWpfReuse
   2: {
   3:     public partial class Page : UserControl
   4:     {
   5:         public Page()
   6:         {
   7:             InitializeComponent();
   8:             Loaded += new RoutedEventHandler(Page_Loaded);
   9:         }
  10:  
  11:         void Page_Loaded(object sender, RoutedEventArgs e)
  12:         {
  13:             CustomerList.ItemsSource = SilverlightClassLibrary1.Customer.GetCustomerData();
  14:         }
  15:     }
  16: }

So if you have a keen eye you’ll see it’s not full cut/paste as you note the xmlns declarations in the root control.  Since the implementations are in two different assemblies (System.Windows.Controls.dll for Silverlight and Microsoft.Windows.Controls.dll for WPF Toolkit) we have to make sure they are referenced accordingly.  We can still use the same prefix though of “controls” so that we have greater re-use across our XAML.  For DataGrid, we need to do an additional step since for Silverlight it is on its own assembly.

If we run these applications here is what we get:

WPF Application:

Silverlight application:

Sure we had to do some maneuvering (xmlns stuff) but if you have some great XAML/code you can still get some good re-use out of those implementations with little effort and share code!

So what about VisualStateManager?  How do you use that in WPF if you already have something in Silverlight?  Let’s simplify it to the most common/basic control – Button.  Using Blend we’ve styled a simple Button control and Blend has generated the appropriate VSM resources for us (note that I am not a designer and just used Blend to quickly make 2 changes that probably look horrible :-):

   1: <Style x:Key="StyledButton" TargetType="Button">
   2:             <Setter Property="Background" Value="#FF1F3B53"/>
   3:             <Setter Property="Foreground" Value="#FF000000"/>
   4:             <Setter Property="Padding" Value="3"/>
   5:             <Setter Property="BorderThickness" Value="1"/>
   6:             <Setter Property="BorderBrush">
   7:                 <Setter.Value>
   8:                     <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
   9:                         <GradientStop Color="#FFA3AEB9" Offset="0"/>
  10:                         <GradientStop Color="#FF8399A9" Offset="0.375"/>
  11:                         <GradientStop Color="#FF718597" Offset="0.375"/>
  12:                         <GradientStop Color="#FF617584" Offset="1"/>
  13:                     </LinearGradientBrush>
  14:                 </Setter.Value>
  15:             </Setter>
  16:             <Setter Property="Template">
  17:                 <Setter.Value>
  18:                     <ControlTemplate TargetType="Button">
  19:                         <Grid>
  20:                             <vsm:VisualStateManager.VisualStateGroups>
  21:                                 <vsm:VisualStateGroup x:Name="CommonStates">
  22:                                     <vsm:VisualState x:Name="Normal"/>
  23:                                     <vsm:VisualState x:Name="MouseOver">
  24:                                         <Storyboard>
  25:                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity">
  26:                                                 <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
  27:                                             </DoubleAnimationUsingKeyFrames>
  28:                                             <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
  29:                                                 <SplineColorKeyFrame KeyTime="0" Value="#F2FFFFFF"/>
  30:                                             </ColorAnimationUsingKeyFrames>
  31:                                             <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
  32:                                                 <SplineColorKeyFrame KeyTime="0" Value="#CCFFFFFF"/>
  33:                                             </ColorAnimationUsingKeyFrames>
  34:                                             <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
  35:                                                 <SplineColorKeyFrame KeyTime="0" Value="#7FE61212"/>
  36:                                             </ColorAnimationUsingKeyFrames>
  37:                                             <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">
  38:                                                 <SplineColorKeyFrame KeyTime="00:00:00" Value="#FFEE4B4B"/>
  39:                                             </ColorAnimationUsingKeyFrames>
  40:                                         </Storyboard>
  41:                                     </vsm:VisualState>
  42:                                     <vsm:VisualState x:Name="Pressed">
  43:                                         <Storyboard>
  44:                                             <ColorAnimationUsingKeyFrames Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">
  45:                                                 <SplineColorKeyFrame KeyTime="0" Value="#FFF40B0B"/>
  46:                                             </ColorAnimationUsingKeyFrames>
  47:                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity">
  48:                                                 <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
  49:                                             </DoubleAnimationUsingKeyFrames>
  50:                                             <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
  51:                                                 <SplineColorKeyFrame KeyTime="0" Value="#D8FFFFFF"/>
  52:                                             </ColorAnimationUsingKeyFrames>
  53:                                             <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
  54:                                                 <SplineColorKeyFrame KeyTime="0" Value="#C6FFFFFF"/>
  55:                                             </ColorAnimationUsingKeyFrames>
  56:                                             <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
  57:                                                 <SplineColorKeyFrame KeyTime="0" Value="#8CFFFFFF"/>
  58:                                             </ColorAnimationUsingKeyFrames>
  59:                                             <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
  60:                                                 <SplineColorKeyFrame KeyTime="0" Value="#3FFFFFFF"/>
  61:                                             </ColorAnimationUsingKeyFrames>
  62:                                         </Storyboard>
  63:                                     </vsm:VisualState>
  64:                                     <vsm:VisualState x:Name="Disabled">
  65:                                         <Storyboard>
  66:                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity">
  67:                                                 <SplineDoubleKeyFrame KeyTime="0" Value=".55"/>
  68:                                             </DoubleAnimationUsingKeyFrames>
  69:                                         </Storyboard>
  70:                                     </vsm:VisualState>
  71:                                 </vsm:VisualStateGroup>
  72:                                 <vsm:VisualStateGroup x:Name="FocusStates">
  73:                                     <vsm:VisualState x:Name="Focused">
  74:                                         <Storyboard>
  75:                                             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity">
  76:                                                 <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
  77:                                             </DoubleAnimationUsingKeyFrames>
  78:                                         </Storyboard>
  79:                                     </vsm:VisualState>
  80:                                     <vsm:VisualState x:Name="Unfocused"/>
  81:                                 </vsm:VisualStateGroup>
  82:                             </vsm:VisualStateManager.VisualStateGroups>
  83:                             <Border x:Name="Background" Background="White" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
  84:                                 <Grid Margin="1" Background="{TemplateBinding Background}">
  85:                                     <Border x:Name="BackgroundAnimation" Opacity="0" Background="#FF448DCA"/>
  86:                                     <Rectangle x:Name="BackgroundGradient">
  87:                                         <Rectangle.Fill>
  88:                                             <LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
  89:                                                 <GradientStop Color="#FFFFFFFF" Offset="0"/>
  90:                                                 <GradientStop Color="#F9FFFFFF" Offset="0.375"/>
  91:                                                 <GradientStop Color="#E5FFFFFF" Offset="0.625"/>
  92:                                                 <GradientStop Color="#C6FFFFFF" Offset="1"/>
  93:                                             </LinearGradientBrush>
  94:                                         </Rectangle.Fill>
  95:                                     </Rectangle>
  96:                                 </Grid>
  97:                             </Border>
  98:                             <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" x:Name="contentPresenter" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
  99:                             <Rectangle x:Name="DisabledVisualElement" IsHitTestVisible="false" Opacity="0" Fill="#FFFFFFFF" RadiusX="3" RadiusY="3"/>
 100:                             <Rectangle Margin="1" x:Name="FocusVisualElement" IsHitTestVisible="false" Opacity="0" Stroke="#FF6DBDD1" StrokeThickness="1" RadiusX="2" RadiusY="2"/>
 101:                         </Grid>
 102:                     </ControlTemplate>
 103:                 </Setter.Value>
 104:             </Setter>
 105:         </Style>

There is nothing more we have to do in Silverlight since VSM is a part of the core.  We just annotate our Button with the style:

   1: <Button Content="Styled Button" Style="{StaticResource StyledButton}" />

Now in WPF we can use those same resources by adding them to our Grid.Resources node in our Window1.xaml file.  The thing is that we don’t need the vsm: prefix.  A simple find/replace removes them and we have our style button.  The resulting full XAML for the style looks the exact same (minus any vsm: prefix) and the XAML for the button also looks the same.

I think there has to be a better way to use linked files here as well, so I’ll think about that and report back if I find one.  I know this is a very simple demonstration of only a bit beyond Hello World, but I hope at least it gets you thinking of how you can get source-level compatibility and some XAML re-use out of your Silverlight and WPF applications. 

What are your thoughts?  Have you found better ways?  What are the stumbling blocks you are facing in code sharing?

| Comments

This is a public service announcement for my Flickr4Writer project.  It was recently brought to my attention that Flickr has some privacy settings that users can opt-in for in their account to protect their images.  Some users felt that my plug-in for Writer was not honoring these settings.  Truly, I didn’t know about them.  You can read the thread on the discussion lists here if you are so inclined.  For me it came down to a couple of items:

    • Flickr enables users to set a flag to prevent “blogging” of their images
    • Flickr enables users to be hidden from 3rd Party/API searches

First, a note on the “blogging” flag.  This is a setting under your Flickr account privacy tab labeled Who can blog your photos or videos?.  To me, this setting is a little misleading because the description of it actually reads:

This means that anyone who does not match at least the contact level you select will not be able to see the "Blog This" button. (Source: http://www.flickr.com/account/prefs/blogging/?from=privacy 07 NOV 2008)

This setting is clearly for the “Blog This” functionality that shows up if you are logged into Flickr as a non-anonymous user and browse photos.  There is some functionality for them to integrate directly with your blog engine to do some one-click blogging of photos and videos.  Because of the way the setting is named however, some users interpret “blogging” in the broader sense.  flickr4writer was challenged as one violating the principal of this setting.  Since the setting ONLY enables authenticated users to even blog (the setting options go from any Flickr user (non-anonymous) to your specific friends/family settings.  flickr4writer does not use any authentication, so browsing any photos has the appearance to violate this term if the plugin enables an anonymous user to browse and select photos in a tool that is build for “blogging.”  While I draw the correlation that flickr4writer is basically a shell to the web site and does not do anything different than an anonymous user being able to browse and grab an image URL, it is the essence of the rule that I was alleged to violate.  One challenge here is also that the API is poorly designed in this regard because the “canblog” setting is returned only at the photo level even though it is an uber setting for the user’s account.  I think it should be a filter param of the photos.search API call.

The second setting about 3rd Party/API blocking from searches gets even more interesting.  First, this totally makes sense.  Again, it was a setting I wasn’t aware of.  You can change your setting under a section titled Hide your photostream from searches on 3rd party sites that use the API?  Great.  You’d think that once a user selected this setting that any search would filter out their photos/vidoes at the API level right?  Wrong.  flickr4writer uses photos.search calls to query data (actually technically the library that Flickr4Writer uses does).  Again, by definition of this API, only public searchable photos will be returned.  UNLESS you specify a user name.  What?!?!  Yes, that’s right…if you specifc a user name, their results will come back in the API call.  Read that again.  If you specify a user name in flickr.photos.search it will not honor the user’s privacy setting.  So this sucks for me as an API developer/consumer who wants to honor those settings.

So on to the resolutions.  First, I added authentication.  flickr4writer now requires you to have a valid Flickr account to even use it (their accounts are free).  This helps with the first part about blogging.  If a user has specified they do not want their content to be blogged, I honor that and will alert the flickr4writer user with a message that the user they searched prevents blogging and no search results will display.  I feel that this complies with that setting within my application.  If a user wants to bypass my app and copy/paste the URL to the photo/video still…that’s Flickr’s problem now, not mine.  Adding authentication also enabled me to comply with the blogging settings of users because it identifies who the user is and whether or not they can blog the content.

The second thing I modified was to only return content that had Creative Commons or No known license attributes.  This actually makes sense and I needed to do it for a while.  The licenses I filter for are identified in the flickr.photos.licenses.getInfo API.  So if a user has content that is “All rights reserved” then it will no longer show up in the search…even if you are the owner of that content.  I’m interested in feedback on this one if you think I should do a check to see if you are the owner and allow you to see licensed content…leave a comment on how you feel about this one.

For the setting of hiding from 3rd parties…I cannot resolve this.  There is no setting for me to look at.  I’m quite disappointed that Flickr isn’t doing this at the API level as I think that they are violating the user preferences by enabling a loophole.  Should they enable a setting for this (I think they just need to fix the API), I will enable my application to comply even more.  Please if you are a Flickr user who has set this privacy setting, let Flickr know that you want it to be honored.

The authentication adds some initial screens to the use of flickr4writer.  When you launch the plug-in from within Writer, you’ll now see some prompts to authorize the application with Flickr.  There will be a button that will take you to Flickr to authorize the action.  This is only required one time and you won’t see it anymore unless you de-authorize the application on your account (which you have the complete control to perform).

Please upgrade to the latest version.  You will have to uninstall any previous version before installing, but will not lose any settings.  Thanks for your assistance in helping keeping flickr4writer compliant.