<%@ Control Language="C#" ClassName="ThumbList" Debug="true"%>
<%@ import Namespace="System.IO" %>
<%@ import Namespace="System.Drawing" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="PhilipSoft.Thumbnails" %>
<script runat="server">
// ----- Copyright Philipos Sakellaropoulos 2002 -------
private String _path,_vpath="", _filter="";
private int _width,_height,_pagesize;
private bool _bSaveThumbnails,_bShowFilenames;
ThumbGenerator _oGenerator;
// ------- public properties of the control ----------
public int Width { get {return _width;} set {_width=value; } }
public int Height { get {return _height;} set {_height=value; } }
public String VPath { get {return _vpath;}
set { _vpath=value.TrimEnd('/'); }
}
public int Columns
{ get {return MyThumbList.RepeatColumns;}
set {MyThumbList.RepeatColumns=value; } }
public String HeaderTitle;
public bool SaveThumbnails
{ get {return _bSaveThumbnails;} set {_bSaveThumbnails=value; } }
public bool ShowFilenames
{ get {return _bShowFilenames;} set {_bShowFilenames=value; } }
// filter example: *.gif;*.jpg
public String Filter { get {return _filter;} set { _filter=value; } }
// im bored of get and set, i 'll make the rest public !!
public bool AllowStretch;
public bool AllowPaging;
public bool HideNavBar;
public bool Sort;
public bool Refresh;
public int PageSize
{ get {return _pagesize;}
set {_pagesize=Math.Abs(value); } }
public int CurPage;
// by default don't use COM object unless explicitly requested
public bool UseCOMobj;
// create bevel effect for thumbnails
public bool Bevel;
public Color ItemBackColor
{ get { return MyThumbList.ItemStyle.BackColor; } set { MyThumbList.ItemStyle.BackColor=value; } }
// new properties
public bool ShowComments;
public bool AllowEdit;
// ~~~~~~~~~~~~~ Standard functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Page_Load(Object Src, EventArgs e)
{
// get physical path of images
_path = Server.MapPath(_vpath);
// register client script to got to a next page
StringBuilder scriptb = new StringBuilder();
scriptb.Append("<script language=\"javascript\">\n");
scriptb.Append("//<!--\n function GoToPage(vpath,n) { \n");
scriptb.AppendFormat("document._ctl0.{0}.value=n; \n",hdnCurPage.ClientID);
scriptb.Append(Page.GetPostBackEventReference(this));
scriptb.Append("\n } \n//-->\n </");
scriptb.Append("script>");
if(!Page.IsClientScriptBlockRegistered("clientGotoPageScript"))
Page.RegisterClientScriptBlock("clientGotoPageScript", scriptb.ToString());
// if not in update, bind every time since parameters may have change
if(MyThumbList.EditItemIndex < 0)
BindThumbList();
}
// we are databound, now we know how many pages we have
// and the current page so we can create the navigation bar
void Item_DataBound(Object sender, DataListItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Footer) {
Trace.Warn("DataBound event for footer");
PlaceHolder plLinks = (PlaceHolder)e.Item.FindControl("plLinks");
if(AllowPaging && !HideNavBar) CreateNavBar(plLinks);
hdnPrevPath.Value = VPath;
}
}
void ThumbList_EditCommand(Object sender, DataListCommandEventArgs e)
{
MyThumbList.EditItemIndex = (int)e.Item.ItemIndex;
BindThumbList();
}
void ThumbList_CancelCommand(Object sender, DataListCommandEventArgs e)
{
MyThumbList.EditItemIndex = -1;
BindThumbList();
}
void ThumbList_UpdateCommand(Object sender, DataListCommandEventArgs e)
{
DataRowView drvTarget;
String sComment = (String)((TextBox)e.Item.FindControl("txtComment")).Text;
String sFilename = ((TextBox)e.Item.FindControl("txtFilename")).Text;
DataSet dsComments = ReadCommentsFromXML();
DataView dvCommentsFromXML = dsComments.Tables[0].DefaultView;
dvCommentsFromXML.RowFilter = "Filename='"+sFilename+"'";
// find row for filename or create a new one if does not exist
if (dvCommentsFromXML.Count > 0) {
drvTarget = dvCommentsFromXML[0];
dvCommentsFromXML.RowFilter = "";
}
else {
drvTarget = dvCommentsFromXML.AddNew();
drvTarget[0] = sFilename;
}
drvTarget[1] = sComment;
drvTarget.EndEdit();
dsComments.WriteXml(_path +"\\ThumbComments.xml");
MyThumbList.EditItemIndex = -1;
BindThumbList();
}
// ~~~~~~~~~~~~~~ Custom Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void BindThumbList()
{
String[] files; int i;
ArrayList arFilesAll = new ArrayList();
try {
if(_filter.Length==0 || _filter=="*.*") {
files = Directory.GetFiles(_path);
arFilesAll.AddRange(files);
}
else { // separate different filters with ';'
String[] filters = _filter.Split(';');
for(i=0; i<filters.Length; i++) {
files = Directory.GetFiles(_path,filters[i]);
arFilesAll.AddRange(files);
}
}
// create the datasource (list of files)
for(i=0; i<arFilesAll.Count; i++)
arFilesAll[i] = Path.GetFileName((String)arFilesAll[i]);
MyThumbList.Attributes["TotalFiles"] = arFilesAll.Count.ToString();
if(_bSaveThumbnails) {
_oGenerator = new ThumbGenerator();
String pathThumbs = _path+"\\thumbnails";
Directory.CreateDirectory(pathThumbs);
} // end if save thumbs
} catch(Exception exDir) { arFilesAll = new ArrayList(); }
// sort file-list if requested
if(Sort)
arFilesAll.Sort();
// page thumblist if requested
ArrayList arFilesToShow;
if(!AllowPaging)
arFilesToShow = arFilesAll;
else { // create a data source with only the page files
int totalPages = (int)Math.Ceiling((float)arFilesAll.Count/PageSize);
if(totalPages==0) totalPages=1;
MyThumbList.Attributes["TotalPages"] = totalPages.ToString();
if(CurPage<1) {
// we have not given a page from caller, get it from hidden field
try {
CurPage = int.Parse(hdnCurPage.Value); //Request.Form["__EVENTARGUMENT"]);
} catch(Exception exParse) { CurPage=1; }
}
if(hdnPrevPath.Value!=VPath) // restart page numbering
CurPage = 1;
Trace.Warn("BindThumbList: Current page=" + CurPage.ToString());
// make sure current page is in the [1,totalPages] range
if(CurPage>totalPages) CurPage=totalPages;
else if(CurPage<1) CurPage=1;
// store curPage in attributes and in hidden field
MyThumbList.Attributes["CurPage"] = CurPage.ToString();
hdnCurPage.Value = CurPage.ToString();
// put files of the page in the dsPageFiles array
int startIndex = (CurPage-1)*PageSize;
int endIndex = Math.Min(CurPage*PageSize,arFilesAll.Count);
arFilesToShow = arFilesAll.GetRange(startIndex, endIndex-startIndex );
} // end define page
// create in-memory DataTable to be the data source
DataTable dtThumbs = CreateCommentsTable();
DataView dvCommentsFromXML = null;
if(ShowComments || AllowEdit) {
DataSet dsComments = ReadCommentsFromXML();
dvCommentsFromXML = dsComments.Tables[0].DefaultView;
}
// add rows with filenames
for(i=0; i<arFilesToShow.Count; i++) {
// Response.Write(arFilesToShow[i]);
DataRow dr = dtThumbs.NewRow();
dr[0] = arFilesToShow[i];
dtThumbs.Rows.Add(dr);
} // next file
// add existing comments
if((ShowComments || AllowEdit) && dvCommentsFromXML!=null) {
for(i = 0; i < dvCommentsFromXML.Count; i++) {
String sFilename=((String)dvCommentsFromXML[i][0]).Trim();
DataRow[] foundRows = dtThumbs.Select("Filename = '"+sFilename+"'");
if(foundRows.Length>0)
foundRows[0][1] = dvCommentsFromXML[i][1]; // copy comment
}
}
MyThumbList.DataSource = dtThumbs.DefaultView;
MyThumbList.DataBind();
} // end method
private void CreateNavBar(PlaceHolder plLinks)
{
Trace.Warn("CreateNavBar()");
CurPage = int.Parse(MyThumbList.Attributes["CurPage"]);
int totalPages = int.Parse(MyThumbList.Attributes["TotalPages"]);
if(totalPages == 1) return;
// --- i found a better solution with client script, see below
// LinkButton lbtPrev = new LinkButton();
// lbtPrev.Text="<< Prev"; lbtPrev.CommandName="Prev";
// lbtPrev.Command += new CommandEventHandler(LinkButton_Command);
// plLinks.Controls.Add(lbtPrev);
// put the path also into the page links to change link status
// (visited or not) when we change the virtual path
if(CurPage>1) {
// GoToPage client script updates hidden field with target page
// and then causes a postback
plLinks.Controls.Add(new LiteralControl(String.Format(
"<A href=\"javascript:GoToPage('{0}',{1});\"><< Prev</A> ",
VPath,CurPage-1 )));
}
for(int i=1; i<=totalPages; i++) {
String si = i.ToString();
plLinks.Controls.Add(new LiteralControl(" "));
if(i==CurPage) {
Label lblPage = new Label();
lblPage.Text = si; lblPage.Font.Bold = true;
plLinks.Controls.Add(lblPage);
}
else {
plLinks.Controls.Add(new LiteralControl(String.Format(
"<A href=\"javascript:GoToPage('{0}',{1});\">{2}</A>",
VPath,si,si)));
}
if(i%10==0)
plLinks.Controls.Add(new LiteralControl("<br/>"));
} // next i
if(CurPage<totalPages) {
plLinks.Controls.Add(new LiteralControl(String.Format(
" <A href=\"javascript:GoToPage('{0}',{1});\">Next >></A>",
VPath,CurPage+1)));
}
}
DataSet ReadCommentsFromXML() {
DataSet dsComments = new DataSet("ThumbnailDataset");
// read comments from XML file
try {
dsComments.ReadXml(_path +"\\ThumbComments.xml");
} catch(Exception exRead) { }
if(dsComments.Tables.Count==0)
dsComments.Tables.Add(CreateCommentsTable());
return dsComments;
}
DataTable CreateCommentsTable() {
DataTable dtThumbs = new DataTable("ThumbComment");
DataColumn dcPrimary = new DataColumn("Filename", typeof(string));
dtThumbs.Columns.Add(dcPrimary);
dtThumbs.Columns.Add(new DataColumn("Comment", typeof(string)));
dtThumbs.PrimaryKey = new DataColumn[] { dcPrimary };
dtThumbs.CaseSensitive = false;
return dtThumbs;
}
// test function - not used
void LinkButton_Command(Object sender, CommandEventArgs e)
{
Trace.Warn("You chose: " + e.CommandName + " Item " + e.CommandArgument);
}
String NumImagesDisplayed() {
String sNum=((ICollection)MyThumbList.DataSource).Count.ToString();
if(AllowPaging) sNum+= " of " + MyThumbList.Attributes["TotalFiles"];
sNum += " images";
if(AllowPaging) {
sNum += String.Format(" (Page {0} of {1})",
MyThumbList.Attributes["CurPage"],
MyThumbList.Attributes["TotalPages"]);
}
return sNum;
}
// construct url of thumbnail
String ThumbUrl(String sFile)
{
// if we use saved thumbnails, we must check if the file exists
// if not we must create it using the oGenerator object
if(_bSaveThumbnails) {
_oGenerator.SetParams(String.Format("{0}\\{1}",_path,sFile),
_width,_height,AllowStretch,Bevel,UseCOMobj);
String sNameToSave = _oGenerator.GetUniqueThumbName();
String sPathThumbFile=String.Format("{0}\\thumbnails\\{1}",
_path,sNameToSave);
if(!File.Exists(sPathThumbFile)) {
try {
Bitmap bmThumb = _oGenerator.ExtractThumbnail();
_oGenerator.SaveThumbnail(bmThumb,sPathThumbFile);
} catch (Exception exSave) { }
} // if not exists
return String.Format("{0}/thumbnails/{1}",_vpath,sNameToSave);
}
else { // create thumbnail in memory using the HTTP handler
StringBuilder thurl = new StringBuilder();
thurl.AppendFormat("{0}/ThumbJpeg.ashx?VFilePath={1}/{2}",
TemplateSourceDirectory,_vpath,sFile);
if(_width>0) thurl.AppendFormat("&Width={0}",_width);
if(_height>0) thurl.AppendFormat("&Height={0}",_height);
if(AllowStretch) thurl.Append("&AllowStretch=true");
if(Bevel) thurl.Append("&Bevel=true");
if(UseCOMobj) thurl.Append("&UseCOMobj=true");
if(Refresh) thurl.Append("&Refresh=true");
return thurl.ToString();
}
}
String AltString(String sFile)
{
FileInfo fi = new FileInfo(String.Format("{0}\\{1}",_path,sFile));
long FileSize = fi.Length;
return "Name: " + sFile + " Size: " + FileSize/1024 + " Kb";
}
</script>
<!-------------------- Controls content here ------------------------------------->
<ASP:DataList id="MyThumbList" RepeatDirection="Horizontal" RepeatColumns="4" CellSpacing="3" runat="server" EnableViewState="true" OnItemDataBound="Item_DataBound"
OnEditCommand="ThumbList_EditCommand" OnUpdateCommand="ThumbList_UpdateCommand"
OnCancelCommand="ThumbList_CancelCommand"
>
<ItemStyle font-size="8pt" horizontalalign="Center" borderwidth="1px" borderstyle="Solid" backcolor="White"></ItemStyle>
<FooterStyle font-size="8pt" horizontalalign="Center" backcolor="#FFFFC0"></FooterStyle>
<HeaderStyle font-size="11pt" font-bold="True" horizontalalign="Center"></HeaderStyle>
<SelectedItemStyle backcolor="#E0E0E0"></SelectedItemStyle>
<EditItemStyle borderwidth="1px" borderstyle="Groove"></EditItemStyle>
<ItemTemplate>
<a href="<%# String.Format("{0}/{1}",_vpath,
((DataRowView)Container.DataItem)["Filename"]) %>" >
<img border="0" src="<%# ThumbUrl((String)((DataRowView)Container.DataItem)["Filename"]) %>"
alt="<%# AltString((String)((DataRowView)Container.DataItem)["Filename"]) %>" /></a>
<%# _bShowFilenames?"<br/>"+((DataRowView)Container.DataItem)["Filename"]:"" %>
<%# ShowComments?"<br/>"+((DataRowView)Container.DataItem)["Comment"]:"" %>
<br/><asp:LinkButton id="button1" Visible='<%# AllowEdit ? true:false %>'
Text="Edit" CommandName="Edit" runat="server"/>
</ItemTemplate>
<EditItemTemplate>
<a href="<%# String.Format("{0}/{1}",_vpath,
((DataRowView)Container.DataItem)["Filename"]) %>" >
<img border="0" src="<%# ThumbUrl((String)((DataRowView)Container.DataItem)["Filename"]) %>"
alt="<%# AltString((String)((DataRowView)Container.DataItem)["Filename"]) %>" /></a>
<%# _bShowFilenames?"<br/>"+((DataRowView)Container.DataItem)["Filename"]:"" %>
<ASP:TextBox id="txtFilename" Visible='false'
Text='<%# ((DataRowView)Container.DataItem)["Filename"] %>' runat="server"/>
<br/><ASP:TextBox id="txtComment" Multiline='true' size='30' Rows='4' TextMode="MultiLine"
Text='<%# ((DataRowView)Container.DataItem)["Comment"] %>' runat="server"/>
<br/><asp:LinkButton id="button2" Text="Save" CommandName="Update" runat="server"/>
<asp:LinkButton id="button3" Text="Cancel" CommandName="Cancel" runat="server"/>
</EditItemTemplate>
<HeaderTemplate>
<%# HeaderTitle %>
</HeaderTemplate>
<FooterTemplate>
<%# NumImagesDisplayed() %>
<tr style="font-size: 8pt;" align="center">
<td colspan=<%# Columns %>
>
<p >
<asp:PlaceHolder id="plLinks" runat="server"></asp:PlaceHolder>
</p>
</td>
</tr>
</FooterTemplate>
</ASP:DataList>
<input id="hdnCurPage" type="hidden" runat="server" />
<input id="hdnPrevPath" type="hidden" runat="server" />