Wednesday, November 10, 2010

Web Album Services: Flickr vs. Google Picasa Web Albums vs. Facebook Photos

As I’m developing an iPhone/iPad app, iShowPhoto, which is mainly used to manage web albums, so I get familiar with some of popular web album services, like Flickr, Google Picasa Web Albums, Facebook Photos, I would like share some information about these services, they may be useful when you wanna share photos.

  • Flickr: Flickr is an online photo management and sharing application, from Flickr’s web site: www.flickr.com, it has two goals:
    • help people make their photos available to the people who matter to them
    • enable new ways of organizing photos and video
         I think Flickr has already done what they want to do, it’s really a great place to store your photos and share them. On Flickr, you can upload your photos and organize them into different Set(like album, but a little different), add friends, add others’ photos to your favorite, and join a group to share photos, and so on..., anyway, there are many ways to share photos with others on Flickr, and it’s easy to find some amazing photos, Flickr is becoming a social network based on photos.
All of these features are free with a little limitation, if you are using a free account, then you can only upload 100MB and 2 videos per month, and you cannot get the original size of your photo(High resolution, > 1024 pixels). Of course you can upgrade to Pro account, now it’s $24.95/year, about $2/month, not so expensive, but almost with on limitation.
Flickr also provide a desktop tool to upload photos, it’s available for Windows and Mac. What should I say to the tool, to be honest, it’s usable, that’s all.

  • Google Picasa Web Albums: Google Picasa Web Albums is also an online photo management application, but I don’t think it’s a sharing application, although it says it does have. Using Picasa, you can upload photos with their original size, and share them with your friends.
  • Only if you have a gmail account, then you can use Picasa. it’s free for the first 1 GB, if you want more, just buy some, it’s really very cheap, 20GB, $5/year, more options can be found here:http://picasa.google.com/support/bin/answer.py?hl=en&answer=165214
Unlike Flickr, Google provides a great desktop tool for Picasa Web Albums, it’s called Google Picasa, which is really awesome, I like it, and it’s free.
  • Facebook Photos: in fact, Facebook Photos is a good place to share photos, it’s not a good place to store your photos, as the upload photos will be scaled to 720 pixels(width or height, the larger one), and all meta data in the photo will be lost. so it’s just a good place to share, but not better than Flickr.
Until now, I didn’t see any official desktop tool to manage photos. Anyway, it’s free, and you have a lot of friends here to share with them.
So, to store your photos online, I prefer Flickr and Google Picasa Web Albums, as they can keep the original photo size and meta data(like camera name, location, taken time, etc.), most of time, they’re important to you, to share your photos, I prefer Flickr and Facebook Photos.

If you know any other good web album service, please share your experience.

Thursday, July 1, 2010

What's wrong with UIScreen.applicationFrame?

I added a subview to my current UINavigationController, but I found that there is a white gap between my subview and top view about 10-20 pixel. I’m not intended to do that, and it’s ugly.

After check each views’ frame, I found that the sub view is inited with the method initWithFrame:[[UIScreen mainScreen] applicationFrame]; and UIScreen.applicationFrame.origin.y is 20, other than 0. From apple’s document, it’s said:
This property contains the screen bounds minus the area occupied by the status bar, if it is visible. Using this property is the recommended way to retrieve your application’s initial window size. The rectangle is specified in points.
but I don’t think that’s the reason of why y is 20. status bar should be at the bottom, right? anyway I changed to use [[UIScreen mainScreen] bounds], but please not that UIScreen.bounds is (0, 0, 320, 480), the height(480) may be wrong, it’s OK right now in my application.

Friday, June 25, 2010

Wired thing after adding subview to UIAlertView

There are many discussions about adding UITextField or other UIView to UIAlertView, here are some links:

  1. New info on adding text fields to alerts
  2. Custom UIAlertView (Color chooser)
  3. Add TextField or other control to UIActionSheet or UIAlertView
At first, I used the undocumented API ‘addTextFieldWithValue’, then I found that your APP may be rejected if undocumented API used. so I changed to the second way, as mentioned in Custom UIAlertView (Color chooser), it works, except one thing, look the following pictures:

This is the first time UIAlertView shows, after I click any button, it dismisses. then when it shows again, looks like this:


