cz.fi.muni.xkremser.editor.client.view.other.PageNumberingManager.java Source code

Java tutorial

Introduction

Here is the source code for cz.fi.muni.xkremser.editor.client.view.other.PageNumberingManager.java

Source

/*
 * Metadata Editor
 * 
 * Metadata Editor - Rich internet application for editing metadata.
 * Copyright (C) 2011  Jiri Kremser (kremser@mzk.cz)
 * Moravian Library in Brno
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * 
 */

package cz.fi.muni.xkremser.editor.client.view.other;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.user.client.Timer;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.tile.TileGrid;

import cz.fi.muni.xkremser.editor.client.util.ClientUtils;
import cz.fi.muni.xkremser.editor.client.util.Constants;
import cz.fi.muni.xkremser.editor.client.view.window.ModalWindow;

/**
 * @author Jiri Kremser
 * @version 6.1.2012
 */
public final class PageNumberingManager {

    private final TileGrid tileGrid;

    public PageNumberingManager(TileGrid tileGrid) {
        this.tileGrid = tileGrid;
    }

    /** The attribute stringNumber */
    private static final String ATTR_STRING_NUMBER = "stringNumber";

    private void shiftToLeft(final int moveOver, final Record[] allRecords, final Record[] selectedRecords,
            final int selLength, final int lastNum) {
        Map<Integer, Record> bufferedRecords = new HashMap<Integer, Record>();
        int lastIndexOfSel = selLength - 1;
        int lastIndex = tileGrid.getRecordList().indexOf(selectedRecords[selLength - 1]);
        int lastNumber = lastNum;
        if (lastNum == Integer.MIN_VALUE) {
            lastNumber = allRecords.length;
            for (int i = 0; i <= lastIndex; i++) {
                String startingNumber = allRecords[i].getAttributeAsString(Constants.ATTR_NAME);
                int stringNumber = getPageNumberFromText(startingNumber);
                if (stringNumber == Integer.MIN_VALUE) {
                    stringNumber = ++lastNumber;
                } else {
                    lastNumber = stringNumber;
                }
                allRecords[i].setAttribute(ATTR_STRING_NUMBER, stringNumber);
            }
        }

        int lastIndexOfAll = tileGrid.getRecordList().indexOf(selectedRecords[selLength - 1]);

        for (int i = lastNumber; (i > 0 && (lastIndexOfSel >= 0)) || !(bufferedRecords.isEmpty()); i--) {

            if (lastIndexOfAll > -1 && allRecords[lastIndexOfAll].getAttributeAsInt(ATTR_STRING_NUMBER) == i) {
                if (!(lastIndexOfSel < 0) && allRecords[lastIndexOfAll].equals(selectedRecords[lastIndexOfSel])) {

                    int newPosition = 0;
                    if (i - (lastIndexOfSel - moveOver) <= 0) {
                        newPosition = lastIndexOfSel + 1;
                    } else {
                        newPosition = i + moveOver;
                    }
                    renumber(newPosition, allRecords[lastIndexOfAll], false);

                    bufferedRecords.put(newPosition, allRecords[lastIndexOfAll]);
                    allRecords[lastIndexOfAll] = null;
                    lastIndexOfSel--;
                }

                if (lastIndexOfAll != lastIndex && (i > -1)) {
                    if (bufferedRecords.containsKey(i + (lastIndex - lastIndexOfAll))) {
                        while (bufferedRecords.containsKey(i + (lastIndex - lastIndexOfAll))) {
                            allRecords[lastIndex] = bufferedRecords.remove(i + (lastIndex - lastIndexOfAll));
                            lastIndex--;
                        }

                    } else if (allRecords[lastIndexOfAll] != null && lastIndexOfAll > -1) {

                        renumber(bufferedRecords.size(), allRecords[lastIndexOfAll], true);

                        allRecords[lastIndex] = allRecords[lastIndexOfAll];
                        lastIndex--;
                    }
                } else if (lastIndexOfAll == lastIndex && allRecords[lastIndexOfAll] != null) {
                    lastIndex--;
                }
                lastIndexOfAll--;
            }
            while (bufferedRecords.containsKey(i + (lastIndex - lastIndexOfAll))) {
                allRecords[lastIndex] = bufferedRecords.remove(i + (lastIndex - lastIndexOfAll));
                lastIndex--;
            }
        }
    }

