Changeset 6319


Ignore:
Timestamp:
2003-12-19T14:47:38+13:00 (20 years ago)
Author:
jmt12
Message:

A new configuration setting - recursion depth, after which gli suspects a cyclic loop. FileQueue makes use of this setting, along with a method of finding folder depth, to make this judgement

Location:
trunk/gli
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/classes/xml/config.xml

    r6151 r6319  
    3838    <Argument name="general.locale">en_NZ</Argument>
    3939    <Argument name="general.home_page">http://www.greenstone.org/</Argument>
     40    <!-- How many folders deep should we recurse before suspecting a cyclic path? [40] -->
     41    <Argument name="general.max_folder_depth">40</Argument>
    4042    <Argument name="general.open_collection"></Argument>
    4143    <Argument name="general.proxy_host"></Argument>
  • trunk/gli/src/org/greenstone/gatherer/Configuration.java

    r6196 r6319  
    656656
    657657    /** Set the named property, from the specified configuration, using the given integer value. */
    658     /* private void setInt(String property, boolean general, int value) {
    659     setString(property, general, String.valueOf(value));
    660     } */
     658    public void setInt(String property, boolean general, int value) {
     659        setString(property, general, String.valueOf(value));
     660    }
    661661
    662662    /** Set the named property, from the specified configuration, using the given Locale value. */
  • trunk/gli/src/org/greenstone/gatherer/file/FileManager.java

    r5593 r6319  
    5454 */
    5555public class FileManager {
     56
     57    static public int countFolderDepth(File file) {
     58    int count = 0;
     59    while(file != null) {
     60        count++;
     61        file = file.getParentFile();
     62    }
     63    return count;
     64    }
     65
    5666    /** Not only the queue of files to be moved, but also the object that moves them. */
    5767    private FileQueue queue = null;
  • trunk/gli/src/org/greenstone/gatherer/file/FileQueue.java

    r6205 r6319  
    231231            if((job.type == FileJob.COPY || job.type == FileJob.MOVE) && !job.done) {
    232232            ///ystem.err.println("Copy/Move: " + origin_node);
    233             FileNode new_node = null;
    234             // Check if file exists, and action as necessary. Be aware the user can choose to cancel the action all together (where upon ready becomes false).
    235             if(target_file.exists()) {
    236                 // We've previously been told
    237                 if(yes_to_all) {
    238                 // Remove the old file and tree entry.
    239                 target_file.delete();
    240                 ready = true;
    241                 }
    242                 else {
    243                 ///atherer.println("Opps! This filename already exists. Give the user some options.");
    244                 Object[] options = { Dictionary.get("General.Yes"), Dictionary.get("FileActions.Yes_To_All"), Dictionary.get("General.No"), Dictionary.get("General.Cancel") };
    245                 int result = JOptionPane.showOptionDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Exists", target_file.getName()), Dictionary.get("General.Warning"), JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
    246                 switch(result) {
    247                 case 1: // Yes To All
    248                     yes_to_all = true;
    249                 case 0: // Yes
     233
     234            // The number one thing to check is whether we are in a cyclic loop. The easiest way is just to check how deep we are
     235            int max_folder_depth = Gatherer.config.getInt("general.max_folder_depth", Configuration.COLLECTION_SPECIFIC);
     236            boolean continue_over_depth = false;
     237            if(FileManager.countFolderDepth(source_file) > max_folder_depth) {
     238                Object[] options = { Dictionary.get("General.Yes"), Dictionary.get("General.No"), Dictionary.get("FileActions.Increase_Depth") };
     239                String args[] = { String.valueOf(max_folder_depth), source_file.getAbsolutePath() };
     240                int result = JOptionPane.showOptionDialog(Gatherer.g_man, Utility.formatHTMLWidth(Dictionary.get("FileActions.Possible_Cyclic_Path", args), 80), Dictionary.get("General.Warning"), JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
     241                args = null;
     242                options = null;
     243                switch(result) {
     244                case 0: // Yes
     245                continue_over_depth = true;
     246                break;
     247                case 2: // Continue and increase depth
     248                continue_over_depth = true;
     249                Gatherer.config.setInt("general.max_folder_depth", Configuration.COLLECTION_SPECIFIC, (max_folder_depth + 1));
     250                break;
     251                }
     252            }
     253            else {
     254                continue_over_depth = true;
     255            }
     256               
     257            if(continue_over_depth) {
     258                FileNode new_node = null;
     259                // Check if file exists, and action as necessary. Be aware the user can choose to cancel the action all together (where upon ready becomes false).
     260                if(target_file.exists()) {
     261                // We've previously been told
     262                if(yes_to_all) {
    250263                    // Remove the old file and tree entry.
    251                     if(destination_node != null) {
    252                     TreePath destination_path = new TreePath(destination_node.getPath());
    253                     FileNode temp_target_node = new FileNode(target_file, target_model, true);
    254                     TreePath target_path = destination_path.pathByAddingChild(temp_target_node);
    255                     SynchronizedTreeModelTools.removeNodeFromParent(target_model, target_model.getNode(target_path));
    256                     target_path = null;
    257                     temp_target_node = null;
    258                     destination_path = null;
    259                     }
    260264                    target_file.delete();
    261265                    ready = true;
    262                     break;
    263                 case 3: // No To All
    264                     cancel_action = true;
    265                 case 2: // No
    266                 default:
    267                     ready = false;
    268                     // Increment progress by size of potentially copied file
    269                     progress.addValue(origin_node.getFile().length());
    270                 }
    271                 }
    272             }
    273             // We proceed with the copy/move if the ready flag is still set. If it is that means there is no longer any existing file of the same name.
    274             if(ready) {
    275                 // update status area
    276                 String args[] = new String[1];
    277                 args[0] = "" + (queue.size() + 1) + "";
    278                 if(job.type == FileJob.COPY) {
    279                 args[0] = Utility.formatPath("FileActions.Copying", source_file.getAbsolutePath(), file_status.getSize().width);
    280                 file_status.setText(Dictionary.get("FileActions.Copying", args));
    281                 }
    282                 else {
    283                 args[0] = Utility.formatPath("FileActions.Moving", source_file.getAbsolutePath(), file_status.getSize().width);
    284                 file_status.setText(Dictionary.get("FileActions.Moving", args));
    285                 }
    286                 args = null;
    287 
    288                 // If source is a file
    289                 if(source_file.isFile()) {
    290                 // copy the file. If anything goes wrong the copy file should throw the appropriate exception. No matter what exception is thrown (bar an IOException) we display some message, perhaps take some action, then cancel the remainder of the pending file jobs. No point in being told your out of hard drive space for each one of six thousand files eh?
    291                 try {
    292                     copyFile(source_file, target_file, progress);
    293                 }
    294                 // If we can't find the source file, then the most likely reason is that the file system has changed since the last time it was mapped. Warn the user that the requested file can't be found, then force a refresh of the source folder involved.
    295                 catch(FileNotFoundException fnf_exception) {
    296                     Gatherer.printStackTrace(fnf_exception);
     266                }
     267                else {
     268                    ///atherer.println("Opps! This filename already exists. Give the user some options.");
     269                    Object[] options = { Dictionary.get("General.Yes"), Dictionary.get("FileActions.Yes_To_All"), Dictionary.get("General.No"), Dictionary.get("General.Cancel") };
     270                    int result = JOptionPane.showOptionDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Exists", target_file.getName()), Dictionary.get("General.Warning"), JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
     271                    switch(result) {
     272                    case 1: // Yes To All
     273                    yes_to_all = true;
     274                    case 0: // Yes
     275                    // Remove the old file and tree entry.
     276                    if(destination_node != null) {
     277                        TreePath destination_path = new TreePath(destination_node.getPath());
     278                        FileNode temp_target_node = new FileNode(target_file, target_model, true);
     279                        TreePath target_path = destination_path.pathByAddingChild(temp_target_node);
     280                        SynchronizedTreeModelTools.removeNodeFromParent(target_model, target_model.getNode(target_path));
     281                        target_path = null;
     282                        temp_target_node = null;
     283                        destination_path = null;
     284                    }
     285                    target_file.delete();
     286                    ready = true;
     287                    break;
     288                    case 3: // No To All
     289                    cancel_action = true;
     290                    case 2: // No
     291                    default:
     292                    ready = false;
     293                    // Increment progress by size of potentially copied file
     294                    progress.addValue(origin_node.getFile().length());
     295                    }
     296                }
     297                }
     298                // We proceed with the copy/move if the ready flag is still set. If it is that means there is no longer any existing file of the same name.
     299                if(ready) {
     300                // update status area
     301                String args[] = new String[1];
     302                args[0] = "" + (queue.size() + 1) + "";
     303                if(job.type == FileJob.COPY) {
     304                    args[0] = Utility.formatPath("FileActions.Copying", source_file.getAbsolutePath(), file_status.getSize().width);
     305                    file_status.setText(Dictionary.get("FileActions.Copying", args));
     306                }
     307                else {
     308                    args[0] = Utility.formatPath("FileActions.Moving", source_file.getAbsolutePath(), file_status.getSize().width);
     309                    file_status.setText(Dictionary.get("FileActions.Moving", args));
     310                }
     311                args = null;
     312               
     313                // If source is a file
     314                if(source_file.isFile()) {
     315                    // copy the file. If anything goes wrong the copy file should throw the appropriate exception. No matter what exception is thrown (bar an IOException) we display some message, perhaps take some action, then cancel the remainder of the pending file jobs. No point in being told your out of hard drive space for each one of six thousand files eh?
     316                    try {
     317                    copyFile(source_file, target_file, progress);
     318                    }
     319                    // If we can't find the source file, then the most likely reason is that the file system has changed since the last time it was mapped. Warn the user that the requested file can't be found, then force a refresh of the source folder involved.
     320                    catch(FileNotFoundException fnf_exception) {
     321                    Gatherer.printStackTrace(fnf_exception);
     322                    cancel_action = true;
     323                    // Show warning.
     324                    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Not_Found_Message", source_file.getName()), Dictionary.get("FileActions.File_Not_Found_Title"), JOptionPane.ERROR_MESSAGE);
     325                    // Force refresh of source folder.
     326                    source_model.refresh(new TreePath(((FileNode)origin_node.getParent()).getPath()));
     327                    }
     328                    catch(FileAlreadyExistsException fae_exception) {
     329                    Gatherer.printStackTrace(fae_exception);
     330                    cancel_action = true;
     331                    // Show warning.
     332                    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Already_Exists_Message", target_file.getName()), Dictionary.get("FileActions.File_Already_Exists_Title"), JOptionPane.ERROR_MESSAGE);
     333                    // Nothing else can be done by the Gatherer.
     334                    }
     335                    catch(InsufficientSpaceException is_exception) {
     336                    Gatherer.printStackTrace(is_exception);
     337                    cancel_action = true;
     338                    // Show warning. The message body of the expection explains how much more space is required for this file copy.
     339                    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Insufficient_Space_Message", is_exception.getMessage()), Dictionary.get("FileActions.Insufficient_Space_Title"), JOptionPane.ERROR_MESSAGE);
     340                    // Nothing else can be done by the Gatherer. In fact if we are really out of space I'm not even sure we can quit safely.
     341                    }
     342                    catch(UnknownFileErrorException ufe_exception) {
     343                    Gatherer.printStackTrace(ufe_exception);
     344                    cancel_action = true;
     345                    // Show warning
     346                    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Unknown_File_Error_Message"), Dictionary.get("FileActions.Unknown_File_Error_Title"), JOptionPane.ERROR_MESSAGE);
     347                    // Nothing else we can do.
     348                    }
     349                    catch(WriteNotPermittedException wnp_exception) {
     350                    Gatherer.printStackTrace(wnp_exception);
     351                    cancel_action = true;
     352                    // Show warning
     353                    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Write_Not_Permitted_Message", target_file.getAbsolutePath()), Dictionary.get("FileActions.Write_Not_Permitted_Title"), JOptionPane.ERROR_MESSAGE);
     354                    // Nothing else we can do.
     355                    }
     356                    catch(IOException exception) {
     357                    // Can't really do much about this.
     358                    Gatherer.printStackTrace(exception);
     359                    }
     360                 // If not cancelled
     361                    if(!cancel_action) {
     362                    // Step one is to create a dummy FileNode. Its important it has the correct structure so getPath works.
     363                    FileNode new_record = new FileNode(target_file);
     364                    SynchronizedTreeModelTools.insertNodeInto(target_model, destination_node, new_record);
     365                    new_node = new_record;
     366                   
     367                    // create undo job
     368                    if(job.undoable) {
     369                        job.undoable = false;
     370                        if(job.type == FileJob.COPY) {
     371                        // A copy is undone with a delete, so it doesn't really matter where the file originally came from (we're not moving it back there, but into the recycle bin). You may also notice we don't make use of the target parent record. This is because no undo action needs this information, and even if it did it could simply ask for records parent!
     372                        Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_COPY, null, null, job.target, new_record, job.undo);
     373                        }
     374                        else {
     375                        // Movements however do need a source and source parent so the file can be moved back to the correct place.
     376                        Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_MOVE, job.source, (FileNode)origin_node.getParent(), job.target, new_record, job.undo);
     377                        }
     378                    }
     379                    new_record = null;
     380                    }
     381                }
     382                // Else
     383                else if(source_file.isDirectory()) {
     384                    // create new record
     385                    FileNode directory_record = new FileNode(target_file);
     386                    ///ystem.err.println("Directory record = " + directory_record + " (" + target_file.getAbsolutePath() + ")");
     387                    SynchronizedTreeModelTools.insertNodeInto(target_model, destination_node, directory_record);
     388                    // Why is this not happening eh?
     389                    directory_record.setParent(destination_node);
     390                    if(!target_file.exists()) {
     391                    // make the directory
     392                    target_file.mkdirs();
     393                    new_node = directory_record;
     394                    // create undo job
     395                    if(job.undoable) {
     396                        job.undoable = false;
     397                        if(job.type == FileJob.COPY) {
     398                        // A copy is undone with a delete, so it doesn't really matter where the file originally came from (we're not moving it back there, but into the recycle bin). You may also notice we don't make use of the target parent record. This is because no undo action needs this information, and even if it did it could simply ask for records parent!
     399                        Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_COPY, null, null, job.target, directory_record, job.undo);
     400                        }
     401                        else {
     402                        // Movements however do need a source and source parent so the file can be moved back to the correct place.
     403                        Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_MOVE, job.source, (FileNode)origin_node.getParent(), job.target, directory_record, job.undo);
     404                        }
     405                    }
     406                    }
     407                    // Else inform the users that a directory already exists and files will be copied into it
     408                    //else {
     409                    //    JOptionPane.showMessageDialog(null, Dictionary.get("FileActions.Directory_Exists", target_file.toString()), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
     410                    //}
     411                    // Queue non-filtered child files for copying. If this directory already existed, the child records will have to generate the undo jobs, as we don't want to entirely delete this directory if it already existed.
     412                    FileNode child_record = null;
     413                    // In order to have a sane copy proceedure (rather than always copying last file first as it used to) we always add the child node at the position the parent was removed from. Consider the file job 'a' at the end of the queue which generates three new jobs 'b', 'c' and 'd'. The resulting flow should look like this.
     414                    // -- Starting queue                   ...[a]
     415                    // remove(position) = 'a'              ...
     416                    // add(position, 'b')                  ...[b]
     417                    // add(position, 'c')                  ...[c][b]
     418                    // add(position, 'd')                  ...[d][c][b]
     419                    // Next loop
     420                    // remove(position) = 'b'              ...[d][c]
     421                    for(int i = 0; i < origin_node.getChildCount(); i++) {
     422                    child_record = (FileNode) origin_node.getChildAt(i);
     423                    addJob(job.ID(), job.source, child_record, job.target, directory_record, job.type, job.undo, false, false, position);
     424                    }
     425                    child_record = null;
     426                    directory_record = null;
     427                }
     428                // The file wasn't found!
     429                else {
    297430                    cancel_action = true;
    298431                    // Show warning.
    299432                    JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Not_Found_Message", source_file.getName()), Dictionary.get("FileActions.File_Not_Found_Title"), JOptionPane.ERROR_MESSAGE);
    300                     // Force refresh of source folder.
     433                // Force refresh of source folder.
    301434                    source_model.refresh(new TreePath(((FileNode)origin_node.getParent()).getPath()));
    302435                }
    303                 catch(FileAlreadyExistsException fae_exception) {
    304                     Gatherer.printStackTrace(fae_exception);
    305                     cancel_action = true;
    306                     // Show warning.
    307                     JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Already_Exists_Message", target_file.getName()), Dictionary.get("FileActions.File_Already_Exists_Title"), JOptionPane.ERROR_MESSAGE);
    308                     // Nothing else can be done by the Gatherer.
    309                 }
    310                 catch(InsufficientSpaceException is_exception) {
    311                     Gatherer.printStackTrace(is_exception);
    312                     cancel_action = true;
    313                     // Show warning. The message body of the expection explains how much more space is required for this file copy.
    314                     JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Insufficient_Space_Message", is_exception.getMessage()), Dictionary.get("FileActions.Insufficient_Space_Title"), JOptionPane.ERROR_MESSAGE);
    315                     // Nothing else can be done by the Gatherer. In fact if we are really out of space I'm not even sure we can quit safely.
    316                 }
    317                 catch(UnknownFileErrorException ufe_exception) {
    318                     Gatherer.printStackTrace(ufe_exception);
    319                     cancel_action = true;
    320                     // Show warning
    321                     JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Unknown_File_Error_Message"), Dictionary.get("FileActions.Unknown_File_Error_Title"), JOptionPane.ERROR_MESSAGE);
    322                     // Nothing else we can do.
    323                 }
    324                 catch(WriteNotPermittedException wnp_exception) {
    325                     Gatherer.printStackTrace(wnp_exception);
    326                     cancel_action = true;
    327                     // Show warning
    328                     JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Write_Not_Permitted_Message", target_file.getAbsolutePath()), Dictionary.get("FileActions.Write_Not_Permitted_Title"), JOptionPane.ERROR_MESSAGE);
    329                     // Nothing else we can do.
    330                 }
    331                 catch(IOException exception) {
    332                     // Can't really do much about this.
    333                     Gatherer.printStackTrace(exception);
    334                 }
    335                 // If not cancelled
    336                 if(!cancel_action) {
    337                     // Step one is to create a dummy FileNode. Its important it has the correct structure so getPath works.
    338                     FileNode new_record = new FileNode(target_file);
    339                     SynchronizedTreeModelTools.insertNodeInto(target_model, destination_node, new_record);
    340                     new_node = new_record;
    341 
    342                     // create undo job
    343                     if(job.undoable) {
    344                     job.undoable = false;
    345                     if(job.type == FileJob.COPY) {
    346                         // A copy is undone with a delete, so it doesn't really matter where the file originally came from (we're not moving it back there, but into the recycle bin). You may also notice we don't make use of the target parent record. This is because no undo action needs this information, and even if it did it could simply ask for records parent!
    347                         Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_COPY, null, null, job.target, new_record, job.undo);
    348                     }
    349                     else {
    350                         // Movements however do need a source and source parent so the file can be moved back to the correct place.
    351                         Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_MOVE, job.source, (FileNode)origin_node.getParent(), job.target, new_record, job.undo);
    352                     }
    353                     }
    354                     new_record = null;
    355                 }
    356                 }
    357                 // Else
    358                 else if(source_file.isDirectory()) {
    359                 // create new record
    360                 FileNode directory_record = new FileNode(target_file);
    361                 ///ystem.err.println("Directory record = " + directory_record + " (" + target_file.getAbsolutePath() + ")");
    362                 SynchronizedTreeModelTools.insertNodeInto(target_model, destination_node, directory_record);
    363                 // Why is this not happening eh?
    364                 directory_record.setParent(destination_node);
    365                 if(!target_file.exists()) {
    366                     // make the directory
    367                     target_file.mkdirs();
    368                     new_node = directory_record;
    369                     // create undo job
    370                     if(job.undoable) {
    371                     job.undoable = false;
    372                     if(job.type == FileJob.COPY) {
    373                         // A copy is undone with a delete, so it doesn't really matter where the file originally came from (we're not moving it back there, but into the recycle bin). You may also notice we don't make use of the target parent record. This is because no undo action needs this information, and even if it did it could simply ask for records parent!
    374                         Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_COPY, null, null, job.target, directory_record, job.undo);
    375                     }
    376                     else {
    377                         // Movements however do need a source and source parent so the file can be moved back to the correct place.
    378                         Gatherer.c_man.undo.addUndo(job.ID(), UndoManager.FILE_MOVE, job.source, (FileNode)origin_node.getParent(), job.target, directory_record, job.undo);
    379                     }
    380                     }
    381                 }
    382                 // Else inform the users that a directory already exists and files will be copied into it
    383                 //else {
    384                 //    JOptionPane.showMessageDialog(null, Dictionary.get("FileActions.Directory_Exists", target_file.toString()), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
    385                 //}
    386                 // Queue non-filtered child files for copying. If this directory already existed, the child records will have to generate the undo jobs, as we don't want to entirely delete this directory if it already existed.
    387                 FileNode child_record = null;
    388                 // In order to have a sane copy proceedure (rather than always copying last file first as it used to) we always add the child node at the position the parent was removed from. Consider the file job 'a' at the end of the queue which generates three new jobs 'b', 'c' and 'd'. The resulting flow should look like this.
    389                 // -- Starting queue                   ...[a]
    390                 // remove(position) = 'a'              ...
    391                 // add(position, 'b')                  ...[b]
    392                 // add(position, 'c')                  ...[c][b]
    393                 // add(position, 'd')                  ...[d][c][b]
    394                 // Next loop
    395                 // remove(position) = 'b'              ...[d][c]
    396                 for(int i = 0; i < origin_node.getChildCount(); i++) {
    397                     child_record = (FileNode) origin_node.getChildAt(i);
    398                     addJob(job.ID(), job.source, child_record, job.target, directory_record, job.type, job.undo, false, false, position);
    399                 }
    400                 child_record = null;
    401                 directory_record = null;
    402                 }
    403                 // The file wasn't found!
    404                 else {
    405                 cancel_action = true;
    406                 // Show warning.
    407                 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Not_Found_Message", source_file.getName()), Dictionary.get("FileActions.File_Not_Found_Title"), JOptionPane.ERROR_MESSAGE);
    408                 // Force refresh of source folder.
    409                 source_model.refresh(new TreePath(((FileNode)origin_node.getParent()).getPath()));
    410                 }
    411 
    412                 // We can't have been cancelled, and we must have created a new FileNode during the above phase, before we can handle metadata.
    413                 if(!cancel_action && new_node != null) {
     436               
     437                // We can't have been cancelled, and we must have created a new FileNode during the above phase, before we can handle metadata.
     438                if(!cancel_action && new_node != null) {
    414439                /* Time to handle any existing metadata. */
    415440                // If the directory came from inside our collection...
    416                 if (job.source.toString().equals("Collection")) {
    417                     ///ystem.err.println("Move within collection...");
    418                     GDMManager gdm = Gatherer.c_man.getCollection().gdm;
    419                     // we just retrieve the metadata attached to the origin node...
    420                     ArrayList existing_metadata = gdm.getMetadataOnly(source_file);
    421                     ///atherer.println("Existing metadata for " + origin_node + ": " + gdm.toString(existing_metadata));
    422                     // then assign this remainder to the new folder.
    423                     ///ystem.err.println("New metadata: " + gdm.toString(existing_metadata));
    424                     gdm.addMetadata(new_node, existing_metadata);
    425                     existing_metadata = null;
    426                     gdm = null;
    427                 }
     441                    if (job.source.toString().equals("Collection")) {
     442                    ///ystem.err.println("Move within collection...");
     443                    GDMManager gdm = Gatherer.c_man.getCollection().gdm;
     444                    // we just retrieve the metadata attached to the origin node...
     445                    ArrayList existing_metadata = gdm.getMetadataOnly(source_file);
     446                    ///atherer.println("Existing metadata for " + origin_node + ": " + gdm.toString(existing_metadata));
     447                    // then assign this remainder to the new folder.
     448                    ///ystem.err.println("New metadata: " + gdm.toString(existing_metadata));
     449                    gdm.addMetadata(new_node, existing_metadata);
     450                    existing_metadata = null;
     451                    gdm = null;
     452                    }
    428453                // If it came from the recycle bin retrieve the metadata from there, once again remembering to account for inherited metadata
    429                 else if (job.source.toString().equals("Undo")) {
    430                     GDMManager gdm = Gatherer.c_man.getCollection().gdm;
    431                     // Retrieve metadata from the recycle bin
    432                     ArrayList existing_metadata = Gatherer.c_man.undo.getMetadata(source_file);
    433                     // then assign this remainder to the new folder.
    434                     gdm.addMetadata(new_node, existing_metadata);
    435                     existing_metadata = null;
    436                     gdm = null;
    437                 }
     454                    else if (job.source.toString().equals("Undo")) {
     455                    GDMManager gdm = Gatherer.c_man.getCollection().gdm;
     456                    // Retrieve metadata from the recycle bin
     457                    ArrayList existing_metadata = Gatherer.c_man.undo.getMetadata(source_file);
     458                    // then assign this remainder to the new folder.
     459                    gdm.addMetadata(new_node, existing_metadata);
     460                    existing_metadata = null;
     461                    gdm = null;
     462                    }
    438463                // Otherwise if it came from the workspace use the MSMs parsers to search for folder level metadata (such as metadata.xml or marc records).
    439                 else if (job.source.toString().equals("Workspace")) {
    440                     cancel_action = !Gatherer.c_man.getCollection().msm.searchForMetadata(new_node, origin_node, job.folder_level);
    441                 }
    442                 }
    443                 new_node = null;
    444 
     464                    else if (job.source.toString().equals("Workspace")) {
     465                    cancel_action = !Gatherer.c_man.getCollection().msm.searchForMetadata(new_node, origin_node, job.folder_level);
     466                    }
     467                }
     468                new_node = null;
     469                }
    445470            }
    446471            }
  • trunk/gli/src/org/greenstone/gatherer/gui/Preferences.java

    r6051 r6319  
     1/**
     2 *#########################################################################
     3 *
     4 * A component of the Gatherer application, part of the Greenstone digital
     5 * library suite from the New Zealand Digital Library Project at the
     6 * University of Waikato, New Zealand.
     7 *
     8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
     9 *
     10 * Copyright (C) 1999 New Zealand Digital Library Project
     11 *
     12 * This program is free software; you can redistribute it and/or modify
     13 * it under the terms of the GNU General Public License as published by
     14 * the Free Software Foundation; either version 2 of the License, or
     15 * (at your option) any later version.
     16 *
     17 * This program is distributed in the hope that it will be useful,
     18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20 * GNU General Public License for more details.
     21 *
     22 * You should have received a copy of the GNU General Public License
     23 * along with this program; if not, write to the Free Software
     24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     25 *########################################################################
     26 */
    127package org.greenstone.gatherer.gui;
    228
     
    1440import org.greenstone.gatherer.checklist.Entry;
    1541import org.greenstone.gatherer.gui.EmailField;
     42import org.greenstone.gatherer.gui.GLIButton;
    1643import org.greenstone.gatherer.gui.ModalDialog;
    1744import org.greenstone.gatherer.gui.SimpleMenuBar;
     
    4774    private JLabel proxy_host_label;
    4875    private JLabel proxy_port_label;
     76    private JLabel recursion_depth_label;
    4977    private JLabel title_label;
    5078    private JTabbedPane tab_pane;
     
    5280    private JTextField proxy_host_field;
    5381    private JSpinner proxy_port_field;
     82    private JSpinner recursion_depth_spinner;
    5483    private Preferences self;
    5584
     
    78107
    79108    JPanel button_pane = new JPanel();
    80     ok_button = new JButton();
     109    ok_button = new GLIButton();
     110    ok_button.setMnemonic(KeyEvent.VK_O);
    81111    Dictionary.registerBoth(ok_button, "General.OK", "General.OK_Tooltip");
    82     apply_button = new JButton();
     112    apply_button = new GLIButton();
     113    apply_button.setMnemonic(KeyEvent.VK_A);
    83114    Dictionary.registerBoth(apply_button, "General.Apply", "General.Apply_Tooltip");
    84     cancel_button = new JButton();
     115    cancel_button = new GLIButton();
     116    cancel_button.setMnemonic(KeyEvent.VK_C);
    85117    Dictionary.registerBoth(cancel_button, "General.Cancel", "General.Cancel_Tooltip");
    86118
     
    263295    Dictionary.registerTooltip(language_combobox, "Preferences.General.Interface_Language_Tooltip");
    264296
     297    // Recursion
     298    JPanel recursion_depth_pane = new JPanel();
     299    recursion_depth_label = new JLabel();
     300    recursion_depth_label.setPreferredSize(LABEL_SIZE);
     301    Dictionary.registerText(recursion_depth_label, "Preferences.General.Recursion_Depth");
     302    recursion_depth_spinner = new JSpinner(new SpinnerNumberModel(Gatherer.config.getInt("general.max_folder_depth", Configuration.COLLECTION_SPECIFIC), 0, Integer.MAX_VALUE, 1));
     303    Dictionary.registerTooltip(recursion_depth_spinner, "Preferences.General.Recursion_Depth_Tooltip");
     304
    265305    // Connect
    266306    language_combobox.addActionListener(new LanguageComboboxListener());
     
    275315    language_pane.add(language_combobox, BorderLayout.CENTER);
    276316
     317    recursion_depth_pane.setLayout(new BorderLayout());
     318    recursion_depth_pane.add(recursion_depth_label, BorderLayout.WEST);
     319    recursion_depth_pane.add(recursion_depth_spinner, BorderLayout.CENTER);
     320
    277321    general_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    278322    general_pane.setLayout(new GridLayout(5,1,0,5));
    279323    general_pane.add(email_pane);
    280324    general_pane.add(language_pane);
     325    general_pane.add(recursion_depth_pane);
    281326    general_pane.add(view_extracted_metadata_checkbox);
    282327    general_pane.add(show_file_size_checkbox);
     
    456501
    457502        Gatherer.config.setLocale("general.locale", Configuration.GENERAL_SETTING, ((DictionaryEntry)language_combobox.getSelectedItem()).getLocale());
     503
     504        Gatherer.config.setInt("general.max_folder_depth", Configuration.COLLECTION_SPECIFIC, ((Integer)recursion_depth_spinner.getValue()).intValue());
    458505
    459506        // Warning preferences
Note: See TracChangeset for help on using the changeset viewer.