I don’t know why, seems cocoa touch re-layout the views again or just forget two buttons positions, as the buttons positions are almost the same as when no subviews in UIAlertView. to avoid this, I have to release the UIAlertView each time after it dismiss.

The following is the code, almost the same as Custom UIAlertView (Color chooser) :
@interface FolderAlertView : UIAlertView
{
        UITextView *errorMsg;
        UITextField *folderName;
}

@property (nonatomic, readonly) UITextView *errorMsg;
@property (nonatomic, readonly) UITextField *folderName;

- (void)clear;
- (NSString *)inputText;
- (void)warn;

@end

@implementation
FolderAlertView

@synthesize errorMsg;
@synthesize folderName;

- (id)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
              
                errorMsg = [[UITextView alloc] initWithFrame:CGRectZero];
                errorMsg.backgroundColor = [UIColor clearColor];
                errorMsg.textColor = [UIColor whiteColor];
                errorMsg.text = @“illegal name“;
                errorMsg.editable = NO;
                errorMsg.font = [UIFont systemFontOfSize:14];
              
                folderName = [[UITextField alloc] initWithFrame:CGRectZero];
                folderName.backgroundColor = [UIColor whiteColor];
                folderName.clearsOnBeginEditing = YES;
                folderName.font = [UIFont systemFontOfSize:17];
                folderName.placeholder = @"Folder Name";
                folderName.adjustsFontSizeToFitWidth = YES;
                folderName.autocorrectionType = UITextAutocorrectionTypeNo;
              
                [super insertSubview:folderName atIndex:0];
                [super insertSubview:errorMsg atIndex:1];
        }
        return self;
}

- (void)setFrame:(CGRect)rect {
        [super setFrame:CGRectMake(0, 0, rect.size.width, 200)];
        self.center = CGPointMake(320/2, 460/2);
}

- (void)layoutSubviews {
        CGFloat buttonTop;
        for (UIView *view in self.subviews) {
                if ([[[view class] description] isEqualToString:@"UIThreePartButton"]) {
                        view.frame = CGRectMake(view.frame.origin.x, self.bounds.size.height - view.frame.size.height - 15,
                                                                        view.frame.size.width, view.frame.size.height);
                        buttonTop = view.frame.origin.y;
                }
        }
      
        buttonTop -= 7;
        buttonTop -= 60;
        errorMsg.frame = CGRectMake(12, buttonTop, self.bounds.size.width - 24, 60);
      
        buttonTop -= 7;
        buttonTop -= 21;
        folderName.frame = CGRectMake(12, buttonTop, self.bounds.size.width - 24, 21);
}

- (void)clear {
        folderName.text = @"";
        errorMsg.textColor = [UIColor whiteColor];
}

- (NSString *)inputText {
        return folderName.text;
}

- (void)warn {
        errorMsg.textColor = [UIColor redColor];
}

- (void)dealloc {
        [errorMsg release];
        [folderName release];
        [super dealloc];
}

@end

Create folder using SharePoint web service

You can find how to create a folder using SharePoint web service at here http://msdn.microsoft.com/en-us/library/lists.lists.updatelistitems%28v=office.12%29.aspx .
The following XML is how to create a folder under a list directly.
<Batch OnError="Continue" PreCalc="TRUE" ListVersion="0" ViewName="{EF2F5A21-0FD0-4654-84ED-112B4F5A48F8}">
<Method ID="1" Cmd="New">
<Field Name="ID">New</Field>
<Field Name="FSObjType">1</Field>
<Field Name="BaseName">FolderA</Field>
</Method>
</Batch>

But my question is how to create a folder in another folder, you cannot set BaseName to the path, like list/folderA/folderB, as BaseName should be the folder name, cannot contain any special characters. after checking the document above, I found that if you want to update/delete a document, the field FileRef must be provided, like this:
<Batch OnError=“Continue” PreCalc=“TRUE” ListVersion=“0” ViewName=“{EF2F5A21-0FD0-4654-84ED-112B4F5A48F8}”>
<Method ID=“1” Cmd=“Delete”>
<Field Name=“ID”>3</Field>
<Field Name=“FileRef”>http://machinename/sites/siteA/listA/folderA</Field>
</Method>
</Batch>

