Subversion Repositories Filer-Free

Rev

Rev 63 | Blame | Compare with Previous | Last modification | View Log | RSS feed

// This file is part of the free Filer module for RISC OS.
// Copyright © 2007 Graham Shaw.
// Redistribution and modification are permitted under the terms of the
// GNU General Public License (version 2 or any later version).

#include <new>

#include "oslib/os.h"
#include "oslib/wimp.h"

#include "layout_method.h"
#include "filer_window.h"
#include "filer_application.h"
#include "main.h"

static wimp_MESSAGE_LIST(1) messages={0};

filer_application::filer_application():
        application("Filer",(wimp_message_list*)&messages),
        _auto_pos(0,0,0,0,1),
        _rename_window(0),
        _rename_icon(0),
        _rename_index(0)
{
        handle_mode_change();
}

void filer_application::handle_key_pressed(wimp_key& block)
{
        bool handled=false;
        if (_rename_window&&block.w==_rename_window->handle()&&
                block.i==_rename_icon)
        {
                // Keypress occurred within rename icon.
                if (block.c=='\r'||block.c=='\n')
                {
                        // Keypress was carriage return or newline.
                        _rename_window->rename(_rename_index,_rename_buffer);
                        cancel_rename();
                        handled=true;
                }
                else if (block.c==0x1b)
                {
                        // Keypress was escape.
                        cancel_rename();
                        handled=true;
                }
        }

        // If not handled above then pass on the keypress.
        if (!handled) application::handle_key_pressed(block);
}

void filer_application::handle_pollword_non_zero(int* pollword)
{
        *pollword=0;
        pathnames.refresh();
}

void filer_application::handle_user_message(wimp_event_no event,
        wimp_message& message)
{
        switch (message.action)
        {
        case message_FILER_OPEN_DIR:
                handle_filer_open_dir(
                        (filer_full_message_open_dir&)message);
                break;
        }
}

void filer_application::deregister_window(window& w)
{
        if (_rename_window==&w)
        {
                // Rename operation in progress within the window.
                // This must be cancelled, but there is no need to explicitly
                // delete the icon because the whole window is to be destroyed.
                _rename_window=0;
                _rename_icon=-1;
                _rename_index=directory::npos;
        }

        application::deregister_window(w);
}

void filer_application::handle_filer_open_dir(
        filer_full_message_open_dir& message)
{
        // Use auto-positioner to choose location for window.
        os_coord pos=_auto_pos();
        os_box box;
        box.x0=pos.x;
        box.y0=pos.y;
        box.x1=pos.x;
        box.y1=pos.y;

        // Open new filer window.
        new(std::nothrow) filer_window(
                this,message.dir_name,box,get_default_options());
}

void filer_application::handle_mode_change()
{
        // Get size of screen in pixels (less one).
        int xpixels;
        int ypixels;
        os_read_mode_variable(os_CURRENT_MODE,os_MODEVAR_XWIND_LIMIT,&xpixels);
        os_read_mode_variable(os_CURRENT_MODE,os_MODEVAR_YWIND_LIMIT,&ypixels);

        // Get eigenvalues.
        int xeig;
        int yeig;
        os_read_mode_variable(os_CURRENT_MODE,os_MODEVAR_XEIG_FACTOR,&xeig);
        os_read_mode_variable(os_CURRENT_MODE,os_MODEVAR_YEIG_FACTOR,&yeig);

        // Calculate size of screen in OS units.
        int xsize=(xpixels+1)<<xeig;
        int ysize=(ypixels+1)<<yeig;

        // Calculate number of steps.
        int step_size=128;
        int steps=xsize/(step_size*2);

        // Re-initialise automatic window positioner.
        _auto_pos=auto_pos(0,3*ysize/4,step_size,0,steps);
}

void filer_application::begin_rename(filer_window& w,
        directory::size_type index,os_coord pos)
{
        cancel_rename();
        _rename_index=index;
        _rename_icon=w.open_rename(index,pos,_rename_buffer);
        _rename_window=&w;
}

void filer_application::cancel_rename()
{
        if (_rename_window)
        {
                _rename_window->close_rename(_rename_icon,_rename_index);
                _rename_window=0;
                _rename_icon=-1;
                _rename_index=directory::npos;
        }
}

pathname_table::node* filer_application::register_pathname(filer_window& w)
{
        return pathnames.insert(&w);
}

void filer_application::deregister_pathname(pathname_table::node* n)
{
        pathnames.erase(n);
}