macro_file BUBBLES;

/* ******************************************************************************
                        MULTI-EDIT MACRO FILE

Name:   BUBBLES

Description:  This macro file contains move block macros.

BUBBLEUP - Move current line or selected block one line up CTRL+ALT+SHIFT+UP K_CtrlAltShftUp
BUBBLELINEUP - Move current line one line up
BUBBLEBLOCKUP - Move selected block one line up
BUBBLEDOWN - Move currrent line or selected block one line down CTRL+ALT+SHIFT+DOWN K_CtrlAltShftDown
BUBBLELINEDOWN - Move current line one line down
BUBBLELEFT - Move selected block one char to the left CTRL+ALT+SHIFT+LEFT K_CtrlAltShftLeft
BUBBLEBLOCKLEFT - Move selected block one char to the left
BUBBLERIGHT - Move selected block one char to the right CTRL+ALT+SHIFT+RIGHT K_CtrlAltShftRight
BUBBLEBLOCKRIGHT - Move selected block one char to the right
INSTALLBUBBLEKEYS - Add the macros to up/right/down/left keys
GETHEXKEYCODE - Helper macro to get the key codes for the up/right/down/left keys

10-Feb-2007: tested on MEW 2006
Make sure you have persistent blocks on. Then you can move single line's
or blocks through your text file. Wrote this for ME6, tested it on MEW2006
and it is still working

3-Nov-2009: Tested on MEW 9.10
Added a force persistent_blocks on. If the persistent blocks flag is not set, the macro
wil set it to true, when the macro finishes, it will restore the original setting.
Added a macro to set the needed keys to call the macro's on a selected block/line. In MEW9.10 you
can call that macro from the Startup2.cfg file. In older version from MEW you can call that macro
from the startup.s macro file.

Please add the next four lines to the Startup2.cfg file.
;
; Configure the keys needed for the Bubbles macro file
;
RunMac Bubbles^InstallBubbleKeys


ToDo/Whishes: Keep / Restore position with Mark_Pos and Goto_Mark
              Cleanup code
              Bubbles macros could be enhanced with a check if the
              indent/unindent macro call moves the text beyound the visible area.

                   (C) Copyright 1997 by Lars Van Jeurissen
****************************************************************************** */

#include Win32.sh
#include MeLib.sh
#include MeUtil.sh
#include MeTools.sh
#include Bubbles.sh

#ifdef _Debug_
  #include MsgLog.sh
#endif


// BubbleUp :  move cursor line up
macro BubbleUp {
  int temp_refresh           = refresh;
  int temp_persistent_blocks = persistent_blocks;

  refresh           = false;
  persistent_blocks = 1;
  push_undo;
  if ( block_stat ) {
    rm( "BUBBLES^BubbleBlockUp" );
  }
  else {
    rm( "BUBBLES^BubbleLineUp" );
  }
  pop_undo;
  persistent_blocks = temp_persistent_blocks;
  refresh           = temp_refresh;
}

macro BubbleLineUp {
  if ( c_line > 1 ) {
    str a[ 2048 ] = get_line;
    up;
    str b[ 2048 ] = get_line;
    put_line( a );
    down;
    put_line( b );
    up;
  }
}
// Written by: Lars Jeurissen
// 12-13-93 07:33am LS simplified and corrected some logic glitches.
// 12-13-93 04:10pm LS made fit for all block types.
// BubbleBlockUp: move block 1 line up
macro BubbleBlockUp {
  int temp_insert            = insert_mode;
  int temp_persistent_blocks = persistent_blocks;
  insert_mode       = true;
  persistent_blocks = 1;
  push_undo;
  Goto_Col( Block_Col1 );
  up;
  Goto_Line( Block_Line1 - 1 );
  move_block;
  pop_undo;
  persistent_blocks = temp_persistent_blocks;
  insert_mode       = temp_insert;
}
// BubbleDown:  move cursor line down
macro BubbleDown {
  int temp_refresh           = refresh;
  int temp_persistent_blocks = persistent_blocks;
  refresh           = false;
  persistent_blocks = 1;
  push_undo;
  if ( block_stat ) { // better : if cursor in block ...
    rm( "BUBBLES^BubbleBlockDown" );
  }
  else {
    rm( "BUBBLES^BubbleLineDown" );
  }
  pop_undo;
  persistent_blocks = temp_persistent_blocks;
  refresh           = temp_refresh;
}