so FileRef is a much important value for SharePoint to identify a document. then I tried to set FileRef field to the folder path when creating a folder, like this:
<Batch OnError="Continue" PreCalc="TRUE" ListVersion="0" ViewName="{EF2F5A21-0FD0-4654-84ED-112B4F5A48F8}">
<Method ID="1" Cmd="New">
<Field Name="ID">New</Field>
<Field Name="FSObjType">1</Field>
<Field Name="BaseName">FolderB</Field>
<Field Name="FileRef">/listA/FolderA/FolderB</Field>
</Method>
</Batch>
There it is. you can see that folder B is created under folder A.

When will google merge google toolbar bookmarks and chrome bookmars?

any plan? or I have to do it manually

in reference to:

"utmx_section("Header") A fast new browser: Now available for Mac"
- Google Chrome - Get a fast new browser. For PC, Mac, and Linux (view on Google Sidewiki)

I do not use Chrome for MAC

I don't know why, after I open Chrome, the OS is freeze for a few seconds frequently.

BTW, why no version information here?

in reference to:

"utmx_section("Header") A fast new browser: Now available for Mac"
- Google Chrome - Get a fast new browser. For PC, Mac, and Linux (view on Google Sidewiki)

Tuesday, June 22, 2010

Delete SharePoint file via web service

As you know, we can talk to SharePoint via web service, Microsoft has provided some default web services for us, also you can deploy your own web services. In this post I will the state the way to delete a file.

The web service method to delete an item is here, send a xml to SharePoint:
<Batch OnError=“Continue” PreCalc=“TRUE” ListVersion=“0” ViewName=“{EF2F5A21-0FD0-4654-84ED-112B4F5A48F8}”>
<Method ID=“1” Cmd=“Delete”>
<Field Name=“ID”>3</Field>
<Field Name=“FileRef”>
http://Server/[sites/][Site/]Shared Documents/File
</Field>
</Method>
</Batch>

Note that to delete a file, other than deleting other type of item, the field “FileRef” must be provided, the url cannot include any encoded characters(exclude / : * .etc that cannot used as folder/file name in SharePoint), for example the above url include a whitespace, if you encode it to ‘%20’, then SharePoint will report an error or do nothing.