    private void shiftToRight(int moveOver, Record[] allRecords, Record[] selectedRecords, int selLength,
            int firstNum, int maxNum) {

        Map<Integer, Record> bufferedRecords = new HashMap<Integer, Record>();
        int firstIndex = tileGrid.getRecordList().indexOf(selectedRecords[0]);
        int lastIndexOfSel = 0;
        int lastIndexOfAll = firstIndex;
        int allLength = allRecords.length;
        int maxNumber = maxNum;
        int firstNumber = firstNum;
        if (firstNum == Integer.MIN_VALUE || maxNum == Integer.MIN_VALUE) {
            firstNumber = allLength;
            maxNumber = allLength;
            for (int i = allLength - 1; i >= firstIndex; i--) {
                String startingNumber = allRecords[i].getAttributeAsString(Constants.ATTR_NAME);
                int stringNumber = getPageNumberFromText(startingNumber);
                if (stringNumber == Integer.MIN_VALUE) {
                    stringNumber = --firstNumber;
                } else {
                    firstNumber = stringNumber;
                }
                if (maxNumber < firstNumber)
                    maxNumber = stringNumber;
                allRecords[i].setAttribute(ATTR_STRING_NUMBER, stringNumber);
            }
        }
        for (int i = firstNumber; (i <= maxNumber && (lastIndexOfSel < selLength))
                || !(bufferedRecords.isEmpty()); i++) {

            if (lastIndexOfAll < allLength
                    && allRecords[lastIndexOfAll].getAttributeAsInt(ATTR_STRING_NUMBER) == i) {
                if (lastIndexOfSel < selLength
                        && allRecords[lastIndexOfAll].equals(selectedRecords[lastIndexOfSel])) {

                    int newPosition = 0;
                    newPosition = i + moveOver;
                    renumber(newPosition, allRecords[lastIndexOfAll], false);
                    bufferedRecords.put(newPosition, allRecords[lastIndexOfAll]);
                    allRecords[lastIndexOfAll] = null;
                    lastIndexOfSel++;
                }

                if (lastIndexOfAll != firstIndex && (i <= maxNumber)) {
                    if (bufferedRecords.containsKey(i + (firstIndex - lastIndexOfAll))) {
                        while (bufferedRecords.containsKey(i + (firstIndex - lastIndexOfAll))) {
                            allRecords[firstIndex] = bufferedRecords.remove(i + (firstIndex - lastIndexOfAll));
                            firstIndex++;
                        }

                    } else if (allRecords[lastIndexOfAll] != null && lastIndexOfAll < allLength) {

                        renumber(-bufferedRecords.size(), allRecords[lastIndexOfAll], true);

                        allRecords[firstIndex] = allRecords[lastIndexOfAll];
                        firstIndex++;
                    }
                } else if (lastIndexOfAll == firstIndex && allRecords[lastIndexOfAll] != null) {
                    firstIndex++;
                }
                lastIndexOfAll++;
            }
            while (bufferedRecords.containsKey(i + (firstIndex - lastIndexOfAll))) {
                allRecords[firstIndex] = bufferedRecords.remove(i + (firstIndex - lastIndexOfAll));
                firstIndex++;
            }
        }
    }

    public void shift(final int n, final boolean isShiftTo, final Canvas canvas) {
        final ModalWindow mw = new ModalWindow(canvas);
        mw.setLoadingIcon("loadingAnimation.gif");
        mw.show(true);

        Timer timer = new Timer() {

            @Override
            public void run() {
                Record[] selectedRecords = tileGrid.getSelection();
                tileGrid.selectAllRecords();
                Record[] allRecords = tileGrid.getSelection();
                int selLength = selectedRecords.length;
                int maxNumber = Integer.MIN_VALUE;
                int firstNumber = Integer.MIN_VALUE;
                int lastNumber = Integer.MIN_VALUE;

                if (selectedRecords != null && selectedRecords.length > 0) {
                    int moveOver = n;

                    if (isShiftTo) {
                        maxNumber = allRecords.length;
                        firstNumber = 0;
                        lastNumber = maxNumber;
                        int number = 0;

                        for (int i = 0; i < allRecords.length; i++) {
                            String startingNumber = allRecords[i].getAttributeAsString(Constants.ATTR_NAME);
                            int stringNumber = getPageNumberFromText(startingNumber);
                            if (stringNumber == Integer.MIN_VALUE) {
                                stringNumber = ++number;
                            } else {
                                number = stringNumber;
                            }
                            if (allRecords[i].equals(selectedRecords[0]))
                                firstNumber = stringNumber;
                            if (allRecords[i].equals(selectedRecords[selLength - 1]))
                                lastNumber = stringNumber;
                            if (maxNumber < firstNumber)
                                maxNumber = firstNumber;
                            allRecords[i].setAttribute(ATTR_STRING_NUMBER, stringNumber);
                        }
                        if (n != firstNumber) {
                            moveOver = n - firstNumber;
                        } else {
                            moveOver = 0;
                        }
                    }

                    if (moveOver == 0) {
                        tileGrid.selectRecords(selectedRecords);
                        mw.hide();
                        return;
                    }

                    if (moveOver < 0) {
                        shiftToLeft(moveOver, allRecords, selectedRecords, selLength, lastNumber);
                    } else {
                        shiftToRight(moveOver, allRecords, selectedRecords, selLength, firstNumber, maxNumber);
                    }
                    tileGrid.removeSelectedData();
                    tileGrid.setData(allRecords);
                    tileGrid.selectRecords(selectedRecords);
                }
            }
        };
        timer.schedule(25);
        mw.hide();
    }