macro BubbleLineDown {
  str a[ 2048 ] = get_line;
  down;
  str b[ 2048 ] = get_line;
  put_line( a );
  up;
  put_line( b );
  down;
}
// Written by: Lars Jeurissen
// 12-13-93 04:10pm LS made fit for all block types.
// simplified logic
// BubbleBlockDown: move block 1 line down
macro BubbleBlockDown {
  int temp_insert            = insert_mode;
  int temp_persistent_blocks = persistent_blocks;
  insert_mode       = true;
  persistent_blocks = 1;
  push_undo;
  int dest = block_line2 + 1;
  Goto_Col( Block_Col1 );
  if ( block_stat == 1 ) {
    ++dest;
  }
  if ( block_stat == 2 ) {
    dest = block_line1 + 1;
  }
  down;
  goto_line( dest );
  move_block;
  goto_line( block_line1 );
  pop_undo;
  persistent_blocks = temp_persistent_blocks;
  insert_mode       = temp_insert;
}
// Written by: Lars Jeurissen
// Bubble block left
// MEW9.10 UNDBLK is moved to BLOCKS
macro BubbleLeft {
  int t_refresh = refresh;
  push_undo;
  refresh = false;
  if ( !Block_Stat ) {
    rm( 'MEUTIL2^MARKBLCK' );
    rm( 'MEUTIL2^UNDBLK' );
    Left;
    Left;
    rm( 'MEUTIL2^BLOCKOFF' );
  }
  else {
    rm( 'MEUTIL2^UNDBLK' );
  }
  refresh = t_refresh;
  pop_undo;
}
// Written by: Lars Jeurissen
// BubbleUp :  move block to the left
macro BubbleBlockleft {
  int flag                   = block_stat;
  int temp_persistent_blocks = persistent_blocks;
  str tmpline;
  int linelen;
  if ( flag == 0 )
    make_message( 'No Block Marked!' );
  else {
    persistent_blocks = 1;
    push_undo;
    tmpline = Get_Line;
    linelen = length( tmpline );
    goto_col( block_col1 );
    if ( ( c_col >= linelen ) and ( at_eof == false ) ) {
      down;
      Goto_Col( 1 );
    }
    left;
    if ( flag == 2 )
      column_move_style;
    move_block;
    pop_undo;
    persistent_blocks = temp_persistent_blocks;
  }
}
// Written by: Lars Jeurissen
// Bubble block right
// MEW9.10 UNDBLK is moved to BLOCKS
macro BubbleRight {
  int t_refresh = refresh;
  push_undo;
  refresh = false;
  if ( !Block_Stat ) {
    rm( 'MEUTIL2^MARKBLCK' );
    rm( 'MEUTIL2^INDBLK ' );
    Right;
    Right;
    rm( 'MEUTIL2^BLOCKOFF' );
  }
  else {
    rm( 'MEUTIL2^INDBLK' );
  }
  refresh = t_refresh;
  pop_undo;
}
// Written by: Lars Jeurissen
// BubbleRight:  move block to the right
macro BubbleBlockRight {
  int flag                   = block_stat;
  int temp_persistent_blocks = persistent_blocks;
  if ( flag == 0 )
    make_message( 'No Block Marked!' );
  else {
    persistent_blocks = 1;
    push_undo;
    goto_col( block_col2 );
    Right;
    Right;
    if ( flag == 2 )
      column_move_style;
    move_block;
    pop_undo;
    persistent_blocks = temp_persistent_blocks;
  }
}
// Written by: Lars Van Jeurissen (3-11-2009)
// InstallBubbleKeys: Keep original copy of ctrl + alt + shift + (up|down|left|right)
macro InstallBubbleKeys {
  Macro_To_Key( K_CtrlAltShftLeft, 'BUBBLES^BUBBLELEFT', Edit );
  Macro_To_Key( K_CtrlAltShftUp, 'BUBBLES^BUBBLEUP', Edit );
  Macro_To_Key( K_CtrlAltShftRight, 'BUBBLES^BUBBLERIGHT', Edit );
  Macro_To_Key( K_CtrlAltShftDown, 'BUBBLES^BUBBLEDOWN', Edit );
}
// Written by: Lars Van Jeurissen (3-11-2009)
// GetHexKeyCode: Get The Hexadecimal KeyCode for the pressed key (ctrl + alt + shift + (up|down|left|right))
// needed to #DEFINE the keycodes
macro GetHexKeyCode {
  str Key_Name;
  Read_Key; /* Get keycode */
  Key_Name = Make_Key_Name( Make_Word( key1, key2 ) );
  Make_Message( "You pressed 0x" + Hex_Str( key1 ) + Hex_Str( key2 ) + " " + Key_Name + " key1: " + Hex_Str( key1 ) + " key2: " + Hex_Str( key2 ));
}

