/** * */ package lampiro.screens; import java.util.Enumeration; import java.util.Vector; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; import it.yup.ui.UIButton; import it.yup.ui.UICanvas; import it.yup.ui.UIHLayout; import it.yup.ui.UIItem; import it.yup.ui.UILabel; import it.yup.ui.UILayout; import it.yup.ui.UIMenu; import it.yup.ui.UIPanel; import it.yup.ui.UIScreen; import it.yup.ui.UISeparator; import it.yup.ui.UIUtils; import it.yup.util.RMSIndex; import it.yup.util.ResourceIDs; import it.yup.util.ResourceManager; import it.yup.xml.BProcessor; import it.yup.xml.Element; import it.yup.xmpp.Config; /** * @author luca * */ public class AlbumScreen extends UIScreen { private static Config cfg = Config.getInstance(); private static String ALBUM = "album"; private static RMSIndex album = new RMSIndex(ALBUM);; private static Element albumEl; public static int getCount(int type) { synchronized (album) { String sType = (type == Config.imgType ? "img" : "snd"); Element child = albumEl.getChildByName(null, sType); if (child != null) return Integer.parseInt(child.getText()); return 0; } } private UIMenu actionMenu = new UIMenu(""); private static AlbumScreen _instance = null; static { synchronized (album) { loadAlbum(); } } private UIPanel albumPanel; static ResourceManager rm = ResourceManager.getManager("common", "en"); private UILabel cmd_exit; private UILabel detailLabel = new UILabel(rm .getString(ResourceIDs.STR_SEE_DETAILS)); private UILabel sendLabel = new UILabel(rm.getString(ResourceIDs.STR_SEND)); private UILabel deleteLabel = new UILabel(rm .getString(ResourceIDs.STR_DELETE)); private UIButton prevCmd = new UIButton(rm.getString(ResourceIDs.STR_PREV)); private UIButton nextCmd = new UIButton(rm.getString(ResourceIDs.STR_NEXT)); private Vector itemsToRemove = new Vector(); /* * To avoid heavy CPU loads not all the album file are loaded when opening the album screen * Some of them are loaded later when exploring the album; * maxLoadFile is the maximum number of file that are to be loaded at start. */ private int maxLoadFile = 3; private int offset = 0; private static Element[] children; private UIHLayout buttonLayout = null; private UISeparator dummySeparator = new UISeparator(0); /* * The resource for the contact that will be the default one to receive the selected * file */ private String fullJid = null; public boolean keyPressed(int key) { boolean keepFocus = false; boolean rolled = false; if (albumPanel.getSelectedIndex() >= 0 && albumPanel.getItems().elementAt( albumPanel.getSelectedIndex()) == this.buttonLayout) keepFocus = true; if (keepFocus == false) rolled = RosterScreen.makeRoll(key, this); if (rolled == false) return super.keyPressed(key); return true; } public void menuAction(UIMenu menu, UIItem cmd) { if (cmd == cmd_exit) { UICanvas.getInstance().close(this); _instance = null; } else if (cmd == deleteLabel) { itemAction(cmd); } else if (cmd == detailLabel || cmd == sendLabel) { itemAction(detailLabel); } } public void itemAction(UIItem c) { if (c == prevCmd) { offset -= maxLoadFile; if (offset < 0) { offset = (children.length - (children.length % maxLoadFile)); if (offset == children.length) offset -= 3; } synchronized (album) { album.open(); loadFiles(); album.close(); } this.buttonLayout.setSelectedItem(prevCmd); } else if (c == nextCmd) { offset += maxLoadFile; if (offset >= children.length) { offset = 0; } synchronized (album) { album.open(); loadFiles(); album.close(); } this.buttonLayout.setSelectedItem(nextCmd); } else if (c == deleteLabel) { UIHLayout selLayout = (UIHLayout) this.albumPanel.getSelectedItem(); String code = ((UILabel) selLayout.getItem(2)).getText(); AlbumScreen.deleteAlbum(code); // remove item and separator int index = albumPanel.getItems().indexOf(selLayout); albumPanel.removeItem(selLayout); albumPanel.removeItemAt(index); if (offset >= children.length && offset > 0) { offset -= this.maxLoadFile; } synchronized (album) { album.open(); loadFiles(); album.close(); } } else if (c == detailLabel || c == sendLabel || c instanceof UIHLayout) { UIHLayout selLayout = (UIHLayout) this.albumPanel.getSelectedItem(); String code = ((UILabel) selLayout.getItem(2)).getText(); album.open(); Element[] children = albumEl.getChildrenByName(null, "file"); for (int i = 0; i < children.length; i++) { Element ithChild = children[i]; Element idEl = ithChild.getChildByName(null, "id"); String fileId = idEl.getText(); if (fileId.equals(code)) { Element nameEl = ithChild.getChildByName(null, "name"); Element descEl = ithChild.getChildByName(null, "desc"); Element typeEl = ithChild.getChildByName(null, "type"); String fileName = nameEl.getText(); String fileDesc = descEl.getText(); byte[] fileData = album.load(fileId.getBytes()); int mmType = Integer.parseInt(typeEl.getText()); SendMMScreen mms = new SendMMScreen(fileData, fileName, null, fileDesc, mmType, fullJid); /* * reorganize here the bar with send / save related buttons */ // mms.cmd_layout.insert(new UILabel(""), 0, 33, // UILayout.CONSTRAINT_PERCENTUAL); // mms.cmd_layout.insert(mms.cmd_send, 1, 33, // UILayout.CONSTRAINT_PERCENTUAL); // mms.cmd_layout.insert(new UILabel(""), 2, 33, // UILayout.CONSTRAINT_PERCENTUAL); // int oldIndex = mms.mainPanel.removeItem(mms.cmd_layout); mms.cmd_layout = UIUtils.easyCenterLayout(mms.cmd_send, 90); mms.mainPanel.insertItemAt(mms.cmd_layout, oldIndex); mms.mainPanel.removeItem(mms.cmd_layout_send_save); UICanvas.getInstance().open(mms, true); break; } } album.close(); } } public static AlbumScreen getInstance() { if (_instance == null) { _instance = new AlbumScreen(); } return _instance; } /* * The album is opened and the contact passed in the constructor * will be the default one to receive the selected file */ public static AlbumScreen getInstance(String contactToSend) { AlbumScreen album = AlbumScreen.getInstance(); album.fullJid = contactToSend; return album; } /** * */ private AlbumScreen() { cmd_exit = new UILabel(rm.getString(ResourceIDs.STR_CLOSE) .toUpperCase()); setMenu(new UIMenu("")); UIMenu menu = getMenu(); menu.append(cmd_exit); this.setTitle(rm.getString(ResourceIDs.STR_MM_ALBUM)); setupScreen(); } private void setupScreen() { this.removeAll(); albumPanel = new UIPanel(true, false); albumPanel.setMaxHeight(-1); albumPanel.setFocusable(true); albumPanel.setModal(true); this.append(albumPanel); actionMenu.removeAll(); actionMenu.append(this.detailLabel); actionMenu.append(this.sendLabel); actionMenu.append(this.deleteLabel); buttonLayout = new UIHLayout(3); prevCmd.setAnchorPoint(Graphics.HCENTER); nextCmd.setAnchorPoint(Graphics.HCENTER); buttonLayout.setGroup(false); buttonLayout.insert(prevCmd, 0, 50, UILayout.CONSTRAINT_PERCENTUAL); buttonLayout.insert(dummySeparator, 1, 20, UILayout.CONSTRAINT_PIXELS); buttonLayout.insert(nextCmd, 2, 50, UILayout.CONSTRAINT_PERCENTUAL); synchronized (album) { album.open(); updateChildren(); loadFiles(); album.close(); } } private static void updateChildren() { Element[] children = albumEl.getChildrenByName(null, "file"); AlbumScreen.children = children; } private void loadFiles() { Enumeration en = itemsToRemove.elements(); while (en.hasMoreElements()) { UIItem object = (UIItem) en.nextElement(); this.albumPanel.removeItem(object); } itemsToRemove.removeAllElements(); albumPanel.removeItem(buttonLayout); for (int i = offset; i < Math .min(children.length, offset + maxLoadFile); i++) { Element ithChild = children[i]; Element idEl = ithChild.getChildByName(null, "id"); String fileId = idEl.getText(); UIHLayout ithLayout = new UIHLayout(3); ithLayout.setSubmenu(actionMenu); ithLayout.setFocusable(true); String fileName = ""; int mmType = 0; Element typeEl = ithChild.getChildByName(null, "type"); mmType = Integer.parseInt(typeEl.getText()); Element nameEl = ithChild.getChildByName(null, "name"); fileName = nameEl.getText(); Image resImg = null; int imgWidth = -1; int imgHeight = -1; byte[] fileData = album.load(fileId.getBytes()); // this happens when a file cannot be loaded // XXX: delete the file in album ? if (fileData == null) continue; if (mmType == Config.imgType) { Image convImage = null; convImage = Image.createImage(fileData, 0, fileData.length); imgWidth = convImage.getWidth(); imgHeight = convImage.getHeight(); resImg = UIUtils.imageResize(convImage, UICanvas.getInstance() .getWidth() / 2, -1); } else { resImg = UICanvas.getUIImage("/icons/mic.png"); } UILabel ithLabel = new UILabel(resImg); ithLayout.insert(ithLabel, 0, UICanvas.getInstance().getWidth() / 2, UILayout.CONSTRAINT_PIXELS); String fileString = fileName + " " + fileData.length / 1000 + "Kb"; if (mmType == Config.imgType) { fileString += " "; fileString += (imgWidth + "x" + imgHeight); } UILabel filenameLabel = new UILabel(fileString); filenameLabel.setAnchorPoint(Graphics.HCENTER); ithLayout.insert(filenameLabel, 1, 100, UILayout.CONSTRAINT_PERCENTUAL); filenameLabel.setWrappable(true, UICanvas.getInstance().getWidth() - resImg.getWidth() - 20); ithLayout.insert(new UILabel(fileId), 2, 0, UILayout.CONSTRAINT_PERCENTUAL); itemsToRemove.addElement(ithLayout); this.albumPanel.addItem(ithLayout); UISeparator sep = new UISeparator(2); sep.setFg_color(0x777777); this.albumPanel.addItem(sep); itemsToRemove.addElement(sep); } if (children.length > maxLoadFile) { albumPanel.addItem(buttonLayout); buttonLayout.setSelected(true); buttonLayout.setSelected(false); nextCmd.setSelected(false); prevCmd.setSelected(false); // if (offset > 0) { buttonLayout.insert(prevCmd, 0, 50, UILayout.CONSTRAINT_PERCENTUAL); buttonLayout.setSelectedItem(prevCmd); // } else // buttonLayout.insert(dummySeparator, 0, 50, // UILayout.CONSTRAINT_PERCENTUAL); // if (offset + maxLoadFile < children.length) { buttonLayout.insert(nextCmd, 2, 50, UILayout.CONSTRAINT_PERCENTUAL); buttonLayout.setSelectedItem(nextCmd); // } else // buttonLayout.insert(dummySeparator, 2, 50, // UILayout.CONSTRAINT_PERCENTUAL); } albumPanel.setSelectedIndex(-1); albumPanel.setFirstVisible(0); this.askRepaint(); } /* * This function add a new data to the multimedia album. Eventually it checks * if the number of elements in the album exceeds the maximum allocated size. * * @param fileData * the byte array that contain the data * @param fileName * the name of the file to save * @param fileData * the multimedia type of the file (Config.audioType or Config.imgType) */ public static void addAlbum(byte[] fileData, String fileName, String fileDescription, int mmType) { synchronized (album) { Element idChild = albumEl.getChildByName(null, "id"); int id = Integer.parseInt(idChild.getText()); album.open(); String idCode = (ALBUM + id); album.store(idCode.getBytes(), fileData); idChild.removeAllElements(); idChild.addText((id + 1) + ""); Element fileEL = albumEl.addElement(null, "file"); fileEL.addElementAndContent(null, "id", idCode); fileEL.addElementAndContent(null, "name", fileName); fileEL.addElementAndContent(null, "desc", fileDescription); fileEL.addElementAndContent(null, "type", mmType + ""); String sType = (mmType == Config.imgType ? "img" : "snd"); Element child = albumEl.getChildByName(null, sType); if (child != null) { int count = Integer.parseInt(child.getText()) + 1; child.removeAllElements(); child.addText(count + ""); } else { albumEl.addElement(null, sType).addText("1"); } saveAlbum(); album.close(); updateChildren(); } if (AlbumScreen._instance != null && UICanvas.getInstance().getScreenList().contains( AlbumScreen._instance)) { AlbumScreen._instance.setFreezed(true); AlbumScreen._instance.setupScreen(); AlbumScreen._instance.setFreezed(false); } } public static void deleteAlbum(String fileCode) { synchronized (album) { Element[] children = albumEl.getChildrenByName(null, "file"); for (int i = 0; i < children.length; i++) { Element ithChild = children[i]; if (ithChild.getChildByName(null, "id").getText().compareTo( fileCode) == 0) { albumEl.removeChild(ithChild); album.open(); album.delete(fileCode.getBytes()); saveAlbum(); album.close(); break; } } updateChildren(); } } private static void saveAlbum() { byte[] albumBytes = BProcessor.toBinary(albumEl); album.store(ALBUM.getBytes(), albumBytes); } private static void loadAlbum() { album.open(); byte[] albumBytes = album.load(ALBUM.getBytes()); if (albumBytes == null || albumBytes.length == 0) { // setup album and first id albumEl = new Element(ALBUM, ALBUM); albumEl.addElement(null, "id").addText("1"); saveAlbum(); } else albumEl = BProcessor.parse(albumBytes); album.close(); } }