Another wired thing is, In my environment, I can browse SharePoint using both machine IP(http://192.168.0.100/) and machine name(http://sharepointserver/), I can use the machine IP to fetch the file content, but when deleting a file, machine name must be used, or SharePoint will report that unable to find the file.

Wednesday, June 9, 2010

Cascade Order

I’m reading a book “Pro.CSS.and.HTML.Design.Patterns”, as I found so many wired things when using CSS, and I think this book may be helpful for me. and I post some of patterns in the book while learning.

CSS Selector Priority
As a CSS rule(like border:1px solid blue) may be assigned to an element multiple times, we must understand which one will effect the element style, so the following are rules, the priority is from high to low:
  1. !important this has the highest priority, when a rule comes with this, it’s the boss.
  2. style on element here style is the HTML element attribute, like <p style=“margin:2px”/>
  3. ID, again ID is the id of a HTML element. like <div id=“css”/>, then you can use #css to define CSS rules for this div.
  4. CSS class, like .cssClass{...}, also including the pseudo, like .cssClass:after{...}, they have the same priority
  5. HTML element like p, div, br .etc
  6. * this is the universal selector, you can write CSS like this *{padding:1px}, then it applies to every HTML element
Most of time, we use class and ID selectors, but I think class selector is enough, which is at forth priority. especially when I started to use JQuery and JQuery UI, it’s a bad idea to use ID as a CSS selector. as in the HTML page, there may be many elements have the same ID but different element and/or usage, and when you collaborate with others, a good idea is to use multiple class selectors to find an element or apply rules.

Sometimes, you may use a combination of several selectors, for example, #css .cssClass .button{...}, or #css2 .cssClass p {...}. at this time, the one has higher priority when it has more selectors of a higher priority. so in the above example, the first one win, as both of them have ID selector, but the first one has two class selectors, and the second has only one class selector.

Location Priority
What if both selectors have the same number and level of selectors? they’er further prioritized by location. here are the rules, from high priority to low:
  1. <style> in HTML <header>
  2. @import within <style>
  3. <link>
  4. @import within a CSS file attached by <link>
  5. CSS file attached by an end user? how? don’t understand :(
  6. default CSS supplied by a browser
when multiple stylesheets are attached or imported at the same level, stylesheet attached later override stylesheets attached previously.

Thursday, May 27, 2010

iTunes lyrics tool

I was trying to find a good iTunes tool that can download lyrics automatically today, but didn't get any one. nLyrics always crashed, GimmeSomeTune cannot find most of my song, Get Lyrics cannot get any lyrics either. anyone know a good tool?

Wednesday, May 26, 2010

Text Replacement Pattern

I’m reading a book “Pro.CSS.and.HTML.Design.Patterns”, as I found so many wired things when using CSS, and I think this book may be helpful for me. and I post some of patterns in the book while learning.

Usage
Text Replacement pattern is a combination of Absolute pattern and Background pattern, it’s used to display an image, if the image fails to download, the text will be shown.

Implement
To implement Text Replacement pattern, we need three HTML elements, one is the container, one is used to show image, and another displays text(also you can combine the container and text together to reduce the tags). the following is the code:
<head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>background</title>
        <style type="text/css">
#h2 { position:relative; width:500px; height:100px; overflow:hidden; }
#h2 span { position:absolute; width:
500px; height:100px; left:0; top:0;
background:url("500x100.png") no-repeat; }
        
</style>
</head>
<body>
<h1>Text Replacement</h1>
<h2 id="h2">Heading 2<span></span></h2>
</body>

this is the picture in browser:

and after the change the background image to a nonexistent image, then it looks like this:


Alternate
Yes, I know that you can use Alt attribute of img tag, like this:
<img src="500x100.png" alt="Heading 2"/>
It almost has the same effect with Text Replacement pattern, except that you can not control the text style. With Text Replacement pattern, you can decide how to display the text.

Note
This is not a complex pattern, but I think the most important part is “Combination”, you may know many CSS properties, but can you combine them together to get a new style?

Tuesday, May 25, 2010

Absolute pattern

I’m reading a book “Pro.CSS.and.HTML.Design.Patterns”, as I found so many wired things when using CSS, and I think this book may be helpful for me. and I post some of patterns in the book while learning.

Absolute pattern
Like background pattern, it’s a simple CSS built in property, position:absolute. using absolute pattern, you can position a HTML element at a specified position in its ancestor’s area, and the HTML element will not be in the HTML tag flow(placed one by one).

here is the code(I added the border in CSS, so that you can find where each HTML tag is):
<head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>Absolute</title>
        <style type="text/css">
             .positioned { position : relative; border : 1px solid #000000;}
             .absolute {
                 position : absolute;
                 top :
10px;
                 left :
10px;
                 border :
1px solid #000000;
             }
        
</style>
</head>
<body>
<h1>Absolute</h1>
<div class="positioned">
<span class="absolute">Sized Absolute</span>
</div>
</body>


Note
One thing to mention, in the book, the above code displays like this

but in my firefox 3.6, it looks like this

I think you already find the difference, the <div/> in my firefox looks like just one black line, does not wrap the <span/>, I think that’s because <span/> used Absolute pattern, it’s not a child of <div/> when shown in browser, although it is physically(in code). but from firebug, if you disable <span/>’s ‘position:absolute’, then everything looks like image in the book.

Monday, May 24, 2010

Jquery UI web site down?

When I visit JQuery UI website http://jqueryui.com/, it only show me “Welcome to nginx!”, the website is down? anyone knows why?

Background pattern

I’m reading a book “Pro.CSS.and.HTML.Design.Patterns”, as I found so many wired things when using CSS, and I think this book may be helpful for me. and I post some of patterns in the book while learning.

Background pattern
In fact this is a built in property of CSS, which is used to set the background image of an HTML element.

for example:
<head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>background</title>
        <style type="text/css">
                div {
                        background : url(corner.jpg) no-repeat;
                        width :
220px;
                        height :
220px;
                }
        
</style>
</head>
<body>
<h2>Background Image</h2>
<div></div>
</body>


it’s very simple, and most of coders known it.

Related CSS Properties
I just want to introduce several CSS properties that related to background.
background is a shorthand of a list of ordered properties, they are:
  1. background-color : set the color of background
  2. background-image : set background image, which is used in this pattern
  3. background-repeat : by default, the background image is repeated to fill the whole HTML element, but you can control how to repeat or do not repeat, it has three values: repeat-x(horizontal), repeat-y(vertical), no-repeat
  4. background-attachment : sets whether a background image is fixed or scrolls with the rest of the page. so if you set it to scroll, then the background image may be not shown when you scroll down the page, but if it’s fixed, then the image always shown at the original place, no matter how to scroll
  5. background-position : the starting position of background image, you may use keywords(left, right, center, top, bottom) or integer or % to specify the position.
Note
  • it’s recommended to test the every pattern in the book, and you can use firebug(firefox add-on) to disable a property or add new CSS property, the tool is much helpful, no need to switch between the CSS/HTML file and browser, just test what you want on browser first, when everything is OK, copy the CSS back to file.

Tuesday, May 18, 2010

clear:both

As I’m a newbie in coding CSS, so I use this blog to record any problem I’ve encountered, and most of time, the title is how I resolved it.




Problem:

now I want to create a form-like div:
<style type="text/css">
.test{
display : block;
}
.left {
float : left;
}
.right {
float : right;
}
#test {
width : 300px;
}
</style>

<div id="test">
<div class="test">
<label class="left">Test1</label>
<input type="text" class="right"/>
</div>
<div class="test">
<label class="left">Test2</label>
<textarea type="text" class="right"></textarea>
</div>
<div class="test">
<label class="left">Test3</label>
<input type="text" class="right"/>
</div>
</div>

what I want is each pair of label and input stay in one line. but using the above code, I got a ugly view. all the labels and inputs are in one line, other than in three lines. but I’ve already used display:block, that’s what I know used to clear the whole line, apparently, it doesn’t work here.

JQuery UI:
then I remeber that jquery ui provides a CSS class ‘ui-help-clearfix’, so I add it to my code like this:
<div class="test ui-help-clearfix”>
<label class="left">Test1</label>
<input type="text" class="right"/>
</div>
this really works, why!

from firebug(firefox add-on), I found that ui-help-clearfix is the same as my CSS class ‘test’:
.ui-help-clearfix{
display : block;
}
then I checked the jquery ui code, found the following code:
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
.ui-helper-clearfix { display: inline-block; }
/* required comment for clearfix to work in Opera \*/
* html .ui-helper-clearfix { height:1%; }
.ui-helper-clearfix { display:block; }
I think what makes it work is the persudo-class ‘:after’. so I comment ‘.ui-helper-clearfix:after’, then the view got ugly again. the pesudo-class ‘:after’ is used to add content after the given selector. then I deleted ‘visibility: hidden;’ from ‘.ui-helper-clearfix:after’, and change height to 10px, so that I can see what added. I think you already know what added, just a dot ‘.’, :). and jquery ui hide the dot. after several test by deleting each CSS property, you can find that ‘clear:both’ helps to eliminate other tags shown in the same line, so I add ‘clear:both’ to my CSS class ‘test’, then everything works fine.

others:
another point is firebug cannot show the content added by pesudo class ‘:after’.

but why jquery ui uses ‘.ui-helper-clearfix:after’ to clear everything other than add ‘clear:both’ to ‘.ui-helper-clearfix’, emmm.... thinking.....

Wednesday, May 12, 2010

JQuery.wrap()

This may be a trap when using JQuery.wrap().
for example, when I want to wrap a form with a new div, then I continue to use newly created as a JQuery UI dialog, then I found that the dialog is empty, the was not in it.

the following is the code:
var form = $('body').find('form');
//the new div
var div = $('&ltdiv/&gt');
form.wrap(div);

div.dialog();

I think the reason is when calling div.dialog(), the object div is still the newly created div, it has not been added to HTML(or its clonely was added to HTML), so to fix it, we can use the selector to get it again:

var form = $('body').find('form');
//the new div
var div = $('&ltdiv id="test"/&gt');
form.wrap(div);

div = $('body').find('#test');
//this time it works
div.dialog();