    private void renumber(int newNumber, Record record, boolean fromString) {
        String stringNumber = record.getAttributeAsString(Constants.ATTR_NAME);
        int number = getPageNumberFromText(stringNumber);

        if (number != Integer.MIN_VALUE) {
            StringBuffer sb = new StringBuffer("");
            if (stringNumber.contains("["))
                sb.append("[");
            sb.append(fromString ? (number + newNumber) : newNumber);
            if (stringNumber.contains("]"))
                sb.append("]");
            record.setAttribute(Constants.ATTR_NAME, sb.toString());
        }
    }

    public void toAbcN(final int n) {
        if (n > 26 || n < 2)
            throw new IllegalArgumentException("bad argument (allowed values are between 2 and 26)");
        final char[] alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
                'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
        Record[] data = tileGrid.getSelection();
        if (data != null && data.length > 0) {
            String startingNumber = data[0].getAttributeAsString(Constants.ATTR_NAME);
            int i = getPageNumberFromText(startingNumber);
            boolean isRoman = false;
            if (i == Integer.MIN_VALUE) {
                i = ClientUtils.romanToDecimal(data[0].getAttributeAsString(Constants.ATTR_NAME));
                if (!(isRoman = i > 0)) {
                    i = tileGrid.getRecordIndex(data[0]) + 1;
                }
            }
            int j = 0;
            for (Record rec : data) {
                String number = !isRoman ? String.valueOf(i + (j / n))
                        : ClientUtils.decimalToRoman((i + (j / n)), false);
                rec.setAttribute(Constants.ATTR_NAME, number + "" + alphabet[j % n]);
                j++;
            }
        }
    }

    public void foliation() {
        Record[] data = tileGrid.getSelection();
        if (data != null && data.length > 0) {
            String startingNumber = data[0].getAttributeAsString(Constants.ATTR_NAME);
            int i = getPageNumberFromText(startingNumber);
            if (i == Integer.MIN_VALUE) {
                i = tileGrid.getRecordIndex(data[0]) + 1;
            }
            int j = 0;
            for (Record rec : data) {
                rec.setAttribute(Constants.ATTR_NAME, (i + (j / 2)) + "" + (j % 2 == 0 ? 'r' : 'v'));
                j++;
            }
        }
    }

    public void toColumn() {
        List<Record> selection = Arrays.asList(tileGrid.getSelection());
        RecordList allRecords = tileGrid.getRecordList();
        String name = selection.get(0).getAttributeAsString(Constants.ATTR_NAME);
        int number = getPageNumberFromText(name);
        if (number < 0) {
            if (name.contains(Constants.TWO_PAGES_SEPARATOR)) {
                String[] splitedName = name.split("\\" + Constants.TWO_PAGES_SEPARATOR);
                if ((number = getPageNumberFromText(splitedName[0].replaceAll(" ", ""))) < 0)
                    number = allRecords.indexOf(selection.get(0)) + 1;
            } else {
                number = allRecords.indexOf(selection.get(0)) + 1;
            }
        }
        number--;

        for (int i = allRecords.indexOf(selection.get(0)); i < allRecords.getLength(); i++) {
            if (selection.contains(allRecords.get(i)) || allRecords.get(i).getAttributeAsString(Constants.ATTR_NAME)
                    .contains(Constants.TWO_PAGES_SEPARATOR)) {
                allRecords.get(i).setAttribute(Constants.ATTR_NAME,
                        ++number + Constants.TWO_PAGES_SEPARATOR + ++number);
            } else {
                allRecords.get(i).setAttribute(Constants.ATTR_NAME, ++number);
            }
        }
    }

    private int getPageNumberFromText(String text) {
        if (text != null && !"".equals(text)) {
            try {
                if (text.charAt(0) == '[') {
                    text = text.substring(1, text.lastIndexOf(']'));
                }
                while (!"".equals(text) && !Character.isDigit(text.charAt(text.length() - 1))) {
                    text = text.substring(0, text.length() - 1);
                }
                if (!"".equals(text)) {
                    return Integer.parseInt(text);
                }
            } catch (NumberFormatException nfe) {
                return Integer.MIN_VALUE;
            }
        }
        return Integer.MIN_VALUE;
    }

}