История буфера обмена в виде меню

Обсуждение программ nnCron и nnCron LITE

История буфера обмена в виде меню

Postby Morituruz » Sat, 21 Jul 2012, 12:44

По хоткею (alt + c) вызывается меню, в котором содержится история буфера обмена + образцы.
Если кликнуть по строчке в истории, то выбранный пункт помещается в буфер обмена и наверх списка.
Если кликнуть с шифтом, то выбранный пункт помещается в список образцов (идёт после разделителя внизу).
Если с шифтом кликнуть на образец, то он удалится из списка.

Image

Изображения (PrintScreen) и файловые ссылки в список не попадают, только текст.

Для работы требуются плагины: Autostrings, Lists, KEYSTATE.

Code: Select all
<%
GLOBAL-STRING-LIST: cb_history
GLOBAL-STRING-LIST: cb_examples
VARIABLE cb_menu_selected_item
VARIABLE cb_examples_flag
\ буфер для цирка с конями:
0 VALUE cb_buffer

CREATE soh_zstr 1 C,  0 C,
:  soh_str  soh_zstr 1 ;
: StringReplace { a1 u1 a2 u2  a3 u3 \ rest a4 u4 buf -- a u }  \ Заменить в строке 1 подстроку 2 на строку 3, на стеке останется измененая строка
  AT buf TO a4
  a1 u1
  BEGIN OVER SWAP a2 u2 SEARCH WHILE
    TO rest SWAP 2DUP - a4 u4 2SWAP S+ TO u4 TO a4
    a3 u3 a4 u4 2SWAP S+ TO u4 TO a4
    rest u2 /STRING
  REPEAT
  a4 u4 2SWAP S+
  ROT DROP
;
: cb_replace " |t" "  " StringReplace
CRLF "  " StringReplace
;

: make_cb_menu_popup
POPUPMENU
cb_history(
   NODE@ DUP 100 >
   IF
      \ обрезаем до 100 символов
      DROP 100 S" ..." S+ cb_replace S>ZALLOC TO cb_buffer
   ELSE
      cb_replace S>ZALLOC TO cb_buffer
   THEN
   cb_buffer ASCIIZ> NODE MENUITEM
   cb_buffer FREE DROP
)cb_history
MENUSEPARATOR
\ откомментировать, если хочется вложенное меню с образцами:
\ POPUP
   cb_examples(
      NODE@ DUP 100 >
      IF
         \ цирк с конями, т.к. MENUITEM хочет строку с 0
         \ обрезаем до 100 символов
         DROP 100 S" ..." S+ cb_replace S>ZALLOC TO cb_buffer
      ELSE
         cb_replace S>ZALLOC TO cb_buffer
      THEN
      cb_buffer ASCIIZ> NODE MENUITEM
      cb_buffer FREE DROP
   )cb_examples
\ S" Образцы" END-POPUP
END-MENU
;

: start_cb_menu_item { id -- }
id cb_history NODE># -1 =
IF
   VK_LSHIFT KEY-PRESSED?
   VK_RSHIFT KEY-PRESSED?
   OR
   IF
      \ если в меню образцов кликаем с зажатым shift, то удаляем этот образец
      S" cb_examples" FILE id cb_history NODE>@ soh_str S+ "" StringReplace
      2DUP
      S" cb_examples" FWRITE
      cb_examples LIST-FREE
      \ ищем в файле cb_examples всё, что содержится между символами x01
      S" /(\x01)?#1.+?(\x01)?=/is" RE-ALL
         $0 !cb_examples
      ;RE-ALL
   ELSE
      \ получаем строку из списка, помещаем её в буфер обмена
      cb_examples_flag ON
      id cb_examples NODE>@ CLIPBOARD!
      id cb_menu_selected_item !
   THEN
ELSE
   VK_LSHIFT KEY-PRESSED?
   VK_RSHIFT KEY-PRESSED?
   OR
   IF
      \ если зажать shift, добавляем пункт в файл cb_examples (образцы)
      id cb_history NODE>@ 2DUP 2DUP cb_examples LIST? NOT
      IF
         soh_str S+ S" cb_examples" FAPPEND
         !cb_examples
      ELSE
         2DROP 2DROP
      THEN
   ELSE
      \ получаем строку из списка, помещаем её в буфер обмена
      \ повторно в список она не добавится, т.к. уже там есть
      id cb_history NODE>@ CLIPBOARD!
      \ сохраняем, чтобы сделать данный пункт меню жирным:
      id cb_menu_selected_item !
   THEN
THEN
;

USER invisible_window
: cb_menu
    WITH TrayIcon
    Z" static" 0 0 Window invisible_window !
    ENDWITH
make_cb_menu_popup >R
\ делаем выбранный пункт жирным шрифтом
cb_menu_selected_item @
IF
   0 cb_menu_selected_item @ R@ SetMenuDefaultItem DROP
THEN

    invisible_window @ SetForegroundWindow DROP
    0 invisible_window @
MOUSE-POS SWAP
( TPM_RETURNCMD) 256 R@ TrackPopupMenuEx
?DUP IF start_cb_menu_item THEN
R> DestroyMenu DROP
;

%>

#( add_clipboard_to_list
\ 10:16 06.07.2012
\ NoActive
HyperActive
NoLog
SingleInstance
WatchClipboard: "*"
Action:
\ если в буфере появился образец, то выходим
cb_examples_flag @ IF cb_examples_flag OFF EXIT THEN
S" cb_history" EXIST?
IF
   \ заменяем в файле истории все совпадения с буфером обмена
   \ после чего приписываем буфер в конец файла
   \ после этого всё что в файле добавляем в список
   CLIPBOARD 2DUP
   S" cb_history" FILE 2SWAP soh_str S+ "" StringReplace
   2SWAP soh_str S+ S+
   cb_history LIST-FREE
   \ ищем в файле cb_history всё, что содержится между символами x01
   S" /(\x01)?#1.+?(\x01)?=/is" RE-ALL
      $0 !cb_history
   ;RE-ALL
   \ проходим по списку, подсчитывая значения, составляем строку заново
   \ и записываем в файл:
   soh_str 0
   cb_history(
      \ ограничиваем максимальное количество строк 10
      1+ DUP 21 <
      IF
         SWAP ROT SWAP soh_str NODE@ S+ 2SWAP S+ ROT
      ELSE
         NDEL
      THEN
   )cb_history
   DROP
   S" cb_history" FWRITE
ELSE
   soh_str CLIPBOARD 2DUP !cb_history 2OVER S+ S+ S" cb_history" FWRITE
THEN

S" cb_examples" EXIST?
IF
   cb_examples# 0=
   IF
      \ ищем в файле cb_examples всё, что содержится между символами x01
      " cb_examples" FILE " /(\x01)?#1.+?(\x01)?=/is" RE-ALL
         $0 !cb_examples
      ;RE-ALL
   THEN
ELSE
   soh_str S" cb_examples" FWRITE
THEN

\ и сохраняем номерок, чтобы жирненьким был
0 cb_history LIST#> cb_menu_selected_item !
)#

#( cb_menu_hotkey
NoLog
\ alt+c
WatchHotKey: "@c"
SingleInstance
Action:
\ вызов меню:
cb_menu
)#
User avatar
Morituruz
 
Posts: 727
Joined: Sun, 14 Oct 2007, 01:51

Re: История буфера обмена в виде меню

Postby Morituruz » Tue, 24 Jul 2012, 09:47

Обновлено, добавил слово StringReplace, т.к. оно не из справки, а от VoidVolker-а.
User avatar
Morituruz
 
Posts: 727
Joined: Sun, 14 Oct 2007, 01:51


Return to nnCron forum (Russian)

Who is online

Users browsing this forum: No registered users and 4 guests

cron